1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski *
3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file
5*b1cdbd2cSJim Jagielski * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file
7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski *
11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski *
13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the
17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski * under the License.
19*b1cdbd2cSJim Jagielski *
20*b1cdbd2cSJim Jagielski *************************************************************/
21*b1cdbd2cSJim Jagielski
22*b1cdbd2cSJim Jagielski
23*b1cdbd2cSJim Jagielski
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_editeng.hxx"
26*b1cdbd2cSJim Jagielski
27*b1cdbd2cSJim Jagielski #include <vcl/wrkwin.hxx>
28*b1cdbd2cSJim Jagielski #include <vcl/dialog.hxx>
29*b1cdbd2cSJim Jagielski #include <vcl/msgbox.hxx>
30*b1cdbd2cSJim Jagielski #include <vcl/svapp.hxx>
31*b1cdbd2cSJim Jagielski
32*b1cdbd2cSJim Jagielski #include <editeng/lspcitem.hxx>
33*b1cdbd2cSJim Jagielski #include <editeng/flditem.hxx>
34*b1cdbd2cSJim Jagielski #include <impedit.hxx>
35*b1cdbd2cSJim Jagielski #include <editeng/editeng.hxx>
36*b1cdbd2cSJim Jagielski #include <editeng/editview.hxx>
37*b1cdbd2cSJim Jagielski #include <editdbg.hxx>
38*b1cdbd2cSJim Jagielski #include <eerdll2.hxx>
39*b1cdbd2cSJim Jagielski #include <editeng/eerdll.hxx>
40*b1cdbd2cSJim Jagielski #include <edtspell.hxx>
41*b1cdbd2cSJim Jagielski #include <eeobj.hxx>
42*b1cdbd2cSJim Jagielski #include <editeng/txtrange.hxx>
43*b1cdbd2cSJim Jagielski #include <svl/urlbmk.hxx>
44*b1cdbd2cSJim Jagielski #include <svtools/colorcfg.hxx>
45*b1cdbd2cSJim Jagielski #include <svl/ctloptions.hxx>
46*b1cdbd2cSJim Jagielski #include <editeng/acorrcfg.hxx>
47*b1cdbd2cSJim Jagielski #include <editeng/fhgtitem.hxx>
48*b1cdbd2cSJim Jagielski #include <editeng/lrspitem.hxx>
49*b1cdbd2cSJim Jagielski #include <editeng/ulspitem.hxx>
50*b1cdbd2cSJim Jagielski #include <editeng/wghtitem.hxx>
51*b1cdbd2cSJim Jagielski #include <editeng/postitem.hxx>
52*b1cdbd2cSJim Jagielski #include <editeng/udlnitem.hxx>
53*b1cdbd2cSJim Jagielski #include <editeng/adjitem.hxx>
54*b1cdbd2cSJim Jagielski #include <editeng/scripttypeitem.hxx>
55*b1cdbd2cSJim Jagielski #include <editeng/frmdiritem.hxx>
56*b1cdbd2cSJim Jagielski #include <editeng/fontitem.hxx>
57*b1cdbd2cSJim Jagielski #include <vcl/cmdevt.h>
58*b1cdbd2cSJim Jagielski
59*b1cdbd2cSJim Jagielski #include <com/sun/star/i18n/CharacterIteratorMode.hpp>
60*b1cdbd2cSJim Jagielski #include <com/sun/star/i18n/WordType.hpp>
61*b1cdbd2cSJim Jagielski #include <com/sun/star/i18n/ScriptType.hpp>
62*b1cdbd2cSJim Jagielski #include <com/sun/star/lang/Locale.hpp>
63*b1cdbd2cSJim Jagielski #include <com/sun/star/text/CharacterCompressionType.hpp>
64*b1cdbd2cSJim Jagielski #include <com/sun/star/i18n/InputSequenceCheckMode.hpp>
65*b1cdbd2cSJim Jagielski
66*b1cdbd2cSJim Jagielski #include <comphelper/processfactory.hxx>
67*b1cdbd2cSJim Jagielski
68*b1cdbd2cSJim Jagielski #include <sot/formats.hxx>
69*b1cdbd2cSJim Jagielski
70*b1cdbd2cSJim Jagielski #include <unicode/ubidi.h>
71*b1cdbd2cSJim Jagielski
72*b1cdbd2cSJim Jagielski using namespace ::com::sun::star;
73*b1cdbd2cSJim Jagielski
lcl_CalcExtraSpace(ParaPortion *,const SvxLineSpacingItem & rLSItem)74*b1cdbd2cSJim Jagielski sal_uInt16 lcl_CalcExtraSpace( ParaPortion*, const SvxLineSpacingItem& rLSItem )
75*b1cdbd2cSJim Jagielski {
76*b1cdbd2cSJim Jagielski sal_uInt16 nExtra = 0;
77*b1cdbd2cSJim Jagielski /* if ( ( rLSItem.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_PROP )
78*b1cdbd2cSJim Jagielski && ( rLSItem.GetPropLineSpace() != 100 ) )
79*b1cdbd2cSJim Jagielski {
80*b1cdbd2cSJim Jagielski // sal_uLong nH = pPortion->GetNode()->GetCharAttribs().GetDefFont().GetSize().Height();
81*b1cdbd2cSJim Jagielski sal_uLong nH = pPortion->GetLines().GetObject( 0 )->GetHeight();
82*b1cdbd2cSJim Jagielski long n = nH * rLSItem.GetPropLineSpace();
83*b1cdbd2cSJim Jagielski n /= 100;
84*b1cdbd2cSJim Jagielski n -= nH; // nur den Abstand
85*b1cdbd2cSJim Jagielski if ( n > 0 )
86*b1cdbd2cSJim Jagielski nExtra = (sal_uInt16)n;
87*b1cdbd2cSJim Jagielski }
88*b1cdbd2cSJim Jagielski else */
89*b1cdbd2cSJim Jagielski if ( rLSItem.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_FIX )
90*b1cdbd2cSJim Jagielski {
91*b1cdbd2cSJim Jagielski nExtra = rLSItem.GetInterLineSpace();
92*b1cdbd2cSJim Jagielski }
93*b1cdbd2cSJim Jagielski
94*b1cdbd2cSJim Jagielski return nExtra;
95*b1cdbd2cSJim Jagielski }
96*b1cdbd2cSJim Jagielski
97*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------
98*b1cdbd2cSJim Jagielski // class ImpEditEngine
99*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------
100*b1cdbd2cSJim Jagielski
ImpEditEngine(EditEngine * pEE,SfxItemPool * pItemPool)101*b1cdbd2cSJim Jagielski ImpEditEngine::ImpEditEngine( EditEngine* pEE, SfxItemPool* pItemPool ) :
102*b1cdbd2cSJim Jagielski aPaperSize( 0x7FFFFFFF, 0x7FFFFFFF ),
103*b1cdbd2cSJim Jagielski aMinAutoPaperSize( 0x0, 0x0 ),
104*b1cdbd2cSJim Jagielski aMaxAutoPaperSize( 0x7FFFFFFF, 0x7FFFFFFF ),
105*b1cdbd2cSJim Jagielski aEditDoc( pItemPool ),
106*b1cdbd2cSJim Jagielski aWordDelimiters( RTL_CONSTASCII_USTRINGPARAM( " .,;:-'`'?!_=\"{}()[]\0xFF" ) ),
107*b1cdbd2cSJim Jagielski aGroupChars( RTL_CONSTASCII_USTRINGPARAM( "{}()[]" ) )
108*b1cdbd2cSJim Jagielski {
109*b1cdbd2cSJim Jagielski pEditEngine = pEE;
110*b1cdbd2cSJim Jagielski pRefDev = NULL;
111*b1cdbd2cSJim Jagielski pVirtDev = NULL;
112*b1cdbd2cSJim Jagielski pEmptyItemSet = NULL;
113*b1cdbd2cSJim Jagielski pActiveView = NULL;
114*b1cdbd2cSJim Jagielski pSpellInfo = NULL;
115*b1cdbd2cSJim Jagielski pConvInfo = NULL;
116*b1cdbd2cSJim Jagielski pTextObjectPool = NULL;
117*b1cdbd2cSJim Jagielski mpIMEInfos = NULL;
118*b1cdbd2cSJim Jagielski pStylePool = NULL;
119*b1cdbd2cSJim Jagielski pUndoManager = NULL;
120*b1cdbd2cSJim Jagielski pUndoMarkSelection = NULL;
121*b1cdbd2cSJim Jagielski pTextRanger = NULL;
122*b1cdbd2cSJim Jagielski pColorConfig = NULL;
123*b1cdbd2cSJim Jagielski pCTLOptions = NULL;
124*b1cdbd2cSJim Jagielski
125*b1cdbd2cSJim Jagielski nCurTextHeight = 0;
126*b1cdbd2cSJim Jagielski nBlockNotifications = 0;
127*b1cdbd2cSJim Jagielski nBigTextObjectStart = 20;
128*b1cdbd2cSJim Jagielski
129*b1cdbd2cSJim Jagielski nStretchX = 100;
130*b1cdbd2cSJim Jagielski nStretchY = 100;
131*b1cdbd2cSJim Jagielski
132*b1cdbd2cSJim Jagielski bInSelection = sal_False;
133*b1cdbd2cSJim Jagielski bOwnerOfRefDev = sal_False;
134*b1cdbd2cSJim Jagielski bDowning = sal_False;
135*b1cdbd2cSJim Jagielski bIsInUndo = sal_False;
136*b1cdbd2cSJim Jagielski bIsFormatting = sal_False;
137*b1cdbd2cSJim Jagielski bFormatted = sal_False;
138*b1cdbd2cSJim Jagielski bUpdate = sal_True;
139*b1cdbd2cSJim Jagielski bUpdateForAcc = TRUE;
140*b1cdbd2cSJim Jagielski bUseAutoColor = sal_True;
141*b1cdbd2cSJim Jagielski bForceAutoColor = sal_False;
142*b1cdbd2cSJim Jagielski bAddExtLeading = sal_False;
143*b1cdbd2cSJim Jagielski bUndoEnabled = sal_True;
144*b1cdbd2cSJim Jagielski bCallParaInsertedOrDeleted = sal_False;
145*b1cdbd2cSJim Jagielski bImpConvertFirstCall= sal_False;
146*b1cdbd2cSJim Jagielski bFirstWordCapitalization = sal_True;
147*b1cdbd2cSJim Jagielski
148*b1cdbd2cSJim Jagielski eDefLanguage = LANGUAGE_DONTKNOW;
149*b1cdbd2cSJim Jagielski maBackgroundColor = COL_AUTO;
150*b1cdbd2cSJim Jagielski
151*b1cdbd2cSJim Jagielski nAsianCompressionMode = text::CharacterCompressionType::NONE;
152*b1cdbd2cSJim Jagielski bKernAsianPunctuation = sal_False;
153*b1cdbd2cSJim Jagielski
154*b1cdbd2cSJim Jagielski eDefaultHorizontalTextDirection = EE_HTEXTDIR_DEFAULT;
155*b1cdbd2cSJim Jagielski
156*b1cdbd2cSJim Jagielski
157*b1cdbd2cSJim Jagielski aStatus.GetControlWord() = EE_CNTRL_USECHARATTRIBS | EE_CNTRL_DOIDLEFORMAT |
158*b1cdbd2cSJim Jagielski EE_CNTRL_PASTESPECIAL | EE_CNTRL_UNDOATTRIBS |
159*b1cdbd2cSJim Jagielski EE_CNTRL_ALLOWBIGOBJS | EE_CNTRL_RTFSTYLESHEETS |
160*b1cdbd2cSJim Jagielski EE_CNTRL_FORMAT100;
161*b1cdbd2cSJim Jagielski
162*b1cdbd2cSJim Jagielski aSelEngine.SetFunctionSet( &aSelFuncSet );
163*b1cdbd2cSJim Jagielski
164*b1cdbd2cSJim Jagielski aStatusTimer.SetTimeout( 200 );
165*b1cdbd2cSJim Jagielski aStatusTimer.SetTimeoutHdl( LINK( this, ImpEditEngine, StatusTimerHdl ) );
166*b1cdbd2cSJim Jagielski
167*b1cdbd2cSJim Jagielski aIdleFormatter.SetTimeout( 5 );
168*b1cdbd2cSJim Jagielski aIdleFormatter.SetTimeoutHdl( LINK( this, ImpEditEngine, IdleFormatHdl ) );
169*b1cdbd2cSJim Jagielski
170*b1cdbd2cSJim Jagielski aOnlineSpellTimer.SetTimeout( 100 );
171*b1cdbd2cSJim Jagielski aOnlineSpellTimer.SetTimeoutHdl( LINK( this, ImpEditEngine, OnlineSpellHdl ) );
172*b1cdbd2cSJim Jagielski
173*b1cdbd2cSJim Jagielski pRefDev = EE_DLL()->GetGlobalData()->GetStdRefDevice();
174*b1cdbd2cSJim Jagielski
175*b1cdbd2cSJim Jagielski // Ab hier wird schon auf Daten zugegriffen!
176*b1cdbd2cSJim Jagielski SetRefDevice( pRefDev );
177*b1cdbd2cSJim Jagielski InitDoc( sal_False );
178*b1cdbd2cSJim Jagielski
179*b1cdbd2cSJim Jagielski bCallParaInsertedOrDeleted = sal_True;
180*b1cdbd2cSJim Jagielski
181*b1cdbd2cSJim Jagielski aEditDoc.SetModifyHdl( LINK( this, ImpEditEngine, DocModified ) );
182*b1cdbd2cSJim Jagielski
183*b1cdbd2cSJim Jagielski mbLastTryMerge = sal_False;
184*b1cdbd2cSJim Jagielski }
185*b1cdbd2cSJim Jagielski
~ImpEditEngine()186*b1cdbd2cSJim Jagielski ImpEditEngine::~ImpEditEngine()
187*b1cdbd2cSJim Jagielski {
188*b1cdbd2cSJim Jagielski aStatusTimer.Stop();
189*b1cdbd2cSJim Jagielski aOnlineSpellTimer.Stop();
190*b1cdbd2cSJim Jagielski aIdleFormatter.Stop();
191*b1cdbd2cSJim Jagielski
192*b1cdbd2cSJim Jagielski // das Zerstoeren von Vorlagen kann sonst unnoetiges Formatieren ausloesen,
193*b1cdbd2cSJim Jagielski // wenn eine Parent-Vorlage zerstoert wird.
194*b1cdbd2cSJim Jagielski // Und das nach dem Zerstoeren der Daten!
195*b1cdbd2cSJim Jagielski bDowning = sal_True;
196*b1cdbd2cSJim Jagielski SetUpdateMode( sal_False );
197*b1cdbd2cSJim Jagielski
198*b1cdbd2cSJim Jagielski delete pVirtDev;
199*b1cdbd2cSJim Jagielski delete pEmptyItemSet;
200*b1cdbd2cSJim Jagielski delete pUndoManager;
201*b1cdbd2cSJim Jagielski delete pTextRanger;
202*b1cdbd2cSJim Jagielski delete mpIMEInfos;
203*b1cdbd2cSJim Jagielski delete pColorConfig;
204*b1cdbd2cSJim Jagielski delete pCTLOptions;
205*b1cdbd2cSJim Jagielski if ( bOwnerOfRefDev )
206*b1cdbd2cSJim Jagielski delete pRefDev;
207*b1cdbd2cSJim Jagielski delete pSpellInfo;
208*b1cdbd2cSJim Jagielski }
209*b1cdbd2cSJim Jagielski
SetRefDevice(OutputDevice * pRef)210*b1cdbd2cSJim Jagielski void ImpEditEngine::SetRefDevice( OutputDevice* pRef )
211*b1cdbd2cSJim Jagielski {
212*b1cdbd2cSJim Jagielski if ( bOwnerOfRefDev )
213*b1cdbd2cSJim Jagielski delete pRefDev;
214*b1cdbd2cSJim Jagielski
215*b1cdbd2cSJim Jagielski pRefDev = pRef;
216*b1cdbd2cSJim Jagielski bOwnerOfRefDev = sal_False;
217*b1cdbd2cSJim Jagielski
218*b1cdbd2cSJim Jagielski if ( !pRef )
219*b1cdbd2cSJim Jagielski pRefDev = EE_DLL()->GetGlobalData()->GetStdRefDevice();
220*b1cdbd2cSJim Jagielski
221*b1cdbd2cSJim Jagielski nOnePixelInRef = (sal_uInt16)pRefDev->PixelToLogic( Size( 1, 0 ) ).Width();
222*b1cdbd2cSJim Jagielski
223*b1cdbd2cSJim Jagielski if ( IsFormatted() )
224*b1cdbd2cSJim Jagielski {
225*b1cdbd2cSJim Jagielski FormatFullDoc();
226*b1cdbd2cSJim Jagielski UpdateViews( (EditView*) 0);
227*b1cdbd2cSJim Jagielski }
228*b1cdbd2cSJim Jagielski }
229*b1cdbd2cSJim Jagielski
SetRefMapMode(const MapMode & rMapMode)230*b1cdbd2cSJim Jagielski void ImpEditEngine::SetRefMapMode( const MapMode& rMapMode )
231*b1cdbd2cSJim Jagielski {
232*b1cdbd2cSJim Jagielski if ( GetRefDevice()->GetMapMode() == rMapMode )
233*b1cdbd2cSJim Jagielski return;
234*b1cdbd2cSJim Jagielski
235*b1cdbd2cSJim Jagielski // Wenn RefDev == GlobalRefDev => eigenes anlegen!
236*b1cdbd2cSJim Jagielski if ( !bOwnerOfRefDev && ( pRefDev == EE_DLL()->GetGlobalData()->GetStdRefDevice() ) )
237*b1cdbd2cSJim Jagielski {
238*b1cdbd2cSJim Jagielski pRefDev = new VirtualDevice;
239*b1cdbd2cSJim Jagielski pRefDev->SetMapMode( MAP_TWIP );
240*b1cdbd2cSJim Jagielski SetRefDevice( pRefDev );
241*b1cdbd2cSJim Jagielski bOwnerOfRefDev = sal_True;
242*b1cdbd2cSJim Jagielski }
243*b1cdbd2cSJim Jagielski pRefDev->SetMapMode( rMapMode );
244*b1cdbd2cSJim Jagielski nOnePixelInRef = (sal_uInt16)pRefDev->PixelToLogic( Size( 1, 0 ) ).Width();
245*b1cdbd2cSJim Jagielski if ( IsFormatted() )
246*b1cdbd2cSJim Jagielski {
247*b1cdbd2cSJim Jagielski FormatFullDoc();
248*b1cdbd2cSJim Jagielski UpdateViews( (EditView*) 0);
249*b1cdbd2cSJim Jagielski }
250*b1cdbd2cSJim Jagielski }
251*b1cdbd2cSJim Jagielski
InitDoc(sal_Bool bKeepParaAttribs)252*b1cdbd2cSJim Jagielski void ImpEditEngine::InitDoc( sal_Bool bKeepParaAttribs )
253*b1cdbd2cSJim Jagielski {
254*b1cdbd2cSJim Jagielski sal_uInt16 nParas = aEditDoc.Count();
255*b1cdbd2cSJim Jagielski for ( sal_uInt16 n = bKeepParaAttribs ? 1 : 0; n < nParas; n++ )
256*b1cdbd2cSJim Jagielski {
257*b1cdbd2cSJim Jagielski if ( aEditDoc[n]->GetStyleSheet() )
258*b1cdbd2cSJim Jagielski EndListening( *aEditDoc[n]->GetStyleSheet(), sal_False );
259*b1cdbd2cSJim Jagielski }
260*b1cdbd2cSJim Jagielski
261*b1cdbd2cSJim Jagielski if ( bKeepParaAttribs )
262*b1cdbd2cSJim Jagielski aEditDoc.RemoveText();
263*b1cdbd2cSJim Jagielski else
264*b1cdbd2cSJim Jagielski aEditDoc.Clear();
265*b1cdbd2cSJim Jagielski
266*b1cdbd2cSJim Jagielski GetParaPortions().Reset();
267*b1cdbd2cSJim Jagielski
268*b1cdbd2cSJim Jagielski ParaPortion* pIniPortion = new ParaPortion( aEditDoc[0] );
269*b1cdbd2cSJim Jagielski GetParaPortions().Insert( pIniPortion, 0 );
270*b1cdbd2cSJim Jagielski
271*b1cdbd2cSJim Jagielski bFormatted = sal_False;
272*b1cdbd2cSJim Jagielski
273*b1cdbd2cSJim Jagielski if ( IsCallParaInsertedOrDeleted() )
274*b1cdbd2cSJim Jagielski {
275*b1cdbd2cSJim Jagielski GetEditEnginePtr()->ParagraphDeleted( EE_PARA_ALL );
276*b1cdbd2cSJim Jagielski GetEditEnginePtr()->ParagraphInserted( 0 );
277*b1cdbd2cSJim Jagielski }
278*b1cdbd2cSJim Jagielski
279*b1cdbd2cSJim Jagielski #ifndef SVX_LIGHT
280*b1cdbd2cSJim Jagielski if ( GetStatus().DoOnlineSpelling() )
281*b1cdbd2cSJim Jagielski aEditDoc.GetObject( 0 )->CreateWrongList();
282*b1cdbd2cSJim Jagielski #endif // !SVX_LIGHT
283*b1cdbd2cSJim Jagielski }
284*b1cdbd2cSJim Jagielski
DeleteSelected(EditSelection aSel)285*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::DeleteSelected( EditSelection aSel )
286*b1cdbd2cSJim Jagielski {
287*b1cdbd2cSJim Jagielski EditPaM aPaM ( ImpDeleteSelection( aSel ) );
288*b1cdbd2cSJim Jagielski return aPaM;
289*b1cdbd2cSJim Jagielski }
290*b1cdbd2cSJim Jagielski
GetSelected(const EditSelection & rSel,const LineEnd eEnd) const291*b1cdbd2cSJim Jagielski XubString ImpEditEngine::GetSelected( const EditSelection& rSel, const LineEnd eEnd ) const
292*b1cdbd2cSJim Jagielski {
293*b1cdbd2cSJim Jagielski XubString aText;
294*b1cdbd2cSJim Jagielski if ( !rSel.HasRange() )
295*b1cdbd2cSJim Jagielski return aText;
296*b1cdbd2cSJim Jagielski
297*b1cdbd2cSJim Jagielski String aSep = EditDoc::GetSepStr( eEnd );
298*b1cdbd2cSJim Jagielski
299*b1cdbd2cSJim Jagielski EditSelection aSel( rSel );
300*b1cdbd2cSJim Jagielski aSel.Adjust( aEditDoc );
301*b1cdbd2cSJim Jagielski
302*b1cdbd2cSJim Jagielski ContentNode* pStartNode = aSel.Min().GetNode();
303*b1cdbd2cSJim Jagielski ContentNode* pEndNode = aSel.Max().GetNode();
304*b1cdbd2cSJim Jagielski sal_uInt16 nStartNode = aEditDoc.GetPos( pStartNode );
305*b1cdbd2cSJim Jagielski sal_uInt16 nEndNode = aEditDoc.GetPos( pEndNode );
306*b1cdbd2cSJim Jagielski
307*b1cdbd2cSJim Jagielski DBG_ASSERT( nStartNode <= nEndNode, "Selektion nicht sortiert ?" );
308*b1cdbd2cSJim Jagielski
309*b1cdbd2cSJim Jagielski // ueber die Absaetze iterieren...
310*b1cdbd2cSJim Jagielski for ( sal_uInt16 nNode = nStartNode; nNode <= nEndNode; nNode++ )
311*b1cdbd2cSJim Jagielski {
312*b1cdbd2cSJim Jagielski DBG_ASSERT( aEditDoc.SaveGetObject( nNode ), "Node nicht gefunden: GetSelected" );
313*b1cdbd2cSJim Jagielski ContentNode* pNode = aEditDoc.GetObject( nNode );
314*b1cdbd2cSJim Jagielski
315*b1cdbd2cSJim Jagielski xub_StrLen nStartPos = 0;
316*b1cdbd2cSJim Jagielski xub_StrLen nEndPos = pNode->Len();
317*b1cdbd2cSJim Jagielski if ( nNode == nStartNode )
318*b1cdbd2cSJim Jagielski nStartPos = aSel.Min().GetIndex();
319*b1cdbd2cSJim Jagielski if ( nNode == nEndNode ) // kann auch == nStart sein!
320*b1cdbd2cSJim Jagielski nEndPos = aSel.Max().GetIndex();
321*b1cdbd2cSJim Jagielski
322*b1cdbd2cSJim Jagielski aText += aEditDoc.GetParaAsString( pNode, nStartPos, nEndPos );
323*b1cdbd2cSJim Jagielski if ( nNode < nEndNode )
324*b1cdbd2cSJim Jagielski aText += aSep;
325*b1cdbd2cSJim Jagielski }
326*b1cdbd2cSJim Jagielski return aText;
327*b1cdbd2cSJim Jagielski }
328*b1cdbd2cSJim Jagielski
MouseButtonDown(const MouseEvent & rMEvt,EditView * pView)329*b1cdbd2cSJim Jagielski sal_Bool ImpEditEngine::MouseButtonDown( const MouseEvent& rMEvt, EditView* pView )
330*b1cdbd2cSJim Jagielski {
331*b1cdbd2cSJim Jagielski GetSelEngine().SetCurView( pView );
332*b1cdbd2cSJim Jagielski SetActiveView( pView );
333*b1cdbd2cSJim Jagielski
334*b1cdbd2cSJim Jagielski if ( GetAutoCompleteText().Len() )
335*b1cdbd2cSJim Jagielski SetAutoCompleteText( String(), sal_True );
336*b1cdbd2cSJim Jagielski
337*b1cdbd2cSJim Jagielski GetSelEngine().SelMouseButtonDown( rMEvt );
338*b1cdbd2cSJim Jagielski // Sonderbehandlungen
339*b1cdbd2cSJim Jagielski EditSelection aCurSel( pView->pImpEditView->GetEditSelection() );
340*b1cdbd2cSJim Jagielski if ( !rMEvt.IsShift() )
341*b1cdbd2cSJim Jagielski {
342*b1cdbd2cSJim Jagielski if ( rMEvt.GetClicks() == 2 )
343*b1cdbd2cSJim Jagielski {
344*b1cdbd2cSJim Jagielski // damit die SelectionEngine weiss, dass Anker.
345*b1cdbd2cSJim Jagielski aSelEngine.CursorPosChanging( sal_True, sal_False );
346*b1cdbd2cSJim Jagielski
347*b1cdbd2cSJim Jagielski EditSelection aNewSelection( SelectWord( aCurSel ) );
348*b1cdbd2cSJim Jagielski pView->pImpEditView->DrawSelection();
349*b1cdbd2cSJim Jagielski pView->pImpEditView->SetEditSelection( aNewSelection );
350*b1cdbd2cSJim Jagielski pView->pImpEditView->DrawSelection();
351*b1cdbd2cSJim Jagielski pView->ShowCursor( sal_True, sal_True );
352*b1cdbd2cSJim Jagielski }
353*b1cdbd2cSJim Jagielski else if ( rMEvt.GetClicks() == 3 )
354*b1cdbd2cSJim Jagielski {
355*b1cdbd2cSJim Jagielski // damit die SelectionEngine weiss, dass Anker.
356*b1cdbd2cSJim Jagielski aSelEngine.CursorPosChanging( sal_True, sal_False );
357*b1cdbd2cSJim Jagielski
358*b1cdbd2cSJim Jagielski EditSelection aNewSelection( aCurSel );
359*b1cdbd2cSJim Jagielski aNewSelection.Min().SetIndex( 0 );
360*b1cdbd2cSJim Jagielski aNewSelection.Max().SetIndex( aCurSel.Min().GetNode()->Len() );
361*b1cdbd2cSJim Jagielski pView->pImpEditView->DrawSelection();
362*b1cdbd2cSJim Jagielski pView->pImpEditView->SetEditSelection( aNewSelection );
363*b1cdbd2cSJim Jagielski pView->pImpEditView->DrawSelection();
364*b1cdbd2cSJim Jagielski pView->ShowCursor( sal_True, sal_True );
365*b1cdbd2cSJim Jagielski }
366*b1cdbd2cSJim Jagielski }
367*b1cdbd2cSJim Jagielski return sal_True;
368*b1cdbd2cSJim Jagielski }
369*b1cdbd2cSJim Jagielski
Command(const CommandEvent & rCEvt,EditView * pView)370*b1cdbd2cSJim Jagielski void ImpEditEngine::Command( const CommandEvent& rCEvt, EditView* pView )
371*b1cdbd2cSJim Jagielski {
372*b1cdbd2cSJim Jagielski GetSelEngine().SetCurView( pView );
373*b1cdbd2cSJim Jagielski SetActiveView( pView );
374*b1cdbd2cSJim Jagielski if ( rCEvt.GetCommand() == COMMAND_VOICE )
375*b1cdbd2cSJim Jagielski {
376*b1cdbd2cSJim Jagielski const CommandVoiceData* pData = rCEvt.GetVoiceData();
377*b1cdbd2cSJim Jagielski if ( pData->GetType() == VOICECOMMANDTYPE_DICTATION )
378*b1cdbd2cSJim Jagielski {
379*b1cdbd2cSJim Jagielski // Funktionen auf KeyEvents umbiegen, wenn keine entsprechende
380*b1cdbd2cSJim Jagielski // Methode an EditView/EditEngine, damit Undo konsistent bleibt.
381*b1cdbd2cSJim Jagielski
382*b1cdbd2cSJim Jagielski SfxPoolItem* pNewAttr = NULL;
383*b1cdbd2cSJim Jagielski
384*b1cdbd2cSJim Jagielski switch ( pData->GetCommand() )
385*b1cdbd2cSJim Jagielski {
386*b1cdbd2cSJim Jagielski case DICTATIONCOMMAND_UNKNOWN:
387*b1cdbd2cSJim Jagielski {
388*b1cdbd2cSJim Jagielski pView->InsertText( pData->GetText() );
389*b1cdbd2cSJim Jagielski }
390*b1cdbd2cSJim Jagielski break;
391*b1cdbd2cSJim Jagielski case DICTATIONCOMMAND_NEWPARAGRAPH:
392*b1cdbd2cSJim Jagielski {
393*b1cdbd2cSJim Jagielski pView->PostKeyEvent( KeyEvent( 0, KeyCode( KEY_RETURN, 0 ) ) );
394*b1cdbd2cSJim Jagielski }
395*b1cdbd2cSJim Jagielski break;
396*b1cdbd2cSJim Jagielski case DICTATIONCOMMAND_NEWLINE:
397*b1cdbd2cSJim Jagielski {
398*b1cdbd2cSJim Jagielski pView->PostKeyEvent( KeyEvent( 0, KeyCode( KEY_RETURN, KEY_SHIFT ) ) );
399*b1cdbd2cSJim Jagielski }
400*b1cdbd2cSJim Jagielski break;
401*b1cdbd2cSJim Jagielski case DICTATIONCOMMAND_TAB:
402*b1cdbd2cSJim Jagielski {
403*b1cdbd2cSJim Jagielski pView->PostKeyEvent( KeyEvent( 0, KeyCode( KEY_TAB, 0 ) ) );
404*b1cdbd2cSJim Jagielski }
405*b1cdbd2cSJim Jagielski break;
406*b1cdbd2cSJim Jagielski case DICTATIONCOMMAND_LEFT:
407*b1cdbd2cSJim Jagielski {
408*b1cdbd2cSJim Jagielski pView->PostKeyEvent( KeyEvent( 0, KeyCode( KEY_LEFT, KEY_MOD1 ) ) );
409*b1cdbd2cSJim Jagielski }
410*b1cdbd2cSJim Jagielski break;
411*b1cdbd2cSJim Jagielski case DICTATIONCOMMAND_RIGHT:
412*b1cdbd2cSJim Jagielski {
413*b1cdbd2cSJim Jagielski pView->PostKeyEvent( KeyEvent( 0, KeyCode( KEY_RIGHT, KEY_MOD1 ) ) );
414*b1cdbd2cSJim Jagielski }
415*b1cdbd2cSJim Jagielski break;
416*b1cdbd2cSJim Jagielski case DICTATIONCOMMAND_UP:
417*b1cdbd2cSJim Jagielski {
418*b1cdbd2cSJim Jagielski pView->PostKeyEvent( KeyEvent( 0, KeyCode( KEY_UP, 0 ) ) );
419*b1cdbd2cSJim Jagielski }
420*b1cdbd2cSJim Jagielski break;
421*b1cdbd2cSJim Jagielski case DICTATIONCOMMAND_DOWN:
422*b1cdbd2cSJim Jagielski {
423*b1cdbd2cSJim Jagielski pView->PostKeyEvent( KeyEvent( 0, KeyCode( KEY_UP, 0 ) ) );
424*b1cdbd2cSJim Jagielski }
425*b1cdbd2cSJim Jagielski break;
426*b1cdbd2cSJim Jagielski case DICTATIONCOMMAND_UNDO:
427*b1cdbd2cSJim Jagielski {
428*b1cdbd2cSJim Jagielski pView->Undo();
429*b1cdbd2cSJim Jagielski }
430*b1cdbd2cSJim Jagielski break;
431*b1cdbd2cSJim Jagielski case DICTATIONCOMMAND_DEL:
432*b1cdbd2cSJim Jagielski {
433*b1cdbd2cSJim Jagielski pView->PostKeyEvent( KeyEvent( 0, KeyCode( KEY_LEFT, KEY_MOD1|KEY_SHIFT ) ) );
434*b1cdbd2cSJim Jagielski pView->DeleteSelected();
435*b1cdbd2cSJim Jagielski }
436*b1cdbd2cSJim Jagielski break;
437*b1cdbd2cSJim Jagielski case DICTATIONCOMMAND_BOLD_ON:
438*b1cdbd2cSJim Jagielski {
439*b1cdbd2cSJim Jagielski pNewAttr = new SvxWeightItem( WEIGHT_BOLD, EE_CHAR_WEIGHT );
440*b1cdbd2cSJim Jagielski }
441*b1cdbd2cSJim Jagielski break;
442*b1cdbd2cSJim Jagielski case DICTATIONCOMMAND_BOLD_OFF:
443*b1cdbd2cSJim Jagielski {
444*b1cdbd2cSJim Jagielski pNewAttr = new SvxWeightItem( WEIGHT_NORMAL, EE_CHAR_WEIGHT );
445*b1cdbd2cSJim Jagielski }
446*b1cdbd2cSJim Jagielski break;
447*b1cdbd2cSJim Jagielski case DICTATIONCOMMAND_ITALIC_ON:
448*b1cdbd2cSJim Jagielski {
449*b1cdbd2cSJim Jagielski pNewAttr = new SvxPostureItem( ITALIC_NORMAL, EE_CHAR_ITALIC );
450*b1cdbd2cSJim Jagielski }
451*b1cdbd2cSJim Jagielski break;
452*b1cdbd2cSJim Jagielski case DICTATIONCOMMAND_ITALIC_OFF:
453*b1cdbd2cSJim Jagielski {
454*b1cdbd2cSJim Jagielski pNewAttr = new SvxPostureItem( ITALIC_NORMAL, EE_CHAR_ITALIC );
455*b1cdbd2cSJim Jagielski }
456*b1cdbd2cSJim Jagielski break;
457*b1cdbd2cSJim Jagielski case DICTATIONCOMMAND_UNDERLINE_ON:
458*b1cdbd2cSJim Jagielski {
459*b1cdbd2cSJim Jagielski pNewAttr = new SvxUnderlineItem( UNDERLINE_SINGLE, EE_CHAR_UNDERLINE );
460*b1cdbd2cSJim Jagielski }
461*b1cdbd2cSJim Jagielski break;
462*b1cdbd2cSJim Jagielski case DICTATIONCOMMAND_UNDERLINE_OFF:
463*b1cdbd2cSJim Jagielski {
464*b1cdbd2cSJim Jagielski pNewAttr = new SvxUnderlineItem( UNDERLINE_NONE, EE_CHAR_UNDERLINE );
465*b1cdbd2cSJim Jagielski }
466*b1cdbd2cSJim Jagielski break;
467*b1cdbd2cSJim Jagielski }
468*b1cdbd2cSJim Jagielski
469*b1cdbd2cSJim Jagielski if ( pNewAttr )
470*b1cdbd2cSJim Jagielski {
471*b1cdbd2cSJim Jagielski SfxItemSet aSet( GetEmptyItemSet() );
472*b1cdbd2cSJim Jagielski aSet.Put( *pNewAttr );
473*b1cdbd2cSJim Jagielski pView->SetAttribs( aSet );
474*b1cdbd2cSJim Jagielski delete pNewAttr;
475*b1cdbd2cSJim Jagielski }
476*b1cdbd2cSJim Jagielski }
477*b1cdbd2cSJim Jagielski }
478*b1cdbd2cSJim Jagielski else if ( rCEvt.GetCommand() == COMMAND_STARTEXTTEXTINPUT )
479*b1cdbd2cSJim Jagielski {
480*b1cdbd2cSJim Jagielski pView->DeleteSelected();
481*b1cdbd2cSJim Jagielski delete mpIMEInfos;
482*b1cdbd2cSJim Jagielski EditPaM aPaM = pView->GetImpEditView()->GetEditSelection().Max();
483*b1cdbd2cSJim Jagielski String aOldTextAfterStartPos = aPaM.GetNode()->Copy( aPaM.GetIndex() );
484*b1cdbd2cSJim Jagielski sal_uInt16 nMax = aOldTextAfterStartPos.Search( CH_FEATURE );
485*b1cdbd2cSJim Jagielski if ( nMax != STRING_NOTFOUND ) // don't overwrite features!
486*b1cdbd2cSJim Jagielski aOldTextAfterStartPos.Erase( nMax );
487*b1cdbd2cSJim Jagielski mpIMEInfos = new ImplIMEInfos( aPaM, aOldTextAfterStartPos );
488*b1cdbd2cSJim Jagielski mpIMEInfos->bWasCursorOverwrite = !pView->IsInsertMode();
489*b1cdbd2cSJim Jagielski UndoActionStart( EDITUNDO_INSERT );
490*b1cdbd2cSJim Jagielski }
491*b1cdbd2cSJim Jagielski else if ( rCEvt.GetCommand() == COMMAND_ENDEXTTEXTINPUT )
492*b1cdbd2cSJim Jagielski {
493*b1cdbd2cSJim Jagielski DBG_ASSERT( mpIMEInfos, "COMMAND_ENDEXTTEXTINPUT => Kein Start ?" );
494*b1cdbd2cSJim Jagielski if( mpIMEInfos )
495*b1cdbd2cSJim Jagielski {
496*b1cdbd2cSJim Jagielski // #102812# convert quotes in IME text
497*b1cdbd2cSJim Jagielski // works on the last input character, this is escpecially in Korean text often done
498*b1cdbd2cSJim Jagielski // quotes that are inside of the string are not replaced!
499*b1cdbd2cSJim Jagielski // Borrowed from sw: edtwin.cxx
500*b1cdbd2cSJim Jagielski if ( mpIMEInfos->nLen )
501*b1cdbd2cSJim Jagielski {
502*b1cdbd2cSJim Jagielski EditSelection aSel( mpIMEInfos->aPos );
503*b1cdbd2cSJim Jagielski aSel.Min().GetIndex() += mpIMEInfos->nLen-1;
504*b1cdbd2cSJim Jagielski aSel.Max().GetIndex() =
505*b1cdbd2cSJim Jagielski aSel.Max().GetIndex() + mpIMEInfos->nLen;
506*b1cdbd2cSJim Jagielski // #102812# convert quotes in IME text
507*b1cdbd2cSJim Jagielski // works on the last input character, this is escpecially in Korean text often done
508*b1cdbd2cSJim Jagielski // quotes that are inside of the string are not replaced!
509*b1cdbd2cSJim Jagielski const sal_Unicode nCharCode = aSel.Min().GetNode()->GetChar( aSel.Min().GetIndex() );
510*b1cdbd2cSJim Jagielski if ( ( GetStatus().DoAutoCorrect() ) && ( ( nCharCode == '\"' ) || ( nCharCode == '\'' ) ) )
511*b1cdbd2cSJim Jagielski {
512*b1cdbd2cSJim Jagielski aSel = DeleteSelected( aSel );
513*b1cdbd2cSJim Jagielski aSel = AutoCorrect( aSel, nCharCode, mpIMEInfos->bWasCursorOverwrite );
514*b1cdbd2cSJim Jagielski pView->pImpEditView->SetEditSelection( aSel );
515*b1cdbd2cSJim Jagielski }
516*b1cdbd2cSJim Jagielski }
517*b1cdbd2cSJim Jagielski
518*b1cdbd2cSJim Jagielski ParaPortion* pPortion = FindParaPortion( mpIMEInfos->aPos.GetNode() );
519*b1cdbd2cSJim Jagielski pPortion->MarkSelectionInvalid( mpIMEInfos->aPos.GetIndex(), 0 );
520*b1cdbd2cSJim Jagielski
521*b1cdbd2cSJim Jagielski sal_Bool bWasCursorOverwrite = mpIMEInfos->bWasCursorOverwrite;
522*b1cdbd2cSJim Jagielski
523*b1cdbd2cSJim Jagielski delete mpIMEInfos;
524*b1cdbd2cSJim Jagielski mpIMEInfos = NULL;
525*b1cdbd2cSJim Jagielski
526*b1cdbd2cSJim Jagielski FormatAndUpdate( pView );
527*b1cdbd2cSJim Jagielski
528*b1cdbd2cSJim Jagielski pView->SetInsertMode( !bWasCursorOverwrite );
529*b1cdbd2cSJim Jagielski }
530*b1cdbd2cSJim Jagielski UndoActionEnd( EDITUNDO_INSERT );
531*b1cdbd2cSJim Jagielski }
532*b1cdbd2cSJim Jagielski else if ( rCEvt.GetCommand() == COMMAND_EXTTEXTINPUT )
533*b1cdbd2cSJim Jagielski {
534*b1cdbd2cSJim Jagielski DBG_ASSERT( mpIMEInfos, "COMMAND_EXTTEXTINPUT => Kein Start ?" );
535*b1cdbd2cSJim Jagielski if( mpIMEInfos )
536*b1cdbd2cSJim Jagielski {
537*b1cdbd2cSJim Jagielski const CommandExtTextInputData* pData = rCEvt.GetExtTextInputData();
538*b1cdbd2cSJim Jagielski
539*b1cdbd2cSJim Jagielski if ( !pData->IsOnlyCursorChanged() )
540*b1cdbd2cSJim Jagielski {
541*b1cdbd2cSJim Jagielski EditSelection aSel( mpIMEInfos->aPos );
542*b1cdbd2cSJim Jagielski aSel.Max().GetIndex() =
543*b1cdbd2cSJim Jagielski aSel.Max().GetIndex() + mpIMEInfos->nLen;
544*b1cdbd2cSJim Jagielski aSel = DeleteSelected( aSel );
545*b1cdbd2cSJim Jagielski aSel = ImpInsertText( aSel, pData->GetText() );
546*b1cdbd2cSJim Jagielski
547*b1cdbd2cSJim Jagielski if ( mpIMEInfos->bWasCursorOverwrite )
548*b1cdbd2cSJim Jagielski {
549*b1cdbd2cSJim Jagielski sal_uInt16 nOldIMETextLen = mpIMEInfos->nLen;
550*b1cdbd2cSJim Jagielski sal_uInt16 nNewIMETextLen = pData->GetText().Len();
551*b1cdbd2cSJim Jagielski
552*b1cdbd2cSJim Jagielski if ( ( nOldIMETextLen > nNewIMETextLen ) &&
553*b1cdbd2cSJim Jagielski ( nNewIMETextLen < mpIMEInfos->aOldTextAfterStartPos.Len() ) )
554*b1cdbd2cSJim Jagielski {
555*b1cdbd2cSJim Jagielski // restore old characters
556*b1cdbd2cSJim Jagielski sal_uInt16 nRestore = nOldIMETextLen - nNewIMETextLen;
557*b1cdbd2cSJim Jagielski EditPaM aPaM( mpIMEInfos->aPos );
558*b1cdbd2cSJim Jagielski aPaM.GetIndex() = aPaM.GetIndex() + nNewIMETextLen;
559*b1cdbd2cSJim Jagielski ImpInsertText( aPaM, mpIMEInfos->aOldTextAfterStartPos.Copy( nNewIMETextLen, nRestore ) );
560*b1cdbd2cSJim Jagielski }
561*b1cdbd2cSJim Jagielski else if ( ( nOldIMETextLen < nNewIMETextLen ) &&
562*b1cdbd2cSJim Jagielski ( nOldIMETextLen < mpIMEInfos->aOldTextAfterStartPos.Len() ) )
563*b1cdbd2cSJim Jagielski {
564*b1cdbd2cSJim Jagielski // overwrite
565*b1cdbd2cSJim Jagielski sal_uInt16 nOverwrite = nNewIMETextLen - nOldIMETextLen;
566*b1cdbd2cSJim Jagielski if ( ( nOldIMETextLen + nOverwrite ) > mpIMEInfos->aOldTextAfterStartPos.Len() )
567*b1cdbd2cSJim Jagielski nOverwrite = mpIMEInfos->aOldTextAfterStartPos.Len() - nOldIMETextLen;
568*b1cdbd2cSJim Jagielski DBG_ASSERT( nOverwrite && (nOverwrite < 0xFF00), "IME Overwrite?!" );
569*b1cdbd2cSJim Jagielski EditPaM aPaM( mpIMEInfos->aPos );
570*b1cdbd2cSJim Jagielski aPaM.GetIndex() = aPaM.GetIndex() + nNewIMETextLen;
571*b1cdbd2cSJim Jagielski EditSelection _aSel( aPaM );
572*b1cdbd2cSJim Jagielski _aSel.Max().GetIndex() =
573*b1cdbd2cSJim Jagielski _aSel.Max().GetIndex() + nOverwrite;
574*b1cdbd2cSJim Jagielski DeleteSelected( _aSel );
575*b1cdbd2cSJim Jagielski }
576*b1cdbd2cSJim Jagielski }
577*b1cdbd2cSJim Jagielski if ( pData->GetTextAttr() )
578*b1cdbd2cSJim Jagielski {
579*b1cdbd2cSJim Jagielski mpIMEInfos->CopyAttribs( pData->GetTextAttr(), pData->GetText().Len() );
580*b1cdbd2cSJim Jagielski mpIMEInfos->bCursor = pData->IsCursorVisible();
581*b1cdbd2cSJim Jagielski }
582*b1cdbd2cSJim Jagielski else
583*b1cdbd2cSJim Jagielski {
584*b1cdbd2cSJim Jagielski mpIMEInfos->DestroyAttribs();
585*b1cdbd2cSJim Jagielski mpIMEInfos->nLen = pData->GetText().Len();
586*b1cdbd2cSJim Jagielski }
587*b1cdbd2cSJim Jagielski
588*b1cdbd2cSJim Jagielski ParaPortion* pPortion = FindParaPortion( mpIMEInfos->aPos.GetNode() );
589*b1cdbd2cSJim Jagielski pPortion->MarkSelectionInvalid( mpIMEInfos->aPos.GetIndex(), 0 );
590*b1cdbd2cSJim Jagielski FormatAndUpdate( pView );
591*b1cdbd2cSJim Jagielski }
592*b1cdbd2cSJim Jagielski
593*b1cdbd2cSJim Jagielski EditSelection aNewSel = EditPaM( mpIMEInfos->aPos.GetNode(), mpIMEInfos->aPos.GetIndex()+pData->GetCursorPos() );
594*b1cdbd2cSJim Jagielski pView->SetSelection( CreateESel( aNewSel ) );
595*b1cdbd2cSJim Jagielski pView->SetInsertMode( !pData->IsCursorOverwrite() );
596*b1cdbd2cSJim Jagielski
597*b1cdbd2cSJim Jagielski if ( pData->IsCursorVisible() )
598*b1cdbd2cSJim Jagielski pView->ShowCursor();
599*b1cdbd2cSJim Jagielski else
600*b1cdbd2cSJim Jagielski pView->HideCursor();
601*b1cdbd2cSJim Jagielski }
602*b1cdbd2cSJim Jagielski }
603*b1cdbd2cSJim Jagielski else if ( rCEvt.GetCommand() == COMMAND_INPUTCONTEXTCHANGE )
604*b1cdbd2cSJim Jagielski {
605*b1cdbd2cSJim Jagielski }
606*b1cdbd2cSJim Jagielski else if ( rCEvt.GetCommand() == COMMAND_CURSORPOS )
607*b1cdbd2cSJim Jagielski {
608*b1cdbd2cSJim Jagielski if ( mpIMEInfos && mpIMEInfos->nLen )
609*b1cdbd2cSJim Jagielski {
610*b1cdbd2cSJim Jagielski EditPaM aPaM( pView->pImpEditView->GetEditSelection().Max() );
611*b1cdbd2cSJim Jagielski Rectangle aR1 = PaMtoEditCursor( aPaM, 0 );
612*b1cdbd2cSJim Jagielski
613*b1cdbd2cSJim Jagielski sal_uInt16 nInputEnd = mpIMEInfos->aPos.GetIndex() + mpIMEInfos->nLen;
614*b1cdbd2cSJim Jagielski
615*b1cdbd2cSJim Jagielski if ( !IsFormatted() )
616*b1cdbd2cSJim Jagielski FormatDoc();
617*b1cdbd2cSJim Jagielski
618*b1cdbd2cSJim Jagielski ParaPortion* pParaPortion = GetParaPortions().SaveGetObject( GetEditDoc().GetPos( aPaM.GetNode() ) );
619*b1cdbd2cSJim Jagielski sal_uInt16 nLine = pParaPortion->GetLines().FindLine( aPaM.GetIndex(), sal_True );
620*b1cdbd2cSJim Jagielski EditLine* pLine = pParaPortion->GetLines().GetObject( nLine );
621*b1cdbd2cSJim Jagielski if ( pLine && ( nInputEnd > pLine->GetEnd() ) )
622*b1cdbd2cSJim Jagielski nInputEnd = pLine->GetEnd();
623*b1cdbd2cSJim Jagielski Rectangle aR2 = PaMtoEditCursor( EditPaM( aPaM.GetNode(), nInputEnd ), GETCRSR_ENDOFLINE );
624*b1cdbd2cSJim Jagielski Rectangle aRect = pView->GetImpEditView()->GetWindowPos( aR1 );
625*b1cdbd2cSJim Jagielski pView->GetWindow()->SetCursorRect( &aRect, aR2.Left()-aR1.Right() );
626*b1cdbd2cSJim Jagielski }
627*b1cdbd2cSJim Jagielski else
628*b1cdbd2cSJim Jagielski {
629*b1cdbd2cSJim Jagielski pView->GetWindow()->SetCursorRect();
630*b1cdbd2cSJim Jagielski }
631*b1cdbd2cSJim Jagielski }
632*b1cdbd2cSJim Jagielski else if ( rCEvt.GetCommand() == COMMAND_SELECTIONCHANGE )
633*b1cdbd2cSJim Jagielski {
634*b1cdbd2cSJim Jagielski const CommandSelectionChangeData *pData = rCEvt.GetSelectionChangeData();
635*b1cdbd2cSJim Jagielski
636*b1cdbd2cSJim Jagielski ESelection aSelection = pView->GetSelection();
637*b1cdbd2cSJim Jagielski aSelection.Adjust();
638*b1cdbd2cSJim Jagielski
639*b1cdbd2cSJim Jagielski if( pView->HasSelection() )
640*b1cdbd2cSJim Jagielski {
641*b1cdbd2cSJim Jagielski aSelection.nEndPos = aSelection.nStartPos;
642*b1cdbd2cSJim Jagielski aSelection.nStartPos += pData->GetStart();
643*b1cdbd2cSJim Jagielski aSelection.nEndPos += pData->GetEnd();
644*b1cdbd2cSJim Jagielski }
645*b1cdbd2cSJim Jagielski else
646*b1cdbd2cSJim Jagielski {
647*b1cdbd2cSJim Jagielski aSelection.nStartPos = pData->GetStart();
648*b1cdbd2cSJim Jagielski aSelection.nEndPos = pData->GetEnd();
649*b1cdbd2cSJim Jagielski }
650*b1cdbd2cSJim Jagielski pView->SetSelection( aSelection );
651*b1cdbd2cSJim Jagielski }
652*b1cdbd2cSJim Jagielski else if ( rCEvt.GetCommand() == COMMAND_PREPARERECONVERSION )
653*b1cdbd2cSJim Jagielski {
654*b1cdbd2cSJim Jagielski if ( pView->HasSelection() )
655*b1cdbd2cSJim Jagielski {
656*b1cdbd2cSJim Jagielski ESelection aSelection = pView->GetSelection();
657*b1cdbd2cSJim Jagielski aSelection.Adjust();
658*b1cdbd2cSJim Jagielski
659*b1cdbd2cSJim Jagielski if ( aSelection.nStartPara != aSelection.nEndPara )
660*b1cdbd2cSJim Jagielski {
661*b1cdbd2cSJim Jagielski xub_StrLen aParaLen = pEditEngine->GetTextLen( aSelection.nStartPara );
662*b1cdbd2cSJim Jagielski aSelection.nEndPara = aSelection.nStartPara;
663*b1cdbd2cSJim Jagielski aSelection.nEndPos = aParaLen;
664*b1cdbd2cSJim Jagielski pView->SetSelection( aSelection );
665*b1cdbd2cSJim Jagielski }
666*b1cdbd2cSJim Jagielski }
667*b1cdbd2cSJim Jagielski }
668*b1cdbd2cSJim Jagielski
669*b1cdbd2cSJim Jagielski GetSelEngine().Command( rCEvt );
670*b1cdbd2cSJim Jagielski }
671*b1cdbd2cSJim Jagielski
MouseButtonUp(const MouseEvent & rMEvt,EditView * pView)672*b1cdbd2cSJim Jagielski sal_Bool ImpEditEngine::MouseButtonUp( const MouseEvent& rMEvt, EditView* pView )
673*b1cdbd2cSJim Jagielski {
674*b1cdbd2cSJim Jagielski GetSelEngine().SetCurView( pView );
675*b1cdbd2cSJim Jagielski GetSelEngine().SelMouseButtonUp( rMEvt );
676*b1cdbd2cSJim Jagielski bInSelection = sal_False;
677*b1cdbd2cSJim Jagielski // Sonderbehandlungen
678*b1cdbd2cSJim Jagielski EditSelection aCurSel( pView->pImpEditView->GetEditSelection() );
679*b1cdbd2cSJim Jagielski if ( !aCurSel.HasRange() )
680*b1cdbd2cSJim Jagielski {
681*b1cdbd2cSJim Jagielski if ( ( rMEvt.GetClicks() == 1 ) && rMEvt.IsLeft() && !rMEvt.IsMod2() )
682*b1cdbd2cSJim Jagielski {
683*b1cdbd2cSJim Jagielski const SvxFieldItem* pFld = pView->GetFieldUnderMousePointer();
684*b1cdbd2cSJim Jagielski if ( pFld )
685*b1cdbd2cSJim Jagielski {
686*b1cdbd2cSJim Jagielski EditPaM aPaM( aCurSel.Max() );
687*b1cdbd2cSJim Jagielski sal_uInt16 nPara = GetEditDoc().GetPos( aPaM.GetNode() );
688*b1cdbd2cSJim Jagielski GetEditEnginePtr()->FieldClicked( *pFld, nPara, aPaM.GetIndex() );
689*b1cdbd2cSJim Jagielski }
690*b1cdbd2cSJim Jagielski }
691*b1cdbd2cSJim Jagielski }
692*b1cdbd2cSJim Jagielski return sal_True;
693*b1cdbd2cSJim Jagielski }
694*b1cdbd2cSJim Jagielski
MouseMove(const MouseEvent & rMEvt,EditView * pView)695*b1cdbd2cSJim Jagielski sal_Bool ImpEditEngine::MouseMove( const MouseEvent& rMEvt, EditView* pView )
696*b1cdbd2cSJim Jagielski {
697*b1cdbd2cSJim Jagielski // MouseMove wird sofort nach ShowQuickHelp() gerufen!
698*b1cdbd2cSJim Jagielski // if ( GetAutoCompleteText().Len() )
699*b1cdbd2cSJim Jagielski // SetAutoCompleteText( String(), sal_True );
700*b1cdbd2cSJim Jagielski GetSelEngine().SetCurView( pView );
701*b1cdbd2cSJim Jagielski GetSelEngine().SelMouseMove( rMEvt );
702*b1cdbd2cSJim Jagielski return sal_True;
703*b1cdbd2cSJim Jagielski }
704*b1cdbd2cSJim Jagielski
InsertText(EditSelection aSel,const XubString & rStr)705*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::InsertText( EditSelection aSel, const XubString& rStr )
706*b1cdbd2cSJim Jagielski {
707*b1cdbd2cSJim Jagielski EditPaM aPaM = ImpInsertText( aSel, rStr );
708*b1cdbd2cSJim Jagielski return aPaM;
709*b1cdbd2cSJim Jagielski }
710*b1cdbd2cSJim Jagielski
Clear()711*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::Clear()
712*b1cdbd2cSJim Jagielski {
713*b1cdbd2cSJim Jagielski InitDoc( sal_False );
714*b1cdbd2cSJim Jagielski
715*b1cdbd2cSJim Jagielski EditPaM aPaM = aEditDoc.GetStartPaM();
716*b1cdbd2cSJim Jagielski EditSelection aSel( aPaM );
717*b1cdbd2cSJim Jagielski
718*b1cdbd2cSJim Jagielski nCurTextHeight = 0;
719*b1cdbd2cSJim Jagielski
720*b1cdbd2cSJim Jagielski ResetUndoManager();
721*b1cdbd2cSJim Jagielski
722*b1cdbd2cSJim Jagielski for ( sal_uInt16 nView = aEditViews.Count(); nView; )
723*b1cdbd2cSJim Jagielski {
724*b1cdbd2cSJim Jagielski EditView* pView = aEditViews[--nView];
725*b1cdbd2cSJim Jagielski DBG_CHKOBJ( pView, EditView, 0 );
726*b1cdbd2cSJim Jagielski pView->pImpEditView->SetEditSelection( aSel );
727*b1cdbd2cSJim Jagielski }
728*b1cdbd2cSJim Jagielski
729*b1cdbd2cSJim Jagielski return aPaM;
730*b1cdbd2cSJim Jagielski }
731*b1cdbd2cSJim Jagielski
RemoveText()732*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::RemoveText()
733*b1cdbd2cSJim Jagielski {
734*b1cdbd2cSJim Jagielski InitDoc( sal_True );
735*b1cdbd2cSJim Jagielski
736*b1cdbd2cSJim Jagielski EditPaM aStartPaM = aEditDoc.GetStartPaM();
737*b1cdbd2cSJim Jagielski EditSelection aEmptySel( aStartPaM, aStartPaM );
738*b1cdbd2cSJim Jagielski for ( sal_uInt16 nView = 0; nView < aEditViews.Count(); nView++ )
739*b1cdbd2cSJim Jagielski {
740*b1cdbd2cSJim Jagielski EditView* pView = aEditViews.GetObject(nView);
741*b1cdbd2cSJim Jagielski DBG_CHKOBJ( pView, EditView, 0 );
742*b1cdbd2cSJim Jagielski pView->pImpEditView->SetEditSelection( aEmptySel );
743*b1cdbd2cSJim Jagielski }
744*b1cdbd2cSJim Jagielski ResetUndoManager();
745*b1cdbd2cSJim Jagielski return aEditDoc.GetStartPaM();
746*b1cdbd2cSJim Jagielski }
747*b1cdbd2cSJim Jagielski
748*b1cdbd2cSJim Jagielski
SetText(const XubString & rText)749*b1cdbd2cSJim Jagielski void ImpEditEngine::SetText( const XubString& rText )
750*b1cdbd2cSJim Jagielski {
751*b1cdbd2cSJim Jagielski // RemoveText loescht die Undo-Liste!
752*b1cdbd2cSJim Jagielski EditPaM aStartPaM = RemoveText();
753*b1cdbd2cSJim Jagielski sal_Bool bUndoCurrentlyEnabled = IsUndoEnabled();
754*b1cdbd2cSJim Jagielski // Der von Hand reingesteckte Text kann nicht vom Anwender rueckgaengig gemacht werden.
755*b1cdbd2cSJim Jagielski EnableUndo( sal_False );
756*b1cdbd2cSJim Jagielski
757*b1cdbd2cSJim Jagielski EditSelection aEmptySel( aStartPaM, aStartPaM );
758*b1cdbd2cSJim Jagielski EditPaM aPaM = aStartPaM;
759*b1cdbd2cSJim Jagielski if ( rText.Len() )
760*b1cdbd2cSJim Jagielski aPaM = ImpInsertText( aEmptySel, rText );
761*b1cdbd2cSJim Jagielski
762*b1cdbd2cSJim Jagielski for ( sal_uInt16 nView = 0; nView < aEditViews.Count(); nView++ )
763*b1cdbd2cSJim Jagielski {
764*b1cdbd2cSJim Jagielski EditView* pView = aEditViews[nView];
765*b1cdbd2cSJim Jagielski DBG_CHKOBJ( pView, EditView, 0 );
766*b1cdbd2cSJim Jagielski pView->pImpEditView->SetEditSelection( EditSelection( aPaM, aPaM ) );
767*b1cdbd2cSJim Jagielski // Wenn kein Text, dann auch Kein Format&Update
768*b1cdbd2cSJim Jagielski // => Der Text bleibt stehen.
769*b1cdbd2cSJim Jagielski if ( !rText.Len() && GetUpdateMode() )
770*b1cdbd2cSJim Jagielski {
771*b1cdbd2cSJim Jagielski Rectangle aTmpRec( pView->GetOutputArea().TopLeft(),
772*b1cdbd2cSJim Jagielski Size( aPaperSize.Width(), nCurTextHeight ) );
773*b1cdbd2cSJim Jagielski aTmpRec.Intersection( pView->GetOutputArea() );
774*b1cdbd2cSJim Jagielski pView->GetWindow()->Invalidate( aTmpRec );
775*b1cdbd2cSJim Jagielski }
776*b1cdbd2cSJim Jagielski }
777*b1cdbd2cSJim Jagielski if( !rText.Len() ) // sonst muss spaeter noch invalidiert werden, !bFormatted reicht.
778*b1cdbd2cSJim Jagielski nCurTextHeight = 0;
779*b1cdbd2cSJim Jagielski EnableUndo( bUndoCurrentlyEnabled );
780*b1cdbd2cSJim Jagielski #ifndef SVX_LIGHT
781*b1cdbd2cSJim Jagielski DBG_ASSERT( !HasUndoManager() || !GetUndoManager().GetUndoActionCount(), "Undo nach SetText?" );
782*b1cdbd2cSJim Jagielski #endif
783*b1cdbd2cSJim Jagielski }
784*b1cdbd2cSJim Jagielski
785*b1cdbd2cSJim Jagielski
GetEmptyItemSet()786*b1cdbd2cSJim Jagielski const SfxItemSet& ImpEditEngine::GetEmptyItemSet()
787*b1cdbd2cSJim Jagielski {
788*b1cdbd2cSJim Jagielski if ( !pEmptyItemSet )
789*b1cdbd2cSJim Jagielski {
790*b1cdbd2cSJim Jagielski pEmptyItemSet = new SfxItemSet( aEditDoc.GetItemPool(), EE_ITEMS_START, EE_ITEMS_END );
791*b1cdbd2cSJim Jagielski for ( sal_uInt16 nWhich = EE_ITEMS_START; nWhich <= EE_CHAR_END; nWhich++)
792*b1cdbd2cSJim Jagielski {
793*b1cdbd2cSJim Jagielski pEmptyItemSet->ClearItem( nWhich );
794*b1cdbd2cSJim Jagielski }
795*b1cdbd2cSJim Jagielski }
796*b1cdbd2cSJim Jagielski return *pEmptyItemSet;
797*b1cdbd2cSJim Jagielski }
798*b1cdbd2cSJim Jagielski
799*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------
800*b1cdbd2cSJim Jagielski // MISC
801*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------
CursorMoved(ContentNode * pPrevNode)802*b1cdbd2cSJim Jagielski void ImpEditEngine::CursorMoved( ContentNode* pPrevNode )
803*b1cdbd2cSJim Jagielski {
804*b1cdbd2cSJim Jagielski // Leere Attribute loeschen, aber nur, wenn Absatz nicht leer!
805*b1cdbd2cSJim Jagielski if ( pPrevNode->GetCharAttribs().HasEmptyAttribs() && pPrevNode->Len() )
806*b1cdbd2cSJim Jagielski pPrevNode->GetCharAttribs().DeleteEmptyAttribs( aEditDoc.GetItemPool() );
807*b1cdbd2cSJim Jagielski }
808*b1cdbd2cSJim Jagielski
TextModified()809*b1cdbd2cSJim Jagielski void ImpEditEngine::TextModified()
810*b1cdbd2cSJim Jagielski {
811*b1cdbd2cSJim Jagielski bFormatted = sal_False;
812*b1cdbd2cSJim Jagielski
813*b1cdbd2cSJim Jagielski if ( GetNotifyHdl().IsSet() )
814*b1cdbd2cSJim Jagielski {
815*b1cdbd2cSJim Jagielski EENotify aNotify( EE_NOTIFY_TEXTMODIFIED );
816*b1cdbd2cSJim Jagielski aNotify.pEditEngine = GetEditEnginePtr();
817*b1cdbd2cSJim Jagielski CallNotify( aNotify );
818*b1cdbd2cSJim Jagielski }
819*b1cdbd2cSJim Jagielski }
820*b1cdbd2cSJim Jagielski
821*b1cdbd2cSJim Jagielski
ParaAttribsChanged(ContentNode * pNode)822*b1cdbd2cSJim Jagielski void ImpEditEngine::ParaAttribsChanged( ContentNode* pNode )
823*b1cdbd2cSJim Jagielski {
824*b1cdbd2cSJim Jagielski DBG_ASSERT( pNode, "ParaAttribsChanged: Welcher?" );
825*b1cdbd2cSJim Jagielski
826*b1cdbd2cSJim Jagielski aEditDoc.SetModified( sal_True );
827*b1cdbd2cSJim Jagielski bFormatted = sal_False;
828*b1cdbd2cSJim Jagielski
829*b1cdbd2cSJim Jagielski ParaPortion* pPortion = FindParaPortion( pNode );
830*b1cdbd2cSJim Jagielski DBG_ASSERT( pPortion, "ParaAttribsChanged: Portion?" );
831*b1cdbd2cSJim Jagielski pPortion->MarkSelectionInvalid( 0, pNode->Len() );
832*b1cdbd2cSJim Jagielski
833*b1cdbd2cSJim Jagielski sal_uInt16 nPara = aEditDoc.GetPos( pNode );
834*b1cdbd2cSJim Jagielski pEditEngine->ParaAttribsChanged( nPara );
835*b1cdbd2cSJim Jagielski
836*b1cdbd2cSJim Jagielski ParaPortion* pNextPortion = GetParaPortions().SaveGetObject( nPara+1 );
837*b1cdbd2cSJim Jagielski // => wird sowieso noch formatiert, wenn Invalid.
838*b1cdbd2cSJim Jagielski if ( pNextPortion && !pNextPortion->IsInvalid() )
839*b1cdbd2cSJim Jagielski CalcHeight( pNextPortion );
840*b1cdbd2cSJim Jagielski }
841*b1cdbd2cSJim Jagielski
842*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------
843*b1cdbd2cSJim Jagielski // Cursorbewegungen
844*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------
845*b1cdbd2cSJim Jagielski
MoveCursor(const KeyEvent & rKeyEvent,EditView * pEditView)846*b1cdbd2cSJim Jagielski EditSelection ImpEditEngine::MoveCursor( const KeyEvent& rKeyEvent, EditView* pEditView )
847*b1cdbd2cSJim Jagielski {
848*b1cdbd2cSJim Jagielski // Eigentlich nur bei Up/Down noetig, aber was solls.
849*b1cdbd2cSJim Jagielski CheckIdleFormatter();
850*b1cdbd2cSJim Jagielski
851*b1cdbd2cSJim Jagielski EditPaM aPaM( pEditView->pImpEditView->GetEditSelection().Max() );
852*b1cdbd2cSJim Jagielski
853*b1cdbd2cSJim Jagielski EditPaM aOldPaM( aPaM );
854*b1cdbd2cSJim Jagielski
855*b1cdbd2cSJim Jagielski TextDirectionality eTextDirection = TextDirectionality_LeftToRight_TopToBottom;
856*b1cdbd2cSJim Jagielski if ( IsVertical() )
857*b1cdbd2cSJim Jagielski eTextDirection = TextDirectionality_TopToBottom_RightToLeft;
858*b1cdbd2cSJim Jagielski else if ( IsRightToLeft( GetEditDoc().GetPos( aPaM.GetNode() ) ) )
859*b1cdbd2cSJim Jagielski eTextDirection = TextDirectionality_RightToLeft_TopToBottom;
860*b1cdbd2cSJim Jagielski
861*b1cdbd2cSJim Jagielski KeyEvent aTranslatedKeyEvent = rKeyEvent.LogicalTextDirectionality( eTextDirection );
862*b1cdbd2cSJim Jagielski
863*b1cdbd2cSJim Jagielski sal_Bool bCtrl = aTranslatedKeyEvent.GetKeyCode().IsMod1() ? sal_True : sal_False;
864*b1cdbd2cSJim Jagielski sal_uInt16 nCode = aTranslatedKeyEvent.GetKeyCode().GetCode();
865*b1cdbd2cSJim Jagielski
866*b1cdbd2cSJim Jagielski if ( DoVisualCursorTraveling( aPaM.GetNode() ) )
867*b1cdbd2cSJim Jagielski {
868*b1cdbd2cSJim Jagielski // Only for simple cursor movement...
869*b1cdbd2cSJim Jagielski if ( !bCtrl && ( ( nCode == KEY_LEFT ) || ( nCode == KEY_RIGHT ) ) )
870*b1cdbd2cSJim Jagielski {
871*b1cdbd2cSJim Jagielski aPaM = CursorVisualLeftRight( pEditView, aPaM, rKeyEvent.GetKeyCode().IsMod2() ? i18n::CharacterIteratorMode::SKIPCHARACTER : i18n::CharacterIteratorMode::SKIPCELL, rKeyEvent.GetKeyCode().GetCode() == KEY_LEFT );
872*b1cdbd2cSJim Jagielski nCode = 0; // skip switch statement
873*b1cdbd2cSJim Jagielski }
874*b1cdbd2cSJim Jagielski /*
875*b1cdbd2cSJim Jagielski else if ( !bCtrl && ( ( nCode == KEY_HOME ) || ( nCode == KEY_END ) ) )
876*b1cdbd2cSJim Jagielski {
877*b1cdbd2cSJim Jagielski aPaM = CursorVisualStartEnd( pEditView, aPaM, nCode == KEY_HOME );
878*b1cdbd2cSJim Jagielski nCode = 0; // skip switch statement
879*b1cdbd2cSJim Jagielski }
880*b1cdbd2cSJim Jagielski */
881*b1cdbd2cSJim Jagielski }
882*b1cdbd2cSJim Jagielski
883*b1cdbd2cSJim Jagielski bool bKeyModifySelection = aTranslatedKeyEvent.GetKeyCode().IsShift();
884*b1cdbd2cSJim Jagielski switch ( nCode )
885*b1cdbd2cSJim Jagielski {
886*b1cdbd2cSJim Jagielski case KEY_UP: aPaM = CursorUp( aPaM, pEditView );
887*b1cdbd2cSJim Jagielski break;
888*b1cdbd2cSJim Jagielski case KEY_DOWN: aPaM = CursorDown( aPaM, pEditView );
889*b1cdbd2cSJim Jagielski break;
890*b1cdbd2cSJim Jagielski case KEY_LEFT: aPaM = bCtrl ? WordLeft( aPaM ) : CursorLeft( aPaM, aTranslatedKeyEvent.GetKeyCode().IsMod2() ? i18n::CharacterIteratorMode::SKIPCHARACTER : i18n::CharacterIteratorMode::SKIPCELL );
891*b1cdbd2cSJim Jagielski break;
892*b1cdbd2cSJim Jagielski case KEY_RIGHT: aPaM = bCtrl ? WordRight( aPaM ) : CursorRight( aPaM, aTranslatedKeyEvent.GetKeyCode().IsMod2() ? i18n::CharacterIteratorMode::SKIPCHARACTER : i18n::CharacterIteratorMode::SKIPCELL );
893*b1cdbd2cSJim Jagielski break;
894*b1cdbd2cSJim Jagielski case KEY_HOME: aPaM = bCtrl ? CursorStartOfDoc() : CursorStartOfLine( aPaM );
895*b1cdbd2cSJim Jagielski break;
896*b1cdbd2cSJim Jagielski case KEY_END: aPaM = bCtrl ? CursorEndOfDoc() : CursorEndOfLine( aPaM );
897*b1cdbd2cSJim Jagielski break;
898*b1cdbd2cSJim Jagielski case KEY_PAGEUP: aPaM = bCtrl ? CursorStartOfDoc() : PageUp( aPaM, pEditView );
899*b1cdbd2cSJim Jagielski break;
900*b1cdbd2cSJim Jagielski case KEY_PAGEDOWN: aPaM = bCtrl ? CursorEndOfDoc() : PageDown( aPaM, pEditView );
901*b1cdbd2cSJim Jagielski break;
902*b1cdbd2cSJim Jagielski case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_LINE:
903*b1cdbd2cSJim Jagielski aPaM = CursorStartOfLine( aPaM );
904*b1cdbd2cSJim Jagielski bKeyModifySelection = false;
905*b1cdbd2cSJim Jagielski break;
906*b1cdbd2cSJim Jagielski case com::sun::star::awt::Key::MOVE_TO_END_OF_LINE:
907*b1cdbd2cSJim Jagielski aPaM = CursorEndOfLine( aPaM );
908*b1cdbd2cSJim Jagielski bKeyModifySelection = false;
909*b1cdbd2cSJim Jagielski break;
910*b1cdbd2cSJim Jagielski case com::sun::star::awt::Key::MOVE_WORD_BACKWARD:
911*b1cdbd2cSJim Jagielski aPaM = WordLeft( aPaM );
912*b1cdbd2cSJim Jagielski bKeyModifySelection = false;
913*b1cdbd2cSJim Jagielski break;
914*b1cdbd2cSJim Jagielski case com::sun::star::awt::Key::MOVE_WORD_FORWARD:
915*b1cdbd2cSJim Jagielski aPaM = WordRight( aPaM );
916*b1cdbd2cSJim Jagielski bKeyModifySelection = false;
917*b1cdbd2cSJim Jagielski break;
918*b1cdbd2cSJim Jagielski case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_PARAGRAPH:
919*b1cdbd2cSJim Jagielski aPaM = CursorStartOfParagraph( aPaM );
920*b1cdbd2cSJim Jagielski if( aPaM == aOldPaM )
921*b1cdbd2cSJim Jagielski {
922*b1cdbd2cSJim Jagielski aPaM = CursorLeft( aPaM, i18n::CharacterIteratorMode::SKIPCELL );
923*b1cdbd2cSJim Jagielski aPaM = CursorStartOfParagraph( aPaM );
924*b1cdbd2cSJim Jagielski }
925*b1cdbd2cSJim Jagielski bKeyModifySelection = false;
926*b1cdbd2cSJim Jagielski break;
927*b1cdbd2cSJim Jagielski case com::sun::star::awt::Key::MOVE_TO_END_OF_PARAGRAPH:
928*b1cdbd2cSJim Jagielski aPaM = CursorEndOfParagraph( aPaM );
929*b1cdbd2cSJim Jagielski if( aPaM == aOldPaM )
930*b1cdbd2cSJim Jagielski {
931*b1cdbd2cSJim Jagielski aPaM = CursorRight( aPaM, i18n::CharacterIteratorMode::SKIPCELL );
932*b1cdbd2cSJim Jagielski aPaM = CursorEndOfParagraph( aPaM );
933*b1cdbd2cSJim Jagielski }
934*b1cdbd2cSJim Jagielski bKeyModifySelection = false;
935*b1cdbd2cSJim Jagielski break;
936*b1cdbd2cSJim Jagielski case com::sun::star::awt::Key::MOVE_TO_BEGIN_OF_DOCUMENT:
937*b1cdbd2cSJim Jagielski aPaM = CursorStartOfDoc();
938*b1cdbd2cSJim Jagielski bKeyModifySelection = false;
939*b1cdbd2cSJim Jagielski break;
940*b1cdbd2cSJim Jagielski case com::sun::star::awt::Key::MOVE_TO_END_OF_DOCUMENT:
941*b1cdbd2cSJim Jagielski aPaM = CursorEndOfDoc();
942*b1cdbd2cSJim Jagielski bKeyModifySelection = false;
943*b1cdbd2cSJim Jagielski break;
944*b1cdbd2cSJim Jagielski case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_LINE:
945*b1cdbd2cSJim Jagielski aPaM = CursorStartOfLine( aPaM );
946*b1cdbd2cSJim Jagielski bKeyModifySelection = true;
947*b1cdbd2cSJim Jagielski break;
948*b1cdbd2cSJim Jagielski case com::sun::star::awt::Key::SELECT_TO_END_OF_LINE:
949*b1cdbd2cSJim Jagielski aPaM = CursorEndOfLine( aPaM );
950*b1cdbd2cSJim Jagielski bKeyModifySelection = true;
951*b1cdbd2cSJim Jagielski break;
952*b1cdbd2cSJim Jagielski case com::sun::star::awt::Key::SELECT_BACKWARD:
953*b1cdbd2cSJim Jagielski aPaM = CursorLeft( aPaM, i18n::CharacterIteratorMode::SKIPCELL );
954*b1cdbd2cSJim Jagielski bKeyModifySelection = true;
955*b1cdbd2cSJim Jagielski break;
956*b1cdbd2cSJim Jagielski case com::sun::star::awt::Key::SELECT_FORWARD:
957*b1cdbd2cSJim Jagielski aPaM = CursorRight( aPaM, i18n::CharacterIteratorMode::SKIPCELL );
958*b1cdbd2cSJim Jagielski bKeyModifySelection = true;
959*b1cdbd2cSJim Jagielski break;
960*b1cdbd2cSJim Jagielski case com::sun::star::awt::Key::SELECT_WORD_BACKWARD:
961*b1cdbd2cSJim Jagielski aPaM = WordLeft( aPaM );
962*b1cdbd2cSJim Jagielski bKeyModifySelection = true;
963*b1cdbd2cSJim Jagielski break;
964*b1cdbd2cSJim Jagielski case com::sun::star::awt::Key::SELECT_WORD_FORWARD:
965*b1cdbd2cSJim Jagielski aPaM = WordRight( aPaM );
966*b1cdbd2cSJim Jagielski bKeyModifySelection = true;
967*b1cdbd2cSJim Jagielski break;
968*b1cdbd2cSJim Jagielski case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_PARAGRAPH:
969*b1cdbd2cSJim Jagielski aPaM = CursorStartOfParagraph( aPaM );
970*b1cdbd2cSJim Jagielski if( aPaM == aOldPaM )
971*b1cdbd2cSJim Jagielski {
972*b1cdbd2cSJim Jagielski aPaM = CursorLeft( aPaM, i18n::CharacterIteratorMode::SKIPCELL );
973*b1cdbd2cSJim Jagielski aPaM = CursorStartOfParagraph( aPaM );
974*b1cdbd2cSJim Jagielski }
975*b1cdbd2cSJim Jagielski bKeyModifySelection = true;
976*b1cdbd2cSJim Jagielski break;
977*b1cdbd2cSJim Jagielski case com::sun::star::awt::Key::SELECT_TO_END_OF_PARAGRAPH:
978*b1cdbd2cSJim Jagielski aPaM = CursorEndOfParagraph( aPaM );
979*b1cdbd2cSJim Jagielski if( aPaM == aOldPaM )
980*b1cdbd2cSJim Jagielski {
981*b1cdbd2cSJim Jagielski aPaM = CursorRight( aPaM, i18n::CharacterIteratorMode::SKIPCELL );
982*b1cdbd2cSJim Jagielski aPaM = CursorEndOfParagraph( aPaM );
983*b1cdbd2cSJim Jagielski }
984*b1cdbd2cSJim Jagielski bKeyModifySelection = true;
985*b1cdbd2cSJim Jagielski break;
986*b1cdbd2cSJim Jagielski case com::sun::star::awt::Key::SELECT_TO_BEGIN_OF_DOCUMENT:
987*b1cdbd2cSJim Jagielski aPaM = CursorStartOfDoc();
988*b1cdbd2cSJim Jagielski bKeyModifySelection = true;
989*b1cdbd2cSJim Jagielski break;
990*b1cdbd2cSJim Jagielski case com::sun::star::awt::Key::SELECT_TO_END_OF_DOCUMENT:
991*b1cdbd2cSJim Jagielski aPaM = CursorEndOfDoc();
992*b1cdbd2cSJim Jagielski bKeyModifySelection = true;
993*b1cdbd2cSJim Jagielski break;
994*b1cdbd2cSJim Jagielski }
995*b1cdbd2cSJim Jagielski
996*b1cdbd2cSJim Jagielski if ( aOldPaM != aPaM )
997*b1cdbd2cSJim Jagielski {
998*b1cdbd2cSJim Jagielski CursorMoved( aOldPaM.GetNode() );
999*b1cdbd2cSJim Jagielski if ( aStatus.NotifyCursorMovements() && ( aOldPaM.GetNode() != aPaM.GetNode() ) )
1000*b1cdbd2cSJim Jagielski {
1001*b1cdbd2cSJim Jagielski aStatus.GetStatusWord() = aStatus.GetStatusWord() | EE_STAT_CRSRLEFTPARA;
1002*b1cdbd2cSJim Jagielski aStatus.GetPrevParagraph() = aEditDoc.GetPos( aOldPaM.GetNode() );
1003*b1cdbd2cSJim Jagielski }
1004*b1cdbd2cSJim Jagielski }
1005*b1cdbd2cSJim Jagielski else
1006*b1cdbd2cSJim Jagielski aStatus.GetStatusWord() = aStatus.GetStatusWord() | EE_STAT_CRSRMOVEFAIL;
1007*b1cdbd2cSJim Jagielski
1008*b1cdbd2cSJim Jagielski // Bewirkt evtl. ein CreateAnchor oder Deselection all
1009*b1cdbd2cSJim Jagielski aSelEngine.SetCurView( pEditView );
1010*b1cdbd2cSJim Jagielski aSelEngine.CursorPosChanging( bKeyModifySelection, aTranslatedKeyEvent.GetKeyCode().IsMod1() );
1011*b1cdbd2cSJim Jagielski EditPaM aOldEnd( pEditView->pImpEditView->GetEditSelection().Max() );
1012*b1cdbd2cSJim Jagielski pEditView->pImpEditView->GetEditSelection().Max() = aPaM;
1013*b1cdbd2cSJim Jagielski if ( bKeyModifySelection )
1014*b1cdbd2cSJim Jagielski {
1015*b1cdbd2cSJim Jagielski // Dann wird die Selektion erweitert...
1016*b1cdbd2cSJim Jagielski EditSelection aTmpNewSel( aOldEnd, aPaM );
1017*b1cdbd2cSJim Jagielski pEditView->pImpEditView->DrawSelection( aTmpNewSel );
1018*b1cdbd2cSJim Jagielski }
1019*b1cdbd2cSJim Jagielski else
1020*b1cdbd2cSJim Jagielski pEditView->pImpEditView->GetEditSelection().Min() = aPaM;
1021*b1cdbd2cSJim Jagielski
1022*b1cdbd2cSJim Jagielski return pEditView->pImpEditView->GetEditSelection();
1023*b1cdbd2cSJim Jagielski }
1024*b1cdbd2cSJim Jagielski
CursorVisualStartEnd(EditView * pEditView,const EditPaM & rPaM,sal_Bool bStart)1025*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::CursorVisualStartEnd( EditView* pEditView, const EditPaM& rPaM, sal_Bool bStart )
1026*b1cdbd2cSJim Jagielski {
1027*b1cdbd2cSJim Jagielski EditPaM aPaM( rPaM );
1028*b1cdbd2cSJim Jagielski
1029*b1cdbd2cSJim Jagielski sal_uInt16 nPara = GetEditDoc().GetPos( aPaM.GetNode() );
1030*b1cdbd2cSJim Jagielski ParaPortion* pParaPortion = GetParaPortions().SaveGetObject( nPara );
1031*b1cdbd2cSJim Jagielski
1032*b1cdbd2cSJim Jagielski sal_uInt16 nLine = pParaPortion->GetLines().FindLine( aPaM.GetIndex(), sal_False );
1033*b1cdbd2cSJim Jagielski EditLine* pLine = pParaPortion->GetLines().GetObject( nLine );
1034*b1cdbd2cSJim Jagielski sal_Bool bEmptyLine = pLine->GetStart() == pLine->GetEnd();
1035*b1cdbd2cSJim Jagielski
1036*b1cdbd2cSJim Jagielski pEditView->pImpEditView->nExtraCursorFlags = 0;
1037*b1cdbd2cSJim Jagielski
1038*b1cdbd2cSJim Jagielski if ( !bEmptyLine )
1039*b1cdbd2cSJim Jagielski {
1040*b1cdbd2cSJim Jagielski String aLine( *aPaM.GetNode(), pLine->GetStart(), pLine->GetEnd() - pLine->GetStart() );
1041*b1cdbd2cSJim Jagielski // sal_uInt16 nPosInLine = aPaM.GetIndex() - pLine->GetStart();
1042*b1cdbd2cSJim Jagielski
1043*b1cdbd2cSJim Jagielski const sal_Unicode* pLineString = aLine.GetBuffer();
1044*b1cdbd2cSJim Jagielski
1045*b1cdbd2cSJim Jagielski UErrorCode nError = U_ZERO_ERROR;
1046*b1cdbd2cSJim Jagielski UBiDi* pBidi = ubidi_openSized( aLine.Len(), 0, &nError );
1047*b1cdbd2cSJim Jagielski
1048*b1cdbd2cSJim Jagielski const UBiDiLevel nBidiLevel = IsRightToLeft( nPara ) ? 1 /*RTL*/ : 0 /*LTR*/;
1049*b1cdbd2cSJim Jagielski ubidi_setPara( pBidi, reinterpret_cast<const UChar *>(pLineString), aLine.Len(), nBidiLevel, NULL, &nError ); // UChar != sal_Unicode in MinGW
1050*b1cdbd2cSJim Jagielski
1051*b1cdbd2cSJim Jagielski sal_uInt16 nVisPos = bStart ? 0 : aLine.Len()-1;
1052*b1cdbd2cSJim Jagielski sal_uInt16 nLogPos = (sal_uInt16)ubidi_getLogicalIndex( pBidi, nVisPos, &nError );
1053*b1cdbd2cSJim Jagielski
1054*b1cdbd2cSJim Jagielski ubidi_close( pBidi );
1055*b1cdbd2cSJim Jagielski
1056*b1cdbd2cSJim Jagielski aPaM.GetIndex() = nLogPos + pLine->GetStart();
1057*b1cdbd2cSJim Jagielski
1058*b1cdbd2cSJim Jagielski sal_uInt16 nTmp;
1059*b1cdbd2cSJim Jagielski sal_uInt16 nTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), nTmp, sal_True );
1060*b1cdbd2cSJim Jagielski TextPortion* pTextPortion = pParaPortion->GetTextPortions().GetObject( nTextPortion );
1061*b1cdbd2cSJim Jagielski sal_uInt16 nRTLLevel = pTextPortion->GetRightToLeft();
1062*b1cdbd2cSJim Jagielski // sal_Bool bParaRTL = IsRightToLeft( nPara );
1063*b1cdbd2cSJim Jagielski sal_Bool bPortionRTL = nRTLLevel%2 ? sal_True : sal_False;
1064*b1cdbd2cSJim Jagielski
1065*b1cdbd2cSJim Jagielski if ( bStart )
1066*b1cdbd2cSJim Jagielski {
1067*b1cdbd2cSJim Jagielski pEditView->pImpEditView->SetCursorBidiLevel( bPortionRTL ? 0 : 1 );
1068*b1cdbd2cSJim Jagielski // Maybe we must be *behind* the character
1069*b1cdbd2cSJim Jagielski if ( bPortionRTL && pEditView->IsInsertMode() )
1070*b1cdbd2cSJim Jagielski aPaM.GetIndex()++;
1071*b1cdbd2cSJim Jagielski }
1072*b1cdbd2cSJim Jagielski else
1073*b1cdbd2cSJim Jagielski {
1074*b1cdbd2cSJim Jagielski pEditView->pImpEditView->SetCursorBidiLevel( bPortionRTL ? 1 : 0 );
1075*b1cdbd2cSJim Jagielski if ( !bPortionRTL && pEditView->IsInsertMode() )
1076*b1cdbd2cSJim Jagielski aPaM.GetIndex()++;
1077*b1cdbd2cSJim Jagielski }
1078*b1cdbd2cSJim Jagielski }
1079*b1cdbd2cSJim Jagielski
1080*b1cdbd2cSJim Jagielski return aPaM;
1081*b1cdbd2cSJim Jagielski }
1082*b1cdbd2cSJim Jagielski
CursorVisualLeftRight(EditView * pEditView,const EditPaM & rPaM,sal_uInt16 nCharacterIteratorMode,sal_Bool bVisualToLeft)1083*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::CursorVisualLeftRight( EditView* pEditView, const EditPaM& rPaM, sal_uInt16 nCharacterIteratorMode, sal_Bool bVisualToLeft )
1084*b1cdbd2cSJim Jagielski {
1085*b1cdbd2cSJim Jagielski EditPaM aPaM( rPaM );
1086*b1cdbd2cSJim Jagielski
1087*b1cdbd2cSJim Jagielski sal_uInt16 nPara = GetEditDoc().GetPos( aPaM.GetNode() );
1088*b1cdbd2cSJim Jagielski ParaPortion* pParaPortion = GetParaPortions().SaveGetObject( nPara );
1089*b1cdbd2cSJim Jagielski
1090*b1cdbd2cSJim Jagielski sal_uInt16 nLine = pParaPortion->GetLines().FindLine( aPaM.GetIndex(), sal_False );
1091*b1cdbd2cSJim Jagielski EditLine* pLine = pParaPortion->GetLines().GetObject( nLine );
1092*b1cdbd2cSJim Jagielski sal_Bool bEmptyLine = pLine->GetStart() == pLine->GetEnd();
1093*b1cdbd2cSJim Jagielski
1094*b1cdbd2cSJim Jagielski // sal_uInt16 nCurrentCursorFlags = pEditView->pImpEditView->nExtraCursorFlags;
1095*b1cdbd2cSJim Jagielski pEditView->pImpEditView->nExtraCursorFlags = 0;
1096*b1cdbd2cSJim Jagielski
1097*b1cdbd2cSJim Jagielski sal_Bool bParaRTL = IsRightToLeft( nPara );
1098*b1cdbd2cSJim Jagielski
1099*b1cdbd2cSJim Jagielski sal_Bool bDone = sal_False;
1100*b1cdbd2cSJim Jagielski
1101*b1cdbd2cSJim Jagielski if ( bEmptyLine )
1102*b1cdbd2cSJim Jagielski {
1103*b1cdbd2cSJim Jagielski if ( bVisualToLeft )
1104*b1cdbd2cSJim Jagielski {
1105*b1cdbd2cSJim Jagielski aPaM = CursorUp( aPaM, pEditView );
1106*b1cdbd2cSJim Jagielski if ( aPaM != rPaM )
1107*b1cdbd2cSJim Jagielski aPaM = CursorVisualStartEnd( pEditView, aPaM, sal_False );
1108*b1cdbd2cSJim Jagielski }
1109*b1cdbd2cSJim Jagielski else
1110*b1cdbd2cSJim Jagielski {
1111*b1cdbd2cSJim Jagielski aPaM = CursorDown( aPaM, pEditView );
1112*b1cdbd2cSJim Jagielski if ( aPaM != rPaM )
1113*b1cdbd2cSJim Jagielski aPaM = CursorVisualStartEnd( pEditView, aPaM, sal_True );
1114*b1cdbd2cSJim Jagielski }
1115*b1cdbd2cSJim Jagielski
1116*b1cdbd2cSJim Jagielski bDone = sal_True;
1117*b1cdbd2cSJim Jagielski }
1118*b1cdbd2cSJim Jagielski
1119*b1cdbd2cSJim Jagielski sal_Bool bLogicalBackward = bParaRTL ? !bVisualToLeft : bVisualToLeft;
1120*b1cdbd2cSJim Jagielski
1121*b1cdbd2cSJim Jagielski if ( !bDone && pEditView->IsInsertMode() )
1122*b1cdbd2cSJim Jagielski {
1123*b1cdbd2cSJim Jagielski // Check if we are within a portion and don't have overwrite mode, then it's easy...
1124*b1cdbd2cSJim Jagielski sal_uInt16 nPortionStart;
1125*b1cdbd2cSJim Jagielski sal_uInt16 nTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), nPortionStart, sal_False );
1126*b1cdbd2cSJim Jagielski TextPortion* pTextPortion = pParaPortion->GetTextPortions().GetObject( nTextPortion );
1127*b1cdbd2cSJim Jagielski
1128*b1cdbd2cSJim Jagielski sal_Bool bPortionBoundary = ( aPaM.GetIndex() == nPortionStart ) || ( aPaM.GetIndex() == (nPortionStart+pTextPortion->GetLen()) );
1129*b1cdbd2cSJim Jagielski sal_uInt16 nRTLLevel = pTextPortion->GetRightToLeft();
1130*b1cdbd2cSJim Jagielski
1131*b1cdbd2cSJim Jagielski // Portion boundary doesn't matter if both have same RTL level
1132*b1cdbd2cSJim Jagielski sal_uInt16 nRTLLevelNextPortion = 0xFFFF;
1133*b1cdbd2cSJim Jagielski if ( bPortionBoundary && aPaM.GetIndex() && ( aPaM.GetIndex() < aPaM.GetNode()->Len() ) )
1134*b1cdbd2cSJim Jagielski {
1135*b1cdbd2cSJim Jagielski sal_uInt16 nTmp;
1136*b1cdbd2cSJim Jagielski sal_uInt16 nNextTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex()+1, nTmp, bLogicalBackward ? sal_False : sal_True );
1137*b1cdbd2cSJim Jagielski TextPortion* pNextTextPortion = pParaPortion->GetTextPortions().GetObject( nNextTextPortion );
1138*b1cdbd2cSJim Jagielski nRTLLevelNextPortion = pNextTextPortion->GetRightToLeft();
1139*b1cdbd2cSJim Jagielski }
1140*b1cdbd2cSJim Jagielski
1141*b1cdbd2cSJim Jagielski if ( !bPortionBoundary || ( nRTLLevel == nRTLLevelNextPortion ) )
1142*b1cdbd2cSJim Jagielski {
1143*b1cdbd2cSJim Jagielski if ( ( bVisualToLeft && !(nRTLLevel%2) ) || ( !bVisualToLeft && (nRTLLevel%2) ) )
1144*b1cdbd2cSJim Jagielski {
1145*b1cdbd2cSJim Jagielski aPaM = CursorLeft( aPaM, nCharacterIteratorMode );
1146*b1cdbd2cSJim Jagielski pEditView->pImpEditView->SetCursorBidiLevel( 1 );
1147*b1cdbd2cSJim Jagielski }
1148*b1cdbd2cSJim Jagielski else
1149*b1cdbd2cSJim Jagielski {
1150*b1cdbd2cSJim Jagielski aPaM = CursorRight( aPaM, nCharacterIteratorMode );
1151*b1cdbd2cSJim Jagielski pEditView->pImpEditView->SetCursorBidiLevel( 0 );
1152*b1cdbd2cSJim Jagielski }
1153*b1cdbd2cSJim Jagielski bDone = sal_True;
1154*b1cdbd2cSJim Jagielski }
1155*b1cdbd2cSJim Jagielski }
1156*b1cdbd2cSJim Jagielski
1157*b1cdbd2cSJim Jagielski if ( !bDone )
1158*b1cdbd2cSJim Jagielski {
1159*b1cdbd2cSJim Jagielski sal_Bool bGotoStartOfNextLine = sal_False;
1160*b1cdbd2cSJim Jagielski sal_Bool bGotoEndOfPrevLine = sal_False;
1161*b1cdbd2cSJim Jagielski
1162*b1cdbd2cSJim Jagielski String aLine( *aPaM.GetNode(), pLine->GetStart(), pLine->GetEnd() - pLine->GetStart() );
1163*b1cdbd2cSJim Jagielski sal_uInt16 nPosInLine = aPaM.GetIndex() - pLine->GetStart();
1164*b1cdbd2cSJim Jagielski
1165*b1cdbd2cSJim Jagielski const sal_Unicode* pLineString = aLine.GetBuffer();
1166*b1cdbd2cSJim Jagielski
1167*b1cdbd2cSJim Jagielski UErrorCode nError = U_ZERO_ERROR;
1168*b1cdbd2cSJim Jagielski UBiDi* pBidi = ubidi_openSized( aLine.Len(), 0, &nError );
1169*b1cdbd2cSJim Jagielski
1170*b1cdbd2cSJim Jagielski const UBiDiLevel nBidiLevel = IsRightToLeft( nPara ) ? 1 /*RTL*/ : 0 /*LTR*/;
1171*b1cdbd2cSJim Jagielski ubidi_setPara( pBidi, reinterpret_cast<const UChar *>(pLineString), aLine.Len(), nBidiLevel, NULL, &nError ); // UChar != sal_Unicode in MinGW
1172*b1cdbd2cSJim Jagielski
1173*b1cdbd2cSJim Jagielski if ( !pEditView->IsInsertMode() )
1174*b1cdbd2cSJim Jagielski {
1175*b1cdbd2cSJim Jagielski sal_Bool bEndOfLine = nPosInLine == aLine.Len();
1176*b1cdbd2cSJim Jagielski sal_uInt16 nVisPos = (sal_uInt16)ubidi_getVisualIndex( pBidi, !bEndOfLine ? nPosInLine : nPosInLine-1, &nError );
1177*b1cdbd2cSJim Jagielski if ( bVisualToLeft )
1178*b1cdbd2cSJim Jagielski {
1179*b1cdbd2cSJim Jagielski bGotoEndOfPrevLine = nVisPos == 0;
1180*b1cdbd2cSJim Jagielski if ( !bEndOfLine )
1181*b1cdbd2cSJim Jagielski nVisPos--;
1182*b1cdbd2cSJim Jagielski }
1183*b1cdbd2cSJim Jagielski else
1184*b1cdbd2cSJim Jagielski {
1185*b1cdbd2cSJim Jagielski bGotoStartOfNextLine = nVisPos == (aLine.Len() - 1);
1186*b1cdbd2cSJim Jagielski if ( !bEndOfLine )
1187*b1cdbd2cSJim Jagielski nVisPos++;
1188*b1cdbd2cSJim Jagielski }
1189*b1cdbd2cSJim Jagielski
1190*b1cdbd2cSJim Jagielski if ( !bGotoEndOfPrevLine && !bGotoStartOfNextLine )
1191*b1cdbd2cSJim Jagielski {
1192*b1cdbd2cSJim Jagielski sal_uInt16 nLogPos = (sal_uInt16)ubidi_getLogicalIndex( pBidi, nVisPos, &nError );
1193*b1cdbd2cSJim Jagielski aPaM.GetIndex() = pLine->GetStart() + nLogPos;
1194*b1cdbd2cSJim Jagielski pEditView->pImpEditView->SetCursorBidiLevel( 0 );
1195*b1cdbd2cSJim Jagielski }
1196*b1cdbd2cSJim Jagielski }
1197*b1cdbd2cSJim Jagielski else
1198*b1cdbd2cSJim Jagielski {
1199*b1cdbd2cSJim Jagielski sal_Bool bWasBehind = sal_False;
1200*b1cdbd2cSJim Jagielski sal_Bool bBeforePortion = !nPosInLine || pEditView->pImpEditView->GetCursorBidiLevel() == 1;
1201*b1cdbd2cSJim Jagielski if ( nPosInLine && ( !bBeforePortion ) ) // before the next portion
1202*b1cdbd2cSJim Jagielski bWasBehind = sal_True; // step one back, otherwise visual will be unusable when rtl portion follows.
1203*b1cdbd2cSJim Jagielski
1204*b1cdbd2cSJim Jagielski sal_uInt16 nPortionStart;
1205*b1cdbd2cSJim Jagielski sal_uInt16 nTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), nPortionStart, bBeforePortion );
1206*b1cdbd2cSJim Jagielski TextPortion* pTextPortion = pParaPortion->GetTextPortions().GetObject( nTextPortion );
1207*b1cdbd2cSJim Jagielski sal_Bool bRTLPortion = (pTextPortion->GetRightToLeft() % 2) != 0;
1208*b1cdbd2cSJim Jagielski
1209*b1cdbd2cSJim Jagielski // -1: We are 'behind' the character
1210*b1cdbd2cSJim Jagielski long nVisPos = (long)ubidi_getVisualIndex( pBidi, bWasBehind ? nPosInLine-1 : nPosInLine, &nError );
1211*b1cdbd2cSJim Jagielski if ( bVisualToLeft )
1212*b1cdbd2cSJim Jagielski {
1213*b1cdbd2cSJim Jagielski if ( !bWasBehind || bRTLPortion )
1214*b1cdbd2cSJim Jagielski nVisPos--;
1215*b1cdbd2cSJim Jagielski }
1216*b1cdbd2cSJim Jagielski else
1217*b1cdbd2cSJim Jagielski {
1218*b1cdbd2cSJim Jagielski if ( bWasBehind || bRTLPortion || bBeforePortion )
1219*b1cdbd2cSJim Jagielski nVisPos++;
1220*b1cdbd2cSJim Jagielski // if ( bWasBehind && bRTLPortion )
1221*b1cdbd2cSJim Jagielski // nVisPos++;
1222*b1cdbd2cSJim Jagielski }
1223*b1cdbd2cSJim Jagielski
1224*b1cdbd2cSJim Jagielski bGotoEndOfPrevLine = nVisPos < 0;
1225*b1cdbd2cSJim Jagielski bGotoStartOfNextLine = nVisPos >= aLine.Len();
1226*b1cdbd2cSJim Jagielski
1227*b1cdbd2cSJim Jagielski if ( !bGotoEndOfPrevLine && !bGotoStartOfNextLine )
1228*b1cdbd2cSJim Jagielski {
1229*b1cdbd2cSJim Jagielski sal_uInt16 nLogPos = (sal_uInt16)ubidi_getLogicalIndex( pBidi, nVisPos, &nError );
1230*b1cdbd2cSJim Jagielski
1231*b1cdbd2cSJim Jagielski /*
1232*b1cdbd2cSJim Jagielski if ( nLogPos == aPaM.GetIndex() )
1233*b1cdbd2cSJim Jagielski {
1234*b1cdbd2cSJim Jagielski if ( bVisualToLeft )
1235*b1cdbd2cSJim Jagielski bGotoEndOfPrevLine = sal_True;
1236*b1cdbd2cSJim Jagielski else
1237*b1cdbd2cSJim Jagielski bGotoStartOfNextLine = sal_True;
1238*b1cdbd2cSJim Jagielski }
1239*b1cdbd2cSJim Jagielski else
1240*b1cdbd2cSJim Jagielski */
1241*b1cdbd2cSJim Jagielski {
1242*b1cdbd2cSJim Jagielski aPaM.GetIndex() = pLine->GetStart() + nLogPos;
1243*b1cdbd2cSJim Jagielski
1244*b1cdbd2cSJim Jagielski // RTL portion, stay visually on the left side.
1245*b1cdbd2cSJim Jagielski sal_uInt16 _nPortionStart;
1246*b1cdbd2cSJim Jagielski // sal_uInt16 nTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), nPortionStart, !bRTLPortion );
1247*b1cdbd2cSJim Jagielski sal_uInt16 _nTextPortion = pParaPortion->GetTextPortions().FindPortion( aPaM.GetIndex(), _nPortionStart, sal_True );
1248*b1cdbd2cSJim Jagielski TextPortion* _pTextPortion = pParaPortion->GetTextPortions().GetObject( _nTextPortion );
1249*b1cdbd2cSJim Jagielski if ( bVisualToLeft && !bRTLPortion && ( _pTextPortion->GetRightToLeft() % 2 ) )
1250*b1cdbd2cSJim Jagielski aPaM.GetIndex()++;
1251*b1cdbd2cSJim Jagielski else if ( !bVisualToLeft && bRTLPortion && ( bWasBehind || !(_pTextPortion->GetRightToLeft() % 2 )) )
1252*b1cdbd2cSJim Jagielski aPaM.GetIndex()++;
1253*b1cdbd2cSJim Jagielski
1254*b1cdbd2cSJim Jagielski pEditView->pImpEditView->SetCursorBidiLevel( _nPortionStart );
1255*b1cdbd2cSJim Jagielski }
1256*b1cdbd2cSJim Jagielski }
1257*b1cdbd2cSJim Jagielski }
1258*b1cdbd2cSJim Jagielski
1259*b1cdbd2cSJim Jagielski ubidi_close( pBidi );
1260*b1cdbd2cSJim Jagielski
1261*b1cdbd2cSJim Jagielski if ( bGotoEndOfPrevLine )
1262*b1cdbd2cSJim Jagielski {
1263*b1cdbd2cSJim Jagielski aPaM = CursorUp( aPaM, pEditView );
1264*b1cdbd2cSJim Jagielski if ( aPaM != rPaM )
1265*b1cdbd2cSJim Jagielski aPaM = CursorVisualStartEnd( pEditView, aPaM, sal_False );
1266*b1cdbd2cSJim Jagielski }
1267*b1cdbd2cSJim Jagielski else if ( bGotoStartOfNextLine )
1268*b1cdbd2cSJim Jagielski {
1269*b1cdbd2cSJim Jagielski aPaM = CursorDown( aPaM, pEditView );
1270*b1cdbd2cSJim Jagielski if ( aPaM != rPaM )
1271*b1cdbd2cSJim Jagielski aPaM = CursorVisualStartEnd( pEditView, aPaM, sal_True );
1272*b1cdbd2cSJim Jagielski }
1273*b1cdbd2cSJim Jagielski }
1274*b1cdbd2cSJim Jagielski return aPaM;
1275*b1cdbd2cSJim Jagielski }
1276*b1cdbd2cSJim Jagielski
1277*b1cdbd2cSJim Jagielski
CursorLeft(const EditPaM & rPaM,sal_uInt16 nCharacterIteratorMode)1278*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::CursorLeft( const EditPaM& rPaM, sal_uInt16 nCharacterIteratorMode )
1279*b1cdbd2cSJim Jagielski {
1280*b1cdbd2cSJim Jagielski EditPaM aCurPaM( rPaM );
1281*b1cdbd2cSJim Jagielski EditPaM aNewPaM( aCurPaM );
1282*b1cdbd2cSJim Jagielski
1283*b1cdbd2cSJim Jagielski if ( aCurPaM.GetIndex() )
1284*b1cdbd2cSJim Jagielski {
1285*b1cdbd2cSJim Jagielski sal_Int32 nCount = 1;
1286*b1cdbd2cSJim Jagielski uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
1287*b1cdbd2cSJim Jagielski aNewPaM.SetIndex( (sal_uInt16)_xBI->previousCharacters( *aNewPaM.GetNode(), aNewPaM.GetIndex(), GetLocale( aNewPaM ), nCharacterIteratorMode, nCount, nCount ) );
1288*b1cdbd2cSJim Jagielski }
1289*b1cdbd2cSJim Jagielski else
1290*b1cdbd2cSJim Jagielski {
1291*b1cdbd2cSJim Jagielski ContentNode* pNode = aCurPaM.GetNode();
1292*b1cdbd2cSJim Jagielski pNode = GetPrevVisNode( pNode );
1293*b1cdbd2cSJim Jagielski if ( pNode )
1294*b1cdbd2cSJim Jagielski {
1295*b1cdbd2cSJim Jagielski aNewPaM.SetNode( pNode );
1296*b1cdbd2cSJim Jagielski aNewPaM.SetIndex( pNode->Len() );
1297*b1cdbd2cSJim Jagielski }
1298*b1cdbd2cSJim Jagielski }
1299*b1cdbd2cSJim Jagielski
1300*b1cdbd2cSJim Jagielski return aNewPaM;
1301*b1cdbd2cSJim Jagielski }
1302*b1cdbd2cSJim Jagielski
CursorRight(const EditPaM & rPaM,sal_uInt16 nCharacterIteratorMode)1303*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::CursorRight( const EditPaM& rPaM, sal_uInt16 nCharacterIteratorMode )
1304*b1cdbd2cSJim Jagielski {
1305*b1cdbd2cSJim Jagielski EditPaM aCurPaM( rPaM );
1306*b1cdbd2cSJim Jagielski EditPaM aNewPaM( aCurPaM );
1307*b1cdbd2cSJim Jagielski
1308*b1cdbd2cSJim Jagielski if ( aCurPaM.GetIndex() < aCurPaM.GetNode()->Len() )
1309*b1cdbd2cSJim Jagielski {
1310*b1cdbd2cSJim Jagielski uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
1311*b1cdbd2cSJim Jagielski sal_Int32 nCount = 1;
1312*b1cdbd2cSJim Jagielski aNewPaM.SetIndex( (sal_uInt16)_xBI->nextCharacters( *aNewPaM.GetNode(), aNewPaM.GetIndex(), GetLocale( aNewPaM ), nCharacterIteratorMode, nCount, nCount ) );
1313*b1cdbd2cSJim Jagielski }
1314*b1cdbd2cSJim Jagielski else
1315*b1cdbd2cSJim Jagielski {
1316*b1cdbd2cSJim Jagielski ContentNode* pNode = aCurPaM.GetNode();
1317*b1cdbd2cSJim Jagielski pNode = GetNextVisNode( pNode );
1318*b1cdbd2cSJim Jagielski if ( pNode )
1319*b1cdbd2cSJim Jagielski {
1320*b1cdbd2cSJim Jagielski aNewPaM.SetNode( pNode );
1321*b1cdbd2cSJim Jagielski aNewPaM.SetIndex( 0 );
1322*b1cdbd2cSJim Jagielski }
1323*b1cdbd2cSJim Jagielski }
1324*b1cdbd2cSJim Jagielski
1325*b1cdbd2cSJim Jagielski return aNewPaM;
1326*b1cdbd2cSJim Jagielski }
1327*b1cdbd2cSJim Jagielski
CursorUp(const EditPaM & rPaM,EditView * pView)1328*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::CursorUp( const EditPaM& rPaM, EditView* pView )
1329*b1cdbd2cSJim Jagielski {
1330*b1cdbd2cSJim Jagielski DBG_ASSERT( pView, "Keine View - Keine Cursorbewegung!" );
1331*b1cdbd2cSJim Jagielski
1332*b1cdbd2cSJim Jagielski ParaPortion* pPPortion = FindParaPortion( rPaM.GetNode() );
1333*b1cdbd2cSJim Jagielski DBG_ASSERT( pPPortion, "Keine passende Portion gefunden: CursorUp" );
1334*b1cdbd2cSJim Jagielski sal_uInt16 nLine = pPPortion->GetLineNumber( rPaM.GetIndex() );
1335*b1cdbd2cSJim Jagielski EditLine* pLine = pPPortion->GetLines().GetObject( nLine );
1336*b1cdbd2cSJim Jagielski
1337*b1cdbd2cSJim Jagielski long nX;
1338*b1cdbd2cSJim Jagielski if ( pView->pImpEditView->nTravelXPos == TRAVEL_X_DONTKNOW )
1339*b1cdbd2cSJim Jagielski {
1340*b1cdbd2cSJim Jagielski nX = GetXPos( pPPortion, pLine, rPaM.GetIndex() );
1341*b1cdbd2cSJim Jagielski pView->pImpEditView->nTravelXPos = nX+nOnePixelInRef;
1342*b1cdbd2cSJim Jagielski }
1343*b1cdbd2cSJim Jagielski else
1344*b1cdbd2cSJim Jagielski nX = pView->pImpEditView->nTravelXPos;
1345*b1cdbd2cSJim Jagielski
1346*b1cdbd2cSJim Jagielski EditPaM aNewPaM( rPaM );
1347*b1cdbd2cSJim Jagielski if ( nLine ) // gleicher Absatz
1348*b1cdbd2cSJim Jagielski {
1349*b1cdbd2cSJim Jagielski EditLine* pPrevLine = pPPortion->GetLines().GetObject(nLine-1);
1350*b1cdbd2cSJim Jagielski aNewPaM.SetIndex( GetChar( pPPortion, pPrevLine, nX ) );
1351*b1cdbd2cSJim Jagielski // Wenn davor eine autom.Umgebrochene Zeile, und ich muss genau an das
1352*b1cdbd2cSJim Jagielski // Ende dieser Zeile, landet der Cursor in der aktuellen Zeile am Anfang
1353*b1cdbd2cSJim Jagielski // Siehe Problem: Letztes Zeichen einer autom.umgebr. Zeile = Cursor
1354*b1cdbd2cSJim Jagielski if ( aNewPaM.GetIndex() && ( aNewPaM.GetIndex() == pLine->GetStart() ) )
1355*b1cdbd2cSJim Jagielski aNewPaM = CursorLeft( aNewPaM );
1356*b1cdbd2cSJim Jagielski }
1357*b1cdbd2cSJim Jagielski else // vorheriger Absatz
1358*b1cdbd2cSJim Jagielski {
1359*b1cdbd2cSJim Jagielski ParaPortion* pPrevPortion = GetPrevVisPortion( pPPortion );
1360*b1cdbd2cSJim Jagielski if ( pPrevPortion )
1361*b1cdbd2cSJim Jagielski {
1362*b1cdbd2cSJim Jagielski pLine = pPrevPortion->GetLines().GetObject( pPrevPortion->GetLines().Count()-1 );
1363*b1cdbd2cSJim Jagielski DBG_ASSERT( pLine, "Zeile davor nicht gefunden: CursorUp" );
1364*b1cdbd2cSJim Jagielski aNewPaM.SetNode( pPrevPortion->GetNode() );
1365*b1cdbd2cSJim Jagielski aNewPaM.SetIndex( GetChar( pPrevPortion, pLine, nX+nOnePixelInRef ) );
1366*b1cdbd2cSJim Jagielski }
1367*b1cdbd2cSJim Jagielski }
1368*b1cdbd2cSJim Jagielski
1369*b1cdbd2cSJim Jagielski return aNewPaM;
1370*b1cdbd2cSJim Jagielski }
1371*b1cdbd2cSJim Jagielski
CursorDown(const EditPaM & rPaM,EditView * pView)1372*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::CursorDown( const EditPaM& rPaM, EditView* pView )
1373*b1cdbd2cSJim Jagielski {
1374*b1cdbd2cSJim Jagielski DBG_ASSERT( pView, "Keine View - Keine Cursorbewegung!" );
1375*b1cdbd2cSJim Jagielski
1376*b1cdbd2cSJim Jagielski ParaPortion* pPPortion = FindParaPortion( rPaM.GetNode() );
1377*b1cdbd2cSJim Jagielski DBG_ASSERT( pPPortion, "Keine passende Portion gefunden: CursorDown" );
1378*b1cdbd2cSJim Jagielski sal_uInt16 nLine = pPPortion->GetLineNumber( rPaM.GetIndex() );
1379*b1cdbd2cSJim Jagielski
1380*b1cdbd2cSJim Jagielski long nX;
1381*b1cdbd2cSJim Jagielski if ( pView->pImpEditView->nTravelXPos == TRAVEL_X_DONTKNOW )
1382*b1cdbd2cSJim Jagielski {
1383*b1cdbd2cSJim Jagielski EditLine* pLine = pPPortion->GetLines().GetObject(nLine);
1384*b1cdbd2cSJim Jagielski nX = GetXPos( pPPortion, pLine, rPaM.GetIndex() );
1385*b1cdbd2cSJim Jagielski pView->pImpEditView->nTravelXPos = nX+nOnePixelInRef;
1386*b1cdbd2cSJim Jagielski }
1387*b1cdbd2cSJim Jagielski else
1388*b1cdbd2cSJim Jagielski nX = pView->pImpEditView->nTravelXPos;
1389*b1cdbd2cSJim Jagielski
1390*b1cdbd2cSJim Jagielski EditPaM aNewPaM( rPaM );
1391*b1cdbd2cSJim Jagielski if ( nLine < pPPortion->GetLines().Count()-1 )
1392*b1cdbd2cSJim Jagielski {
1393*b1cdbd2cSJim Jagielski EditLine* pNextLine = pPPortion->GetLines().GetObject(nLine+1);
1394*b1cdbd2cSJim Jagielski aNewPaM.SetIndex( GetChar( pPPortion, pNextLine, nX ) );
1395*b1cdbd2cSJim Jagielski // Sonderbehandlung siehe CursorUp...
1396*b1cdbd2cSJim Jagielski if ( ( aNewPaM.GetIndex() == pNextLine->GetEnd() ) && ( aNewPaM.GetIndex() > pNextLine->GetStart() ) && ( aNewPaM.GetIndex() < pPPortion->GetNode()->Len() ) )
1397*b1cdbd2cSJim Jagielski aNewPaM = CursorLeft( aNewPaM );
1398*b1cdbd2cSJim Jagielski }
1399*b1cdbd2cSJim Jagielski else // naechster Absatz
1400*b1cdbd2cSJim Jagielski {
1401*b1cdbd2cSJim Jagielski ParaPortion* pNextPortion = GetNextVisPortion( pPPortion );
1402*b1cdbd2cSJim Jagielski if ( pNextPortion )
1403*b1cdbd2cSJim Jagielski {
1404*b1cdbd2cSJim Jagielski EditLine* pLine = pNextPortion->GetLines().GetObject(0);
1405*b1cdbd2cSJim Jagielski DBG_ASSERT( pLine, "Zeile davor nicht gefunden: CursorUp" );
1406*b1cdbd2cSJim Jagielski aNewPaM.SetNode( pNextPortion->GetNode() );
1407*b1cdbd2cSJim Jagielski // Nie ganz ans Ende wenn mehrere Zeilen, da dann eine
1408*b1cdbd2cSJim Jagielski // Zeile darunter der Cursor angezeigt wird.
1409*b1cdbd2cSJim Jagielski aNewPaM.SetIndex( GetChar( pNextPortion, pLine, nX+nOnePixelInRef ) );
1410*b1cdbd2cSJim Jagielski if ( ( aNewPaM.GetIndex() == pLine->GetEnd() ) && ( aNewPaM.GetIndex() > pLine->GetStart() ) && ( pNextPortion->GetLines().Count() > 1 ) )
1411*b1cdbd2cSJim Jagielski aNewPaM = CursorLeft( aNewPaM );
1412*b1cdbd2cSJim Jagielski }
1413*b1cdbd2cSJim Jagielski }
1414*b1cdbd2cSJim Jagielski
1415*b1cdbd2cSJim Jagielski return aNewPaM;
1416*b1cdbd2cSJim Jagielski }
1417*b1cdbd2cSJim Jagielski
CursorStartOfLine(const EditPaM & rPaM)1418*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::CursorStartOfLine( const EditPaM& rPaM )
1419*b1cdbd2cSJim Jagielski {
1420*b1cdbd2cSJim Jagielski ParaPortion* pCurPortion = FindParaPortion( rPaM.GetNode() );
1421*b1cdbd2cSJim Jagielski DBG_ASSERT( pCurPortion, "Keine Portion fuer den PaM ?" );
1422*b1cdbd2cSJim Jagielski sal_uInt16 nLine = pCurPortion->GetLineNumber( rPaM.GetIndex() );
1423*b1cdbd2cSJim Jagielski EditLine* pLine = pCurPortion->GetLines().GetObject(nLine);
1424*b1cdbd2cSJim Jagielski DBG_ASSERT( pLine, "Aktuelle Zeile nicht gefunden ?!" );
1425*b1cdbd2cSJim Jagielski
1426*b1cdbd2cSJim Jagielski EditPaM aNewPaM( rPaM );
1427*b1cdbd2cSJim Jagielski aNewPaM.SetIndex( pLine->GetStart() );
1428*b1cdbd2cSJim Jagielski return aNewPaM;
1429*b1cdbd2cSJim Jagielski }
1430*b1cdbd2cSJim Jagielski
CursorEndOfLine(const EditPaM & rPaM)1431*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::CursorEndOfLine( const EditPaM& rPaM )
1432*b1cdbd2cSJim Jagielski {
1433*b1cdbd2cSJim Jagielski ParaPortion* pCurPortion = FindParaPortion( rPaM.GetNode() );
1434*b1cdbd2cSJim Jagielski DBG_ASSERT( pCurPortion, "Keine Portion fuer den PaM ?" );
1435*b1cdbd2cSJim Jagielski sal_uInt16 nLine = pCurPortion->GetLineNumber( rPaM.GetIndex() );
1436*b1cdbd2cSJim Jagielski EditLine* pLine = pCurPortion->GetLines().GetObject(nLine);
1437*b1cdbd2cSJim Jagielski DBG_ASSERT( pLine, "Aktuelle Zeile nicht gefunden ?!" );
1438*b1cdbd2cSJim Jagielski
1439*b1cdbd2cSJim Jagielski EditPaM aNewPaM( rPaM );
1440*b1cdbd2cSJim Jagielski aNewPaM.SetIndex( pLine->GetEnd() );
1441*b1cdbd2cSJim Jagielski if ( pLine->GetEnd() > pLine->GetStart() )
1442*b1cdbd2cSJim Jagielski {
1443*b1cdbd2cSJim Jagielski // xub_Unicode cLastChar = aNewPaM.GetNode()->GetChar( aNewPaM.GetIndex()-1 );
1444*b1cdbd2cSJim Jagielski if ( aNewPaM.GetNode()->IsFeature( aNewPaM.GetIndex() - 1 ) )
1445*b1cdbd2cSJim Jagielski {
1446*b1cdbd2cSJim Jagielski // Bei einem weichen Umbruch muss ich davor stehen!
1447*b1cdbd2cSJim Jagielski EditCharAttrib* pNextFeature = aNewPaM.GetNode()->GetCharAttribs().FindFeature( aNewPaM.GetIndex()-1 );
1448*b1cdbd2cSJim Jagielski if ( pNextFeature && ( pNextFeature->GetItem()->Which() == EE_FEATURE_LINEBR ) )
1449*b1cdbd2cSJim Jagielski aNewPaM = CursorLeft( aNewPaM );
1450*b1cdbd2cSJim Jagielski }
1451*b1cdbd2cSJim Jagielski else if ( ( aNewPaM.GetNode()->GetChar( aNewPaM.GetIndex() - 1 ) == ' ' ) && ( aNewPaM.GetIndex() != aNewPaM.GetNode()->Len() ) )
1452*b1cdbd2cSJim Jagielski {
1453*b1cdbd2cSJim Jagielski // Bei einem Blank in einer autom. umgebrochenen Zeile macht es Sinn,
1454*b1cdbd2cSJim Jagielski // davor zu stehen, da der Anwender hinter das Wort will.
1455*b1cdbd2cSJim Jagielski // Wenn diese geaendert wird, Sonderbehandlung fuer Pos1 nach End!
1456*b1cdbd2cSJim Jagielski aNewPaM = CursorLeft( aNewPaM );
1457*b1cdbd2cSJim Jagielski }
1458*b1cdbd2cSJim Jagielski }
1459*b1cdbd2cSJim Jagielski return aNewPaM;
1460*b1cdbd2cSJim Jagielski }
1461*b1cdbd2cSJim Jagielski
CursorStartOfParagraph(const EditPaM & rPaM)1462*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::CursorStartOfParagraph( const EditPaM& rPaM )
1463*b1cdbd2cSJim Jagielski {
1464*b1cdbd2cSJim Jagielski EditPaM aPaM( rPaM.GetNode(), 0 );
1465*b1cdbd2cSJim Jagielski return aPaM;
1466*b1cdbd2cSJim Jagielski }
1467*b1cdbd2cSJim Jagielski
CursorEndOfParagraph(const EditPaM & rPaM)1468*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::CursorEndOfParagraph( const EditPaM& rPaM )
1469*b1cdbd2cSJim Jagielski {
1470*b1cdbd2cSJim Jagielski EditPaM aPaM( rPaM.GetNode(), rPaM.GetNode()->Len() );
1471*b1cdbd2cSJim Jagielski return aPaM;
1472*b1cdbd2cSJim Jagielski }
1473*b1cdbd2cSJim Jagielski
CursorStartOfDoc()1474*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::CursorStartOfDoc()
1475*b1cdbd2cSJim Jagielski {
1476*b1cdbd2cSJim Jagielski EditPaM aPaM( aEditDoc.SaveGetObject( 0 ), 0 );
1477*b1cdbd2cSJim Jagielski return aPaM;
1478*b1cdbd2cSJim Jagielski }
1479*b1cdbd2cSJim Jagielski
CursorEndOfDoc()1480*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::CursorEndOfDoc()
1481*b1cdbd2cSJim Jagielski {
1482*b1cdbd2cSJim Jagielski ContentNode* pLastNode = aEditDoc.SaveGetObject( aEditDoc.Count()-1 );
1483*b1cdbd2cSJim Jagielski ParaPortion* pLastPortion = GetParaPortions().SaveGetObject( aEditDoc.Count()-1 );
1484*b1cdbd2cSJim Jagielski DBG_ASSERT( pLastNode && pLastPortion, "CursorEndOfDoc: Node oder Portion nicht gefunden" );
1485*b1cdbd2cSJim Jagielski
1486*b1cdbd2cSJim Jagielski if ( !pLastPortion->IsVisible() )
1487*b1cdbd2cSJim Jagielski {
1488*b1cdbd2cSJim Jagielski pLastNode = GetPrevVisNode( pLastPortion->GetNode() );
1489*b1cdbd2cSJim Jagielski DBG_ASSERT( pLastNode, "Kein sichtbarer Absatz?" );
1490*b1cdbd2cSJim Jagielski if ( !pLastNode )
1491*b1cdbd2cSJim Jagielski pLastNode = aEditDoc.SaveGetObject( aEditDoc.Count()-1 );
1492*b1cdbd2cSJim Jagielski }
1493*b1cdbd2cSJim Jagielski
1494*b1cdbd2cSJim Jagielski EditPaM aPaM( pLastNode, pLastNode->Len() );
1495*b1cdbd2cSJim Jagielski return aPaM;
1496*b1cdbd2cSJim Jagielski }
1497*b1cdbd2cSJim Jagielski
PageUp(const EditPaM & rPaM,EditView * pView)1498*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::PageUp( const EditPaM& rPaM, EditView* pView )
1499*b1cdbd2cSJim Jagielski {
1500*b1cdbd2cSJim Jagielski Rectangle aRec = PaMtoEditCursor( rPaM );
1501*b1cdbd2cSJim Jagielski Point aTopLeft = aRec.TopLeft();
1502*b1cdbd2cSJim Jagielski aTopLeft.Y() -= pView->GetVisArea().GetHeight() *9/10;
1503*b1cdbd2cSJim Jagielski aTopLeft.X() += nOnePixelInRef;
1504*b1cdbd2cSJim Jagielski if ( aTopLeft.Y() < 0 )
1505*b1cdbd2cSJim Jagielski {
1506*b1cdbd2cSJim Jagielski aTopLeft.Y() = 0;
1507*b1cdbd2cSJim Jagielski }
1508*b1cdbd2cSJim Jagielski return GetPaM( aTopLeft );
1509*b1cdbd2cSJim Jagielski }
1510*b1cdbd2cSJim Jagielski
PageDown(const EditPaM & rPaM,EditView * pView)1511*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::PageDown( const EditPaM& rPaM, EditView* pView )
1512*b1cdbd2cSJim Jagielski {
1513*b1cdbd2cSJim Jagielski Rectangle aRec = PaMtoEditCursor( rPaM );
1514*b1cdbd2cSJim Jagielski Point aBottomRight = aRec.BottomRight();
1515*b1cdbd2cSJim Jagielski aBottomRight.Y() += pView->GetVisArea().GetHeight() *9/10;
1516*b1cdbd2cSJim Jagielski aBottomRight.X() += nOnePixelInRef;
1517*b1cdbd2cSJim Jagielski long nHeight = GetTextHeight();
1518*b1cdbd2cSJim Jagielski if ( aBottomRight.Y() > nHeight )
1519*b1cdbd2cSJim Jagielski {
1520*b1cdbd2cSJim Jagielski aBottomRight.Y() = nHeight-2;
1521*b1cdbd2cSJim Jagielski }
1522*b1cdbd2cSJim Jagielski return GetPaM( aBottomRight );
1523*b1cdbd2cSJim Jagielski }
1524*b1cdbd2cSJim Jagielski
WordLeft(const EditPaM & rPaM,sal_Int16 nWordType)1525*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::WordLeft( const EditPaM& rPaM, sal_Int16 nWordType )
1526*b1cdbd2cSJim Jagielski {
1527*b1cdbd2cSJim Jagielski sal_uInt16 nCurrentPos = rPaM.GetIndex();
1528*b1cdbd2cSJim Jagielski EditPaM aNewPaM( rPaM );
1529*b1cdbd2cSJim Jagielski if ( nCurrentPos == 0 )
1530*b1cdbd2cSJim Jagielski {
1531*b1cdbd2cSJim Jagielski // Vorheriger Absatz...
1532*b1cdbd2cSJim Jagielski sal_uInt16 nCurPara = aEditDoc.GetPos( aNewPaM.GetNode() );
1533*b1cdbd2cSJim Jagielski ContentNode* pPrevNode = aEditDoc.SaveGetObject( --nCurPara );
1534*b1cdbd2cSJim Jagielski if ( pPrevNode )
1535*b1cdbd2cSJim Jagielski {
1536*b1cdbd2cSJim Jagielski aNewPaM.SetNode( pPrevNode );
1537*b1cdbd2cSJim Jagielski aNewPaM.SetIndex( pPrevNode->Len() );
1538*b1cdbd2cSJim Jagielski }
1539*b1cdbd2cSJim Jagielski }
1540*b1cdbd2cSJim Jagielski else
1541*b1cdbd2cSJim Jagielski {
1542*b1cdbd2cSJim Jagielski // we need to increase the position by 1 when retrieving the locale
1543*b1cdbd2cSJim Jagielski // since the attribute for the char left to the cursor position is returned
1544*b1cdbd2cSJim Jagielski EditPaM aTmpPaM( aNewPaM );
1545*b1cdbd2cSJim Jagielski xub_StrLen nMax = rPaM.GetNode()->Len();
1546*b1cdbd2cSJim Jagielski if ( aTmpPaM.GetIndex() < nMax )
1547*b1cdbd2cSJim Jagielski aTmpPaM.SetIndex( aTmpPaM.GetIndex() + 1 );
1548*b1cdbd2cSJim Jagielski lang::Locale aLocale( GetLocale( aTmpPaM ) );
1549*b1cdbd2cSJim Jagielski
1550*b1cdbd2cSJim Jagielski uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
1551*b1cdbd2cSJim Jagielski i18n::Boundary aBoundary = _xBI->getWordBoundary( *aNewPaM.GetNode(), nCurrentPos, aLocale, nWordType, sal_True );
1552*b1cdbd2cSJim Jagielski if ( aBoundary.startPos >= nCurrentPos )
1553*b1cdbd2cSJim Jagielski aBoundary = _xBI->previousWord( *aNewPaM.GetNode(), nCurrentPos, aLocale, nWordType );
1554*b1cdbd2cSJim Jagielski aNewPaM.SetIndex( ( aBoundary.startPos != (-1) ) ? (sal_uInt16)aBoundary.startPos : 0 );
1555*b1cdbd2cSJim Jagielski }
1556*b1cdbd2cSJim Jagielski
1557*b1cdbd2cSJim Jagielski return aNewPaM;
1558*b1cdbd2cSJim Jagielski }
1559*b1cdbd2cSJim Jagielski
WordRight(const EditPaM & rPaM,sal_Int16 nWordType)1560*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::WordRight( const EditPaM& rPaM, sal_Int16 nWordType )
1561*b1cdbd2cSJim Jagielski {
1562*b1cdbd2cSJim Jagielski xub_StrLen nMax = rPaM.GetNode()->Len();
1563*b1cdbd2cSJim Jagielski EditPaM aNewPaM( rPaM );
1564*b1cdbd2cSJim Jagielski if ( aNewPaM.GetIndex() < nMax )
1565*b1cdbd2cSJim Jagielski {
1566*b1cdbd2cSJim Jagielski // we need to increase the position by 1 when retrieving the locale
1567*b1cdbd2cSJim Jagielski // since the attribute for the char left to the cursor position is returned
1568*b1cdbd2cSJim Jagielski EditPaM aTmpPaM( aNewPaM );
1569*b1cdbd2cSJim Jagielski aTmpPaM.SetIndex( aTmpPaM.GetIndex() + 1 );
1570*b1cdbd2cSJim Jagielski lang::Locale aLocale( GetLocale( aTmpPaM ) );
1571*b1cdbd2cSJim Jagielski
1572*b1cdbd2cSJim Jagielski uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
1573*b1cdbd2cSJim Jagielski i18n::Boundary aBoundary = _xBI->nextWord( *aNewPaM.GetNode(), aNewPaM.GetIndex(), aLocale, nWordType );
1574*b1cdbd2cSJim Jagielski aNewPaM.SetIndex( (sal_uInt16)aBoundary.startPos );
1575*b1cdbd2cSJim Jagielski }
1576*b1cdbd2cSJim Jagielski // not 'else', maybe the index reached nMax now...
1577*b1cdbd2cSJim Jagielski if ( aNewPaM.GetIndex() >= nMax )
1578*b1cdbd2cSJim Jagielski {
1579*b1cdbd2cSJim Jagielski // Naechster Absatz...
1580*b1cdbd2cSJim Jagielski sal_uInt16 nCurPara = aEditDoc.GetPos( aNewPaM.GetNode() );
1581*b1cdbd2cSJim Jagielski ContentNode* pNextNode = aEditDoc.SaveGetObject( ++nCurPara );
1582*b1cdbd2cSJim Jagielski if ( pNextNode )
1583*b1cdbd2cSJim Jagielski {
1584*b1cdbd2cSJim Jagielski aNewPaM.SetNode( pNextNode );
1585*b1cdbd2cSJim Jagielski aNewPaM.SetIndex( 0 );
1586*b1cdbd2cSJim Jagielski }
1587*b1cdbd2cSJim Jagielski }
1588*b1cdbd2cSJim Jagielski return aNewPaM;
1589*b1cdbd2cSJim Jagielski }
1590*b1cdbd2cSJim Jagielski
StartOfWord(const EditPaM & rPaM,sal_Int16 nWordType)1591*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::StartOfWord( const EditPaM& rPaM, sal_Int16 nWordType )
1592*b1cdbd2cSJim Jagielski {
1593*b1cdbd2cSJim Jagielski EditPaM aNewPaM( rPaM );
1594*b1cdbd2cSJim Jagielski
1595*b1cdbd2cSJim Jagielski // we need to increase the position by 1 when retrieving the locale
1596*b1cdbd2cSJim Jagielski // since the attribute for the char left to the cursor position is returned
1597*b1cdbd2cSJim Jagielski EditPaM aTmpPaM( aNewPaM );
1598*b1cdbd2cSJim Jagielski xub_StrLen nMax = rPaM.GetNode()->Len();
1599*b1cdbd2cSJim Jagielski if ( aTmpPaM.GetIndex() < nMax )
1600*b1cdbd2cSJim Jagielski aTmpPaM.SetIndex( aTmpPaM.GetIndex() + 1 );
1601*b1cdbd2cSJim Jagielski lang::Locale aLocale( GetLocale( aTmpPaM ) );
1602*b1cdbd2cSJim Jagielski
1603*b1cdbd2cSJim Jagielski uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
1604*b1cdbd2cSJim Jagielski i18n::Boundary aBoundary = _xBI->getWordBoundary( *rPaM.GetNode(), rPaM.GetIndex(), aLocale, nWordType, sal_True );
1605*b1cdbd2cSJim Jagielski aNewPaM.SetIndex( (sal_uInt16)aBoundary.startPos );
1606*b1cdbd2cSJim Jagielski return aNewPaM;
1607*b1cdbd2cSJim Jagielski }
1608*b1cdbd2cSJim Jagielski
EndOfWord(const EditPaM & rPaM,sal_Int16 nWordType)1609*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::EndOfWord( const EditPaM& rPaM, sal_Int16 nWordType )
1610*b1cdbd2cSJim Jagielski {
1611*b1cdbd2cSJim Jagielski EditPaM aNewPaM( rPaM );
1612*b1cdbd2cSJim Jagielski
1613*b1cdbd2cSJim Jagielski // we need to increase the position by 1 when retrieving the locale
1614*b1cdbd2cSJim Jagielski // since the attribute for the char left to the cursor position is returned
1615*b1cdbd2cSJim Jagielski EditPaM aTmpPaM( aNewPaM );
1616*b1cdbd2cSJim Jagielski xub_StrLen nMax = rPaM.GetNode()->Len();
1617*b1cdbd2cSJim Jagielski if ( aTmpPaM.GetIndex() < nMax )
1618*b1cdbd2cSJim Jagielski aTmpPaM.SetIndex( aTmpPaM.GetIndex() + 1 );
1619*b1cdbd2cSJim Jagielski lang::Locale aLocale( GetLocale( aTmpPaM ) );
1620*b1cdbd2cSJim Jagielski
1621*b1cdbd2cSJim Jagielski uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
1622*b1cdbd2cSJim Jagielski i18n::Boundary aBoundary = _xBI->getWordBoundary( *rPaM.GetNode(), rPaM.GetIndex(), aLocale, nWordType, sal_True );
1623*b1cdbd2cSJim Jagielski aNewPaM.SetIndex( (sal_uInt16)aBoundary.endPos );
1624*b1cdbd2cSJim Jagielski return aNewPaM;
1625*b1cdbd2cSJim Jagielski }
1626*b1cdbd2cSJim Jagielski
SelectWord(const EditSelection & rCurSel,sal_Int16 nWordType,sal_Bool bAcceptStartOfWord)1627*b1cdbd2cSJim Jagielski EditSelection ImpEditEngine::SelectWord( const EditSelection& rCurSel, sal_Int16 nWordType, sal_Bool bAcceptStartOfWord )
1628*b1cdbd2cSJim Jagielski {
1629*b1cdbd2cSJim Jagielski EditSelection aNewSel( rCurSel );
1630*b1cdbd2cSJim Jagielski EditPaM aPaM( rCurSel.Max() );
1631*b1cdbd2cSJim Jagielski
1632*b1cdbd2cSJim Jagielski // we need to increase the position by 1 when retrieving the locale
1633*b1cdbd2cSJim Jagielski // since the attribute for the char left to the cursor position is returned
1634*b1cdbd2cSJim Jagielski EditPaM aTmpPaM( aPaM );
1635*b1cdbd2cSJim Jagielski xub_StrLen nMax = aPaM.GetNode()->Len();
1636*b1cdbd2cSJim Jagielski if ( aTmpPaM.GetIndex() < nMax )
1637*b1cdbd2cSJim Jagielski aTmpPaM.SetIndex( aTmpPaM.GetIndex() + 1 );
1638*b1cdbd2cSJim Jagielski lang::Locale aLocale( GetLocale( aTmpPaM ) );
1639*b1cdbd2cSJim Jagielski
1640*b1cdbd2cSJim Jagielski uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
1641*b1cdbd2cSJim Jagielski sal_Int16 nType = _xBI->getWordType( *aPaM.GetNode(), aPaM.GetIndex(), aLocale );
1642*b1cdbd2cSJim Jagielski if ( nType == i18n::WordType::ANY_WORD )
1643*b1cdbd2cSJim Jagielski {
1644*b1cdbd2cSJim Jagielski i18n::Boundary aBoundary = _xBI->getWordBoundary( *aPaM.GetNode(), aPaM.GetIndex(), aLocale, nWordType, sal_True );
1645*b1cdbd2cSJim Jagielski // don't select when curser at end of word
1646*b1cdbd2cSJim Jagielski if ( ( aBoundary.endPos > aPaM.GetIndex() ) &&
1647*b1cdbd2cSJim Jagielski ( ( aBoundary.startPos < aPaM.GetIndex() ) || ( bAcceptStartOfWord && ( aBoundary.startPos == aPaM.GetIndex() ) ) ) )
1648*b1cdbd2cSJim Jagielski {
1649*b1cdbd2cSJim Jagielski aNewSel.Min().SetIndex( (sal_uInt16)aBoundary.startPos );
1650*b1cdbd2cSJim Jagielski aNewSel.Max().SetIndex( (sal_uInt16)aBoundary.endPos );
1651*b1cdbd2cSJim Jagielski }
1652*b1cdbd2cSJim Jagielski }
1653*b1cdbd2cSJim Jagielski
1654*b1cdbd2cSJim Jagielski return aNewSel;
1655*b1cdbd2cSJim Jagielski }
1656*b1cdbd2cSJim Jagielski
SelectSentence(const EditSelection & rCurSel)1657*b1cdbd2cSJim Jagielski EditSelection ImpEditEngine::SelectSentence( const EditSelection& rCurSel )
1658*b1cdbd2cSJim Jagielski {
1659*b1cdbd2cSJim Jagielski uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
1660*b1cdbd2cSJim Jagielski const EditPaM& rPaM = rCurSel.Min();
1661*b1cdbd2cSJim Jagielski const ContentNode* pNode = rPaM.GetNode();
1662*b1cdbd2cSJim Jagielski // #i50710# line breaks are marked with 0x01 - the break iterator prefers 0x0a for that
1663*b1cdbd2cSJim Jagielski String sParagraph(*pNode);
1664*b1cdbd2cSJim Jagielski sParagraph.SearchAndReplaceAll(0x01,0x0a);
1665*b1cdbd2cSJim Jagielski //return Null if search starts at the beginning of the string
1666*b1cdbd2cSJim Jagielski long nStart = rPaM.GetIndex() ? _xBI->beginOfSentence( sParagraph, rPaM.GetIndex(), GetLocale( rPaM ) ) : 0;
1667*b1cdbd2cSJim Jagielski
1668*b1cdbd2cSJim Jagielski long nEnd = _xBI->endOfSentence( *pNode, rPaM.GetIndex(), GetLocale( rPaM ) );
1669*b1cdbd2cSJim Jagielski EditSelection aNewSel( rCurSel );
1670*b1cdbd2cSJim Jagielski DBG_ASSERT(nStart < pNode->Len() && nEnd <= pNode->Len(), "sentence indices out of range");
1671*b1cdbd2cSJim Jagielski aNewSel.Min().SetIndex( (sal_uInt16)nStart );
1672*b1cdbd2cSJim Jagielski aNewSel.Max().SetIndex( (sal_uInt16)nEnd );
1673*b1cdbd2cSJim Jagielski return aNewSel;
1674*b1cdbd2cSJim Jagielski }
1675*b1cdbd2cSJim Jagielski
IsInputSequenceCheckingRequired(sal_Unicode nChar,const EditSelection & rCurSel) const1676*b1cdbd2cSJim Jagielski sal_Bool ImpEditEngine::IsInputSequenceCheckingRequired( sal_Unicode nChar, const EditSelection& rCurSel ) const
1677*b1cdbd2cSJim Jagielski {
1678*b1cdbd2cSJim Jagielski uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
1679*b1cdbd2cSJim Jagielski if (!pCTLOptions)
1680*b1cdbd2cSJim Jagielski pCTLOptions = new SvtCTLOptions;
1681*b1cdbd2cSJim Jagielski
1682*b1cdbd2cSJim Jagielski // get the index that really is first
1683*b1cdbd2cSJim Jagielski sal_uInt16 nFirstPos = rCurSel.Min().GetIndex();
1684*b1cdbd2cSJim Jagielski sal_uInt16 nMaxPos = rCurSel.Max().GetIndex();
1685*b1cdbd2cSJim Jagielski if (nMaxPos < nFirstPos)
1686*b1cdbd2cSJim Jagielski nFirstPos = nMaxPos;
1687*b1cdbd2cSJim Jagielski
1688*b1cdbd2cSJim Jagielski sal_Bool bIsSequenceChecking =
1689*b1cdbd2cSJim Jagielski pCTLOptions->IsCTLFontEnabled() &&
1690*b1cdbd2cSJim Jagielski pCTLOptions->IsCTLSequenceChecking() &&
1691*b1cdbd2cSJim Jagielski nFirstPos != 0 && /* first char needs not to be checked */
1692*b1cdbd2cSJim Jagielski _xBI.is() && i18n::ScriptType::COMPLEX == _xBI->getScriptType( rtl::OUString( nChar ), 0 );
1693*b1cdbd2cSJim Jagielski
1694*b1cdbd2cSJim Jagielski return bIsSequenceChecking;
1695*b1cdbd2cSJim Jagielski }
1696*b1cdbd2cSJim Jagielski
1697*b1cdbd2cSJim Jagielski /*************************************************************************
1698*b1cdbd2cSJim Jagielski * lcl_HasStrongLTR
1699*b1cdbd2cSJim Jagielski *************************************************************************/
lcl_HasStrongLTR(const String & rTxt,xub_StrLen nStart,xub_StrLen nEnd)1700*b1cdbd2cSJim Jagielski bool lcl_HasStrongLTR ( const String& rTxt, xub_StrLen nStart, xub_StrLen nEnd )
1701*b1cdbd2cSJim Jagielski {
1702*b1cdbd2cSJim Jagielski for ( xub_StrLen nCharIdx = nStart; nCharIdx < nEnd; ++nCharIdx )
1703*b1cdbd2cSJim Jagielski {
1704*b1cdbd2cSJim Jagielski const UCharDirection nCharDir = u_charDirection ( rTxt.GetChar ( nCharIdx ));
1705*b1cdbd2cSJim Jagielski if ( nCharDir == U_LEFT_TO_RIGHT ||
1706*b1cdbd2cSJim Jagielski nCharDir == U_LEFT_TO_RIGHT_EMBEDDING ||
1707*b1cdbd2cSJim Jagielski nCharDir == U_LEFT_TO_RIGHT_OVERRIDE )
1708*b1cdbd2cSJim Jagielski return true;
1709*b1cdbd2cSJim Jagielski }
1710*b1cdbd2cSJim Jagielski return false;
1711*b1cdbd2cSJim Jagielski }
1712*b1cdbd2cSJim Jagielski
1713*b1cdbd2cSJim Jagielski
1714*b1cdbd2cSJim Jagielski
InitScriptTypes(sal_uInt16 nPara)1715*b1cdbd2cSJim Jagielski void ImpEditEngine::InitScriptTypes( sal_uInt16 nPara )
1716*b1cdbd2cSJim Jagielski {
1717*b1cdbd2cSJim Jagielski ParaPortion* pParaPortion = GetParaPortions().SaveGetObject( nPara );
1718*b1cdbd2cSJim Jagielski ScriptTypePosInfos& rTypes = pParaPortion->aScriptInfos;
1719*b1cdbd2cSJim Jagielski rTypes.clear();
1720*b1cdbd2cSJim Jagielski
1721*b1cdbd2cSJim Jagielski ContentNode* pNode = pParaPortion->GetNode();
1722*b1cdbd2cSJim Jagielski if ( pNode->Len() )
1723*b1cdbd2cSJim Jagielski {
1724*b1cdbd2cSJim Jagielski uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
1725*b1cdbd2cSJim Jagielski
1726*b1cdbd2cSJim Jagielski String aText( *pNode );
1727*b1cdbd2cSJim Jagielski
1728*b1cdbd2cSJim Jagielski // To handle fields put the character from the field in the string,
1729*b1cdbd2cSJim Jagielski // because endOfScript( ... ) will skip the CH_FEATURE, because this is WEAK
1730*b1cdbd2cSJim Jagielski EditCharAttrib* pField = pNode->GetCharAttribs().FindNextAttrib( EE_FEATURE_FIELD, 0 );
1731*b1cdbd2cSJim Jagielski while ( pField )
1732*b1cdbd2cSJim Jagielski {
1733*b1cdbd2cSJim Jagielski ::rtl::OUString aFldText( ((EditCharAttribField*)pField)->GetFieldValue() );
1734*b1cdbd2cSJim Jagielski if ( aFldText.getLength() )
1735*b1cdbd2cSJim Jagielski {
1736*b1cdbd2cSJim Jagielski aText.SetChar( pField->GetStart(), aFldText.getStr()[0] );
1737*b1cdbd2cSJim Jagielski short nFldScriptType = _xBI->getScriptType( aFldText, 0 );
1738*b1cdbd2cSJim Jagielski
1739*b1cdbd2cSJim Jagielski for ( sal_uInt16 nCharInField = 1; nCharInField < aFldText.getLength(); nCharInField++ )
1740*b1cdbd2cSJim Jagielski {
1741*b1cdbd2cSJim Jagielski short nTmpType = _xBI->getScriptType( aFldText, nCharInField );
1742*b1cdbd2cSJim Jagielski
1743*b1cdbd2cSJim Jagielski // First char from field wins...
1744*b1cdbd2cSJim Jagielski if ( nFldScriptType == i18n::ScriptType::WEAK )
1745*b1cdbd2cSJim Jagielski {
1746*b1cdbd2cSJim Jagielski nFldScriptType = nTmpType;
1747*b1cdbd2cSJim Jagielski aText.SetChar( pField->GetStart(), aFldText.getStr()[nCharInField] );
1748*b1cdbd2cSJim Jagielski }
1749*b1cdbd2cSJim Jagielski
1750*b1cdbd2cSJim Jagielski // ... but if the first one is LATIN, and there are CJK or CTL chars too,
1751*b1cdbd2cSJim Jagielski // we prefer that ScripType because we need an other font.
1752*b1cdbd2cSJim Jagielski if ( ( nTmpType == i18n::ScriptType::ASIAN ) || ( nTmpType == i18n::ScriptType::COMPLEX ) )
1753*b1cdbd2cSJim Jagielski {
1754*b1cdbd2cSJim Jagielski aText.SetChar( pField->GetStart(), aFldText.getStr()[nCharInField] );
1755*b1cdbd2cSJim Jagielski break;
1756*b1cdbd2cSJim Jagielski }
1757*b1cdbd2cSJim Jagielski }
1758*b1cdbd2cSJim Jagielski }
1759*b1cdbd2cSJim Jagielski // #112831# Last Field might go from 0xffff to 0x0000
1760*b1cdbd2cSJim Jagielski pField = pField->GetEnd() ? pNode->GetCharAttribs().FindNextAttrib( EE_FEATURE_FIELD, pField->GetEnd() ) : NULL;
1761*b1cdbd2cSJim Jagielski }
1762*b1cdbd2cSJim Jagielski
1763*b1cdbd2cSJim Jagielski ::rtl::OUString aOUText( aText );
1764*b1cdbd2cSJim Jagielski sal_uInt16 nTextLen = (sal_uInt16)aOUText.getLength();
1765*b1cdbd2cSJim Jagielski
1766*b1cdbd2cSJim Jagielski sal_Int32 nPos = 0;
1767*b1cdbd2cSJim Jagielski short nScriptType = _xBI->getScriptType( aOUText, nPos );
1768*b1cdbd2cSJim Jagielski rTypes.push_back( ScriptTypePosInfo( nScriptType, (sal_uInt16)nPos, nTextLen ) );
1769*b1cdbd2cSJim Jagielski nPos = _xBI->endOfScript( aOUText, nPos, nScriptType );
1770*b1cdbd2cSJim Jagielski while ( ( nPos != (-1) ) && ( nPos < nTextLen ) )
1771*b1cdbd2cSJim Jagielski {
1772*b1cdbd2cSJim Jagielski rTypes.back().nEndPos = (sal_uInt16)nPos;
1773*b1cdbd2cSJim Jagielski
1774*b1cdbd2cSJim Jagielski nScriptType = _xBI->getScriptType( aOUText, nPos );
1775*b1cdbd2cSJim Jagielski long nEndPos = _xBI->endOfScript( aOUText, nPos, nScriptType );
1776*b1cdbd2cSJim Jagielski
1777*b1cdbd2cSJim Jagielski if ( ( nScriptType == i18n::ScriptType::WEAK ) || ( nScriptType == rTypes.back().nScriptType ) )
1778*b1cdbd2cSJim Jagielski {
1779*b1cdbd2cSJim Jagielski // Expand last ScriptTypePosInfo, don't create weak or unecessary portions
1780*b1cdbd2cSJim Jagielski rTypes.back().nEndPos = (sal_uInt16)nEndPos;
1781*b1cdbd2cSJim Jagielski }
1782*b1cdbd2cSJim Jagielski else
1783*b1cdbd2cSJim Jagielski {
1784*b1cdbd2cSJim Jagielski if ( _xBI->getScriptType( aOUText, nPos - 1 ) == i18n::ScriptType::WEAK )
1785*b1cdbd2cSJim Jagielski {
1786*b1cdbd2cSJim Jagielski switch ( u_charType(aOUText.iterateCodePoints(&nPos, 0) ) ) {
1787*b1cdbd2cSJim Jagielski case U_NON_SPACING_MARK:
1788*b1cdbd2cSJim Jagielski case U_ENCLOSING_MARK:
1789*b1cdbd2cSJim Jagielski case U_COMBINING_SPACING_MARK:
1790*b1cdbd2cSJim Jagielski --nPos;
1791*b1cdbd2cSJim Jagielski rTypes.back().nEndPos--;
1792*b1cdbd2cSJim Jagielski break;
1793*b1cdbd2cSJim Jagielski }
1794*b1cdbd2cSJim Jagielski }
1795*b1cdbd2cSJim Jagielski rTypes.push_back( ScriptTypePosInfo( nScriptType, (sal_uInt16)nPos, nTextLen ) );
1796*b1cdbd2cSJim Jagielski }
1797*b1cdbd2cSJim Jagielski
1798*b1cdbd2cSJim Jagielski nPos = nEndPos;
1799*b1cdbd2cSJim Jagielski }
1800*b1cdbd2cSJim Jagielski
1801*b1cdbd2cSJim Jagielski if ( rTypes[0].nScriptType == i18n::ScriptType::WEAK )
1802*b1cdbd2cSJim Jagielski rTypes[0].nScriptType = ( rTypes.size() > 1 ) ? rTypes[1].nScriptType : GetI18NScriptTypeOfLanguage( GetDefaultLanguage() );
1803*b1cdbd2cSJim Jagielski
1804*b1cdbd2cSJim Jagielski // create writing direction information:
1805*b1cdbd2cSJim Jagielski if ( pParaPortion->aWritingDirectionInfos.empty() )
1806*b1cdbd2cSJim Jagielski InitWritingDirections( nPara );
1807*b1cdbd2cSJim Jagielski
1808*b1cdbd2cSJim Jagielski // i89825: Use CTL font for numbers embedded into an RTL run:
1809*b1cdbd2cSJim Jagielski WritingDirectionInfos& rDirInfos = pParaPortion->aWritingDirectionInfos;
1810*b1cdbd2cSJim Jagielski for ( size_t n = 0; n < rDirInfos.size(); ++n )
1811*b1cdbd2cSJim Jagielski {
1812*b1cdbd2cSJim Jagielski const xub_StrLen nStart = rDirInfos[n].nStartPos;
1813*b1cdbd2cSJim Jagielski const xub_StrLen nEnd = rDirInfos[n].nEndPos;
1814*b1cdbd2cSJim Jagielski const sal_uInt8 nCurrDirType = rDirInfos[n].nType;
1815*b1cdbd2cSJim Jagielski
1816*b1cdbd2cSJim Jagielski if ( nCurrDirType % 2 == UBIDI_RTL || // text in RTL run
1817*b1cdbd2cSJim Jagielski ( nCurrDirType > UBIDI_LTR && !lcl_HasStrongLTR( aText, nStart, nEnd ) ) ) // non-strong text in embedded LTR run
1818*b1cdbd2cSJim Jagielski {
1819*b1cdbd2cSJim Jagielski size_t nIdx = 0;
1820*b1cdbd2cSJim Jagielski
1821*b1cdbd2cSJim Jagielski // Skip entries in ScriptArray which are not inside the RTL run:
1822*b1cdbd2cSJim Jagielski while ( nIdx < rTypes.size() && rTypes[nIdx].nStartPos < nStart )
1823*b1cdbd2cSJim Jagielski ++nIdx;
1824*b1cdbd2cSJim Jagielski
1825*b1cdbd2cSJim Jagielski // Remove any entries *inside* the current run:
1826*b1cdbd2cSJim Jagielski while ( nIdx < rTypes.size() && rTypes[nIdx].nEndPos <= nEnd )
1827*b1cdbd2cSJim Jagielski rTypes.erase( rTypes.begin()+nIdx );
1828*b1cdbd2cSJim Jagielski
1829*b1cdbd2cSJim Jagielski // special case:
1830*b1cdbd2cSJim Jagielski if(nIdx < rTypes.size() && rTypes[nIdx].nStartPos < nStart && rTypes[nIdx].nEndPos > nEnd)
1831*b1cdbd2cSJim Jagielski {
1832*b1cdbd2cSJim Jagielski rTypes.insert( rTypes.begin()+nIdx, ScriptTypePosInfo( rTypes[nIdx].nScriptType, (sal_uInt16)nEnd, rTypes[nIdx].nEndPos ) );
1833*b1cdbd2cSJim Jagielski rTypes[nIdx].nEndPos = nStart;
1834*b1cdbd2cSJim Jagielski }
1835*b1cdbd2cSJim Jagielski
1836*b1cdbd2cSJim Jagielski if( nIdx )
1837*b1cdbd2cSJim Jagielski rTypes[nIdx - 1].nEndPos = nStart;
1838*b1cdbd2cSJim Jagielski
1839*b1cdbd2cSJim Jagielski rTypes.insert( rTypes.begin()+nIdx, ScriptTypePosInfo( i18n::ScriptType::COMPLEX, (sal_uInt16)nStart, (sal_uInt16)nEnd) );
1840*b1cdbd2cSJim Jagielski ++nIdx;
1841*b1cdbd2cSJim Jagielski
1842*b1cdbd2cSJim Jagielski if( nIdx < rTypes.size() )
1843*b1cdbd2cSJim Jagielski rTypes[nIdx].nStartPos = nEnd;
1844*b1cdbd2cSJim Jagielski }
1845*b1cdbd2cSJim Jagielski }
1846*b1cdbd2cSJim Jagielski
1847*b1cdbd2cSJim Jagielski #if OSL_DEBUG_LEVEL > 1
1848*b1cdbd2cSJim Jagielski sal_uInt16 nDebugStt = 0;
1849*b1cdbd2cSJim Jagielski sal_uInt16 nDebugEnd = 0;
1850*b1cdbd2cSJim Jagielski short nDebugType = 0;
1851*b1cdbd2cSJim Jagielski for ( size_t n = 0; n < rTypes.size(); ++n )
1852*b1cdbd2cSJim Jagielski {
1853*b1cdbd2cSJim Jagielski nDebugStt = rTypes[n].nStartPos;
1854*b1cdbd2cSJim Jagielski nDebugEnd = rTypes[n].nEndPos;
1855*b1cdbd2cSJim Jagielski nDebugType = rTypes[n].nScriptType;
1856*b1cdbd2cSJim Jagielski }
1857*b1cdbd2cSJim Jagielski #endif
1858*b1cdbd2cSJim Jagielski }
1859*b1cdbd2cSJim Jagielski }
1860*b1cdbd2cSJim Jagielski
GetScriptType(const EditPaM & rPaM,sal_uInt16 * pEndPos) const1861*b1cdbd2cSJim Jagielski sal_uInt16 ImpEditEngine::GetScriptType( const EditPaM& rPaM, sal_uInt16* pEndPos ) const
1862*b1cdbd2cSJim Jagielski {
1863*b1cdbd2cSJim Jagielski sal_uInt16 nScriptType = 0;
1864*b1cdbd2cSJim Jagielski
1865*b1cdbd2cSJim Jagielski if ( pEndPos )
1866*b1cdbd2cSJim Jagielski *pEndPos = rPaM.GetNode()->Len();
1867*b1cdbd2cSJim Jagielski
1868*b1cdbd2cSJim Jagielski if ( rPaM.GetNode()->Len() )
1869*b1cdbd2cSJim Jagielski {
1870*b1cdbd2cSJim Jagielski sal_uInt16 nPara = GetEditDoc().GetPos( rPaM.GetNode() );
1871*b1cdbd2cSJim Jagielski ParaPortion* pParaPortion = GetParaPortions().SaveGetObject( nPara );
1872*b1cdbd2cSJim Jagielski if ( pParaPortion->aScriptInfos.empty() )
1873*b1cdbd2cSJim Jagielski ((ImpEditEngine*)this)->InitScriptTypes( nPara );
1874*b1cdbd2cSJim Jagielski
1875*b1cdbd2cSJim Jagielski ScriptTypePosInfos& rTypes = pParaPortion->aScriptInfos;
1876*b1cdbd2cSJim Jagielski sal_uInt16 nPos = rPaM.GetIndex();
1877*b1cdbd2cSJim Jagielski for ( size_t n = 0; n < rTypes.size(); n++ )
1878*b1cdbd2cSJim Jagielski {
1879*b1cdbd2cSJim Jagielski if ( ( rTypes[n].nStartPos <= nPos ) && ( rTypes[n].nEndPos >= nPos ) )
1880*b1cdbd2cSJim Jagielski {
1881*b1cdbd2cSJim Jagielski nScriptType = rTypes[n].nScriptType;
1882*b1cdbd2cSJim Jagielski if( pEndPos )
1883*b1cdbd2cSJim Jagielski *pEndPos = rTypes[n].nEndPos;
1884*b1cdbd2cSJim Jagielski break;
1885*b1cdbd2cSJim Jagielski }
1886*b1cdbd2cSJim Jagielski }
1887*b1cdbd2cSJim Jagielski }
1888*b1cdbd2cSJim Jagielski return nScriptType ? nScriptType : GetI18NScriptTypeOfLanguage( GetDefaultLanguage() );
1889*b1cdbd2cSJim Jagielski }
1890*b1cdbd2cSJim Jagielski
GetScriptType(const EditSelection & rSel) const1891*b1cdbd2cSJim Jagielski sal_uInt16 ImpEditEngine::GetScriptType( const EditSelection& rSel ) const
1892*b1cdbd2cSJim Jagielski {
1893*b1cdbd2cSJim Jagielski EditSelection aSel( rSel );
1894*b1cdbd2cSJim Jagielski aSel.Adjust( aEditDoc );
1895*b1cdbd2cSJim Jagielski
1896*b1cdbd2cSJim Jagielski short nScriptType = 0;
1897*b1cdbd2cSJim Jagielski
1898*b1cdbd2cSJim Jagielski sal_uInt16 nStartPara = GetEditDoc().GetPos( aSel.Min().GetNode() );
1899*b1cdbd2cSJim Jagielski sal_uInt16 nEndPara = GetEditDoc().GetPos( aSel.Max().GetNode() );
1900*b1cdbd2cSJim Jagielski
1901*b1cdbd2cSJim Jagielski for ( sal_uInt16 nPara = nStartPara; nPara <= nEndPara; nPara++ )
1902*b1cdbd2cSJim Jagielski {
1903*b1cdbd2cSJim Jagielski ParaPortion* pParaPortion = GetParaPortions().SaveGetObject( nPara );
1904*b1cdbd2cSJim Jagielski if ( pParaPortion->aScriptInfos.empty() )
1905*b1cdbd2cSJim Jagielski ((ImpEditEngine*)this)->InitScriptTypes( nPara );
1906*b1cdbd2cSJim Jagielski
1907*b1cdbd2cSJim Jagielski ScriptTypePosInfos& rTypes = pParaPortion->aScriptInfos;
1908*b1cdbd2cSJim Jagielski
1909*b1cdbd2cSJim Jagielski // find the first(!) script type position that holds the
1910*b1cdbd2cSJim Jagielski // complete selection. Thus it will work for selections as
1911*b1cdbd2cSJim Jagielski // well as with just moving the cursor from char to char.
1912*b1cdbd2cSJim Jagielski sal_uInt16 nS = ( nPara == nStartPara ) ? aSel.Min().GetIndex() : 0;
1913*b1cdbd2cSJim Jagielski sal_uInt16 nE = ( nPara == nEndPara ) ? aSel.Max().GetIndex() : pParaPortion->GetNode()->Len();
1914*b1cdbd2cSJim Jagielski for ( size_t n = 0; n < rTypes.size(); n++ )
1915*b1cdbd2cSJim Jagielski {
1916*b1cdbd2cSJim Jagielski if (rTypes[n].nStartPos <= nS && nE <= rTypes[n].nEndPos)
1917*b1cdbd2cSJim Jagielski {
1918*b1cdbd2cSJim Jagielski if ( rTypes[n].nScriptType != i18n::ScriptType::WEAK )
1919*b1cdbd2cSJim Jagielski {
1920*b1cdbd2cSJim Jagielski nScriptType |= GetItemScriptType ( rTypes[n].nScriptType );
1921*b1cdbd2cSJim Jagielski }
1922*b1cdbd2cSJim Jagielski else
1923*b1cdbd2cSJim Jagielski {
1924*b1cdbd2cSJim Jagielski if ( !nScriptType && n )
1925*b1cdbd2cSJim Jagielski {
1926*b1cdbd2cSJim Jagielski // #93548# When starting with WEAK, use prev ScriptType...
1927*b1cdbd2cSJim Jagielski nScriptType = rTypes[n-1].nScriptType;
1928*b1cdbd2cSJim Jagielski }
1929*b1cdbd2cSJim Jagielski }
1930*b1cdbd2cSJim Jagielski break;
1931*b1cdbd2cSJim Jagielski }
1932*b1cdbd2cSJim Jagielski }
1933*b1cdbd2cSJim Jagielski }
1934*b1cdbd2cSJim Jagielski return nScriptType ? nScriptType : GetI18NScriptTypeOfLanguage( GetDefaultLanguage() );
1935*b1cdbd2cSJim Jagielski }
1936*b1cdbd2cSJim Jagielski
IsScriptChange(const EditPaM & rPaM) const1937*b1cdbd2cSJim Jagielski sal_Bool ImpEditEngine::IsScriptChange( const EditPaM& rPaM ) const
1938*b1cdbd2cSJim Jagielski {
1939*b1cdbd2cSJim Jagielski sal_Bool bScriptChange = sal_False;
1940*b1cdbd2cSJim Jagielski
1941*b1cdbd2cSJim Jagielski if ( rPaM.GetNode()->Len() )
1942*b1cdbd2cSJim Jagielski {
1943*b1cdbd2cSJim Jagielski sal_uInt16 nPara = GetEditDoc().GetPos( rPaM.GetNode() );
1944*b1cdbd2cSJim Jagielski ParaPortion* pParaPortion = GetParaPortions().SaveGetObject( nPara );
1945*b1cdbd2cSJim Jagielski if ( pParaPortion->aScriptInfos.empty() )
1946*b1cdbd2cSJim Jagielski ((ImpEditEngine*)this)->InitScriptTypes( nPara );
1947*b1cdbd2cSJim Jagielski
1948*b1cdbd2cSJim Jagielski ScriptTypePosInfos& rTypes = pParaPortion->aScriptInfos;
1949*b1cdbd2cSJim Jagielski sal_uInt16 nPos = rPaM.GetIndex();
1950*b1cdbd2cSJim Jagielski for ( size_t n = 0; n < rTypes.size(); n++ )
1951*b1cdbd2cSJim Jagielski {
1952*b1cdbd2cSJim Jagielski if ( rTypes[n].nStartPos == nPos )
1953*b1cdbd2cSJim Jagielski {
1954*b1cdbd2cSJim Jagielski bScriptChange = sal_True;
1955*b1cdbd2cSJim Jagielski break;
1956*b1cdbd2cSJim Jagielski }
1957*b1cdbd2cSJim Jagielski }
1958*b1cdbd2cSJim Jagielski }
1959*b1cdbd2cSJim Jagielski return bScriptChange;
1960*b1cdbd2cSJim Jagielski }
1961*b1cdbd2cSJim Jagielski
HasScriptType(sal_uInt16 nPara,sal_uInt16 nType) const1962*b1cdbd2cSJim Jagielski sal_Bool ImpEditEngine::HasScriptType( sal_uInt16 nPara, sal_uInt16 nType ) const
1963*b1cdbd2cSJim Jagielski {
1964*b1cdbd2cSJim Jagielski sal_Bool bTypeFound = sal_False;
1965*b1cdbd2cSJim Jagielski
1966*b1cdbd2cSJim Jagielski ParaPortion* pParaPortion = GetParaPortions().SaveGetObject( nPara );
1967*b1cdbd2cSJim Jagielski if ( pParaPortion->aScriptInfos.empty() )
1968*b1cdbd2cSJim Jagielski ((ImpEditEngine*)this)->InitScriptTypes( nPara );
1969*b1cdbd2cSJim Jagielski
1970*b1cdbd2cSJim Jagielski ScriptTypePosInfos& rTypes = pParaPortion->aScriptInfos;
1971*b1cdbd2cSJim Jagielski for ( size_t n = rTypes.size(); n && !bTypeFound; )
1972*b1cdbd2cSJim Jagielski {
1973*b1cdbd2cSJim Jagielski if ( rTypes[--n].nScriptType == nType )
1974*b1cdbd2cSJim Jagielski bTypeFound = sal_True;
1975*b1cdbd2cSJim Jagielski }
1976*b1cdbd2cSJim Jagielski return bTypeFound;
1977*b1cdbd2cSJim Jagielski }
1978*b1cdbd2cSJim Jagielski
InitWritingDirections(sal_uInt16 nPara)1979*b1cdbd2cSJim Jagielski void ImpEditEngine::InitWritingDirections( sal_uInt16 nPara )
1980*b1cdbd2cSJim Jagielski {
1981*b1cdbd2cSJim Jagielski ParaPortion* pParaPortion = GetParaPortions().SaveGetObject( nPara );
1982*b1cdbd2cSJim Jagielski WritingDirectionInfos& rInfos = pParaPortion->aWritingDirectionInfos;
1983*b1cdbd2cSJim Jagielski rInfos.clear();
1984*b1cdbd2cSJim Jagielski
1985*b1cdbd2cSJim Jagielski sal_Bool bCTL = sal_False;
1986*b1cdbd2cSJim Jagielski ScriptTypePosInfos& rTypes = pParaPortion->aScriptInfos;
1987*b1cdbd2cSJim Jagielski for ( size_t n = 0; n < rTypes.size(); n++ )
1988*b1cdbd2cSJim Jagielski {
1989*b1cdbd2cSJim Jagielski if ( rTypes[n].nScriptType == i18n::ScriptType::COMPLEX )
1990*b1cdbd2cSJim Jagielski {
1991*b1cdbd2cSJim Jagielski bCTL = sal_True;
1992*b1cdbd2cSJim Jagielski break;
1993*b1cdbd2cSJim Jagielski }
1994*b1cdbd2cSJim Jagielski }
1995*b1cdbd2cSJim Jagielski
1996*b1cdbd2cSJim Jagielski const UBiDiLevel nBidiLevel = IsRightToLeft( nPara ) ? 1 /*RTL*/ : 0 /*LTR*/;
1997*b1cdbd2cSJim Jagielski if ( ( bCTL || ( nBidiLevel == 1 /*RTL*/ ) ) && pParaPortion->GetNode()->Len() )
1998*b1cdbd2cSJim Jagielski {
1999*b1cdbd2cSJim Jagielski
2000*b1cdbd2cSJim Jagielski String aText( *pParaPortion->GetNode() );
2001*b1cdbd2cSJim Jagielski
2002*b1cdbd2cSJim Jagielski //
2003*b1cdbd2cSJim Jagielski // Bidi functions from icu 2.0
2004*b1cdbd2cSJim Jagielski //
2005*b1cdbd2cSJim Jagielski UErrorCode nError = U_ZERO_ERROR;
2006*b1cdbd2cSJim Jagielski UBiDi* pBidi = ubidi_openSized( aText.Len(), 0, &nError );
2007*b1cdbd2cSJim Jagielski nError = U_ZERO_ERROR;
2008*b1cdbd2cSJim Jagielski
2009*b1cdbd2cSJim Jagielski ubidi_setPara( pBidi, reinterpret_cast<const UChar *>(aText.GetBuffer()), aText.Len(), nBidiLevel, NULL, &nError ); // UChar != sal_Unicode in MinGW
2010*b1cdbd2cSJim Jagielski nError = U_ZERO_ERROR;
2011*b1cdbd2cSJim Jagielski
2012*b1cdbd2cSJim Jagielski size_t nCount = ubidi_countRuns( pBidi, &nError );
2013*b1cdbd2cSJim Jagielski
2014*b1cdbd2cSJim Jagielski int32_t nStart = 0;
2015*b1cdbd2cSJim Jagielski int32_t nEnd;
2016*b1cdbd2cSJim Jagielski UBiDiLevel nCurrDir;
2017*b1cdbd2cSJim Jagielski
2018*b1cdbd2cSJim Jagielski for ( size_t nIdx = 0; nIdx < nCount; ++nIdx )
2019*b1cdbd2cSJim Jagielski {
2020*b1cdbd2cSJim Jagielski ubidi_getLogicalRun( pBidi, nStart, &nEnd, &nCurrDir );
2021*b1cdbd2cSJim Jagielski rInfos.push_back( WritingDirectionInfo( nCurrDir, (sal_uInt16)nStart, (sal_uInt16)nEnd ) );
2022*b1cdbd2cSJim Jagielski nStart = nEnd;
2023*b1cdbd2cSJim Jagielski }
2024*b1cdbd2cSJim Jagielski
2025*b1cdbd2cSJim Jagielski ubidi_close( pBidi );
2026*b1cdbd2cSJim Jagielski }
2027*b1cdbd2cSJim Jagielski
2028*b1cdbd2cSJim Jagielski // No infos mean no CTL and default dir is L2R...
2029*b1cdbd2cSJim Jagielski if ( rInfos.empty() )
2030*b1cdbd2cSJim Jagielski rInfos.push_back( WritingDirectionInfo( 0, 0, (sal_uInt16)pParaPortion->GetNode()->Len() ) );
2031*b1cdbd2cSJim Jagielski
2032*b1cdbd2cSJim Jagielski }
2033*b1cdbd2cSJim Jagielski
IsRightToLeft(sal_uInt16 nPara) const2034*b1cdbd2cSJim Jagielski sal_Bool ImpEditEngine::IsRightToLeft( sal_uInt16 nPara ) const
2035*b1cdbd2cSJim Jagielski {
2036*b1cdbd2cSJim Jagielski sal_Bool bR2L = sal_False;
2037*b1cdbd2cSJim Jagielski const SvxFrameDirectionItem* pFrameDirItem = NULL;
2038*b1cdbd2cSJim Jagielski
2039*b1cdbd2cSJim Jagielski if ( !IsVertical() )
2040*b1cdbd2cSJim Jagielski {
2041*b1cdbd2cSJim Jagielski bR2L = GetDefaultHorizontalTextDirection() == EE_HTEXTDIR_R2L;
2042*b1cdbd2cSJim Jagielski pFrameDirItem = &(const SvxFrameDirectionItem&)GetParaAttrib( nPara, EE_PARA_WRITINGDIR );
2043*b1cdbd2cSJim Jagielski if ( pFrameDirItem->GetValue() == FRMDIR_ENVIRONMENT )
2044*b1cdbd2cSJim Jagielski {
2045*b1cdbd2cSJim Jagielski // #103045# if DefaultHorizontalTextDirection is set, use that value, otherwise pool default.
2046*b1cdbd2cSJim Jagielski if ( GetDefaultHorizontalTextDirection() != EE_HTEXTDIR_DEFAULT )
2047*b1cdbd2cSJim Jagielski {
2048*b1cdbd2cSJim Jagielski pFrameDirItem = NULL; // bR2L allready set to default horizontal text direction
2049*b1cdbd2cSJim Jagielski }
2050*b1cdbd2cSJim Jagielski else
2051*b1cdbd2cSJim Jagielski {
2052*b1cdbd2cSJim Jagielski // Use pool default
2053*b1cdbd2cSJim Jagielski pFrameDirItem = &(const SvxFrameDirectionItem&)((ImpEditEngine*)this)->GetEmptyItemSet().Get( EE_PARA_WRITINGDIR );
2054*b1cdbd2cSJim Jagielski }
2055*b1cdbd2cSJim Jagielski }
2056*b1cdbd2cSJim Jagielski }
2057*b1cdbd2cSJim Jagielski
2058*b1cdbd2cSJim Jagielski if ( pFrameDirItem )
2059*b1cdbd2cSJim Jagielski bR2L = pFrameDirItem->GetValue() == FRMDIR_HORI_RIGHT_TOP;
2060*b1cdbd2cSJim Jagielski
2061*b1cdbd2cSJim Jagielski return bR2L;
2062*b1cdbd2cSJim Jagielski }
2063*b1cdbd2cSJim Jagielski
HasDifferentRTLLevels(const ContentNode * pNode)2064*b1cdbd2cSJim Jagielski sal_Bool ImpEditEngine::HasDifferentRTLLevels( const ContentNode* pNode )
2065*b1cdbd2cSJim Jagielski {
2066*b1cdbd2cSJim Jagielski sal_uInt16 nPara = GetEditDoc().GetPos( (ContentNode*)pNode );
2067*b1cdbd2cSJim Jagielski ParaPortion* pParaPortion = GetParaPortions().SaveGetObject( nPara );
2068*b1cdbd2cSJim Jagielski
2069*b1cdbd2cSJim Jagielski sal_Bool bHasDifferentRTLLevels = sal_False;
2070*b1cdbd2cSJim Jagielski
2071*b1cdbd2cSJim Jagielski sal_uInt16 nRTLLevel = IsRightToLeft( nPara ) ? 1 : 0;
2072*b1cdbd2cSJim Jagielski for ( sal_uInt16 n = 0; n < pParaPortion->GetTextPortions().Count(); n++ )
2073*b1cdbd2cSJim Jagielski {
2074*b1cdbd2cSJim Jagielski TextPortion* pTextPortion = pParaPortion->GetTextPortions().GetObject( n );
2075*b1cdbd2cSJim Jagielski if ( pTextPortion->GetRightToLeft() != nRTLLevel )
2076*b1cdbd2cSJim Jagielski {
2077*b1cdbd2cSJim Jagielski bHasDifferentRTLLevels = sal_True;
2078*b1cdbd2cSJim Jagielski break;
2079*b1cdbd2cSJim Jagielski }
2080*b1cdbd2cSJim Jagielski }
2081*b1cdbd2cSJim Jagielski return bHasDifferentRTLLevels;
2082*b1cdbd2cSJim Jagielski }
2083*b1cdbd2cSJim Jagielski
2084*b1cdbd2cSJim Jagielski
GetRightToLeft(sal_uInt16 nPara,sal_uInt16 nPos,sal_uInt16 * pStart,sal_uInt16 * pEnd)2085*b1cdbd2cSJim Jagielski sal_uInt8 ImpEditEngine::GetRightToLeft( sal_uInt16 nPara, sal_uInt16 nPos, sal_uInt16* pStart, sal_uInt16* pEnd )
2086*b1cdbd2cSJim Jagielski {
2087*b1cdbd2cSJim Jagielski // sal_uInt8 nRightToLeft = IsRightToLeft( nPara ) ? 1 : 0;
2088*b1cdbd2cSJim Jagielski sal_uInt8 nRightToLeft = 0;
2089*b1cdbd2cSJim Jagielski
2090*b1cdbd2cSJim Jagielski ContentNode* pNode = aEditDoc.SaveGetObject( nPara );
2091*b1cdbd2cSJim Jagielski if ( pNode && pNode->Len() )
2092*b1cdbd2cSJim Jagielski {
2093*b1cdbd2cSJim Jagielski ParaPortion* pParaPortion = GetParaPortions().SaveGetObject( nPara );
2094*b1cdbd2cSJim Jagielski if ( pParaPortion->aWritingDirectionInfos.empty() )
2095*b1cdbd2cSJim Jagielski InitWritingDirections( nPara );
2096*b1cdbd2cSJim Jagielski
2097*b1cdbd2cSJim Jagielski // sal_uInt8 nType = 0;
2098*b1cdbd2cSJim Jagielski WritingDirectionInfos& rDirInfos = pParaPortion->aWritingDirectionInfos;
2099*b1cdbd2cSJim Jagielski for ( size_t n = 0; n < rDirInfos.size(); n++ )
2100*b1cdbd2cSJim Jagielski {
2101*b1cdbd2cSJim Jagielski if ( ( rDirInfos[n].nStartPos <= nPos ) && ( rDirInfos[n].nEndPos >= nPos ) )
2102*b1cdbd2cSJim Jagielski {
2103*b1cdbd2cSJim Jagielski nRightToLeft = rDirInfos[n].nType;
2104*b1cdbd2cSJim Jagielski if ( pStart )
2105*b1cdbd2cSJim Jagielski *pStart = rDirInfos[n].nStartPos;
2106*b1cdbd2cSJim Jagielski if ( pEnd )
2107*b1cdbd2cSJim Jagielski *pEnd = rDirInfos[n].nEndPos;
2108*b1cdbd2cSJim Jagielski break;
2109*b1cdbd2cSJim Jagielski }
2110*b1cdbd2cSJim Jagielski }
2111*b1cdbd2cSJim Jagielski }
2112*b1cdbd2cSJim Jagielski return nRightToLeft;
2113*b1cdbd2cSJim Jagielski }
2114*b1cdbd2cSJim Jagielski
GetJustification(sal_uInt16 nPara) const2115*b1cdbd2cSJim Jagielski SvxAdjust ImpEditEngine::GetJustification( sal_uInt16 nPara ) const
2116*b1cdbd2cSJim Jagielski {
2117*b1cdbd2cSJim Jagielski SvxAdjust eJustification = SVX_ADJUST_LEFT;
2118*b1cdbd2cSJim Jagielski
2119*b1cdbd2cSJim Jagielski if ( !aStatus.IsOutliner() )
2120*b1cdbd2cSJim Jagielski {
2121*b1cdbd2cSJim Jagielski eJustification = ((const SvxAdjustItem&) GetParaAttrib( nPara, EE_PARA_JUST )).GetAdjust();
2122*b1cdbd2cSJim Jagielski
2123*b1cdbd2cSJim Jagielski if ( IsRightToLeft( nPara ) )
2124*b1cdbd2cSJim Jagielski {
2125*b1cdbd2cSJim Jagielski if ( eJustification == SVX_ADJUST_LEFT )
2126*b1cdbd2cSJim Jagielski eJustification = SVX_ADJUST_RIGHT;
2127*b1cdbd2cSJim Jagielski else if ( eJustification == SVX_ADJUST_RIGHT )
2128*b1cdbd2cSJim Jagielski eJustification = SVX_ADJUST_LEFT;
2129*b1cdbd2cSJim Jagielski }
2130*b1cdbd2cSJim Jagielski }
2131*b1cdbd2cSJim Jagielski return eJustification;
2132*b1cdbd2cSJim Jagielski }
2133*b1cdbd2cSJim Jagielski
2134*b1cdbd2cSJim Jagielski
2135*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------
2136*b1cdbd2cSJim Jagielski // Textaenderung
2137*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------
2138*b1cdbd2cSJim Jagielski
ImpRemoveChars(const EditPaM & rPaM,sal_uInt16 nChars,EditUndoRemoveChars * pCurUndo)2139*b1cdbd2cSJim Jagielski void ImpEditEngine::ImpRemoveChars( const EditPaM& rPaM, sal_uInt16 nChars, EditUndoRemoveChars* pCurUndo )
2140*b1cdbd2cSJim Jagielski {
2141*b1cdbd2cSJim Jagielski if ( IsUndoEnabled() && !IsInUndo() )
2142*b1cdbd2cSJim Jagielski {
2143*b1cdbd2cSJim Jagielski XubString aStr( rPaM.GetNode()->Copy( rPaM.GetIndex(), nChars ) );
2144*b1cdbd2cSJim Jagielski
2145*b1cdbd2cSJim Jagielski // Pruefen, ob Attribute geloescht oder geaendert werden:
2146*b1cdbd2cSJim Jagielski sal_uInt16 nStart = rPaM.GetIndex();
2147*b1cdbd2cSJim Jagielski sal_uInt16 nEnd = nStart + nChars;
2148*b1cdbd2cSJim Jagielski CharAttribArray& rAttribs = rPaM.GetNode()->GetCharAttribs().GetAttribs();
2149*b1cdbd2cSJim Jagielski // sal_uInt16 nAttrs = rAttribs.Count();
2150*b1cdbd2cSJim Jagielski for ( sal_uInt16 nAttr = 0; nAttr < rAttribs.Count(); nAttr++ )
2151*b1cdbd2cSJim Jagielski {
2152*b1cdbd2cSJim Jagielski EditCharAttrib* pAttr = rAttribs[nAttr];
2153*b1cdbd2cSJim Jagielski if ( ( pAttr->GetEnd() >= nStart ) && ( pAttr->GetStart() < nEnd ) )
2154*b1cdbd2cSJim Jagielski {
2155*b1cdbd2cSJim Jagielski #ifndef SVX_LIGHT
2156*b1cdbd2cSJim Jagielski EditSelection aSel( rPaM );
2157*b1cdbd2cSJim Jagielski aSel.Max().GetIndex() = aSel.Max().GetIndex() + nChars;
2158*b1cdbd2cSJim Jagielski EditUndoSetAttribs* pAttrUndo = CreateAttribUndo( aSel, GetEmptyItemSet() );
2159*b1cdbd2cSJim Jagielski InsertUndo( pAttrUndo );
2160*b1cdbd2cSJim Jagielski #endif
2161*b1cdbd2cSJim Jagielski break; // for
2162*b1cdbd2cSJim Jagielski }
2163*b1cdbd2cSJim Jagielski }
2164*b1cdbd2cSJim Jagielski if ( pCurUndo && ( CreateEditPaM( pCurUndo->GetEPaM() ) == rPaM ) )
2165*b1cdbd2cSJim Jagielski pCurUndo->GetStr() += aStr;
2166*b1cdbd2cSJim Jagielski #ifndef SVX_LIGHT
2167*b1cdbd2cSJim Jagielski else
2168*b1cdbd2cSJim Jagielski InsertUndo( new EditUndoRemoveChars( this, CreateEPaM( rPaM ), aStr ) );
2169*b1cdbd2cSJim Jagielski #endif
2170*b1cdbd2cSJim Jagielski }
2171*b1cdbd2cSJim Jagielski
2172*b1cdbd2cSJim Jagielski aEditDoc.RemoveChars( rPaM, nChars );
2173*b1cdbd2cSJim Jagielski TextModified();
2174*b1cdbd2cSJim Jagielski }
2175*b1cdbd2cSJim Jagielski
ImpMoveParagraphs(Range aOldPositions,sal_uInt16 nNewPos)2176*b1cdbd2cSJim Jagielski EditSelection ImpEditEngine::ImpMoveParagraphs( Range aOldPositions, sal_uInt16 nNewPos )
2177*b1cdbd2cSJim Jagielski {
2178*b1cdbd2cSJim Jagielski aOldPositions.Justify();
2179*b1cdbd2cSJim Jagielski sal_Bool bValidAction = ( (long)nNewPos < aOldPositions.Min() ) || ( (long)nNewPos > aOldPositions.Max() );
2180*b1cdbd2cSJim Jagielski DBG_ASSERT( bValidAction, "Move in sich selbst ?" );
2181*b1cdbd2cSJim Jagielski DBG_ASSERT( aOldPositions.Max() <= (long)GetParaPortions().Count(), "Voll drueber weg: MoveParagraphs" );
2182*b1cdbd2cSJim Jagielski
2183*b1cdbd2cSJim Jagielski EditSelection aSelection;
2184*b1cdbd2cSJim Jagielski
2185*b1cdbd2cSJim Jagielski if ( !bValidAction )
2186*b1cdbd2cSJim Jagielski {
2187*b1cdbd2cSJim Jagielski aSelection = aEditDoc.GetStartPaM();
2188*b1cdbd2cSJim Jagielski return aSelection;
2189*b1cdbd2cSJim Jagielski }
2190*b1cdbd2cSJim Jagielski
2191*b1cdbd2cSJim Jagielski sal_uLong nParaCount = GetParaPortions().Count();
2192*b1cdbd2cSJim Jagielski
2193*b1cdbd2cSJim Jagielski if ( nNewPos >= nParaCount )
2194*b1cdbd2cSJim Jagielski nNewPos = GetParaPortions().Count();
2195*b1cdbd2cSJim Jagielski
2196*b1cdbd2cSJim Jagielski // Height may change when moving first or last Paragraph
2197*b1cdbd2cSJim Jagielski ParaPortion* pRecalc1 = NULL;
2198*b1cdbd2cSJim Jagielski ParaPortion* pRecalc2 = NULL;
2199*b1cdbd2cSJim Jagielski ParaPortion* pRecalc3 = NULL;
2200*b1cdbd2cSJim Jagielski ParaPortion* pRecalc4 = NULL;
2201*b1cdbd2cSJim Jagielski
2202*b1cdbd2cSJim Jagielski if ( nNewPos == 0 ) // Move to Start
2203*b1cdbd2cSJim Jagielski {
2204*b1cdbd2cSJim Jagielski pRecalc1 = GetParaPortions().GetObject( 0 );
2205*b1cdbd2cSJim Jagielski pRecalc2 = GetParaPortions().GetObject( (sal_uInt16)aOldPositions.Min() );
2206*b1cdbd2cSJim Jagielski
2207*b1cdbd2cSJim Jagielski }
2208*b1cdbd2cSJim Jagielski else if ( nNewPos == nParaCount )
2209*b1cdbd2cSJim Jagielski {
2210*b1cdbd2cSJim Jagielski pRecalc1 = GetParaPortions().GetObject( (sal_uInt16)(nParaCount-1) );
2211*b1cdbd2cSJim Jagielski pRecalc2 = GetParaPortions().GetObject( (sal_uInt16)aOldPositions.Max() );
2212*b1cdbd2cSJim Jagielski }
2213*b1cdbd2cSJim Jagielski
2214*b1cdbd2cSJim Jagielski if ( aOldPositions.Min() == 0 ) // Move from Start
2215*b1cdbd2cSJim Jagielski {
2216*b1cdbd2cSJim Jagielski pRecalc3 = GetParaPortions().GetObject( 0 );
2217*b1cdbd2cSJim Jagielski pRecalc4 = GetParaPortions().GetObject(
2218*b1cdbd2cSJim Jagielski sal::static_int_cast< sal_uInt16 >( aOldPositions.Max()+1 ) );
2219*b1cdbd2cSJim Jagielski }
2220*b1cdbd2cSJim Jagielski else if ( (sal_uInt16)aOldPositions.Max() == (nParaCount-1) )
2221*b1cdbd2cSJim Jagielski {
2222*b1cdbd2cSJim Jagielski pRecalc3 = GetParaPortions().GetObject( (sal_uInt16)aOldPositions.Max() );
2223*b1cdbd2cSJim Jagielski pRecalc4 = GetParaPortions().GetObject( (sal_uInt16)(aOldPositions.Min()-1) );
2224*b1cdbd2cSJim Jagielski }
2225*b1cdbd2cSJim Jagielski
2226*b1cdbd2cSJim Jagielski MoveParagraphsInfo aMoveParagraphsInfo( sal::static_int_cast< sal_uInt16 >(aOldPositions.Min()), sal::static_int_cast< sal_uInt16 >(aOldPositions.Max()), nNewPos );
2227*b1cdbd2cSJim Jagielski aBeginMovingParagraphsHdl.Call( &aMoveParagraphsInfo );
2228*b1cdbd2cSJim Jagielski
2229*b1cdbd2cSJim Jagielski if ( IsUndoEnabled() && !IsInUndo())
2230*b1cdbd2cSJim Jagielski InsertUndo( new EditUndoMoveParagraphs( this, aOldPositions, nNewPos ) );
2231*b1cdbd2cSJim Jagielski
2232*b1cdbd2cSJim Jagielski // Position nicht aus dem Auge verlieren!
2233*b1cdbd2cSJim Jagielski ParaPortion* pDestPortion = GetParaPortions().SaveGetObject( nNewPos );
2234*b1cdbd2cSJim Jagielski
2235*b1cdbd2cSJim Jagielski ParaPortionList aTmpPortionList;
2236*b1cdbd2cSJim Jagielski sal_uInt16 i;
2237*b1cdbd2cSJim Jagielski for ( i = (sal_uInt16)aOldPositions.Min(); i <= (sal_uInt16)aOldPositions.Max(); i++ )
2238*b1cdbd2cSJim Jagielski {
2239*b1cdbd2cSJim Jagielski // Immer aOldPositions.Min(), da Remove().
2240*b1cdbd2cSJim Jagielski ParaPortion* pTmpPortion = GetParaPortions().GetObject( (sal_uInt16)aOldPositions.Min() );
2241*b1cdbd2cSJim Jagielski GetParaPortions().Remove( (sal_uInt16)aOldPositions.Min() );
2242*b1cdbd2cSJim Jagielski aEditDoc.Remove( (sal_uInt16)aOldPositions.Min() );
2243*b1cdbd2cSJim Jagielski aTmpPortionList.Insert( pTmpPortion, aTmpPortionList.Count() );
2244*b1cdbd2cSJim Jagielski }
2245*b1cdbd2cSJim Jagielski
2246*b1cdbd2cSJim Jagielski sal_uInt16 nRealNewPos = pDestPortion ? GetParaPortions().GetPos( pDestPortion ) : GetParaPortions().Count();
2247*b1cdbd2cSJim Jagielski DBG_ASSERT( nRealNewPos != USHRT_MAX, "ImpMoveParagraphs: Ungueltige Position!" );
2248*b1cdbd2cSJim Jagielski
2249*b1cdbd2cSJim Jagielski for ( i = 0; i < (sal_uInt16)aTmpPortionList.Count(); i++ )
2250*b1cdbd2cSJim Jagielski {
2251*b1cdbd2cSJim Jagielski ParaPortion* pTmpPortion = aTmpPortionList.GetObject( i );
2252*b1cdbd2cSJim Jagielski if ( i == 0 )
2253*b1cdbd2cSJim Jagielski aSelection.Min().SetNode( pTmpPortion->GetNode() );
2254*b1cdbd2cSJim Jagielski
2255*b1cdbd2cSJim Jagielski aSelection.Max().SetNode( pTmpPortion->GetNode() );
2256*b1cdbd2cSJim Jagielski aSelection.Max().SetIndex( pTmpPortion->GetNode()->Len() );
2257*b1cdbd2cSJim Jagielski
2258*b1cdbd2cSJim Jagielski ContentNode* pN = pTmpPortion->GetNode();
2259*b1cdbd2cSJim Jagielski aEditDoc.Insert( pN, nRealNewPos+i );
2260*b1cdbd2cSJim Jagielski
2261*b1cdbd2cSJim Jagielski GetParaPortions().Insert( pTmpPortion, nRealNewPos+i );
2262*b1cdbd2cSJim Jagielski }
2263*b1cdbd2cSJim Jagielski
2264*b1cdbd2cSJim Jagielski aEndMovingParagraphsHdl.Call( &aMoveParagraphsInfo );
2265*b1cdbd2cSJim Jagielski
2266*b1cdbd2cSJim Jagielski if ( GetNotifyHdl().IsSet() )
2267*b1cdbd2cSJim Jagielski {
2268*b1cdbd2cSJim Jagielski EENotify aNotify( EE_NOTIFY_PARAGRAPHSMOVED );
2269*b1cdbd2cSJim Jagielski aNotify.pEditEngine = GetEditEnginePtr();
2270*b1cdbd2cSJim Jagielski aNotify.nParagraph = nNewPos;
2271*b1cdbd2cSJim Jagielski aNotify.nParam1 = sal::static_int_cast< sal_uInt16 >(aOldPositions.Min());
2272*b1cdbd2cSJim Jagielski aNotify.nParam2 = sal::static_int_cast< sal_uInt16 >(aOldPositions.Max());
2273*b1cdbd2cSJim Jagielski CallNotify( aNotify );
2274*b1cdbd2cSJim Jagielski }
2275*b1cdbd2cSJim Jagielski
2276*b1cdbd2cSJim Jagielski aEditDoc.SetModified( sal_True );
2277*b1cdbd2cSJim Jagielski
2278*b1cdbd2cSJim Jagielski if ( pRecalc1 )
2279*b1cdbd2cSJim Jagielski CalcHeight( pRecalc1 );
2280*b1cdbd2cSJim Jagielski if ( pRecalc2 )
2281*b1cdbd2cSJim Jagielski CalcHeight( pRecalc2 );
2282*b1cdbd2cSJim Jagielski if ( pRecalc3 )
2283*b1cdbd2cSJim Jagielski CalcHeight( pRecalc3 );
2284*b1cdbd2cSJim Jagielski if ( pRecalc4 )
2285*b1cdbd2cSJim Jagielski CalcHeight( pRecalc4 );
2286*b1cdbd2cSJim Jagielski
2287*b1cdbd2cSJim Jagielski aTmpPortionList.Remove( 0, aTmpPortionList.Count() ); // wichtig !
2288*b1cdbd2cSJim Jagielski
2289*b1cdbd2cSJim Jagielski #ifdef EDITDEBUG
2290*b1cdbd2cSJim Jagielski GetParaPortions().DbgCheck(aEditDoc);
2291*b1cdbd2cSJim Jagielski #endif
2292*b1cdbd2cSJim Jagielski return aSelection;
2293*b1cdbd2cSJim Jagielski }
2294*b1cdbd2cSJim Jagielski
2295*b1cdbd2cSJim Jagielski
ImpConnectParagraphs(ContentNode * pLeft,ContentNode * pRight,sal_Bool bBackward)2296*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::ImpConnectParagraphs( ContentNode* pLeft, ContentNode* pRight, sal_Bool bBackward )
2297*b1cdbd2cSJim Jagielski {
2298*b1cdbd2cSJim Jagielski DBG_ASSERT( pLeft != pRight, "Den gleichen Absatz zusammenfuegen ?" );
2299*b1cdbd2cSJim Jagielski DBG_ASSERT( aEditDoc.GetPos( pLeft ) != USHRT_MAX, "Einzufuegenden Node nicht gefunden(1)" );
2300*b1cdbd2cSJim Jagielski DBG_ASSERT( aEditDoc.GetPos( pRight ) != USHRT_MAX, "Einzufuegenden Node nicht gefunden(2)" );
2301*b1cdbd2cSJim Jagielski
2302*b1cdbd2cSJim Jagielski // #120020# it is possible that left and right are *not* in the desired order (left/right)
2303*b1cdbd2cSJim Jagielski // so correct it. This correction is needed, else an invalid SfxLinkUndoAction will be
2304*b1cdbd2cSJim Jagielski // created from ConnectParagraphs below. Assert this situation, it should be corrected by the
2305*b1cdbd2cSJim Jagielski // caller.
2306*b1cdbd2cSJim Jagielski if(aEditDoc.GetPos( pLeft ) > aEditDoc.GetPos( pRight ))
2307*b1cdbd2cSJim Jagielski {
2308*b1cdbd2cSJim Jagielski OSL_ENSURE(false, "ImpConnectParagraphs wit wrong order of pLeft/pRight nodes (!)");
2309*b1cdbd2cSJim Jagielski std::swap(pLeft, pRight);
2310*b1cdbd2cSJim Jagielski }
2311*b1cdbd2cSJim Jagielski
2312*b1cdbd2cSJim Jagielski sal_uInt16 nParagraphTobeDeleted = aEditDoc.GetPos( pRight );
2313*b1cdbd2cSJim Jagielski DeletedNodeInfo* pInf = new DeletedNodeInfo( (sal_uLong)pRight, nParagraphTobeDeleted );
2314*b1cdbd2cSJim Jagielski aDeletedNodes.Insert( pInf, aDeletedNodes.Count() );
2315*b1cdbd2cSJim Jagielski
2316*b1cdbd2cSJim Jagielski GetEditEnginePtr()->ParagraphConnected( aEditDoc.GetPos( pLeft ), aEditDoc.GetPos( pRight ) );
2317*b1cdbd2cSJim Jagielski
2318*b1cdbd2cSJim Jagielski #ifndef SVX_LIGHT
2319*b1cdbd2cSJim Jagielski if ( IsUndoEnabled() && !IsInUndo() )
2320*b1cdbd2cSJim Jagielski {
2321*b1cdbd2cSJim Jagielski InsertUndo( new EditUndoConnectParas( this,
2322*b1cdbd2cSJim Jagielski aEditDoc.GetPos( pLeft ), pLeft->Len(),
2323*b1cdbd2cSJim Jagielski pLeft->GetContentAttribs().GetItems(), pRight->GetContentAttribs().GetItems(),
2324*b1cdbd2cSJim Jagielski pLeft->GetStyleSheet(), pRight->GetStyleSheet(), bBackward ) );
2325*b1cdbd2cSJim Jagielski }
2326*b1cdbd2cSJim Jagielski #endif
2327*b1cdbd2cSJim Jagielski
2328*b1cdbd2cSJim Jagielski if ( bBackward )
2329*b1cdbd2cSJim Jagielski {
2330*b1cdbd2cSJim Jagielski pLeft->SetStyleSheet( pRight->GetStyleSheet(), sal_True );
2331*b1cdbd2cSJim Jagielski pLeft->GetContentAttribs().GetItems().Set( pRight->GetContentAttribs().GetItems() );
2332*b1cdbd2cSJim Jagielski pLeft->GetCharAttribs().GetDefFont() = pRight->GetCharAttribs().GetDefFont();
2333*b1cdbd2cSJim Jagielski }
2334*b1cdbd2cSJim Jagielski
2335*b1cdbd2cSJim Jagielski ParaAttribsChanged( pLeft );
2336*b1cdbd2cSJim Jagielski
2337*b1cdbd2cSJim Jagielski // Erstmal Portions suchen, da pRight nach ConnectParagraphs weg.
2338*b1cdbd2cSJim Jagielski ParaPortion* pLeftPortion = FindParaPortion( pLeft );
2339*b1cdbd2cSJim Jagielski ParaPortion* pRightPortion = FindParaPortion( pRight );
2340*b1cdbd2cSJim Jagielski DBG_ASSERT( pLeftPortion, "Blinde Portion in ImpConnectParagraphs(1)" );
2341*b1cdbd2cSJim Jagielski DBG_ASSERT( pRightPortion, "Blinde Portion in ImpConnectParagraphs(2)" );
2342*b1cdbd2cSJim Jagielski DBG_ASSERT( nParagraphTobeDeleted == GetParaPortions().GetPos( pRightPortion ), "NodePos != PortionPos?" );
2343*b1cdbd2cSJim Jagielski
2344*b1cdbd2cSJim Jagielski #ifndef SVX_LIGHT
2345*b1cdbd2cSJim Jagielski if ( GetStatus().DoOnlineSpelling() )
2346*b1cdbd2cSJim Jagielski {
2347*b1cdbd2cSJim Jagielski xub_StrLen nEnd = pLeft->Len();
2348*b1cdbd2cSJim Jagielski xub_StrLen nInv = nEnd ? nEnd-1 : nEnd;
2349*b1cdbd2cSJim Jagielski pLeft->GetWrongList()->ClearWrongs( nInv, 0xFFFF, pLeft ); // Evtl. einen wegnehmen
2350*b1cdbd2cSJim Jagielski pLeft->GetWrongList()->MarkInvalid( nInv, nEnd+1 );
2351*b1cdbd2cSJim Jagielski // Falschgeschriebene Woerter ruebernehmen:
2352*b1cdbd2cSJim Jagielski sal_uInt16 nRWrongs = pRight->GetWrongList()->Count();
2353*b1cdbd2cSJim Jagielski for ( sal_uInt16 nW = 0; nW < nRWrongs; nW++ )
2354*b1cdbd2cSJim Jagielski {
2355*b1cdbd2cSJim Jagielski WrongRange aWrong = pRight->GetWrongList()->GetObject( nW );
2356*b1cdbd2cSJim Jagielski if ( aWrong.nStart != 0 ) // Nicht ein anschliessender
2357*b1cdbd2cSJim Jagielski {
2358*b1cdbd2cSJim Jagielski aWrong.nStart = aWrong.nStart + nEnd;
2359*b1cdbd2cSJim Jagielski aWrong.nEnd = aWrong.nEnd + nEnd;
2360*b1cdbd2cSJim Jagielski pLeft->GetWrongList()->InsertWrong( aWrong, pLeft->GetWrongList()->Count() );
2361*b1cdbd2cSJim Jagielski }
2362*b1cdbd2cSJim Jagielski }
2363*b1cdbd2cSJim Jagielski }
2364*b1cdbd2cSJim Jagielski #endif
2365*b1cdbd2cSJim Jagielski
2366*b1cdbd2cSJim Jagielski if ( IsCallParaInsertedOrDeleted() )
2367*b1cdbd2cSJim Jagielski GetEditEnginePtr()->ParagraphDeleted( nParagraphTobeDeleted );
2368*b1cdbd2cSJim Jagielski
2369*b1cdbd2cSJim Jagielski EditPaM aPaM = aEditDoc.ConnectParagraphs( pLeft, pRight );
2370*b1cdbd2cSJim Jagielski GetParaPortions().Remove( nParagraphTobeDeleted );
2371*b1cdbd2cSJim Jagielski delete pRightPortion;
2372*b1cdbd2cSJim Jagielski
2373*b1cdbd2cSJim Jagielski pLeftPortion->MarkSelectionInvalid( aPaM.GetIndex(), pLeft->Len() );
2374*b1cdbd2cSJim Jagielski
2375*b1cdbd2cSJim Jagielski // der rechte Node wird von EditDoc::ConnectParagraphs() geloescht.
2376*b1cdbd2cSJim Jagielski
2377*b1cdbd2cSJim Jagielski if ( GetTextRanger() )
2378*b1cdbd2cSJim Jagielski {
2379*b1cdbd2cSJim Jagielski // Durch das zusammenfuegen wird der linke zwar neu formatiert, aber
2380*b1cdbd2cSJim Jagielski // wenn sich dessen Hoehe nicht aendert bekommt die Formatierung die
2381*b1cdbd2cSJim Jagielski // Aenderung der Gesaamthoehe des Textes zu spaet mit...
2382*b1cdbd2cSJim Jagielski for ( sal_uInt16 n = nParagraphTobeDeleted; n < GetParaPortions().Count(); n++ )
2383*b1cdbd2cSJim Jagielski {
2384*b1cdbd2cSJim Jagielski ParaPortion* pPP = GetParaPortions().GetObject( n );
2385*b1cdbd2cSJim Jagielski pPP->MarkSelectionInvalid( 0, pPP->GetNode()->Len() );
2386*b1cdbd2cSJim Jagielski pPP->GetLines().Reset();
2387*b1cdbd2cSJim Jagielski }
2388*b1cdbd2cSJim Jagielski }
2389*b1cdbd2cSJim Jagielski
2390*b1cdbd2cSJim Jagielski TextModified();
2391*b1cdbd2cSJim Jagielski
2392*b1cdbd2cSJim Jagielski return aPaM;
2393*b1cdbd2cSJim Jagielski }
2394*b1cdbd2cSJim Jagielski
DeleteLeftOrRight(const EditSelection & rSel,sal_uInt8 nMode,sal_uInt8 nDelMode)2395*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::DeleteLeftOrRight( const EditSelection& rSel, sal_uInt8 nMode, sal_uInt8 nDelMode )
2396*b1cdbd2cSJim Jagielski {
2397*b1cdbd2cSJim Jagielski DBG_ASSERT( !EditSelection( rSel ).DbgIsBuggy( aEditDoc ), "Index im Wald in DeleteLeftOrRight" );
2398*b1cdbd2cSJim Jagielski
2399*b1cdbd2cSJim Jagielski if ( rSel.HasRange() ) // dann nur Sel. loeschen
2400*b1cdbd2cSJim Jagielski return ImpDeleteSelection( rSel );
2401*b1cdbd2cSJim Jagielski
2402*b1cdbd2cSJim Jagielski const EditPaM aCurPos( rSel.Max() );
2403*b1cdbd2cSJim Jagielski EditPaM aDelStart( aCurPos );
2404*b1cdbd2cSJim Jagielski EditPaM aDelEnd( aCurPos );
2405*b1cdbd2cSJim Jagielski if ( nMode == DEL_LEFT )
2406*b1cdbd2cSJim Jagielski {
2407*b1cdbd2cSJim Jagielski if ( nDelMode == DELMODE_SIMPLE )
2408*b1cdbd2cSJim Jagielski {
2409*b1cdbd2cSJim Jagielski aDelStart = CursorLeft( aCurPos, i18n::CharacterIteratorMode::SKIPCHARACTER );
2410*b1cdbd2cSJim Jagielski }
2411*b1cdbd2cSJim Jagielski else if ( nDelMode == DELMODE_RESTOFWORD )
2412*b1cdbd2cSJim Jagielski {
2413*b1cdbd2cSJim Jagielski aDelStart = StartOfWord( aCurPos );
2414*b1cdbd2cSJim Jagielski if ( aDelStart.GetIndex() == aCurPos.GetIndex() )
2415*b1cdbd2cSJim Jagielski aDelStart = WordLeft( aCurPos );
2416*b1cdbd2cSJim Jagielski }
2417*b1cdbd2cSJim Jagielski else // DELMODE_RESTOFCONTENT
2418*b1cdbd2cSJim Jagielski {
2419*b1cdbd2cSJim Jagielski aDelStart.SetIndex( 0 );
2420*b1cdbd2cSJim Jagielski if ( aDelStart == aCurPos )
2421*b1cdbd2cSJim Jagielski {
2422*b1cdbd2cSJim Jagielski // kompletter Absatz davor
2423*b1cdbd2cSJim Jagielski ContentNode* pPrev = GetPrevVisNode( aCurPos.GetNode() );
2424*b1cdbd2cSJim Jagielski if ( pPrev )
2425*b1cdbd2cSJim Jagielski aDelStart = EditPaM( pPrev, 0 );
2426*b1cdbd2cSJim Jagielski }
2427*b1cdbd2cSJim Jagielski }
2428*b1cdbd2cSJim Jagielski }
2429*b1cdbd2cSJim Jagielski else
2430*b1cdbd2cSJim Jagielski {
2431*b1cdbd2cSJim Jagielski if ( nDelMode == DELMODE_SIMPLE )
2432*b1cdbd2cSJim Jagielski {
2433*b1cdbd2cSJim Jagielski aDelEnd = CursorRight( aCurPos );
2434*b1cdbd2cSJim Jagielski }
2435*b1cdbd2cSJim Jagielski else if ( nDelMode == DELMODE_RESTOFWORD )
2436*b1cdbd2cSJim Jagielski {
2437*b1cdbd2cSJim Jagielski aDelEnd = EndOfWord( aCurPos );
2438*b1cdbd2cSJim Jagielski
2439*b1cdbd2cSJim Jagielski if (aDelEnd.GetIndex() == aCurPos.GetIndex())
2440*b1cdbd2cSJim Jagielski {
2441*b1cdbd2cSJim Jagielski const xub_StrLen nLen(aCurPos.GetNode()->Len());
2442*b1cdbd2cSJim Jagielski
2443*b1cdbd2cSJim Jagielski // #120020# when 0 == nLen, aDelStart needs to be adapted, not
2444*b1cdbd2cSJim Jagielski // aDelEnd. This would (and did) lead to a wrong order in the
2445*b1cdbd2cSJim Jagielski // ImpConnectParagraphs call later.
2446*b1cdbd2cSJim Jagielski if(nLen)
2447*b1cdbd2cSJim Jagielski {
2448*b1cdbd2cSJim Jagielski // end of para?
2449*b1cdbd2cSJim Jagielski if (aDelEnd.GetIndex() == nLen)
2450*b1cdbd2cSJim Jagielski {
2451*b1cdbd2cSJim Jagielski aDelEnd = WordLeft( aCurPos );
2452*b1cdbd2cSJim Jagielski }
2453*b1cdbd2cSJim Jagielski else // there's still sth to delete on the right
2454*b1cdbd2cSJim Jagielski {
2455*b1cdbd2cSJim Jagielski aDelEnd = EndOfWord( WordRight( aCurPos ) );
2456*b1cdbd2cSJim Jagielski // if there'n no next word...
2457*b1cdbd2cSJim Jagielski if (aDelEnd.GetIndex() == nLen )
2458*b1cdbd2cSJim Jagielski {
2459*b1cdbd2cSJim Jagielski aDelEnd.SetIndex( nLen );
2460*b1cdbd2cSJim Jagielski }
2461*b1cdbd2cSJim Jagielski }
2462*b1cdbd2cSJim Jagielski }
2463*b1cdbd2cSJim Jagielski else
2464*b1cdbd2cSJim Jagielski {
2465*b1cdbd2cSJim Jagielski aDelStart = WordLeft(aCurPos);
2466*b1cdbd2cSJim Jagielski }
2467*b1cdbd2cSJim Jagielski }
2468*b1cdbd2cSJim Jagielski }
2469*b1cdbd2cSJim Jagielski else // DELMODE_RESTOFCONTENT
2470*b1cdbd2cSJim Jagielski {
2471*b1cdbd2cSJim Jagielski aDelEnd.SetIndex( aCurPos.GetNode()->Len() );
2472*b1cdbd2cSJim Jagielski if ( aDelEnd == aCurPos )
2473*b1cdbd2cSJim Jagielski {
2474*b1cdbd2cSJim Jagielski // kompletter Absatz dahinter
2475*b1cdbd2cSJim Jagielski ContentNode* pNext = GetNextVisNode( aCurPos.GetNode() );
2476*b1cdbd2cSJim Jagielski if ( pNext )
2477*b1cdbd2cSJim Jagielski aDelEnd = EditPaM( pNext, pNext->Len() );
2478*b1cdbd2cSJim Jagielski }
2479*b1cdbd2cSJim Jagielski }
2480*b1cdbd2cSJim Jagielski }
2481*b1cdbd2cSJim Jagielski
2482*b1cdbd2cSJim Jagielski // Bei DELMODE_RESTOFCONTENT reicht bei verschiedenen Nodes
2483*b1cdbd2cSJim Jagielski // kein ConnectParagraphs.
2484*b1cdbd2cSJim Jagielski if ( ( nDelMode == DELMODE_RESTOFCONTENT ) || ( aDelStart.GetNode() == aDelEnd.GetNode() ) )
2485*b1cdbd2cSJim Jagielski return ImpDeleteSelection( EditSelection( aDelStart, aDelEnd ) );
2486*b1cdbd2cSJim Jagielski
2487*b1cdbd2cSJim Jagielski // Jetzt entscheiden, ob noch Selektion loeschen (RESTOFCONTENTS)
2488*b1cdbd2cSJim Jagielski sal_Bool bSpecialBackward = ( ( nMode == DEL_LEFT ) && ( nDelMode == DELMODE_SIMPLE ) )
2489*b1cdbd2cSJim Jagielski ? sal_True : sal_False;
2490*b1cdbd2cSJim Jagielski if ( aStatus.IsAnyOutliner() )
2491*b1cdbd2cSJim Jagielski bSpecialBackward = sal_False;
2492*b1cdbd2cSJim Jagielski
2493*b1cdbd2cSJim Jagielski return ImpConnectParagraphs( aDelStart.GetNode(), aDelEnd.GetNode(), bSpecialBackward );
2494*b1cdbd2cSJim Jagielski }
2495*b1cdbd2cSJim Jagielski
ImpDeleteSelection(EditSelection aSel)2496*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::ImpDeleteSelection( EditSelection aSel )
2497*b1cdbd2cSJim Jagielski {
2498*b1cdbd2cSJim Jagielski if ( !aSel.HasRange() )
2499*b1cdbd2cSJim Jagielski return aSel.Min();
2500*b1cdbd2cSJim Jagielski
2501*b1cdbd2cSJim Jagielski aSel.Adjust( aEditDoc );
2502*b1cdbd2cSJim Jagielski EditPaM aStartPaM( aSel.Min() );
2503*b1cdbd2cSJim Jagielski EditPaM aEndPaM( aSel.Max() );
2504*b1cdbd2cSJim Jagielski
2505*b1cdbd2cSJim Jagielski CursorMoved( aStartPaM.GetNode() ); // nur damit neu eingestellte Attribute verschwinden...
2506*b1cdbd2cSJim Jagielski CursorMoved( aEndPaM.GetNode() ); // nur damit neu eingestellte Attribute verschwinden...
2507*b1cdbd2cSJim Jagielski
2508*b1cdbd2cSJim Jagielski DBG_ASSERT( aStartPaM.GetIndex() <= aStartPaM.GetNode()->Len(), "Index im Wald in ImpDeleteSelection" );
2509*b1cdbd2cSJim Jagielski DBG_ASSERT( aEndPaM.GetIndex() <= aEndPaM.GetNode()->Len(), "Index im Wald in ImpDeleteSelection" );
2510*b1cdbd2cSJim Jagielski
2511*b1cdbd2cSJim Jagielski sal_uInt16 nStartNode = aEditDoc.GetPos( aStartPaM.GetNode() );
2512*b1cdbd2cSJim Jagielski sal_uInt16 nEndNode = aEditDoc.GetPos( aEndPaM.GetNode() );
2513*b1cdbd2cSJim Jagielski
2514*b1cdbd2cSJim Jagielski DBG_ASSERT( nEndNode != USHRT_MAX, "Start > End ?!" );
2515*b1cdbd2cSJim Jagielski DBG_ASSERT( nStartNode <= nEndNode, "Start > End ?!" );
2516*b1cdbd2cSJim Jagielski
2517*b1cdbd2cSJim Jagielski // Alle Nodes dazwischen entfernen....
2518*b1cdbd2cSJim Jagielski for ( sal_uLong z = nStartNode+1; z < nEndNode; z++ )
2519*b1cdbd2cSJim Jagielski {
2520*b1cdbd2cSJim Jagielski // Immer nStartNode+1, wegen Remove()!
2521*b1cdbd2cSJim Jagielski ImpRemoveParagraph( nStartNode+1 );
2522*b1cdbd2cSJim Jagielski }
2523*b1cdbd2cSJim Jagielski
2524*b1cdbd2cSJim Jagielski if ( aStartPaM.GetNode() != aEndPaM.GetNode() )
2525*b1cdbd2cSJim Jagielski {
2526*b1cdbd2cSJim Jagielski // Den Rest des StartNodes...
2527*b1cdbd2cSJim Jagielski sal_uInt16 nChars;
2528*b1cdbd2cSJim Jagielski nChars = aStartPaM.GetNode()->Len() - aStartPaM.GetIndex();
2529*b1cdbd2cSJim Jagielski ImpRemoveChars( aStartPaM, nChars );
2530*b1cdbd2cSJim Jagielski ParaPortion* pPortion = FindParaPortion( aStartPaM.GetNode() );
2531*b1cdbd2cSJim Jagielski DBG_ASSERT( pPortion, "Blinde Portion in ImpDeleteSelection(3)" );
2532*b1cdbd2cSJim Jagielski pPortion->MarkSelectionInvalid( aStartPaM.GetIndex(), aStartPaM.GetNode()->Len() );
2533*b1cdbd2cSJim Jagielski
2534*b1cdbd2cSJim Jagielski // Den Anfang des EndNodes....
2535*b1cdbd2cSJim Jagielski nChars = aEndPaM.GetIndex();
2536*b1cdbd2cSJim Jagielski aEndPaM.SetIndex( 0 );
2537*b1cdbd2cSJim Jagielski ImpRemoveChars( aEndPaM, nChars );
2538*b1cdbd2cSJim Jagielski pPortion = FindParaPortion( aEndPaM.GetNode() );
2539*b1cdbd2cSJim Jagielski DBG_ASSERT( pPortion, "Blinde Portion in ImpDeleteSelection(4)" );
2540*b1cdbd2cSJim Jagielski pPortion->MarkSelectionInvalid( 0, aEndPaM.GetNode()->Len() );
2541*b1cdbd2cSJim Jagielski // Zusammenfuegen....
2542*b1cdbd2cSJim Jagielski aStartPaM = ImpConnectParagraphs( aStartPaM.GetNode(), aEndPaM.GetNode() );
2543*b1cdbd2cSJim Jagielski }
2544*b1cdbd2cSJim Jagielski else
2545*b1cdbd2cSJim Jagielski {
2546*b1cdbd2cSJim Jagielski sal_uInt16 nChars;
2547*b1cdbd2cSJim Jagielski nChars = aEndPaM.GetIndex() - aStartPaM.GetIndex();
2548*b1cdbd2cSJim Jagielski ImpRemoveChars( aStartPaM, nChars );
2549*b1cdbd2cSJim Jagielski ParaPortion* pPortion = FindParaPortion( aStartPaM.GetNode() );
2550*b1cdbd2cSJim Jagielski DBG_ASSERT( pPortion, "Blinde Portion in ImpDeleteSelection(5)" );
2551*b1cdbd2cSJim Jagielski pPortion->MarkInvalid( aEndPaM.GetIndex(), aStartPaM.GetIndex() - aEndPaM.GetIndex() );
2552*b1cdbd2cSJim Jagielski }
2553*b1cdbd2cSJim Jagielski
2554*b1cdbd2cSJim Jagielski UpdateSelections();
2555*b1cdbd2cSJim Jagielski TextModified();
2556*b1cdbd2cSJim Jagielski return aStartPaM;
2557*b1cdbd2cSJim Jagielski }
2558*b1cdbd2cSJim Jagielski
ImpRemoveParagraph(sal_uInt16 nPara)2559*b1cdbd2cSJim Jagielski void ImpEditEngine::ImpRemoveParagraph( sal_uInt16 nPara )
2560*b1cdbd2cSJim Jagielski {
2561*b1cdbd2cSJim Jagielski ContentNode* pNode = aEditDoc.SaveGetObject( nPara );
2562*b1cdbd2cSJim Jagielski ContentNode* pNextNode = aEditDoc.SaveGetObject( nPara+1 );
2563*b1cdbd2cSJim Jagielski ParaPortion* pPortion = GetParaPortions().SaveGetObject( nPara );
2564*b1cdbd2cSJim Jagielski
2565*b1cdbd2cSJim Jagielski DBG_ASSERT( pNode, "Blinder Node in ImpRemoveParagraph" );
2566*b1cdbd2cSJim Jagielski DBG_ASSERT( pPortion, "Blinde Portion in ImpRemoveParagraph(2)" );
2567*b1cdbd2cSJim Jagielski
2568*b1cdbd2cSJim Jagielski DeletedNodeInfo* pInf = new DeletedNodeInfo( (sal_uLong)pNode, nPara );
2569*b1cdbd2cSJim Jagielski aDeletedNodes.Insert( pInf, aDeletedNodes.Count() );
2570*b1cdbd2cSJim Jagielski
2571*b1cdbd2cSJim Jagielski // Der Node wird vom Undo verwaltet und ggf. zerstoert!
2572*b1cdbd2cSJim Jagielski /* delete */ aEditDoc.Remove( nPara );
2573*b1cdbd2cSJim Jagielski GetParaPortions().Remove( nPara );
2574*b1cdbd2cSJim Jagielski delete pPortion;
2575*b1cdbd2cSJim Jagielski
2576*b1cdbd2cSJim Jagielski if ( IsCallParaInsertedOrDeleted() )
2577*b1cdbd2cSJim Jagielski {
2578*b1cdbd2cSJim Jagielski GetEditEnginePtr()->ParagraphDeleted( nPara );
2579*b1cdbd2cSJim Jagielski }
2580*b1cdbd2cSJim Jagielski
2581*b1cdbd2cSJim Jagielski // Im folgenden muss ggf. Extra-Space neu ermittelt werden.
2582*b1cdbd2cSJim Jagielski // Bei ParaAttribsChanged wird leider der Absatz neu formatiert,
2583*b1cdbd2cSJim Jagielski // aber diese Methode sollte nicht Zeitkritsch sein!
2584*b1cdbd2cSJim Jagielski if ( pNextNode )
2585*b1cdbd2cSJim Jagielski ParaAttribsChanged( pNextNode );
2586*b1cdbd2cSJim Jagielski
2587*b1cdbd2cSJim Jagielski #ifndef SVX_LIGHT
2588*b1cdbd2cSJim Jagielski if ( IsUndoEnabled() && !IsInUndo() )
2589*b1cdbd2cSJim Jagielski InsertUndo( new EditUndoDelContent( this, pNode, nPara ) );
2590*b1cdbd2cSJim Jagielski else
2591*b1cdbd2cSJim Jagielski #endif
2592*b1cdbd2cSJim Jagielski {
2593*b1cdbd2cSJim Jagielski aEditDoc.RemoveItemsFromPool( pNode );
2594*b1cdbd2cSJim Jagielski if ( pNode->GetStyleSheet() )
2595*b1cdbd2cSJim Jagielski EndListening( *pNode->GetStyleSheet(), sal_False );
2596*b1cdbd2cSJim Jagielski delete pNode;
2597*b1cdbd2cSJim Jagielski }
2598*b1cdbd2cSJim Jagielski }
2599*b1cdbd2cSJim Jagielski
AutoCorrect(const EditSelection & rCurSel,xub_Unicode c,sal_Bool bOverwrite)2600*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::AutoCorrect( const EditSelection& rCurSel, xub_Unicode c, sal_Bool bOverwrite )
2601*b1cdbd2cSJim Jagielski {
2602*b1cdbd2cSJim Jagielski EditSelection aSel( rCurSel );
2603*b1cdbd2cSJim Jagielski #ifndef SVX_LIGHT
2604*b1cdbd2cSJim Jagielski SvxAutoCorrect* pAutoCorrect = SvxAutoCorrCfg::Get()->GetAutoCorrect();
2605*b1cdbd2cSJim Jagielski if ( pAutoCorrect )
2606*b1cdbd2cSJim Jagielski {
2607*b1cdbd2cSJim Jagielski if ( aSel.HasRange() )
2608*b1cdbd2cSJim Jagielski aSel = ImpDeleteSelection( rCurSel );
2609*b1cdbd2cSJim Jagielski
2610*b1cdbd2cSJim Jagielski // #i78661 allow application to turn off capitalization of
2611*b1cdbd2cSJim Jagielski // start sentence explicitly.
2612*b1cdbd2cSJim Jagielski // (This is done by setting IsFirstWordCapitalization to sal_False.)
2613*b1cdbd2cSJim Jagielski sal_Bool bOldCptlSttSntnc = pAutoCorrect->IsAutoCorrFlag( CptlSttSntnc );
2614*b1cdbd2cSJim Jagielski if (!IsFirstWordCapitalization())
2615*b1cdbd2cSJim Jagielski {
2616*b1cdbd2cSJim Jagielski ESelection aESel( CreateESel(aSel) );
2617*b1cdbd2cSJim Jagielski EditSelection aFirstWordSel;
2618*b1cdbd2cSJim Jagielski EditSelection aSecondWordSel;
2619*b1cdbd2cSJim Jagielski if (aESel.nEndPara == 0) // is this the first para?
2620*b1cdbd2cSJim Jagielski {
2621*b1cdbd2cSJim Jagielski // select first word...
2622*b1cdbd2cSJim Jagielski // start by checking if para starts with word.
2623*b1cdbd2cSJim Jagielski aFirstWordSel = SelectWord( CreateSel(ESelection()) );
2624*b1cdbd2cSJim Jagielski if (aFirstWordSel.Min().GetIndex() == 0 && aFirstWordSel.Max().GetIndex() == 0)
2625*b1cdbd2cSJim Jagielski {
2626*b1cdbd2cSJim Jagielski // para does not start with word -> select next/first word
2627*b1cdbd2cSJim Jagielski EditPaM aRightWord( WordRight( aFirstWordSel.Max(), 1 ) );
2628*b1cdbd2cSJim Jagielski aFirstWordSel = SelectWord( EditSelection( aRightWord ) );
2629*b1cdbd2cSJim Jagielski }
2630*b1cdbd2cSJim Jagielski
2631*b1cdbd2cSJim Jagielski // select second word
2632*b1cdbd2cSJim Jagielski // (sometimes aSel mightnot point to the end of the first word
2633*b1cdbd2cSJim Jagielski // but to some following char like '.'. ':', ...
2634*b1cdbd2cSJim Jagielski // In those cases we need aSecondWordSel to see if aSel
2635*b1cdbd2cSJim Jagielski // will actually effect the first word.)
2636*b1cdbd2cSJim Jagielski EditPaM aRight2Word( WordRight( aFirstWordSel.Max(), 1 ) );
2637*b1cdbd2cSJim Jagielski aSecondWordSel = SelectWord( EditSelection( aRight2Word ) );
2638*b1cdbd2cSJim Jagielski }
2639*b1cdbd2cSJim Jagielski sal_Bool bIsFirstWordInFirstPara = aESel.nEndPara == 0 &&
2640*b1cdbd2cSJim Jagielski aFirstWordSel.Max().GetIndex() <= aSel.Max().GetIndex() &&
2641*b1cdbd2cSJim Jagielski aSel.Max().GetIndex() <= aSecondWordSel.Min().GetIndex();
2642*b1cdbd2cSJim Jagielski
2643*b1cdbd2cSJim Jagielski if (bIsFirstWordInFirstPara)
2644*b1cdbd2cSJim Jagielski pAutoCorrect->SetAutoCorrFlag( CptlSttSntnc, IsFirstWordCapitalization() );
2645*b1cdbd2cSJim Jagielski }
2646*b1cdbd2cSJim Jagielski
2647*b1cdbd2cSJim Jagielski ContentNode* pNode = aSel.Max().GetNode();
2648*b1cdbd2cSJim Jagielski sal_uInt16 nIndex = aSel.Max().GetIndex();
2649*b1cdbd2cSJim Jagielski EdtAutoCorrDoc aAuto( this, pNode, nIndex, c );
2650*b1cdbd2cSJim Jagielski pAutoCorrect->AutoCorrect( aAuto, *pNode, nIndex, c, !bOverwrite );
2651*b1cdbd2cSJim Jagielski aSel.Max().SetIndex( aAuto.GetCursor() );
2652*b1cdbd2cSJim Jagielski
2653*b1cdbd2cSJim Jagielski // #i78661 since the SvxAutoCorrect object used here is
2654*b1cdbd2cSJim Jagielski // shared we need to reset the value to it's original state.
2655*b1cdbd2cSJim Jagielski pAutoCorrect->SetAutoCorrFlag( CptlSttSntnc, bOldCptlSttSntnc );
2656*b1cdbd2cSJim Jagielski }
2657*b1cdbd2cSJim Jagielski #endif // !SVX_LIGHT
2658*b1cdbd2cSJim Jagielski return aSel.Max();
2659*b1cdbd2cSJim Jagielski }
2660*b1cdbd2cSJim Jagielski
2661*b1cdbd2cSJim Jagielski
InsertText(const EditSelection & rCurSel,xub_Unicode c,sal_Bool bOverwrite,sal_Bool bIsUserInput)2662*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::InsertText( const EditSelection& rCurSel,
2663*b1cdbd2cSJim Jagielski xub_Unicode c, sal_Bool bOverwrite, sal_Bool bIsUserInput )
2664*b1cdbd2cSJim Jagielski {
2665*b1cdbd2cSJim Jagielski DBG_ASSERT( c != '\t', "Tab bei InsertText ?" );
2666*b1cdbd2cSJim Jagielski DBG_ASSERT( c != '\n', "Zeilenumbruch bei InsertText ?" );
2667*b1cdbd2cSJim Jagielski
2668*b1cdbd2cSJim Jagielski EditPaM aPaM( rCurSel.Min() );
2669*b1cdbd2cSJim Jagielski
2670*b1cdbd2cSJim Jagielski sal_Bool bDoOverwrite = ( bOverwrite &&
2671*b1cdbd2cSJim Jagielski ( aPaM.GetIndex() < aPaM.GetNode()->Len() ) ) ? sal_True : sal_False;
2672*b1cdbd2cSJim Jagielski
2673*b1cdbd2cSJim Jagielski sal_Bool bUndoAction = ( rCurSel.HasRange() || bDoOverwrite );
2674*b1cdbd2cSJim Jagielski
2675*b1cdbd2cSJim Jagielski if ( bUndoAction )
2676*b1cdbd2cSJim Jagielski UndoActionStart( EDITUNDO_INSERT );
2677*b1cdbd2cSJim Jagielski
2678*b1cdbd2cSJim Jagielski if ( rCurSel.HasRange() )
2679*b1cdbd2cSJim Jagielski {
2680*b1cdbd2cSJim Jagielski aPaM = ImpDeleteSelection( rCurSel );
2681*b1cdbd2cSJim Jagielski }
2682*b1cdbd2cSJim Jagielski else if ( bDoOverwrite )
2683*b1cdbd2cSJim Jagielski {
2684*b1cdbd2cSJim Jagielski // Wenn Selektion, dann nicht auch noch ein Zeichen ueberschreiben!
2685*b1cdbd2cSJim Jagielski EditSelection aTmpSel( aPaM );
2686*b1cdbd2cSJim Jagielski aTmpSel.Max().GetIndex()++;
2687*b1cdbd2cSJim Jagielski DBG_ASSERT( !aTmpSel.DbgIsBuggy( aEditDoc ), "Overwrite: Fehlerhafte Selektion!" );
2688*b1cdbd2cSJim Jagielski ImpDeleteSelection( aTmpSel );
2689*b1cdbd2cSJim Jagielski }
2690*b1cdbd2cSJim Jagielski
2691*b1cdbd2cSJim Jagielski if ( aPaM.GetNode()->Len() < MAXCHARSINPARA )
2692*b1cdbd2cSJim Jagielski {
2693*b1cdbd2cSJim Jagielski if (bIsUserInput && IsInputSequenceCheckingRequired( c, rCurSel ))
2694*b1cdbd2cSJim Jagielski {
2695*b1cdbd2cSJim Jagielski uno::Reference < i18n::XExtendedInputSequenceChecker > _xISC( ImplGetInputSequenceChecker() );
2696*b1cdbd2cSJim Jagielski if (!pCTLOptions)
2697*b1cdbd2cSJim Jagielski pCTLOptions = new SvtCTLOptions;
2698*b1cdbd2cSJim Jagielski
2699*b1cdbd2cSJim Jagielski if (_xISC.is() || pCTLOptions)
2700*b1cdbd2cSJim Jagielski {
2701*b1cdbd2cSJim Jagielski xub_StrLen nTmpPos = aPaM.GetIndex();
2702*b1cdbd2cSJim Jagielski sal_Int16 nCheckMode = pCTLOptions->IsCTLSequenceCheckingRestricted() ?
2703*b1cdbd2cSJim Jagielski i18n::InputSequenceCheckMode::STRICT : i18n::InputSequenceCheckMode::BASIC;
2704*b1cdbd2cSJim Jagielski
2705*b1cdbd2cSJim Jagielski // the text that needs to be checked is only the one
2706*b1cdbd2cSJim Jagielski // before the current cursor position
2707*b1cdbd2cSJim Jagielski rtl::OUString aOldText( aPaM.GetNode()->Copy(0, nTmpPos) );
2708*b1cdbd2cSJim Jagielski rtl::OUString aNewText( aOldText );
2709*b1cdbd2cSJim Jagielski if (pCTLOptions->IsCTLSequenceCheckingTypeAndReplace())
2710*b1cdbd2cSJim Jagielski {
2711*b1cdbd2cSJim Jagielski /*const xub_StrLen nPrevPos = static_cast< xub_StrLen >*/( _xISC->correctInputSequence( aNewText, nTmpPos - 1, c, nCheckMode ) );
2712*b1cdbd2cSJim Jagielski
2713*b1cdbd2cSJim Jagielski // find position of first character that has changed
2714*b1cdbd2cSJim Jagielski sal_Int32 nOldLen = aOldText.getLength();
2715*b1cdbd2cSJim Jagielski sal_Int32 nNewLen = aNewText.getLength();
2716*b1cdbd2cSJim Jagielski const sal_Unicode *pOldTxt = aOldText.getStr();
2717*b1cdbd2cSJim Jagielski const sal_Unicode *pNewTxt = aNewText.getStr();
2718*b1cdbd2cSJim Jagielski sal_Int32 nChgPos = 0;
2719*b1cdbd2cSJim Jagielski while ( nChgPos < nOldLen && nChgPos < nNewLen &&
2720*b1cdbd2cSJim Jagielski pOldTxt[nChgPos] == pNewTxt[nChgPos] )
2721*b1cdbd2cSJim Jagielski ++nChgPos;
2722*b1cdbd2cSJim Jagielski
2723*b1cdbd2cSJim Jagielski xub_StrLen nChgLen = static_cast< xub_StrLen >( nNewLen - nChgPos );
2724*b1cdbd2cSJim Jagielski String aChgText( aNewText.copy( nChgPos ).getStr(), nChgLen );
2725*b1cdbd2cSJim Jagielski
2726*b1cdbd2cSJim Jagielski // select text from first pos to be changed to current pos
2727*b1cdbd2cSJim Jagielski EditSelection aSel( EditPaM( aPaM.GetNode(), (sal_uInt16) nChgPos ), aPaM );
2728*b1cdbd2cSJim Jagielski
2729*b1cdbd2cSJim Jagielski if (aChgText.Len())
2730*b1cdbd2cSJim Jagielski return InsertText( aSel, aChgText ); // implicitly handles undo
2731*b1cdbd2cSJim Jagielski else
2732*b1cdbd2cSJim Jagielski return aPaM;
2733*b1cdbd2cSJim Jagielski }
2734*b1cdbd2cSJim Jagielski else
2735*b1cdbd2cSJim Jagielski {
2736*b1cdbd2cSJim Jagielski // should the character be ignored (i.e. not get inserted) ?
2737*b1cdbd2cSJim Jagielski if (!_xISC->checkInputSequence( aOldText, nTmpPos - 1, c, nCheckMode ))
2738*b1cdbd2cSJim Jagielski return aPaM; // nothing to be done -> no need for undo
2739*b1cdbd2cSJim Jagielski }
2740*b1cdbd2cSJim Jagielski }
2741*b1cdbd2cSJim Jagielski
2742*b1cdbd2cSJim Jagielski // at this point now we will insert the character 'normally' some lines below...
2743*b1cdbd2cSJim Jagielski }
2744*b1cdbd2cSJim Jagielski
2745*b1cdbd2cSJim Jagielski if ( IsUndoEnabled() && !IsInUndo() )
2746*b1cdbd2cSJim Jagielski {
2747*b1cdbd2cSJim Jagielski EditUndoInsertChars* pNewUndo = new EditUndoInsertChars( this, CreateEPaM( aPaM ), c );
2748*b1cdbd2cSJim Jagielski sal_Bool bTryMerge = ( !bDoOverwrite && ( c != ' ' ) ) ? sal_True : sal_False;
2749*b1cdbd2cSJim Jagielski InsertUndo( pNewUndo, bTryMerge );
2750*b1cdbd2cSJim Jagielski }
2751*b1cdbd2cSJim Jagielski
2752*b1cdbd2cSJim Jagielski aEditDoc.InsertText( (const EditPaM&)aPaM, c );
2753*b1cdbd2cSJim Jagielski ParaPortion* pPortion = FindParaPortion( aPaM.GetNode() );
2754*b1cdbd2cSJim Jagielski DBG_ASSERT( pPortion, "Blinde Portion in InsertText" );
2755*b1cdbd2cSJim Jagielski pPortion->MarkInvalid( aPaM.GetIndex(), 1 );
2756*b1cdbd2cSJim Jagielski aPaM.GetIndex()++; // macht EditDoc-Methode nicht mehr
2757*b1cdbd2cSJim Jagielski }
2758*b1cdbd2cSJim Jagielski
2759*b1cdbd2cSJim Jagielski TextModified();
2760*b1cdbd2cSJim Jagielski
2761*b1cdbd2cSJim Jagielski if ( bUndoAction )
2762*b1cdbd2cSJim Jagielski UndoActionEnd( EDITUNDO_INSERT );
2763*b1cdbd2cSJim Jagielski
2764*b1cdbd2cSJim Jagielski return aPaM;
2765*b1cdbd2cSJim Jagielski }
2766*b1cdbd2cSJim Jagielski
ImpInsertText(EditSelection aCurSel,const XubString & rStr)2767*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::ImpInsertText( EditSelection aCurSel, const XubString& rStr )
2768*b1cdbd2cSJim Jagielski {
2769*b1cdbd2cSJim Jagielski UndoActionStart( EDITUNDO_INSERT );
2770*b1cdbd2cSJim Jagielski
2771*b1cdbd2cSJim Jagielski EditPaM aPaM;
2772*b1cdbd2cSJim Jagielski if ( aCurSel.HasRange() )
2773*b1cdbd2cSJim Jagielski aPaM = ImpDeleteSelection( aCurSel );
2774*b1cdbd2cSJim Jagielski else
2775*b1cdbd2cSJim Jagielski aPaM = aCurSel.Max();
2776*b1cdbd2cSJim Jagielski
2777*b1cdbd2cSJim Jagielski EditPaM aCurPaM( aPaM ); // fuers Invalidieren
2778*b1cdbd2cSJim Jagielski
2779*b1cdbd2cSJim Jagielski // get word boundaries in order to clear possible WrongList entries
2780*b1cdbd2cSJim Jagielski // and invalidate all the necessary text (everything after and including the
2781*b1cdbd2cSJim Jagielski // start of the word)
2782*b1cdbd2cSJim Jagielski // #i107201# do the expensive SelectWord call only if online spelling is active
2783*b1cdbd2cSJim Jagielski EditSelection aCurWord;
2784*b1cdbd2cSJim Jagielski if ( GetStatus().DoOnlineSpelling() )
2785*b1cdbd2cSJim Jagielski aCurWord = SelectWord( aCurPaM, i18n::WordType::DICTIONARY_WORD );
2786*b1cdbd2cSJim Jagielski
2787*b1cdbd2cSJim Jagielski XubString aText( rStr );
2788*b1cdbd2cSJim Jagielski aText.ConvertLineEnd( LINEEND_LF );
2789*b1cdbd2cSJim Jagielski SfxVoidItem aTabItem( EE_FEATURE_TAB );
2790*b1cdbd2cSJim Jagielski
2791*b1cdbd2cSJim Jagielski // Konvertiert nach LineSep = \n
2792*b1cdbd2cSJim Jagielski // Token mit LINE_SEP abfragen,
2793*b1cdbd2cSJim Jagielski // da der MAC-Compiler aus \n etwas anderes macht!
2794*b1cdbd2cSJim Jagielski
2795*b1cdbd2cSJim Jagielski // #117400
2796*b1cdbd2cSJim Jagielski // The loop run variable must be capable to hold STRLEN_MAX+1,
2797*b1cdbd2cSJim Jagielski // that with STRING32 would be SAL_MAX_INT32+1 but with 16-bit is 0xFFFF+1
2798*b1cdbd2cSJim Jagielski sal_uInt32 nStart = 0;
2799*b1cdbd2cSJim Jagielski while ( nStart < aText.Len() )
2800*b1cdbd2cSJim Jagielski {
2801*b1cdbd2cSJim Jagielski sal_uInt32 nEnd = aText.Search( LINE_SEP, static_cast<xub_StrLen>(nStart) );
2802*b1cdbd2cSJim Jagielski if ( nEnd == STRING_NOTFOUND )
2803*b1cdbd2cSJim Jagielski nEnd = aText.Len(); // nicht dereferenzieren!
2804*b1cdbd2cSJim Jagielski
2805*b1cdbd2cSJim Jagielski // Start == End => Leerzeile
2806*b1cdbd2cSJim Jagielski if ( nEnd > nStart )
2807*b1cdbd2cSJim Jagielski {
2808*b1cdbd2cSJim Jagielski XubString aLine( aText, nStart, static_cast<xub_StrLen>(nEnd-nStart) );
2809*b1cdbd2cSJim Jagielski xub_StrLen nChars = aPaM.GetNode()->Len() + aLine.Len();
2810*b1cdbd2cSJim Jagielski if ( nChars > MAXCHARSINPARA )
2811*b1cdbd2cSJim Jagielski {
2812*b1cdbd2cSJim Jagielski xub_StrLen nMaxNewChars = MAXCHARSINPARA-aPaM.GetNode()->Len();
2813*b1cdbd2cSJim Jagielski nEnd -= ( aLine.Len() - nMaxNewChars ); // Dann landen die Zeichen im naechsten Absatz.
2814*b1cdbd2cSJim Jagielski aLine.Erase( nMaxNewChars ); // Del Rest...
2815*b1cdbd2cSJim Jagielski }
2816*b1cdbd2cSJim Jagielski #ifndef SVX_LIGHT
2817*b1cdbd2cSJim Jagielski if ( IsUndoEnabled() && !IsInUndo() )
2818*b1cdbd2cSJim Jagielski InsertUndo( new EditUndoInsertChars( this, CreateEPaM( aPaM ), aLine ) );
2819*b1cdbd2cSJim Jagielski #endif
2820*b1cdbd2cSJim Jagielski // Tabs ?
2821*b1cdbd2cSJim Jagielski if ( aLine.Search( '\t' ) == STRING_NOTFOUND )
2822*b1cdbd2cSJim Jagielski aPaM = aEditDoc.InsertText( aPaM, aLine );
2823*b1cdbd2cSJim Jagielski else
2824*b1cdbd2cSJim Jagielski {
2825*b1cdbd2cSJim Jagielski sal_uInt32 nStart2 = 0;
2826*b1cdbd2cSJim Jagielski while ( nStart2 < aLine.Len() )
2827*b1cdbd2cSJim Jagielski {
2828*b1cdbd2cSJim Jagielski sal_uInt32 nEnd2 = aLine.Search( '\t', static_cast<xub_StrLen>(nStart2) );
2829*b1cdbd2cSJim Jagielski if ( nEnd2 == STRING_NOTFOUND )
2830*b1cdbd2cSJim Jagielski nEnd2 = aLine.Len(); // nicht dereferenzieren!
2831*b1cdbd2cSJim Jagielski
2832*b1cdbd2cSJim Jagielski if ( nEnd2 > nStart2 )
2833*b1cdbd2cSJim Jagielski aPaM = aEditDoc.InsertText( aPaM, XubString( aLine,
2834*b1cdbd2cSJim Jagielski static_cast<xub_StrLen>(nStart2),
2835*b1cdbd2cSJim Jagielski static_cast<xub_StrLen>(nEnd2-nStart2 ) ) );
2836*b1cdbd2cSJim Jagielski if ( nEnd2 < aLine.Len() )
2837*b1cdbd2cSJim Jagielski {
2838*b1cdbd2cSJim Jagielski // aPaM = ImpInsertFeature( EditSelection( aPaM, aPaM ), );
2839*b1cdbd2cSJim Jagielski aPaM = aEditDoc.InsertFeature( aPaM, aTabItem );
2840*b1cdbd2cSJim Jagielski }
2841*b1cdbd2cSJim Jagielski nStart2 = nEnd2+1;
2842*b1cdbd2cSJim Jagielski }
2843*b1cdbd2cSJim Jagielski }
2844*b1cdbd2cSJim Jagielski ParaPortion* pPortion = FindParaPortion( aPaM.GetNode() );
2845*b1cdbd2cSJim Jagielski DBG_ASSERT( pPortion, "Blinde Portion in InsertText" );
2846*b1cdbd2cSJim Jagielski
2847*b1cdbd2cSJim Jagielski if ( GetStatus().DoOnlineSpelling() )
2848*b1cdbd2cSJim Jagielski {
2849*b1cdbd2cSJim Jagielski // now remove the Wrongs (red spell check marks) from both words...
2850*b1cdbd2cSJim Jagielski WrongList *pWrongs = aCurPaM.GetNode()->GetWrongList();
2851*b1cdbd2cSJim Jagielski if (pWrongs && pWrongs->HasWrongs())
2852*b1cdbd2cSJim Jagielski pWrongs->ClearWrongs( aCurWord.Min().GetIndex(), aPaM.GetIndex(), aPaM.GetNode() );
2853*b1cdbd2cSJim Jagielski // ... and mark both words as 'to be checked again'
2854*b1cdbd2cSJim Jagielski pPortion->MarkInvalid( aCurWord.Min().GetIndex(), aLine.Len() );
2855*b1cdbd2cSJim Jagielski }
2856*b1cdbd2cSJim Jagielski else
2857*b1cdbd2cSJim Jagielski pPortion->MarkInvalid( aCurPaM.GetIndex(), aLine.Len() );
2858*b1cdbd2cSJim Jagielski }
2859*b1cdbd2cSJim Jagielski if ( nEnd < aText.Len() )
2860*b1cdbd2cSJim Jagielski aPaM = ImpInsertParaBreak( aPaM );
2861*b1cdbd2cSJim Jagielski
2862*b1cdbd2cSJim Jagielski nStart = nEnd+1;
2863*b1cdbd2cSJim Jagielski }
2864*b1cdbd2cSJim Jagielski
2865*b1cdbd2cSJim Jagielski UndoActionEnd( EDITUNDO_INSERT );
2866*b1cdbd2cSJim Jagielski
2867*b1cdbd2cSJim Jagielski TextModified();
2868*b1cdbd2cSJim Jagielski return aPaM;
2869*b1cdbd2cSJim Jagielski }
2870*b1cdbd2cSJim Jagielski
ImpFastInsertText(EditPaM aPaM,const XubString & rStr)2871*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::ImpFastInsertText( EditPaM aPaM, const XubString& rStr )
2872*b1cdbd2cSJim Jagielski {
2873*b1cdbd2cSJim Jagielski DBG_ASSERT( rStr.Search( 0x0A ) == STRING_NOTFOUND, "FastInsertText: Zeilentrenner nicht erlaubt!" );
2874*b1cdbd2cSJim Jagielski DBG_ASSERT( rStr.Search( 0x0D ) == STRING_NOTFOUND, "FastInsertText: Zeilentrenner nicht erlaubt!" );
2875*b1cdbd2cSJim Jagielski DBG_ASSERT( rStr.Search( '\t' ) == STRING_NOTFOUND, "FastInsertText: Features nicht erlaubt!" );
2876*b1cdbd2cSJim Jagielski
2877*b1cdbd2cSJim Jagielski if ( ( aPaM.GetNode()->Len() + rStr.Len() ) < MAXCHARSINPARA )
2878*b1cdbd2cSJim Jagielski {
2879*b1cdbd2cSJim Jagielski #ifndef SVX_LIGHT
2880*b1cdbd2cSJim Jagielski if ( IsUndoEnabled() && !IsInUndo() )
2881*b1cdbd2cSJim Jagielski InsertUndo( new EditUndoInsertChars( this, CreateEPaM( aPaM ), rStr ) );
2882*b1cdbd2cSJim Jagielski #endif
2883*b1cdbd2cSJim Jagielski
2884*b1cdbd2cSJim Jagielski aPaM = aEditDoc.InsertText( aPaM, rStr );
2885*b1cdbd2cSJim Jagielski TextModified();
2886*b1cdbd2cSJim Jagielski }
2887*b1cdbd2cSJim Jagielski else
2888*b1cdbd2cSJim Jagielski {
2889*b1cdbd2cSJim Jagielski aPaM = ImpInsertText( aPaM, rStr );
2890*b1cdbd2cSJim Jagielski }
2891*b1cdbd2cSJim Jagielski
2892*b1cdbd2cSJim Jagielski return aPaM;
2893*b1cdbd2cSJim Jagielski }
2894*b1cdbd2cSJim Jagielski
ImpInsertFeature(EditSelection aCurSel,const SfxPoolItem & rItem)2895*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::ImpInsertFeature( EditSelection aCurSel, const SfxPoolItem& rItem )
2896*b1cdbd2cSJim Jagielski {
2897*b1cdbd2cSJim Jagielski EditPaM aPaM;
2898*b1cdbd2cSJim Jagielski if ( aCurSel.HasRange() )
2899*b1cdbd2cSJim Jagielski aPaM = ImpDeleteSelection( aCurSel );
2900*b1cdbd2cSJim Jagielski else
2901*b1cdbd2cSJim Jagielski aPaM = aCurSel.Max();
2902*b1cdbd2cSJim Jagielski
2903*b1cdbd2cSJim Jagielski if ( aPaM.GetIndex() >= 0xfffe )
2904*b1cdbd2cSJim Jagielski return aPaM;
2905*b1cdbd2cSJim Jagielski
2906*b1cdbd2cSJim Jagielski #ifndef SVX_LIGHT
2907*b1cdbd2cSJim Jagielski if ( IsUndoEnabled() && !IsInUndo() )
2908*b1cdbd2cSJim Jagielski InsertUndo( new EditUndoInsertFeature( this, CreateEPaM( aPaM ), rItem ) );
2909*b1cdbd2cSJim Jagielski #endif
2910*b1cdbd2cSJim Jagielski aPaM = aEditDoc.InsertFeature( aPaM, rItem );
2911*b1cdbd2cSJim Jagielski
2912*b1cdbd2cSJim Jagielski ParaPortion* pPortion = FindParaPortion( aPaM.GetNode() );
2913*b1cdbd2cSJim Jagielski DBG_ASSERT( pPortion, "Blinde Portion in InsertFeature" );
2914*b1cdbd2cSJim Jagielski pPortion->MarkInvalid( aPaM.GetIndex()-1, 1 );
2915*b1cdbd2cSJim Jagielski
2916*b1cdbd2cSJim Jagielski TextModified();
2917*b1cdbd2cSJim Jagielski
2918*b1cdbd2cSJim Jagielski return aPaM;
2919*b1cdbd2cSJim Jagielski }
2920*b1cdbd2cSJim Jagielski
ImpInsertParaBreak(const EditSelection & rCurSel,sal_Bool bKeepEndingAttribs)2921*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::ImpInsertParaBreak( const EditSelection& rCurSel, sal_Bool bKeepEndingAttribs )
2922*b1cdbd2cSJim Jagielski {
2923*b1cdbd2cSJim Jagielski EditPaM aPaM;
2924*b1cdbd2cSJim Jagielski if ( rCurSel.HasRange() )
2925*b1cdbd2cSJim Jagielski aPaM = ImpDeleteSelection( rCurSel );
2926*b1cdbd2cSJim Jagielski else
2927*b1cdbd2cSJim Jagielski aPaM = rCurSel.Max();
2928*b1cdbd2cSJim Jagielski
2929*b1cdbd2cSJim Jagielski return ImpInsertParaBreak( aPaM, bKeepEndingAttribs );
2930*b1cdbd2cSJim Jagielski }
2931*b1cdbd2cSJim Jagielski
ImpInsertParaBreak(const EditPaM & rPaM,sal_Bool bKeepEndingAttribs)2932*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::ImpInsertParaBreak( const EditPaM& rPaM, sal_Bool bKeepEndingAttribs )
2933*b1cdbd2cSJim Jagielski {
2934*b1cdbd2cSJim Jagielski if ( aEditDoc.Count() >= 0xFFFE )
2935*b1cdbd2cSJim Jagielski {
2936*b1cdbd2cSJim Jagielski DBG_ERROR( "Can't process more than 64K paragraphs!" );
2937*b1cdbd2cSJim Jagielski return rPaM;
2938*b1cdbd2cSJim Jagielski }
2939*b1cdbd2cSJim Jagielski
2940*b1cdbd2cSJim Jagielski #ifndef SVX_LIGHT
2941*b1cdbd2cSJim Jagielski if ( IsUndoEnabled() && !IsInUndo() )
2942*b1cdbd2cSJim Jagielski InsertUndo( new EditUndoSplitPara( this, aEditDoc.GetPos( rPaM.GetNode() ), rPaM.GetIndex() ) );
2943*b1cdbd2cSJim Jagielski #endif
2944*b1cdbd2cSJim Jagielski
2945*b1cdbd2cSJim Jagielski EditPaM aPaM( aEditDoc.InsertParaBreak( rPaM, bKeepEndingAttribs ) );
2946*b1cdbd2cSJim Jagielski
2947*b1cdbd2cSJim Jagielski #ifndef SVX_LIGHT
2948*b1cdbd2cSJim Jagielski if ( GetStatus().DoOnlineSpelling() )
2949*b1cdbd2cSJim Jagielski {
2950*b1cdbd2cSJim Jagielski xub_StrLen nEnd = rPaM.GetNode()->Len();
2951*b1cdbd2cSJim Jagielski aPaM.GetNode()->CreateWrongList();
2952*b1cdbd2cSJim Jagielski WrongList* pLWrongs = rPaM.GetNode()->GetWrongList();
2953*b1cdbd2cSJim Jagielski WrongList* pRWrongs = aPaM.GetNode()->GetWrongList();
2954*b1cdbd2cSJim Jagielski // Falschgeschriebene Woerter ruebernehmen:
2955*b1cdbd2cSJim Jagielski sal_uInt16 nLWrongs = pLWrongs->Count();
2956*b1cdbd2cSJim Jagielski for ( sal_uInt16 nW = 0; nW < nLWrongs; nW++ )
2957*b1cdbd2cSJim Jagielski {
2958*b1cdbd2cSJim Jagielski WrongRange& rWrong = pLWrongs->GetObject( nW );
2959*b1cdbd2cSJim Jagielski // Nur wenn wirklich dahinter, ein ueberlappendes wird beim Spell korrigiert
2960*b1cdbd2cSJim Jagielski if ( rWrong.nStart > nEnd )
2961*b1cdbd2cSJim Jagielski {
2962*b1cdbd2cSJim Jagielski pRWrongs->InsertWrong( rWrong, pRWrongs->Count() );
2963*b1cdbd2cSJim Jagielski WrongRange& rRWrong = pRWrongs->GetObject( pRWrongs->Count() - 1 );
2964*b1cdbd2cSJim Jagielski rRWrong.nStart = rRWrong.nStart - nEnd;
2965*b1cdbd2cSJim Jagielski rRWrong.nEnd = rRWrong.nEnd - nEnd;
2966*b1cdbd2cSJim Jagielski }
2967*b1cdbd2cSJim Jagielski else if ( ( rWrong.nStart < nEnd ) && ( rWrong.nEnd > nEnd ) )
2968*b1cdbd2cSJim Jagielski rWrong.nEnd = nEnd;
2969*b1cdbd2cSJim Jagielski }
2970*b1cdbd2cSJim Jagielski sal_uInt16 nInv = nEnd ? nEnd-1 : nEnd;
2971*b1cdbd2cSJim Jagielski if ( nEnd )
2972*b1cdbd2cSJim Jagielski pLWrongs->MarkInvalid( nInv, nEnd );
2973*b1cdbd2cSJim Jagielski else
2974*b1cdbd2cSJim Jagielski pLWrongs->SetValid();
2975*b1cdbd2cSJim Jagielski pRWrongs->SetValid(); // sonst 0 - 0xFFFF
2976*b1cdbd2cSJim Jagielski pRWrongs->MarkInvalid( 0, 1 ); // Nur das erste Wort testen
2977*b1cdbd2cSJim Jagielski }
2978*b1cdbd2cSJim Jagielski #endif // !SVX_LIGHT
2979*b1cdbd2cSJim Jagielski
2980*b1cdbd2cSJim Jagielski
2981*b1cdbd2cSJim Jagielski ParaPortion* pPortion = FindParaPortion( rPaM.GetNode() );
2982*b1cdbd2cSJim Jagielski DBG_ASSERT( pPortion, "Blinde Portion in ImpInsertParaBreak" );
2983*b1cdbd2cSJim Jagielski pPortion->MarkInvalid( rPaM.GetIndex(), 0 );
2984*b1cdbd2cSJim Jagielski
2985*b1cdbd2cSJim Jagielski // Optimieren: Nicht unnoetig viele GetPos auf die Listen ansetzen!
2986*b1cdbd2cSJim Jagielski // Hier z.B. bei Undo, aber auch in allen anderen Methoden.
2987*b1cdbd2cSJim Jagielski sal_uInt16 nPos = GetParaPortions().GetPos( pPortion );
2988*b1cdbd2cSJim Jagielski ParaPortion* pNewPortion = new ParaPortion( aPaM.GetNode() );
2989*b1cdbd2cSJim Jagielski GetParaPortions().Insert( pNewPortion, nPos + 1 );
2990*b1cdbd2cSJim Jagielski ParaAttribsChanged( pNewPortion->GetNode() );
2991*b1cdbd2cSJim Jagielski if ( IsCallParaInsertedOrDeleted() )
2992*b1cdbd2cSJim Jagielski GetEditEnginePtr()->ParagraphInserted( nPos+1 );
2993*b1cdbd2cSJim Jagielski
2994*b1cdbd2cSJim Jagielski CursorMoved( rPaM.GetNode() ); // falls leeres Attribut entstanden.
2995*b1cdbd2cSJim Jagielski TextModified();
2996*b1cdbd2cSJim Jagielski return aPaM;
2997*b1cdbd2cSJim Jagielski }
2998*b1cdbd2cSJim Jagielski
ImpFastInsertParagraph(sal_uInt16 nPara)2999*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::ImpFastInsertParagraph( sal_uInt16 nPara )
3000*b1cdbd2cSJim Jagielski {
3001*b1cdbd2cSJim Jagielski #ifndef SVX_LIGHT
3002*b1cdbd2cSJim Jagielski if ( IsUndoEnabled() && !IsInUndo() )
3003*b1cdbd2cSJim Jagielski {
3004*b1cdbd2cSJim Jagielski if ( nPara )
3005*b1cdbd2cSJim Jagielski {
3006*b1cdbd2cSJim Jagielski DBG_ASSERT( aEditDoc.SaveGetObject( nPara-1 ), "FastInsertParagraph: Prev existiert nicht" );
3007*b1cdbd2cSJim Jagielski InsertUndo( new EditUndoSplitPara( this, nPara-1, aEditDoc.GetObject( nPara-1 )->Len() ) );
3008*b1cdbd2cSJim Jagielski }
3009*b1cdbd2cSJim Jagielski else
3010*b1cdbd2cSJim Jagielski InsertUndo( new EditUndoSplitPara( this, 0, 0 ) );
3011*b1cdbd2cSJim Jagielski }
3012*b1cdbd2cSJim Jagielski #endif
3013*b1cdbd2cSJim Jagielski
3014*b1cdbd2cSJim Jagielski ContentNode* pNode = new ContentNode( aEditDoc.GetItemPool() );
3015*b1cdbd2cSJim Jagielski // Falls FlatMode, wird spaeter kein Font eingestellt:
3016*b1cdbd2cSJim Jagielski pNode->GetCharAttribs().GetDefFont() = aEditDoc.GetDefFont();
3017*b1cdbd2cSJim Jagielski
3018*b1cdbd2cSJim Jagielski #ifndef SVX_LIGHT
3019*b1cdbd2cSJim Jagielski if ( GetStatus().DoOnlineSpelling() )
3020*b1cdbd2cSJim Jagielski pNode->CreateWrongList();
3021*b1cdbd2cSJim Jagielski #endif // !SVX_LIGHT
3022*b1cdbd2cSJim Jagielski
3023*b1cdbd2cSJim Jagielski aEditDoc.Insert( pNode, nPara );
3024*b1cdbd2cSJim Jagielski
3025*b1cdbd2cSJim Jagielski ParaPortion* pNewPortion = new ParaPortion( pNode );
3026*b1cdbd2cSJim Jagielski GetParaPortions().Insert( pNewPortion, nPara );
3027*b1cdbd2cSJim Jagielski if ( IsCallParaInsertedOrDeleted() )
3028*b1cdbd2cSJim Jagielski GetEditEnginePtr()->ParagraphInserted( nPara );
3029*b1cdbd2cSJim Jagielski
3030*b1cdbd2cSJim Jagielski return EditPaM( pNode, 0 );
3031*b1cdbd2cSJim Jagielski }
3032*b1cdbd2cSJim Jagielski
InsertParaBreak(EditSelection aCurSel)3033*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::InsertParaBreak( EditSelection aCurSel )
3034*b1cdbd2cSJim Jagielski {
3035*b1cdbd2cSJim Jagielski EditPaM aPaM( ImpInsertParaBreak( aCurSel ) );
3036*b1cdbd2cSJim Jagielski if ( aStatus.DoAutoIndenting() )
3037*b1cdbd2cSJim Jagielski {
3038*b1cdbd2cSJim Jagielski sal_uInt16 nPara = aEditDoc.GetPos( aPaM.GetNode() );
3039*b1cdbd2cSJim Jagielski DBG_ASSERT( nPara > 0, "AutoIndenting: Fehler!" );
3040*b1cdbd2cSJim Jagielski XubString aPrevParaText( GetEditDoc().GetParaAsString( nPara-1 ) );
3041*b1cdbd2cSJim Jagielski sal_uInt16 n = 0;
3042*b1cdbd2cSJim Jagielski while ( ( n < aPrevParaText.Len() ) &&
3043*b1cdbd2cSJim Jagielski ( ( aPrevParaText.GetChar(n) == ' ' ) || ( aPrevParaText.GetChar(n) == '\t' ) ) )
3044*b1cdbd2cSJim Jagielski {
3045*b1cdbd2cSJim Jagielski if ( aPrevParaText.GetChar(n) == '\t' )
3046*b1cdbd2cSJim Jagielski aPaM = ImpInsertFeature( aPaM, SfxVoidItem( EE_FEATURE_TAB ) );
3047*b1cdbd2cSJim Jagielski else
3048*b1cdbd2cSJim Jagielski aPaM = ImpInsertText( aPaM, aPrevParaText.GetChar(n) );
3049*b1cdbd2cSJim Jagielski n++;
3050*b1cdbd2cSJim Jagielski }
3051*b1cdbd2cSJim Jagielski
3052*b1cdbd2cSJim Jagielski }
3053*b1cdbd2cSJim Jagielski return aPaM;
3054*b1cdbd2cSJim Jagielski }
3055*b1cdbd2cSJim Jagielski
InsertTab(EditSelection aCurSel)3056*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::InsertTab( EditSelection aCurSel )
3057*b1cdbd2cSJim Jagielski {
3058*b1cdbd2cSJim Jagielski EditPaM aPaM( ImpInsertFeature( aCurSel, SfxVoidItem( EE_FEATURE_TAB ) ) );
3059*b1cdbd2cSJim Jagielski return aPaM;
3060*b1cdbd2cSJim Jagielski }
3061*b1cdbd2cSJim Jagielski
InsertField(EditSelection aCurSel,const SvxFieldItem & rFld)3062*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::InsertField( EditSelection aCurSel, const SvxFieldItem& rFld )
3063*b1cdbd2cSJim Jagielski {
3064*b1cdbd2cSJim Jagielski EditPaM aPaM( ImpInsertFeature( aCurSel, rFld ) );
3065*b1cdbd2cSJim Jagielski return aPaM;
3066*b1cdbd2cSJim Jagielski }
3067*b1cdbd2cSJim Jagielski
UpdateFields()3068*b1cdbd2cSJim Jagielski sal_Bool ImpEditEngine::UpdateFields()
3069*b1cdbd2cSJim Jagielski {
3070*b1cdbd2cSJim Jagielski sal_Bool bChanges = sal_False;
3071*b1cdbd2cSJim Jagielski sal_uInt16 nParas = GetEditDoc().Count();
3072*b1cdbd2cSJim Jagielski for ( sal_uInt16 nPara = 0; nPara < nParas; nPara++ )
3073*b1cdbd2cSJim Jagielski {
3074*b1cdbd2cSJim Jagielski sal_Bool bChangesInPara = sal_False;
3075*b1cdbd2cSJim Jagielski ContentNode* pNode = GetEditDoc().GetObject( nPara );
3076*b1cdbd2cSJim Jagielski DBG_ASSERT( pNode, "NULL-Pointer im Doc" );
3077*b1cdbd2cSJim Jagielski CharAttribArray& rAttribs = pNode->GetCharAttribs().GetAttribs();
3078*b1cdbd2cSJim Jagielski // sal_uInt16 nAttrs = rAttribs.Count();
3079*b1cdbd2cSJim Jagielski for ( sal_uInt16 nAttr = 0; nAttr < rAttribs.Count(); nAttr++ )
3080*b1cdbd2cSJim Jagielski {
3081*b1cdbd2cSJim Jagielski EditCharAttrib* pAttr = rAttribs[nAttr];
3082*b1cdbd2cSJim Jagielski if ( pAttr->Which() == EE_FEATURE_FIELD )
3083*b1cdbd2cSJim Jagielski {
3084*b1cdbd2cSJim Jagielski EditCharAttribField* pField = (EditCharAttribField*)pAttr;
3085*b1cdbd2cSJim Jagielski EditCharAttribField* pCurrent = new EditCharAttribField( *pField );
3086*b1cdbd2cSJim Jagielski pField->Reset();
3087*b1cdbd2cSJim Jagielski
3088*b1cdbd2cSJim Jagielski if ( aStatus.MarkFields() )
3089*b1cdbd2cSJim Jagielski pField->GetFldColor() = new Color( GetColorConfig().GetColorValue( svtools::WRITERFIELDSHADINGS ).nColor );
3090*b1cdbd2cSJim Jagielski
3091*b1cdbd2cSJim Jagielski XubString aFldValue = GetEditEnginePtr()->CalcFieldValue(
3092*b1cdbd2cSJim Jagielski (const SvxFieldItem&)*pField->GetItem(),
3093*b1cdbd2cSJim Jagielski nPara, pField->GetStart(),
3094*b1cdbd2cSJim Jagielski pField->GetTxtColor(), pField->GetFldColor() );
3095*b1cdbd2cSJim Jagielski pField->GetFieldValue() = aFldValue;
3096*b1cdbd2cSJim Jagielski if ( *pField != *pCurrent )
3097*b1cdbd2cSJim Jagielski {
3098*b1cdbd2cSJim Jagielski bChanges = sal_True;
3099*b1cdbd2cSJim Jagielski bChangesInPara = sal_True;
3100*b1cdbd2cSJim Jagielski }
3101*b1cdbd2cSJim Jagielski delete pCurrent;
3102*b1cdbd2cSJim Jagielski }
3103*b1cdbd2cSJim Jagielski }
3104*b1cdbd2cSJim Jagielski if ( bChangesInPara )
3105*b1cdbd2cSJim Jagielski {
3106*b1cdbd2cSJim Jagielski // ggf. etwas genauer invalidieren.
3107*b1cdbd2cSJim Jagielski ParaPortion* pPortion = GetParaPortions().GetObject( nPara );
3108*b1cdbd2cSJim Jagielski DBG_ASSERT( pPortion, "NULL-Pointer im Doc" );
3109*b1cdbd2cSJim Jagielski pPortion->MarkSelectionInvalid( 0, pNode->Len() );
3110*b1cdbd2cSJim Jagielski }
3111*b1cdbd2cSJim Jagielski }
3112*b1cdbd2cSJim Jagielski return bChanges;
3113*b1cdbd2cSJim Jagielski }
3114*b1cdbd2cSJim Jagielski
InsertLineBreak(EditSelection aCurSel)3115*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::InsertLineBreak( EditSelection aCurSel )
3116*b1cdbd2cSJim Jagielski {
3117*b1cdbd2cSJim Jagielski EditPaM aPaM( ImpInsertFeature( aCurSel, SfxVoidItem( EE_FEATURE_LINEBR ) ) );
3118*b1cdbd2cSJim Jagielski return aPaM;
3119*b1cdbd2cSJim Jagielski }
3120*b1cdbd2cSJim Jagielski
3121*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------
3122*b1cdbd2cSJim Jagielski // Hilfsfunktionen
3123*b1cdbd2cSJim Jagielski // ----------------------------------------------------------------------
PaMtoEditCursor(EditPaM aPaM,sal_uInt16 nFlags)3124*b1cdbd2cSJim Jagielski Rectangle ImpEditEngine::PaMtoEditCursor( EditPaM aPaM, sal_uInt16 nFlags )
3125*b1cdbd2cSJim Jagielski {
3126*b1cdbd2cSJim Jagielski DBG_ASSERT( GetUpdateMode(), "Darf bei Update=sal_False nicht erreicht werden: PaMtoEditCursor" );
3127*b1cdbd2cSJim Jagielski
3128*b1cdbd2cSJim Jagielski Rectangle aEditCursor;
3129*b1cdbd2cSJim Jagielski long nY = 0;
3130*b1cdbd2cSJim Jagielski for ( sal_uInt16 nPortion = 0; nPortion < GetParaPortions().Count(); nPortion++ )
3131*b1cdbd2cSJim Jagielski {
3132*b1cdbd2cSJim Jagielski ParaPortion* pPortion = GetParaPortions().GetObject(nPortion);
3133*b1cdbd2cSJim Jagielski ContentNode* pNode = pPortion->GetNode();
3134*b1cdbd2cSJim Jagielski DBG_ASSERT( pNode, "Ungueltiger Node in Portion!" );
3135*b1cdbd2cSJim Jagielski if ( pNode != aPaM.GetNode() )
3136*b1cdbd2cSJim Jagielski {
3137*b1cdbd2cSJim Jagielski nY += pPortion->GetHeight();
3138*b1cdbd2cSJim Jagielski }
3139*b1cdbd2cSJim Jagielski else
3140*b1cdbd2cSJim Jagielski {
3141*b1cdbd2cSJim Jagielski aEditCursor = GetEditCursor( pPortion, aPaM.GetIndex(), nFlags );
3142*b1cdbd2cSJim Jagielski aEditCursor.Top() += nY;
3143*b1cdbd2cSJim Jagielski aEditCursor.Bottom() += nY;
3144*b1cdbd2cSJim Jagielski return aEditCursor;
3145*b1cdbd2cSJim Jagielski }
3146*b1cdbd2cSJim Jagielski }
3147*b1cdbd2cSJim Jagielski DBG_ERROR( "Portion nicht gefunden!" );
3148*b1cdbd2cSJim Jagielski return aEditCursor;
3149*b1cdbd2cSJim Jagielski }
3150*b1cdbd2cSJim Jagielski
GetPaM(Point aDocPos,sal_Bool bSmart)3151*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::GetPaM( Point aDocPos, sal_Bool bSmart )
3152*b1cdbd2cSJim Jagielski {
3153*b1cdbd2cSJim Jagielski DBG_ASSERT( GetUpdateMode(), "Darf bei Update=sal_False nicht erreicht werden: GetPaM" );
3154*b1cdbd2cSJim Jagielski
3155*b1cdbd2cSJim Jagielski long nY = 0;
3156*b1cdbd2cSJim Jagielski long nTmpHeight;
3157*b1cdbd2cSJim Jagielski EditPaM aPaM;
3158*b1cdbd2cSJim Jagielski sal_uInt16 nPortion;
3159*b1cdbd2cSJim Jagielski for ( nPortion = 0; nPortion < GetParaPortions().Count(); nPortion++ )
3160*b1cdbd2cSJim Jagielski {
3161*b1cdbd2cSJim Jagielski ParaPortion* pPortion = GetParaPortions().GetObject(nPortion);
3162*b1cdbd2cSJim Jagielski nTmpHeight = pPortion->GetHeight(); // sollte auch bei !bVisible richtig sein!
3163*b1cdbd2cSJim Jagielski nY += nTmpHeight;
3164*b1cdbd2cSJim Jagielski if ( nY > aDocPos.Y() )
3165*b1cdbd2cSJim Jagielski {
3166*b1cdbd2cSJim Jagielski nY -= nTmpHeight;
3167*b1cdbd2cSJim Jagielski aDocPos.Y() -= nY;
3168*b1cdbd2cSJim Jagielski // unsichtbare Portions ueberspringen:
3169*b1cdbd2cSJim Jagielski while ( pPortion && !pPortion->IsVisible() )
3170*b1cdbd2cSJim Jagielski {
3171*b1cdbd2cSJim Jagielski nPortion++;
3172*b1cdbd2cSJim Jagielski pPortion = GetParaPortions().SaveGetObject( nPortion );
3173*b1cdbd2cSJim Jagielski }
3174*b1cdbd2cSJim Jagielski DBG_ASSERT( pPortion, "Keinen sichtbaren Absatz gefunden: GetPaM" );
3175*b1cdbd2cSJim Jagielski aPaM = GetPaM( pPortion, aDocPos, bSmart );
3176*b1cdbd2cSJim Jagielski return aPaM;
3177*b1cdbd2cSJim Jagielski
3178*b1cdbd2cSJim Jagielski }
3179*b1cdbd2cSJim Jagielski }
3180*b1cdbd2cSJim Jagielski // Dann den letzten sichtbaren Suchen:
3181*b1cdbd2cSJim Jagielski nPortion = GetParaPortions().Count()-1;
3182*b1cdbd2cSJim Jagielski while ( nPortion && !GetParaPortions()[nPortion]->IsVisible() )
3183*b1cdbd2cSJim Jagielski nPortion--;
3184*b1cdbd2cSJim Jagielski
3185*b1cdbd2cSJim Jagielski DBG_ASSERT( GetParaPortions()[nPortion]->IsVisible(), "Keinen sichtbaren Absatz gefunden: GetPaM" );
3186*b1cdbd2cSJim Jagielski aPaM.SetNode( GetParaPortions()[nPortion]->GetNode() );
3187*b1cdbd2cSJim Jagielski aPaM.SetIndex( GetParaPortions()[nPortion]->GetNode()->Len() );
3188*b1cdbd2cSJim Jagielski return aPaM;
3189*b1cdbd2cSJim Jagielski }
3190*b1cdbd2cSJim Jagielski
GetTextHeight() const3191*b1cdbd2cSJim Jagielski sal_uInt32 ImpEditEngine::GetTextHeight() const
3192*b1cdbd2cSJim Jagielski {
3193*b1cdbd2cSJim Jagielski DBG_ASSERT( GetUpdateMode(), "Sollte bei Update=sal_False nicht verwendet werden: GetTextHeight" );
3194*b1cdbd2cSJim Jagielski DBG_ASSERT( IsFormatted() || IsFormatting(), "GetTextHeight: Nicht formatiert" );
3195*b1cdbd2cSJim Jagielski return nCurTextHeight;
3196*b1cdbd2cSJim Jagielski }
3197*b1cdbd2cSJim Jagielski
CalcTextWidth(sal_Bool bIgnoreExtraSpace)3198*b1cdbd2cSJim Jagielski sal_uInt32 ImpEditEngine::CalcTextWidth( sal_Bool bIgnoreExtraSpace )
3199*b1cdbd2cSJim Jagielski {
3200*b1cdbd2cSJim Jagielski // Wenn noch nicht formatiert und nicht gerade dabei.
3201*b1cdbd2cSJim Jagielski // Wird in der Formatierung bei AutoPageSize gerufen.
3202*b1cdbd2cSJim Jagielski if ( !IsFormatted() && !IsFormatting() )
3203*b1cdbd2cSJim Jagielski FormatDoc();
3204*b1cdbd2cSJim Jagielski
3205*b1cdbd2cSJim Jagielski EditLine* pLine;
3206*b1cdbd2cSJim Jagielski
3207*b1cdbd2cSJim Jagielski long nMaxWidth = 0;
3208*b1cdbd2cSJim Jagielski long nCurWidth = 0;
3209*b1cdbd2cSJim Jagielski
3210*b1cdbd2cSJim Jagielski // --------------------------------------------------
3211*b1cdbd2cSJim Jagielski // Ueber alle Absaetze...
3212*b1cdbd2cSJim Jagielski // --------------------------------------------------
3213*b1cdbd2cSJim Jagielski sal_uInt16 nParas = GetParaPortions().Count();
3214*b1cdbd2cSJim Jagielski // sal_uInt16 nBiggestPara = 0;
3215*b1cdbd2cSJim Jagielski // sal_uInt16 nBiggestLine = 0;
3216*b1cdbd2cSJim Jagielski for ( sal_uInt16 nPara = 0; nPara < nParas; nPara++ )
3217*b1cdbd2cSJim Jagielski {
3218*b1cdbd2cSJim Jagielski ParaPortion* pPortion = GetParaPortions().GetObject( nPara );
3219*b1cdbd2cSJim Jagielski if ( pPortion->IsVisible() )
3220*b1cdbd2cSJim Jagielski {
3221*b1cdbd2cSJim Jagielski const SvxLRSpaceItem& rLRItem = GetLRSpaceItem( pPortion->GetNode() );
3222*b1cdbd2cSJim Jagielski sal_Int32 nSpaceBeforeAndMinLabelWidth = GetSpaceBeforeAndMinLabelWidth( pPortion->GetNode() );
3223*b1cdbd2cSJim Jagielski
3224*b1cdbd2cSJim Jagielski // --------------------------------------------------
3225*b1cdbd2cSJim Jagielski // Ueber die Zeilen des Absatzes...
3226*b1cdbd2cSJim Jagielski // --------------------------------------------------
3227*b1cdbd2cSJim Jagielski sal_uLong nLines = pPortion->GetLines().Count();
3228*b1cdbd2cSJim Jagielski for ( sal_uInt16 nLine = 0; nLine < nLines; nLine++ )
3229*b1cdbd2cSJim Jagielski {
3230*b1cdbd2cSJim Jagielski pLine = pPortion->GetLines().GetObject( nLine );
3231*b1cdbd2cSJim Jagielski DBG_ASSERT( pLine, "NULL-Pointer im Zeileniterator in CalcWidth" );
3232*b1cdbd2cSJim Jagielski // nCurWidth = pLine->GetStartPosX();
3233*b1cdbd2cSJim Jagielski // Bei Center oder Right haengt die breite von der
3234*b1cdbd2cSJim Jagielski // Papierbreite ab, hier nicht erwuenscht.
3235*b1cdbd2cSJim Jagielski // Am besten generell nicht auf StartPosX verlassen,
3236*b1cdbd2cSJim Jagielski // es muss auch die rechte Einrueckung beruecksichtigt werden!
3237*b1cdbd2cSJim Jagielski nCurWidth = GetXValue( rLRItem.GetTxtLeft() + nSpaceBeforeAndMinLabelWidth );
3238*b1cdbd2cSJim Jagielski if ( nLine == 0 )
3239*b1cdbd2cSJim Jagielski {
3240*b1cdbd2cSJim Jagielski long nFI = GetXValue( rLRItem.GetTxtFirstLineOfst() );
3241*b1cdbd2cSJim Jagielski nCurWidth -= nFI;
3242*b1cdbd2cSJim Jagielski if ( pPortion->GetBulletX() > nCurWidth )
3243*b1cdbd2cSJim Jagielski {
3244*b1cdbd2cSJim Jagielski nCurWidth += nFI; // LI?
3245*b1cdbd2cSJim Jagielski if ( pPortion->GetBulletX() > nCurWidth )
3246*b1cdbd2cSJim Jagielski nCurWidth = pPortion->GetBulletX();
3247*b1cdbd2cSJim Jagielski }
3248*b1cdbd2cSJim Jagielski }
3249*b1cdbd2cSJim Jagielski nCurWidth += GetXValue( rLRItem.GetRight() );
3250*b1cdbd2cSJim Jagielski nCurWidth += CalcLineWidth( pPortion, pLine, bIgnoreExtraSpace );
3251*b1cdbd2cSJim Jagielski if ( nCurWidth > nMaxWidth )
3252*b1cdbd2cSJim Jagielski {
3253*b1cdbd2cSJim Jagielski nMaxWidth = nCurWidth;
3254*b1cdbd2cSJim Jagielski }
3255*b1cdbd2cSJim Jagielski }
3256*b1cdbd2cSJim Jagielski }
3257*b1cdbd2cSJim Jagielski }
3258*b1cdbd2cSJim Jagielski if ( nMaxWidth < 0 )
3259*b1cdbd2cSJim Jagielski nMaxWidth = 0;
3260*b1cdbd2cSJim Jagielski
3261*b1cdbd2cSJim Jagielski nMaxWidth++; // Ein breiter, da in CreateLines bei >= umgebrochen wird.
3262*b1cdbd2cSJim Jagielski return (sal_uInt32)nMaxWidth;
3263*b1cdbd2cSJim Jagielski }
3264*b1cdbd2cSJim Jagielski
CalcLineWidth(ParaPortion * pPortion,EditLine * pLine,sal_Bool bIgnoreExtraSpace)3265*b1cdbd2cSJim Jagielski sal_uInt32 ImpEditEngine::CalcLineWidth( ParaPortion* pPortion, EditLine* pLine, sal_Bool bIgnoreExtraSpace )
3266*b1cdbd2cSJim Jagielski {
3267*b1cdbd2cSJim Jagielski sal_uInt16 nPara = GetEditDoc().GetPos( pPortion->GetNode() );
3268*b1cdbd2cSJim Jagielski
3269*b1cdbd2cSJim Jagielski // #114278# Saving both layout mode and language (since I'm
3270*b1cdbd2cSJim Jagielski // potentially changing both)
3271*b1cdbd2cSJim Jagielski GetRefDevice()->Push( PUSH_TEXTLAYOUTMODE|PUSH_TEXTLANGUAGE );
3272*b1cdbd2cSJim Jagielski
3273*b1cdbd2cSJim Jagielski ImplInitLayoutMode( GetRefDevice(), nPara, 0xFFFF );
3274*b1cdbd2cSJim Jagielski
3275*b1cdbd2cSJim Jagielski SvxAdjust eJustification = GetJustification( nPara );
3276*b1cdbd2cSJim Jagielski
3277*b1cdbd2cSJim Jagielski // Berechnung der Breite ohne die Indents...
3278*b1cdbd2cSJim Jagielski sal_uInt32 nWidth = 0;
3279*b1cdbd2cSJim Jagielski sal_uInt16 nPos = pLine->GetStart();
3280*b1cdbd2cSJim Jagielski for ( sal_uInt16 nTP = pLine->GetStartPortion(); nTP <= pLine->GetEndPortion(); nTP++ )
3281*b1cdbd2cSJim Jagielski {
3282*b1cdbd2cSJim Jagielski TextPortion* pTextPortion = pPortion->GetTextPortions().GetObject( nTP );
3283*b1cdbd2cSJim Jagielski switch ( pTextPortion->GetKind() )
3284*b1cdbd2cSJim Jagielski {
3285*b1cdbd2cSJim Jagielski case PORTIONKIND_FIELD:
3286*b1cdbd2cSJim Jagielski case PORTIONKIND_HYPHENATOR:
3287*b1cdbd2cSJim Jagielski case PORTIONKIND_TAB:
3288*b1cdbd2cSJim Jagielski {
3289*b1cdbd2cSJim Jagielski nWidth += pTextPortion->GetSize().Width();
3290*b1cdbd2cSJim Jagielski }
3291*b1cdbd2cSJim Jagielski break;
3292*b1cdbd2cSJim Jagielski case PORTIONKIND_TEXT:
3293*b1cdbd2cSJim Jagielski {
3294*b1cdbd2cSJim Jagielski if ( ( eJustification != SVX_ADJUST_BLOCK ) || ( !bIgnoreExtraSpace ) )
3295*b1cdbd2cSJim Jagielski {
3296*b1cdbd2cSJim Jagielski nWidth += pTextPortion->GetSize().Width();
3297*b1cdbd2cSJim Jagielski }
3298*b1cdbd2cSJim Jagielski else
3299*b1cdbd2cSJim Jagielski {
3300*b1cdbd2cSJim Jagielski SvxFont aTmpFont( pPortion->GetNode()->GetCharAttribs().GetDefFont() );
3301*b1cdbd2cSJim Jagielski SeekCursor( pPortion->GetNode(), nPos+1, aTmpFont );
3302*b1cdbd2cSJim Jagielski aTmpFont.SetPhysFont( GetRefDevice() );
3303*b1cdbd2cSJim Jagielski ImplInitDigitMode( GetRefDevice(), 0, 0, 0, aTmpFont.GetLanguage() );
3304*b1cdbd2cSJim Jagielski nWidth += aTmpFont.QuickGetTextSize( GetRefDevice(), *pPortion->GetNode(), nPos, pTextPortion->GetLen(), NULL ).Width();
3305*b1cdbd2cSJim Jagielski }
3306*b1cdbd2cSJim Jagielski }
3307*b1cdbd2cSJim Jagielski break;
3308*b1cdbd2cSJim Jagielski }
3309*b1cdbd2cSJim Jagielski nPos = nPos + pTextPortion->GetLen();
3310*b1cdbd2cSJim Jagielski }
3311*b1cdbd2cSJim Jagielski
3312*b1cdbd2cSJim Jagielski GetRefDevice()->Pop();
3313*b1cdbd2cSJim Jagielski
3314*b1cdbd2cSJim Jagielski return nWidth;
3315*b1cdbd2cSJim Jagielski }
3316*b1cdbd2cSJim Jagielski
CalcTextHeight()3317*b1cdbd2cSJim Jagielski sal_uInt32 ImpEditEngine::CalcTextHeight()
3318*b1cdbd2cSJim Jagielski {
3319*b1cdbd2cSJim Jagielski DBG_ASSERT( GetUpdateMode(), "Sollte bei Update=sal_False nicht verwendet werden: CalcTextHeight" );
3320*b1cdbd2cSJim Jagielski sal_uInt32 nY = 0;
3321*b1cdbd2cSJim Jagielski for ( sal_uInt16 nPortion = 0; nPortion < GetParaPortions().Count(); nPortion++ )
3322*b1cdbd2cSJim Jagielski nY += GetParaPortions()[nPortion]->GetHeight();
3323*b1cdbd2cSJim Jagielski return nY;
3324*b1cdbd2cSJim Jagielski }
3325*b1cdbd2cSJim Jagielski
GetLineCount(sal_uInt16 nParagraph) const3326*b1cdbd2cSJim Jagielski sal_uInt16 ImpEditEngine::GetLineCount( sal_uInt16 nParagraph ) const
3327*b1cdbd2cSJim Jagielski {
3328*b1cdbd2cSJim Jagielski DBG_ASSERT( nParagraph < GetParaPortions().Count(), "GetLineCount: Out of range" );
3329*b1cdbd2cSJim Jagielski ParaPortion* pPPortion = GetParaPortions().SaveGetObject( nParagraph );
3330*b1cdbd2cSJim Jagielski DBG_ASSERT( pPPortion, "Absatz nicht gefunden: GetLineCount" );
3331*b1cdbd2cSJim Jagielski if ( pPPortion )
3332*b1cdbd2cSJim Jagielski return pPPortion->GetLines().Count();
3333*b1cdbd2cSJim Jagielski
3334*b1cdbd2cSJim Jagielski return 0xFFFF;
3335*b1cdbd2cSJim Jagielski }
3336*b1cdbd2cSJim Jagielski
GetLineLen(sal_uInt16 nParagraph,sal_uInt16 nLine) const3337*b1cdbd2cSJim Jagielski xub_StrLen ImpEditEngine::GetLineLen( sal_uInt16 nParagraph, sal_uInt16 nLine ) const
3338*b1cdbd2cSJim Jagielski {
3339*b1cdbd2cSJim Jagielski DBG_ASSERT( nParagraph < GetParaPortions().Count(), "GetLineLen: Out of range" );
3340*b1cdbd2cSJim Jagielski ParaPortion* pPPortion = GetParaPortions().SaveGetObject( nParagraph );
3341*b1cdbd2cSJim Jagielski DBG_ASSERT( pPPortion, "Absatz nicht gefunden: GetLineLen" );
3342*b1cdbd2cSJim Jagielski if ( pPPortion && ( nLine < pPPortion->GetLines().Count() ) )
3343*b1cdbd2cSJim Jagielski {
3344*b1cdbd2cSJim Jagielski EditLine* pLine = pPPortion->GetLines().GetObject( nLine );
3345*b1cdbd2cSJim Jagielski DBG_ASSERT( pLine, "Zeile nicht gefunden: GetLineHeight" );
3346*b1cdbd2cSJim Jagielski return pLine->GetLen();
3347*b1cdbd2cSJim Jagielski }
3348*b1cdbd2cSJim Jagielski
3349*b1cdbd2cSJim Jagielski return 0xFFFF;
3350*b1cdbd2cSJim Jagielski }
3351*b1cdbd2cSJim Jagielski
GetLineBoundaries(sal_uInt16 & rStart,sal_uInt16 & rEnd,sal_uInt16 nParagraph,sal_uInt16 nLine) const3352*b1cdbd2cSJim Jagielski void ImpEditEngine::GetLineBoundaries( /*out*/sal_uInt16 &rStart, /*out*/sal_uInt16 &rEnd, sal_uInt16 nParagraph, sal_uInt16 nLine ) const
3353*b1cdbd2cSJim Jagielski {
3354*b1cdbd2cSJim Jagielski DBG_ASSERT( nParagraph < GetParaPortions().Count(), "GetLineCount: Out of range" );
3355*b1cdbd2cSJim Jagielski ParaPortion* pPPortion = GetParaPortions().SaveGetObject( nParagraph );
3356*b1cdbd2cSJim Jagielski DBG_ASSERT( pPPortion, "Absatz nicht gefunden: GetLineBoundaries" );
3357*b1cdbd2cSJim Jagielski rStart = rEnd = 0xFFFF; // default values in case of error
3358*b1cdbd2cSJim Jagielski if ( pPPortion && ( nLine < pPPortion->GetLines().Count() ) )
3359*b1cdbd2cSJim Jagielski {
3360*b1cdbd2cSJim Jagielski EditLine* pLine = pPPortion->GetLines().GetObject( nLine );
3361*b1cdbd2cSJim Jagielski DBG_ASSERT( pLine, "Zeile nicht gefunden: GetLineBoundaries" );
3362*b1cdbd2cSJim Jagielski rStart = pLine->GetStart();
3363*b1cdbd2cSJim Jagielski rEnd = pLine->GetEnd();
3364*b1cdbd2cSJim Jagielski }
3365*b1cdbd2cSJim Jagielski }
3366*b1cdbd2cSJim Jagielski
GetLineNumberAtIndex(sal_uInt16 nPara,sal_uInt16 nIndex) const3367*b1cdbd2cSJim Jagielski sal_uInt16 ImpEditEngine::GetLineNumberAtIndex( sal_uInt16 nPara, sal_uInt16 nIndex ) const
3368*b1cdbd2cSJim Jagielski {
3369*b1cdbd2cSJim Jagielski sal_uInt16 nLineNo = 0xFFFF;
3370*b1cdbd2cSJim Jagielski ContentNode* pNode = GetEditDoc().SaveGetObject( nPara );
3371*b1cdbd2cSJim Jagielski DBG_ASSERT( pNode, "GetLineNumberAtIndex: invalid paragraph index" );
3372*b1cdbd2cSJim Jagielski if (pNode)
3373*b1cdbd2cSJim Jagielski {
3374*b1cdbd2cSJim Jagielski // we explicitly allow for the index to point at the character right behind the text
3375*b1cdbd2cSJim Jagielski const bool bValidIndex = /*0 <= nIndex &&*/ nIndex <= pNode->Len();
3376*b1cdbd2cSJim Jagielski DBG_ASSERT( bValidIndex, "GetLineNumberAtIndex: invalid index" );
3377*b1cdbd2cSJim Jagielski const sal_uInt16 nLineCount = GetLineCount( nPara );
3378*b1cdbd2cSJim Jagielski if (nIndex == pNode->Len())
3379*b1cdbd2cSJim Jagielski nLineNo = nLineCount > 0 ? nLineCount - 1 : 0;
3380*b1cdbd2cSJim Jagielski else if (bValidIndex) // nIndex < pNode->Len()
3381*b1cdbd2cSJim Jagielski {
3382*b1cdbd2cSJim Jagielski sal_uInt16 nStart = USHRT_MAX, nEnd = USHRT_MAX;
3383*b1cdbd2cSJim Jagielski for (sal_uInt16 i = 0; i < nLineCount && nLineNo == 0xFFFF; ++i)
3384*b1cdbd2cSJim Jagielski {
3385*b1cdbd2cSJim Jagielski GetLineBoundaries( nStart, nEnd, nPara, i );
3386*b1cdbd2cSJim Jagielski if (nStart <= nIndex && nIndex < nEnd)
3387*b1cdbd2cSJim Jagielski nLineNo = i;
3388*b1cdbd2cSJim Jagielski }
3389*b1cdbd2cSJim Jagielski }
3390*b1cdbd2cSJim Jagielski }
3391*b1cdbd2cSJim Jagielski return nLineNo;
3392*b1cdbd2cSJim Jagielski }
3393*b1cdbd2cSJim Jagielski
GetLineHeight(sal_uInt16 nParagraph,sal_uInt16 nLine)3394*b1cdbd2cSJim Jagielski sal_uInt16 ImpEditEngine::GetLineHeight( sal_uInt16 nParagraph, sal_uInt16 nLine )
3395*b1cdbd2cSJim Jagielski {
3396*b1cdbd2cSJim Jagielski DBG_ASSERT( nParagraph < GetParaPortions().Count(), "GetLineCount: Out of range" );
3397*b1cdbd2cSJim Jagielski ParaPortion* pPPortion = GetParaPortions().SaveGetObject( nParagraph );
3398*b1cdbd2cSJim Jagielski DBG_ASSERT( pPPortion, "Absatz nicht gefunden: GetLineHeight" );
3399*b1cdbd2cSJim Jagielski if ( pPPortion && ( nLine < pPPortion->GetLines().Count() ) )
3400*b1cdbd2cSJim Jagielski {
3401*b1cdbd2cSJim Jagielski EditLine* pLine = pPPortion->GetLines().GetObject( nLine );
3402*b1cdbd2cSJim Jagielski DBG_ASSERT( pLine, "Zeile nicht gefunden: GetLineHeight" );
3403*b1cdbd2cSJim Jagielski return pLine->GetHeight();
3404*b1cdbd2cSJim Jagielski }
3405*b1cdbd2cSJim Jagielski
3406*b1cdbd2cSJim Jagielski return 0xFFFF;
3407*b1cdbd2cSJim Jagielski }
3408*b1cdbd2cSJim Jagielski
GetParaHeight(sal_uInt16 nParagraph)3409*b1cdbd2cSJim Jagielski sal_uInt32 ImpEditEngine::GetParaHeight( sal_uInt16 nParagraph )
3410*b1cdbd2cSJim Jagielski {
3411*b1cdbd2cSJim Jagielski sal_uInt32 nHeight = 0;
3412*b1cdbd2cSJim Jagielski
3413*b1cdbd2cSJim Jagielski ParaPortion* pPPortion = GetParaPortions().SaveGetObject( nParagraph );
3414*b1cdbd2cSJim Jagielski DBG_ASSERT( pPPortion, "Absatz nicht gefunden: GetParaHeight" );
3415*b1cdbd2cSJim Jagielski
3416*b1cdbd2cSJim Jagielski if ( pPPortion )
3417*b1cdbd2cSJim Jagielski nHeight = pPPortion->GetHeight();
3418*b1cdbd2cSJim Jagielski
3419*b1cdbd2cSJim Jagielski return nHeight;
3420*b1cdbd2cSJim Jagielski }
3421*b1cdbd2cSJim Jagielski
UpdateSelections()3422*b1cdbd2cSJim Jagielski void ImpEditEngine::UpdateSelections()
3423*b1cdbd2cSJim Jagielski {
3424*b1cdbd2cSJim Jagielski sal_uInt16 nInvNodes = aDeletedNodes.Count();
3425*b1cdbd2cSJim Jagielski
3426*b1cdbd2cSJim Jagielski // Pruefen, ob eine der Selektionen auf einem geloeschten Node steht...
3427*b1cdbd2cSJim Jagielski // Wenn der Node gueltig ist, muss noch der Index geprueft werden!
3428*b1cdbd2cSJim Jagielski for ( sal_uInt16 nView = 0; nView < aEditViews.Count(); nView++ )
3429*b1cdbd2cSJim Jagielski {
3430*b1cdbd2cSJim Jagielski EditView* pView = aEditViews.GetObject(nView);
3431*b1cdbd2cSJim Jagielski DBG_CHKOBJ( pView, EditView, 0 );
3432*b1cdbd2cSJim Jagielski EditSelection aCurSel( pView->pImpEditView->GetEditSelection() );
3433*b1cdbd2cSJim Jagielski sal_Bool bChanged = sal_False;
3434*b1cdbd2cSJim Jagielski for ( sal_uInt16 n = 0; n < nInvNodes; n++ )
3435*b1cdbd2cSJim Jagielski {
3436*b1cdbd2cSJim Jagielski DeletedNodeInfo* pInf = aDeletedNodes.GetObject( n );
3437*b1cdbd2cSJim Jagielski if ( ( ( sal_uLong )(aCurSel.Min().GetNode()) == pInf->GetInvalidAdress() ) ||
3438*b1cdbd2cSJim Jagielski ( ( sal_uLong )(aCurSel.Max().GetNode()) == pInf->GetInvalidAdress() ) )
3439*b1cdbd2cSJim Jagielski {
3440*b1cdbd2cSJim Jagielski // ParaPortions verwenden, da jetzt auch versteckte
3441*b1cdbd2cSJim Jagielski // Absaetze beruecksichtigt werden muessen!
3442*b1cdbd2cSJim Jagielski sal_uInt16 nPara = pInf->GetPosition();
3443*b1cdbd2cSJim Jagielski ParaPortion* pPPortion = GetParaPortions().SaveGetObject( nPara );
3444*b1cdbd2cSJim Jagielski if ( !pPPortion ) // letzter Absatz
3445*b1cdbd2cSJim Jagielski {
3446*b1cdbd2cSJim Jagielski nPara = GetParaPortions().Count()-1;
3447*b1cdbd2cSJim Jagielski pPPortion = GetParaPortions().GetObject( nPara );
3448*b1cdbd2cSJim Jagielski }
3449*b1cdbd2cSJim Jagielski DBG_ASSERT( pPPortion, "Leeres Document in UpdateSelections ?" );
3450*b1cdbd2cSJim Jagielski // Nicht aus einem verstecktem Absatz landen:
3451*b1cdbd2cSJim Jagielski sal_uInt16 nCurPara = nPara;
3452*b1cdbd2cSJim Jagielski sal_uInt16 nLastPara = GetParaPortions().Count()-1;
3453*b1cdbd2cSJim Jagielski while ( nPara <= nLastPara && !GetParaPortions()[nPara]->IsVisible() )
3454*b1cdbd2cSJim Jagielski nPara++;
3455*b1cdbd2cSJim Jagielski if ( nPara > nLastPara ) // dann eben rueckwaerts...
3456*b1cdbd2cSJim Jagielski {
3457*b1cdbd2cSJim Jagielski nPara = nCurPara;
3458*b1cdbd2cSJim Jagielski while ( nPara && !GetParaPortions()[nPara]->IsVisible() )
3459*b1cdbd2cSJim Jagielski nPara--;
3460*b1cdbd2cSJim Jagielski }
3461*b1cdbd2cSJim Jagielski DBG_ASSERT( GetParaPortions()[nPara]->IsVisible(), "Keinen sichtbaren Absatz gefunden: UpdateSelections" );
3462*b1cdbd2cSJim Jagielski
3463*b1cdbd2cSJim Jagielski ParaPortion* pParaPortion = GetParaPortions()[nPara];
3464*b1cdbd2cSJim Jagielski EditSelection aTmpSelection( EditPaM( pParaPortion->GetNode(), 0 ) );
3465*b1cdbd2cSJim Jagielski pView->pImpEditView->SetEditSelection( aTmpSelection );
3466*b1cdbd2cSJim Jagielski bChanged=sal_True;
3467*b1cdbd2cSJim Jagielski break; // for-Schleife
3468*b1cdbd2cSJim Jagielski }
3469*b1cdbd2cSJim Jagielski }
3470*b1cdbd2cSJim Jagielski if ( !bChanged )
3471*b1cdbd2cSJim Jagielski {
3472*b1cdbd2cSJim Jagielski // Index prueffen, falls Node geschrumpft.
3473*b1cdbd2cSJim Jagielski if ( aCurSel.Min().GetIndex() > aCurSel.Min().GetNode()->Len() )
3474*b1cdbd2cSJim Jagielski {
3475*b1cdbd2cSJim Jagielski aCurSel.Min().GetIndex() = aCurSel.Min().GetNode()->Len();
3476*b1cdbd2cSJim Jagielski pView->pImpEditView->SetEditSelection( aCurSel );
3477*b1cdbd2cSJim Jagielski }
3478*b1cdbd2cSJim Jagielski if ( aCurSel.Max().GetIndex() > aCurSel.Max().GetNode()->Len() )
3479*b1cdbd2cSJim Jagielski {
3480*b1cdbd2cSJim Jagielski aCurSel.Max().GetIndex() = aCurSel.Max().GetNode()->Len();
3481*b1cdbd2cSJim Jagielski pView->pImpEditView->SetEditSelection( aCurSel );
3482*b1cdbd2cSJim Jagielski }
3483*b1cdbd2cSJim Jagielski }
3484*b1cdbd2cSJim Jagielski }
3485*b1cdbd2cSJim Jagielski
3486*b1cdbd2cSJim Jagielski // Loeschen...
3487*b1cdbd2cSJim Jagielski for ( sal_uInt16 n = 0; n < nInvNodes; n++ )
3488*b1cdbd2cSJim Jagielski {
3489*b1cdbd2cSJim Jagielski DeletedNodeInfo* pInf = aDeletedNodes.GetObject( n );
3490*b1cdbd2cSJim Jagielski delete pInf;
3491*b1cdbd2cSJim Jagielski }
3492*b1cdbd2cSJim Jagielski aDeletedNodes.Remove( 0, aDeletedNodes.Count() );
3493*b1cdbd2cSJim Jagielski }
3494*b1cdbd2cSJim Jagielski
ConvertSelection(sal_uInt16 nStartPara,sal_uInt16 nStartPos,sal_uInt16 nEndPara,sal_uInt16 nEndPos) const3495*b1cdbd2cSJim Jagielski EditSelection ImpEditEngine::ConvertSelection( sal_uInt16 nStartPara, sal_uInt16 nStartPos,
3496*b1cdbd2cSJim Jagielski sal_uInt16 nEndPara, sal_uInt16 nEndPos ) const
3497*b1cdbd2cSJim Jagielski {
3498*b1cdbd2cSJim Jagielski EditSelection aNewSelection;
3499*b1cdbd2cSJim Jagielski
3500*b1cdbd2cSJim Jagielski // Start...
3501*b1cdbd2cSJim Jagielski ContentNode* pNode = aEditDoc.SaveGetObject( nStartPara );
3502*b1cdbd2cSJim Jagielski sal_uInt16 nIndex = nStartPos;
3503*b1cdbd2cSJim Jagielski if ( !pNode )
3504*b1cdbd2cSJim Jagielski {
3505*b1cdbd2cSJim Jagielski pNode = aEditDoc[ aEditDoc.Count()-1 ];
3506*b1cdbd2cSJim Jagielski nIndex = pNode->Len();
3507*b1cdbd2cSJim Jagielski }
3508*b1cdbd2cSJim Jagielski else if ( nIndex > pNode->Len() )
3509*b1cdbd2cSJim Jagielski nIndex = pNode->Len();
3510*b1cdbd2cSJim Jagielski
3511*b1cdbd2cSJim Jagielski aNewSelection.Min().SetNode( pNode );
3512*b1cdbd2cSJim Jagielski aNewSelection.Min().SetIndex( nIndex );
3513*b1cdbd2cSJim Jagielski
3514*b1cdbd2cSJim Jagielski // End...
3515*b1cdbd2cSJim Jagielski pNode = aEditDoc.SaveGetObject( nEndPara );
3516*b1cdbd2cSJim Jagielski nIndex = nEndPos;
3517*b1cdbd2cSJim Jagielski if ( !pNode )
3518*b1cdbd2cSJim Jagielski {
3519*b1cdbd2cSJim Jagielski pNode = aEditDoc[ aEditDoc.Count()-1 ];
3520*b1cdbd2cSJim Jagielski nIndex = pNode->Len();
3521*b1cdbd2cSJim Jagielski }
3522*b1cdbd2cSJim Jagielski else if ( nIndex > pNode->Len() )
3523*b1cdbd2cSJim Jagielski nIndex = pNode->Len();
3524*b1cdbd2cSJim Jagielski
3525*b1cdbd2cSJim Jagielski aNewSelection.Max().SetNode( pNode );
3526*b1cdbd2cSJim Jagielski aNewSelection.Max().SetIndex( nIndex );
3527*b1cdbd2cSJim Jagielski
3528*b1cdbd2cSJim Jagielski return aNewSelection;
3529*b1cdbd2cSJim Jagielski }
3530*b1cdbd2cSJim Jagielski
MatchGroup(const EditSelection & rSel)3531*b1cdbd2cSJim Jagielski EditSelection ImpEditEngine::MatchGroup( const EditSelection& rSel )
3532*b1cdbd2cSJim Jagielski {
3533*b1cdbd2cSJim Jagielski EditSelection aMatchSel;
3534*b1cdbd2cSJim Jagielski EditSelection aTmpSel( rSel );
3535*b1cdbd2cSJim Jagielski aTmpSel.Adjust( GetEditDoc() );
3536*b1cdbd2cSJim Jagielski if ( ( aTmpSel.Min().GetNode() != aTmpSel.Max().GetNode() ) ||
3537*b1cdbd2cSJim Jagielski ( ( aTmpSel.Max().GetIndex() - aTmpSel.Min().GetIndex() ) > 1 ) )
3538*b1cdbd2cSJim Jagielski {
3539*b1cdbd2cSJim Jagielski return aMatchSel;
3540*b1cdbd2cSJim Jagielski }
3541*b1cdbd2cSJim Jagielski
3542*b1cdbd2cSJim Jagielski sal_uInt16 nPos = aTmpSel.Min().GetIndex();
3543*b1cdbd2cSJim Jagielski ContentNode* pNode = aTmpSel.Min().GetNode();
3544*b1cdbd2cSJim Jagielski if ( nPos >= pNode->Len() )
3545*b1cdbd2cSJim Jagielski return aMatchSel;
3546*b1cdbd2cSJim Jagielski
3547*b1cdbd2cSJim Jagielski sal_uInt16 nMatchChar = aGroupChars.Search( pNode->GetChar( nPos ) );
3548*b1cdbd2cSJim Jagielski if ( nMatchChar != STRING_NOTFOUND )
3549*b1cdbd2cSJim Jagielski {
3550*b1cdbd2cSJim Jagielski sal_uInt16 nNode = aEditDoc.GetPos( pNode );
3551*b1cdbd2cSJim Jagielski if ( ( nMatchChar % 2 ) == 0 )
3552*b1cdbd2cSJim Jagielski {
3553*b1cdbd2cSJim Jagielski // Vorwaerts suchen...
3554*b1cdbd2cSJim Jagielski xub_Unicode nSC = aGroupChars.GetChar( nMatchChar );
3555*b1cdbd2cSJim Jagielski DBG_ASSERT( aGroupChars.Len() > (nMatchChar+1), "Ungueltige Gruppe von MatchChars!" );
3556*b1cdbd2cSJim Jagielski xub_Unicode nEC = aGroupChars.GetChar( nMatchChar+1 );
3557*b1cdbd2cSJim Jagielski
3558*b1cdbd2cSJim Jagielski sal_uInt16 nCur = aTmpSel.Min().GetIndex()+1;
3559*b1cdbd2cSJim Jagielski sal_uInt16 nLevel = 1;
3560*b1cdbd2cSJim Jagielski while ( pNode && nLevel )
3561*b1cdbd2cSJim Jagielski {
3562*b1cdbd2cSJim Jagielski XubString& rStr = *pNode;
3563*b1cdbd2cSJim Jagielski while ( nCur < rStr.Len() )
3564*b1cdbd2cSJim Jagielski {
3565*b1cdbd2cSJim Jagielski if ( rStr.GetChar( nCur ) == nSC )
3566*b1cdbd2cSJim Jagielski nLevel++;
3567*b1cdbd2cSJim Jagielski else if ( rStr.GetChar( nCur ) == nEC )
3568*b1cdbd2cSJim Jagielski {
3569*b1cdbd2cSJim Jagielski nLevel--;
3570*b1cdbd2cSJim Jagielski if ( !nLevel )
3571*b1cdbd2cSJim Jagielski break; // while nCur...
3572*b1cdbd2cSJim Jagielski }
3573*b1cdbd2cSJim Jagielski nCur++;
3574*b1cdbd2cSJim Jagielski }
3575*b1cdbd2cSJim Jagielski
3576*b1cdbd2cSJim Jagielski if ( nLevel )
3577*b1cdbd2cSJim Jagielski {
3578*b1cdbd2cSJim Jagielski nNode++;
3579*b1cdbd2cSJim Jagielski pNode = nNode < aEditDoc.Count() ? aEditDoc.GetObject( nNode ) : 0;
3580*b1cdbd2cSJim Jagielski nCur = 0;
3581*b1cdbd2cSJim Jagielski }
3582*b1cdbd2cSJim Jagielski }
3583*b1cdbd2cSJim Jagielski if ( nLevel == 0 ) // gefunden
3584*b1cdbd2cSJim Jagielski {
3585*b1cdbd2cSJim Jagielski aMatchSel.Min() = aTmpSel.Min();
3586*b1cdbd2cSJim Jagielski aMatchSel.Max() = EditPaM( pNode, nCur+1 );
3587*b1cdbd2cSJim Jagielski }
3588*b1cdbd2cSJim Jagielski }
3589*b1cdbd2cSJim Jagielski else
3590*b1cdbd2cSJim Jagielski {
3591*b1cdbd2cSJim Jagielski // Rueckwaerts suchen...
3592*b1cdbd2cSJim Jagielski xub_Unicode nEC = aGroupChars.GetChar( nMatchChar );
3593*b1cdbd2cSJim Jagielski xub_Unicode nSC = aGroupChars.GetChar( nMatchChar-1 );
3594*b1cdbd2cSJim Jagielski
3595*b1cdbd2cSJim Jagielski sal_uInt16 nCur = aTmpSel.Min().GetIndex()-1;
3596*b1cdbd2cSJim Jagielski sal_uInt16 nLevel = 1;
3597*b1cdbd2cSJim Jagielski while ( pNode && nLevel )
3598*b1cdbd2cSJim Jagielski {
3599*b1cdbd2cSJim Jagielski if ( pNode->Len() )
3600*b1cdbd2cSJim Jagielski {
3601*b1cdbd2cSJim Jagielski XubString& rStr = *pNode;
3602*b1cdbd2cSJim Jagielski while ( nCur )
3603*b1cdbd2cSJim Jagielski {
3604*b1cdbd2cSJim Jagielski if ( rStr.GetChar( nCur ) == nSC )
3605*b1cdbd2cSJim Jagielski {
3606*b1cdbd2cSJim Jagielski nLevel--;
3607*b1cdbd2cSJim Jagielski if ( !nLevel )
3608*b1cdbd2cSJim Jagielski break; // while nCur...
3609*b1cdbd2cSJim Jagielski }
3610*b1cdbd2cSJim Jagielski else if ( rStr.GetChar( nCur ) == nEC )
3611*b1cdbd2cSJim Jagielski nLevel++;
3612*b1cdbd2cSJim Jagielski
3613*b1cdbd2cSJim Jagielski nCur--;
3614*b1cdbd2cSJim Jagielski }
3615*b1cdbd2cSJim Jagielski }
3616*b1cdbd2cSJim Jagielski
3617*b1cdbd2cSJim Jagielski if ( nLevel )
3618*b1cdbd2cSJim Jagielski {
3619*b1cdbd2cSJim Jagielski pNode = nNode ? aEditDoc.GetObject( --nNode ) : 0;
3620*b1cdbd2cSJim Jagielski if ( pNode )
3621*b1cdbd2cSJim Jagielski nCur = pNode->Len()-1; // egal ob negativ, weil if Len()
3622*b1cdbd2cSJim Jagielski }
3623*b1cdbd2cSJim Jagielski }
3624*b1cdbd2cSJim Jagielski
3625*b1cdbd2cSJim Jagielski if ( nLevel == 0 ) // gefunden
3626*b1cdbd2cSJim Jagielski {
3627*b1cdbd2cSJim Jagielski aMatchSel.Min() = aTmpSel.Min();
3628*b1cdbd2cSJim Jagielski aMatchSel.Min().GetIndex()++; // hinter das Zeichen
3629*b1cdbd2cSJim Jagielski aMatchSel.Max() = EditPaM( pNode, nCur );
3630*b1cdbd2cSJim Jagielski }
3631*b1cdbd2cSJim Jagielski }
3632*b1cdbd2cSJim Jagielski }
3633*b1cdbd2cSJim Jagielski return aMatchSel;
3634*b1cdbd2cSJim Jagielski }
3635*b1cdbd2cSJim Jagielski
StopSelectionMode()3636*b1cdbd2cSJim Jagielski void ImpEditEngine::StopSelectionMode()
3637*b1cdbd2cSJim Jagielski {
3638*b1cdbd2cSJim Jagielski if ( ( IsInSelectionMode() || aSelEngine.IsInSelection() ) && pActiveView )
3639*b1cdbd2cSJim Jagielski {
3640*b1cdbd2cSJim Jagielski pActiveView->pImpEditView->DrawSelection(); // Wegzeichnen...
3641*b1cdbd2cSJim Jagielski EditSelection aSel( pActiveView->pImpEditView->GetEditSelection() );
3642*b1cdbd2cSJim Jagielski aSel.Min() = aSel.Max();
3643*b1cdbd2cSJim Jagielski pActiveView->pImpEditView->SetEditSelection( aSel );
3644*b1cdbd2cSJim Jagielski pActiveView->ShowCursor();
3645*b1cdbd2cSJim Jagielski aSelEngine.Reset();
3646*b1cdbd2cSJim Jagielski bInSelection = sal_False;
3647*b1cdbd2cSJim Jagielski }
3648*b1cdbd2cSJim Jagielski }
3649*b1cdbd2cSJim Jagielski
SetActiveView(EditView * pView)3650*b1cdbd2cSJim Jagielski void ImpEditEngine::SetActiveView( EditView* pView )
3651*b1cdbd2cSJim Jagielski {
3652*b1cdbd2cSJim Jagielski // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3653*b1cdbd2cSJim Jagielski // Eigentlich waere jetzt ein bHasVisSel und HideSelection notwendig !!!
3654*b1cdbd2cSJim Jagielski
3655*b1cdbd2cSJim Jagielski if ( pView == pActiveView )
3656*b1cdbd2cSJim Jagielski return;
3657*b1cdbd2cSJim Jagielski
3658*b1cdbd2cSJim Jagielski if ( pActiveView && pActiveView->HasSelection() )
3659*b1cdbd2cSJim Jagielski pActiveView->pImpEditView->DrawSelection(); // Wegzeichnen...
3660*b1cdbd2cSJim Jagielski
3661*b1cdbd2cSJim Jagielski pActiveView = pView;
3662*b1cdbd2cSJim Jagielski
3663*b1cdbd2cSJim Jagielski if ( pActiveView && pActiveView->HasSelection() )
3664*b1cdbd2cSJim Jagielski pActiveView->pImpEditView->DrawSelection(); // Wegzeichnen...
3665*b1cdbd2cSJim Jagielski
3666*b1cdbd2cSJim Jagielski // NN: Quick fix for #78668#:
3667*b1cdbd2cSJim Jagielski // When editing of a cell in Calc is ended, the edit engine is not deleted,
3668*b1cdbd2cSJim Jagielski // only the edit views are removed. If mpIMEInfos is still set in that case,
3669*b1cdbd2cSJim Jagielski // mpIMEInfos->aPos points to an invalid selection.
3670*b1cdbd2cSJim Jagielski // -> reset mpIMEInfos now
3671*b1cdbd2cSJim Jagielski // (probably something like this is necessary whenever the content is modified
3672*b1cdbd2cSJim Jagielski // from the outside)
3673*b1cdbd2cSJim Jagielski
3674*b1cdbd2cSJim Jagielski if ( !pView && mpIMEInfos )
3675*b1cdbd2cSJim Jagielski {
3676*b1cdbd2cSJim Jagielski delete mpIMEInfos;
3677*b1cdbd2cSJim Jagielski mpIMEInfos = NULL;
3678*b1cdbd2cSJim Jagielski }
3679*b1cdbd2cSJim Jagielski }
3680*b1cdbd2cSJim Jagielski
CreateTransferable(const EditSelection & rSelection) const3681*b1cdbd2cSJim Jagielski uno::Reference< datatransfer::XTransferable > ImpEditEngine::CreateTransferable( const EditSelection& rSelection ) const
3682*b1cdbd2cSJim Jagielski {
3683*b1cdbd2cSJim Jagielski #ifndef SVX_LIGHT
3684*b1cdbd2cSJim Jagielski EditSelection aSelection( rSelection );
3685*b1cdbd2cSJim Jagielski aSelection.Adjust( GetEditDoc() );
3686*b1cdbd2cSJim Jagielski
3687*b1cdbd2cSJim Jagielski EditDataObject* pDataObj = new EditDataObject;
3688*b1cdbd2cSJim Jagielski uno::Reference< datatransfer::XTransferable > xDataObj;
3689*b1cdbd2cSJim Jagielski xDataObj = pDataObj;
3690*b1cdbd2cSJim Jagielski
3691*b1cdbd2cSJim Jagielski XubString aText( GetSelected( aSelection ) );
3692*b1cdbd2cSJim Jagielski aText.ConvertLineEnd(); // Systemspezifisch
3693*b1cdbd2cSJim Jagielski pDataObj->GetString() = aText;
3694*b1cdbd2cSJim Jagielski
3695*b1cdbd2cSJim Jagielski SvxFontItem::EnableStoreUnicodeNames( sal_True );
3696*b1cdbd2cSJim Jagielski WriteBin( pDataObj->GetStream(), aSelection, sal_True );
3697*b1cdbd2cSJim Jagielski pDataObj->GetStream().Seek( 0 );
3698*b1cdbd2cSJim Jagielski SvxFontItem::EnableStoreUnicodeNames( sal_False );
3699*b1cdbd2cSJim Jagielski
3700*b1cdbd2cSJim Jagielski ((ImpEditEngine*)this)->WriteRTF( pDataObj->GetRTFStream(), aSelection );
3701*b1cdbd2cSJim Jagielski pDataObj->GetRTFStream().Seek( 0 );
3702*b1cdbd2cSJim Jagielski
3703*b1cdbd2cSJim Jagielski if ( ( aSelection.Min().GetNode() == aSelection.Max().GetNode() )
3704*b1cdbd2cSJim Jagielski && ( aSelection.Max().GetIndex() == (aSelection.Min().GetIndex()+1) ) )
3705*b1cdbd2cSJim Jagielski {
3706*b1cdbd2cSJim Jagielski const EditCharAttrib* pAttr = aSelection.Min().GetNode()->GetCharAttribs().
3707*b1cdbd2cSJim Jagielski FindFeature( aSelection.Min().GetIndex() );
3708*b1cdbd2cSJim Jagielski if ( pAttr &&
3709*b1cdbd2cSJim Jagielski ( pAttr->GetStart() == aSelection.Min().GetIndex() ) &&
3710*b1cdbd2cSJim Jagielski ( pAttr->Which() == EE_FEATURE_FIELD ) )
3711*b1cdbd2cSJim Jagielski {
3712*b1cdbd2cSJim Jagielski const SvxFieldItem* pField = (const SvxFieldItem*)pAttr->GetItem();
3713*b1cdbd2cSJim Jagielski const SvxFieldData* pFld = pField->GetField();
3714*b1cdbd2cSJim Jagielski if ( pFld && pFld->ISA( SvxURLField ) )
3715*b1cdbd2cSJim Jagielski {
3716*b1cdbd2cSJim Jagielski // Office-Bookmark
3717*b1cdbd2cSJim Jagielski String aURL( ((const SvxURLField*)pFld)->GetURL() );
3718*b1cdbd2cSJim Jagielski String aTxt( ((const SvxURLField*)pFld)->GetRepresentation() );
3719*b1cdbd2cSJim Jagielski pDataObj->GetURL() = aURL;
3720*b1cdbd2cSJim Jagielski }
3721*b1cdbd2cSJim Jagielski }
3722*b1cdbd2cSJim Jagielski }
3723*b1cdbd2cSJim Jagielski
3724*b1cdbd2cSJim Jagielski return xDataObj;
3725*b1cdbd2cSJim Jagielski #else
3726*b1cdbd2cSJim Jagielski return uno::Reference< datatransfer::XTransferable >();
3727*b1cdbd2cSJim Jagielski #endif
3728*b1cdbd2cSJim Jagielski }
3729*b1cdbd2cSJim Jagielski
InsertText(uno::Reference<datatransfer::XTransferable> & rxDataObj,const String & rBaseURL,const EditPaM & rPaM,sal_Bool bUseSpecial)3730*b1cdbd2cSJim Jagielski EditSelection ImpEditEngine::InsertText( uno::Reference< datatransfer::XTransferable >& rxDataObj, const String& rBaseURL, const EditPaM& rPaM, sal_Bool bUseSpecial )
3731*b1cdbd2cSJim Jagielski {
3732*b1cdbd2cSJim Jagielski EditSelection aNewSelection( rPaM );
3733*b1cdbd2cSJim Jagielski
3734*b1cdbd2cSJim Jagielski if ( rxDataObj.is() )
3735*b1cdbd2cSJim Jagielski {
3736*b1cdbd2cSJim Jagielski datatransfer::DataFlavor aFlavor;
3737*b1cdbd2cSJim Jagielski sal_Bool bDone = sal_False;
3738*b1cdbd2cSJim Jagielski
3739*b1cdbd2cSJim Jagielski if ( bUseSpecial )
3740*b1cdbd2cSJim Jagielski {
3741*b1cdbd2cSJim Jagielski // BIN
3742*b1cdbd2cSJim Jagielski SotExchange::GetFormatDataFlavor( SOT_FORMATSTR_ID_EDITENGINE, aFlavor );
3743*b1cdbd2cSJim Jagielski if ( rxDataObj->isDataFlavorSupported( aFlavor ) )
3744*b1cdbd2cSJim Jagielski {
3745*b1cdbd2cSJim Jagielski try
3746*b1cdbd2cSJim Jagielski {
3747*b1cdbd2cSJim Jagielski uno::Any aData = rxDataObj->getTransferData( aFlavor );
3748*b1cdbd2cSJim Jagielski uno::Sequence< sal_Int8 > aSeq;
3749*b1cdbd2cSJim Jagielski aData >>= aSeq;
3750*b1cdbd2cSJim Jagielski {
3751*b1cdbd2cSJim Jagielski SvMemoryStream aBinStream( aSeq.getArray(), aSeq.getLength(), STREAM_READ );
3752*b1cdbd2cSJim Jagielski aNewSelection = Read( aBinStream, rBaseURL, EE_FORMAT_BIN, rPaM );
3753*b1cdbd2cSJim Jagielski }
3754*b1cdbd2cSJim Jagielski bDone = sal_True;
3755*b1cdbd2cSJim Jagielski }
3756*b1cdbd2cSJim Jagielski catch( const ::com::sun::star::uno::Exception& )
3757*b1cdbd2cSJim Jagielski {
3758*b1cdbd2cSJim Jagielski }
3759*b1cdbd2cSJim Jagielski }
3760*b1cdbd2cSJim Jagielski
3761*b1cdbd2cSJim Jagielski if ( !bDone )
3762*b1cdbd2cSJim Jagielski {
3763*b1cdbd2cSJim Jagielski // Bookmark
3764*b1cdbd2cSJim Jagielski /*
3765*b1cdbd2cSJim Jagielski String aURL = ...;
3766*b1cdbd2cSJim Jagielski String aTxt = ...;
3767*b1cdbd2cSJim Jagielski // Feld nur einfuegen, wenn Factory vorhanden.
3768*b1cdbd2cSJim Jagielski if ( ITEMDATA() && ITEMDATA()->GetClassManager().Get( SVX_URLFIELD ) )
3769*b1cdbd2cSJim Jagielski {
3770*b1cdbd2cSJim Jagielski SvxFieldItem aField( SvxURLField( aURL, aTxt, SVXURLFORMAT_URL ), EE_FEATURE_FIELD );
3771*b1cdbd2cSJim Jagielski aNewSelection = InsertField( aPaM, aField );
3772*b1cdbd2cSJim Jagielski UpdateFields();
3773*b1cdbd2cSJim Jagielski }
3774*b1cdbd2cSJim Jagielski else
3775*b1cdbd2cSJim Jagielski aNewSelection = ImpInsertText( aPaM, aURL );
3776*b1cdbd2cSJim Jagielski }
3777*b1cdbd2cSJim Jagielski */
3778*b1cdbd2cSJim Jagielski }
3779*b1cdbd2cSJim Jagielski if ( !bDone )
3780*b1cdbd2cSJim Jagielski {
3781*b1cdbd2cSJim Jagielski // RTF
3782*b1cdbd2cSJim Jagielski SotExchange::GetFormatDataFlavor( SOT_FORMAT_RTF, aFlavor );
3783*b1cdbd2cSJim Jagielski if ( rxDataObj->isDataFlavorSupported( aFlavor ) )
3784*b1cdbd2cSJim Jagielski {
3785*b1cdbd2cSJim Jagielski try
3786*b1cdbd2cSJim Jagielski {
3787*b1cdbd2cSJim Jagielski uno::Any aData = rxDataObj->getTransferData( aFlavor );
3788*b1cdbd2cSJim Jagielski uno::Sequence< sal_Int8 > aSeq;
3789*b1cdbd2cSJim Jagielski aData >>= aSeq;
3790*b1cdbd2cSJim Jagielski {
3791*b1cdbd2cSJim Jagielski SvMemoryStream aRTFStream( aSeq.getArray(), aSeq.getLength(), STREAM_READ );
3792*b1cdbd2cSJim Jagielski aNewSelection = Read( aRTFStream, rBaseURL, EE_FORMAT_RTF, rPaM );
3793*b1cdbd2cSJim Jagielski }
3794*b1cdbd2cSJim Jagielski bDone = sal_True;
3795*b1cdbd2cSJim Jagielski }
3796*b1cdbd2cSJim Jagielski catch( const ::com::sun::star::uno::Exception& )
3797*b1cdbd2cSJim Jagielski {
3798*b1cdbd2cSJim Jagielski }
3799*b1cdbd2cSJim Jagielski }
3800*b1cdbd2cSJim Jagielski }
3801*b1cdbd2cSJim Jagielski if ( !bDone )
3802*b1cdbd2cSJim Jagielski {
3803*b1cdbd2cSJim Jagielski // XML ?
3804*b1cdbd2cSJim Jagielski // Currently, there is nothing like "The" XML format, StarOffice doesn't offer plain XML in Clipboard...
3805*b1cdbd2cSJim Jagielski }
3806*b1cdbd2cSJim Jagielski }
3807*b1cdbd2cSJim Jagielski if ( !bDone )
3808*b1cdbd2cSJim Jagielski {
3809*b1cdbd2cSJim Jagielski SotExchange::GetFormatDataFlavor( SOT_FORMAT_STRING, aFlavor );
3810*b1cdbd2cSJim Jagielski if ( rxDataObj->isDataFlavorSupported( aFlavor ) )
3811*b1cdbd2cSJim Jagielski {
3812*b1cdbd2cSJim Jagielski try
3813*b1cdbd2cSJim Jagielski {
3814*b1cdbd2cSJim Jagielski uno::Any aData = rxDataObj->getTransferData( aFlavor );
3815*b1cdbd2cSJim Jagielski ::rtl::OUString aText;
3816*b1cdbd2cSJim Jagielski aData >>= aText;
3817*b1cdbd2cSJim Jagielski aNewSelection = ImpInsertText( rPaM, aText );
3818*b1cdbd2cSJim Jagielski bDone = sal_True;
3819*b1cdbd2cSJim Jagielski }
3820*b1cdbd2cSJim Jagielski catch( ... )
3821*b1cdbd2cSJim Jagielski {
3822*b1cdbd2cSJim Jagielski ; // #i9286# can happen, even if isDataFlavorSupported returns true...
3823*b1cdbd2cSJim Jagielski }
3824*b1cdbd2cSJim Jagielski }
3825*b1cdbd2cSJim Jagielski }
3826*b1cdbd2cSJim Jagielski }
3827*b1cdbd2cSJim Jagielski
3828*b1cdbd2cSJim Jagielski return aNewSelection;
3829*b1cdbd2cSJim Jagielski }
3830*b1cdbd2cSJim Jagielski
GetInvalidYOffsets(ParaPortion * pPortion)3831*b1cdbd2cSJim Jagielski Range ImpEditEngine::GetInvalidYOffsets( ParaPortion* pPortion )
3832*b1cdbd2cSJim Jagielski {
3833*b1cdbd2cSJim Jagielski Range aRange( 0, 0 );
3834*b1cdbd2cSJim Jagielski
3835*b1cdbd2cSJim Jagielski if ( pPortion->IsVisible() )
3836*b1cdbd2cSJim Jagielski {
3837*b1cdbd2cSJim Jagielski const SvxULSpaceItem& rULSpace = (const SvxULSpaceItem&)pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_ULSPACE );
3838*b1cdbd2cSJim Jagielski const SvxLineSpacingItem& rLSItem = (const SvxLineSpacingItem&)pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_SBL );
3839*b1cdbd2cSJim Jagielski sal_uInt16 nSBL = ( rLSItem.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_FIX )
3840*b1cdbd2cSJim Jagielski ? GetYValue( rLSItem.GetInterLineSpace() ) : 0;
3841*b1cdbd2cSJim Jagielski
3842*b1cdbd2cSJim Jagielski // erst von vorne...
3843*b1cdbd2cSJim Jagielski sal_uInt16 nFirstInvalid = 0xFFFF;
3844*b1cdbd2cSJim Jagielski sal_uInt16 nLine;
3845*b1cdbd2cSJim Jagielski for ( nLine = 0; nLine < pPortion->GetLines().Count(); nLine++ )
3846*b1cdbd2cSJim Jagielski {
3847*b1cdbd2cSJim Jagielski EditLine* pL = pPortion->GetLines().GetObject( nLine );
3848*b1cdbd2cSJim Jagielski if ( pL->IsInvalid() )
3849*b1cdbd2cSJim Jagielski {
3850*b1cdbd2cSJim Jagielski nFirstInvalid = nLine;
3851*b1cdbd2cSJim Jagielski break;
3852*b1cdbd2cSJim Jagielski }
3853*b1cdbd2cSJim Jagielski if ( nLine && !aStatus.IsOutliner() ) // nicht die erste Zeile
3854*b1cdbd2cSJim Jagielski aRange.Min() += nSBL;
3855*b1cdbd2cSJim Jagielski aRange.Min() += pL->GetHeight();
3856*b1cdbd2cSJim Jagielski }
3857*b1cdbd2cSJim Jagielski DBG_ASSERT( nFirstInvalid != 0xFFFF, "Keine ungueltige Zeile gefunden in GetInvalidYOffset(1)" );
3858*b1cdbd2cSJim Jagielski
3859*b1cdbd2cSJim Jagielski
3860*b1cdbd2cSJim Jagielski // Abgleichen und weiter...
3861*b1cdbd2cSJim Jagielski aRange.Max() = aRange.Min();
3862*b1cdbd2cSJim Jagielski aRange.Max() += pPortion->GetFirstLineOffset();
3863*b1cdbd2cSJim Jagielski if ( nFirstInvalid != 0 ) // Nur wenn nicht die erste Zeile ungueltig
3864*b1cdbd2cSJim Jagielski aRange.Min() = aRange.Max();
3865*b1cdbd2cSJim Jagielski
3866*b1cdbd2cSJim Jagielski sal_uInt16 nLastInvalid = pPortion->GetLines().Count()-1;
3867*b1cdbd2cSJim Jagielski for ( nLine = nFirstInvalid; nLine < pPortion->GetLines().Count(); nLine++ )
3868*b1cdbd2cSJim Jagielski {
3869*b1cdbd2cSJim Jagielski EditLine* pL = pPortion->GetLines().GetObject( nLine );
3870*b1cdbd2cSJim Jagielski if ( pL->IsValid() )
3871*b1cdbd2cSJim Jagielski {
3872*b1cdbd2cSJim Jagielski nLastInvalid = nLine;
3873*b1cdbd2cSJim Jagielski break;
3874*b1cdbd2cSJim Jagielski }
3875*b1cdbd2cSJim Jagielski
3876*b1cdbd2cSJim Jagielski if ( nLine && !aStatus.IsOutliner() )
3877*b1cdbd2cSJim Jagielski aRange.Max() += nSBL;
3878*b1cdbd2cSJim Jagielski aRange.Max() += pL->GetHeight();
3879*b1cdbd2cSJim Jagielski }
3880*b1cdbd2cSJim Jagielski
3881*b1cdbd2cSJim Jagielski // MT 07/00 SBL kann jetzt kleiner 100% sein => ggf. die Zeile davor neu ausgeben.
3882*b1cdbd2cSJim Jagielski if( ( rLSItem.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_PROP ) && rLSItem.GetPropLineSpace() &&
3883*b1cdbd2cSJim Jagielski ( rLSItem.GetPropLineSpace() < 100 ) )
3884*b1cdbd2cSJim Jagielski {
3885*b1cdbd2cSJim Jagielski EditLine* pL = pPortion->GetLines().GetObject( nFirstInvalid );
3886*b1cdbd2cSJim Jagielski long n = pL->GetTxtHeight() * ( 100 - rLSItem.GetPropLineSpace() );
3887*b1cdbd2cSJim Jagielski n /= 100;
3888*b1cdbd2cSJim Jagielski aRange.Min() -= n;
3889*b1cdbd2cSJim Jagielski aRange.Max() += n;
3890*b1cdbd2cSJim Jagielski }
3891*b1cdbd2cSJim Jagielski
3892*b1cdbd2cSJim Jagielski if ( ( nLastInvalid == pPortion->GetLines().Count()-1 ) && ( !aStatus.IsOutliner() ) )
3893*b1cdbd2cSJim Jagielski aRange.Max() += GetYValue( rULSpace.GetLower() );
3894*b1cdbd2cSJim Jagielski }
3895*b1cdbd2cSJim Jagielski return aRange;
3896*b1cdbd2cSJim Jagielski }
3897*b1cdbd2cSJim Jagielski
GetPaM(ParaPortion * pPortion,Point aDocPos,sal_Bool bSmart)3898*b1cdbd2cSJim Jagielski EditPaM ImpEditEngine::GetPaM( ParaPortion* pPortion, Point aDocPos, sal_Bool bSmart )
3899*b1cdbd2cSJim Jagielski {
3900*b1cdbd2cSJim Jagielski DBG_ASSERT( pPortion->IsVisible(), "Wozu GetPaM() bei einem unsichtbaren Absatz?" );
3901*b1cdbd2cSJim Jagielski DBG_ASSERT( IsFormatted(), "GetPaM: Nicht formatiert" );
3902*b1cdbd2cSJim Jagielski
3903*b1cdbd2cSJim Jagielski sal_uInt16 nCurIndex = 0;
3904*b1cdbd2cSJim Jagielski EditPaM aPaM;
3905*b1cdbd2cSJim Jagielski aPaM.SetNode( pPortion->GetNode() );
3906*b1cdbd2cSJim Jagielski
3907*b1cdbd2cSJim Jagielski const SvxLineSpacingItem& rLSItem = (const SvxLineSpacingItem&)pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_SBL );
3908*b1cdbd2cSJim Jagielski sal_uInt16 nSBL = ( rLSItem.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_FIX )
3909*b1cdbd2cSJim Jagielski ? GetYValue( rLSItem.GetInterLineSpace() ) : 0;
3910*b1cdbd2cSJim Jagielski
3911*b1cdbd2cSJim Jagielski long nY = pPortion->GetFirstLineOffset();
3912*b1cdbd2cSJim Jagielski
3913*b1cdbd2cSJim Jagielski DBG_ASSERT( pPortion->GetLines().Count(), "Leere ParaPortion in GetPaM!" );
3914*b1cdbd2cSJim Jagielski
3915*b1cdbd2cSJim Jagielski EditLine* pLine = 0;
3916*b1cdbd2cSJim Jagielski for ( sal_uInt16 nLine = 0; nLine < pPortion->GetLines().Count(); nLine++ )
3917*b1cdbd2cSJim Jagielski {
3918*b1cdbd2cSJim Jagielski EditLine* pTmpLine = pPortion->GetLines().GetObject( nLine );
3919*b1cdbd2cSJim Jagielski nY += pTmpLine->GetHeight();
3920*b1cdbd2cSJim Jagielski if ( !aStatus.IsOutliner() )
3921*b1cdbd2cSJim Jagielski nY += nSBL;
3922*b1cdbd2cSJim Jagielski if ( nY > aDocPos.Y() ) // das war 'se
3923*b1cdbd2cSJim Jagielski {
3924*b1cdbd2cSJim Jagielski pLine = pTmpLine;
3925*b1cdbd2cSJim Jagielski break; // richtige Y-Position intressiert nicht
3926*b1cdbd2cSJim Jagielski }
3927*b1cdbd2cSJim Jagielski
3928*b1cdbd2cSJim Jagielski nCurIndex = nCurIndex + pTmpLine->GetLen();
3929*b1cdbd2cSJim Jagielski }
3930*b1cdbd2cSJim Jagielski
3931*b1cdbd2cSJim Jagielski if ( !pLine ) // darf nur im Bereich von SA passieren!
3932*b1cdbd2cSJim Jagielski {
3933*b1cdbd2cSJim Jagielski #ifdef DBG_UTIL
3934*b1cdbd2cSJim Jagielski const SvxULSpaceItem& rULSpace =(const SvxULSpaceItem&)pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_ULSPACE );
3935*b1cdbd2cSJim Jagielski DBG_ASSERT( nY+GetYValue( rULSpace.GetLower() ) >= aDocPos.Y() , "Index in keiner Zeile, GetPaM ?" );
3936*b1cdbd2cSJim Jagielski #endif
3937*b1cdbd2cSJim Jagielski aPaM.SetIndex( pPortion->GetNode()->Len() );
3938*b1cdbd2cSJim Jagielski return aPaM;
3939*b1cdbd2cSJim Jagielski }
3940*b1cdbd2cSJim Jagielski
3941*b1cdbd2cSJim Jagielski // Wenn Zeile gefunden, nur noch X-Position => Index
3942*b1cdbd2cSJim Jagielski nCurIndex = GetChar( pPortion, pLine, aDocPos.X(), bSmart );
3943*b1cdbd2cSJim Jagielski aPaM.SetIndex( nCurIndex );
3944*b1cdbd2cSJim Jagielski
3945*b1cdbd2cSJim Jagielski if ( nCurIndex && ( nCurIndex == pLine->GetEnd() ) &&
3946*b1cdbd2cSJim Jagielski ( pLine != pPortion->GetLines().GetObject( pPortion->GetLines().Count()-1) ) )
3947*b1cdbd2cSJim Jagielski {
3948*b1cdbd2cSJim Jagielski aPaM = CursorLeft( aPaM, ::com::sun::star::i18n::CharacterIteratorMode::SKIPCELL );
3949*b1cdbd2cSJim Jagielski }
3950*b1cdbd2cSJim Jagielski
3951*b1cdbd2cSJim Jagielski return aPaM;
3952*b1cdbd2cSJim Jagielski }
3953*b1cdbd2cSJim Jagielski
GetChar(ParaPortion * pParaPortion,EditLine * pLine,long nXPos,sal_Bool bSmart)3954*b1cdbd2cSJim Jagielski sal_uInt16 ImpEditEngine::GetChar( ParaPortion* pParaPortion, EditLine* pLine, long nXPos, sal_Bool bSmart )
3955*b1cdbd2cSJim Jagielski {
3956*b1cdbd2cSJim Jagielski DBG_ASSERT( pLine, "Keine Zeile erhalten: GetChar" );
3957*b1cdbd2cSJim Jagielski
3958*b1cdbd2cSJim Jagielski sal_uInt16 nChar = 0xFFFF;
3959*b1cdbd2cSJim Jagielski sal_uInt16 nCurIndex = pLine->GetStart();
3960*b1cdbd2cSJim Jagielski
3961*b1cdbd2cSJim Jagielski
3962*b1cdbd2cSJim Jagielski // Search best matching portion with GetPortionXOffset()
3963*b1cdbd2cSJim Jagielski for ( sal_uInt16 i = pLine->GetStartPortion(); i <= pLine->GetEndPortion(); i++ )
3964*b1cdbd2cSJim Jagielski {
3965*b1cdbd2cSJim Jagielski TextPortion* pPortion = pParaPortion->GetTextPortions().GetObject( i );
3966*b1cdbd2cSJim Jagielski long nXLeft = GetPortionXOffset( pParaPortion, pLine, i );
3967*b1cdbd2cSJim Jagielski long nXRight = nXLeft + pPortion->GetSize().Width();
3968*b1cdbd2cSJim Jagielski if ( ( nXLeft <= nXPos ) && ( nXRight >= nXPos ) )
3969*b1cdbd2cSJim Jagielski {
3970*b1cdbd2cSJim Jagielski nChar = nCurIndex;
3971*b1cdbd2cSJim Jagielski
3972*b1cdbd2cSJim Jagielski // Search within Portion...
3973*b1cdbd2cSJim Jagielski
3974*b1cdbd2cSJim Jagielski // Don't search within special portions...
3975*b1cdbd2cSJim Jagielski if ( pPortion->GetKind() != PORTIONKIND_TEXT )
3976*b1cdbd2cSJim Jagielski {
3977*b1cdbd2cSJim Jagielski // ...but check on which side
3978*b1cdbd2cSJim Jagielski if ( bSmart )
3979*b1cdbd2cSJim Jagielski {
3980*b1cdbd2cSJim Jagielski long nLeftDiff = nXPos-nXLeft;
3981*b1cdbd2cSJim Jagielski long nRightDiff = nXRight-nXPos;
3982*b1cdbd2cSJim Jagielski if ( nRightDiff < nLeftDiff )
3983*b1cdbd2cSJim Jagielski nChar++;
3984*b1cdbd2cSJim Jagielski }
3985*b1cdbd2cSJim Jagielski }
3986*b1cdbd2cSJim Jagielski else
3987*b1cdbd2cSJim Jagielski {
3988*b1cdbd2cSJim Jagielski sal_uInt16 nMax = pPortion->GetLen();
3989*b1cdbd2cSJim Jagielski sal_uInt16 nOffset = 0xFFFF;
3990*b1cdbd2cSJim Jagielski sal_uInt16 nTmpCurIndex = nChar - pLine->GetStart();
3991*b1cdbd2cSJim Jagielski
3992*b1cdbd2cSJim Jagielski long nXInPortion = nXPos - nXLeft;
3993*b1cdbd2cSJim Jagielski if ( pPortion->IsRightToLeft() )
3994*b1cdbd2cSJim Jagielski nXInPortion = nXRight - nXPos;
3995*b1cdbd2cSJim Jagielski
3996*b1cdbd2cSJim Jagielski // Search in Array...
3997*b1cdbd2cSJim Jagielski for ( sal_uInt16 x = 0; x < nMax; x++ )
3998*b1cdbd2cSJim Jagielski {
3999*b1cdbd2cSJim Jagielski long nTmpPosMax = pLine->GetCharPosArray().GetObject( nTmpCurIndex+x );
4000*b1cdbd2cSJim Jagielski if ( nTmpPosMax > nXInPortion )
4001*b1cdbd2cSJim Jagielski {
4002*b1cdbd2cSJim Jagielski // pruefen, ob dieser oder der davor...
4003*b1cdbd2cSJim Jagielski long nTmpPosMin = x ? pLine->GetCharPosArray().GetObject( nTmpCurIndex+x-1 ) : 0;
4004*b1cdbd2cSJim Jagielski long nDiffLeft = nXInPortion - nTmpPosMin;
4005*b1cdbd2cSJim Jagielski long nDiffRight = nTmpPosMax - nXInPortion;
4006*b1cdbd2cSJim Jagielski DBG_ASSERT( nDiffLeft >= 0, "DiffLeft negativ" );
4007*b1cdbd2cSJim Jagielski DBG_ASSERT( nDiffRight >= 0, "DiffRight negativ" );
4008*b1cdbd2cSJim Jagielski nOffset = ( bSmart && ( nDiffRight < nDiffLeft ) ) ? x+1 : x;
4009*b1cdbd2cSJim Jagielski // I18N: If there are character position with the length of 0,
4010*b1cdbd2cSJim Jagielski // they belong to the same character, we can not use this position as an index.
4011*b1cdbd2cSJim Jagielski // Skip all 0-positions, cheaper than using XBreakIterator:
4012*b1cdbd2cSJim Jagielski if ( nOffset < nMax )
4013*b1cdbd2cSJim Jagielski {
4014*b1cdbd2cSJim Jagielski const long nX = pLine->GetCharPosArray().GetObject(nOffset);
4015*b1cdbd2cSJim Jagielski while ( ( (nOffset+1) < nMax ) && ( pLine->GetCharPosArray().GetObject(nOffset+1) == nX ) )
4016*b1cdbd2cSJim Jagielski nOffset++;
4017*b1cdbd2cSJim Jagielski }
4018*b1cdbd2cSJim Jagielski break;
4019*b1cdbd2cSJim Jagielski }
4020*b1cdbd2cSJim Jagielski }
4021*b1cdbd2cSJim Jagielski
4022*b1cdbd2cSJim Jagielski // Bei Verwendung des CharPosArray duerfte es keine Ungenauigkeiten geben!
4023*b1cdbd2cSJim Jagielski // Vielleicht bei Kerning ?
4024*b1cdbd2cSJim Jagielski // 0xFFF passiert z.B. bei Outline-Font, wenn ganz hinten.
4025*b1cdbd2cSJim Jagielski if ( nOffset == 0xFFFF )
4026*b1cdbd2cSJim Jagielski nOffset = nMax;
4027*b1cdbd2cSJim Jagielski
4028*b1cdbd2cSJim Jagielski DBG_ASSERT( nOffset <= nMax, "nOffset > nMax" );
4029*b1cdbd2cSJim Jagielski
4030*b1cdbd2cSJim Jagielski nChar = nChar + nOffset;
4031*b1cdbd2cSJim Jagielski
4032*b1cdbd2cSJim Jagielski // Check if index is within a cell:
4033*b1cdbd2cSJim Jagielski if ( nChar && ( nChar < pParaPortion->GetNode()->Len() ) )
4034*b1cdbd2cSJim Jagielski {
4035*b1cdbd2cSJim Jagielski EditPaM aPaM( pParaPortion->GetNode(), nChar+1 );
4036*b1cdbd2cSJim Jagielski sal_uInt16 nScriptType = GetScriptType( aPaM );
4037*b1cdbd2cSJim Jagielski if ( nScriptType == i18n::ScriptType::COMPLEX )
4038*b1cdbd2cSJim Jagielski {
4039*b1cdbd2cSJim Jagielski uno::Reference < i18n::XBreakIterator > _xBI( ImplGetBreakIterator() );
4040*b1cdbd2cSJim Jagielski sal_Int32 nCount = 1;
4041*b1cdbd2cSJim Jagielski lang::Locale aLocale = GetLocale( aPaM );
4042*b1cdbd2cSJim Jagielski sal_uInt16 nRight = (sal_uInt16)_xBI->nextCharacters( *pParaPortion->GetNode(), nChar, aLocale, ::com::sun::star::i18n::CharacterIteratorMode::SKIPCELL, nCount, nCount );
4043*b1cdbd2cSJim Jagielski sal_uInt16 nLeft = (sal_uInt16)_xBI->previousCharacters( *pParaPortion->GetNode(), nRight, aLocale, ::com::sun::star::i18n::CharacterIteratorMode::SKIPCELL, nCount, nCount );
4044*b1cdbd2cSJim Jagielski if ( ( nLeft != nChar ) && ( nRight != nChar ) )
4045*b1cdbd2cSJim Jagielski {
4046*b1cdbd2cSJim Jagielski nChar = ( Abs( nRight - nChar ) < Abs( nLeft - nChar ) ) ? nRight : nLeft;
4047*b1cdbd2cSJim Jagielski }
4048*b1cdbd2cSJim Jagielski }
4049*b1cdbd2cSJim Jagielski }
4050*b1cdbd2cSJim Jagielski }
4051*b1cdbd2cSJim Jagielski }
4052*b1cdbd2cSJim Jagielski
4053*b1cdbd2cSJim Jagielski nCurIndex = nCurIndex + pPortion->GetLen();
4054*b1cdbd2cSJim Jagielski }
4055*b1cdbd2cSJim Jagielski
4056*b1cdbd2cSJim Jagielski if ( nChar == 0xFFFF )
4057*b1cdbd2cSJim Jagielski {
4058*b1cdbd2cSJim Jagielski nChar = ( nXPos <= pLine->GetStartPosX() ) ? pLine->GetStart() : pLine->GetEnd();
4059*b1cdbd2cSJim Jagielski }
4060*b1cdbd2cSJim Jagielski
4061*b1cdbd2cSJim Jagielski return nChar;
4062*b1cdbd2cSJim Jagielski }
4063*b1cdbd2cSJim Jagielski
GetLineXPosStartEnd(ParaPortion * pParaPortion,EditLine * pLine)4064*b1cdbd2cSJim Jagielski Range ImpEditEngine::GetLineXPosStartEnd( ParaPortion* pParaPortion, EditLine* pLine )
4065*b1cdbd2cSJim Jagielski {
4066*b1cdbd2cSJim Jagielski Range aLineXPosStartEnd;
4067*b1cdbd2cSJim Jagielski
4068*b1cdbd2cSJim Jagielski sal_uInt16 nPara = GetEditDoc().GetPos( pParaPortion->GetNode() );
4069*b1cdbd2cSJim Jagielski if ( !IsRightToLeft( nPara ) )
4070*b1cdbd2cSJim Jagielski {
4071*b1cdbd2cSJim Jagielski aLineXPosStartEnd.Min() = pLine->GetStartPosX();
4072*b1cdbd2cSJim Jagielski aLineXPosStartEnd.Max() = pLine->GetStartPosX() + pLine->GetTextWidth();
4073*b1cdbd2cSJim Jagielski }
4074*b1cdbd2cSJim Jagielski else
4075*b1cdbd2cSJim Jagielski {
4076*b1cdbd2cSJim Jagielski aLineXPosStartEnd.Min() = GetPaperSize().Width() - ( pLine->GetStartPosX() + pLine->GetTextWidth() );
4077*b1cdbd2cSJim Jagielski aLineXPosStartEnd.Max() = GetPaperSize().Width() - pLine->GetStartPosX();
4078*b1cdbd2cSJim Jagielski }
4079*b1cdbd2cSJim Jagielski
4080*b1cdbd2cSJim Jagielski
4081*b1cdbd2cSJim Jagielski return aLineXPosStartEnd;
4082*b1cdbd2cSJim Jagielski }
4083*b1cdbd2cSJim Jagielski
GetPortionXOffset(ParaPortion * pParaPortion,EditLine * pLine,sal_uInt16 nTextPortion)4084*b1cdbd2cSJim Jagielski long ImpEditEngine::GetPortionXOffset( ParaPortion* pParaPortion, EditLine* pLine, sal_uInt16 nTextPortion )
4085*b1cdbd2cSJim Jagielski {
4086*b1cdbd2cSJim Jagielski long nX = pLine->GetStartPosX();
4087*b1cdbd2cSJim Jagielski
4088*b1cdbd2cSJim Jagielski for ( sal_uInt16 i = pLine->GetStartPortion(); i < nTextPortion; i++ )
4089*b1cdbd2cSJim Jagielski {
4090*b1cdbd2cSJim Jagielski TextPortion* pPortion = pParaPortion->GetTextPortions().GetObject( i );
4091*b1cdbd2cSJim Jagielski switch ( pPortion->GetKind() )
4092*b1cdbd2cSJim Jagielski {
4093*b1cdbd2cSJim Jagielski case PORTIONKIND_FIELD:
4094*b1cdbd2cSJim Jagielski case PORTIONKIND_TEXT:
4095*b1cdbd2cSJim Jagielski case PORTIONKIND_HYPHENATOR:
4096*b1cdbd2cSJim Jagielski case PORTIONKIND_TAB:
4097*b1cdbd2cSJim Jagielski // case PORTIONKIND_EXTRASPACE:
4098*b1cdbd2cSJim Jagielski {
4099*b1cdbd2cSJim Jagielski nX += pPortion->GetSize().Width();
4100*b1cdbd2cSJim Jagielski }
4101*b1cdbd2cSJim Jagielski break;
4102*b1cdbd2cSJim Jagielski }
4103*b1cdbd2cSJim Jagielski }
4104*b1cdbd2cSJim Jagielski
4105*b1cdbd2cSJim Jagielski sal_uInt16 nPara = GetEditDoc().GetPos( pParaPortion->GetNode() );
4106*b1cdbd2cSJim Jagielski sal_Bool bR2LPara = IsRightToLeft( nPara );
4107*b1cdbd2cSJim Jagielski
4108*b1cdbd2cSJim Jagielski TextPortion* pDestPortion = pParaPortion->GetTextPortions().GetObject( nTextPortion );
4109*b1cdbd2cSJim Jagielski if ( pDestPortion->GetKind() != PORTIONKIND_TAB )
4110*b1cdbd2cSJim Jagielski {
4111*b1cdbd2cSJim Jagielski if ( !bR2LPara && pDestPortion->GetRightToLeft() )
4112*b1cdbd2cSJim Jagielski {
4113*b1cdbd2cSJim Jagielski // Portions behind must be added, visual before this portion
4114*b1cdbd2cSJim Jagielski sal_uInt16 nTmpPortion = nTextPortion+1;
4115*b1cdbd2cSJim Jagielski while ( nTmpPortion <= pLine->GetEndPortion() )
4116*b1cdbd2cSJim Jagielski {
4117*b1cdbd2cSJim Jagielski TextPortion* pNextTextPortion = pParaPortion->GetTextPortions().GetObject( nTmpPortion );
4118*b1cdbd2cSJim Jagielski if ( pNextTextPortion->GetRightToLeft() && ( pNextTextPortion->GetKind() != PORTIONKIND_TAB ) )
4119*b1cdbd2cSJim Jagielski nX += pNextTextPortion->GetSize().Width();
4120*b1cdbd2cSJim Jagielski else
4121*b1cdbd2cSJim Jagielski break;
4122*b1cdbd2cSJim Jagielski nTmpPortion++;
4123*b1cdbd2cSJim Jagielski }
4124*b1cdbd2cSJim Jagielski // Portions before must be removed, visual behind this portion
4125*b1cdbd2cSJim Jagielski nTmpPortion = nTextPortion;
4126*b1cdbd2cSJim Jagielski while ( nTmpPortion > pLine->GetStartPortion() )
4127*b1cdbd2cSJim Jagielski {
4128*b1cdbd2cSJim Jagielski --nTmpPortion;
4129*b1cdbd2cSJim Jagielski TextPortion* pPrevTextPortion = pParaPortion->GetTextPortions().GetObject( nTmpPortion );
4130*b1cdbd2cSJim Jagielski if ( pPrevTextPortion->GetRightToLeft() && ( pPrevTextPortion->GetKind() != PORTIONKIND_TAB ) )
4131*b1cdbd2cSJim Jagielski nX -= pPrevTextPortion->GetSize().Width();
4132*b1cdbd2cSJim Jagielski else
4133*b1cdbd2cSJim Jagielski break;
4134*b1cdbd2cSJim Jagielski }
4135*b1cdbd2cSJim Jagielski }
4136*b1cdbd2cSJim Jagielski else if ( bR2LPara && !pDestPortion->IsRightToLeft() )
4137*b1cdbd2cSJim Jagielski {
4138*b1cdbd2cSJim Jagielski // Portions behind must be ermoved, visual behind this portion
4139*b1cdbd2cSJim Jagielski sal_uInt16 nTmpPortion = nTextPortion+1;
4140*b1cdbd2cSJim Jagielski while ( nTmpPortion <= pLine->GetEndPortion() )
4141*b1cdbd2cSJim Jagielski {
4142*b1cdbd2cSJim Jagielski TextPortion* pNextTextPortion = pParaPortion->GetTextPortions().GetObject( nTmpPortion );
4143*b1cdbd2cSJim Jagielski if ( !pNextTextPortion->IsRightToLeft() && ( pNextTextPortion->GetKind() != PORTIONKIND_TAB ) )
4144*b1cdbd2cSJim Jagielski nX += pNextTextPortion->GetSize().Width();
4145*b1cdbd2cSJim Jagielski else
4146*b1cdbd2cSJim Jagielski break;
4147*b1cdbd2cSJim Jagielski nTmpPortion++;
4148*b1cdbd2cSJim Jagielski }
4149*b1cdbd2cSJim Jagielski // Portions before must be added, visual before this portion
4150*b1cdbd2cSJim Jagielski nTmpPortion = nTextPortion;
4151*b1cdbd2cSJim Jagielski while ( nTmpPortion > pLine->GetStartPortion() )
4152*b1cdbd2cSJim Jagielski {
4153*b1cdbd2cSJim Jagielski --nTmpPortion;
4154*b1cdbd2cSJim Jagielski TextPortion* pPrevTextPortion = pParaPortion->GetTextPortions().GetObject( nTmpPortion );
4155*b1cdbd2cSJim Jagielski if ( !pPrevTextPortion->IsRightToLeft() && ( pPrevTextPortion->GetKind() != PORTIONKIND_TAB ) )
4156*b1cdbd2cSJim Jagielski nX -= pPrevTextPortion->GetSize().Width();
4157*b1cdbd2cSJim Jagielski else
4158*b1cdbd2cSJim Jagielski break;
4159*b1cdbd2cSJim Jagielski }
4160*b1cdbd2cSJim Jagielski }
4161*b1cdbd2cSJim Jagielski }
4162*b1cdbd2cSJim Jagielski if ( bR2LPara )
4163*b1cdbd2cSJim Jagielski {
4164*b1cdbd2cSJim Jagielski // Switch X postions...
4165*b1cdbd2cSJim Jagielski DBG_ASSERT( GetTextRanger() || GetPaperSize().Width(), "GetPortionXOffset - paper size?!" );
4166*b1cdbd2cSJim Jagielski DBG_ASSERT( GetTextRanger() || (nX <= GetPaperSize().Width()), "GetPortionXOffset - position out of paper size!" );
4167*b1cdbd2cSJim Jagielski nX = GetPaperSize().Width() - nX;
4168*b1cdbd2cSJim Jagielski nX -= pDestPortion->GetSize().Width();
4169*b1cdbd2cSJim Jagielski }
4170*b1cdbd2cSJim Jagielski
4171*b1cdbd2cSJim Jagielski return nX;
4172*b1cdbd2cSJim Jagielski }
4173*b1cdbd2cSJim Jagielski
GetXPos(ParaPortion * pParaPortion,EditLine * pLine,sal_uInt16 nIndex,sal_Bool bPreferPortionStart)4174*b1cdbd2cSJim Jagielski long ImpEditEngine::GetXPos( ParaPortion* pParaPortion, EditLine* pLine, sal_uInt16 nIndex, sal_Bool bPreferPortionStart )
4175*b1cdbd2cSJim Jagielski {
4176*b1cdbd2cSJim Jagielski DBG_ASSERT( pLine, "Keine Zeile erhalten: GetXPos" );
4177*b1cdbd2cSJim Jagielski DBG_ASSERT( ( nIndex >= pLine->GetStart() ) && ( nIndex <= pLine->GetEnd() ) , "GetXPos muss richtig gerufen werden!" );
4178*b1cdbd2cSJim Jagielski
4179*b1cdbd2cSJim Jagielski sal_Bool bDoPreferPortionStart = bPreferPortionStart;
4180*b1cdbd2cSJim Jagielski // Assure that the portion belongs to this line:
4181*b1cdbd2cSJim Jagielski if ( nIndex == pLine->GetStart() )
4182*b1cdbd2cSJim Jagielski bDoPreferPortionStart = sal_True;
4183*b1cdbd2cSJim Jagielski else if ( nIndex == pLine->GetEnd() )
4184*b1cdbd2cSJim Jagielski bDoPreferPortionStart = sal_False;
4185*b1cdbd2cSJim Jagielski
4186*b1cdbd2cSJim Jagielski sal_uInt16 nTextPortionStart = 0;
4187*b1cdbd2cSJim Jagielski sal_uInt16 nTextPortion = pParaPortion->GetTextPortions().FindPortion( nIndex, nTextPortionStart, bDoPreferPortionStart );
4188*b1cdbd2cSJim Jagielski
4189*b1cdbd2cSJim Jagielski DBG_ASSERT( ( nTextPortion >= pLine->GetStartPortion() ) && ( nTextPortion <= pLine->GetEndPortion() ), "GetXPos: Portion not in current line! " );
4190*b1cdbd2cSJim Jagielski
4191*b1cdbd2cSJim Jagielski TextPortion* pPortion = pParaPortion->GetTextPortions().GetObject( nTextPortion );
4192*b1cdbd2cSJim Jagielski
4193*b1cdbd2cSJim Jagielski long nX = GetPortionXOffset( pParaPortion, pLine, nTextPortion );
4194*b1cdbd2cSJim Jagielski
4195*b1cdbd2cSJim Jagielski // calc text width, portion size may include CJK/CTL spacing...
4196*b1cdbd2cSJim Jagielski // But the array migh not be init yet, if using text ranger this method is called within CreateLines()...
4197*b1cdbd2cSJim Jagielski long nPortionTextWidth = pPortion->GetSize().Width();
4198*b1cdbd2cSJim Jagielski if ( ( pPortion->GetKind() == PORTIONKIND_TEXT ) && pPortion->GetLen() && !GetTextRanger() )
4199*b1cdbd2cSJim Jagielski nPortionTextWidth = pLine->GetCharPosArray().GetObject( nTextPortionStart + pPortion->GetLen() - 1 - pLine->GetStart() );
4200*b1cdbd2cSJim Jagielski
4201*b1cdbd2cSJim Jagielski if ( nTextPortionStart != nIndex )
4202*b1cdbd2cSJim Jagielski {
4203*b1cdbd2cSJim Jagielski // Search within portion...
4204*b1cdbd2cSJim Jagielski if ( nIndex == ( nTextPortionStart + pPortion->GetLen() ) )
4205*b1cdbd2cSJim Jagielski {
4206*b1cdbd2cSJim Jagielski // End of Portion
4207*b1cdbd2cSJim Jagielski if ( pPortion->GetKind() == PORTIONKIND_TAB )
4208*b1cdbd2cSJim Jagielski {
4209*b1cdbd2cSJim Jagielski if ( (nTextPortion+1) < pParaPortion->GetTextPortions().Count() )
4210*b1cdbd2cSJim Jagielski {
4211*b1cdbd2cSJim Jagielski TextPortion* pNextPortion = pParaPortion->GetTextPortions().GetObject( nTextPortion+1 );
4212*b1cdbd2cSJim Jagielski if ( pNextPortion->GetKind() != PORTIONKIND_TAB )
4213*b1cdbd2cSJim Jagielski {
4214*b1cdbd2cSJim Jagielski // DBG_ASSERT( !bPreferPortionStart, "GetXPos - How can we this tab portion here???" );
4215*b1cdbd2cSJim Jagielski // #109879# We loop if nIndex == pLine->GetEnd, because bPreferPortionStart will be reset
4216*b1cdbd2cSJim Jagielski if ( !bPreferPortionStart )
4217*b1cdbd2cSJim Jagielski nX = GetXPos( pParaPortion, pLine, nIndex, sal_True );
4218*b1cdbd2cSJim Jagielski else if ( !IsRightToLeft( GetEditDoc().GetPos( pParaPortion->GetNode() ) ) )
4219*b1cdbd2cSJim Jagielski nX += nPortionTextWidth;
4220*b1cdbd2cSJim Jagielski }
4221*b1cdbd2cSJim Jagielski }
4222*b1cdbd2cSJim Jagielski else if ( !IsRightToLeft( GetEditDoc().GetPos( pParaPortion->GetNode() ) ) )
4223*b1cdbd2cSJim Jagielski {
4224*b1cdbd2cSJim Jagielski nX += nPortionTextWidth;
4225*b1cdbd2cSJim Jagielski }
4226*b1cdbd2cSJim Jagielski }
4227*b1cdbd2cSJim Jagielski else if ( !pPortion->IsRightToLeft() )
4228*b1cdbd2cSJim Jagielski {
4229*b1cdbd2cSJim Jagielski nX += nPortionTextWidth;
4230*b1cdbd2cSJim Jagielski }
4231*b1cdbd2cSJim Jagielski }
4232*b1cdbd2cSJim Jagielski else if ( pPortion->GetKind() == PORTIONKIND_TEXT )
4233*b1cdbd2cSJim Jagielski {
4234*b1cdbd2cSJim Jagielski DBG_ASSERT( nIndex != pLine->GetStart(), "Strange behavior in new GetXPos()" );
4235*b1cdbd2cSJim Jagielski DBG_ASSERT( pLine && pLine->GetCharPosArray().Count(), "svx::ImpEditEngine::GetXPos(), portion in an empty line?" );
4236*b1cdbd2cSJim Jagielski
4237*b1cdbd2cSJim Jagielski if( pLine->GetCharPosArray().Count() )
4238*b1cdbd2cSJim Jagielski {
4239*b1cdbd2cSJim Jagielski sal_uInt16 nPos = nIndex - 1 - pLine->GetStart();
4240*b1cdbd2cSJim Jagielski if( nPos >= pLine->GetCharPosArray().Count() )
4241*b1cdbd2cSJim Jagielski {
4242*b1cdbd2cSJim Jagielski nPos = pLine->GetCharPosArray().Count()-1;
4243*b1cdbd2cSJim Jagielski DBG_ERROR("svx::ImpEditEngine::GetXPos(), index out of range!");
4244*b1cdbd2cSJim Jagielski }
4245*b1cdbd2cSJim Jagielski
4246*b1cdbd2cSJim Jagielski // old code restored see #i112788 (which leaves #i74188 unfixed again)
4247*b1cdbd2cSJim Jagielski long nPosInPortion = pLine->GetCharPosArray().GetObject( nPos );
4248*b1cdbd2cSJim Jagielski
4249*b1cdbd2cSJim Jagielski if ( !pPortion->IsRightToLeft() )
4250*b1cdbd2cSJim Jagielski {
4251*b1cdbd2cSJim Jagielski nX += nPosInPortion;
4252*b1cdbd2cSJim Jagielski }
4253*b1cdbd2cSJim Jagielski else
4254*b1cdbd2cSJim Jagielski {
4255*b1cdbd2cSJim Jagielski nX += nPortionTextWidth - nPosInPortion;
4256*b1cdbd2cSJim Jagielski }
4257*b1cdbd2cSJim Jagielski
4258*b1cdbd2cSJim Jagielski if ( pPortion->GetExtraInfos() && pPortion->GetExtraInfos()->bCompressed )
4259*b1cdbd2cSJim Jagielski {
4260*b1cdbd2cSJim Jagielski nX += pPortion->GetExtraInfos()->nPortionOffsetX;
4261*b1cdbd2cSJim Jagielski if ( pPortion->GetExtraInfos()->nAsianCompressionTypes & CHAR_PUNCTUATIONRIGHT )
4262*b1cdbd2cSJim Jagielski {
4263*b1cdbd2cSJim Jagielski sal_uInt8 nType = GetCharTypeForCompression( pParaPortion->GetNode()->GetChar( nIndex ) );
4264*b1cdbd2cSJim Jagielski if ( nType == CHAR_PUNCTUATIONRIGHT )
4265*b1cdbd2cSJim Jagielski {
4266*b1cdbd2cSJim Jagielski sal_uInt16 n = nIndex - nTextPortionStart;
4267*b1cdbd2cSJim Jagielski const sal_Int32* pDXArray = pLine->GetCharPosArray().GetData()+( nTextPortionStart-pLine->GetStart() );
4268*b1cdbd2cSJim Jagielski sal_Int32 nCharWidth = ( ( (n+1) < pPortion->GetLen() ) ? pDXArray[n] : pPortion->GetSize().Width() )
4269*b1cdbd2cSJim Jagielski - ( n ? pDXArray[n-1] : 0 );
4270*b1cdbd2cSJim Jagielski if ( (n+1) < pPortion->GetLen() )
4271*b1cdbd2cSJim Jagielski {
4272*b1cdbd2cSJim Jagielski // smaller, when char behind is CHAR_PUNCTUATIONRIGHT also
4273*b1cdbd2cSJim Jagielski nType = GetCharTypeForCompression( pParaPortion->GetNode()->GetChar( nIndex+1 ) );
4274*b1cdbd2cSJim Jagielski if ( nType == CHAR_PUNCTUATIONRIGHT )
4275*b1cdbd2cSJim Jagielski {
4276*b1cdbd2cSJim Jagielski sal_Int32 nNextCharWidth = ( ( (n+2) < pPortion->GetLen() ) ? pDXArray[n+1] : pPortion->GetSize().Width() )
4277*b1cdbd2cSJim Jagielski - pDXArray[n];
4278*b1cdbd2cSJim Jagielski sal_Int32 nCompressed = nNextCharWidth/2;
4279*b1cdbd2cSJim Jagielski nCompressed *= pPortion->GetExtraInfos()->nMaxCompression100thPercent;
4280*b1cdbd2cSJim Jagielski nCompressed /= 10000;
4281*b1cdbd2cSJim Jagielski nCharWidth += nCompressed;
4282*b1cdbd2cSJim Jagielski }
4283*b1cdbd2cSJim Jagielski }
4284*b1cdbd2cSJim Jagielski else
4285*b1cdbd2cSJim Jagielski {
4286*b1cdbd2cSJim Jagielski nCharWidth *= 2; // last char pos to portion end is only compressed size
4287*b1cdbd2cSJim Jagielski }
4288*b1cdbd2cSJim Jagielski nX += nCharWidth/2; // 50% compression
4289*b1cdbd2cSJim Jagielski }
4290*b1cdbd2cSJim Jagielski }
4291*b1cdbd2cSJim Jagielski }
4292*b1cdbd2cSJim Jagielski }
4293*b1cdbd2cSJim Jagielski }
4294*b1cdbd2cSJim Jagielski }
4295*b1cdbd2cSJim Jagielski else // if ( nIndex == pLine->GetStart() )
4296*b1cdbd2cSJim Jagielski {
4297*b1cdbd2cSJim Jagielski if ( pPortion->IsRightToLeft() )
4298*b1cdbd2cSJim Jagielski {
4299*b1cdbd2cSJim Jagielski nX += nPortionTextWidth;
4300*b1cdbd2cSJim Jagielski }
4301*b1cdbd2cSJim Jagielski }
4302*b1cdbd2cSJim Jagielski
4303*b1cdbd2cSJim Jagielski return nX;
4304*b1cdbd2cSJim Jagielski }
4305*b1cdbd2cSJim Jagielski
CalcHeight(ParaPortion * pPortion)4306*b1cdbd2cSJim Jagielski void ImpEditEngine::CalcHeight( ParaPortion* pPortion )
4307*b1cdbd2cSJim Jagielski {
4308*b1cdbd2cSJim Jagielski pPortion->nHeight = 0;
4309*b1cdbd2cSJim Jagielski pPortion->nFirstLineOffset = 0;
4310*b1cdbd2cSJim Jagielski
4311*b1cdbd2cSJim Jagielski if ( pPortion->IsVisible() )
4312*b1cdbd2cSJim Jagielski {
4313*b1cdbd2cSJim Jagielski DBG_ASSERT( pPortion->GetLines().Count(), "Absatz ohne Zeilen in ParaPortion::CalcHeight" );
4314*b1cdbd2cSJim Jagielski for ( sal_uInt16 nLine = 0; nLine < pPortion->GetLines().Count(); nLine++ )
4315*b1cdbd2cSJim Jagielski pPortion->nHeight += pPortion->GetLines().GetObject( nLine )->GetHeight();
4316*b1cdbd2cSJim Jagielski
4317*b1cdbd2cSJim Jagielski if ( !aStatus.IsOutliner() )
4318*b1cdbd2cSJim Jagielski {
4319*b1cdbd2cSJim Jagielski const SvxULSpaceItem& rULItem = (const SvxULSpaceItem&)pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_ULSPACE );
4320*b1cdbd2cSJim Jagielski const SvxLineSpacingItem& rLSItem = (const SvxLineSpacingItem&)pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_SBL );
4321*b1cdbd2cSJim Jagielski sal_uInt16 nSBL = ( rLSItem.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_FIX ) ? GetYValue( rLSItem.GetInterLineSpace() ) : 0;
4322*b1cdbd2cSJim Jagielski
4323*b1cdbd2cSJim Jagielski if ( nSBL )
4324*b1cdbd2cSJim Jagielski {
4325*b1cdbd2cSJim Jagielski if ( pPortion->GetLines().Count() > 1 )
4326*b1cdbd2cSJim Jagielski pPortion->nHeight += ( pPortion->GetLines().Count() - 1 ) * nSBL;
4327*b1cdbd2cSJim Jagielski if ( aStatus.ULSpaceSummation() )
4328*b1cdbd2cSJim Jagielski pPortion->nHeight += nSBL;
4329*b1cdbd2cSJim Jagielski }
4330*b1cdbd2cSJim Jagielski
4331*b1cdbd2cSJim Jagielski sal_uInt16 nPortion = GetParaPortions().GetPos( pPortion );
4332*b1cdbd2cSJim Jagielski if ( nPortion || aStatus.ULSpaceFirstParagraph() )
4333*b1cdbd2cSJim Jagielski {
4334*b1cdbd2cSJim Jagielski sal_uInt16 nUpper = GetYValue( rULItem.GetUpper() );
4335*b1cdbd2cSJim Jagielski pPortion->nHeight += nUpper;
4336*b1cdbd2cSJim Jagielski pPortion->nFirstLineOffset = nUpper;
4337*b1cdbd2cSJim Jagielski }
4338*b1cdbd2cSJim Jagielski
4339*b1cdbd2cSJim Jagielski if ( ( nPortion != (GetParaPortions().Count()-1) ) )
4340*b1cdbd2cSJim Jagielski {
4341*b1cdbd2cSJim Jagielski pPortion->nHeight += GetYValue( rULItem.GetLower() ); // nicht in letzter
4342*b1cdbd2cSJim Jagielski }
4343*b1cdbd2cSJim Jagielski
4344*b1cdbd2cSJim Jagielski
4345*b1cdbd2cSJim Jagielski if ( nPortion && !aStatus.ULSpaceSummation() )
4346*b1cdbd2cSJim Jagielski {
4347*b1cdbd2cSJim Jagielski ParaPortion* pPrev = GetParaPortions().SaveGetObject( nPortion-1 );
4348*b1cdbd2cSJim Jagielski const SvxULSpaceItem& rPrevULItem = (const SvxULSpaceItem&)pPrev->GetNode()->GetContentAttribs().GetItem( EE_PARA_ULSPACE );
4349*b1cdbd2cSJim Jagielski const SvxLineSpacingItem& rPrevLSItem = (const SvxLineSpacingItem&)pPrev->GetNode()->GetContentAttribs().GetItem( EE_PARA_SBL );
4350*b1cdbd2cSJim Jagielski
4351*b1cdbd2cSJim Jagielski // Verhalten WinWord6/Writer3:
4352*b1cdbd2cSJim Jagielski // Bei einem proportionalen Zeilenabstand wird auch der Absatzabstand
4353*b1cdbd2cSJim Jagielski // manipuliert.
4354*b1cdbd2cSJim Jagielski // Nur Writer3: Nicht aufaddieren, sondern Mindestabstand.
4355*b1cdbd2cSJim Jagielski
4356*b1cdbd2cSJim Jagielski // Pruefen, ob Abstand durch LineSpacing > Upper:
4357*b1cdbd2cSJim Jagielski sal_uInt16 nExtraSpace = GetYValue( lcl_CalcExtraSpace( pPortion, rLSItem ) );
4358*b1cdbd2cSJim Jagielski if ( nExtraSpace > pPortion->nFirstLineOffset )
4359*b1cdbd2cSJim Jagielski {
4360*b1cdbd2cSJim Jagielski // Absatz wird 'groesser':
4361*b1cdbd2cSJim Jagielski pPortion->nHeight += ( nExtraSpace - pPortion->nFirstLineOffset );
4362*b1cdbd2cSJim Jagielski pPortion->nFirstLineOffset = nExtraSpace;
4363*b1cdbd2cSJim Jagielski }
4364*b1cdbd2cSJim Jagielski
4365*b1cdbd2cSJim Jagielski // nFirstLineOffset jetzt f(pNode) => jetzt f(pNode, pPrev) ermitteln:
4366*b1cdbd2cSJim Jagielski sal_uInt16 nPrevLower = GetYValue( rPrevULItem.GetLower() );
4367*b1cdbd2cSJim Jagielski
4368*b1cdbd2cSJim Jagielski // Dieser PrevLower steckt noch in der Hoehe der PrevPortion...
4369*b1cdbd2cSJim Jagielski if ( nPrevLower > pPortion->nFirstLineOffset )
4370*b1cdbd2cSJim Jagielski {
4371*b1cdbd2cSJim Jagielski // Absatz wird 'kleiner':
4372*b1cdbd2cSJim Jagielski pPortion->nHeight -= pPortion->nFirstLineOffset;
4373*b1cdbd2cSJim Jagielski pPortion->nFirstLineOffset = 0;
4374*b1cdbd2cSJim Jagielski }
4375*b1cdbd2cSJim Jagielski else if ( nPrevLower )
4376*b1cdbd2cSJim Jagielski {
4377*b1cdbd2cSJim Jagielski // Absatz wird 'etwas kleiner':
4378*b1cdbd2cSJim Jagielski pPortion->nHeight -= nPrevLower;
4379*b1cdbd2cSJim Jagielski pPortion->nFirstLineOffset =
4380*b1cdbd2cSJim Jagielski pPortion->nFirstLineOffset - nPrevLower;
4381*b1cdbd2cSJim Jagielski }
4382*b1cdbd2cSJim Jagielski
4383*b1cdbd2cSJim Jagielski // Finde ich zwar nicht so gut, aber Writer3-Feature:
4384*b1cdbd2cSJim Jagielski // Pruefen, ob Abstand durch LineSpacing > Lower:
4385*b1cdbd2cSJim Jagielski // Dieser Wert steckt nicht in der Hoehe der PrevPortion.
4386*b1cdbd2cSJim Jagielski if ( !pPrev->IsInvalid() )
4387*b1cdbd2cSJim Jagielski {
4388*b1cdbd2cSJim Jagielski nExtraSpace = GetYValue( lcl_CalcExtraSpace( pPrev, rPrevLSItem ) );
4389*b1cdbd2cSJim Jagielski if ( nExtraSpace > nPrevLower )
4390*b1cdbd2cSJim Jagielski {
4391*b1cdbd2cSJim Jagielski sal_uInt16 nMoreLower = nExtraSpace - nPrevLower;
4392*b1cdbd2cSJim Jagielski // Absatz wird 'groesser', 'waechst' nach unten:
4393*b1cdbd2cSJim Jagielski if ( nMoreLower > pPortion->nFirstLineOffset )
4394*b1cdbd2cSJim Jagielski {
4395*b1cdbd2cSJim Jagielski pPortion->nHeight += ( nMoreLower - pPortion->nFirstLineOffset );
4396*b1cdbd2cSJim Jagielski pPortion->nFirstLineOffset = nMoreLower;
4397*b1cdbd2cSJim Jagielski }
4398*b1cdbd2cSJim Jagielski }
4399*b1cdbd2cSJim Jagielski }
4400*b1cdbd2cSJim Jagielski }
4401*b1cdbd2cSJim Jagielski }
4402*b1cdbd2cSJim Jagielski }
4403*b1cdbd2cSJim Jagielski }
4404*b1cdbd2cSJim Jagielski
GetEditCursor(ParaPortion * pPortion,sal_uInt16 nIndex,sal_uInt16 nFlags)4405*b1cdbd2cSJim Jagielski Rectangle ImpEditEngine::GetEditCursor( ParaPortion* pPortion, sal_uInt16 nIndex, sal_uInt16 nFlags )
4406*b1cdbd2cSJim Jagielski {
4407*b1cdbd2cSJim Jagielski DBG_ASSERT( pPortion->IsVisible(), "Wozu GetEditCursor() bei einem unsichtbaren Absatz?" );
4408*b1cdbd2cSJim Jagielski DBG_ASSERT( IsFormatted() || GetTextRanger(), "GetEditCursor: Nicht formatiert" );
4409*b1cdbd2cSJim Jagielski
4410*b1cdbd2cSJim Jagielski /*
4411*b1cdbd2cSJim Jagielski GETCRSR_ENDOFLINE: Wenn hinter dem letzten Zeichen einer umgebrochenen Zeile,
4412*b1cdbd2cSJim Jagielski am Ende der Zeile bleiben, nicht am Anfang der naechsten.
4413*b1cdbd2cSJim Jagielski Zweck: - END => wirklich hinter das letzte Zeichen
4414*b1cdbd2cSJim Jagielski - Selektion....
4415*b1cdbd2cSJim Jagielski */
4416*b1cdbd2cSJim Jagielski
4417*b1cdbd2cSJim Jagielski long nY = pPortion->GetFirstLineOffset();
4418*b1cdbd2cSJim Jagielski
4419*b1cdbd2cSJim Jagielski const SvxLineSpacingItem& rLSItem = (const SvxLineSpacingItem&)pPortion->GetNode()->GetContentAttribs().GetItem( EE_PARA_SBL );
4420*b1cdbd2cSJim Jagielski sal_uInt16 nSBL = ( rLSItem.GetInterLineSpaceRule() == SVX_INTER_LINE_SPACE_FIX )
4421*b1cdbd2cSJim Jagielski ? GetYValue( rLSItem.GetInterLineSpace() ) : 0;
4422*b1cdbd2cSJim Jagielski
4423*b1cdbd2cSJim Jagielski sal_uInt16 nCurIndex = 0;
4424*b1cdbd2cSJim Jagielski DBG_ASSERT( pPortion->GetLines().Count(), "Leere ParaPortion in GetEditCursor!" );
4425*b1cdbd2cSJim Jagielski EditLine* pLine = 0;
4426*b1cdbd2cSJim Jagielski sal_Bool bEOL = ( nFlags & GETCRSR_ENDOFLINE ) ? sal_True : sal_False;
4427*b1cdbd2cSJim Jagielski for ( sal_uInt16 nLine = 0; nLine < pPortion->GetLines().Count(); nLine++ )
4428*b1cdbd2cSJim Jagielski {
4429*b1cdbd2cSJim Jagielski EditLine* pTmpLine = pPortion->GetLines().GetObject( nLine );
4430*b1cdbd2cSJim Jagielski if ( ( pTmpLine->GetStart() == nIndex ) || ( pTmpLine->IsIn( nIndex, bEOL ) ) )
4431*b1cdbd2cSJim Jagielski {
4432*b1cdbd2cSJim Jagielski pLine = pTmpLine;
4433*b1cdbd2cSJim Jagielski break;
4434*b1cdbd2cSJim Jagielski }
4435*b1cdbd2cSJim Jagielski
4436*b1cdbd2cSJim Jagielski nCurIndex = nCurIndex + pTmpLine->GetLen();
4437*b1cdbd2cSJim Jagielski nY += pTmpLine->GetHeight();
4438*b1cdbd2cSJim Jagielski if ( !aStatus.IsOutliner() )
4439*b1cdbd2cSJim Jagielski nY += nSBL;
4440*b1cdbd2cSJim Jagielski }
4441*b1cdbd2cSJim Jagielski if ( !pLine )
4442*b1cdbd2cSJim Jagielski {
4443*b1cdbd2cSJim Jagielski // Cursor am Ende des Absatzes.
4444*b1cdbd2cSJim Jagielski DBG_ASSERT( nIndex == nCurIndex, "Index voll daneben in GetEditCursor!" );
4445*b1cdbd2cSJim Jagielski
4446*b1cdbd2cSJim Jagielski pLine = pPortion->GetLines().GetObject( pPortion->GetLines().Count()-1 );
4447*b1cdbd2cSJim Jagielski nY -= pLine->GetHeight();
4448*b1cdbd2cSJim Jagielski if ( !aStatus.IsOutliner() )
4449*b1cdbd2cSJim Jagielski nY -= nSBL;
4450*b1cdbd2cSJim Jagielski nCurIndex = nCurIndex - pLine->GetLen();
4451*b1cdbd2cSJim Jagielski }
4452*b1cdbd2cSJim Jagielski
4453*b1cdbd2cSJim Jagielski Rectangle aEditCursor;
4454*b1cdbd2cSJim Jagielski
4455*b1cdbd2cSJim Jagielski aEditCursor.Top() = nY;
4456*b1cdbd2cSJim Jagielski nY += pLine->GetHeight();
4457*b1cdbd2cSJim Jagielski aEditCursor.Bottom() = nY-1;
4458*b1cdbd2cSJim Jagielski
4459*b1cdbd2cSJim Jagielski // innerhalb der Zeile suchen...
4460*b1cdbd2cSJim Jagielski long nX;
4461*b1cdbd2cSJim Jagielski
4462*b1cdbd2cSJim Jagielski if ( ( nIndex == pLine->GetStart() ) && ( nFlags & GETCRSR_STARTOFLINE ) )
4463*b1cdbd2cSJim Jagielski {
4464*b1cdbd2cSJim Jagielski Range aXRange = GetLineXPosStartEnd( pPortion, pLine );
4465*b1cdbd2cSJim Jagielski nX = !IsRightToLeft( GetEditDoc().GetPos( pPortion->GetNode() ) ) ? aXRange.Min() : aXRange.Max();
4466*b1cdbd2cSJim Jagielski }
4467*b1cdbd2cSJim Jagielski else if ( ( nIndex == pLine->GetEnd() ) && ( nFlags & GETCRSR_ENDOFLINE ) )
4468*b1cdbd2cSJim Jagielski {
4469*b1cdbd2cSJim Jagielski Range aXRange = GetLineXPosStartEnd( pPortion, pLine );
4470*b1cdbd2cSJim Jagielski nX = !IsRightToLeft( GetEditDoc().GetPos( pPortion->GetNode() ) ) ? aXRange.Max() : aXRange.Min();
4471*b1cdbd2cSJim Jagielski }
4472*b1cdbd2cSJim Jagielski else
4473*b1cdbd2cSJim Jagielski {
4474*b1cdbd2cSJim Jagielski nX = GetXPos( pPortion, pLine, nIndex, ( nFlags & GETCRSR_PREFERPORTIONSTART ) ? sal_True : sal_False );
4475*b1cdbd2cSJim Jagielski }
4476*b1cdbd2cSJim Jagielski
4477*b1cdbd2cSJim Jagielski aEditCursor.Left() = aEditCursor.Right() = nX;
4478*b1cdbd2cSJim Jagielski
4479*b1cdbd2cSJim Jagielski if ( nFlags & GETCRSR_TXTONLY )
4480*b1cdbd2cSJim Jagielski aEditCursor.Top() = aEditCursor.Bottom() - pLine->GetTxtHeight() + 1;
4481*b1cdbd2cSJim Jagielski else
4482*b1cdbd2cSJim Jagielski aEditCursor.Top() = aEditCursor.Bottom() - Min( pLine->GetTxtHeight(), pLine->GetHeight() ) + 1;
4483*b1cdbd2cSJim Jagielski
4484*b1cdbd2cSJim Jagielski return aEditCursor;
4485*b1cdbd2cSJim Jagielski }
4486*b1cdbd2cSJim Jagielski
SetValidPaperSize(const Size & rNewSz)4487*b1cdbd2cSJim Jagielski void ImpEditEngine::SetValidPaperSize( const Size& rNewSz )
4488*b1cdbd2cSJim Jagielski {
4489*b1cdbd2cSJim Jagielski aPaperSize = rNewSz;
4490*b1cdbd2cSJim Jagielski
4491*b1cdbd2cSJim Jagielski long nMinWidth = aStatus.AutoPageWidth() ? aMinAutoPaperSize.Width() : 0;
4492*b1cdbd2cSJim Jagielski long nMaxWidth = aStatus.AutoPageWidth() ? aMaxAutoPaperSize.Width() : 0x7FFFFFFF;
4493*b1cdbd2cSJim Jagielski long nMinHeight = aStatus.AutoPageHeight() ? aMinAutoPaperSize.Height() : 0;
4494*b1cdbd2cSJim Jagielski long nMaxHeight = aStatus.AutoPageHeight() ? aMaxAutoPaperSize.Height() : 0x7FFFFFFF;
4495*b1cdbd2cSJim Jagielski
4496*b1cdbd2cSJim Jagielski // Minimale/Maximale Breite:
4497*b1cdbd2cSJim Jagielski if ( aPaperSize.Width() < nMinWidth )
4498*b1cdbd2cSJim Jagielski aPaperSize.Width() = nMinWidth;
4499*b1cdbd2cSJim Jagielski else if ( aPaperSize.Width() > nMaxWidth )
4500*b1cdbd2cSJim Jagielski aPaperSize.Width() = nMaxWidth;
4501*b1cdbd2cSJim Jagielski
4502*b1cdbd2cSJim Jagielski // Minimale/Maximale Hoehe:
4503*b1cdbd2cSJim Jagielski if ( aPaperSize.Height() < nMinHeight )
4504*b1cdbd2cSJim Jagielski aPaperSize.Height() = nMinHeight;
4505*b1cdbd2cSJim Jagielski else if ( aPaperSize.Height() > nMaxHeight )
4506*b1cdbd2cSJim Jagielski aPaperSize.Height() = nMaxHeight;
4507*b1cdbd2cSJim Jagielski }
4508*b1cdbd2cSJim Jagielski
IndentBlock(EditView * pEditView,sal_Bool bRight)4509*b1cdbd2cSJim Jagielski void ImpEditEngine::IndentBlock( EditView* pEditView, sal_Bool bRight )
4510*b1cdbd2cSJim Jagielski {
4511*b1cdbd2cSJim Jagielski ESelection aESel( CreateESel( pEditView->pImpEditView->GetEditSelection() ) );
4512*b1cdbd2cSJim Jagielski aESel.Adjust();
4513*b1cdbd2cSJim Jagielski
4514*b1cdbd2cSJim Jagielski // Nur wenn mehrere selektierte Absaetze...
4515*b1cdbd2cSJim Jagielski if ( aESel.nEndPara > aESel.nStartPara )
4516*b1cdbd2cSJim Jagielski {
4517*b1cdbd2cSJim Jagielski ESelection aNewSel = aESel;
4518*b1cdbd2cSJim Jagielski aNewSel.nStartPos = 0;
4519*b1cdbd2cSJim Jagielski aNewSel.nEndPos = 0xFFFF;
4520*b1cdbd2cSJim Jagielski
4521*b1cdbd2cSJim Jagielski if ( aESel.nEndPos == 0 )
4522*b1cdbd2cSJim Jagielski {
4523*b1cdbd2cSJim Jagielski aESel.nEndPara--; // dann diesen Absatz nicht...
4524*b1cdbd2cSJim Jagielski aNewSel.nEndPos = 0;
4525*b1cdbd2cSJim Jagielski }
4526*b1cdbd2cSJim Jagielski
4527*b1cdbd2cSJim Jagielski pEditView->pImpEditView->DrawSelection();
4528*b1cdbd2cSJim Jagielski pEditView->pImpEditView->SetEditSelection(
4529*b1cdbd2cSJim Jagielski pEditView->pImpEditView->GetEditSelection().Max() );
4530*b1cdbd2cSJim Jagielski UndoActionStart( bRight ? EDITUNDO_INDENTBLOCK : EDITUNDO_UNINDENTBLOCK );
4531*b1cdbd2cSJim Jagielski
4532*b1cdbd2cSJim Jagielski for ( sal_uInt16 nPara = aESel.nStartPara; nPara <= aESel.nEndPara; nPara++ )
4533*b1cdbd2cSJim Jagielski {
4534*b1cdbd2cSJim Jagielski ContentNode* pNode = GetEditDoc().GetObject( nPara );
4535*b1cdbd2cSJim Jagielski if ( bRight )
4536*b1cdbd2cSJim Jagielski {
4537*b1cdbd2cSJim Jagielski // Tabs hinzufuegen
4538*b1cdbd2cSJim Jagielski EditPaM aPaM( pNode, 0 );
4539*b1cdbd2cSJim Jagielski InsertTab( aPaM );
4540*b1cdbd2cSJim Jagielski }
4541*b1cdbd2cSJim Jagielski else
4542*b1cdbd2cSJim Jagielski {
4543*b1cdbd2cSJim Jagielski // Tabs entfernen
4544*b1cdbd2cSJim Jagielski EditCharAttrib* pFeature = pNode->GetCharAttribs().FindFeature( 0 );
4545*b1cdbd2cSJim Jagielski if ( pFeature && ( pFeature->GetStart() == 0 ) &&
4546*b1cdbd2cSJim Jagielski ( pFeature->GetItem()->Which() == EE_FEATURE_TAB ) )
4547*b1cdbd2cSJim Jagielski {
4548*b1cdbd2cSJim Jagielski EditPaM aStartPaM( pNode, 0 );
4549*b1cdbd2cSJim Jagielski EditPaM aEndPaM( pNode, 1 );
4550*b1cdbd2cSJim Jagielski ImpDeleteSelection( EditSelection( aStartPaM, aEndPaM ) );
4551*b1cdbd2cSJim Jagielski }
4552*b1cdbd2cSJim Jagielski }
4553*b1cdbd2cSJim Jagielski }
4554*b1cdbd2cSJim Jagielski
4555*b1cdbd2cSJim Jagielski UndoActionEnd( bRight ? EDITUNDO_INDENTBLOCK : EDITUNDO_UNINDENTBLOCK );
4556*b1cdbd2cSJim Jagielski UpdateSelections();
4557*b1cdbd2cSJim Jagielski FormatAndUpdate( pEditView );
4558*b1cdbd2cSJim Jagielski
4559*b1cdbd2cSJim Jagielski ContentNode* pLastNode = GetEditDoc().GetObject( aNewSel.nEndPara );
4560*b1cdbd2cSJim Jagielski if ( pLastNode->Len() < aNewSel.nEndPos )
4561*b1cdbd2cSJim Jagielski aNewSel.nEndPos = pLastNode->Len();
4562*b1cdbd2cSJim Jagielski pEditView->pImpEditView->SetEditSelection( CreateSel( aNewSel ) );
4563*b1cdbd2cSJim Jagielski pEditView->pImpEditView->DrawSelection();
4564*b1cdbd2cSJim Jagielski pEditView->pImpEditView->ShowCursor( sal_False, sal_True );
4565*b1cdbd2cSJim Jagielski }
4566*b1cdbd2cSJim Jagielski }
4567*b1cdbd2cSJim Jagielski
GetForbiddenCharsTable(sal_Bool bGetInternal) const4568*b1cdbd2cSJim Jagielski vos::ORef<SvxForbiddenCharactersTable> ImpEditEngine::GetForbiddenCharsTable( sal_Bool bGetInternal ) const
4569*b1cdbd2cSJim Jagielski {
4570*b1cdbd2cSJim Jagielski vos::ORef<SvxForbiddenCharactersTable> xF = xForbiddenCharsTable;
4571*b1cdbd2cSJim Jagielski if ( !xF.isValid() && bGetInternal )
4572*b1cdbd2cSJim Jagielski xF = EE_DLL()->GetGlobalData()->GetForbiddenCharsTable();
4573*b1cdbd2cSJim Jagielski return xF;
4574*b1cdbd2cSJim Jagielski }
4575*b1cdbd2cSJim Jagielski
SetForbiddenCharsTable(vos::ORef<SvxForbiddenCharactersTable> xForbiddenChars)4576*b1cdbd2cSJim Jagielski void ImpEditEngine::SetForbiddenCharsTable( vos::ORef<SvxForbiddenCharactersTable> xForbiddenChars )
4577*b1cdbd2cSJim Jagielski {
4578*b1cdbd2cSJim Jagielski EE_DLL()->GetGlobalData()->SetForbiddenCharsTable( xForbiddenChars );
4579*b1cdbd2cSJim Jagielski }
4580*b1cdbd2cSJim Jagielski
GetColorConfig()4581*b1cdbd2cSJim Jagielski svtools::ColorConfig& ImpEditEngine::GetColorConfig()
4582*b1cdbd2cSJim Jagielski {
4583*b1cdbd2cSJim Jagielski if ( !pColorConfig )
4584*b1cdbd2cSJim Jagielski pColorConfig = new svtools::ColorConfig;
4585*b1cdbd2cSJim Jagielski
4586*b1cdbd2cSJim Jagielski return *pColorConfig;
4587*b1cdbd2cSJim Jagielski }
4588*b1cdbd2cSJim Jagielski
IsVisualCursorTravelingEnabled()4589*b1cdbd2cSJim Jagielski sal_Bool ImpEditEngine::IsVisualCursorTravelingEnabled()
4590*b1cdbd2cSJim Jagielski {
4591*b1cdbd2cSJim Jagielski sal_Bool bVisualCursorTravaling = sal_False;
4592*b1cdbd2cSJim Jagielski
4593*b1cdbd2cSJim Jagielski if( !pCTLOptions )
4594*b1cdbd2cSJim Jagielski pCTLOptions = new SvtCTLOptions;
4595*b1cdbd2cSJim Jagielski
4596*b1cdbd2cSJim Jagielski if ( pCTLOptions->IsCTLFontEnabled() && ( pCTLOptions->GetCTLCursorMovement() == SvtCTLOptions::MOVEMENT_VISUAL ) )
4597*b1cdbd2cSJim Jagielski {
4598*b1cdbd2cSJim Jagielski bVisualCursorTravaling = sal_True;
4599*b1cdbd2cSJim Jagielski }
4600*b1cdbd2cSJim Jagielski
4601*b1cdbd2cSJim Jagielski return bVisualCursorTravaling;
4602*b1cdbd2cSJim Jagielski
4603*b1cdbd2cSJim Jagielski }
4604*b1cdbd2cSJim Jagielski
DoVisualCursorTraveling(const ContentNode *)4605*b1cdbd2cSJim Jagielski sal_Bool ImpEditEngine::DoVisualCursorTraveling( const ContentNode* )
4606*b1cdbd2cSJim Jagielski {
4607*b1cdbd2cSJim Jagielski // Don't check if it's necessary, because we also need it when leaving the paragraph
4608*b1cdbd2cSJim Jagielski return IsVisualCursorTravelingEnabled();
4609*b1cdbd2cSJim Jagielski /*
4610*b1cdbd2cSJim Jagielski sal_Bool bDoVisualCursorTraveling = sal_False;
4611*b1cdbd2cSJim Jagielski
4612*b1cdbd2cSJim Jagielski if ( IsVisualCursorTravelingEnabled() && pNode->Len() )
4613*b1cdbd2cSJim Jagielski {
4614*b1cdbd2cSJim Jagielski // Only necessary when RTL text in LTR para or LTR text in RTL para
4615*b1cdbd2cSJim Jagielski bDoVisualCursorTraveling = HasDifferentRTLLevels( pNode );
4616*b1cdbd2cSJim Jagielski }
4617*b1cdbd2cSJim Jagielski
4618*b1cdbd2cSJim Jagielski return bDoVisualCursorTraveling;
4619*b1cdbd2cSJim Jagielski */
4620*b1cdbd2cSJim Jagielski }
4621*b1cdbd2cSJim Jagielski
4622*b1cdbd2cSJim Jagielski
CallNotify(EENotify & rNotify)4623*b1cdbd2cSJim Jagielski void ImpEditEngine::CallNotify( EENotify& rNotify )
4624*b1cdbd2cSJim Jagielski {
4625*b1cdbd2cSJim Jagielski if ( !nBlockNotifications )
4626*b1cdbd2cSJim Jagielski {
4627*b1cdbd2cSJim Jagielski GetNotifyHdl().Call( &rNotify );
4628*b1cdbd2cSJim Jagielski }
4629*b1cdbd2cSJim Jagielski else
4630*b1cdbd2cSJim Jagielski {
4631*b1cdbd2cSJim Jagielski EENotify* pNewNotify = new EENotify( rNotify );
4632*b1cdbd2cSJim Jagielski aNotifyCache.Insert( pNewNotify, aNotifyCache.Count() );
4633*b1cdbd2cSJim Jagielski }
4634*b1cdbd2cSJim Jagielski }
4635*b1cdbd2cSJim Jagielski
EnterBlockNotifications()4636*b1cdbd2cSJim Jagielski void ImpEditEngine::EnterBlockNotifications()
4637*b1cdbd2cSJim Jagielski {
4638*b1cdbd2cSJim Jagielski if( !nBlockNotifications )
4639*b1cdbd2cSJim Jagielski {
4640*b1cdbd2cSJim Jagielski // #109864# Send out START notification immediately, to allow
4641*b1cdbd2cSJim Jagielski // external, non-queued events to be captured as well from
4642*b1cdbd2cSJim Jagielski // client side
4643*b1cdbd2cSJim Jagielski EENotify aNotify( EE_NOTIFY_BLOCKNOTIFICATION_START );
4644*b1cdbd2cSJim Jagielski aNotify.pEditEngine = GetEditEnginePtr();
4645*b1cdbd2cSJim Jagielski GetNotifyHdl().Call( &aNotify );
4646*b1cdbd2cSJim Jagielski }
4647*b1cdbd2cSJim Jagielski
4648*b1cdbd2cSJim Jagielski nBlockNotifications++;
4649*b1cdbd2cSJim Jagielski }
4650*b1cdbd2cSJim Jagielski
LeaveBlockNotifications()4651*b1cdbd2cSJim Jagielski void ImpEditEngine::LeaveBlockNotifications()
4652*b1cdbd2cSJim Jagielski {
4653*b1cdbd2cSJim Jagielski DBG_ASSERT( nBlockNotifications, "LeaveBlockNotifications - Why?" );
4654*b1cdbd2cSJim Jagielski
4655*b1cdbd2cSJim Jagielski nBlockNotifications--;
4656*b1cdbd2cSJim Jagielski if ( !nBlockNotifications )
4657*b1cdbd2cSJim Jagielski {
4658*b1cdbd2cSJim Jagielski // Call blocked notify events...
4659*b1cdbd2cSJim Jagielski while ( aNotifyCache.Count() )
4660*b1cdbd2cSJim Jagielski {
4661*b1cdbd2cSJim Jagielski EENotify* pNotify = aNotifyCache[0];
4662*b1cdbd2cSJim Jagielski // Remove from list before calling, maybe we enter LeaveBlockNotifications while calling the handler...
4663*b1cdbd2cSJim Jagielski aNotifyCache.Remove( 0 );
4664*b1cdbd2cSJim Jagielski GetNotifyHdl().Call( pNotify );
4665*b1cdbd2cSJim Jagielski delete pNotify;
4666*b1cdbd2cSJim Jagielski }
4667*b1cdbd2cSJim Jagielski
4668*b1cdbd2cSJim Jagielski EENotify aNotify( EE_NOTIFY_BLOCKNOTIFICATION_END );
4669*b1cdbd2cSJim Jagielski aNotify.pEditEngine = GetEditEnginePtr();
4670*b1cdbd2cSJim Jagielski GetNotifyHdl().Call( &aNotify );
4671*b1cdbd2cSJim Jagielski }
4672*b1cdbd2cSJim Jagielski }
4673*b1cdbd2cSJim Jagielski
IMPL_LINK(ImpEditEngine,DocModified,void *,EMPTYARG)4674*b1cdbd2cSJim Jagielski IMPL_LINK( ImpEditEngine, DocModified, void*, EMPTYARG )
4675*b1cdbd2cSJim Jagielski {
4676*b1cdbd2cSJim Jagielski aModifyHdl.Call( NULL /*GetEditEnginePtr()*/ ); // NULL, because also used for Outliner
4677*b1cdbd2cSJim Jagielski return 0;
4678*b1cdbd2cSJim Jagielski }
4679