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