1190118d0SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3190118d0SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4190118d0SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5190118d0SAndrew Rist  * distributed with this work for additional information
6190118d0SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7190118d0SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8190118d0SAndrew Rist  * "License"); you may not use this file except in compliance
9190118d0SAndrew Rist  * with the License.  You may obtain a copy of the License at
10190118d0SAndrew Rist  *
11190118d0SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12190118d0SAndrew Rist  *
13190118d0SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14190118d0SAndrew Rist  * software distributed under the License is distributed on an
15190118d0SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16190118d0SAndrew Rist  * KIND, either express or implied.  See the License for the
17190118d0SAndrew Rist  * specific language governing permissions and limitations
18190118d0SAndrew Rist  * under the License.
19190118d0SAndrew Rist  *
20190118d0SAndrew Rist  *************************************************************/
21190118d0SAndrew Rist 
22190118d0SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_editeng.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <vcl/wrkwin.hxx>
28cdf0e10cSrcweir #include <vcl/dialog.hxx>
29cdf0e10cSrcweir #include <vcl/msgbox.hxx>
30cdf0e10cSrcweir #include <vcl/svapp.hxx>
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include <svl/srchitem.hxx>
33cdf0e10cSrcweir #include <editeng/lspcitem.hxx>
34cdf0e10cSrcweir #include <editeng/adjitem.hxx>
35cdf0e10cSrcweir #include <editeng/tstpitem.hxx>
36cdf0e10cSrcweir 
37cdf0e10cSrcweir #include <eertfpar.hxx>
38cdf0e10cSrcweir #include <editeng/editeng.hxx>
39cdf0e10cSrcweir #include <impedit.hxx>
40cdf0e10cSrcweir #include <editeng/editview.hxx>
41cdf0e10cSrcweir #include <eehtml.hxx>
42cdf0e10cSrcweir #include <editobj2.hxx>
43cdf0e10cSrcweir #include <i18npool/lang.h>
44cdf0e10cSrcweir 
45cdf0e10cSrcweir #include "editxml.hxx"
46cdf0e10cSrcweir 
47cdf0e10cSrcweir #include <editeng/akrnitem.hxx>
48cdf0e10cSrcweir #include <editeng/cntritem.hxx>
49cdf0e10cSrcweir #include <editeng/colritem.hxx>
50cdf0e10cSrcweir #include <editeng/crsditem.hxx>
51cdf0e10cSrcweir #include <editeng/escpitem.hxx>
52cdf0e10cSrcweir #include <editeng/fhgtitem.hxx>
53cdf0e10cSrcweir #include <editeng/fontitem.hxx>
54cdf0e10cSrcweir #include <editeng/kernitem.hxx>
55cdf0e10cSrcweir #include <editeng/lrspitem.hxx>
56cdf0e10cSrcweir #include <editeng/postitem.hxx>
57cdf0e10cSrcweir #include <editeng/shdditem.hxx>
58cdf0e10cSrcweir #include <editeng/udlnitem.hxx>
59cdf0e10cSrcweir #include <editeng/ulspitem.hxx>
60cdf0e10cSrcweir #include <editeng/wghtitem.hxx>
61cdf0e10cSrcweir #include <editeng/langitem.hxx>
62cdf0e10cSrcweir #include <editeng/charreliefitem.hxx>
63cdf0e10cSrcweir #include <editeng/frmdiritem.hxx>
64cdf0e10cSrcweir #include <editeng/emphitem.hxx>
65cdf0e10cSrcweir #include <textconv.hxx>
66cdf0e10cSrcweir #include <rtl/tencinfo.h>
67cdf0e10cSrcweir #include <svtools/rtfout.hxx>
68cdf0e10cSrcweir #include <edtspell.hxx>
69cdf0e10cSrcweir #include <editeng/scripttypeitem.hxx>
70cdf0e10cSrcweir #include <editeng/unolingu.hxx>
71cdf0e10cSrcweir #include <linguistic/lngprops.hxx>
72cdf0e10cSrcweir #include <com/sun/star/linguistic2/XThesaurus.hpp>
73cdf0e10cSrcweir #include <com/sun/star/linguistic2/XMeaning.hpp>
74cdf0e10cSrcweir #include <com/sun/star/i18n/ScriptType.hpp>
75cdf0e10cSrcweir #include <com/sun/star/i18n/WordType.hpp>
76cdf0e10cSrcweir #include <com/sun/star/i18n/TransliterationModules.hpp>
77cdf0e10cSrcweir #include <com/sun/star/i18n/TransliterationModulesExtra.hpp>
78cdf0e10cSrcweir #include <unotools/transliterationwrapper.hxx>
79cdf0e10cSrcweir #include <unotools/textsearch.hxx>
80cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
81cdf0e10cSrcweir #include <vcl/help.hxx>
82cdf0e10cSrcweir #include <svtools/rtfkeywd.hxx>
83cdf0e10cSrcweir #include <editeng/edtdlg.hxx>
84cdf0e10cSrcweir 
85cdf0e10cSrcweir #include <vector>
86cdf0e10cSrcweir 
87cdf0e10cSrcweir using namespace ::com::sun::star;
88cdf0e10cSrcweir using namespace ::com::sun::star::uno;
89cdf0e10cSrcweir using namespace ::com::sun::star::beans;
90cdf0e10cSrcweir using namespace ::com::sun::star::linguistic2;
91cdf0e10cSrcweir 
Swapsal_uIt16s(sal_uInt16 & rX,sal_uInt16 & rY)92cdf0e10cSrcweir void Swapsal_uIt16s( sal_uInt16& rX, sal_uInt16& rY )
93cdf0e10cSrcweir {
94cdf0e10cSrcweir 	sal_uInt16 n = rX;
95cdf0e10cSrcweir 	rX = rY;
96cdf0e10cSrcweir 	rY = n;
97cdf0e10cSrcweir }
98cdf0e10cSrcweir 
Read(SvStream & rInput,const String & rBaseURL,EETextFormat eFormat,EditSelection aSel,SvKeyValueIterator * pHTTPHeaderAttrs)99cdf0e10cSrcweir EditPaM ImpEditEngine::Read( SvStream& rInput, const String& rBaseURL, EETextFormat eFormat, EditSelection aSel, SvKeyValueIterator* pHTTPHeaderAttrs )
100cdf0e10cSrcweir {
101cdf0e10cSrcweir 	sal_Bool _bUpdate = GetUpdateMode();
102cdf0e10cSrcweir 	SetUpdateMode( sal_False );
103cdf0e10cSrcweir 	EditPaM aPaM;
104cdf0e10cSrcweir 	if ( eFormat == EE_FORMAT_TEXT )
105cdf0e10cSrcweir 		aPaM = ReadText( rInput, aSel );
106cdf0e10cSrcweir 	else if ( eFormat == EE_FORMAT_RTF )
107cdf0e10cSrcweir 		aPaM = ReadRTF( rInput, aSel );
108cdf0e10cSrcweir 	else if ( eFormat == EE_FORMAT_XML )
109cdf0e10cSrcweir 		aPaM = ReadXML( rInput, aSel );
110cdf0e10cSrcweir 	else if ( eFormat == EE_FORMAT_HTML )
111cdf0e10cSrcweir         aPaM = ReadHTML( rInput, rBaseURL, aSel, pHTTPHeaderAttrs );
112cdf0e10cSrcweir 	else if ( eFormat == EE_FORMAT_BIN)
113cdf0e10cSrcweir 		aPaM = ReadBin( rInput, aSel );
114cdf0e10cSrcweir 	else
115cdf0e10cSrcweir 	{
116cdf0e10cSrcweir 		DBG_ERROR( "Read: Unbekanntes Format" );
117cdf0e10cSrcweir 	}
118cdf0e10cSrcweir 
119cdf0e10cSrcweir 	FormatFullDoc();		// reicht vielleicht auch ein einfaches Format?
120cdf0e10cSrcweir 	SetUpdateMode( _bUpdate );
121cdf0e10cSrcweir 
122cdf0e10cSrcweir 	return aPaM;
123cdf0e10cSrcweir }
124cdf0e10cSrcweir 
ReadText(SvStream & rInput,EditSelection aSel)125cdf0e10cSrcweir EditPaM ImpEditEngine::ReadText( SvStream& rInput, EditSelection aSel )
126cdf0e10cSrcweir {
127cdf0e10cSrcweir 	if ( aSel.HasRange() )
128cdf0e10cSrcweir 		aSel = ImpDeleteSelection( aSel );
129cdf0e10cSrcweir 	EditPaM aPaM = aSel.Max();
130cdf0e10cSrcweir 
131cdf0e10cSrcweir 	XubString aTmpStr, aStr;
132cdf0e10cSrcweir 	sal_Bool bDone = rInput.ReadByteStringLine( aTmpStr );
133cdf0e10cSrcweir 	while ( bDone )
134cdf0e10cSrcweir 	{
135cdf0e10cSrcweir 		aTmpStr.Erase( MAXCHARSINPARA );
136cdf0e10cSrcweir 		aPaM = ImpInsertText( EditSelection( aPaM, aPaM ), aTmpStr );
137cdf0e10cSrcweir 		aPaM = ImpInsertParaBreak( aPaM );
138cdf0e10cSrcweir 		bDone = rInput.ReadByteStringLine( aTmpStr );
139cdf0e10cSrcweir 	}
140cdf0e10cSrcweir 	return aPaM;
141cdf0e10cSrcweir }
142cdf0e10cSrcweir 
ReadXML(SvStream & rInput,EditSelection aSel)143cdf0e10cSrcweir EditPaM ImpEditEngine::ReadXML( SvStream& rInput, EditSelection aSel )
144cdf0e10cSrcweir {
145cdf0e10cSrcweir #ifndef SVX_LIGHT
146cdf0e10cSrcweir 	if ( aSel.HasRange() )
147cdf0e10cSrcweir 		aSel = ImpDeleteSelection( aSel );
148cdf0e10cSrcweir 
149cdf0e10cSrcweir     ESelection aESel = CreateESel( aSel );
150cdf0e10cSrcweir 
151cdf0e10cSrcweir     ::SvxReadXML( *GetEditEnginePtr(), rInput, aESel );
152cdf0e10cSrcweir 
153cdf0e10cSrcweir     return aSel.Max();
154cdf0e10cSrcweir #else
155cdf0e10cSrcweir 	return EditPaM();
156cdf0e10cSrcweir #endif
157cdf0e10cSrcweir }
158cdf0e10cSrcweir 
ReadRTF(SvStream & rInput,EditSelection aSel)159cdf0e10cSrcweir EditPaM ImpEditEngine::ReadRTF( SvStream& rInput, EditSelection aSel )
160cdf0e10cSrcweir {
161cdf0e10cSrcweir #ifndef SVX_LIGHT
162cdf0e10cSrcweir 
163cdf0e10cSrcweir #if defined (EDITDEBUG) && !defined( UNX )
164cdf0e10cSrcweir 	SvFileStream aRTFOut( String( RTL_CONSTASCII_USTRINGPARAM ( "d:\\rtf_in.rtf" ) ), STREAM_WRITE );
165cdf0e10cSrcweir 	aRTFOut << rInput;
166cdf0e10cSrcweir 	aRTFOut.Close();
167cdf0e10cSrcweir 	rInput.Seek( 0 );
168cdf0e10cSrcweir #endif
169cdf0e10cSrcweir 	if ( aSel.HasRange() )
170cdf0e10cSrcweir 		aSel = ImpDeleteSelection( aSel );
171cdf0e10cSrcweir 
172cdf0e10cSrcweir //	sal_Bool bCharsBeforeInsertPos = ( aSel.Min().GetIndex() ) ? sal_True : sal_False;
173cdf0e10cSrcweir //	sal_Bool bCharsBehindInsertPos = ( aSel.Min().GetIndex() < aSel.Min().GetNode()->Len() ) ? sal_True : sal_False;
174cdf0e10cSrcweir 
175cdf0e10cSrcweir 	// Der SvRTF-Parser erwartet, dass das Which-Mapping am uebergebenen Pool,
176cdf0e10cSrcweir 	// nicht an einem Secondary haengt.
177cdf0e10cSrcweir 	SfxItemPool* pPool = &aEditDoc.GetItemPool();
178cdf0e10cSrcweir 	while ( pPool->GetSecondaryPool() && !pPool->GetName().EqualsAscii( "EditEngineItemPool" ) )
179cdf0e10cSrcweir 	{
180cdf0e10cSrcweir 		pPool = pPool->GetSecondaryPool();
181cdf0e10cSrcweir 
182cdf0e10cSrcweir 	}
183cdf0e10cSrcweir 	DBG_ASSERT( pPool && pPool->GetName().EqualsAscii( "EditEngineItemPool" ), "ReadRTF: Kein EditEnginePool!" );
184cdf0e10cSrcweir 
185cdf0e10cSrcweir 	EditRTFParserRef xPrsr = new EditRTFParser( rInput, aSel, *pPool, this );
186cdf0e10cSrcweir 	SvParserState eState = xPrsr->CallParser();
187cdf0e10cSrcweir 	if ( ( eState != SVPAR_ACCEPTED ) && ( !rInput.GetError() ) )
188cdf0e10cSrcweir 	{
189cdf0e10cSrcweir 		rInput.SetError( EE_READWRITE_WRONGFORMAT );
190cdf0e10cSrcweir 		return aSel.Min();
191cdf0e10cSrcweir 	}
192cdf0e10cSrcweir 	return xPrsr->GetCurPaM();
193cdf0e10cSrcweir #else
194cdf0e10cSrcweir 	return EditPaM();
195cdf0e10cSrcweir #endif
196cdf0e10cSrcweir }
197cdf0e10cSrcweir 
ReadHTML(SvStream & rInput,const String & rBaseURL,EditSelection aSel,SvKeyValueIterator * pHTTPHeaderAttrs)198cdf0e10cSrcweir EditPaM ImpEditEngine::ReadHTML( SvStream& rInput, const String& rBaseURL, EditSelection aSel, SvKeyValueIterator* pHTTPHeaderAttrs )
199cdf0e10cSrcweir {
200cdf0e10cSrcweir #ifndef SVX_LIGHT
201cdf0e10cSrcweir 
202cdf0e10cSrcweir 	if ( aSel.HasRange() )
203cdf0e10cSrcweir 		aSel = ImpDeleteSelection( aSel );
204cdf0e10cSrcweir 
205cdf0e10cSrcweir //	sal_Bool bCharsBeforeInsertPos = ( aSel.Min().GetIndex() ) ? sal_True : sal_False;
206cdf0e10cSrcweir //	sal_Bool bCharsBehindInsertPos = ( aSel.Min().GetIndex() < aSel.Min().GetNode()->Len() ) ? sal_True : sal_False;
207cdf0e10cSrcweir 
208cdf0e10cSrcweir     EditHTMLParserRef xPrsr = new EditHTMLParser( rInput, rBaseURL, pHTTPHeaderAttrs );
209cdf0e10cSrcweir 	SvParserState eState = xPrsr->CallParser( this, aSel.Max() );
210cdf0e10cSrcweir 	if ( ( eState != SVPAR_ACCEPTED ) && ( !rInput.GetError() ) )
211cdf0e10cSrcweir 	{
212cdf0e10cSrcweir 		rInput.SetError( EE_READWRITE_WRONGFORMAT );
213cdf0e10cSrcweir 		return aSel.Min();
214cdf0e10cSrcweir 	}
215cdf0e10cSrcweir 	return xPrsr->GetCurSelection().Max();
216cdf0e10cSrcweir #else
217cdf0e10cSrcweir 	return EditPaM();
218cdf0e10cSrcweir #endif
219cdf0e10cSrcweir }
220cdf0e10cSrcweir 
ReadBin(SvStream & rInput,EditSelection aSel)221cdf0e10cSrcweir EditPaM ImpEditEngine::ReadBin( SvStream& rInput, EditSelection aSel )
222cdf0e10cSrcweir {
223cdf0e10cSrcweir 	// Einfach ein temporaeres TextObject missbrauchen...
224cdf0e10cSrcweir 	EditTextObject* pObj = EditTextObject::Create( rInput, NULL );
225cdf0e10cSrcweir 
226cdf0e10cSrcweir 	EditPaM aLastPaM = aSel.Max();
227cdf0e10cSrcweir 	if ( pObj )
228cdf0e10cSrcweir 		aLastPaM = InsertText( *pObj, aSel ).Max();
229cdf0e10cSrcweir 
230cdf0e10cSrcweir 	delete pObj;
231cdf0e10cSrcweir 	return aLastPaM;
232cdf0e10cSrcweir }
233cdf0e10cSrcweir 
234cdf0e10cSrcweir #ifndef SVX_LIGHT
Write(SvStream & rOutput,EETextFormat eFormat,EditSelection aSel)235cdf0e10cSrcweir void ImpEditEngine::Write( SvStream& rOutput, EETextFormat eFormat, EditSelection aSel )
236cdf0e10cSrcweir {
237cdf0e10cSrcweir 	if ( !rOutput.IsWritable() )
238cdf0e10cSrcweir 		rOutput.SetError( SVSTREAM_WRITE_ERROR );
239cdf0e10cSrcweir 
240cdf0e10cSrcweir 	if ( !rOutput.GetError() )
241cdf0e10cSrcweir 	{
242cdf0e10cSrcweir 		if ( eFormat == EE_FORMAT_TEXT )
243cdf0e10cSrcweir 			WriteText( rOutput, aSel );
244cdf0e10cSrcweir 		else if ( eFormat == EE_FORMAT_RTF )
245cdf0e10cSrcweir 			WriteRTF( rOutput, aSel );
246cdf0e10cSrcweir 		else if ( eFormat == EE_FORMAT_XML )
247cdf0e10cSrcweir 			WriteXML( rOutput, aSel );
248cdf0e10cSrcweir 		else if ( eFormat == EE_FORMAT_HTML )
249cdf0e10cSrcweir 			WriteHTML( rOutput, aSel );
250cdf0e10cSrcweir 		else if ( eFormat == EE_FORMAT_BIN)
251cdf0e10cSrcweir 			WriteBin( rOutput, aSel );
252cdf0e10cSrcweir 		else
253cdf0e10cSrcweir 		{
254cdf0e10cSrcweir 			DBG_ERROR( "Write: Unbekanntes Format" );
255cdf0e10cSrcweir 		}
256cdf0e10cSrcweir 	}
257cdf0e10cSrcweir }
258cdf0e10cSrcweir #endif
259cdf0e10cSrcweir 
WriteText(SvStream & rOutput,EditSelection aSel)260cdf0e10cSrcweir sal_uInt32 ImpEditEngine::WriteText( SvStream& rOutput, EditSelection aSel )
261cdf0e10cSrcweir {
262*7a980842SDamjanJovanovic 	sal_uInt32 nStartNode, nEndNode;
263cdf0e10cSrcweir 	sal_Bool bRange = aSel.HasRange();
264cdf0e10cSrcweir 	if ( bRange )
265cdf0e10cSrcweir 	{
266cdf0e10cSrcweir 		aSel.Adjust( aEditDoc );
267cdf0e10cSrcweir 		nStartNode = aEditDoc.GetPos( aSel.Min().GetNode() );
268cdf0e10cSrcweir 		nEndNode = aEditDoc.GetPos( aSel.Max().GetNode() );
269cdf0e10cSrcweir 	}
270cdf0e10cSrcweir 	else
271cdf0e10cSrcweir 	{
272cdf0e10cSrcweir 		nStartNode = 0;
273cdf0e10cSrcweir 		nEndNode = aEditDoc.Count()-1;
274cdf0e10cSrcweir 	}
275cdf0e10cSrcweir 
276cdf0e10cSrcweir 	// ueber die Absaetze iterieren...
277*7a980842SDamjanJovanovic 	for ( sal_uInt32 nNode = nStartNode; nNode <= nEndNode; nNode++  )
278cdf0e10cSrcweir 	{
279cdf0e10cSrcweir 		ContentNode* pNode = aEditDoc.GetObject( nNode );
280cdf0e10cSrcweir 		DBG_ASSERT( pNode, "Node nicht gefunden: Search&Replace" );
281cdf0e10cSrcweir 
282cdf0e10cSrcweir 		sal_uInt16 nStartPos = 0;
283cdf0e10cSrcweir 		sal_uInt16 nEndPos = pNode->Len();
284cdf0e10cSrcweir 		if ( bRange )
285cdf0e10cSrcweir 		{
286cdf0e10cSrcweir 			if ( nNode == nStartNode )
287cdf0e10cSrcweir 				nStartPos = aSel.Min().GetIndex();
288cdf0e10cSrcweir 			if ( nNode == nEndNode ) // kann auch == nStart sein!
289cdf0e10cSrcweir 				nEndPos = aSel.Max().GetIndex();
290cdf0e10cSrcweir 		}
291cdf0e10cSrcweir 		XubString aTmpStr = aEditDoc.GetParaAsString( pNode, nStartPos, nEndPos );
292cdf0e10cSrcweir 		rOutput.WriteByteStringLine( aTmpStr );
293cdf0e10cSrcweir 	}
294cdf0e10cSrcweir 
295cdf0e10cSrcweir 	return rOutput.GetError();
296cdf0e10cSrcweir }
297cdf0e10cSrcweir 
WriteItemListAsRTF(ItemList & rLst,SvStream & rOutput,sal_uInt32 nPara,sal_uInt16 nPos,SvxFontTable & rFontTable,SvxColorList & rColorList)298*7a980842SDamjanJovanovic sal_Bool ImpEditEngine::WriteItemListAsRTF( ItemList& rLst, SvStream& rOutput, sal_uInt32 nPara, sal_uInt16 nPos,
299cdf0e10cSrcweir 						SvxFontTable& rFontTable, SvxColorList& rColorList )
300cdf0e10cSrcweir {
301cdf0e10cSrcweir 	const SfxPoolItem* pAttrItem = rLst.First();
302cdf0e10cSrcweir 	while ( pAttrItem )
303cdf0e10cSrcweir 	{
304cdf0e10cSrcweir 		WriteItemAsRTF( *pAttrItem, rOutput, nPara, nPos,rFontTable, rColorList );
305cdf0e10cSrcweir 		pAttrItem = rLst.Next();
306cdf0e10cSrcweir 	}
307cdf0e10cSrcweir 	return ( rLst.Count() ? sal_True : sal_False );
308cdf0e10cSrcweir }
309cdf0e10cSrcweir 
lcl_FindValidAttribs(ItemList & rLst,ContentNode * pNode,sal_uInt16 nIndex,sal_uInt16 nScriptType)310cdf0e10cSrcweir void lcl_FindValidAttribs( ItemList& rLst, ContentNode* pNode, sal_uInt16 nIndex, sal_uInt16 nScriptType )
311cdf0e10cSrcweir {
312cdf0e10cSrcweir 	sal_uInt16 nAttr = 0;
313cdf0e10cSrcweir 	EditCharAttrib* pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
314cdf0e10cSrcweir 	while ( pAttr && ( pAttr->GetStart() <= nIndex ) )
315cdf0e10cSrcweir 	{
316cdf0e10cSrcweir 		// Start wird in While ueberprueft...
317cdf0e10cSrcweir 		if ( pAttr->GetEnd() > nIndex )
318cdf0e10cSrcweir         {
319cdf0e10cSrcweir             if ( IsScriptItemValid( pAttr->GetItem()->Which(), nScriptType ) )
320cdf0e10cSrcweir 			    rLst.Insert( pAttr->GetItem(), LIST_APPEND );
321cdf0e10cSrcweir 		}
322cdf0e10cSrcweir 		nAttr++;
323cdf0e10cSrcweir 		pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
324cdf0e10cSrcweir 	}
325cdf0e10cSrcweir }
326cdf0e10cSrcweir 
WriteBin(SvStream & rOutput,EditSelection aSel,sal_Bool bStoreUnicodeStrings) const327cdf0e10cSrcweir sal_uInt32 ImpEditEngine::WriteBin( SvStream& rOutput, EditSelection aSel, sal_Bool bStoreUnicodeStrings ) const
328cdf0e10cSrcweir {
329cdf0e10cSrcweir 	BinTextObject* pObj = (BinTextObject*)CreateBinTextObject( aSel, NULL );
330cdf0e10cSrcweir 	pObj->StoreUnicodeStrings( bStoreUnicodeStrings );
331cdf0e10cSrcweir 	pObj->Store( rOutput );
332cdf0e10cSrcweir 	delete pObj;
333cdf0e10cSrcweir 	return 0;
334cdf0e10cSrcweir }
335cdf0e10cSrcweir 
336cdf0e10cSrcweir #ifndef SVX_LIGHT
WriteXML(SvStream & rOutput,EditSelection aSel)337cdf0e10cSrcweir sal_uInt32 ImpEditEngine::WriteXML( SvStream& rOutput, EditSelection aSel )
338cdf0e10cSrcweir {
339cdf0e10cSrcweir     ESelection aESel = CreateESel( aSel );
340cdf0e10cSrcweir 
341cdf0e10cSrcweir     SvxWriteXML( *GetEditEnginePtr(), rOutput, aESel );
342cdf0e10cSrcweir 
343cdf0e10cSrcweir     return 0;
344cdf0e10cSrcweir }
345cdf0e10cSrcweir #endif
346cdf0e10cSrcweir 
getStylePos(const SfxStyles & rStyles,SfxStyleSheet * pSheet)347cdf0e10cSrcweir static sal_uInt16 getStylePos( const SfxStyles& rStyles, SfxStyleSheet* pSheet )
348cdf0e10cSrcweir {
349cdf0e10cSrcweir 	sal_uInt16 nNumber = 0;
350cdf0e10cSrcweir 	SfxStyles::const_iterator iter( rStyles.begin() );
351cdf0e10cSrcweir 	while( iter != rStyles.end() )
352cdf0e10cSrcweir 	{
353cdf0e10cSrcweir 		if( (*iter++).get() == pSheet )
354cdf0e10cSrcweir 			return nNumber;
355cdf0e10cSrcweir 		++nNumber;
356cdf0e10cSrcweir 	}
357cdf0e10cSrcweir 	return 0;
358cdf0e10cSrcweir }
359cdf0e10cSrcweir 
WriteRTF(SvStream & rOutput,EditSelection aSel)360cdf0e10cSrcweir sal_uInt32 ImpEditEngine::WriteRTF( SvStream& rOutput, EditSelection aSel )
361cdf0e10cSrcweir {
362cdf0e10cSrcweir #ifndef SVX_LIGHT
363cdf0e10cSrcweir 	DBG_ASSERT( GetUpdateMode(), "WriteRTF bei UpdateMode = sal_False!" );
364cdf0e10cSrcweir 	CheckIdleFormatter();
365cdf0e10cSrcweir 	if ( !IsFormatted() )
366cdf0e10cSrcweir 		FormatDoc();
367cdf0e10cSrcweir 
368*7a980842SDamjanJovanovic 	sal_uInt32 nStartNode, nEndNode;
369cdf0e10cSrcweir 	aSel.Adjust( aEditDoc );
370cdf0e10cSrcweir 
371cdf0e10cSrcweir 	nStartNode = aEditDoc.GetPos( aSel.Min().GetNode() );
372cdf0e10cSrcweir 	nEndNode = aEditDoc.GetPos( aSel.Max().GetNode() );
373cdf0e10cSrcweir 
374cdf0e10cSrcweir 	// RTF-Vorspann...
375cdf0e10cSrcweir 	rOutput << '{' ;
376cdf0e10cSrcweir 
377cdf0e10cSrcweir 	rOutput << OOO_STRING_SVTOOLS_RTF_RTF;
378cdf0e10cSrcweir 
379cdf0e10cSrcweir 	rOutput << OOO_STRING_SVTOOLS_RTF_ANSI;
380cdf0e10cSrcweir 	rtl_TextEncoding eDestEnc = RTL_TEXTENCODING_MS_1252;
381cdf0e10cSrcweir 
382cdf0e10cSrcweir 	// Fonttabelle erzeugen und rausschreiben...
383cdf0e10cSrcweir 	SvxFontTable aFontTable;
384cdf0e10cSrcweir 	// DefaultFont muss ganz vorne stehen, damit DEF-Font im RTF
385cdf0e10cSrcweir 	aFontTable.Insert( 0, new SvxFontItem( (const SvxFontItem&)aEditDoc.GetItemPool().GetDefaultItem( EE_CHAR_FONTINFO ) ) );
386cdf0e10cSrcweir 	aFontTable.Insert( 1, new SvxFontItem( (const SvxFontItem&)aEditDoc.GetItemPool().GetDefaultItem( EE_CHAR_FONTINFO_CJK ) ) );
387cdf0e10cSrcweir 	aFontTable.Insert( 2, new SvxFontItem( (const SvxFontItem&)aEditDoc.GetItemPool().GetDefaultItem( EE_CHAR_FONTINFO_CTL ) ) );
388cdf0e10cSrcweir     for ( sal_uInt16 nScriptType = 0; nScriptType < 3; nScriptType++ )
389cdf0e10cSrcweir     {
390cdf0e10cSrcweir         sal_uInt16 nWhich = EE_CHAR_FONTINFO;
391cdf0e10cSrcweir         if ( nScriptType == 1 )
392cdf0e10cSrcweir             nWhich = EE_CHAR_FONTINFO_CJK;
393cdf0e10cSrcweir         else if ( nScriptType == 2 )
394cdf0e10cSrcweir             nWhich = EE_CHAR_FONTINFO_CTL;
395cdf0e10cSrcweir 
396cdf0e10cSrcweir         sal_uInt32 i = 0;
397cdf0e10cSrcweir 	    SvxFontItem* pFontItem = (SvxFontItem*)aEditDoc.GetItemPool().GetItem2( nWhich, i );
398cdf0e10cSrcweir 	    while ( pFontItem )
399cdf0e10cSrcweir 	    {
400cdf0e10cSrcweir             bool bAlreadyExist = false;
401cdf0e10cSrcweir             sal_uLong nTestMax = nScriptType ? aFontTable.Count() : 1;
402cdf0e10cSrcweir             for ( sal_uLong nTest = 0; !bAlreadyExist && ( nTest < nTestMax ); nTest++ )
403cdf0e10cSrcweir             {
404cdf0e10cSrcweir                 bAlreadyExist = *aFontTable.Get( nTest ) == *pFontItem;
405cdf0e10cSrcweir             }
406cdf0e10cSrcweir 
407cdf0e10cSrcweir             if ( !bAlreadyExist )
408cdf0e10cSrcweir 		        aFontTable.Insert( aFontTable.Count(), new SvxFontItem( *pFontItem ) );
409cdf0e10cSrcweir 
410cdf0e10cSrcweir             pFontItem = (SvxFontItem*)aEditDoc.GetItemPool().GetItem2( nWhich, ++i );
411cdf0e10cSrcweir 	    }
412cdf0e10cSrcweir     }
413cdf0e10cSrcweir 
414cdf0e10cSrcweir 	rOutput << endl << '{' << OOO_STRING_SVTOOLS_RTF_FONTTBL;
415cdf0e10cSrcweir 	sal_uInt16 j;
416cdf0e10cSrcweir 	for ( j = 0; j < aFontTable.Count(); j++ )
417cdf0e10cSrcweir 	{
418cdf0e10cSrcweir 		SvxFontItem* pFontItem = aFontTable.Get( j );
419cdf0e10cSrcweir 		rOutput << '{';
420cdf0e10cSrcweir 		rOutput << OOO_STRING_SVTOOLS_RTF_F;
421cdf0e10cSrcweir 		rOutput.WriteNumber( j );
422cdf0e10cSrcweir 		switch ( pFontItem->GetFamily()  )
423cdf0e10cSrcweir 		{
424cdf0e10cSrcweir 			case FAMILY_DONTKNOW:		rOutput << OOO_STRING_SVTOOLS_RTF_FNIL;
425cdf0e10cSrcweir 										break;
426cdf0e10cSrcweir 			case FAMILY_DECORATIVE:		rOutput << OOO_STRING_SVTOOLS_RTF_FDECOR;
427cdf0e10cSrcweir 										break;
428cdf0e10cSrcweir 			case FAMILY_MODERN:			rOutput << OOO_STRING_SVTOOLS_RTF_FMODERN;
429cdf0e10cSrcweir 										break;
430cdf0e10cSrcweir 			case FAMILY_ROMAN:			rOutput << OOO_STRING_SVTOOLS_RTF_FROMAN;
431cdf0e10cSrcweir 										break;
432cdf0e10cSrcweir 			case FAMILY_SCRIPT:			rOutput << OOO_STRING_SVTOOLS_RTF_FSCRIPT;
433cdf0e10cSrcweir 										break;
434cdf0e10cSrcweir 			case FAMILY_SWISS:			rOutput << OOO_STRING_SVTOOLS_RTF_FSWISS;
435cdf0e10cSrcweir 										break;
436cdf0e10cSrcweir 			default:
437cdf0e10cSrcweir 				break;
438cdf0e10cSrcweir 		}
439cdf0e10cSrcweir 		rOutput << OOO_STRING_SVTOOLS_RTF_FPRQ;
440cdf0e10cSrcweir 		sal_uInt16 nVal = 0;
441cdf0e10cSrcweir 		switch( pFontItem->GetPitch() )
442cdf0e10cSrcweir 		{
443cdf0e10cSrcweir 			case PITCH_FIXED:		nVal = 1;		break;
444cdf0e10cSrcweir 			case PITCH_VARIABLE:	nVal = 2;		break;
445cdf0e10cSrcweir 			default:
446cdf0e10cSrcweir 				break;
447cdf0e10cSrcweir 		}
448cdf0e10cSrcweir 		rOutput.WriteNumber( nVal );
449cdf0e10cSrcweir 
450cdf0e10cSrcweir 		CharSet eChrSet = pFontItem->GetCharSet();
451cdf0e10cSrcweir 		DBG_ASSERT( eChrSet != 9, "SystemCharSet?!" );
452cdf0e10cSrcweir 		if( RTL_TEXTENCODING_DONTKNOW == eChrSet )
453cdf0e10cSrcweir 			eChrSet = gsl_getSystemTextEncoding();
454cdf0e10cSrcweir 		rOutput << OOO_STRING_SVTOOLS_RTF_FCHARSET;
455cdf0e10cSrcweir 		rOutput.WriteNumber( rtl_getBestWindowsCharsetFromTextEncoding( eChrSet ) );
456cdf0e10cSrcweir 
457cdf0e10cSrcweir 		rOutput << ' ';
458cdf0e10cSrcweir         RTFOutFuncs::Out_String( rOutput, pFontItem->GetFamilyName(), eDestEnc );
459cdf0e10cSrcweir 		rOutput << ";}";
460cdf0e10cSrcweir 	}
461cdf0e10cSrcweir 	rOutput << '}';
462cdf0e10cSrcweir 	rOutput << endl;
463cdf0e10cSrcweir 
464cdf0e10cSrcweir 	// ColorList rausschreiben...
465cdf0e10cSrcweir 	SvxColorList aColorList;
466cdf0e10cSrcweir 	sal_uInt32 i = 0;
467cdf0e10cSrcweir 	SvxColorItem* pColorItem = (SvxColorItem*)aEditDoc.GetItemPool().GetItem2( EE_CHAR_COLOR, i );
468cdf0e10cSrcweir 	while ( pColorItem )
469cdf0e10cSrcweir 	{
470cdf0e10cSrcweir 		sal_uInt32 nPos = i;
471cdf0e10cSrcweir 		if ( pColorItem->GetValue() == COL_AUTO )
472cdf0e10cSrcweir 			nPos = 0;
473cdf0e10cSrcweir 		aColorList.Insert( new SvxColorItem( *pColorItem ), nPos );
474cdf0e10cSrcweir 		pColorItem = (SvxColorItem*)aEditDoc.GetItemPool().GetItem2( EE_CHAR_COLOR, ++i );
475cdf0e10cSrcweir 	}
476cdf0e10cSrcweir 	aColorList.Insert( new SvxColorItem( (const SvxColorItem&)aEditDoc.GetItemPool().GetDefaultItem( EE_CHAR_COLOR) ), i );
477cdf0e10cSrcweir 
478cdf0e10cSrcweir 	rOutput << '{' << OOO_STRING_SVTOOLS_RTF_COLORTBL;
479cdf0e10cSrcweir 	for ( j = 0; j < aColorList.Count(); j++ )
480cdf0e10cSrcweir 	{
481cdf0e10cSrcweir 		pColorItem = aColorList.GetObject( j );
482cdf0e10cSrcweir 		if ( !j || ( pColorItem->GetValue() != COL_AUTO ) )
483cdf0e10cSrcweir 		{
484cdf0e10cSrcweir 			rOutput << OOO_STRING_SVTOOLS_RTF_RED;
485cdf0e10cSrcweir 			rOutput.WriteNumber( pColorItem->GetValue().GetRed() );
486cdf0e10cSrcweir 			rOutput << OOO_STRING_SVTOOLS_RTF_GREEN;
487cdf0e10cSrcweir 			rOutput.WriteNumber( pColorItem->GetValue().GetGreen() );
488cdf0e10cSrcweir 			rOutput << OOO_STRING_SVTOOLS_RTF_BLUE;
489cdf0e10cSrcweir 			rOutput.WriteNumber( pColorItem->GetValue().GetBlue() );
490cdf0e10cSrcweir 		}
491cdf0e10cSrcweir 		rOutput << ';';
492cdf0e10cSrcweir 	}
493cdf0e10cSrcweir 	rOutput << '}';
494cdf0e10cSrcweir 	rOutput << endl;
495cdf0e10cSrcweir 
496cdf0e10cSrcweir 	// StyleSheets...
497cdf0e10cSrcweir 	if ( GetStyleSheetPool() )
498cdf0e10cSrcweir 	{
499cdf0e10cSrcweir 		sal_uInt16 nStyles = (sal_uInt16)GetStyleSheetPool()->GetStyles().size();
500cdf0e10cSrcweir 		if ( nStyles )
501cdf0e10cSrcweir 		{
502cdf0e10cSrcweir 			rOutput << '{' << OOO_STRING_SVTOOLS_RTF_STYLESHEET;
503cdf0e10cSrcweir 
504cdf0e10cSrcweir 			for ( sal_uInt16 nStyle = 0; nStyle < nStyles; nStyle++ )
505cdf0e10cSrcweir 			{
506cdf0e10cSrcweir 
507cdf0e10cSrcweir 				SfxStyleSheet* pStyle = (SfxStyleSheet*)GetStyleSheetPool()->GetStyles()[ nStyle ].get();
508cdf0e10cSrcweir 
509cdf0e10cSrcweir 				rOutput << endl << '{' << OOO_STRING_SVTOOLS_RTF_S;
510cdf0e10cSrcweir 				sal_uInt16 nNumber = (sal_uInt16) (nStyle + 1);
511cdf0e10cSrcweir 				rOutput.WriteNumber( nNumber );
512cdf0e10cSrcweir 
513cdf0e10cSrcweir 				// Attribute, auch aus Parent!
514cdf0e10cSrcweir 				for ( sal_uInt16 nParAttr = EE_PARA_START; nParAttr <= EE_CHAR_END; nParAttr++ )
515cdf0e10cSrcweir 				{
516cdf0e10cSrcweir 					if ( pStyle->GetItemSet().GetItemState( nParAttr ) == SFX_ITEM_ON )
517cdf0e10cSrcweir 					{
518cdf0e10cSrcweir 						const SfxPoolItem& rItem = pStyle->GetItemSet().Get( nParAttr );
519cdf0e10cSrcweir 						WriteItemAsRTF( rItem, rOutput, 0, 0, aFontTable, aColorList );
520cdf0e10cSrcweir 					}
521cdf0e10cSrcweir 				}
522cdf0e10cSrcweir 
523cdf0e10cSrcweir 				// Parent...(nur wenn noetig)
524cdf0e10cSrcweir 				if ( pStyle->GetParent().Len() && ( pStyle->GetParent() != pStyle->GetName() ) )
525cdf0e10cSrcweir 				{
526cdf0e10cSrcweir 					SfxStyleSheet* pParent = (SfxStyleSheet*)GetStyleSheetPool()->Find( pStyle->GetParent(), pStyle->GetFamily() );
527cdf0e10cSrcweir 					DBG_ASSERT( pParent, "Parent nicht gefunden!" );
528cdf0e10cSrcweir 					rOutput << OOO_STRING_SVTOOLS_RTF_SBASEDON;
529cdf0e10cSrcweir 					nNumber = (sal_uInt16) getStylePos( GetStyleSheetPool()->GetStyles(), pParent ) + 1;
530cdf0e10cSrcweir 					rOutput.WriteNumber( nNumber );
531cdf0e10cSrcweir 				}
532cdf0e10cSrcweir 
533cdf0e10cSrcweir 				// Folgevorlage...(immer)
534cdf0e10cSrcweir 				SfxStyleSheet* pNext = pStyle;
535cdf0e10cSrcweir 				if ( pStyle->GetFollow().Len() && ( pStyle->GetFollow() != pStyle->GetName() ) )
536cdf0e10cSrcweir 					pNext = (SfxStyleSheet*)GetStyleSheetPool()->Find( pStyle->GetFollow(), pStyle->GetFamily() );
537cdf0e10cSrcweir 
538cdf0e10cSrcweir 				DBG_ASSERT( pNext, "Naechsten nicht gefunden!" );
539cdf0e10cSrcweir 				rOutput << OOO_STRING_SVTOOLS_RTF_SNEXT;
540cdf0e10cSrcweir 				nNumber = (sal_uInt16) getStylePos( GetStyleSheetPool()->GetStyles(), pNext ) + 1;
541cdf0e10cSrcweir 				rOutput.WriteNumber( nNumber );
542cdf0e10cSrcweir 
543cdf0e10cSrcweir 				// Namen der Vorlage...
544cdf0e10cSrcweir 				rOutput << " " << ByteString( pStyle->GetName(), eDestEnc ).GetBuffer();
545cdf0e10cSrcweir 				rOutput << ";}";
546cdf0e10cSrcweir 			}
547cdf0e10cSrcweir 			rOutput << '}';
548cdf0e10cSrcweir 			rOutput << endl;
549cdf0e10cSrcweir 		}
550cdf0e10cSrcweir 	}
551cdf0e10cSrcweir 
552cdf0e10cSrcweir 	// Die Pool-Defaults vorweg schreiben...
553cdf0e10cSrcweir 	rOutput << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE << "\\EditEnginePoolDefaults";
554cdf0e10cSrcweir 	for ( sal_uInt16 nPoolDefItem = EE_PARA_START; nPoolDefItem <= EE_CHAR_END; nPoolDefItem++)
555cdf0e10cSrcweir 	{
556cdf0e10cSrcweir 		const SfxPoolItem& rItem = aEditDoc.GetItemPool().GetDefaultItem( nPoolDefItem );
557cdf0e10cSrcweir 		WriteItemAsRTF( rItem, rOutput, 0, 0, aFontTable, aColorList );
558cdf0e10cSrcweir 	}
559cdf0e10cSrcweir 	rOutput << '}' << endl;
560cdf0e10cSrcweir 
561cdf0e10cSrcweir 	// Def-Hoehe vorweg, da sonst 12Pt
562cdf0e10cSrcweir 	// Doch nicht, onst in jedem Absatz hart!
563cdf0e10cSrcweir 	// SfxItemSet aTmpSet( GetEmptyItemSet() );
564cdf0e10cSrcweir 	// const SvxFontHeightItem& rDefFontHeight = (const SvxFontHeightItem&)aTmpSet.Get( EE_CHAR_FONTHEIGHT );
565cdf0e10cSrcweir 	// WriteItemAsRTF( rDefFontHeight, rOutput, aFontTable, aColorList );
566cdf0e10cSrcweir 	// rOutput << '{' << OOO_STRING_SVTOOLS_RTF_IGNORE << "\\EditEnginePoolDefaultHeight}" << endl;
567cdf0e10cSrcweir 
568cdf0e10cSrcweir 	// DefTab:
569cdf0e10cSrcweir 	MapMode aTwpMode( MAP_TWIP );
570cdf0e10cSrcweir 	sal_uInt16 nDefTabTwps = (sal_uInt16) GetRefDevice()->LogicToLogic(
571cdf0e10cSrcweir 										Point( aEditDoc.GetDefTab(), 0 ),
572cdf0e10cSrcweir 										&GetRefMapMode(), &aTwpMode ).X();
573cdf0e10cSrcweir 	rOutput << OOO_STRING_SVTOOLS_RTF_DEFTAB;
574cdf0e10cSrcweir 	rOutput.WriteNumber( nDefTabTwps );
575cdf0e10cSrcweir 	rOutput << endl;
576cdf0e10cSrcweir 
577cdf0e10cSrcweir 	// ueber die Absaetze iterieren...
578cdf0e10cSrcweir 	rOutput << '{' << endl;
579*7a980842SDamjanJovanovic 	for ( sal_uInt32 nNode = nStartNode; nNode <= nEndNode; nNode++  )
580cdf0e10cSrcweir 	{
581cdf0e10cSrcweir 		ContentNode* pNode = aEditDoc.SaveGetObject( nNode );
582cdf0e10cSrcweir 		DBG_ASSERT( pNode, "Node nicht gefunden: Search&Replace" );
583cdf0e10cSrcweir 
584cdf0e10cSrcweir 		// Die Absatzattribute vorweg...
585cdf0e10cSrcweir 		sal_Bool bAttr = sal_False;
586cdf0e10cSrcweir 
587cdf0e10cSrcweir 		// Vorlage ?
588cdf0e10cSrcweir 		if ( pNode->GetStyleSheet() )
589cdf0e10cSrcweir 		{
590cdf0e10cSrcweir 			// Nummer der Vorlage
591cdf0e10cSrcweir 			rOutput << OOO_STRING_SVTOOLS_RTF_S;
592cdf0e10cSrcweir 			sal_uInt16 nNumber = (sal_uInt16) getStylePos( GetStyleSheetPool()->GetStyles(), pNode->GetStyleSheet() ) + 1;
593cdf0e10cSrcweir 			rOutput.WriteNumber( nNumber );
594cdf0e10cSrcweir 
595cdf0e10cSrcweir 			// Alle Attribute
596cdf0e10cSrcweir 			// Attribute, auch aus Parent!
597cdf0e10cSrcweir 			for ( sal_uInt16 nParAttr = EE_PARA_START; nParAttr <= EE_CHAR_END; nParAttr++ )
598cdf0e10cSrcweir 			{
599cdf0e10cSrcweir 				if ( pNode->GetStyleSheet()->GetItemSet().GetItemState( nParAttr ) == SFX_ITEM_ON )
600cdf0e10cSrcweir 				{
601cdf0e10cSrcweir 					const SfxPoolItem& rItem = pNode->GetStyleSheet()->GetItemSet().Get( nParAttr );
602cdf0e10cSrcweir 					WriteItemAsRTF( rItem, rOutput, nNode, 0, aFontTable, aColorList );
603cdf0e10cSrcweir 					bAttr = sal_True;
604cdf0e10cSrcweir 				}
605cdf0e10cSrcweir 			}
606cdf0e10cSrcweir 		}
607cdf0e10cSrcweir 
608cdf0e10cSrcweir 		for ( sal_uInt16 nParAttr = EE_PARA_START; nParAttr <= EE_CHAR_END; nParAttr++ )
609cdf0e10cSrcweir 		{
610cdf0e10cSrcweir //			const SfxPoolItem& rItem = pNode->GetContentAttribs().GetItem( nParAttr );
611cdf0e10cSrcweir 			// Jetzt, wo StyleSheet-Verarbeitung, nur noch harte Absatzattribute!
612cdf0e10cSrcweir 			if ( pNode->GetContentAttribs().GetItems().GetItemState( nParAttr ) == SFX_ITEM_ON )
613cdf0e10cSrcweir 			{
614cdf0e10cSrcweir 				const SfxPoolItem& rItem = pNode->GetContentAttribs().GetItems().Get( nParAttr );
615cdf0e10cSrcweir 				WriteItemAsRTF( rItem, rOutput, nNode, 0, aFontTable, aColorList );
616cdf0e10cSrcweir 				bAttr = sal_True;
617cdf0e10cSrcweir 			}
618cdf0e10cSrcweir 		}
619cdf0e10cSrcweir 		if ( bAttr )
620cdf0e10cSrcweir 			rOutput << ' ';	// Separator
621cdf0e10cSrcweir 
622cdf0e10cSrcweir 		ItemList aAttribItems;
623cdf0e10cSrcweir 		ParaPortion* pParaPortion = FindParaPortion( pNode );
624cdf0e10cSrcweir 		DBG_ASSERT( pParaPortion, "Portion nicht gefunden: WriteRTF" );
625cdf0e10cSrcweir 
626cdf0e10cSrcweir 		sal_uInt16 nIndex = 0;
627cdf0e10cSrcweir 		sal_uInt16 nStartPos = 0;
628cdf0e10cSrcweir 		sal_uInt16 nEndPos = pNode->Len();
629cdf0e10cSrcweir 		sal_uInt16 nStartPortion = 0;
630cdf0e10cSrcweir 		sal_uInt16 nEndPortion = (sal_uInt16)pParaPortion->GetTextPortions().Count() - 1;
631cdf0e10cSrcweir 		sal_Bool bFinishPortion = sal_False;
632cdf0e10cSrcweir 		sal_uInt16 nPortionStart;
633cdf0e10cSrcweir 
634cdf0e10cSrcweir 		if ( nNode == nStartNode )
635cdf0e10cSrcweir 		{
636cdf0e10cSrcweir 			nStartPos = aSel.Min().GetIndex();
637cdf0e10cSrcweir 			nStartPortion = pParaPortion->GetTextPortions().FindPortion( nStartPos, nPortionStart );
638cdf0e10cSrcweir 			if ( nStartPos != 0 )
639cdf0e10cSrcweir 			{
640cdf0e10cSrcweir 				aAttribItems.Clear();
641cdf0e10cSrcweir                 lcl_FindValidAttribs( aAttribItems, pNode, nStartPos, GetScriptType( EditPaM( pNode, 0 ) ) );
642cdf0e10cSrcweir 				if ( aAttribItems.Count() )
643cdf0e10cSrcweir 				{
644cdf0e10cSrcweir 					// Diese Attribute duerfen nicht fuer den gesamten
645cdf0e10cSrcweir 					// Absatz gelten:
646cdf0e10cSrcweir 					rOutput << '{';
647cdf0e10cSrcweir 					WriteItemListAsRTF( aAttribItems, rOutput, nNode, nStartPos, aFontTable, aColorList );
648cdf0e10cSrcweir 					bFinishPortion = sal_True;
649cdf0e10cSrcweir 				}
650cdf0e10cSrcweir 				aAttribItems.Clear();
651cdf0e10cSrcweir 			}
652cdf0e10cSrcweir 		}
653cdf0e10cSrcweir 		if ( nNode == nEndNode ) // kann auch == nStart sein!
654cdf0e10cSrcweir 		{
655cdf0e10cSrcweir 			nEndPos = aSel.Max().GetIndex();
656cdf0e10cSrcweir 			nEndPortion = pParaPortion->GetTextPortions().FindPortion( nEndPos, nPortionStart );
657cdf0e10cSrcweir 		}
658cdf0e10cSrcweir 
659cdf0e10cSrcweir 		EditCharAttrib* pNextFeature = pNode->GetCharAttribs().FindFeature( nIndex );
660cdf0e10cSrcweir 		// Bei 0 anfangen, damit der Index richtig ist...
661cdf0e10cSrcweir 
662cdf0e10cSrcweir 		for ( sal_uInt16 n = 0; n <= nEndPortion; n++ )
663cdf0e10cSrcweir 		{
664cdf0e10cSrcweir 			TextPortion* pTextPortion = pParaPortion->GetTextPortions().GetObject(n);
665cdf0e10cSrcweir 			if ( n < nStartPortion )
666cdf0e10cSrcweir 			{
667cdf0e10cSrcweir 				nIndex = nIndex + pTextPortion->GetLen();
668cdf0e10cSrcweir 				continue;
669cdf0e10cSrcweir 			}
670cdf0e10cSrcweir 
671cdf0e10cSrcweir 			if ( pNextFeature && ( pNextFeature->GetStart() == nIndex ) && ( pNextFeature->GetItem()->Which() != EE_FEATURE_FIELD ) )
672cdf0e10cSrcweir 			{
673cdf0e10cSrcweir 				WriteItemAsRTF( *pNextFeature->GetItem(), rOutput, nNode, nIndex, aFontTable, aColorList );
674cdf0e10cSrcweir 				pNextFeature = pNode->GetCharAttribs().FindFeature( pNextFeature->GetStart() + 1 );
675cdf0e10cSrcweir 			}
676cdf0e10cSrcweir 			else
677cdf0e10cSrcweir 			{
678cdf0e10cSrcweir 				aAttribItems.Clear();
679cdf0e10cSrcweir                 sal_uInt16 nScriptType = GetScriptType( EditPaM( pNode, nIndex+1 ) );
680cdf0e10cSrcweir                 if ( !n || IsScriptChange( EditPaM( pNode, nIndex ) ) )
681cdf0e10cSrcweir                 {
682cdf0e10cSrcweir                     SfxItemSet aAttribs = GetAttribs( nNode, nIndex+1, nIndex+1 );
683cdf0e10cSrcweir                     aAttribItems.Insert( &aAttribs.Get( GetScriptItemId( EE_CHAR_FONTINFO, nScriptType ) ), LIST_APPEND );
684cdf0e10cSrcweir                     aAttribItems.Insert( &aAttribs.Get( GetScriptItemId( EE_CHAR_FONTHEIGHT, nScriptType ) ), LIST_APPEND );
685cdf0e10cSrcweir                     aAttribItems.Insert( &aAttribs.Get( GetScriptItemId( EE_CHAR_WEIGHT, nScriptType ) ), LIST_APPEND );
686cdf0e10cSrcweir                     aAttribItems.Insert( &aAttribs.Get( GetScriptItemId( EE_CHAR_ITALIC, nScriptType ) ), LIST_APPEND );
687cdf0e10cSrcweir                     aAttribItems.Insert( &aAttribs.Get( GetScriptItemId( EE_CHAR_LANGUAGE, nScriptType ) ), LIST_APPEND );
688cdf0e10cSrcweir                 }
689cdf0e10cSrcweir                 // #96298# Insert hard attribs AFTER CJK attribs...
690cdf0e10cSrcweir 				lcl_FindValidAttribs( aAttribItems, pNode, nIndex, nScriptType );
691cdf0e10cSrcweir 
692cdf0e10cSrcweir 				rOutput << '{';
693cdf0e10cSrcweir 				if ( WriteItemListAsRTF( aAttribItems, rOutput, nNode, nIndex, aFontTable, aColorList ) )
694cdf0e10cSrcweir 					rOutput << ' ';
695cdf0e10cSrcweir 
696cdf0e10cSrcweir 				sal_uInt16 nS = nIndex;
697cdf0e10cSrcweir 				sal_uInt16 nE = nIndex + pTextPortion->GetLen();
698cdf0e10cSrcweir 				if ( n == nStartPortion )
699cdf0e10cSrcweir 					nS = nStartPos;
700cdf0e10cSrcweir 				if ( n == nEndPortion )
701cdf0e10cSrcweir 					nE = nEndPos;
702cdf0e10cSrcweir 
703cdf0e10cSrcweir 				XubString aRTFStr = aEditDoc.GetParaAsString( pNode, nS, nE);
704cdf0e10cSrcweir 				RTFOutFuncs::Out_String( rOutput, aRTFStr, eDestEnc );
705cdf0e10cSrcweir 				rOutput << '}';
706cdf0e10cSrcweir 			}
707cdf0e10cSrcweir 			if ( bFinishPortion )
708cdf0e10cSrcweir 			{
709cdf0e10cSrcweir 				rOutput << '}';
710cdf0e10cSrcweir 				bFinishPortion = sal_False;
711cdf0e10cSrcweir 			}
712cdf0e10cSrcweir 
713cdf0e10cSrcweir 			nIndex = nIndex + pTextPortion->GetLen();
714cdf0e10cSrcweir 		}
715cdf0e10cSrcweir 
716cdf0e10cSrcweir 		rOutput << OOO_STRING_SVTOOLS_RTF_PAR << OOO_STRING_SVTOOLS_RTF_PARD << OOO_STRING_SVTOOLS_RTF_PLAIN;;
717cdf0e10cSrcweir 		rOutput << endl;
718cdf0e10cSrcweir 	}
719cdf0e10cSrcweir 	// RTF-Nachspann...
720cdf0e10cSrcweir 	rOutput << "}}";	// 1xKlammerung Absaetze, 1x Klammerung RTF-Dokument
721cdf0e10cSrcweir 	rOutput.Flush();
722cdf0e10cSrcweir 
723cdf0e10cSrcweir #if defined (EDITDEBUG) && !defined( UNX )
724cdf0e10cSrcweir     {
725cdf0e10cSrcweir         SvFileStream aStream( String( RTL_CONSTASCII_USTRINGPARAM ( "d:\\rtf_out.rtf" ) ), STREAM_WRITE|STREAM_TRUNC );
726cdf0e10cSrcweir         sal_uLong nP = rOutput.Tell();
727cdf0e10cSrcweir         rOutput.Seek( 0 );
728cdf0e10cSrcweir         aStream << rOutput;
729cdf0e10cSrcweir         rOutput.Seek( nP );
730cdf0e10cSrcweir     }
731cdf0e10cSrcweir #endif
732cdf0e10cSrcweir 
733cdf0e10cSrcweir 	return rOutput.GetError();
734cdf0e10cSrcweir #else
735cdf0e10cSrcweir 	return 0;
736cdf0e10cSrcweir #endif
737cdf0e10cSrcweir }
738cdf0e10cSrcweir 
739cdf0e10cSrcweir 
WriteItemAsRTF(const SfxPoolItem & rItem,SvStream & rOutput,sal_uInt32 nPara,sal_uInt16 nPos,SvxFontTable & rFontTable,SvxColorList & rColorList)740*7a980842SDamjanJovanovic void ImpEditEngine::WriteItemAsRTF( const SfxPoolItem& rItem, SvStream& rOutput, sal_uInt32 nPara, sal_uInt16 nPos,
741cdf0e10cSrcweir 							SvxFontTable& rFontTable, SvxColorList& rColorList )
742cdf0e10cSrcweir {
743cdf0e10cSrcweir 	sal_uInt16 nWhich = rItem.Which();
744cdf0e10cSrcweir 	switch ( nWhich )
745cdf0e10cSrcweir 	{
746cdf0e10cSrcweir         case EE_PARA_WRITINGDIR:
747cdf0e10cSrcweir         {
748cdf0e10cSrcweir             const SvxFrameDirectionItem& rWritingMode = (const SvxFrameDirectionItem&)rItem;
749cdf0e10cSrcweir             if ( rWritingMode.GetValue() == FRMDIR_HORI_RIGHT_TOP )
750cdf0e10cSrcweir                 rOutput << "\\rtlpar";
751cdf0e10cSrcweir             else
752cdf0e10cSrcweir                 rOutput << "\\ltrpar";
753cdf0e10cSrcweir         }
754cdf0e10cSrcweir         break;
755cdf0e10cSrcweir 		case EE_PARA_OUTLLEVEL:
756cdf0e10cSrcweir 		{
757cdf0e10cSrcweir 			sal_Int16 nLevel = ((const SfxInt16Item&)rItem).GetValue();
758cdf0e10cSrcweir 			if( nLevel >= 0 )
759cdf0e10cSrcweir 			{
760cdf0e10cSrcweir 				rOutput << "\\level";
761cdf0e10cSrcweir 				rOutput.WriteNumber( nLevel );
762cdf0e10cSrcweir 			}
763cdf0e10cSrcweir 		}
764cdf0e10cSrcweir 		break;
765cdf0e10cSrcweir 		case EE_PARA_OUTLLRSPACE:
766cdf0e10cSrcweir 		case EE_PARA_LRSPACE:
767cdf0e10cSrcweir 		{
768cdf0e10cSrcweir //            const ContentNode *pNode = aEditDoc.GetObject( nPara );
769cdf0e10cSrcweir 
770cdf0e10cSrcweir 			rOutput << OOO_STRING_SVTOOLS_RTF_FI;
771cdf0e10cSrcweir 			short nTxtFirst = ((const SvxLRSpaceItem&)rItem).GetTxtFirstLineOfst();
772cdf0e10cSrcweir 			nTxtFirst = (short)LogicToTwips( nTxtFirst );
773cdf0e10cSrcweir 			rOutput.WriteNumber( nTxtFirst );
774cdf0e10cSrcweir 			rOutput << OOO_STRING_SVTOOLS_RTF_LI;
775cdf0e10cSrcweir             sal_uInt16 nTxtLeft = static_cast< sal_uInt16 >(((const SvxLRSpaceItem&)rItem).GetTxtLeft());
776cdf0e10cSrcweir 			nTxtLeft = (sal_uInt16)LogicToTwips( nTxtLeft );
777cdf0e10cSrcweir 			rOutput.WriteNumber( nTxtLeft );
778cdf0e10cSrcweir 			rOutput << OOO_STRING_SVTOOLS_RTF_RI;
779cdf0e10cSrcweir 			sal_uInt32 nTxtRight = ((const SvxLRSpaceItem&)rItem).GetRight();
780cdf0e10cSrcweir 			nTxtRight = LogicToTwips( nTxtRight);
781cdf0e10cSrcweir 			rOutput.WriteNumber( nTxtRight );
782cdf0e10cSrcweir 		}
783cdf0e10cSrcweir 		break;
784cdf0e10cSrcweir 		case EE_PARA_ULSPACE:
785cdf0e10cSrcweir 		{
786cdf0e10cSrcweir 			rOutput << OOO_STRING_SVTOOLS_RTF_SB;
787cdf0e10cSrcweir 			sal_uInt16 nUpper = ((const SvxULSpaceItem&)rItem).GetUpper();
788cdf0e10cSrcweir 			nUpper = (sal_uInt16)LogicToTwips( nUpper );
789cdf0e10cSrcweir 			rOutput.WriteNumber( nUpper );
790cdf0e10cSrcweir 			rOutput << OOO_STRING_SVTOOLS_RTF_SA;
791cdf0e10cSrcweir 			sal_uInt16 nLower = ((const SvxULSpaceItem&)rItem).GetLower();
792cdf0e10cSrcweir 			nLower = (sal_uInt16)LogicToTwips( nLower );
793cdf0e10cSrcweir 			rOutput.WriteNumber( nLower );
794cdf0e10cSrcweir 		}
795cdf0e10cSrcweir 		break;
796cdf0e10cSrcweir 		case EE_PARA_SBL:
797cdf0e10cSrcweir 		{
798cdf0e10cSrcweir 			rOutput << OOO_STRING_SVTOOLS_RTF_SL;
799cdf0e10cSrcweir 			long nVal = ((const SvxLineSpacingItem&)rItem).GetLineHeight();
800cdf0e10cSrcweir             char cMult = '0';
801cdf0e10cSrcweir 			if ( ((const SvxLineSpacingItem&)rItem).GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_PROP )
802cdf0e10cSrcweir 			{
803cdf0e10cSrcweir 				// Woher kriege ich jetzt den Wert?
804cdf0e10cSrcweir 				// Der SwRTF-Parser geht von einem 240er Font aus!
805cdf0e10cSrcweir 				nVal = ((const SvxLineSpacingItem&)rItem).GetPropLineSpace();
806cdf0e10cSrcweir 				nVal *= 240;
807cdf0e10cSrcweir 				nVal /= 100;
808cdf0e10cSrcweir                 cMult = '1';
809cdf0e10cSrcweir 			}
810cdf0e10cSrcweir 			rOutput.WriteNumber( nVal );
811cdf0e10cSrcweir             rOutput << OOO_STRING_SVTOOLS_RTF_SLMULT << cMult;
812cdf0e10cSrcweir 		}
813cdf0e10cSrcweir 		break;
814cdf0e10cSrcweir 		case EE_PARA_JUST:
815cdf0e10cSrcweir 		{
816cdf0e10cSrcweir 			SvxAdjust eJustification = ((const SvxAdjustItem&)rItem).GetAdjust();
817cdf0e10cSrcweir 			switch ( eJustification )
818cdf0e10cSrcweir 			{
819cdf0e10cSrcweir 				case SVX_ADJUST_CENTER:	rOutput << OOO_STRING_SVTOOLS_RTF_QC;
820cdf0e10cSrcweir 										break;
821cdf0e10cSrcweir 				case SVX_ADJUST_RIGHT:	rOutput << OOO_STRING_SVTOOLS_RTF_QR;
822cdf0e10cSrcweir 										break;
823cdf0e10cSrcweir 				default:				rOutput << OOO_STRING_SVTOOLS_RTF_QL;
824cdf0e10cSrcweir 										break;
825cdf0e10cSrcweir 			}
826cdf0e10cSrcweir 		}
827cdf0e10cSrcweir 		break;
828cdf0e10cSrcweir 		case EE_PARA_TABS:
829cdf0e10cSrcweir 		{
830cdf0e10cSrcweir 			const SvxTabStopItem& rTabs = (const SvxTabStopItem&) rItem;
831cdf0e10cSrcweir 			for ( sal_uInt16 i = 0; i < rTabs.Count(); i++ )
832cdf0e10cSrcweir 			{
833cdf0e10cSrcweir 				const SvxTabStop& rTab = rTabs[i];
834cdf0e10cSrcweir 				rOutput << OOO_STRING_SVTOOLS_RTF_TX;
835cdf0e10cSrcweir 				rOutput.WriteNumber( LogicToTwips( rTab.GetTabPos() ) );
836cdf0e10cSrcweir 			}
837cdf0e10cSrcweir 		}
838cdf0e10cSrcweir 		break;
839cdf0e10cSrcweir 		case EE_CHAR_COLOR:
840cdf0e10cSrcweir 		{
841cdf0e10cSrcweir 			sal_uInt32 n = rColorList.GetId( (const SvxColorItem&)rItem );
842cdf0e10cSrcweir 			rOutput << OOO_STRING_SVTOOLS_RTF_CF;
843cdf0e10cSrcweir 			rOutput.WriteNumber( n );
844cdf0e10cSrcweir 		}
845cdf0e10cSrcweir 		break;
846cdf0e10cSrcweir 		case EE_CHAR_FONTINFO:
847cdf0e10cSrcweir 		case EE_CHAR_FONTINFO_CJK:
848cdf0e10cSrcweir 		case EE_CHAR_FONTINFO_CTL:
849cdf0e10cSrcweir 		{
850cdf0e10cSrcweir 			sal_uInt32 n = rFontTable.GetId( (const SvxFontItem&)rItem );
851cdf0e10cSrcweir 			rOutput << OOO_STRING_SVTOOLS_RTF_F;
852cdf0e10cSrcweir 			rOutput.WriteNumber( n );
853cdf0e10cSrcweir 		}
854cdf0e10cSrcweir 		break;
855cdf0e10cSrcweir 		case EE_CHAR_FONTHEIGHT:
856cdf0e10cSrcweir 		case EE_CHAR_FONTHEIGHT_CJK:
857cdf0e10cSrcweir 		case EE_CHAR_FONTHEIGHT_CTL:
858cdf0e10cSrcweir 		{
859cdf0e10cSrcweir 			rOutput << OOO_STRING_SVTOOLS_RTF_FS;
860cdf0e10cSrcweir 			long nHeight = ((const SvxFontHeightItem&)rItem).GetHeight();
861cdf0e10cSrcweir 			nHeight = LogicToTwips( nHeight );
862cdf0e10cSrcweir 			// Twips => HalfPoints
863cdf0e10cSrcweir 			nHeight /= 10;
864cdf0e10cSrcweir 			rOutput.WriteNumber( nHeight );
865cdf0e10cSrcweir 		}
866cdf0e10cSrcweir 		break;
867cdf0e10cSrcweir 		case EE_CHAR_WEIGHT:
868cdf0e10cSrcweir 		case EE_CHAR_WEIGHT_CJK:
869cdf0e10cSrcweir 		case EE_CHAR_WEIGHT_CTL:
870cdf0e10cSrcweir 		{
871cdf0e10cSrcweir 			FontWeight e = ((const SvxWeightItem&)rItem).GetWeight();
872cdf0e10cSrcweir 			switch ( e )
873cdf0e10cSrcweir 			{
874cdf0e10cSrcweir 				case WEIGHT_BOLD:	rOutput << OOO_STRING_SVTOOLS_RTF_B;				break;
875cdf0e10cSrcweir 				default:			rOutput << OOO_STRING_SVTOOLS_RTF_B << '0';		break;
876cdf0e10cSrcweir 			}
877cdf0e10cSrcweir 		}
878cdf0e10cSrcweir 		break;
879cdf0e10cSrcweir 		case EE_CHAR_UNDERLINE:
880cdf0e10cSrcweir 		{
881cdf0e10cSrcweir 			// muesste bei WordLineMode ggf. ulw werden,
882cdf0e10cSrcweir 			// aber die Information fehlt hier
883cdf0e10cSrcweir 			FontUnderline e = ((const SvxUnderlineItem&)rItem).GetLineStyle();
884cdf0e10cSrcweir 			switch ( e )
885cdf0e10cSrcweir 			{
886cdf0e10cSrcweir 				case UNDERLINE_NONE:	rOutput << OOO_STRING_SVTOOLS_RTF_ULNONE;		break;
887cdf0e10cSrcweir 				case UNDERLINE_SINGLE:	rOutput << OOO_STRING_SVTOOLS_RTF_UL; 		break;
888cdf0e10cSrcweir 				case UNDERLINE_DOUBLE:	rOutput << OOO_STRING_SVTOOLS_RTF_ULDB;		break;
889cdf0e10cSrcweir 				case UNDERLINE_DOTTED:	rOutput << OOO_STRING_SVTOOLS_RTF_ULD;		break;
890cdf0e10cSrcweir 				default:
891cdf0e10cSrcweir 					break;
892cdf0e10cSrcweir 			}
893cdf0e10cSrcweir 		}
894cdf0e10cSrcweir 		break;
895cdf0e10cSrcweir 		case EE_CHAR_OVERLINE:
896cdf0e10cSrcweir 		{
897cdf0e10cSrcweir 			FontUnderline e = ((const SvxOverlineItem&)rItem).GetLineStyle();
898cdf0e10cSrcweir 			switch ( e )
899cdf0e10cSrcweir 			{
900cdf0e10cSrcweir 				case UNDERLINE_NONE:	rOutput << OOO_STRING_SVTOOLS_RTF_OLNONE;		break;
901cdf0e10cSrcweir 				case UNDERLINE_SINGLE:	rOutput << OOO_STRING_SVTOOLS_RTF_OL; 		break;
902cdf0e10cSrcweir 				case UNDERLINE_DOUBLE:	rOutput << OOO_STRING_SVTOOLS_RTF_OLDB;		break;
903cdf0e10cSrcweir 				case UNDERLINE_DOTTED:	rOutput << OOO_STRING_SVTOOLS_RTF_OLD;		break;
904cdf0e10cSrcweir 				default:
905cdf0e10cSrcweir 					break;
906cdf0e10cSrcweir 			}
907cdf0e10cSrcweir 		}
908cdf0e10cSrcweir 		break;
909cdf0e10cSrcweir 		case EE_CHAR_STRIKEOUT:
910cdf0e10cSrcweir 		{
911cdf0e10cSrcweir 			FontStrikeout e = ((const SvxCrossedOutItem&)rItem).GetStrikeout();
912cdf0e10cSrcweir 			switch ( e )
913cdf0e10cSrcweir 			{
914cdf0e10cSrcweir 				case STRIKEOUT_SINGLE:
915cdf0e10cSrcweir 				case STRIKEOUT_DOUBLE:	rOutput << OOO_STRING_SVTOOLS_RTF_STRIKE; 		break;
916cdf0e10cSrcweir 				case STRIKEOUT_NONE:	rOutput << OOO_STRING_SVTOOLS_RTF_STRIKE << '0';	break;
917cdf0e10cSrcweir 				default:
918cdf0e10cSrcweir 					break;
919cdf0e10cSrcweir 			}
920cdf0e10cSrcweir 		}
921cdf0e10cSrcweir 		break;
922cdf0e10cSrcweir 		case EE_CHAR_ITALIC:
923cdf0e10cSrcweir 		case EE_CHAR_ITALIC_CJK:
924cdf0e10cSrcweir 		case EE_CHAR_ITALIC_CTL:
925cdf0e10cSrcweir 		{
926cdf0e10cSrcweir 			FontItalic e = ((const SvxPostureItem&)rItem).GetPosture();
927cdf0e10cSrcweir 			switch ( e )
928cdf0e10cSrcweir 			{
929cdf0e10cSrcweir 				case ITALIC_OBLIQUE:
930cdf0e10cSrcweir 				case ITALIC_NORMAL:	rOutput << OOO_STRING_SVTOOLS_RTF_I; 		break;
931cdf0e10cSrcweir 				case ITALIC_NONE:	rOutput << OOO_STRING_SVTOOLS_RTF_I << '0';	break;
932cdf0e10cSrcweir 				default:
933cdf0e10cSrcweir 					break;
934cdf0e10cSrcweir 			}
935cdf0e10cSrcweir 		}
936cdf0e10cSrcweir 		break;
937cdf0e10cSrcweir 		case EE_CHAR_OUTLINE:
938cdf0e10cSrcweir 		{
939cdf0e10cSrcweir 			rOutput << OOO_STRING_SVTOOLS_RTF_OUTL;
940cdf0e10cSrcweir 			if ( ((const SvxContourItem&)rItem).GetValue() == 0 )
941cdf0e10cSrcweir 				rOutput << '0';
942cdf0e10cSrcweir 		}
943cdf0e10cSrcweir 		break;
944cdf0e10cSrcweir 		case EE_CHAR_RELIEF:
945cdf0e10cSrcweir 		{
946cdf0e10cSrcweir 			sal_uInt16 nRelief = ((const SvxCharReliefItem&)rItem).GetValue();
947cdf0e10cSrcweir 			if ( nRelief == RELIEF_EMBOSSED )
948cdf0e10cSrcweir 				rOutput << OOO_STRING_SVTOOLS_RTF_EMBO;
949cdf0e10cSrcweir 			if ( nRelief == RELIEF_ENGRAVED )
950cdf0e10cSrcweir 				rOutput << OOO_STRING_SVTOOLS_RTF_IMPR;
951cdf0e10cSrcweir 		}
952cdf0e10cSrcweir 		break;
953cdf0e10cSrcweir 		case EE_CHAR_EMPHASISMARK:
954cdf0e10cSrcweir 		{
955cdf0e10cSrcweir 			sal_uInt16 nMark = ((const SvxEmphasisMarkItem&)rItem).GetValue();
956cdf0e10cSrcweir 			if ( nMark == EMPHASISMARK_NONE )
957cdf0e10cSrcweir 				rOutput << OOO_STRING_SVTOOLS_RTF_ACCNONE;
958cdf0e10cSrcweir 			else if ( nMark == EMPHASISMARK_SIDE_DOTS )
959cdf0e10cSrcweir 				rOutput << OOO_STRING_SVTOOLS_RTF_ACCCOMMA;
960cdf0e10cSrcweir 			else
961cdf0e10cSrcweir 				rOutput << OOO_STRING_SVTOOLS_RTF_ACCDOT;
962cdf0e10cSrcweir 		}
963cdf0e10cSrcweir 		break;
964cdf0e10cSrcweir 		case EE_CHAR_SHADOW:
965cdf0e10cSrcweir 		{
966cdf0e10cSrcweir 			rOutput << OOO_STRING_SVTOOLS_RTF_SHAD;
967cdf0e10cSrcweir 			if ( ((const SvxShadowedItem&)rItem).GetValue() == 0 )
968cdf0e10cSrcweir 				rOutput << '0';
969cdf0e10cSrcweir 		}
970cdf0e10cSrcweir 		break;
971cdf0e10cSrcweir 		case EE_FEATURE_TAB:
972cdf0e10cSrcweir 		{
973cdf0e10cSrcweir 			rOutput << OOO_STRING_SVTOOLS_RTF_TAB;
974cdf0e10cSrcweir 		}
975cdf0e10cSrcweir 		break;
976cdf0e10cSrcweir 		case EE_FEATURE_LINEBR:
977cdf0e10cSrcweir 		{
978cdf0e10cSrcweir 			rOutput << OOO_STRING_SVTOOLS_RTF_SL;
979cdf0e10cSrcweir 		}
980cdf0e10cSrcweir 		break;
981cdf0e10cSrcweir 		case EE_CHAR_KERNING:
982cdf0e10cSrcweir 		{
983cdf0e10cSrcweir 			rOutput << OOO_STRING_SVTOOLS_RTF_EXPNDTW;
984cdf0e10cSrcweir 			rOutput.WriteNumber( LogicToTwips(
985cdf0e10cSrcweir 				((const SvxKerningItem&)rItem).GetValue() ) );
986cdf0e10cSrcweir 		}
987cdf0e10cSrcweir 		break;
988cdf0e10cSrcweir 		case EE_CHAR_PAIRKERNING:
989cdf0e10cSrcweir 		{
990cdf0e10cSrcweir 			rOutput << OOO_STRING_SVTOOLS_RTF_KERNING;
991cdf0e10cSrcweir 			rOutput.WriteNumber( ((const SvxAutoKernItem&)rItem).GetValue() ? 1 : 0 );
992cdf0e10cSrcweir 		}
993cdf0e10cSrcweir 		break;
994cdf0e10cSrcweir 		case EE_CHAR_ESCAPEMENT:
995cdf0e10cSrcweir 		{
996cdf0e10cSrcweir 			SvxFont aFont;
997cdf0e10cSrcweir 			ContentNode* pNode = aEditDoc.GetObject( nPara );
998cdf0e10cSrcweir 			SeekCursor( pNode, nPos, aFont );
999cdf0e10cSrcweir 			MapMode aPntMode( MAP_POINT );
1000cdf0e10cSrcweir 			long nFontHeight = GetRefDevice()->LogicToLogic(
1001cdf0e10cSrcweir 					aFont.GetSize(), &GetRefMapMode(), &aPntMode ).Height();
1002cdf0e10cSrcweir 			nFontHeight *=2;	// HalfPoints
1003cdf0e10cSrcweir 			sal_uInt16 nProp = ((const SvxEscapementItem&)rItem).GetProp();
1004cdf0e10cSrcweir 			sal_uInt16 nProp100 = nProp*100;	// Fuer SWG-Token Prop in 100tel Prozent.
1005cdf0e10cSrcweir 			short nEsc = ((const SvxEscapementItem&)rItem).GetEsc();
1006cdf0e10cSrcweir 			if ( nEsc == DFLT_ESC_AUTO_SUPER )
1007cdf0e10cSrcweir 			{
1008cdf0e10cSrcweir 				nEsc = 100 - nProp;
1009cdf0e10cSrcweir 				nProp100++;	// Eine 1 hinten bedeutet 'automatisch'.
1010cdf0e10cSrcweir 			}
1011cdf0e10cSrcweir 			else if ( nEsc == DFLT_ESC_AUTO_SUB )
1012cdf0e10cSrcweir 			{
1013cdf0e10cSrcweir 				nEsc = sal::static_int_cast< short >( -( 100 - nProp ) );
1014cdf0e10cSrcweir 				nProp100++;
1015cdf0e10cSrcweir 			}
1016cdf0e10cSrcweir 			// SWG:
1017cdf0e10cSrcweir 			if ( nEsc )
1018cdf0e10cSrcweir 				rOutput << "{\\*\\updnprop" << ByteString::CreateFromInt32( nProp100 ).GetBuffer() << '}';
1019cdf0e10cSrcweir 			long nUpDown = nFontHeight * Abs( nEsc ) / 100;
1020cdf0e10cSrcweir 			ByteString aUpDown = ByteString::CreateFromInt32( nUpDown );
1021cdf0e10cSrcweir 			if ( nEsc < 0 )
1022cdf0e10cSrcweir 				rOutput << OOO_STRING_SVTOOLS_RTF_DN << aUpDown.GetBuffer();
1023cdf0e10cSrcweir 			else if ( nEsc > 0 )
1024cdf0e10cSrcweir 				rOutput << OOO_STRING_SVTOOLS_RTF_UP << aUpDown.GetBuffer();
1025cdf0e10cSrcweir 		}
1026cdf0e10cSrcweir 		break;
1027cdf0e10cSrcweir 	}
1028cdf0e10cSrcweir }
1029cdf0e10cSrcweir 
WriteHTML(SvStream &,EditSelection)1030cdf0e10cSrcweir sal_uInt32 ImpEditEngine::WriteHTML( SvStream&, EditSelection )
1031cdf0e10cSrcweir {
1032cdf0e10cSrcweir 	return 0;
1033cdf0e10cSrcweir }
1034cdf0e10cSrcweir 
1035cdf0e10cSrcweir 
CreateTextObject()1036cdf0e10cSrcweir EditTextObject*	ImpEditEngine::CreateTextObject()
1037cdf0e10cSrcweir {
1038cdf0e10cSrcweir 	EditSelection aCompleteSelection;
1039cdf0e10cSrcweir 	aCompleteSelection.Min() = aEditDoc.GetStartPaM();
1040cdf0e10cSrcweir 	aCompleteSelection.Max() = aEditDoc.GetEndPaM();
1041cdf0e10cSrcweir 
1042cdf0e10cSrcweir 	return CreateTextObject( aCompleteSelection );
1043cdf0e10cSrcweir }
1044cdf0e10cSrcweir 
CreateTextObject(EditSelection aSel)1045cdf0e10cSrcweir EditTextObject*	ImpEditEngine::CreateTextObject( EditSelection aSel )
1046cdf0e10cSrcweir {
1047cdf0e10cSrcweir 	return CreateBinTextObject( aSel, GetEditTextObjectPool(), aStatus.AllowBigObjects(), nBigTextObjectStart );
1048cdf0e10cSrcweir }
1049cdf0e10cSrcweir 
CreateBinTextObject(EditSelection aSel,SfxItemPool * pPool,sal_Bool bAllowBigObjects,sal_uInt16 nBigObjectStart) const1050cdf0e10cSrcweir EditTextObject*	ImpEditEngine::CreateBinTextObject( EditSelection aSel, SfxItemPool* pPool, sal_Bool bAllowBigObjects, sal_uInt16 nBigObjectStart ) const
1051cdf0e10cSrcweir {
1052cdf0e10cSrcweir 	BinTextObject* pTxtObj = new BinTextObject( pPool );
1053cdf0e10cSrcweir 	pTxtObj->SetVertical( IsVertical() );
1054cdf0e10cSrcweir 	MapUnit eMapUnit = (MapUnit)aEditDoc.GetItemPool().GetMetric( DEF_METRIC );
1055cdf0e10cSrcweir 	pTxtObj->SetMetric( (sal_uInt16) eMapUnit );
1056cdf0e10cSrcweir 	if ( pTxtObj->IsOwnerOfPool() )
1057cdf0e10cSrcweir 		pTxtObj->GetPool()->SetDefaultMetric( (SfxMapUnit) eMapUnit );
1058cdf0e10cSrcweir 
1059*7a980842SDamjanJovanovic 	sal_uInt32 nStartNode, nEndNode;
1060cdf0e10cSrcweir 	sal_uInt32 nTextPortions = 0;
1061cdf0e10cSrcweir 
1062cdf0e10cSrcweir 	aSel.Adjust( aEditDoc );
1063cdf0e10cSrcweir 	nStartNode = aEditDoc.GetPos( aSel.Min().GetNode() );
1064cdf0e10cSrcweir 	nEndNode = aEditDoc.GetPos( aSel.Max().GetNode() );
1065cdf0e10cSrcweir 
1066cdf0e10cSrcweir 	sal_Bool bOnlyFullParagraphs = ( aSel.Min().GetIndex() ||
1067cdf0e10cSrcweir 		( aSel.Max().GetIndex() < aSel.Max().GetNode()->Len() ) ) ?
1068cdf0e10cSrcweir 			sal_False : sal_True;
1069cdf0e10cSrcweir 
1070cdf0e10cSrcweir 	// Vorlagen werden nicht gespeichert!
1071cdf0e10cSrcweir 	// ( Nur Name und Familie, Vorlage selbst muss in App stehen! )
1072cdf0e10cSrcweir 
1073cdf0e10cSrcweir 	pTxtObj->SetScriptType( GetScriptType( aSel ) );
1074cdf0e10cSrcweir 
1075cdf0e10cSrcweir 	// ueber die Absaetze iterieren...
1076*7a980842SDamjanJovanovic 	sal_uInt32 nNode;
1077cdf0e10cSrcweir 	for ( nNode = nStartNode; nNode <= nEndNode; nNode++  )
1078cdf0e10cSrcweir 	{
1079cdf0e10cSrcweir 		ContentNode* pNode = aEditDoc.SaveGetObject( nNode );
1080cdf0e10cSrcweir 		DBG_ASSERT( pNode, "Node nicht gefunden: Search&Replace" );
1081cdf0e10cSrcweir 
1082cdf0e10cSrcweir 		if ( bOnlyFullParagraphs )
1083cdf0e10cSrcweir 		{
1084cdf0e10cSrcweir 			ParaPortion* pParaPortion = GetParaPortions()[nNode];
1085cdf0e10cSrcweir 			nTextPortions += pParaPortion->GetTextPortions().Count();
1086cdf0e10cSrcweir 		}
1087cdf0e10cSrcweir 
1088cdf0e10cSrcweir 		sal_uInt16 nStartPos = 0;
1089cdf0e10cSrcweir 		sal_uInt16 nEndPos = pNode->Len();
1090cdf0e10cSrcweir 
1091cdf0e10cSrcweir 		sal_Bool bEmptyPara = nEndPos ? sal_False : sal_True;
1092cdf0e10cSrcweir 
1093cdf0e10cSrcweir 		if ( ( nNode == nStartNode ) && !bOnlyFullParagraphs )
1094cdf0e10cSrcweir 			nStartPos = aSel.Min().GetIndex();
1095cdf0e10cSrcweir 		if ( ( nNode == nEndNode ) && !bOnlyFullParagraphs )
1096cdf0e10cSrcweir 			nEndPos = aSel.Max().GetIndex();
1097cdf0e10cSrcweir 
1098cdf0e10cSrcweir 
1099cdf0e10cSrcweir 		ContentInfo* pC = pTxtObj->CreateAndInsertContent();
1100cdf0e10cSrcweir 
1101cdf0e10cSrcweir 		// Die Absatzattribute...
1102cdf0e10cSrcweir 		pC->GetParaAttribs().Set( pNode->GetContentAttribs().GetItems() );
1103cdf0e10cSrcweir 
1104cdf0e10cSrcweir 		// Das StyleSheet...
1105cdf0e10cSrcweir 		if ( pNode->GetStyleSheet() )
1106cdf0e10cSrcweir 		{
1107cdf0e10cSrcweir 			pC->GetStyle() = pNode->GetStyleSheet()->GetName();
1108cdf0e10cSrcweir 			pC->GetFamily() = pNode->GetStyleSheet()->GetFamily();
1109cdf0e10cSrcweir 		}
1110cdf0e10cSrcweir 
1111cdf0e10cSrcweir 		// Der Text...
1112cdf0e10cSrcweir 		pC->GetText() = pNode->Copy( nStartPos, nEndPos-nStartPos );
1113cdf0e10cSrcweir 
1114cdf0e10cSrcweir 		// und die Attribute...
1115cdf0e10cSrcweir 		sal_uInt16 nAttr = 0;
1116cdf0e10cSrcweir 		EditCharAttrib* pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
1117cdf0e10cSrcweir 		while ( pAttr )
1118cdf0e10cSrcweir 		{
1119cdf0e10cSrcweir 			// In einem leeren Absatz die Attribute behalten!
1120cdf0e10cSrcweir 			if ( bEmptyPara ||
1121cdf0e10cSrcweir 				 ( ( pAttr->GetEnd() > nStartPos ) && ( pAttr->GetStart() < nEndPos ) ) )
1122cdf0e10cSrcweir 			{
1123cdf0e10cSrcweir 				XEditAttribute* pX = pTxtObj->CreateAttrib( *pAttr->GetItem(), pAttr->GetStart(), pAttr->GetEnd() );
1124cdf0e10cSrcweir 				// Evtl. korrigieren...
1125cdf0e10cSrcweir 				if ( ( nNode == nStartNode ) && ( nStartPos != 0 ) )
1126cdf0e10cSrcweir 				{
1127cdf0e10cSrcweir 					pX->GetStart() = ( pX->GetStart() > nStartPos ) ? pX->GetStart()-nStartPos : 0;
1128cdf0e10cSrcweir 					pX->GetEnd() = pX->GetEnd() - nStartPos;
1129cdf0e10cSrcweir 
1130cdf0e10cSrcweir 				}
1131cdf0e10cSrcweir 				if ( nNode == nEndNode )
1132cdf0e10cSrcweir 				{
1133cdf0e10cSrcweir 					if ( pX->GetEnd() > (nEndPos-nStartPos) )
1134cdf0e10cSrcweir 						pX->GetEnd() = nEndPos-nStartPos;
1135cdf0e10cSrcweir 				}
1136cdf0e10cSrcweir 				DBG_ASSERT( pX->GetEnd() <= (nEndPos-nStartPos), "CreateBinTextObject: Attribut zu lang!" );
1137cdf0e10cSrcweir 				if ( !pX->GetLen() && !bEmptyPara )
1138cdf0e10cSrcweir 					pTxtObj->DestroyAttrib( pX );
1139cdf0e10cSrcweir 				else
1140cdf0e10cSrcweir 					pC->GetAttribs().Insert( pX, pC->GetAttribs().Count() );
1141cdf0e10cSrcweir 			}
1142cdf0e10cSrcweir 			nAttr++;
1143cdf0e10cSrcweir 			pAttr = GetAttrib( pNode->GetCharAttribs().GetAttribs(), nAttr );
1144cdf0e10cSrcweir 		}
1145cdf0e10cSrcweir 
1146cdf0e10cSrcweir #ifndef SVX_LIGHT
1147cdf0e10cSrcweir 		// ggf. Online-Spelling
1148cdf0e10cSrcweir 		if ( bAllowBigObjects && bOnlyFullParagraphs && pNode->GetWrongList() )
1149cdf0e10cSrcweir 			pC->SetWrongList( pNode->GetWrongList()->Clone() );
1150cdf0e10cSrcweir #endif // !SVX_LIGHT
1151cdf0e10cSrcweir 
1152cdf0e10cSrcweir 	}
1153cdf0e10cSrcweir 
1154cdf0e10cSrcweir 	// Bei grossen Textobjekten die PortionInfos merken:
1155cdf0e10cSrcweir 	// Schwelle rauf setzen, wenn Olli die Absaetze nicht mehr zerhackt!
1156cdf0e10cSrcweir 	if ( bAllowBigObjects && bOnlyFullParagraphs && IsFormatted() && GetUpdateMode() && ( nTextPortions >= nBigObjectStart ) )
1157cdf0e10cSrcweir 	{
1158cdf0e10cSrcweir 		XParaPortionList* pXList = new XParaPortionList( GetRefDevice(), aPaperSize.Width() );
1159cdf0e10cSrcweir 		pTxtObj->SetPortionInfo( pXList );
1160cdf0e10cSrcweir 		for ( nNode = nStartNode; nNode <= nEndNode; nNode++  )
1161cdf0e10cSrcweir 		{
1162cdf0e10cSrcweir 			ParaPortion* pParaPortion = GetParaPortions()[nNode];
1163cdf0e10cSrcweir 			XParaPortion* pX = new XParaPortion;
1164cdf0e10cSrcweir 			pXList->Insert( pX, pXList->Count() );
1165cdf0e10cSrcweir 
1166cdf0e10cSrcweir 			pX->nHeight = pParaPortion->GetHeight();
1167cdf0e10cSrcweir 			pX->nFirstLineOffset = pParaPortion->GetFirstLineOffset();
1168cdf0e10cSrcweir 
1169cdf0e10cSrcweir 			// Die TextPortions
1170cdf0e10cSrcweir 			sal_uInt16 nCount = pParaPortion->GetTextPortions().Count();
1171cdf0e10cSrcweir 			sal_uInt16 n;
1172cdf0e10cSrcweir 			for ( n = 0; n < nCount; n++ )
1173cdf0e10cSrcweir 			{
1174cdf0e10cSrcweir 				TextPortion* pTextPortion = pParaPortion->GetTextPortions()[n];
1175cdf0e10cSrcweir 				TextPortion* pNew = new TextPortion( *pTextPortion );
1176cdf0e10cSrcweir 				pX->aTextPortions.Insert( pNew, pX->aTextPortions.Count() );
1177cdf0e10cSrcweir 			}
1178cdf0e10cSrcweir 
1179cdf0e10cSrcweir 			// Die Zeilen
1180cdf0e10cSrcweir 			nCount = pParaPortion->GetLines().Count();
1181cdf0e10cSrcweir 			for ( n = 0; n < nCount; n++ )
1182cdf0e10cSrcweir 			{
1183cdf0e10cSrcweir 				EditLine* pLine = pParaPortion->GetLines()[n];
1184cdf0e10cSrcweir 				EditLine* pNew = pLine->Clone();
1185cdf0e10cSrcweir 				pX->aLines.Insert( pNew, pX->aLines.Count() );
1186cdf0e10cSrcweir 			}
1187cdf0e10cSrcweir #ifdef DBG_UTIL
1188cdf0e10cSrcweir 			sal_uInt16 nTest;
1189cdf0e10cSrcweir             int nTPLen = 0, nTxtLen = 0;
1190cdf0e10cSrcweir 			for ( nTest = pParaPortion->GetTextPortions().Count(); nTest; )
1191cdf0e10cSrcweir 				nTPLen += pParaPortion->GetTextPortions().GetObject( --nTest )->GetLen();
1192cdf0e10cSrcweir 			for ( nTest = pParaPortion->GetLines().Count(); nTest; )
1193cdf0e10cSrcweir 				nTxtLen += pParaPortion->GetLines().GetObject( --nTest )->GetLen();
1194cdf0e10cSrcweir 			DBG_ASSERT( ( nTPLen == pParaPortion->GetNode()->Len() ) && ( nTxtLen == pParaPortion->GetNode()->Len() ), "CreateBinTextObject: ParaPortion not completely formatted!" );
1195cdf0e10cSrcweir #endif
1196cdf0e10cSrcweir 		}
1197cdf0e10cSrcweir 	}
1198cdf0e10cSrcweir 	return pTxtObj;
1199cdf0e10cSrcweir }
1200cdf0e10cSrcweir 
SetText(const EditTextObject & rTextObject)1201cdf0e10cSrcweir void ImpEditEngine::SetText( const EditTextObject& rTextObject )
1202cdf0e10cSrcweir {
1203cdf0e10cSrcweir 	// Da Setzen eines TextObject ist nicht Undo-faehig!
1204cdf0e10cSrcweir 	ResetUndoManager();
1205cdf0e10cSrcweir 	sal_Bool _bUpdate = GetUpdateMode();
1206cdf0e10cSrcweir 	sal_Bool _bUndo = IsUndoEnabled();
1207cdf0e10cSrcweir 
1208cdf0e10cSrcweir 	SetText( XubString() );
1209cdf0e10cSrcweir 	EditPaM aPaM = aEditDoc.GetStartPaM();
1210cdf0e10cSrcweir 
1211cdf0e10cSrcweir 	SetUpdateMode( sal_False );
1212cdf0e10cSrcweir 	EnableUndo( sal_False );
1213cdf0e10cSrcweir 
1214cdf0e10cSrcweir 	InsertText( rTextObject, EditSelection( aPaM, aPaM ) );
1215cdf0e10cSrcweir 	SetVertical( rTextObject.IsVertical() );
1216cdf0e10cSrcweir 
1217cdf0e10cSrcweir #ifndef SVX_LIGHT
1218cdf0e10cSrcweir 	DBG_ASSERT( !HasUndoManager() || !GetUndoManager().GetUndoActionCount(), "Woher kommt das Undo in SetText ?!" );
1219cdf0e10cSrcweir #endif
1220cdf0e10cSrcweir 	SetUpdateMode( _bUpdate );
1221cdf0e10cSrcweir 	EnableUndo( _bUndo );
1222cdf0e10cSrcweir }
1223cdf0e10cSrcweir 
InsertText(const EditTextObject & rTextObject,EditSelection aSel)1224cdf0e10cSrcweir EditSelection ImpEditEngine::InsertText( const EditTextObject& rTextObject, EditSelection aSel )
1225cdf0e10cSrcweir {
1226cdf0e10cSrcweir     EnterBlockNotifications();
1227cdf0e10cSrcweir 	aSel.Adjust( aEditDoc );
1228cdf0e10cSrcweir 	if ( aSel.HasRange() )
1229cdf0e10cSrcweir 		aSel = ImpDeleteSelection( aSel );
1230cdf0e10cSrcweir 	EditSelection aNewSel = InsertBinTextObject( (BinTextObject&)rTextObject, aSel.Max() );
1231cdf0e10cSrcweir     LeaveBlockNotifications();
1232cdf0e10cSrcweir     return aNewSel;
1233cdf0e10cSrcweir 
1234cdf0e10cSrcweir 	// MT 05/00: InsertBinTextObject direkt hier machen...
1235cdf0e10cSrcweir }
1236cdf0e10cSrcweir 
InsertBinTextObject(BinTextObject & rTextObject,EditPaM aPaM)1237cdf0e10cSrcweir EditSelection ImpEditEngine::InsertBinTextObject( BinTextObject& rTextObject, EditPaM aPaM )
1238cdf0e10cSrcweir {
1239cdf0e10cSrcweir 	// Optimieren:
1240cdf0e10cSrcweir 	// Kein GetPos undFindParaportion, sondern Index berechnen!
1241cdf0e10cSrcweir 	EditSelection aSel( aPaM, aPaM );
1242cdf0e10cSrcweir 	DBG_ASSERT( !aSel.DbgIsBuggy( aEditDoc ), "InsertBibTextObject: Selektion kaput!(1)" );
124325d782d7SPedro Giffuni 
1244cdf0e10cSrcweir 	sal_Bool bUsePortionInfo = sal_False;
1245cdf0e10cSrcweir //	sal_Bool bFields = sal_False;
1246cdf0e10cSrcweir 	XParaPortionList* pPortionInfo = rTextObject.GetPortionInfo();
1247cdf0e10cSrcweir 
1248cdf0e10cSrcweir 	if ( pPortionInfo && ( (long)pPortionInfo->GetPaperWidth() == aPaperSize.Width() )
1249cdf0e10cSrcweir 			&& ( pPortionInfo->GetRefMapMode() == GetRefDevice()->GetMapMode() ) )
1250cdf0e10cSrcweir 	{
1251cdf0e10cSrcweir 		if ( ( pPortionInfo->GetRefDevPtr() == (sal_uIntPtr)GetRefDevice() ) ||
1252cdf0e10cSrcweir 			 ( ( pPortionInfo->GetRefDevType() == OUTDEV_VIRDEV ) &&
1253cdf0e10cSrcweir 			   ( GetRefDevice()->GetOutDevType() == OUTDEV_VIRDEV ) ) )
1254cdf0e10cSrcweir 		bUsePortionInfo = sal_True;
1255cdf0e10cSrcweir 	}
1256cdf0e10cSrcweir 
1257cdf0e10cSrcweir 	sal_Bool bConvertItems = sal_False;
1258cdf0e10cSrcweir 	MapUnit eSourceUnit = MapUnit(), eDestUnit = MapUnit();
1259cdf0e10cSrcweir 	if ( rTextObject.HasMetric() )
1260cdf0e10cSrcweir 	{
1261cdf0e10cSrcweir 		eSourceUnit = (MapUnit)rTextObject.GetMetric();
1262cdf0e10cSrcweir 		eDestUnit = (MapUnit)aEditDoc.GetItemPool().GetMetric( DEF_METRIC );
1263cdf0e10cSrcweir 		if ( eSourceUnit != eDestUnit )
1264cdf0e10cSrcweir 			bConvertItems = sal_True;
1265cdf0e10cSrcweir 	}
1266cdf0e10cSrcweir 
1267*7a980842SDamjanJovanovic 	sal_uInt32 nContents = rTextObject.GetContents().Count();
1268*7a980842SDamjanJovanovic 	sal_uInt32 nPara = aEditDoc.GetPos( aPaM.GetNode() );
1269cdf0e10cSrcweir 
1270*7a980842SDamjanJovanovic 	for ( sal_uInt32 n = 0; n < nContents; n++, nPara++ )
1271cdf0e10cSrcweir 	{
1272cdf0e10cSrcweir 		ContentInfo* pC = rTextObject.GetContents().GetObject( n );
1273cdf0e10cSrcweir 		sal_Bool bNewContent = aPaM.GetNode()->Len() ? sal_False: sal_True;
1274cdf0e10cSrcweir 		sal_uInt16 nStartPos = aPaM.GetIndex();
1275cdf0e10cSrcweir 
1276cdf0e10cSrcweir 		aPaM = ImpFastInsertText( aPaM, pC->GetText() );
1277cdf0e10cSrcweir 
1278cdf0e10cSrcweir 		ParaPortion* pPortion = FindParaPortion( aPaM.GetNode() );
1279cdf0e10cSrcweir 		DBG_ASSERT( pPortion, "Blinde Portion in FastInsertText" );
1280cdf0e10cSrcweir 		pPortion->MarkInvalid( nStartPos, pC->GetText().Len() );
1281cdf0e10cSrcweir 
1282cdf0e10cSrcweir 		// Zeicheattribute...
1283cdf0e10cSrcweir 		sal_Bool bAllreadyHasAttribs = aPaM.GetNode()->GetCharAttribs().Count() ? sal_True : sal_False;
1284cdf0e10cSrcweir 		sal_uInt16 nNewAttribs = pC->GetAttribs().Count();
1285cdf0e10cSrcweir 		if ( nNewAttribs )
1286cdf0e10cSrcweir 		{
1287cdf0e10cSrcweir             sal_Bool bUpdateFields = sal_False;
1288cdf0e10cSrcweir 			for ( sal_uInt16 nAttr = 0; nAttr < nNewAttribs; nAttr++ )
1289cdf0e10cSrcweir 			{
1290cdf0e10cSrcweir 				XEditAttribute* pX = pC->GetAttribs().GetObject( nAttr );
1291cdf0e10cSrcweir 				// Kann passieren wenn Absaetze >16K entstehen, dann wird einfach umgebrochen.
1292cdf0e10cSrcweir 				if ( pX->GetEnd() <= aPaM.GetNode()->Len() )
1293cdf0e10cSrcweir 				{
1294cdf0e10cSrcweir 					if ( !bAllreadyHasAttribs || pX->IsFeature() )
1295cdf0e10cSrcweir 					{
1296cdf0e10cSrcweir 						// Normale Attribute gehen dann schneller...
1297cdf0e10cSrcweir 						// Features duerfen nicht ueber EditDoc::InsertAttrib
1298cdf0e10cSrcweir 						// eingefuegt werden, sie sind bei FastInsertText schon im TextFluss
1299cdf0e10cSrcweir 						DBG_ASSERT( pX->GetEnd() <= aPaM.GetNode()->Len(), "InsertBinTextObject: Attribut zu gross!" );
1300cdf0e10cSrcweir 						EditCharAttrib* pAttr;
1301cdf0e10cSrcweir 						if ( !bConvertItems )
1302cdf0e10cSrcweir 							pAttr = MakeCharAttrib( aEditDoc.GetItemPool(), *(pX->GetItem()), pX->GetStart()+nStartPos, pX->GetEnd()+nStartPos );
1303cdf0e10cSrcweir 						else
1304cdf0e10cSrcweir 						{
1305cdf0e10cSrcweir 							SfxPoolItem* pNew = pX->GetItem()->Clone();
1306cdf0e10cSrcweir 							ConvertItem( *pNew, eSourceUnit, eDestUnit );
1307cdf0e10cSrcweir 							pAttr = MakeCharAttrib( aEditDoc.GetItemPool(), *pNew, pX->GetStart()+nStartPos, pX->GetEnd()+nStartPos );
1308cdf0e10cSrcweir 							delete pNew;
1309cdf0e10cSrcweir 						}
1310cdf0e10cSrcweir 						DBG_ASSERT( pAttr->GetEnd() <= aPaM.GetNode()->Len(), "InsertBinTextObject: Attribut passt nicht! (1)" );
1311cdf0e10cSrcweir 						aPaM.GetNode()->GetCharAttribs().InsertAttrib( pAttr );
1312cdf0e10cSrcweir 						if ( pAttr->Which() == EE_FEATURE_FIELD )
1313cdf0e10cSrcweir                             bUpdateFields = sal_True;
1314cdf0e10cSrcweir 					}
1315cdf0e10cSrcweir 					else
1316cdf0e10cSrcweir 					{
1317cdf0e10cSrcweir 						DBG_ASSERT( pX->GetEnd()+nStartPos <= aPaM.GetNode()->Len(), "InsertBinTextObject: Attribut passt nicht! (2)" );
1318cdf0e10cSrcweir 						// Tabs und andere Features koennen nicht ueber InsertAttrib eingefuegt werden:
1319cdf0e10cSrcweir 						aEditDoc.InsertAttrib( aPaM.GetNode(), pX->GetStart()+nStartPos, pX->GetEnd()+nStartPos, *pX->GetItem() );
1320cdf0e10cSrcweir 					}
1321cdf0e10cSrcweir 				}
1322cdf0e10cSrcweir 			}
1323cdf0e10cSrcweir             if ( bUpdateFields )
1324cdf0e10cSrcweir                 UpdateFields();
1325cdf0e10cSrcweir 
1326cdf0e10cSrcweir             // Sonst QuickFormat => Keine Attribute!
1327cdf0e10cSrcweir 			pPortion->MarkSelectionInvalid( nStartPos, pC->GetText().Len() );
1328cdf0e10cSrcweir 		}
1329cdf0e10cSrcweir 
1330cdf0e10cSrcweir 		DBG_ASSERT( CheckOrderedList( aPaM.GetNode()->GetCharAttribs().GetAttribs(), sal_True ), "InsertBinTextObject: Start-Liste verdreht" );
1331cdf0e10cSrcweir 
1332cdf0e10cSrcweir 		sal_Bool bParaAttribs = sal_False;
1333cdf0e10cSrcweir 		if ( bNewContent || ( ( n > 0 ) && ( n < (nContents-1) ) ) )
1334cdf0e10cSrcweir 		{
1335cdf0e10cSrcweir             bParaAttribs = sal_False;
1336cdf0e10cSrcweir             // #101512# Don't overwrite level/style from existing paragraph in OutlineView
1337cdf0e10cSrcweir             // MT 10/2002: Removed because of #103874#, handled in Outliner::EndPasteOrDropHdl now.
1338cdf0e10cSrcweir //            if ( !aStatus.IsOutliner() || n )
1339cdf0e10cSrcweir             {
1340cdf0e10cSrcweir 			    // nur dann Style und ParaAttribs, wenn neuer Absatz, oder
1341cdf0e10cSrcweir 			    // komplett inneliegender...
1342cdf0e10cSrcweir 			    bParaAttribs = pC->GetParaAttribs().Count() ? sal_True : sal_False;
1343cdf0e10cSrcweir 			    if ( GetStyleSheetPool() && pC->GetStyle().Len() )
1344cdf0e10cSrcweir 			    {
1345cdf0e10cSrcweir 				    SfxStyleSheet* pStyle = (SfxStyleSheet*)GetStyleSheetPool()->Find( pC->GetStyle(), pC->GetFamily() );
1346cdf0e10cSrcweir 				    DBG_ASSERT( pStyle, "InsertBinTextObject - Style not found!" );
1347cdf0e10cSrcweir 				    SetStyleSheet( nPara, pStyle );
1348cdf0e10cSrcweir 			    }
1349cdf0e10cSrcweir 			    if ( !bConvertItems )
1350cdf0e10cSrcweir 				    SetParaAttribs( aEditDoc.GetPos( aPaM.GetNode() ), pC->GetParaAttribs() );
1351cdf0e10cSrcweir 			    else
1352cdf0e10cSrcweir 			    {
1353cdf0e10cSrcweir 				    SfxItemSet aAttribs( GetEmptyItemSet() );
1354cdf0e10cSrcweir 				    ConvertAndPutItems( aAttribs, pC->GetParaAttribs(), &eSourceUnit, &eDestUnit );
1355cdf0e10cSrcweir 				    SetParaAttribs( aEditDoc.GetPos( aPaM.GetNode() ), aAttribs );
1356cdf0e10cSrcweir 			    }
1357cdf0e10cSrcweir             }
1358cdf0e10cSrcweir 			if ( bNewContent && bUsePortionInfo )
1359cdf0e10cSrcweir 			{
1360cdf0e10cSrcweir 				XParaPortion* pXP = pPortionInfo->GetObject( n );
1361cdf0e10cSrcweir 				DBG_ASSERT( pXP, "InsertBinTextObject: PortionInfo?" );
1362cdf0e10cSrcweir 				ParaPortion* pParaPortion = GetParaPortions()[ nPara ];
1363cdf0e10cSrcweir 				DBG_ASSERT( pParaPortion, "InsertBinTextObject: ParaPortion?" );
1364cdf0e10cSrcweir 				pParaPortion->nHeight = pXP->nHeight;
1365cdf0e10cSrcweir 				pParaPortion->nFirstLineOffset = pXP->nFirstLineOffset;
1366cdf0e10cSrcweir 				pParaPortion->bForceRepaint = sal_True;
1367cdf0e10cSrcweir 				pParaPortion->SetValid();	// Nicht formatieren
1368cdf0e10cSrcweir 
1369cdf0e10cSrcweir 				// Die TextPortions
1370cdf0e10cSrcweir 				pParaPortion->GetTextPortions().Reset();
1371cdf0e10cSrcweir 				sal_uInt16 nCount = pXP->aTextPortions.Count();
1372cdf0e10cSrcweir 				for ( sal_uInt16 _n = 0; _n < nCount; _n++ )
1373cdf0e10cSrcweir 				{
1374cdf0e10cSrcweir 					TextPortion* pTextPortion = pXP->aTextPortions[_n];
1375cdf0e10cSrcweir 					TextPortion* pNew = new TextPortion( *pTextPortion );
1376cdf0e10cSrcweir 					pParaPortion->GetTextPortions().Insert( pNew, _n );
1377cdf0e10cSrcweir 				}
1378cdf0e10cSrcweir 
1379cdf0e10cSrcweir 				// Die Zeilen
1380cdf0e10cSrcweir 				pParaPortion->GetLines().Reset();
1381cdf0e10cSrcweir 				nCount = pXP->aLines.Count();
1382cdf0e10cSrcweir 				for ( sal_uInt16 m = 0; m < nCount; m++ )
1383cdf0e10cSrcweir 				{
1384cdf0e10cSrcweir 					EditLine* pLine = pXP->aLines[m];
1385cdf0e10cSrcweir 					EditLine* pNew = pLine->Clone();
1386cdf0e10cSrcweir 					pNew->SetInvalid();	// neu Painten!
1387cdf0e10cSrcweir 					pParaPortion->GetLines().Insert( pNew, m );
1388cdf0e10cSrcweir 				}
1389cdf0e10cSrcweir #ifdef DBG_UTIL
1390cdf0e10cSrcweir 				sal_uInt16 nTest;
1391cdf0e10cSrcweir                 int nTPLen = 0, nTxtLen = 0;
1392cdf0e10cSrcweir 				for ( nTest = pParaPortion->GetTextPortions().Count(); nTest; )
1393cdf0e10cSrcweir 					nTPLen += pParaPortion->GetTextPortions().GetObject( --nTest )->GetLen();
1394cdf0e10cSrcweir 				for ( nTest = pParaPortion->GetLines().Count(); nTest; )
1395cdf0e10cSrcweir 					nTxtLen += pParaPortion->GetLines().GetObject( --nTest )->GetLen();
1396cdf0e10cSrcweir 				DBG_ASSERT( ( nTPLen == pParaPortion->GetNode()->Len() ) && ( nTxtLen == pParaPortion->GetNode()->Len() ), "InsertBinTextObject: ParaPortion not completely formatted!" );
1397cdf0e10cSrcweir #endif
1398cdf0e10cSrcweir 			}
1399cdf0e10cSrcweir 		}
1400cdf0e10cSrcweir 		if ( !bParaAttribs ) // DefFont wird bei FastInsertParagraph nicht berechnet
1401cdf0e10cSrcweir 		{
1402cdf0e10cSrcweir 			aPaM.GetNode()->GetCharAttribs().GetDefFont() = aEditDoc.GetDefFont();
1403cdf0e10cSrcweir 			if ( aStatus.UseCharAttribs() )
1404cdf0e10cSrcweir 				aPaM.GetNode()->CreateDefFont();
1405cdf0e10cSrcweir 		}
1406cdf0e10cSrcweir 
1407cdf0e10cSrcweir #ifndef SVX_LIGHT
1408cdf0e10cSrcweir 		if ( bNewContent && GetStatus().DoOnlineSpelling() && pC->GetWrongList() )
1409cdf0e10cSrcweir 		{
1410cdf0e10cSrcweir 			aPaM.GetNode()->DestroyWrongList();	// otherwise MLK, if list exists...
1411cdf0e10cSrcweir 			aPaM.GetNode()->SetWrongList( pC->GetWrongList()->Clone() );
1412cdf0e10cSrcweir 		}
1413cdf0e10cSrcweir #endif // !SVX_LIGHT
1414cdf0e10cSrcweir 
1415cdf0e10cSrcweir 		// Zeilenumbruch, wenn weitere folgen...
1416cdf0e10cSrcweir 		if ( n < ( nContents-1) )
1417cdf0e10cSrcweir 		{
1418cdf0e10cSrcweir 			if ( bNewContent )
1419cdf0e10cSrcweir 				aPaM = ImpFastInsertParagraph( nPara+1 );
1420cdf0e10cSrcweir 			else
1421cdf0e10cSrcweir 				aPaM = ImpInsertParaBreak( aPaM, sal_False );
1422cdf0e10cSrcweir 		}
1423cdf0e10cSrcweir 	}
1424cdf0e10cSrcweir 
14255b4f8e55SPedro Giffuni 	aSel.Max() = aPaM;
1426cdf0e10cSrcweir 	DBG_ASSERT( !aSel.DbgIsBuggy( aEditDoc ), "InsertBibTextObject: Selektion kaput!(1)" );
1427cdf0e10cSrcweir 	return aSel;
1428cdf0e10cSrcweir }
1429cdf0e10cSrcweir 
GetLanguage(const EditPaM & rPaM,sal_uInt16 * pEndPos) const1430cdf0e10cSrcweir LanguageType ImpEditEngine::GetLanguage( const EditPaM& rPaM, sal_uInt16* pEndPos ) const
1431cdf0e10cSrcweir {
1432cdf0e10cSrcweir 	short nScriptType = GetScriptType( rPaM, pEndPos );	// pEndPos will be valid now, pointing to ScriptChange or NodeLen
1433cdf0e10cSrcweir 	sal_uInt16 nLangId = GetScriptItemId( EE_CHAR_LANGUAGE, nScriptType );
1434cdf0e10cSrcweir 	const SvxLanguageItem* pLangItem = &(const SvxLanguageItem&)rPaM.GetNode()->GetContentAttribs().GetItem( nLangId );
1435cdf0e10cSrcweir 	EditCharAttrib*	pAttr = rPaM.GetNode()->GetCharAttribs().FindAttrib( nLangId, rPaM.GetIndex() );
1436cdf0e10cSrcweir 	if ( pAttr )
1437cdf0e10cSrcweir 		pLangItem = (const SvxLanguageItem*)pAttr->GetItem();
1438cdf0e10cSrcweir 
1439cdf0e10cSrcweir 	if ( pEndPos && pAttr && ( pAttr->GetEnd() < *pEndPos ) )
1440cdf0e10cSrcweir 		*pEndPos = pAttr->GetEnd();
1441cdf0e10cSrcweir 
1442cdf0e10cSrcweir 	return pLangItem->GetLanguage();
1443cdf0e10cSrcweir }
1444cdf0e10cSrcweir 
GetLocale(const EditPaM & rPaM) const1445cdf0e10cSrcweir ::com::sun::star::lang::Locale ImpEditEngine::GetLocale( const EditPaM& rPaM ) const
1446cdf0e10cSrcweir {
1447cdf0e10cSrcweir 	return SvxCreateLocale( GetLanguage( rPaM ) );
1448cdf0e10cSrcweir }
1449cdf0e10cSrcweir 
GetSpeller()1450cdf0e10cSrcweir Reference< XSpellChecker1 > ImpEditEngine::GetSpeller()
1451cdf0e10cSrcweir {
1452cdf0e10cSrcweir #ifndef SVX_LIGHT
1453cdf0e10cSrcweir 	if ( !xSpeller.is() )
1454cdf0e10cSrcweir 		xSpeller = SvxGetSpellChecker();
1455cdf0e10cSrcweir #endif
1456cdf0e10cSrcweir 	return xSpeller;
1457cdf0e10cSrcweir }
1458cdf0e10cSrcweir 
1459cdf0e10cSrcweir 
CreateSpellInfo(const EditSelection & rSel,bool bMultipleDocs)1460cdf0e10cSrcweir SpellInfo * ImpEditEngine::CreateSpellInfo( const EditSelection &rSel, bool bMultipleDocs )
1461cdf0e10cSrcweir {
1462cdf0e10cSrcweir     if (!pSpellInfo)
1463cdf0e10cSrcweir 	    pSpellInfo = new SpellInfo;
1464cdf0e10cSrcweir     else
1465cdf0e10cSrcweir         *pSpellInfo = SpellInfo();  // reset to default values
1466cdf0e10cSrcweir 
1467cdf0e10cSrcweir 	pSpellInfo->bMultipleDoc = bMultipleDocs;
1468cdf0e10cSrcweir     EditSelection aSentenceSel( SelectSentence( rSel ) );
1469cdf0e10cSrcweir //    pSpellInfo->aSpellStart = CreateEPaM( aSentenceSel.Min() );
1470cdf0e10cSrcweir //    pSpellInfo->aSpellTo    = CreateEPaM( rSel.HasRange()? aSentenceSel.Max() : aSentenceSel.Min() );
1471cdf0e10cSrcweir     // always spell draw objects completely, startting at the top.
1472cdf0e10cSrcweir     // (spelling in only a selection or not starting with the top requires
1473cdf0e10cSrcweir     // further changes elsewehe to work properly)
1474cdf0e10cSrcweir 	pSpellInfo->aSpellStart = EPaM();
1475cdf0e10cSrcweir     pSpellInfo->aSpellTo    = EPaM( EE_PARA_NOT_FOUND, EE_INDEX_NOT_FOUND );
1476cdf0e10cSrcweir     return pSpellInfo;
1477cdf0e10cSrcweir }
1478cdf0e10cSrcweir 
1479cdf0e10cSrcweir 
Spell(EditView * pEditView,sal_Bool bMultipleDoc)1480cdf0e10cSrcweir EESpellState ImpEditEngine::Spell( EditView* pEditView, sal_Bool bMultipleDoc )
1481cdf0e10cSrcweir {
1482cdf0e10cSrcweir #ifdef SVX_LIGHT
1483cdf0e10cSrcweir 	return EE_SPELL_NOSPELLER;
1484cdf0e10cSrcweir #else
1485cdf0e10cSrcweir 
1486cdf0e10cSrcweir 	DBG_ASSERTWARNING( xSpeller.is(), "Kein Speller gesetzt!" );
1487cdf0e10cSrcweir 
1488cdf0e10cSrcweir 	if ( !xSpeller.is() )
1489cdf0e10cSrcweir 		return EE_SPELL_NOSPELLER;
1490cdf0e10cSrcweir 
1491cdf0e10cSrcweir 	aOnlineSpellTimer.Stop();
1492cdf0e10cSrcweir 
1493cdf0e10cSrcweir 	// Bei MultipleDoc immer von vorne/hinten...
1494cdf0e10cSrcweir 	if ( bMultipleDoc )
1495cdf0e10cSrcweir 	{
1496cdf0e10cSrcweir         pEditView->pImpEditView->SetEditSelection( aEditDoc.GetStartPaM() );
1497cdf0e10cSrcweir 	}
1498cdf0e10cSrcweir 
1499cdf0e10cSrcweir 	EditSelection aCurSel( pEditView->pImpEditView->GetEditSelection() );
1500cdf0e10cSrcweir 	pSpellInfo = CreateSpellInfo( aCurSel, bMultipleDoc );
1501cdf0e10cSrcweir 
1502cdf0e10cSrcweir 	sal_Bool bIsStart = sal_False;
1503cdf0e10cSrcweir 	if ( bMultipleDoc )
1504cdf0e10cSrcweir 		bIsStart = sal_True;	// Immer von Vorne bzw. von hinten...
1505cdf0e10cSrcweir     else if ( ( CreateEPaM( aEditDoc.GetStartPaM() ) == pSpellInfo->aSpellStart ) )
1506cdf0e10cSrcweir 		bIsStart = sal_True;
1507cdf0e10cSrcweir 
1508cdf0e10cSrcweir 	EditSpellWrapper* pWrp = new EditSpellWrapper( Application::GetDefDialogParent(),
1509cdf0e10cSrcweir 			xSpeller, bIsStart, sal_False, pEditView );
1510cdf0e10cSrcweir 	pWrp->SpellDocument();
1511cdf0e10cSrcweir 	delete pWrp;
1512cdf0e10cSrcweir 
1513cdf0e10cSrcweir 	if ( !bMultipleDoc )
1514cdf0e10cSrcweir 	{
1515cdf0e10cSrcweir 		pEditView->pImpEditView->DrawSelection();
1516cdf0e10cSrcweir 		if ( aCurSel.Max().GetIndex() > aCurSel.Max().GetNode()->Len() )
1517cdf0e10cSrcweir 			aCurSel.Max().GetIndex() = aCurSel.Max().GetNode()->Len();
1518cdf0e10cSrcweir 		aCurSel.Min() = aCurSel.Max();
1519cdf0e10cSrcweir 		pEditView->pImpEditView->SetEditSelection( aCurSel );
1520cdf0e10cSrcweir 		pEditView->pImpEditView->DrawSelection();
1521cdf0e10cSrcweir 		pEditView->ShowCursor( sal_True, sal_False );
1522cdf0e10cSrcweir 	}
1523cdf0e10cSrcweir 	EESpellState eState = pSpellInfo->eState;
1524cdf0e10cSrcweir 	delete pSpellInfo;
1525cdf0e10cSrcweir 	pSpellInfo = 0;
1526cdf0e10cSrcweir 	return eState;
1527cdf0e10cSrcweir #endif
1528cdf0e10cSrcweir }
1529cdf0e10cSrcweir 
1530cdf0e10cSrcweir 
HasConvertibleTextPortion(LanguageType nSrcLang)1531cdf0e10cSrcweir sal_Bool ImpEditEngine::HasConvertibleTextPortion( LanguageType nSrcLang )
1532cdf0e10cSrcweir {
1533cdf0e10cSrcweir #ifdef SVX_LIGHT
1534cdf0e10cSrcweir     return sal_False;
1535cdf0e10cSrcweir #else
1536cdf0e10cSrcweir     sal_Bool    bHasConvTxt = sal_False;
1537cdf0e10cSrcweir 
1538*7a980842SDamjanJovanovic     sal_uInt32 nParas = pEditEngine->GetParagraphCount();
1539*7a980842SDamjanJovanovic     for (sal_uInt32 k = 0;  k < nParas;  ++k)
1540cdf0e10cSrcweir     {
1541cdf0e10cSrcweir         SvUShorts aPortions;
1542cdf0e10cSrcweir         pEditEngine->GetPortions( k, aPortions );
1543cdf0e10cSrcweir         for ( sal_uInt16 nPos = 0; nPos < aPortions.Count(); ++nPos )
1544cdf0e10cSrcweir         {
1545cdf0e10cSrcweir             sal_uInt16 nEnd   = aPortions.GetObject( nPos );
1546cdf0e10cSrcweir             sal_uInt16 nStart = nPos > 0 ? aPortions.GetObject( nPos - 1 ) : 0;
1547cdf0e10cSrcweir 
1548cdf0e10cSrcweir 			// if the paragraph is not empty we need to increase the index
1549cdf0e10cSrcweir 			// by one since the attribute of the character left to the
1550cdf0e10cSrcweir 			// specified position is evaluated.
1551cdf0e10cSrcweir 			if (nEnd > nStart)	// empty para?
1552cdf0e10cSrcweir 				++nStart;
1553cdf0e10cSrcweir             LanguageType nLangFound = pEditEngine->GetLanguage( k, nStart );
1554cdf0e10cSrcweir #ifdef DEBUG
1555cdf0e10cSrcweir             lang::Locale aLocale( SvxCreateLocale( nLangFound ) );
1556cdf0e10cSrcweir #endif
1557cdf0e10cSrcweir             bHasConvTxt =   (nSrcLang == nLangFound) ||
1558cdf0e10cSrcweir                             (editeng::HangulHanjaConversion::IsChinese( nLangFound ) &&
1559cdf0e10cSrcweir                              editeng::HangulHanjaConversion::IsChinese( nSrcLang ));
1560cdf0e10cSrcweir             if (bHasConvTxt)
1561cdf0e10cSrcweir                 return bHasConvTxt;
1562cdf0e10cSrcweir        }
1563cdf0e10cSrcweir     }
1564cdf0e10cSrcweir 
1565cdf0e10cSrcweir #endif
1566cdf0e10cSrcweir     return bHasConvTxt;
1567cdf0e10cSrcweir }
1568cdf0e10cSrcweir 
1569cdf0e10cSrcweir 
Convert(EditView * pEditView,LanguageType nSrcLang,LanguageType nDestLang,const Font * pDestFont,sal_Int32 nOptions,sal_Bool bIsInteractive,sal_Bool bMultipleDoc)1570cdf0e10cSrcweir void ImpEditEngine::Convert( EditView* pEditView,
1571cdf0e10cSrcweir         LanguageType nSrcLang, LanguageType nDestLang, const Font *pDestFont,
1572cdf0e10cSrcweir         sal_Int32 nOptions, sal_Bool bIsInteractive, sal_Bool bMultipleDoc )
1573cdf0e10cSrcweir {
1574cdf0e10cSrcweir     // modified version of ImpEditEngine::Spell
1575cdf0e10cSrcweir 
1576cdf0e10cSrcweir #ifdef SVX_LIGHT
1577cdf0e10cSrcweir #else
1578cdf0e10cSrcweir 
1579cdf0e10cSrcweir     // Bei MultipleDoc immer von vorne/hinten...
1580cdf0e10cSrcweir     if ( bMultipleDoc )
1581cdf0e10cSrcweir         pEditView->pImpEditView->SetEditSelection( aEditDoc.GetStartPaM() );
1582cdf0e10cSrcweir 
1583cdf0e10cSrcweir 	//
1584cdf0e10cSrcweir 	// initialize pConvInfo
1585cdf0e10cSrcweir 	//
1586cdf0e10cSrcweir     EditSelection aCurSel( pEditView->pImpEditView->GetEditSelection() );
1587cdf0e10cSrcweir     aCurSel.Adjust( aEditDoc );
1588cdf0e10cSrcweir     pConvInfo = new ConvInfo;
1589cdf0e10cSrcweir     pConvInfo->bMultipleDoc = bMultipleDoc;
1590cdf0e10cSrcweir     pConvInfo->aConvStart = CreateEPaM( aCurSel.Min() );
1591cdf0e10cSrcweir 	//
1592cdf0e10cSrcweir 	// if it is not just a selection and we are about to begin
1593cdf0e10cSrcweir 	// with the current conversion for the very first time
1594cdf0e10cSrcweir 	// we need to find the start of the current (initial)
1595cdf0e10cSrcweir 	// convertible unit in order for the text conversion to give
1596cdf0e10cSrcweir 	// the correct result for that. Since it is easier to obtain
1597cdf0e10cSrcweir 	// the start of the word we use that though.
1598cdf0e10cSrcweir 	if (!aCurSel.HasRange() && ImplGetBreakIterator().is())
1599cdf0e10cSrcweir 	{
1600cdf0e10cSrcweir 		EditPaM aWordStartPaM(	SelectWord( aCurSel, i18n::WordType::DICTIONARY_WORD ).Min() );
1601cdf0e10cSrcweir 
1602cdf0e10cSrcweir 		// since #118246 / #117803 still occurs if the cursor is placed
1603cdf0e10cSrcweir 		// between the two chinese characters to be converted (because both
1604cdf0e10cSrcweir 		// of them are words on their own!) using the word boundary here does
1605cdf0e10cSrcweir 		// not work. Thus since chinese conversion is not interactive we start
1606cdf0e10cSrcweir 		// at the begin of the paragraph to solve the problem, i.e. have the
1607cdf0e10cSrcweir         // TextConversion service get those characters together in the same call.
1608cdf0e10cSrcweir 		sal_uInt16 nStartIdx = ( editeng::HangulHanjaConversion::IsChinese( nSrcLang ) ) ?
1609cdf0e10cSrcweir 								0 : aWordStartPaM.GetIndex();
1610cdf0e10cSrcweir 		pConvInfo->aConvStart.nIndex = nStartIdx;
1611cdf0e10cSrcweir 	}
1612cdf0e10cSrcweir 	//
1613cdf0e10cSrcweir     pConvInfo->aConvContinue = pConvInfo->aConvStart;
1614cdf0e10cSrcweir 
1615cdf0e10cSrcweir     sal_Bool bIsStart = sal_False;
1616cdf0e10cSrcweir     if ( bMultipleDoc )
1617cdf0e10cSrcweir         bIsStart = sal_True;    // Immer von Vorne bzw. von hinten...
1618cdf0e10cSrcweir     else if ( CreateEPaM( aEditDoc.GetStartPaM() ) == pConvInfo->aConvStart )
1619cdf0e10cSrcweir         bIsStart = sal_True;
1620cdf0e10cSrcweir 
1621cdf0e10cSrcweir     bImpConvertFirstCall = sal_True;    // next ImpConvert call is the very first in this conversion turn
1622cdf0e10cSrcweir 
1623cdf0e10cSrcweir     Reference< lang::XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory();
1624cdf0e10cSrcweir     TextConvWrapper aWrp( Application::GetDefDialogParent(), xMSF,
1625cdf0e10cSrcweir                           SvxCreateLocale( nSrcLang ), SvxCreateLocale( nDestLang ),
1626cdf0e10cSrcweir                           pDestFont,
1627cdf0e10cSrcweir                           nOptions, bIsInteractive,
1628cdf0e10cSrcweir                           bIsStart, pEditView );
1629cdf0e10cSrcweir 
1630cdf0e10cSrcweir 	//
1631cdf0e10cSrcweir 	//!! optimization does not work since when update mode is false
1632cdf0e10cSrcweir     //!! the object is 'lying' about it portions, paragraphs,
1633cdf0e10cSrcweir 	//!! EndPaM... later on.
1634cdf0e10cSrcweir     //!! Should not be a great problem since text boxes or cells in
1635cdf0e10cSrcweir 	//!! Calc usually have only a rather short text.
1636cdf0e10cSrcweir 	//
1637cdf0e10cSrcweir 	// disallow formatting, updating the view, ... while
1638cdf0e10cSrcweir 	// non-interactively converting the document. (saves time)
1639cdf0e10cSrcweir 	//if (!bIsInteractive)
1640cdf0e10cSrcweir 	//	SetUpdateMode( sal_False );
1641cdf0e10cSrcweir 
1642cdf0e10cSrcweir 	aWrp.Convert();
1643cdf0e10cSrcweir 
1644cdf0e10cSrcweir 	//if (!bIsInteractive)
1645cdf0e10cSrcweir 	//SetUpdateMode( sal_True, 0, sal_True );
1646cdf0e10cSrcweir 
1647cdf0e10cSrcweir     if ( !bMultipleDoc )
1648cdf0e10cSrcweir     {
1649cdf0e10cSrcweir         pEditView->pImpEditView->DrawSelection();
1650cdf0e10cSrcweir         if ( aCurSel.Max().GetIndex() > aCurSel.Max().GetNode()->Len() )
1651cdf0e10cSrcweir             aCurSel.Max().GetIndex() = aCurSel.Max().GetNode()->Len();
1652cdf0e10cSrcweir         aCurSel.Min() = aCurSel.Max();
1653cdf0e10cSrcweir         pEditView->pImpEditView->SetEditSelection( aCurSel );
1654cdf0e10cSrcweir         pEditView->pImpEditView->DrawSelection();
1655cdf0e10cSrcweir         pEditView->ShowCursor( sal_True, sal_False );
1656cdf0e10cSrcweir     }
1657cdf0e10cSrcweir     delete pConvInfo;
1658cdf0e10cSrcweir     pConvInfo = 0;
1659cdf0e10cSrcweir #endif
1660cdf0e10cSrcweir }
1661cdf0e10cSrcweir 
1662cdf0e10cSrcweir 
SetLanguageAndFont(const ESelection & rESel,LanguageType nLang,sal_uInt16 nLangWhichId,const Font * pFont,sal_uInt16 nFontWhichId)1663cdf0e10cSrcweir void ImpEditEngine::SetLanguageAndFont(
1664cdf0e10cSrcweir     const ESelection &rESel,
1665cdf0e10cSrcweir     LanguageType nLang, sal_uInt16 nLangWhichId,
1666cdf0e10cSrcweir     const Font *pFont,  sal_uInt16 nFontWhichId )
1667cdf0e10cSrcweir {
1668cdf0e10cSrcweir     ESelection aOldSel = pActiveView->GetSelection();
1669cdf0e10cSrcweir     pActiveView->SetSelection( rESel );
1670cdf0e10cSrcweir 
1671cdf0e10cSrcweir     // set new language attribute
1672cdf0e10cSrcweir     SfxItemSet aNewSet( pActiveView->GetEmptyItemSet() );
1673cdf0e10cSrcweir     aNewSet.Put( SvxLanguageItem( nLang, nLangWhichId ) );
1674cdf0e10cSrcweir 
1675cdf0e10cSrcweir     // new font to be set?
1676cdf0e10cSrcweir     DBG_ASSERT( pFont, "target font missing?" );
1677cdf0e10cSrcweir     if (pFont)
1678cdf0e10cSrcweir     {
1679cdf0e10cSrcweir         // set new font attribute
1680cdf0e10cSrcweir         SvxFontItem aFontItem = (SvxFontItem&) aNewSet.Get( nFontWhichId );
1681cdf0e10cSrcweir         aFontItem.SetFamilyName( pFont->GetName());
1682cdf0e10cSrcweir         aFontItem.SetFamily( pFont->GetFamily());
1683cdf0e10cSrcweir         aFontItem.SetStyleName( pFont->GetStyleName());
1684cdf0e10cSrcweir         aFontItem.SetPitch( pFont->GetPitch());
1685cdf0e10cSrcweir         aFontItem.SetCharSet( pFont->GetCharSet() );
1686cdf0e10cSrcweir         aNewSet.Put( aFontItem );
1687cdf0e10cSrcweir     }
1688cdf0e10cSrcweir 
1689cdf0e10cSrcweir     // apply new attributes
1690cdf0e10cSrcweir     pActiveView->SetAttribs( aNewSet );
1691cdf0e10cSrcweir 
1692cdf0e10cSrcweir     pActiveView->SetSelection( aOldSel );
1693cdf0e10cSrcweir }
1694cdf0e10cSrcweir 
1695cdf0e10cSrcweir 
ImpConvert(rtl::OUString & rConvTxt,LanguageType & rConvTxtLang,EditView * pEditView,LanguageType nSrcLang,const ESelection & rConvRange,sal_Bool bAllowImplicitChangesForNotConvertibleText,LanguageType nTargetLang,const Font * pTargetFont)1696cdf0e10cSrcweir void ImpEditEngine::ImpConvert( rtl::OUString &rConvTxt, LanguageType &rConvTxtLang,
1697cdf0e10cSrcweir         EditView* pEditView, LanguageType nSrcLang, const ESelection &rConvRange,
1698cdf0e10cSrcweir         sal_Bool bAllowImplicitChangesForNotConvertibleText,
1699cdf0e10cSrcweir         LanguageType nTargetLang, const Font *pTargetFont  )
1700cdf0e10cSrcweir {
1701cdf0e10cSrcweir     // modified version of ImpEditEngine::ImpSpell
1702cdf0e10cSrcweir 
1703cdf0e10cSrcweir     // looks for next convertible text portion to be passed on to the wrapper
1704cdf0e10cSrcweir 
1705cdf0e10cSrcweir     String aRes;
1706cdf0e10cSrcweir     LanguageType nResLang = LANGUAGE_NONE;
1707cdf0e10cSrcweir 
1708cdf0e10cSrcweir #ifdef SVX_LIGHT
1709cdf0e10cSrcweir     rConvTxt = rtl::OUString();
1710cdf0e10cSrcweir     rConvTxtLang = LANGUAGE_NONE;
1711cdf0e10cSrcweir #else
1712cdf0e10cSrcweir 
1713cdf0e10cSrcweir     /* ContentNode* pLastNode = */ aEditDoc.SaveGetObject( aEditDoc.Count()-1 );
1714cdf0e10cSrcweir 
1715cdf0e10cSrcweir     EditPaM aPos( CreateEditPaM( pConvInfo->aConvContinue ) );
1716cdf0e10cSrcweir 	EditSelection aCurSel = EditSelection( aPos, aPos );
1717cdf0e10cSrcweir 
1718cdf0e10cSrcweir     String aWord;
1719cdf0e10cSrcweir 
1720cdf0e10cSrcweir     while (!aRes.Len())
1721cdf0e10cSrcweir     {
1722cdf0e10cSrcweir         // empty paragraph found that needs to have language and font set?
1723cdf0e10cSrcweir 		if (bAllowImplicitChangesForNotConvertibleText &&
1724cdf0e10cSrcweir             !pEditEngine->GetText( pConvInfo->aConvContinue.nPara ).Len())
1725cdf0e10cSrcweir 		{
1726*7a980842SDamjanJovanovic 			sal_uInt32 nPara = pConvInfo->aConvContinue.nPara;
1727cdf0e10cSrcweir             ESelection aESel( nPara, 0, nPara, 0 );
1728cdf0e10cSrcweir             // see comment for below same function call
1729cdf0e10cSrcweir             SetLanguageAndFont( aESel,
1730cdf0e10cSrcweir                     nTargetLang, EE_CHAR_LANGUAGE_CJK,
1731cdf0e10cSrcweir                     pTargetFont, EE_CHAR_FONTINFO_CJK );
1732cdf0e10cSrcweir 		}
1733cdf0e10cSrcweir 
1734cdf0e10cSrcweir 
1735cdf0e10cSrcweir 		if (pConvInfo->aConvContinue.nPara  == pConvInfo->aConvTo.nPara &&
1736cdf0e10cSrcweir 			pConvInfo->aConvContinue.nIndex >= pConvInfo->aConvTo.nIndex)
1737cdf0e10cSrcweir 			break;
1738cdf0e10cSrcweir 
1739cdf0e10cSrcweir /*
1740cdf0e10cSrcweir         // Bekannter (wahrscheinlicher) Bug: Wenn SpellToCurrent, muss
1741cdf0e10cSrcweir         // Current bei jeder Ersetzung korrigiert werden, sonst passt
1742cdf0e10cSrcweir         // das Ende evtl. nicht mehr genau...
1743cdf0e10cSrcweir         if ( pConvInfo->bConvToEnd || pConvInfo->bMultipleDoc )
1744cdf0e10cSrcweir         {
1745cdf0e10cSrcweir             if ( aCurSel.Max().GetNode() == pLastNode &&
1746cdf0e10cSrcweir                  aCurSel.Max().GetIndex() >= pLastNode->Len() )
1747cdf0e10cSrcweir                 break;
1748cdf0e10cSrcweir         }
1749cdf0e10cSrcweir */
1750cdf0e10cSrcweir 
1751cdf0e10cSrcweir 		sal_uInt16 nAttribStart	= USHRT_MAX;
1752cdf0e10cSrcweir 		sal_uInt16 nAttribEnd	= USHRT_MAX;
1753cdf0e10cSrcweir 		sal_uInt16 nCurPos		= USHRT_MAX;
1754cdf0e10cSrcweir 		EPaM aCurStart = CreateEPaM( aCurSel.Min() );
1755cdf0e10cSrcweir 		SvUShorts aPortions;
1756*7a980842SDamjanJovanovic 		pEditEngine->GetPortions( aCurStart.nPara, aPortions );
1757cdf0e10cSrcweir 		for ( sal_uInt16 nPos = 0; nPos < aPortions.Count(); ++nPos )
1758cdf0e10cSrcweir 		{
1759cdf0e10cSrcweir 			sal_uInt16 nEnd	  = aPortions.GetObject( nPos );
1760cdf0e10cSrcweir 			sal_uInt16 nStart = nPos > 0 ? aPortions.GetObject( nPos - 1 ) : 0;
1761cdf0e10cSrcweir 
1762cdf0e10cSrcweir             // the language attribute is obtained from the left character
1763cdf0e10cSrcweir             // (like usually all other attributes)
1764cdf0e10cSrcweir             // thus we usually have to add 1 in order to get the language
1765cdf0e10cSrcweir             // of the text right to the cursor position
1766cdf0e10cSrcweir             sal_uInt16 nLangIdx = nEnd > nStart ? nStart + 1 : nStart;
1767cdf0e10cSrcweir             LanguageType nLangFound = pEditEngine->GetLanguage( aCurStart.nPara, nLangIdx );
1768cdf0e10cSrcweir #ifdef DEBUG
1769cdf0e10cSrcweir             lang::Locale aLocale( SvxCreateLocale( nLangFound ) );
1770cdf0e10cSrcweir #endif
1771cdf0e10cSrcweir             sal_Bool bLangOk =  (nLangFound == nSrcLang) ||
1772cdf0e10cSrcweir                                 (editeng::HangulHanjaConversion::IsChinese( nLangFound ) &&
1773cdf0e10cSrcweir                                  editeng::HangulHanjaConversion::IsChinese( nSrcLang ));
1774cdf0e10cSrcweir 
1775cdf0e10cSrcweir             if (nAttribEnd != USHRT_MAX) // start already found?
1776cdf0e10cSrcweir 			{
1777cdf0e10cSrcweir 				DBG_ASSERT(nEnd >= aCurStart.nIndex, "error while scanning attributes (a)" );
1778cdf0e10cSrcweir 				DBG_ASSERT(nEnd >= nAttribEnd, "error while scanning attributes (b)" );
1779cdf0e10cSrcweir 				if (/*nEnd >= aCurStart.nIndex &&*/ nLangFound == nResLang)
1780cdf0e10cSrcweir 					nAttribEnd = nEnd;
1781cdf0e10cSrcweir 				else  // language attrib has changed
1782cdf0e10cSrcweir 					break;
1783cdf0e10cSrcweir 			}
1784cdf0e10cSrcweir 			if (nAttribStart == USHRT_MAX && // start not yet found?
1785cdf0e10cSrcweir 				nEnd > aCurStart.nIndex && bLangOk)
1786cdf0e10cSrcweir 			{
1787cdf0e10cSrcweir 				nAttribStart = nStart;
1788cdf0e10cSrcweir 				nAttribEnd   = nEnd;
1789cdf0e10cSrcweir 				nResLang = nLangFound;
1790cdf0e10cSrcweir 			}
1791cdf0e10cSrcweir 			//! the list of portions may have changed compared to the previous
1792cdf0e10cSrcweir 			//! call to this function (because of possibly changed language
1793cdf0e10cSrcweir 			//! attribute!)
1794cdf0e10cSrcweir 			//! But since we don't want to start in the already processed part
1795cdf0e10cSrcweir 			//! we clip the start accordingly.
1796cdf0e10cSrcweir 			if (nAttribStart < aCurStart.nIndex)
1797cdf0e10cSrcweir 			{
1798cdf0e10cSrcweir 				nAttribStart = aCurStart.nIndex;
1799cdf0e10cSrcweir 			}
1800cdf0e10cSrcweir 
1801cdf0e10cSrcweir             // check script type to the right of the start of the current portion
1802cdf0e10cSrcweir             EditPaM aPaM( CreateEditPaM( EPaM(aCurStart.nPara, nLangIdx) ) );
1803cdf0e10cSrcweir             sal_Bool bIsAsianScript = (i18n::ScriptType::ASIAN == GetScriptType( aPaM ));
1804cdf0e10cSrcweir             // not yet processed text part with for conversion
1805cdf0e10cSrcweir             // not suitable language found that needs to be changed?
1806cdf0e10cSrcweir             if (bAllowImplicitChangesForNotConvertibleText &&
1807cdf0e10cSrcweir                 !bLangOk && !bIsAsianScript && nEnd > aCurStart.nIndex)
1808cdf0e10cSrcweir 			{
1809cdf0e10cSrcweir                 ESelection aESel( aCurStart.nPara, nStart, aCurStart.nPara, nEnd );
1810cdf0e10cSrcweir 				// set language and font to target language and font of conversion
1811cdf0e10cSrcweir 				//! Now this especially includes all non convertible text e.g.
1812cdf0e10cSrcweir 				//! spaces, empty paragraphs and western text.
1813cdf0e10cSrcweir 				// This is in order for every *new* text entered at *any* position to
1814cdf0e10cSrcweir 				// have the correct language and font attributes set.
1815cdf0e10cSrcweir                 SetLanguageAndFont( aESel,
1816cdf0e10cSrcweir                         nTargetLang, EE_CHAR_LANGUAGE_CJK,
1817cdf0e10cSrcweir                         pTargetFont, EE_CHAR_FONTINFO_CJK );
1818cdf0e10cSrcweir 			}
1819cdf0e10cSrcweir 
1820cdf0e10cSrcweir 			nCurPos = nEnd;
1821cdf0e10cSrcweir 		}
1822cdf0e10cSrcweir 
1823cdf0e10cSrcweir 		if (nAttribStart != USHRT_MAX  &&  nAttribEnd != USHRT_MAX)
1824cdf0e10cSrcweir 		{
1825cdf0e10cSrcweir 			aCurSel.Min().SetIndex( nAttribStart );
1826cdf0e10cSrcweir 			aCurSel.Max().SetIndex( nAttribEnd );
1827cdf0e10cSrcweir 		}
1828cdf0e10cSrcweir 		else if (nCurPos != USHRT_MAX)
1829cdf0e10cSrcweir 		{
1830cdf0e10cSrcweir 			// set selection to end of scanned text
1831cdf0e10cSrcweir 			// (used to set the position where to continue from later on)
1832cdf0e10cSrcweir 			aCurSel.Min().SetIndex( nCurPos );
1833cdf0e10cSrcweir 			aCurSel.Max().SetIndex( nCurPos );
1834cdf0e10cSrcweir 		}
1835cdf0e10cSrcweir 
1836cdf0e10cSrcweir 		if ( !pConvInfo->bConvToEnd )
1837cdf0e10cSrcweir         {
1838cdf0e10cSrcweir             EPaM aEPaM( CreateEPaM( aCurSel.Min() ) );
1839cdf0e10cSrcweir             if ( !( aEPaM < pConvInfo->aConvTo ) )
1840cdf0e10cSrcweir                 break;
1841cdf0e10cSrcweir         }
1842cdf0e10cSrcweir 
1843cdf0e10cSrcweir 		// clip selected word to the converted area
1844cdf0e10cSrcweir 		// (main use when conversion starts/ends **within** a word)
1845cdf0e10cSrcweir 		EditPaM aPaM( CreateEditPaM( pConvInfo->aConvStart ) );
1846cdf0e10cSrcweir 		if (pConvInfo->bConvToEnd &&
1847cdf0e10cSrcweir 			aCurSel.Min().GetNode() == aPaM.GetNode() &&
1848cdf0e10cSrcweir 			aCurSel.Min().GetIndex() < aPaM.GetIndex())
1849cdf0e10cSrcweir 				aCurSel.Min().SetIndex( aPaM.GetIndex() );
1850cdf0e10cSrcweir 		aPaM = CreateEditPaM( pConvInfo->aConvContinue );
1851cdf0e10cSrcweir 		if (aCurSel.Min().GetNode() == aPaM.GetNode() &&
1852cdf0e10cSrcweir 			aCurSel.Min().GetIndex() < aPaM.GetIndex())
1853cdf0e10cSrcweir 				aCurSel.Min().SetIndex( aPaM.GetIndex() );
1854cdf0e10cSrcweir 		aPaM = CreateEditPaM( pConvInfo->aConvTo );
1855cdf0e10cSrcweir 		if ((!pConvInfo->bConvToEnd || rConvRange.HasRange())&&
1856cdf0e10cSrcweir 			aCurSel.Max().GetNode() == aPaM.GetNode() &&
1857cdf0e10cSrcweir 			aCurSel.Max().GetIndex() > aPaM.GetIndex())
1858cdf0e10cSrcweir 				aCurSel.Max().SetIndex( aPaM.GetIndex() );
1859cdf0e10cSrcweir 
1860cdf0e10cSrcweir 		aWord = GetSelected( aCurSel );
1861cdf0e10cSrcweir 
1862cdf0e10cSrcweir         if ( aWord.Len() > 0 /* && bLangOk */)
1863cdf0e10cSrcweir             aRes = aWord;
1864cdf0e10cSrcweir 
1865cdf0e10cSrcweir 		// move to next word/paragraph if necessary
1866cdf0e10cSrcweir         if ( !aRes.Len() )
1867cdf0e10cSrcweir             aCurSel = WordRight( aCurSel.Min(), ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
1868cdf0e10cSrcweir 
1869cdf0e10cSrcweir         pConvInfo->aConvContinue = CreateEPaM( aCurSel.Max() );
1870cdf0e10cSrcweir     }
1871cdf0e10cSrcweir 
1872cdf0e10cSrcweir     pEditView->pImpEditView->DrawSelection();
1873cdf0e10cSrcweir     pEditView->pImpEditView->SetEditSelection( aCurSel );
1874cdf0e10cSrcweir     pEditView->pImpEditView->DrawSelection();
1875cdf0e10cSrcweir     pEditView->ShowCursor( sal_True, sal_False );
1876cdf0e10cSrcweir 
1877cdf0e10cSrcweir     rConvTxt = aRes;
1878cdf0e10cSrcweir     if (rConvTxt.getLength())
1879cdf0e10cSrcweir         rConvTxtLang = nResLang;
1880cdf0e10cSrcweir #endif
1881cdf0e10cSrcweir }
1882cdf0e10cSrcweir 
1883cdf0e10cSrcweir 
ImpSpell(EditView * pEditView)1884cdf0e10cSrcweir Reference< XSpellAlternatives > ImpEditEngine::ImpSpell( EditView* pEditView )
1885cdf0e10cSrcweir {
1886cdf0e10cSrcweir #ifdef SVX_LIGHT
1887cdf0e10cSrcweir 	return Reference< XSpellAlternatives >();
1888cdf0e10cSrcweir #else
1889cdf0e10cSrcweir 
1890cdf0e10cSrcweir 	DBG_ASSERT( xSpeller.is(), "Kein Speller gesetzt!" );
1891cdf0e10cSrcweir 
1892cdf0e10cSrcweir     ContentNode* pLastNode = aEditDoc.SaveGetObject( (aEditDoc.Count()-1) );
1893cdf0e10cSrcweir 	EditSelection aCurSel( pEditView->pImpEditView->GetEditSelection() );
1894cdf0e10cSrcweir     aCurSel.Min() = aCurSel.Max();
1895cdf0e10cSrcweir 
1896cdf0e10cSrcweir 	String aWord;
1897cdf0e10cSrcweir 	Reference< XSpellAlternatives > xSpellAlt;
1898cdf0e10cSrcweir 	Sequence< PropertyValue > aEmptySeq;
1899cdf0e10cSrcweir 	while (!xSpellAlt.is())
1900cdf0e10cSrcweir 	{
1901cdf0e10cSrcweir 
1902cdf0e10cSrcweir 		// Bekannter (wahrscheinlicher) Bug: Wenn SpellToCurrent, muss
1903cdf0e10cSrcweir 		// Current bei jeder Ersetzung korrigiert werden, sonst passt
1904cdf0e10cSrcweir 		// das Ende evtl. nicht mehr genau...
1905cdf0e10cSrcweir 		if ( pSpellInfo->bSpellToEnd || pSpellInfo->bMultipleDoc )
1906cdf0e10cSrcweir 		{
1907cdf0e10cSrcweir 			if ( aCurSel.Max().GetNode() == pLastNode )
1908cdf0e10cSrcweir 			{
1909cdf0e10cSrcweir                 if ( ( aCurSel.Max().GetIndex() >= pLastNode->Len() ) )
1910cdf0e10cSrcweir 					break;
1911cdf0e10cSrcweir 			}
1912cdf0e10cSrcweir 		}
1913cdf0e10cSrcweir 		else if ( !pSpellInfo->bSpellToEnd )
1914cdf0e10cSrcweir 		{
1915cdf0e10cSrcweir 			EPaM aEPaM( CreateEPaM( aCurSel.Max() ) );
1916cdf0e10cSrcweir             if ( !( aEPaM < pSpellInfo->aSpellTo ) )
1917cdf0e10cSrcweir 				break;
1918cdf0e10cSrcweir 		}
1919cdf0e10cSrcweir 
1920cdf0e10cSrcweir 		aCurSel = SelectWord( aCurSel, ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
1921cdf0e10cSrcweir 		aWord = GetSelected( aCurSel );
1922cdf0e10cSrcweir 
1923cdf0e10cSrcweir 		// Wenn Punkt dahinter, muss dieser mit uebergeben werden !
1924cdf0e10cSrcweir 		// Falls Abkuerzung...
1925cdf0e10cSrcweir 		if ( aWord.Len() && ( aCurSel.Max().GetIndex() < aCurSel.Max().GetNode()->Len() ) )
1926cdf0e10cSrcweir 		{
1927cdf0e10cSrcweir 			sal_Unicode cNext = aCurSel.Max().GetNode()->GetChar( aCurSel.Max().GetIndex() );
1928cdf0e10cSrcweir 			if ( cNext == '.' )
1929cdf0e10cSrcweir 			{
1930cdf0e10cSrcweir 				aCurSel.Max().GetIndex()++;
1931cdf0e10cSrcweir 				aWord += cNext;
1932cdf0e10cSrcweir 			}
1933cdf0e10cSrcweir 		}
1934cdf0e10cSrcweir 
1935cdf0e10cSrcweir 		if ( aWord.Len() > 0 )
1936cdf0e10cSrcweir 		{
1937cdf0e10cSrcweir 			LanguageType eLang = GetLanguage( aCurSel.Max() );
1938cdf0e10cSrcweir 			SvxSpellWrapper::CheckSpellLang( xSpeller, eLang );
1939cdf0e10cSrcweir 			xSpellAlt = xSpeller->spell( aWord, eLang, aEmptySeq );
1940cdf0e10cSrcweir 		}
1941cdf0e10cSrcweir 
1942cdf0e10cSrcweir 		if ( !xSpellAlt.is() )
1943cdf0e10cSrcweir 			aCurSel = WordRight( aCurSel.Min(), ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
1944cdf0e10cSrcweir 		else
1945cdf0e10cSrcweir 			pSpellInfo->eState = EE_SPELL_ERRORFOUND;
1946cdf0e10cSrcweir 	}
1947cdf0e10cSrcweir 
1948cdf0e10cSrcweir 	pEditView->pImpEditView->DrawSelection();
1949cdf0e10cSrcweir 	pEditView->pImpEditView->SetEditSelection( aCurSel );
1950cdf0e10cSrcweir 	pEditView->pImpEditView->DrawSelection();
1951cdf0e10cSrcweir 	pEditView->ShowCursor( sal_True, sal_False );
1952cdf0e10cSrcweir 	return xSpellAlt;
1953cdf0e10cSrcweir #endif
1954cdf0e10cSrcweir }
1955cdf0e10cSrcweir /*-- 13.10.2003 16:43:27---------------------------------------------------
1956cdf0e10cSrcweir 
1957cdf0e10cSrcweir   -----------------------------------------------------------------------*/
EndSpelling()1958cdf0e10cSrcweir void ImpEditEngine::EndSpelling()
1959cdf0e10cSrcweir {
1960cdf0e10cSrcweir     DELETEZ(pSpellInfo);
1961cdf0e10cSrcweir }
1962cdf0e10cSrcweir /*-- 13.10.2003 16:43:27---------------------------------------------------
1963cdf0e10cSrcweir 
1964cdf0e10cSrcweir   -----------------------------------------------------------------------*/
StartSpelling(EditView & rEditView,sal_Bool bMultipleDoc)1965cdf0e10cSrcweir void ImpEditEngine::StartSpelling(EditView& rEditView, sal_Bool bMultipleDoc)
1966cdf0e10cSrcweir {
1967cdf0e10cSrcweir     DBG_ASSERT(!pSpellInfo, "pSpellInfo already set?");
1968cdf0e10cSrcweir     rEditView.pImpEditView->SetEditSelection( aEditDoc.GetStartPaM() );
1969cdf0e10cSrcweir     EditSelection aCurSel( rEditView.pImpEditView->GetEditSelection() );
1970cdf0e10cSrcweir     pSpellInfo = CreateSpellInfo( aCurSel, bMultipleDoc );
1971cdf0e10cSrcweir }
1972cdf0e10cSrcweir /*-- 13.10.2003 16:43:27---------------------------------------------------
1973cdf0e10cSrcweir     Search for the next wrong word within the given selection
1974cdf0e10cSrcweir   -----------------------------------------------------------------------*/
ImpFindNextError(EditSelection & rSelection)1975cdf0e10cSrcweir Reference< XSpellAlternatives > ImpEditEngine::ImpFindNextError(EditSelection& rSelection)
1976cdf0e10cSrcweir {
1977cdf0e10cSrcweir     /* ContentNode* pLastNode = */ aEditDoc.SaveGetObject( (aEditDoc.Count()-1) );
1978cdf0e10cSrcweir     EditSelection aCurSel( rSelection.Min() );
1979cdf0e10cSrcweir 
1980cdf0e10cSrcweir     String aWord;
1981cdf0e10cSrcweir     Reference< XSpellAlternatives > xSpellAlt;
1982cdf0e10cSrcweir     Sequence< PropertyValue > aEmptySeq;
1983cdf0e10cSrcweir     while (!xSpellAlt.is())
1984cdf0e10cSrcweir     {
1985cdf0e10cSrcweir         //check if the end of the selection has been reached
1986cdf0e10cSrcweir         {
1987cdf0e10cSrcweir             EPaM aEPaM( CreateEPaM( aCurSel.Max() ) );
1988cdf0e10cSrcweir             if ( !( aEPaM < CreateEPaM( rSelection.Max()) ) )
1989cdf0e10cSrcweir                 break;
1990cdf0e10cSrcweir         }
1991cdf0e10cSrcweir 
1992cdf0e10cSrcweir         aCurSel = SelectWord( aCurSel, ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
1993cdf0e10cSrcweir         aWord = GetSelected( aCurSel );
1994cdf0e10cSrcweir 
1995cdf0e10cSrcweir         // Wenn Punkt dahinter, muss dieser mit uebergeben werden !
1996cdf0e10cSrcweir         // Falls Abkuerzung...
1997cdf0e10cSrcweir         if ( aWord.Len() && ( aCurSel.Max().GetIndex() < aCurSel.Max().GetNode()->Len() ) )
1998cdf0e10cSrcweir         {
1999cdf0e10cSrcweir             sal_Unicode cNext = aCurSel.Max().GetNode()->GetChar( aCurSel.Max().GetIndex() );
2000cdf0e10cSrcweir             if ( cNext == '.' )
2001cdf0e10cSrcweir             {
2002cdf0e10cSrcweir                 aCurSel.Max().GetIndex()++;
2003cdf0e10cSrcweir                 aWord += cNext;
2004cdf0e10cSrcweir             }
2005cdf0e10cSrcweir         }
2006cdf0e10cSrcweir 
2007cdf0e10cSrcweir         if ( aWord.Len() > 0 )
2008cdf0e10cSrcweir             xSpellAlt = xSpeller->spell( aWord, GetLanguage( aCurSel.Max() ), aEmptySeq );
2009cdf0e10cSrcweir 
2010cdf0e10cSrcweir         if ( !xSpellAlt.is() )
2011cdf0e10cSrcweir             aCurSel = WordRight( aCurSel.Min(), ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
2012cdf0e10cSrcweir         else
2013cdf0e10cSrcweir 		{
2014cdf0e10cSrcweir             pSpellInfo->eState = EE_SPELL_ERRORFOUND;
2015cdf0e10cSrcweir 			rSelection = aCurSel;
2016cdf0e10cSrcweir 		}
2017cdf0e10cSrcweir     }
2018cdf0e10cSrcweir     return xSpellAlt;
2019cdf0e10cSrcweir }
2020cdf0e10cSrcweir /*-- 13.10.2003 16:43:27---------------------------------------------------
2021cdf0e10cSrcweir 
2022cdf0e10cSrcweir   -----------------------------------------------------------------------*/
SpellSentence(EditView & rEditView,::svx::SpellPortions & rToFill,bool)2023cdf0e10cSrcweir bool ImpEditEngine::SpellSentence(EditView& rEditView,
2024cdf0e10cSrcweir     ::svx::SpellPortions& rToFill,
2025cdf0e10cSrcweir     bool /*bIsGrammarChecking*/ )
2026cdf0e10cSrcweir {
2027cdf0e10cSrcweir #ifdef SVX_LIGHT
2028cdf0e10cSrcweir #else
2029cdf0e10cSrcweir     bool bRet = false;
2030cdf0e10cSrcweir     EditSelection aCurSel( rEditView.pImpEditView->GetEditSelection() );
2031cdf0e10cSrcweir     if(!pSpellInfo)
2032cdf0e10cSrcweir 		pSpellInfo = CreateSpellInfo( aCurSel, true );
2033cdf0e10cSrcweir     pSpellInfo->aCurSentenceStart = aCurSel.Min();
2034cdf0e10cSrcweir     DBG_ASSERT( xSpeller.is(), "Kein Speller gesetzt!" );
2035cdf0e10cSrcweir     pSpellInfo->aLastSpellPortions.clear();
2036cdf0e10cSrcweir     pSpellInfo->aLastSpellContentSelections.clear();
2037cdf0e10cSrcweir     rToFill.clear();
2038cdf0e10cSrcweir     //if no selection previously exists the range is extended to the end of the object
2039cdf0e10cSrcweir     if(aCurSel.Min() == aCurSel.Max())
2040cdf0e10cSrcweir     {
2041cdf0e10cSrcweir         ContentNode* pLastNode = aEditDoc.SaveGetObject( aEditDoc.Count()-1);
2042cdf0e10cSrcweir         aCurSel.Max() = EditPaM(pLastNode, pLastNode->Len());
2043cdf0e10cSrcweir     }
2044cdf0e10cSrcweir     // check for next error in aCurSel and set aCurSel to that one if any was found
2045cdf0e10cSrcweir     Reference< XSpellAlternatives > xAlt = ImpFindNextError(aCurSel);
2046cdf0e10cSrcweir     if (xAlt.is())
2047cdf0e10cSrcweir     {
2048cdf0e10cSrcweir         bRet = true;
2049cdf0e10cSrcweir 		//find the sentence boundaries
2050cdf0e10cSrcweir         EditSelection aSentencePaM = SelectSentence(aCurSel);
2051cdf0e10cSrcweir         //make sure that the sentence is never smaller than the error range!
2052cdf0e10cSrcweir         if(aSentencePaM.Max().GetIndex() < aCurSel.Max().GetIndex())
2053cdf0e10cSrcweir             aSentencePaM.Max() = aCurSel.Max();
205407a3d7f1SPedro Giffuni         //add the portion preceding the error
2055cdf0e10cSrcweir         EditSelection aStartSelection(aSentencePaM.Min(), aCurSel.Min());
2056cdf0e10cSrcweir         if(aStartSelection.HasRange())
2057cdf0e10cSrcweir 			AddPortionIterated(rEditView, aStartSelection, 0, rToFill);
2058cdf0e10cSrcweir         //add the error portion
2059cdf0e10cSrcweir         AddPortionIterated(rEditView, aCurSel, xAlt, rToFill);
2060cdf0e10cSrcweir         //find the end of the sentence
2061cdf0e10cSrcweir         //search for all errors in the rest of the sentence and add all the portions
2062cdf0e10cSrcweir         do
2063cdf0e10cSrcweir         {
2064cdf0e10cSrcweir             EditSelection aNextSel = EditSelection(aCurSel.Max(), aSentencePaM.Max());
2065cdf0e10cSrcweir             xAlt = ImpFindNextError(aNextSel);
2066cdf0e10cSrcweir             if(xAlt.is())
2067cdf0e10cSrcweir             {
2068cdf0e10cSrcweir                 //add the part between the previous and the current error
2069cdf0e10cSrcweir 				AddPortionIterated(rEditView, EditSelection(aCurSel.Max(), aNextSel.Min()), 0, rToFill);
2070cdf0e10cSrcweir                 //add the current error
2071cdf0e10cSrcweir 				AddPortionIterated(rEditView, aNextSel, xAlt, rToFill);
2072cdf0e10cSrcweir             }
2073cdf0e10cSrcweir             else
2074cdf0e10cSrcweir                 AddPortionIterated(rEditView, EditSelection(aCurSel.Max(), aSentencePaM.Max()), xAlt, rToFill);
2075cdf0e10cSrcweir 			aCurSel = aNextSel;
2076cdf0e10cSrcweir         }
2077cdf0e10cSrcweir         while( xAlt.is() );
2078cdf0e10cSrcweir 
2079cdf0e10cSrcweir 		//set the selection to the end of the current sentence
2080cdf0e10cSrcweir 		rEditView.pImpEditView->SetEditSelection(aSentencePaM.Max());
2081cdf0e10cSrcweir     }
2082cdf0e10cSrcweir #endif
2083cdf0e10cSrcweir     return bRet;
2084cdf0e10cSrcweir }
2085cdf0e10cSrcweir 
2086cdf0e10cSrcweir /*-- 15.10.2003 16:09:12---------------------------------------------------
2087cdf0e10cSrcweir     adds one portion to the SpellPortions
2088cdf0e10cSrcweir   -----------------------------------------------------------------------*/
AddPortion(const EditSelection rSel,uno::Reference<XSpellAlternatives> xAlt,::svx::SpellPortions & rToFill,bool bIsField)2089cdf0e10cSrcweir void ImpEditEngine::AddPortion(
2090cdf0e10cSrcweir                             const EditSelection rSel,
2091cdf0e10cSrcweir                             uno::Reference< XSpellAlternatives > xAlt,
2092cdf0e10cSrcweir                                 ::svx::SpellPortions& rToFill,
2093cdf0e10cSrcweir                                 bool bIsField)
2094cdf0e10cSrcweir {
2095cdf0e10cSrcweir #ifdef SVX_LIGHT
2096cdf0e10cSrcweir #else
2097cdf0e10cSrcweir     if(rSel.HasRange())
2098cdf0e10cSrcweir 	{
2099cdf0e10cSrcweir 		svx::SpellPortion aPortion;
2100cdf0e10cSrcweir 		aPortion.sText = GetSelected( rSel );
2101cdf0e10cSrcweir 		aPortion.eLanguage = GetLanguage( rSel.Min() );
2102cdf0e10cSrcweir 		aPortion.xAlternatives = xAlt;
2103cdf0e10cSrcweir         aPortion.bIsField = bIsField;
2104cdf0e10cSrcweir         rToFill.push_back(aPortion);
2105cdf0e10cSrcweir 
2106cdf0e10cSrcweir 		//save the spelled portions for later use
2107cdf0e10cSrcweir 		pSpellInfo->aLastSpellPortions.push_back(aPortion);
2108cdf0e10cSrcweir 		pSpellInfo->aLastSpellContentSelections.push_back(rSel);
2109cdf0e10cSrcweir 
2110cdf0e10cSrcweir 	}
2111cdf0e10cSrcweir #endif
2112cdf0e10cSrcweir }
2113cdf0e10cSrcweir 
2114cdf0e10cSrcweir /*-- 15.10.2003 16:07:47---------------------------------------------------
2115cdf0e10cSrcweir     adds one or more portions of text to the SpellPortions depending on language changes
2116cdf0e10cSrcweir   -----------------------------------------------------------------------*/
AddPortionIterated(EditView & rEditView,const EditSelection rSel,Reference<XSpellAlternatives> xAlt,::svx::SpellPortions & rToFill)2117cdf0e10cSrcweir void ImpEditEngine::AddPortionIterated(
2118cdf0e10cSrcweir                             EditView& rEditView,
2119cdf0e10cSrcweir                             const EditSelection rSel,
2120cdf0e10cSrcweir                             Reference< XSpellAlternatives > xAlt,
2121cdf0e10cSrcweir                                 ::svx::SpellPortions& rToFill)
2122cdf0e10cSrcweir {
2123cdf0e10cSrcweir #ifdef SVX_LIGHT
2124cdf0e10cSrcweir #else
2125cdf0e10cSrcweir     if(rSel.Min() != rSel.Max())
2126cdf0e10cSrcweir     {
2127cdf0e10cSrcweir         if(xAlt.is())
2128cdf0e10cSrcweir         {
2129cdf0e10cSrcweir             AddPortion(rSel, xAlt, rToFill, false);
2130cdf0e10cSrcweir         }
2131cdf0e10cSrcweir         else
2132cdf0e10cSrcweir         {
2133cdf0e10cSrcweir             //iterate and search for language attribute changes
2134cdf0e10cSrcweir             //save the start and end positions
2135cdf0e10cSrcweir             bool bTest = rSel.Min().GetIndex() <= rSel.Max().GetIndex();
2136cdf0e10cSrcweir             EditPaM aStart(bTest ? rSel.Min() : rSel.Max());
2137cdf0e10cSrcweir             EditPaM aEnd(bTest ? rSel.Max() : rSel.Min());
2138cdf0e10cSrcweir             //iterate over the text to find changes in language
2139cdf0e10cSrcweir             //set the mark equal to the point
2140cdf0e10cSrcweir             EditPaM aCursor(aStart);
2141cdf0e10cSrcweir             rEditView.pImpEditView->SetEditSelection( aCursor );
2142cdf0e10cSrcweir             LanguageType eStartLanguage = GetLanguage( aCursor );
2143cdf0e10cSrcweir             //search for a field attribute at the beginning - only the end position
2144cdf0e10cSrcweir             //of this field is kept to end a portion at that position
2145cdf0e10cSrcweir             const EditCharAttrib* pFieldAttr = aCursor.GetNode()->GetCharAttribs().
2146cdf0e10cSrcweir                                                     FindFeature( aCursor.GetIndex() );
2147cdf0e10cSrcweir             bool bIsField = pFieldAttr &&
2148cdf0e10cSrcweir                     pFieldAttr->GetStart() == aCursor.GetIndex() &&
2149cdf0e10cSrcweir                     pFieldAttr->GetStart() != pFieldAttr->GetEnd() &&
2150cdf0e10cSrcweir                     pFieldAttr->Which() == EE_FEATURE_FIELD;
2151cdf0e10cSrcweir             sal_uInt16 nEndField = bIsField ? pFieldAttr->GetEnd() : USHRT_MAX;
2152cdf0e10cSrcweir 			bool bIsEndField = false;
2153cdf0e10cSrcweir             do
2154cdf0e10cSrcweir             {
2155cdf0e10cSrcweir                 aCursor = CursorRight( aCursor);
2156cdf0e10cSrcweir                 //determine whether a field and has been reached
2157cdf0e10cSrcweir 				bIsEndField = nEndField == aCursor.GetIndex();
2158cdf0e10cSrcweir                 //search for a new field attribute
2159cdf0e10cSrcweir                 EditCharAttrib* _pFieldAttr = aCursor.GetNode()->GetCharAttribs().
2160cdf0e10cSrcweir                                                         FindFeature( aCursor.GetIndex() );
2161cdf0e10cSrcweir                 bIsField = _pFieldAttr &&
2162cdf0e10cSrcweir                         _pFieldAttr->GetStart() == aCursor.GetIndex() &&
2163cdf0e10cSrcweir                         _pFieldAttr->GetStart() != _pFieldAttr->GetEnd() &&
2164cdf0e10cSrcweir                         _pFieldAttr->Which() == EE_FEATURE_FIELD;
2165cdf0e10cSrcweir                 //on every new field move the end position
2166cdf0e10cSrcweir                 if(bIsField)
2167cdf0e10cSrcweir                     nEndField = bIsField ? _pFieldAttr->GetEnd() : USHRT_MAX;
2168cdf0e10cSrcweir 
2169cdf0e10cSrcweir                 LanguageType eCurLanguage = GetLanguage( aCursor );
2170cdf0e10cSrcweir                 if(eCurLanguage != eStartLanguage || bIsField || bIsEndField)
2171cdf0e10cSrcweir                 {
2172cdf0e10cSrcweir                     eStartLanguage = eCurLanguage;
2173cdf0e10cSrcweir                     //go one step back - the cursor currently selects the first character
2174cdf0e10cSrcweir                     //with a different language
2175cdf0e10cSrcweir                     //create a selection from start to the current Cursor
2176cdf0e10cSrcweir                     EditSelection aSelection(aStart, aCursor);
2177cdf0e10cSrcweir                     AddPortion(aSelection, xAlt, rToFill, bIsEndField);
2178cdf0e10cSrcweir                     aStart = aCursor;
2179cdf0e10cSrcweir                 }
2180cdf0e10cSrcweir             }
2181cdf0e10cSrcweir             while(aCursor.GetIndex() < aEnd.GetIndex());
2182cdf0e10cSrcweir             EditSelection aSelection(aStart, aCursor);
2183cdf0e10cSrcweir             AddPortion(aSelection, xAlt, rToFill, bIsField);
2184cdf0e10cSrcweir         }
2185cdf0e10cSrcweir     }
2186cdf0e10cSrcweir #endif
2187cdf0e10cSrcweir }
2188cdf0e10cSrcweir 
2189cdf0e10cSrcweir /*-- 13.10.2003 16:43:33---------------------------------------------------
2190cdf0e10cSrcweir 
2191cdf0e10cSrcweir   -----------------------------------------------------------------------*/
ApplyChangedSentence(EditView & rEditView,const::svx::SpellPortions & rNewPortions,bool bRecheck)2192cdf0e10cSrcweir void ImpEditEngine::ApplyChangedSentence(EditView& rEditView,
2193cdf0e10cSrcweir     const ::svx::SpellPortions& rNewPortions,
2194cdf0e10cSrcweir     bool bRecheck )
2195cdf0e10cSrcweir {
2196cdf0e10cSrcweir #ifdef SVX_LIGHT
2197cdf0e10cSrcweir #else
2198cdf0e10cSrcweir     // Note: rNewPortions.size() == 0 is valid and happens when the whole
2199cdf0e10cSrcweir     // sentence got removed in the dialog
2200cdf0e10cSrcweir 
2201cdf0e10cSrcweir     DBG_ASSERT(pSpellInfo, "pSpellInfo not initialized");
2202cdf0e10cSrcweir     if (pSpellInfo &&
2203cdf0e10cSrcweir         pSpellInfo->aLastSpellPortions.size() > 0)  // no portions -> no text to be changed
2204cdf0e10cSrcweir     {
2205cdf0e10cSrcweir         // get current paragraph length to calculate later on how the sentence length changed,
2206cdf0e10cSrcweir         // in order to place the cursor at the end of the sentence again
2207cdf0e10cSrcweir         EditSelection aOldSel( rEditView.pImpEditView->GetEditSelection() );
2208cdf0e10cSrcweir         xub_StrLen nOldLen = aOldSel.Max().GetNode()->Len();
2209cdf0e10cSrcweir 
2210cdf0e10cSrcweir         UndoActionStart( EDITUNDO_INSERT );
2211cdf0e10cSrcweir         if(pSpellInfo->aLastSpellPortions.size() == rNewPortions.size())
2212cdf0e10cSrcweir         {
2213cdf0e10cSrcweir             DBG_ASSERT( rNewPortions.size() > 0, "rNewPortions should not be empty here" );
2214cdf0e10cSrcweir             DBG_ASSERT( pSpellInfo->aLastSpellPortions.size() == pSpellInfo->aLastSpellContentSelections.size(),
2215cdf0e10cSrcweir                     "aLastSpellPortions and aLastSpellContentSelections size mismatch" );
2216cdf0e10cSrcweir 
2217cdf0e10cSrcweir             //the simple case: the same number of elements on both sides
2218cdf0e10cSrcweir             //each changed element has to be applied to the corresponding source element
2219cdf0e10cSrcweir             svx::SpellPortions::const_iterator aCurrentNewPortion = rNewPortions.end();
2220cdf0e10cSrcweir             svx::SpellPortions::const_iterator aCurrentOldPortion = pSpellInfo->aLastSpellPortions.end();
2221cdf0e10cSrcweir             SpellContentSelections::const_iterator aCurrentOldPosition = pSpellInfo->aLastSpellContentSelections.end();
2222cdf0e10cSrcweir             bool bSetToEnd = false;
2223cdf0e10cSrcweir 			do
2224cdf0e10cSrcweir             {
2225cdf0e10cSrcweir                 --aCurrentNewPortion;
2226cdf0e10cSrcweir                 --aCurrentOldPortion;
2227cdf0e10cSrcweir                 --aCurrentOldPosition;
2228cdf0e10cSrcweir 				//set the cursor to the end of the sentence - necessary to
2229cdf0e10cSrcweir 				//resume there at the next step
2230cdf0e10cSrcweir 				if(!bSetToEnd)
2231cdf0e10cSrcweir 				{
2232cdf0e10cSrcweir 					bSetToEnd = true;
2233cdf0e10cSrcweir 					rEditView.pImpEditView->SetEditSelection( aCurrentOldPosition->Max() );
2234cdf0e10cSrcweir 				}
2235cdf0e10cSrcweir 
2236cdf0e10cSrcweir                 sal_uInt16 nScriptType = GetI18NScriptTypeOfLanguage( aCurrentNewPortion->eLanguage );
2237cdf0e10cSrcweir //                LanguageType eTextLanguage = GetLanguage( aCurrentOldPosition->Min() );
2238cdf0e10cSrcweir 
2239cdf0e10cSrcweir                 sal_uInt16 nLangWhichId = EE_CHAR_LANGUAGE;
2240cdf0e10cSrcweir                 switch(nScriptType)
2241cdf0e10cSrcweir                 {
2242cdf0e10cSrcweir                     case SCRIPTTYPE_ASIAN : nLangWhichId = EE_CHAR_LANGUAGE_CJK; break;
2243cdf0e10cSrcweir                     case SCRIPTTYPE_COMPLEX : nLangWhichId = EE_CHAR_LANGUAGE_CTL; break;
2244cdf0e10cSrcweir                 }
2245cdf0e10cSrcweir                 if(aCurrentNewPortion->sText != aCurrentOldPortion->sText)
2246cdf0e10cSrcweir                 {
2247cdf0e10cSrcweir                     //change text and apply language
2248cdf0e10cSrcweir                     SfxItemSet aSet( aEditDoc.GetItemPool(), nLangWhichId, nLangWhichId);
2249cdf0e10cSrcweir                     aSet.Put(SvxLanguageItem(aCurrentNewPortion->eLanguage, nLangWhichId));
2250cdf0e10cSrcweir                     SetAttribs( *aCurrentOldPosition, aSet );
2251cdf0e10cSrcweir                     ImpInsertText( *aCurrentOldPosition, aCurrentNewPortion->sText );
2252cdf0e10cSrcweir                 }
2253cdf0e10cSrcweir                 else if(aCurrentNewPortion->eLanguage != aCurrentOldPortion->eLanguage)
2254cdf0e10cSrcweir                 {
2255cdf0e10cSrcweir                     //apply language
2256cdf0e10cSrcweir                     SfxItemSet aSet( aEditDoc.GetItemPool(), nLangWhichId, nLangWhichId);
2257cdf0e10cSrcweir                     aSet.Put(SvxLanguageItem(aCurrentNewPortion->eLanguage, nLangWhichId));
2258cdf0e10cSrcweir                     SetAttribs( *aCurrentOldPosition, aSet );
2259cdf0e10cSrcweir                 }
2260cdf0e10cSrcweir                 if(aCurrentNewPortion == rNewPortions.begin())
2261cdf0e10cSrcweir                     break;
2262cdf0e10cSrcweir             }
2263cdf0e10cSrcweir             while(aCurrentNewPortion != rNewPortions.begin());
2264cdf0e10cSrcweir         }
2265cdf0e10cSrcweir         else
2266cdf0e10cSrcweir         {
2267cdf0e10cSrcweir             DBG_ASSERT( pSpellInfo->aLastSpellContentSelections.size() > 0, "aLastSpellContentSelections should not be empty here" );
2268cdf0e10cSrcweir 
2269cdf0e10cSrcweir             //select the complete sentence
2270cdf0e10cSrcweir             SpellContentSelections::const_iterator aCurrentEndPosition = pSpellInfo->aLastSpellContentSelections.end();
2271cdf0e10cSrcweir             --aCurrentEndPosition;
2272cdf0e10cSrcweir             SpellContentSelections::const_iterator aCurrentStartPosition = pSpellInfo->aLastSpellContentSelections.begin();
2273cdf0e10cSrcweir             EditSelection aAllSentence(aCurrentStartPosition->Min(), aCurrentEndPosition->Max());
2274cdf0e10cSrcweir 
2275cdf0e10cSrcweir             //delete the sentence completely
2276cdf0e10cSrcweir             ImpDeleteSelection( aAllSentence );
2277cdf0e10cSrcweir             svx::SpellPortions::const_iterator aCurrentNewPortion = rNewPortions.begin();
2278cdf0e10cSrcweir             EditPaM aCurrentPaM = aAllSentence.Min();
2279cdf0e10cSrcweir             while(aCurrentNewPortion != rNewPortions.end())
2280cdf0e10cSrcweir             {
2281cdf0e10cSrcweir                 //set the language attribute
2282cdf0e10cSrcweir                 LanguageType eCurLanguage = GetLanguage( aCurrentPaM );
2283cdf0e10cSrcweir                 if(eCurLanguage != aCurrentNewPortion->eLanguage)
2284cdf0e10cSrcweir                 {
2285cdf0e10cSrcweir                     sal_uInt16 nScriptType = GetI18NScriptTypeOfLanguage( aCurrentNewPortion->eLanguage );
2286cdf0e10cSrcweir                     sal_uInt16 nLangWhichId = EE_CHAR_LANGUAGE;
2287cdf0e10cSrcweir                     switch(nScriptType)
2288cdf0e10cSrcweir                     {
2289cdf0e10cSrcweir                         case SCRIPTTYPE_ASIAN : nLangWhichId = EE_CHAR_LANGUAGE_CJK; break;
2290cdf0e10cSrcweir                         case SCRIPTTYPE_COMPLEX : nLangWhichId = EE_CHAR_LANGUAGE_CTL; break;
2291cdf0e10cSrcweir                     }
2292cdf0e10cSrcweir                     SfxItemSet aSet( aEditDoc.GetItemPool(), nLangWhichId, nLangWhichId);
2293cdf0e10cSrcweir                     aSet.Put(SvxLanguageItem(aCurrentNewPortion->eLanguage, nLangWhichId));
2294cdf0e10cSrcweir                     SetAttribs( aCurrentPaM, aSet );
2295cdf0e10cSrcweir                 }
2296cdf0e10cSrcweir                 //insert the new string and set the cursor to the end of the inserted string
2297cdf0e10cSrcweir                 aCurrentPaM = ImpInsertText( aCurrentPaM , aCurrentNewPortion->sText );
2298cdf0e10cSrcweir                 ++aCurrentNewPortion;
2299cdf0e10cSrcweir             }
2300cdf0e10cSrcweir         }
2301cdf0e10cSrcweir         UndoActionEnd( EDITUNDO_INSERT );
2302cdf0e10cSrcweir 
2303cdf0e10cSrcweir         EditPaM aNext;
2304cdf0e10cSrcweir         if (bRecheck)
2305cdf0e10cSrcweir             aNext = pSpellInfo->aCurSentenceStart;
2306cdf0e10cSrcweir         else
2307cdf0e10cSrcweir         {
2308cdf0e10cSrcweir             // restore cursor position to the end of the modified sentence.
2309cdf0e10cSrcweir             // (This will define the continuation position for spell/grammar checking)
2310cdf0e10cSrcweir             // First: check if the sentence/para length changed
2311cdf0e10cSrcweir             sal_Int32 nDelta = rEditView.pImpEditView->GetEditSelection().Max().GetNode()->Len() - nOldLen;
2312cdf0e10cSrcweir             xub_StrLen nEndOfSentence = aOldSel.Max().GetIndex() + nDelta;
2313cdf0e10cSrcweir             aNext = EditPaM( aOldSel.Max().GetNode(), nEndOfSentence );
2314cdf0e10cSrcweir         }
2315cdf0e10cSrcweir         rEditView.pImpEditView->SetEditSelection( aNext );
2316cdf0e10cSrcweir 
2317cdf0e10cSrcweir         FormatAndUpdate();
2318cdf0e10cSrcweir         aEditDoc.SetModified(sal_True);
2319cdf0e10cSrcweir     }
2320cdf0e10cSrcweir #endif
2321cdf0e10cSrcweir }
2322cdf0e10cSrcweir /*-- 08.09.2008 11:33:02---------------------------------------------------
2323cdf0e10cSrcweir 
2324cdf0e10cSrcweir   -----------------------------------------------------------------------*/
PutSpellingToSentenceStart(EditView & rEditView)2325cdf0e10cSrcweir void ImpEditEngine::PutSpellingToSentenceStart( EditView& rEditView )
2326cdf0e10cSrcweir {
2327cdf0e10cSrcweir #ifdef SVX_LIGHT
2328cdf0e10cSrcweir #else
2329cdf0e10cSrcweir     if( pSpellInfo && pSpellInfo->aLastSpellContentSelections.size() )
2330cdf0e10cSrcweir     {
2331cdf0e10cSrcweir         rEditView.pImpEditView->SetEditSelection( pSpellInfo->aLastSpellContentSelections.begin()->Min() );
2332cdf0e10cSrcweir     }
2333cdf0e10cSrcweir 
2334cdf0e10cSrcweir #endif
2335cdf0e10cSrcweir }
2336cdf0e10cSrcweir 
2337cdf0e10cSrcweir 
DoOnlineSpelling(ContentNode * pThisNodeOnly,sal_Bool bSpellAtCursorPos,sal_Bool bInteruptable)2338cdf0e10cSrcweir void ImpEditEngine::DoOnlineSpelling( ContentNode* pThisNodeOnly, sal_Bool bSpellAtCursorPos, sal_Bool bInteruptable )
2339cdf0e10cSrcweir {
2340cdf0e10cSrcweir #ifndef SVX_LIGHT
2341cdf0e10cSrcweir 	/*
2342cdf0e10cSrcweir 	 Er wird ueber alle Absaetze iteriert, nur Absaetze mit invalidierter
2343cdf0e10cSrcweir 	 WrongList werden geprueft...
2344cdf0e10cSrcweir 
2345cdf0e10cSrcweir 	 Es werden alle Woerter im invalidierten Bereich geprueft.
2346cdf0e10cSrcweir 	 Ist ein Wort falsch, aber noch nicht in der WrongList, oder umgekehrt,
2347cdf0e10cSrcweir 	 wird der Bereich des Wortes invalidiert
2348cdf0e10cSrcweir 	  (	kein Invalidate, sondern wenn nur Uebergaenge von richtig=>falsch,
2349cdf0e10cSrcweir 		einfaches Paint, bei Uebergaengen von falsch=>richtig mit VDev
2350cdf0e10cSrcweir 		ueberplaetten )
2351cdf0e10cSrcweir 	*/
2352cdf0e10cSrcweir 
2353cdf0e10cSrcweir  	if ( !xSpeller.is() )
2354cdf0e10cSrcweir 		return;
2355cdf0e10cSrcweir 
2356cdf0e10cSrcweir 	EditPaM aCursorPos;
2357cdf0e10cSrcweir 	if( pActiveView && !bSpellAtCursorPos )
2358cdf0e10cSrcweir 	{
2359cdf0e10cSrcweir 		DBG_CHKOBJ( pActiveView, EditView, 0 );
2360cdf0e10cSrcweir 		aCursorPos = pActiveView->pImpEditView->GetEditSelection().Max();
2361cdf0e10cSrcweir 	}
2362cdf0e10cSrcweir 	sal_Bool bRestartTimer = sal_False;
2363cdf0e10cSrcweir 
2364cdf0e10cSrcweir 	ContentNode* pLastNode = aEditDoc.SaveGetObject( aEditDoc.Count() - 1 );
2365*7a980842SDamjanJovanovic 	sal_uInt32 nNodes = GetEditDoc().Count();
2366cdf0e10cSrcweir 	sal_uInt16 nInvalids = 0;
2367cdf0e10cSrcweir 	Sequence< PropertyValue > aEmptySeq;
2368*7a980842SDamjanJovanovic 	for ( sal_uInt32 n = 0; n < nNodes; n++ )
2369cdf0e10cSrcweir 	{
2370cdf0e10cSrcweir 		ContentNode* pNode = GetEditDoc().GetObject( n );
2371cdf0e10cSrcweir 		if ( pThisNodeOnly )
2372cdf0e10cSrcweir 			pNode = pThisNodeOnly;
2373cdf0e10cSrcweir 
2374cdf0e10cSrcweir 		if ( pNode->GetWrongList()->IsInvalid() )
2375cdf0e10cSrcweir 		{
2376cdf0e10cSrcweir 			WrongList* pWrongList = pNode->GetWrongList();
2377cdf0e10cSrcweir 			sal_uInt16 nInvStart = pWrongList->GetInvalidStart();
2378cdf0e10cSrcweir 			sal_uInt16 nInvEnd = pWrongList->GetInvalidEnd();
2379cdf0e10cSrcweir 
2380cdf0e10cSrcweir 			sal_uInt16 nWrongs = 0;	// Auch im Absatz mal die Kontrolle abgeben...
2381cdf0e10cSrcweir //			sal_Bool bStop = sal_False;
2382cdf0e10cSrcweir 
2383cdf0e10cSrcweir 			sal_uInt16 nPaintFrom = 0xFFFF, nPaintTo = 0;
2384cdf0e10cSrcweir 			sal_Bool bSimpleRepaint = sal_True;
2385cdf0e10cSrcweir 
2386cdf0e10cSrcweir 			pWrongList->SetValid();
2387cdf0e10cSrcweir 
2388cdf0e10cSrcweir 			EditPaM aPaM( pNode, nInvStart );
2389cdf0e10cSrcweir 			EditSelection aSel( aPaM, aPaM );
2390cdf0e10cSrcweir 			while ( ( aSel.Max().GetNode() == pNode ) /* && !bStop */ )
2391cdf0e10cSrcweir 			{
2392cdf0e10cSrcweir 				if ( ( aSel.Min().GetIndex() > nInvEnd )
2393cdf0e10cSrcweir 						|| ( ( aSel.Max().GetNode() == pLastNode ) && ( aSel.Max().GetIndex() >= pLastNode->Len() ) ) )
2394cdf0e10cSrcweir 					break;	// Dokument- oder Ungueltigkeitsbereich-Ende
2395cdf0e10cSrcweir 
2396cdf0e10cSrcweir 				aSel = SelectWord( aSel, ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
2397cdf0e10cSrcweir 				String aWord( GetSelected( aSel ) );
2398cdf0e10cSrcweir 				// Wenn Punkt dahinter, muss dieser mit uebergeben werden !
2399cdf0e10cSrcweir 				// Falls Abkuerzung...
2400cdf0e10cSrcweir 				sal_Bool bDottAdded = sal_False;
2401cdf0e10cSrcweir 				if ( aSel.Max().GetIndex() < aSel.Max().GetNode()->Len() )
2402cdf0e10cSrcweir 				{
2403cdf0e10cSrcweir 					sal_Unicode cNext = aSel.Max().GetNode()->GetChar( aSel.Max().GetIndex() );
2404cdf0e10cSrcweir 					if ( cNext == '.' )
2405cdf0e10cSrcweir 					{
2406cdf0e10cSrcweir 						aSel.Max().GetIndex()++;
2407cdf0e10cSrcweir 						aWord += cNext;
2408cdf0e10cSrcweir 						bDottAdded = sal_True;
2409cdf0e10cSrcweir 					}
2410cdf0e10cSrcweir 				}
2411cdf0e10cSrcweir 
2412cdf0e10cSrcweir 
2413cdf0e10cSrcweir 				sal_Bool bChanged = sal_False;
2414cdf0e10cSrcweir 				if ( aWord.Len() > 0 )
2415cdf0e10cSrcweir 				{
2416cdf0e10cSrcweir 					sal_uInt16 nWStart = aSel.Min().GetIndex();
2417cdf0e10cSrcweir 					sal_uInt16 nWEnd= aSel.Max().GetIndex();
2418cdf0e10cSrcweir 					if ( !xSpeller->isValid( aWord, GetLanguage( EditPaM( aSel.Min().GetNode(), nWStart+1 ) ), aEmptySeq ) )
2419cdf0e10cSrcweir 					{
2420cdf0e10cSrcweir 						// Pruefen, ob schon richtig markiert...
2421cdf0e10cSrcweir 						nWrongs++;
2422cdf0e10cSrcweir 						// Nur bei SimpleRepaint stoppen, sonst zu oft VDev
2423cdf0e10cSrcweir 	//						if ( ( nWrongs > 8 ) && bSimpleRepaint )
2424cdf0e10cSrcweir 	//						{
2425cdf0e10cSrcweir 	//							bStop = sal_True;
2426cdf0e10cSrcweir 	// 							pWrongList->MarkInvalid( aSel.Max().GetIndex(), nInvEnd );
2427cdf0e10cSrcweir 	//						}
2428cdf0e10cSrcweir 						sal_uInt16 nXEnd = bDottAdded ? nWEnd -1 : nWEnd;
2429cdf0e10cSrcweir 						if ( !pWrongList->HasWrong( nWStart, nXEnd ) )
2430cdf0e10cSrcweir 						{
2431cdf0e10cSrcweir 							// Wort als falsch markieren...
2432cdf0e10cSrcweir 							// Aber nur, wenn nicht an Cursor-Position...
2433cdf0e10cSrcweir 							sal_Bool bCursorPos = sal_False;
2434cdf0e10cSrcweir 							if ( aCursorPos.GetNode() == pNode )
2435cdf0e10cSrcweir 							{
2436cdf0e10cSrcweir 								if ( ( nWStart <= aCursorPos.GetIndex() ) && nWEnd >= aCursorPos.GetIndex() )
2437cdf0e10cSrcweir 									bCursorPos = sal_True;
2438cdf0e10cSrcweir 							}
2439cdf0e10cSrcweir 							if ( bCursorPos )
2440cdf0e10cSrcweir 							{
2441cdf0e10cSrcweir 								// Dann weiter als ungueltig markieren...
2442cdf0e10cSrcweir 								pWrongList->GetInvalidStart() = nWStart;
2443cdf0e10cSrcweir 								pWrongList->GetInvalidEnd() = nWEnd;
2444cdf0e10cSrcweir 								bRestartTimer = sal_True;
2445cdf0e10cSrcweir 							}
2446cdf0e10cSrcweir 							else
2447cdf0e10cSrcweir 							{
2448cdf0e10cSrcweir 								// Es kann sein, dass die Wrongs in der Liste nicht
2449cdf0e10cSrcweir 								// genau ueber Woerter aufgespannt sind, weil die
2450cdf0e10cSrcweir 								// WordDelimiters beim Expandieren nicht ausgewrtet werden.
2451cdf0e10cSrcweir 								pWrongList->InsertWrong( nWStart, nXEnd, sal_True );
2452cdf0e10cSrcweir 								bChanged = sal_True;
2453cdf0e10cSrcweir 							}
2454cdf0e10cSrcweir 						}
2455cdf0e10cSrcweir 					}
2456cdf0e10cSrcweir 					else
2457cdf0e10cSrcweir 					{
2458cdf0e10cSrcweir 						// Pruefen, ob nicht als als falsch markiert....
2459cdf0e10cSrcweir 						if ( pWrongList->HasAnyWrong( nWStart, nWEnd ) )
2460cdf0e10cSrcweir 						{
2461cdf0e10cSrcweir 							pWrongList->ClearWrongs( nWStart, nWEnd, pNode );
2462cdf0e10cSrcweir 							bSimpleRepaint = sal_False;
2463cdf0e10cSrcweir 							bChanged = sal_True;
2464cdf0e10cSrcweir 						}
2465cdf0e10cSrcweir 					}
2466cdf0e10cSrcweir 					if ( bChanged  )
2467cdf0e10cSrcweir 					{
2468cdf0e10cSrcweir 						if ( nPaintFrom == 0xFFFF )
2469cdf0e10cSrcweir 							nPaintFrom = nWStart;
2470cdf0e10cSrcweir 						nPaintTo = nWEnd;
2471cdf0e10cSrcweir 					}
2472cdf0e10cSrcweir 				}
2473cdf0e10cSrcweir 
2474cdf0e10cSrcweir 				EditPaM aLastEnd( aSel.Max() );
2475cdf0e10cSrcweir 				aSel = WordRight( aSel.Max(), ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
2476cdf0e10cSrcweir 				if ( bChanged && ( aSel.Min().GetNode() == pNode ) &&
2477cdf0e10cSrcweir 						( ( aSel.Min().GetIndex()-aLastEnd.GetIndex() > 1 ) ) )
2478cdf0e10cSrcweir 				{
2479cdf0e10cSrcweir 					// Wenn zwei Worte durch mehr Zeichen als ein Blank getrennt
2480cdf0e10cSrcweir 					// sind, kann es passieren, dass beim Aufsplitten eines Wrongs
2481cdf0e10cSrcweir 					// der Start den zweiten Wortes vor dem tatsaechlich Wort liegt
2482cdf0e10cSrcweir 					pWrongList->ClearWrongs( aLastEnd.GetIndex(), aSel.Min().GetIndex(), pNode );
2483cdf0e10cSrcweir 				}
2484cdf0e10cSrcweir 			}
2485cdf0e10cSrcweir 
2486cdf0e10cSrcweir 			// Invalidieren?
2487cdf0e10cSrcweir             if ( ( nPaintFrom != 0xFFFF ) )
2488cdf0e10cSrcweir 			{
2489cdf0e10cSrcweir 				aStatus.GetStatusWord() |= EE_STAT_WRONGWORDCHANGED;
2490cdf0e10cSrcweir 				CallStatusHdl();
2491cdf0e10cSrcweir 
2492cdf0e10cSrcweir 				if ( aEditViews.Count() )
2493cdf0e10cSrcweir 				{
2494cdf0e10cSrcweir 					// Bei SimpleRepaint wuerde ein uebermalen ohne VDev reichen,
2495cdf0e10cSrcweir 					// aber dann muesste ich ueber alle Views, Intersecten,
2496cdf0e10cSrcweir 					// Clippen, ...
2497cdf0e10cSrcweir 					// Lohnt wahrscheinlich nicht.
2498cdf0e10cSrcweir 					EditPaM aStartPaM( pNode, nPaintFrom );
2499cdf0e10cSrcweir 					EditPaM aEndPaM( pNode, nPaintTo );
2500cdf0e10cSrcweir 					Rectangle aStartCursor( PaMtoEditCursor( aStartPaM ) );
2501cdf0e10cSrcweir 					Rectangle aEndCursor( PaMtoEditCursor( aEndPaM ) );
2502cdf0e10cSrcweir 					DBG_ASSERT( aInvalidRec.IsEmpty(), "InvalidRect gesetzt!" );
2503cdf0e10cSrcweir 					aInvalidRec.Left() = 0;
2504cdf0e10cSrcweir 					aInvalidRec.Right() = GetPaperSize().Width();
2505cdf0e10cSrcweir 					aInvalidRec.Top() = aStartCursor.Top();
2506cdf0e10cSrcweir 					aInvalidRec.Bottom() = aEndCursor.Bottom();
2507cdf0e10cSrcweir 					if ( pActiveView && pActiveView->HasSelection() )
2508cdf0e10cSrcweir 					{
2509cdf0e10cSrcweir 						// Dann darf nicht ueber VDev ausgegeben werden
2510cdf0e10cSrcweir 						UpdateViews( NULL );
2511cdf0e10cSrcweir 					}
2512cdf0e10cSrcweir 					else if ( bSimpleRepaint )
2513cdf0e10cSrcweir 					{
2514cdf0e10cSrcweir 						for ( sal_uInt16 nView = 0; nView < aEditViews.Count(); nView++ )
2515cdf0e10cSrcweir 						{
2516cdf0e10cSrcweir 							EditView* pView = aEditViews[nView];
2517cdf0e10cSrcweir 							Rectangle aClipRec( aInvalidRec );
2518cdf0e10cSrcweir 							aClipRec.Intersection( pView->GetVisArea() );
2519cdf0e10cSrcweir 							if ( !aClipRec.IsEmpty() )
2520cdf0e10cSrcweir 							{
2521cdf0e10cSrcweir 								// in Fensterkoordinaten umwandeln....
2522cdf0e10cSrcweir 								aClipRec.SetPos( pView->pImpEditView->GetWindowPos( aClipRec.TopLeft() ) );
2523cdf0e10cSrcweir 								// Wenn Selektion, dann VDev...
2524a56bd57bSArmin Le Grand 								Paint( pView->pImpEditView, aClipRec, 0, pView->HasSelection() );
2525cdf0e10cSrcweir 							}
2526cdf0e10cSrcweir 						}
2527cdf0e10cSrcweir 					}
2528cdf0e10cSrcweir 					else
2529cdf0e10cSrcweir 					{
2530cdf0e10cSrcweir 						UpdateViews( pActiveView );
2531cdf0e10cSrcweir 					}
2532cdf0e10cSrcweir 					aInvalidRec = Rectangle();
2533cdf0e10cSrcweir 				}
2534cdf0e10cSrcweir 			}
2535cdf0e10cSrcweir 			// Nach zwei korrigierten Nodes die Kontrolle abgeben...
2536cdf0e10cSrcweir 			nInvalids++;
2537cdf0e10cSrcweir 			if ( bInteruptable && ( nInvalids >= 2 ) )
2538cdf0e10cSrcweir 			{
2539cdf0e10cSrcweir 				bRestartTimer = sal_True;
2540cdf0e10cSrcweir 				break;
2541cdf0e10cSrcweir 			}
2542cdf0e10cSrcweir 		}
2543cdf0e10cSrcweir 
2544cdf0e10cSrcweir 		if ( pThisNodeOnly )
2545cdf0e10cSrcweir 			break;
2546cdf0e10cSrcweir 	}
2547cdf0e10cSrcweir 	if ( bRestartTimer )
2548cdf0e10cSrcweir 		aOnlineSpellTimer.Start();
2549cdf0e10cSrcweir #endif // !SVX_LIGHT
2550cdf0e10cSrcweir }
2551cdf0e10cSrcweir 
2552cdf0e10cSrcweir 
HasSpellErrors()2553cdf0e10cSrcweir EESpellState ImpEditEngine::HasSpellErrors()
2554cdf0e10cSrcweir {
2555cdf0e10cSrcweir 	DBG_ASSERT( xSpeller.is(), "Kein Speller gesetzt!" );
2556cdf0e10cSrcweir 
2557cdf0e10cSrcweir #ifndef SVX_LIGHT
2558cdf0e10cSrcweir 	ContentNode* pLastNode = aEditDoc.SaveGetObject( aEditDoc.Count() - 1 );
2559cdf0e10cSrcweir 	EditSelection aCurSel( aEditDoc.GetStartPaM() );
2560cdf0e10cSrcweir 
2561cdf0e10cSrcweir 	String aWord;
2562cdf0e10cSrcweir 	Reference< XSpellAlternatives > xSpellAlt;
2563cdf0e10cSrcweir 	Sequence< PropertyValue > aEmptySeq;
2564cdf0e10cSrcweir 	while ( !xSpellAlt.is() )
2565cdf0e10cSrcweir 	{
2566cdf0e10cSrcweir 		if ( ( aCurSel.Max().GetNode() == pLastNode ) &&
2567cdf0e10cSrcweir 			 ( aCurSel.Max().GetIndex() >= pLastNode->Len() ) )
2568cdf0e10cSrcweir 		{
2569cdf0e10cSrcweir 			return EE_SPELL_OK;
2570cdf0e10cSrcweir 		}
2571cdf0e10cSrcweir 
2572cdf0e10cSrcweir 		aCurSel = SelectWord( aCurSel, ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
2573cdf0e10cSrcweir 		aWord = GetSelected( aCurSel );
2574cdf0e10cSrcweir 		if ( aWord.Len() > 0 )
2575cdf0e10cSrcweir 		{
2576cdf0e10cSrcweir 			LanguageType eLang = GetLanguage( aCurSel.Max() );
2577cdf0e10cSrcweir 			SvxSpellWrapper::CheckSpellLang( xSpeller, eLang );
2578cdf0e10cSrcweir 			xSpellAlt = xSpeller->spell( aWord, eLang, aEmptySeq );
2579cdf0e10cSrcweir 		}
2580cdf0e10cSrcweir 		aCurSel = WordRight( aCurSel.Max(), ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
2581cdf0e10cSrcweir 	}
2582cdf0e10cSrcweir #endif
2583cdf0e10cSrcweir 
2584cdf0e10cSrcweir 	return EE_SPELL_ERRORFOUND;
2585cdf0e10cSrcweir }
2586cdf0e10cSrcweir 
StartThesaurus(EditView * pEditView)2587cdf0e10cSrcweir EESpellState ImpEditEngine::StartThesaurus( EditView* pEditView )
2588cdf0e10cSrcweir {
2589cdf0e10cSrcweir #ifndef SVX_LIGHT
2590cdf0e10cSrcweir 	EditSelection aCurSel( pEditView->pImpEditView->GetEditSelection() );
2591cdf0e10cSrcweir 	if ( !aCurSel.HasRange() )
2592cdf0e10cSrcweir 		aCurSel = SelectWord( aCurSel, ::com::sun::star::i18n::WordType::DICTIONARY_WORD );
2593cdf0e10cSrcweir 	String aWord( GetSelected( aCurSel ) );
2594cdf0e10cSrcweir 
2595cdf0e10cSrcweir 	Reference< XThesaurus > xThes( SvxGetThesaurus() );
2596cdf0e10cSrcweir 	if (!xThes.is())
2597cdf0e10cSrcweir 		return EE_SPELL_ERRORFOUND;
2598cdf0e10cSrcweir 
2599cdf0e10cSrcweir 	EditAbstractDialogFactory* pFact = EditAbstractDialogFactory::Create();
2600cdf0e10cSrcweir 	AbstractThesaurusDialog* pDlg = pFact->CreateThesaurusDialog( pEditView->GetWindow(), xThes, aWord, GetLanguage( aCurSel.Max() ) );
2601cdf0e10cSrcweir 	if ( pDlg->Execute() == RET_OK )
2602cdf0e10cSrcweir 	{
2603cdf0e10cSrcweir 		// Wort ersetzen...
2604cdf0e10cSrcweir 		pEditView->pImpEditView->DrawSelection();
2605cdf0e10cSrcweir 		pEditView->pImpEditView->SetEditSelection( aCurSel );
2606cdf0e10cSrcweir 		pEditView->pImpEditView->DrawSelection();
2607cdf0e10cSrcweir 		pEditView->InsertText( pDlg->GetWord() );
2608cdf0e10cSrcweir 		pEditView->ShowCursor( sal_True, sal_False );
2609cdf0e10cSrcweir 	}
2610cdf0e10cSrcweir 
2611cdf0e10cSrcweir 	delete pDlg;
2612cdf0e10cSrcweir 	return EE_SPELL_OK;
2613cdf0e10cSrcweir #else
2614cdf0e10cSrcweir 	return EE_SPELL_NOSPELLER;
2615cdf0e10cSrcweir #endif
2616cdf0e10cSrcweir }
2617cdf0e10cSrcweir 
StartSearchAndReplace(EditView * pEditView,const SvxSearchItem & rSearchItem)2618cdf0e10cSrcweir sal_uInt16 ImpEditEngine::StartSearchAndReplace( EditView* pEditView, const SvxSearchItem& rSearchItem )
2619cdf0e10cSrcweir {
2620cdf0e10cSrcweir 	sal_uInt16 nFound = 0;
2621cdf0e10cSrcweir 
2622cdf0e10cSrcweir #ifndef SVX_LIGHT
2623cdf0e10cSrcweir 	EditSelection aCurSel( pEditView->pImpEditView->GetEditSelection() );
2624cdf0e10cSrcweir 
2625cdf0e10cSrcweir 	// FIND_ALL ohne Mehrfachselektion nicht moeglich.
2626cdf0e10cSrcweir 	if ( ( rSearchItem.GetCommand() == SVX_SEARCHCMD_FIND ) ||
2627cdf0e10cSrcweir 		 ( rSearchItem.GetCommand() == SVX_SEARCHCMD_FIND_ALL ) )
2628cdf0e10cSrcweir 	{
2629cdf0e10cSrcweir 		if ( Search( rSearchItem, pEditView ) )
2630cdf0e10cSrcweir 			nFound++;
2631cdf0e10cSrcweir 	}
2632cdf0e10cSrcweir 	else if ( rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE )
2633cdf0e10cSrcweir 	{
2634cdf0e10cSrcweir 		// Das Wort ist selektiert, wenn der Anwender die Selektion
2635cdf0e10cSrcweir 		// nicht zwischendurch manipuliert:
2636cdf0e10cSrcweir 		if ( aCurSel.HasRange() )
2637cdf0e10cSrcweir 		{
2638cdf0e10cSrcweir 			pEditView->InsertText( rSearchItem.GetReplaceString() );
2639cdf0e10cSrcweir 			nFound = 1;
2640cdf0e10cSrcweir 		}
2641cdf0e10cSrcweir 		else
2642cdf0e10cSrcweir 			if( Search( rSearchItem, pEditView ) )
2643cdf0e10cSrcweir 				nFound = 1;
2644cdf0e10cSrcweir 	}
2645cdf0e10cSrcweir 	else if ( rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE_ALL )
2646cdf0e10cSrcweir 	{
2647cdf0e10cSrcweir 		// Der Writer ersetzt alle, vorn Anfang bis Ende...
2648cdf0e10cSrcweir 		SvxSearchItem aTmpItem( rSearchItem );
2649cdf0e10cSrcweir 		aTmpItem.SetBackward( sal_False );
2650cdf0e10cSrcweir 
2651cdf0e10cSrcweir 		pEditView->pImpEditView->DrawSelection();
2652cdf0e10cSrcweir 
2653cdf0e10cSrcweir         aCurSel.Adjust( aEditDoc );
2654cdf0e10cSrcweir 		EditPaM aStartPaM = aTmpItem.GetSelection() ? aCurSel.Min() : aEditDoc.GetStartPaM();
2655cdf0e10cSrcweir 		EditSelection aFoundSel( aCurSel.Max() );
2656cdf0e10cSrcweir 		sal_Bool bFound = ImpSearch( aTmpItem, aCurSel, aStartPaM, aFoundSel );
2657cdf0e10cSrcweir 		if ( bFound )
2658cdf0e10cSrcweir 			UndoActionStart( EDITUNDO_REPLACEALL );
2659cdf0e10cSrcweir 		while ( bFound )
2660cdf0e10cSrcweir 		{
2661cdf0e10cSrcweir 			nFound++;
2662cdf0e10cSrcweir 			aStartPaM = ImpInsertText( aFoundSel, rSearchItem.GetReplaceString() );
2663cdf0e10cSrcweir 			bFound = ImpSearch( aTmpItem, aCurSel, aStartPaM, aFoundSel );
2664cdf0e10cSrcweir 		}
2665cdf0e10cSrcweir 		if ( nFound )
2666cdf0e10cSrcweir 		{
2667cdf0e10cSrcweir 			EditPaM aNewPaM( aFoundSel.Max() );
2668cdf0e10cSrcweir 			if ( aNewPaM.GetIndex() > aNewPaM.GetNode()->Len() )
2669cdf0e10cSrcweir 				aNewPaM.GetIndex() =  aNewPaM.GetNode()->Len();
2670cdf0e10cSrcweir 			pEditView->pImpEditView->SetEditSelection( aNewPaM );
2671cdf0e10cSrcweir 			FormatAndUpdate( pEditView );
2672cdf0e10cSrcweir 			UndoActionEnd( EDITUNDO_REPLACEALL );
2673cdf0e10cSrcweir 		}
2674cdf0e10cSrcweir 		else
2675cdf0e10cSrcweir 		{
2676cdf0e10cSrcweir 			pEditView->pImpEditView->DrawSelection();
2677cdf0e10cSrcweir 			pEditView->ShowCursor( sal_True, sal_False );
2678cdf0e10cSrcweir 		}
2679cdf0e10cSrcweir 	}
2680cdf0e10cSrcweir #endif // !SVX_LIGHT
2681cdf0e10cSrcweir 	return nFound;
2682cdf0e10cSrcweir }
2683cdf0e10cSrcweir 
Search(const SvxSearchItem & rSearchItem,EditView * pEditView)2684cdf0e10cSrcweir sal_Bool ImpEditEngine::Search( const SvxSearchItem& rSearchItem, EditView* pEditView )
2685cdf0e10cSrcweir {
2686cdf0e10cSrcweir 	EditSelection aSel( pEditView->pImpEditView->GetEditSelection() );
2687cdf0e10cSrcweir 	aSel.Adjust( aEditDoc );
2688cdf0e10cSrcweir 	EditPaM aStartPaM( aSel.Max() );
2689cdf0e10cSrcweir 	if ( rSearchItem.GetSelection() && !rSearchItem.GetBackward() )
2690cdf0e10cSrcweir 		aStartPaM = aSel.Min();
2691cdf0e10cSrcweir 
2692cdf0e10cSrcweir 	EditSelection aFoundSel;
2693cdf0e10cSrcweir 	sal_Bool bFound = ImpSearch( rSearchItem, aSel, aStartPaM, aFoundSel );
2694cdf0e10cSrcweir 	if ( bFound && ( aFoundSel == aSel ) )	// Bei Rueckwaetssuche
2695cdf0e10cSrcweir 	{
2696cdf0e10cSrcweir 		aStartPaM = aSel.Min();
2697cdf0e10cSrcweir 		bFound = ImpSearch( rSearchItem, aSel, aStartPaM, aFoundSel );
2698cdf0e10cSrcweir 	}
2699cdf0e10cSrcweir 
2700cdf0e10cSrcweir 	pEditView->pImpEditView->DrawSelection();
2701cdf0e10cSrcweir 	if ( bFound )
2702cdf0e10cSrcweir 	{
2703cdf0e10cSrcweir 		// Erstmal das Min einstellen, damit das ganze Wort in den sichtbaren Bereich kommt.
2704cdf0e10cSrcweir 		pEditView->pImpEditView->SetEditSelection( aFoundSel.Min() );
2705cdf0e10cSrcweir 		pEditView->ShowCursor( sal_True, sal_False );
2706cdf0e10cSrcweir 		pEditView->pImpEditView->SetEditSelection( aFoundSel );
2707cdf0e10cSrcweir 	}
2708cdf0e10cSrcweir 	else
2709cdf0e10cSrcweir 		pEditView->pImpEditView->SetEditSelection( aSel.Max() );
2710cdf0e10cSrcweir 
2711cdf0e10cSrcweir 	pEditView->pImpEditView->DrawSelection();
2712cdf0e10cSrcweir 	pEditView->ShowCursor( sal_True, sal_False );
2713cdf0e10cSrcweir 	return bFound;
2714cdf0e10cSrcweir }
2715cdf0e10cSrcweir 
ImpSearch(const SvxSearchItem & rSearchItem,const EditSelection & rSearchSelection,const EditPaM & rStartPos,EditSelection & rFoundSel)2716cdf0e10cSrcweir sal_Bool ImpEditEngine::ImpSearch( const SvxSearchItem& rSearchItem,
2717cdf0e10cSrcweir 	const EditSelection& rSearchSelection, const EditPaM& rStartPos, EditSelection& rFoundSel )
2718cdf0e10cSrcweir {
2719cdf0e10cSrcweir #ifndef SVX_LIGHT
2720cdf0e10cSrcweir 	util::SearchOptions aSearchOptions( rSearchItem.GetSearchOptions() );
2721cdf0e10cSrcweir 	aSearchOptions.Locale = GetLocale( rStartPos );
2722cdf0e10cSrcweir 
2723cdf0e10cSrcweir 	sal_Bool bBack = rSearchItem.GetBackward();
2724cdf0e10cSrcweir 	sal_Bool bSearchInSelection = rSearchItem.GetSelection();
2725*7a980842SDamjanJovanovic 	sal_uInt32 nStartNode = aEditDoc.GetPos( rStartPos.GetNode() );
2726*7a980842SDamjanJovanovic 	sal_uInt32 nEndNode;
2727cdf0e10cSrcweir 	if ( bSearchInSelection )
2728cdf0e10cSrcweir 	{
2729cdf0e10cSrcweir 		nEndNode = aEditDoc.GetPos( bBack ? rSearchSelection.Min().GetNode() : rSearchSelection.Max().GetNode() );
2730cdf0e10cSrcweir 	}
2731cdf0e10cSrcweir 	else
2732cdf0e10cSrcweir 	{
2733cdf0e10cSrcweir 		nEndNode = bBack ? 0 : aEditDoc.Count()-1;
2734cdf0e10cSrcweir 	}
2735cdf0e10cSrcweir 
2736cdf0e10cSrcweir 	utl::TextSearch aSearcher( aSearchOptions );
2737cdf0e10cSrcweir 
2738cdf0e10cSrcweir 	// ueber die Absaetze iterieren...
2739*7a980842SDamjanJovanovic 	for ( sal_uInt32 nNode = nStartNode;
2740cdf0e10cSrcweir 			bBack ? ( nNode >= nEndNode ) : ( nNode <= nEndNode) ;
2741cdf0e10cSrcweir 			bBack ? nNode-- : nNode++ )
2742cdf0e10cSrcweir 	{
2743cdf0e10cSrcweir 		// Bei rueckwaertsuche, wenn nEndNode = 0:
2744cdf0e10cSrcweir 		if ( nNode >= 0xFFFF )
2745cdf0e10cSrcweir 			return sal_False;
2746cdf0e10cSrcweir 
2747cdf0e10cSrcweir 		ContentNode* pNode = aEditDoc.GetObject( nNode );
2748cdf0e10cSrcweir 
2749cdf0e10cSrcweir 		sal_uInt16 nStartPos = 0;
2750cdf0e10cSrcweir 		sal_uInt16 nEndPos = pNode->Len();
2751cdf0e10cSrcweir 		if ( nNode == nStartNode )
2752cdf0e10cSrcweir 		{
2753cdf0e10cSrcweir 			if ( bBack )
2754cdf0e10cSrcweir 				nEndPos = rStartPos.GetIndex();
2755cdf0e10cSrcweir 			else
2756cdf0e10cSrcweir 				nStartPos = rStartPos.GetIndex();
2757cdf0e10cSrcweir 		}
2758cdf0e10cSrcweir 		if ( ( nNode == nEndNode ) && bSearchInSelection )
2759cdf0e10cSrcweir 		{
2760cdf0e10cSrcweir 			if ( bBack )
2761cdf0e10cSrcweir 				nStartPos = rSearchSelection.Min().GetIndex();
2762cdf0e10cSrcweir 			else
2763cdf0e10cSrcweir 				nEndPos = rSearchSelection.Max().GetIndex();
2764cdf0e10cSrcweir 		}
2765cdf0e10cSrcweir 
2766cdf0e10cSrcweir 		// Suchen...
2767cdf0e10cSrcweir 		XubString aParaStr( GetEditDoc().GetParaAsString( pNode ) );
2768cdf0e10cSrcweir 		bool bFound = false;
2769cdf0e10cSrcweir 		if ( bBack )
2770cdf0e10cSrcweir 		{
2771cdf0e10cSrcweir 			Swapsal_uIt16s( nStartPos, nEndPos );
2772cdf0e10cSrcweir 			bFound = aSearcher.SearchBkwrd( aParaStr, &nStartPos, &nEndPos);
2773cdf0e10cSrcweir 		}
2774cdf0e10cSrcweir 		else
2775cdf0e10cSrcweir 			bFound = aSearcher.SearchFrwrd( aParaStr, &nStartPos, &nEndPos);
2776cdf0e10cSrcweir 
2777cdf0e10cSrcweir 		if ( bFound )
2778cdf0e10cSrcweir 		{
2779cdf0e10cSrcweir 			rFoundSel.Min().SetNode( pNode );
2780cdf0e10cSrcweir 			rFoundSel.Min().SetIndex( nStartPos );
2781cdf0e10cSrcweir 			rFoundSel.Max().SetNode( pNode );
2782cdf0e10cSrcweir 			rFoundSel.Max().SetIndex( nEndPos );
2783cdf0e10cSrcweir 			return sal_True;
2784cdf0e10cSrcweir 		}
2785cdf0e10cSrcweir 	}
2786cdf0e10cSrcweir #endif // !SVX_LIGHT
2787cdf0e10cSrcweir 	return sal_False;
2788cdf0e10cSrcweir }
2789cdf0e10cSrcweir 
HasText(const SvxSearchItem & rSearchItem)2790cdf0e10cSrcweir sal_Bool ImpEditEngine::HasText( const SvxSearchItem& rSearchItem )
2791cdf0e10cSrcweir {
2792cdf0e10cSrcweir #ifndef SVX_LIGHT
2793cdf0e10cSrcweir 	SvxSearchItem aTmpItem( rSearchItem );
2794cdf0e10cSrcweir 	aTmpItem.SetBackward( sal_False );
2795cdf0e10cSrcweir 	aTmpItem.SetSelection( sal_False );
2796cdf0e10cSrcweir 
2797cdf0e10cSrcweir 	EditPaM aStartPaM( aEditDoc.GetStartPaM() );
2798cdf0e10cSrcweir 	EditSelection aDummySel( aStartPaM );
2799cdf0e10cSrcweir 	EditSelection aFoundSel;
2800cdf0e10cSrcweir 	return ImpSearch( aTmpItem, aDummySel, aStartPaM, aFoundSel );
2801cdf0e10cSrcweir #else
2802cdf0e10cSrcweir 	return sal_False;
2803cdf0e10cSrcweir #endif
2804cdf0e10cSrcweir }
2805cdf0e10cSrcweir 
SetAutoCompleteText(const String & rStr,sal_Bool bClearTipWindow)2806cdf0e10cSrcweir void ImpEditEngine::SetAutoCompleteText( const String& rStr, sal_Bool bClearTipWindow )
2807cdf0e10cSrcweir {
2808cdf0e10cSrcweir #ifndef SVX_LIGHT
2809cdf0e10cSrcweir 	aAutoCompleteText = rStr;
2810cdf0e10cSrcweir 	if ( bClearTipWindow && pActiveView )
2811cdf0e10cSrcweir 		Help::ShowQuickHelp( pActiveView->GetWindow(), Rectangle(), String(), 0 );
2812cdf0e10cSrcweir #endif // !SVX_LIGHT
2813cdf0e10cSrcweir }
2814cdf0e10cSrcweir 
281500a33fa1SHerbert Dürr namespace editeng // #i120045# namespace to avoid XCode template-misoptimization
281600a33fa1SHerbert Dürr {
2817cdf0e10cSrcweir struct TransliterationChgData
2818cdf0e10cSrcweir {
2819cdf0e10cSrcweir     sal_uInt16                      nStart;
2820cdf0e10cSrcweir     xub_StrLen                  nLen;
2821cdf0e10cSrcweir     EditSelection               aSelection;
2822cdf0e10cSrcweir     String                      aNewText;
2823cdf0e10cSrcweir     uno::Sequence< sal_Int32 >  aOffsets;
2824cdf0e10cSrcweir };
282500a33fa1SHerbert Dürr }
282600a33fa1SHerbert Dürr using editeng::TransliterationChgData;
2827cdf0e10cSrcweir 
2828cdf0e10cSrcweir 
TransliterateText(const EditSelection & rSelection,sal_Int32 nTransliterationMode)2829cdf0e10cSrcweir EditSelection ImpEditEngine::TransliterateText( const EditSelection& rSelection, sal_Int32 nTransliterationMode )
2830cdf0e10cSrcweir {
2831cdf0e10cSrcweir     uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
2832cdf0e10cSrcweir     if (!_xBI.is())
2833cdf0e10cSrcweir         return rSelection;
2834cdf0e10cSrcweir 
2835cdf0e10cSrcweir 	EditSelection aSel( rSelection );
2836cdf0e10cSrcweir 	aSel.Adjust( aEditDoc );
2837cdf0e10cSrcweir 
2838cdf0e10cSrcweir 	if ( !aSel.HasRange() )
2839cdf0e10cSrcweir 		aSel = SelectWord( aSel );
2840cdf0e10cSrcweir 
2841cdf0e10cSrcweir     EditSelection aNewSel( aSel );
2842cdf0e10cSrcweir 
2843*7a980842SDamjanJovanovic 	const sal_uInt32 nStartNode = aEditDoc.GetPos( aSel.Min().GetNode() );
2844*7a980842SDamjanJovanovic 	const sal_uInt32 nEndNode = aEditDoc.GetPos( aSel.Max().GetNode() );
2845cdf0e10cSrcweir 
2846cdf0e10cSrcweir 	sal_Bool bChanges = sal_False;
2847cdf0e10cSrcweir     sal_Bool bLenChanged = sal_False;
2848cdf0e10cSrcweir 	EditUndoTransliteration* pUndo = NULL;
2849cdf0e10cSrcweir 
2850cdf0e10cSrcweir 	utl::TransliterationWrapper aTranslitarationWrapper( ::comphelper::getProcessServiceFactory(), nTransliterationMode );
2851cdf0e10cSrcweir 	sal_Bool bConsiderLanguage = aTranslitarationWrapper.needLanguageForTheMode();
2852cdf0e10cSrcweir 
2853*7a980842SDamjanJovanovic 	for ( sal_uInt32 nNode = nStartNode; nNode <= nEndNode; nNode++	)
2854cdf0e10cSrcweir 	{
2855cdf0e10cSrcweir 		ContentNode* pNode = aEditDoc.GetObject( nNode );
2856cdf0e10cSrcweir 		xub_StrLen nStartPos = 0;
2857cdf0e10cSrcweir 		xub_StrLen nEndPos = pNode->Len();
2858cdf0e10cSrcweir 		if ( nNode == nStartNode )
2859cdf0e10cSrcweir 			nStartPos = aSel.Min().GetIndex();
2860cdf0e10cSrcweir 		if ( nNode == nEndNode ) // kann auch == nStart sein!
2861cdf0e10cSrcweir 			nEndPos = aSel.Max().GetIndex();
2862cdf0e10cSrcweir 
2863cdf0e10cSrcweir 		sal_uInt16 nCurrentStart = nStartPos;
2864cdf0e10cSrcweir 		sal_uInt16 nCurrentEnd = nEndPos;
2865cdf0e10cSrcweir 		sal_uInt16 nLanguage = LANGUAGE_SYSTEM;
2866cdf0e10cSrcweir 
2867cdf0e10cSrcweir         // since we don't use Hiragana/Katakana or half-width/full-width transliterations here
2868cdf0e10cSrcweir         // it is fine to use ANYWORD_IGNOREWHITESPACES. (ANY_WORD btw is broken and will
2869cdf0e10cSrcweir         // occasionaly miss words in consecutive sentences). Also with ANYWORD_IGNOREWHITESPACES
2870cdf0e10cSrcweir         // text like 'just-in-time' will be converted to 'Just-In-Time' which seems to be the
2871cdf0e10cSrcweir         // proper thing to do.
2872cdf0e10cSrcweir         const sal_Int16 nWordType = i18n::WordType::ANYWORD_IGNOREWHITESPACES;
2873cdf0e10cSrcweir 
2874cdf0e10cSrcweir         //! In order to have less trouble with changing text size, e.g. because
2875cdf0e10cSrcweir         //! of ligatures or � (German small sz) being resolved, we need to process
2876cdf0e10cSrcweir         //! the text replacements from end to start.
2877cdf0e10cSrcweir         //! This way the offsets for the yet to be changed words will be
2878cdf0e10cSrcweir         //! left unchanged by the already replaced text.
2879cdf0e10cSrcweir         //! For this we temporarily save the changes to be done in this vector
2880cdf0e10cSrcweir         std::vector< TransliterationChgData >   aChanges;
2881cdf0e10cSrcweir         TransliterationChgData                  aChgData;
2882cdf0e10cSrcweir 
2883cdf0e10cSrcweir         if (nTransliterationMode == i18n::TransliterationModulesExtra::TITLE_CASE)
2884cdf0e10cSrcweir         {
2885cdf0e10cSrcweir             // for 'capitalize every word' we need to iterate over each word
2886cdf0e10cSrcweir 
2887cdf0e10cSrcweir             i18n::Boundary aSttBndry;
2888cdf0e10cSrcweir             i18n::Boundary aEndBndry;
2889cdf0e10cSrcweir             aSttBndry = _xBI->getWordBoundary(
2890cdf0e10cSrcweir                         *pNode, nStartPos,
2891cdf0e10cSrcweir                         SvxCreateLocale( GetLanguage( EditPaM( pNode, nStartPos + 1 ) ) ),
2892cdf0e10cSrcweir                         nWordType, sal_True /*prefer forward direction*/);
2893cdf0e10cSrcweir             aEndBndry = _xBI->getWordBoundary(
2894cdf0e10cSrcweir                         *pNode, nEndPos,
2895cdf0e10cSrcweir                         SvxCreateLocale( GetLanguage( EditPaM( pNode, nEndPos + 1 ) ) ),
2896cdf0e10cSrcweir                         nWordType, sal_False /*prefer backward direction*/);
2897cdf0e10cSrcweir 
2898cdf0e10cSrcweir             // prevent backtracking to the previous word if selection is at word boundary
2899cdf0e10cSrcweir             if (aSttBndry.endPos <= nStartPos)
2900cdf0e10cSrcweir             {
2901cdf0e10cSrcweir                 aSttBndry = _xBI->nextWord(
2902cdf0e10cSrcweir                         *pNode, aSttBndry.endPos,
2903cdf0e10cSrcweir                         SvxCreateLocale( GetLanguage( EditPaM( pNode, aSttBndry.endPos + 1 ) ) ),
2904cdf0e10cSrcweir                         nWordType);
2905cdf0e10cSrcweir             }
2906cdf0e10cSrcweir             // prevent advancing to the next word if selection is at word boundary
2907cdf0e10cSrcweir             if (aEndBndry.startPos >= nEndPos)
2908cdf0e10cSrcweir             {
2909cdf0e10cSrcweir                 aEndBndry = _xBI->previousWord(
2910cdf0e10cSrcweir                         *pNode, aEndBndry.startPos,
2911cdf0e10cSrcweir                         SvxCreateLocale( GetLanguage( EditPaM( pNode, aEndBndry.startPos + 1 ) ) ),
2912cdf0e10cSrcweir                         nWordType);
2913cdf0e10cSrcweir             }
2914cdf0e10cSrcweir 
2915cdf0e10cSrcweir             i18n::Boundary aCurWordBndry( aSttBndry );
2916cdf0e10cSrcweir             while (aCurWordBndry.startPos <= aEndBndry.startPos)
2917cdf0e10cSrcweir             {
2918cdf0e10cSrcweir                 nCurrentStart = (xub_StrLen)aCurWordBndry.startPos;
2919cdf0e10cSrcweir                 nCurrentEnd   = (xub_StrLen)aCurWordBndry.endPos;
2920cdf0e10cSrcweir                 sal_Int32 nLen = nCurrentEnd - nCurrentStart;
2921cdf0e10cSrcweir                 DBG_ASSERT( nLen > 0, "invalid word length of 0" );
2922cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
2923cdf0e10cSrcweir                 String aText( pNode->Copy( nCurrentStart, nLen ) );
2924cdf0e10cSrcweir #endif
2925cdf0e10cSrcweir 
2926cdf0e10cSrcweir 	            Sequence< sal_Int32 > aOffsets;
2927cdf0e10cSrcweir                 String aNewText( aTranslitarationWrapper.transliterate( *pNode,
2928cdf0e10cSrcweir                         GetLanguage( EditPaM( pNode, nCurrentStart + 1 ) ),
2929cdf0e10cSrcweir                         nCurrentStart, nLen, &aOffsets ));
2930cdf0e10cSrcweir 
2931cdf0e10cSrcweir                 if (!pNode->Equals( aNewText, nCurrentStart, nLen ))
2932cdf0e10cSrcweir                 {
2933cdf0e10cSrcweir                     aChgData.nStart     = nCurrentStart;
2934cdf0e10cSrcweir                     aChgData.nLen       = nLen;
2935cdf0e10cSrcweir                     aChgData.aSelection = EditSelection( EditPaM( pNode, nCurrentStart ), EditPaM( pNode, nCurrentEnd ) );
2936cdf0e10cSrcweir                     aChgData.aNewText   = aNewText;
2937cdf0e10cSrcweir                     aChgData.aOffsets   = aOffsets;
2938cdf0e10cSrcweir                     aChanges.push_back( aChgData );
2939cdf0e10cSrcweir                 }
2940cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
2941cdf0e10cSrcweir                 String aSelTxt ( GetSelected( aChgData.aSelection ) );
2942cdf0e10cSrcweir                 (void) aSelTxt;
2943cdf0e10cSrcweir #endif
2944cdf0e10cSrcweir 
2945cdf0e10cSrcweir                 aCurWordBndry = _xBI->nextWord( *pNode, nCurrentEnd,
2946cdf0e10cSrcweir                         SvxCreateLocale( GetLanguage( EditPaM( pNode, nCurrentEnd + 1 ) ) ),
2947cdf0e10cSrcweir                         nWordType);
2948cdf0e10cSrcweir             }
2949cdf0e10cSrcweir             DBG_ASSERT( nCurrentEnd >= aEndBndry.endPos, "failed to reach end of transliteration" );
2950cdf0e10cSrcweir         }
2951cdf0e10cSrcweir         else if (nTransliterationMode == i18n::TransliterationModulesExtra::SENTENCE_CASE)
2952cdf0e10cSrcweir         {
2953cdf0e10cSrcweir             // for 'sentence case' we need to iterate sentence by sentence
2954cdf0e10cSrcweir 
2955cdf0e10cSrcweir             sal_Int32 nLastStart = _xBI->beginOfSentence(
2956cdf0e10cSrcweir                     *pNode, nEndPos,
2957cdf0e10cSrcweir                     SvxCreateLocale( GetLanguage( EditPaM( pNode, nEndPos + 1 ) ) ) );
2958cdf0e10cSrcweir             sal_Int32 nLastEnd = _xBI->endOfSentence(
2959cdf0e10cSrcweir                     *pNode, nLastStart,
2960cdf0e10cSrcweir                     SvxCreateLocale( GetLanguage( EditPaM( pNode, nLastStart + 1 ) ) ) );
2961cdf0e10cSrcweir 
2962cdf0e10cSrcweir             // extend nCurrentStart, nCurrentEnd to the current sentence boundaries
2963cdf0e10cSrcweir             nCurrentStart = _xBI->beginOfSentence(
2964cdf0e10cSrcweir                     *pNode, nStartPos,
2965cdf0e10cSrcweir                     SvxCreateLocale( GetLanguage( EditPaM( pNode, nStartPos + 1 ) ) ) );
2966cdf0e10cSrcweir             nCurrentEnd = _xBI->endOfSentence(
2967cdf0e10cSrcweir                     *pNode, nCurrentStart,
2968cdf0e10cSrcweir                     SvxCreateLocale( GetLanguage( EditPaM( pNode, nCurrentStart + 1 ) ) ) );
2969cdf0e10cSrcweir 
2970cdf0e10cSrcweir             // prevent backtracking to the previous sentence if selection starts at end of a sentence
2971cdf0e10cSrcweir             if (nCurrentEnd <= nStartPos)
2972cdf0e10cSrcweir             {
2973cdf0e10cSrcweir                 // now nCurrentStart is probably located on a non-letter word. (unless we
2974cdf0e10cSrcweir                 // are in Asian text with no spaces...)
2975cdf0e10cSrcweir                 // Thus to get the real sentence start we should locate the next real word,
2976cdf0e10cSrcweir                 // that is one found by DICTIONARY_WORD
2977cdf0e10cSrcweir                 i18n::Boundary aBndry = _xBI->nextWord( *pNode, nCurrentEnd,
2978cdf0e10cSrcweir                         SvxCreateLocale( GetLanguage( EditPaM( pNode, nCurrentEnd + 1 ) ) ),
2979cdf0e10cSrcweir                         i18n::WordType::DICTIONARY_WORD);
2980cdf0e10cSrcweir 
2981cdf0e10cSrcweir                 // now get new current sentence boundaries
2982cdf0e10cSrcweir                 nCurrentStart = _xBI->beginOfSentence(
2983cdf0e10cSrcweir                         *pNode, aBndry.startPos,
2984cdf0e10cSrcweir                         SvxCreateLocale( GetLanguage( EditPaM( pNode, aBndry.startPos + 1 ) ) ) );
2985cdf0e10cSrcweir                 nCurrentEnd = _xBI->endOfSentence(
2986cdf0e10cSrcweir                         *pNode, nCurrentStart,
2987cdf0e10cSrcweir                         SvxCreateLocale( GetLanguage( EditPaM( pNode, nCurrentStart + 1 ) ) ) );
2988cdf0e10cSrcweir             }
2989cdf0e10cSrcweir             // prevent advancing to the next sentence if selection ends at start of a sentence
2990cdf0e10cSrcweir             if (nLastStart >= nEndPos)
2991cdf0e10cSrcweir             {
2992cdf0e10cSrcweir                 // now nCurrentStart is probably located on a non-letter word. (unless we
2993cdf0e10cSrcweir                 // are in Asian text with no spaces...)
2994cdf0e10cSrcweir                 // Thus to get the real sentence start we should locate the previous real word,
2995cdf0e10cSrcweir                 // that is one found by DICTIONARY_WORD
2996cdf0e10cSrcweir                 i18n::Boundary aBndry = _xBI->previousWord( *pNode, nLastStart,
2997cdf0e10cSrcweir                         SvxCreateLocale( GetLanguage( EditPaM( pNode, nLastStart + 1 ) ) ),
2998cdf0e10cSrcweir                         i18n::WordType::DICTIONARY_WORD);
2999cdf0e10cSrcweir                 nLastEnd = _xBI->endOfSentence(
3000cdf0e10cSrcweir                         *pNode, aBndry.startPos,
3001cdf0e10cSrcweir                         SvxCreateLocale( GetLanguage( EditPaM( pNode, aBndry.startPos + 1 ) ) ) );
3002cdf0e10cSrcweir                 if (nCurrentEnd > nLastEnd)
3003cdf0e10cSrcweir                     nCurrentEnd = nLastEnd;
3004cdf0e10cSrcweir             }
3005cdf0e10cSrcweir 
3006cdf0e10cSrcweir             while (nCurrentStart < nLastEnd)
3007cdf0e10cSrcweir             {
3008cdf0e10cSrcweir                 sal_Int32 nLen = nCurrentEnd - nCurrentStart;
3009cdf0e10cSrcweir                 DBG_ASSERT( nLen > 0, "invalid word length of 0" );
3010cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
3011cdf0e10cSrcweir                 String aText( pNode->Copy( nCurrentStart, nLen ) );
3012cdf0e10cSrcweir #endif
3013cdf0e10cSrcweir 
3014cdf0e10cSrcweir 	            Sequence< sal_Int32 > aOffsets;
3015cdf0e10cSrcweir                 String aNewText( aTranslitarationWrapper.transliterate( *pNode,
3016cdf0e10cSrcweir                         GetLanguage( EditPaM( pNode, nCurrentStart + 1 ) ),
3017cdf0e10cSrcweir                         nCurrentStart, nLen, &aOffsets ));
3018cdf0e10cSrcweir 
3019cdf0e10cSrcweir                 if (!pNode->Equals( aNewText, nCurrentStart, nLen ))
3020cdf0e10cSrcweir                 {
3021cdf0e10cSrcweir                     aChgData.nStart     = nCurrentStart;
3022cdf0e10cSrcweir                     aChgData.nLen       = nLen;
3023cdf0e10cSrcweir                     aChgData.aSelection = EditSelection( EditPaM( pNode, nCurrentStart ), EditPaM( pNode, nCurrentEnd ) );
3024cdf0e10cSrcweir                     aChgData.aNewText   = aNewText;
3025cdf0e10cSrcweir                     aChgData.aOffsets   = aOffsets;
3026cdf0e10cSrcweir                     aChanges.push_back( aChgData );
3027cdf0e10cSrcweir                 }
3028cdf0e10cSrcweir 
3029cdf0e10cSrcweir                 i18n::Boundary aFirstWordBndry;
3030cdf0e10cSrcweir                 aFirstWordBndry = _xBI->nextWord(
3031cdf0e10cSrcweir                         *pNode, nCurrentEnd,
3032cdf0e10cSrcweir                         SvxCreateLocale( GetLanguage( EditPaM( pNode, nCurrentEnd + 1 ) ) ),
3033cdf0e10cSrcweir                         nWordType);
3034cdf0e10cSrcweir                 nCurrentStart = aFirstWordBndry.startPos;
3035cdf0e10cSrcweir                 nCurrentEnd = _xBI->endOfSentence(
3036cdf0e10cSrcweir                         *pNode, nCurrentStart,
3037cdf0e10cSrcweir                         SvxCreateLocale( GetLanguage( EditPaM( pNode, nCurrentStart + 1 ) ) ) );
3038cdf0e10cSrcweir             }
3039cdf0e10cSrcweir             DBG_ASSERT( nCurrentEnd >= nLastEnd, "failed to reach end of transliteration" );
3040cdf0e10cSrcweir         }
3041cdf0e10cSrcweir         else
3042cdf0e10cSrcweir         {
3043cdf0e10cSrcweir             do
3044cdf0e10cSrcweir             {
3045cdf0e10cSrcweir 		        if ( bConsiderLanguage )
3046cdf0e10cSrcweir 		        {
3047cdf0e10cSrcweir 			        nLanguage = GetLanguage( EditPaM( pNode, nCurrentStart+1 ), &nCurrentEnd );
3048cdf0e10cSrcweir 			        if ( nCurrentEnd > nEndPos )
3049cdf0e10cSrcweir 				        nCurrentEnd = nEndPos;
3050cdf0e10cSrcweir 		        }
3051cdf0e10cSrcweir 
3052cdf0e10cSrcweir 		        xub_StrLen nLen = nCurrentEnd - nCurrentStart;
3053cdf0e10cSrcweir 
3054cdf0e10cSrcweir 		        Sequence< sal_Int32 > aOffsets;
3055cdf0e10cSrcweir 		        String aNewText( aTranslitarationWrapper.transliterate( *pNode, nLanguage, nCurrentStart, nLen, &aOffsets ) );
3056cdf0e10cSrcweir 
3057cdf0e10cSrcweir                 if (!pNode->Equals( aNewText, nCurrentStart, nLen ))
3058cdf0e10cSrcweir                 {
3059cdf0e10cSrcweir                     aChgData.nStart     = nCurrentStart;
3060cdf0e10cSrcweir                     aChgData.nLen       = nLen;
3061cdf0e10cSrcweir                     aChgData.aSelection = EditSelection( EditPaM( pNode, nCurrentStart ), EditPaM( pNode, nCurrentEnd ) );
3062cdf0e10cSrcweir                     aChgData.aNewText   = aNewText;
3063cdf0e10cSrcweir                     aChgData.aOffsets   = aOffsets;
3064cdf0e10cSrcweir                     aChanges.push_back( aChgData );
3065cdf0e10cSrcweir                 }
3066cdf0e10cSrcweir 
3067cdf0e10cSrcweir 		        nCurrentStart = nCurrentEnd;
3068cdf0e10cSrcweir 		    } while( nCurrentEnd < nEndPos );
3069cdf0e10cSrcweir         }
3070cdf0e10cSrcweir 
3071cdf0e10cSrcweir         if (aChanges.size() > 0)
3072cdf0e10cSrcweir         {
3073cdf0e10cSrcweir #ifndef SVX_LIGHT
3074cdf0e10cSrcweir             // Create a single UndoAction on Demand for all the changes ...
3075cdf0e10cSrcweir             if ( !pUndo && IsUndoEnabled() && !IsInUndo() )
3076cdf0e10cSrcweir             {
3077cdf0e10cSrcweir                 // adjust selection to include all changes
3078cdf0e10cSrcweir                 for (size_t i = 0; i < aChanges.size(); ++i)
3079cdf0e10cSrcweir                 {
3080cdf0e10cSrcweir                     const EditSelection &rSel = aChanges[i].aSelection;
3081cdf0e10cSrcweir                     if (aSel.Min().GetNode() == rSel.Min().GetNode() &&
3082cdf0e10cSrcweir                         aSel.Min().GetIndex() > rSel.Min().GetIndex())
3083cdf0e10cSrcweir                         aSel.Min().SetIndex( rSel.Min().GetIndex() );
3084cdf0e10cSrcweir                     if (aSel.Max().GetNode() == rSel.Max().GetNode() &&
3085cdf0e10cSrcweir                         aSel.Max().GetIndex() < rSel.Max().GetIndex())
3086cdf0e10cSrcweir                         aSel.Max().SetIndex( rSel.Max().GetIndex() );
3087cdf0e10cSrcweir                 }
3088cdf0e10cSrcweir                 aNewSel = aSel;
3089cdf0e10cSrcweir 
3090cdf0e10cSrcweir                 ESelection aESel( CreateESel( aSel ) );
3091cdf0e10cSrcweir                 pUndo = new EditUndoTransliteration( this, aESel, nTransliterationMode );
3092cdf0e10cSrcweir 
3093cdf0e10cSrcweir                 const bool bSingleNode = aSel.Min().GetNode()== aSel.Max().GetNode();
3094cdf0e10cSrcweir                 const bool bHasAttribs = aSel.Min().GetNode()->GetCharAttribs().HasAttrib( aSel.Min().GetIndex(), aSel.Max().GetIndex() );
3095cdf0e10cSrcweir                 if (bSingleNode && !bHasAttribs)
3096cdf0e10cSrcweir 	                pUndo->SetText( aSel.Min().GetNode()->Copy( aSel.Min().GetIndex(), aSel.Max().GetIndex()-aSel.Min().GetIndex() ) );
3097cdf0e10cSrcweir                 else
3098cdf0e10cSrcweir 	                pUndo->SetText( CreateBinTextObject( aSel, NULL ) );
3099cdf0e10cSrcweir             }
3100cdf0e10cSrcweir #endif
3101cdf0e10cSrcweir 
3102cdf0e10cSrcweir             // now apply the changes from end to start to leave the offsets of the
3103cdf0e10cSrcweir             // yet unchanged text parts remain the same.
3104cdf0e10cSrcweir             for (size_t i = 0; i < aChanges.size(); ++i)
3105cdf0e10cSrcweir             {
3106cdf0e10cSrcweir                 const TransliterationChgData &rData = aChanges[ aChanges.size() - 1 - i ];
3107cdf0e10cSrcweir 
3108cdf0e10cSrcweir 			    bChanges = sal_True;
3109cdf0e10cSrcweir                 if (rData.nLen != rData.aNewText.Len())
3110cdf0e10cSrcweir                     bLenChanged = sal_True;
3111cdf0e10cSrcweir 
311207a3d7f1SPedro Giffuni                 // Change text without losing the attributes
3113cdf0e10cSrcweir                 sal_uInt16 nDiffs = ReplaceTextOnly( rData.aSelection.Min().GetNode(),
3114cdf0e10cSrcweir                         rData.nStart, rData.nLen, rData.aNewText, rData.aOffsets );
3115cdf0e10cSrcweir 
3116cdf0e10cSrcweir                 // adjust selection in end node to possibly changed size
3117cdf0e10cSrcweir                 if (aSel.Max().GetNode() == rData.aSelection.Max().GetNode())
3118cdf0e10cSrcweir                     aNewSel.Max().GetIndex() = aNewSel.Max().GetIndex() + nDiffs;
3119cdf0e10cSrcweir 
3120*7a980842SDamjanJovanovic                 sal_uInt32 nSelNode = aEditDoc.GetPos( rData.aSelection.Min().GetNode() );
3121cdf0e10cSrcweir                 ParaPortion* pParaPortion = GetParaPortions()[nSelNode];
3122cdf0e10cSrcweir 			    pParaPortion->MarkSelectionInvalid( rData.nStart,
3123cdf0e10cSrcweir                         std::max< sal_uInt16 >( rData.nStart + rData.nLen,
3124cdf0e10cSrcweir                                             rData.nStart + rData.aNewText.Len() ) );
3125cdf0e10cSrcweir 		    }
3126cdf0e10cSrcweir         } // if (aChanges.size() > 0)
3127cdf0e10cSrcweir     }
3128cdf0e10cSrcweir 
3129cdf0e10cSrcweir #ifndef SVX_LIGHT
3130cdf0e10cSrcweir 	if ( pUndo )
3131cdf0e10cSrcweir 	{
3132cdf0e10cSrcweir 		ESelection aESel( CreateESel( aNewSel ) );
3133cdf0e10cSrcweir 		pUndo->SetNewSelection( aESel );
3134cdf0e10cSrcweir 		InsertUndo( pUndo );
3135cdf0e10cSrcweir 	}
3136cdf0e10cSrcweir #endif
3137cdf0e10cSrcweir 
3138cdf0e10cSrcweir 	if ( bChanges )
3139cdf0e10cSrcweir     {
3140cdf0e10cSrcweir         TextModified();
3141cdf0e10cSrcweir         SetModifyFlag( sal_True );
3142cdf0e10cSrcweir         if ( bLenChanged )
3143cdf0e10cSrcweir             UpdateSelections();
3144cdf0e10cSrcweir 		FormatAndUpdate();
3145cdf0e10cSrcweir     }
3146cdf0e10cSrcweir 
3147cdf0e10cSrcweir     return aNewSel;
3148cdf0e10cSrcweir }
3149cdf0e10cSrcweir 
3150cdf0e10cSrcweir 
ReplaceTextOnly(ContentNode * pNode,sal_uInt16 nCurrentStart,xub_StrLen nLen,const String & rNewText,const uno::Sequence<sal_Int32> & rOffsets)3151cdf0e10cSrcweir short ImpEditEngine::ReplaceTextOnly(
3152cdf0e10cSrcweir     ContentNode* pNode,
3153cdf0e10cSrcweir     sal_uInt16 nCurrentStart, xub_StrLen nLen,
3154cdf0e10cSrcweir 	const String& rNewText,
3155cdf0e10cSrcweir     const uno::Sequence< sal_Int32 >& rOffsets )
3156cdf0e10cSrcweir {
3157cdf0e10cSrcweir     (void)  nLen;
3158cdf0e10cSrcweir 
315907a3d7f1SPedro Giffuni     // Change text without losing the attributes
3160cdf0e10cSrcweir     sal_uInt16 nCharsAfterTransliteration =
3161cdf0e10cSrcweir         sal::static_int_cast< sal_uInt16 >(rOffsets.getLength());
3162cdf0e10cSrcweir     const sal_Int32* pOffsets = rOffsets.getConstArray();
3163cdf0e10cSrcweir     short nDiffs = 0;
3164cdf0e10cSrcweir     for ( sal_uInt16 n = 0; n < nCharsAfterTransliteration; n++ )
3165cdf0e10cSrcweir     {
3166cdf0e10cSrcweir         sal_uInt16 nCurrentPos = nCurrentStart+n;
3167cdf0e10cSrcweir         sal_Int32 nDiff = (nCurrentPos-nDiffs) - pOffsets[n];
3168cdf0e10cSrcweir 
3169cdf0e10cSrcweir         if ( !nDiff )
3170cdf0e10cSrcweir         {
3171cdf0e10cSrcweir             DBG_ASSERT( nCurrentPos < pNode->Len(), "TransliterateText - String smaller than expected!" );
3172cdf0e10cSrcweir             pNode->SetChar( nCurrentPos, rNewText.GetChar(n) );
3173cdf0e10cSrcweir         }
3174cdf0e10cSrcweir         else if ( nDiff < 0 )
3175cdf0e10cSrcweir         {
3176cdf0e10cSrcweir             // Replace first char, delete the rest...
3177cdf0e10cSrcweir             DBG_ASSERT( nCurrentPos < pNode->Len(), "TransliterateText - String smaller than expected!" );
3178cdf0e10cSrcweir             pNode->SetChar( nCurrentPos, rNewText.GetChar(n) );
3179cdf0e10cSrcweir 
3180cdf0e10cSrcweir             DBG_ASSERT( (nCurrentPos+1) < pNode->Len(), "TransliterateText - String smaller than expected!" );
3181cdf0e10cSrcweir             GetEditDoc().RemoveChars( EditPaM( pNode, nCurrentPos+1 ), sal::static_int_cast< sal_uInt16 >(-nDiff) );
3182cdf0e10cSrcweir         }
3183cdf0e10cSrcweir         else
3184cdf0e10cSrcweir         {
3185cdf0e10cSrcweir             DBG_ASSERT( nDiff == 1, "TransliterateText - Diff other than expected! But should work..." );
3186cdf0e10cSrcweir             GetEditDoc().InsertText( EditPaM( pNode, nCurrentPos ), rNewText.GetChar(n) );
3187cdf0e10cSrcweir 
3188cdf0e10cSrcweir         }
3189cdf0e10cSrcweir         nDiffs = sal::static_int_cast< short >(nDiffs + nDiff);
3190cdf0e10cSrcweir     }
3191cdf0e10cSrcweir 
3192cdf0e10cSrcweir     return nDiffs;
3193cdf0e10cSrcweir }
3194cdf0e10cSrcweir 
3195cdf0e10cSrcweir 
SetAsianCompressionMode(sal_uInt16 n)3196cdf0e10cSrcweir void ImpEditEngine::SetAsianCompressionMode( sal_uInt16 n )
3197cdf0e10cSrcweir {
3198cdf0e10cSrcweir     if ( n != nAsianCompressionMode )
3199cdf0e10cSrcweir     {
3200cdf0e10cSrcweir         nAsianCompressionMode = n;
3201cdf0e10cSrcweir         if ( ImplHasText() )
3202cdf0e10cSrcweir         {
3203cdf0e10cSrcweir             FormatFullDoc();
3204cdf0e10cSrcweir             UpdateViews();
3205cdf0e10cSrcweir         }
3206cdf0e10cSrcweir     }
3207cdf0e10cSrcweir }
3208cdf0e10cSrcweir 
SetKernAsianPunctuation(sal_Bool b)3209cdf0e10cSrcweir void ImpEditEngine::SetKernAsianPunctuation( sal_Bool b )
3210cdf0e10cSrcweir {
3211cdf0e10cSrcweir     if ( b != bKernAsianPunctuation )
3212cdf0e10cSrcweir     {
3213cdf0e10cSrcweir         bKernAsianPunctuation = b;
3214cdf0e10cSrcweir         if ( ImplHasText() )
3215cdf0e10cSrcweir         {
3216cdf0e10cSrcweir             FormatFullDoc();
3217cdf0e10cSrcweir             UpdateViews();
3218cdf0e10cSrcweir         }
3219cdf0e10cSrcweir     }
3220cdf0e10cSrcweir }
3221cdf0e10cSrcweir 
SetAddExtLeading(sal_Bool bExtLeading)3222cdf0e10cSrcweir void ImpEditEngine::SetAddExtLeading( sal_Bool bExtLeading )
3223cdf0e10cSrcweir {
3224cdf0e10cSrcweir     if ( IsAddExtLeading() != bExtLeading )
3225cdf0e10cSrcweir     {
3226cdf0e10cSrcweir         bAddExtLeading = bExtLeading;
3227cdf0e10cSrcweir         if ( ImplHasText() )
3228cdf0e10cSrcweir         {
3229cdf0e10cSrcweir             FormatFullDoc();
3230cdf0e10cSrcweir             UpdateViews();
3231cdf0e10cSrcweir         }
3232cdf0e10cSrcweir     }
3233cdf0e10cSrcweir };
3234cdf0e10cSrcweir 
3235cdf0e10cSrcweir 
3236cdf0e10cSrcweir 
ImplHasText() const3237cdf0e10cSrcweir sal_Bool ImpEditEngine::ImplHasText() const
3238cdf0e10cSrcweir {
3239cdf0e10cSrcweir     return ( ( GetEditDoc().Count() > 1 ) || GetEditDoc().GetObject(0)->Len() );
3240cdf0e10cSrcweir }
3241cdf0e10cSrcweir 
LogicToTwips(long n)3242cdf0e10cSrcweir long ImpEditEngine::LogicToTwips( long n )
3243cdf0e10cSrcweir {
3244cdf0e10cSrcweir 	Size aSz( n, 0 );
3245cdf0e10cSrcweir 	MapMode aTwipsMode( MAP_TWIP );
3246cdf0e10cSrcweir 	aSz = pRefDev->LogicToLogic( aSz, NULL, &aTwipsMode );
3247cdf0e10cSrcweir 	return aSz.Width();
3248cdf0e10cSrcweir }
3249cdf0e10cSrcweir 
3250cdf0e10cSrcweir 
3251