Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "hintids.hxx"
30 : : #include <svl/whiter.hxx>
31 : : #include <tools/shl.hxx>
32 : : #include <com/sun/star/i18n/ScriptType.hpp>
33 : : #include <swmodule.hxx>
34 : : #include <redline.hxx> // SwRedline
35 : : #include <txtatr.hxx> // SwTxt ...
36 : : #include <docary.hxx> // SwRedlineTbl
37 : : #include <itratr.hxx> // SwAttrIter
38 : : #include <ndtxt.hxx> // SwTxtNode
39 : : #include <doc.hxx> // SwDoc
40 : : #include <rootfrm.hxx>
41 : : #include <breakit.hxx>
42 : : #include <vcl/keycodes.hxx>
43 : : #include <vcl/cmdevt.hxx>
44 : : #include <vcl/settings.hxx>
45 : : #include <txtfrm.hxx> // SwTxtFrm
46 : : #include <vcl/svapp.hxx>
47 : : #include <redlnitr.hxx>
48 : : #include <extinput.hxx>
49 : : #include <sfx2/printer.hxx>
50 : : #include <vcl/window.hxx>
51 : :
52 : : using namespace ::com::sun::star;
53 : :
54 : : /*************************************************************************
55 : : * SwAttrIter::CtorInitAttrIter()
56 : : *************************************************************************/
57 : 94706 : void SwAttrIter::CtorInitAttrIter( SwTxtNode& rTxtNode, SwScriptInfo& rScrInf, SwTxtFrm* pFrm )
58 : : {
59 : : // Beim HTML-Import kann es vorkommen, dass kein Layout existiert.
60 [ + - ][ + - ]: 94706 : SwRootFrm* pRootFrm = rTxtNode.getIDocumentLayoutAccess()->GetCurrentLayout();
61 [ + + ]: 94706 : pShell = pRootFrm ? pRootFrm->GetCurrShell() : 0; //swmod 080218
62 : :
63 : 94706 : pScriptInfo = &rScrInf;
64 : :
65 : : // attributes set at the whole paragraph
66 [ + - ]: 94706 : pAttrSet = rTxtNode.GetpSwAttrSet();
67 : : // attribute array
68 : 94706 : pHints = rTxtNode.GetpSwpHints();
69 : :
70 : : // Build a font matching the default paragraph style:
71 [ + - ]: 94706 : SwFontAccess aFontAccess( &rTxtNode.GetAnyFmtColl(), pShell );
72 [ - + ][ # # ]: 94706 : delete pFnt;
73 [ + - ][ + - ]: 94706 : pFnt = new SwFont( *aFontAccess.Get()->GetFont() );
[ + - ]
74 : :
75 : : // set font to vertical if frame layout is vertical
76 : 94706 : sal_Bool bVertLayout = sal_False;
77 : 94706 : sal_Bool bRTL = sal_False;
78 [ + + ]: 94706 : if ( pFrm )
79 : : {
80 [ + - ][ - + ]: 94498 : if ( pFrm->IsVertical() )
81 : : {
82 : 0 : bVertLayout = sal_True;
83 [ # # ][ # # ]: 0 : pFnt->SetVertical( pFnt->GetOrientation(), sal_True );
84 : : }
85 [ + - ]: 94498 : bRTL = pFrm->IsRightToLeft();
86 : : }
87 : :
88 : : // Initialize the default attribute of the attribute handler
89 : : // based on the attribute array cached together with the font.
90 : : // If any further attributes for the paragraph are given in pAttrSet
91 : : // consider them during construction of the default array, and apply
92 : : // them to the font
93 : : aAttrHandler.Init( aFontAccess.Get()->GetDefault(), pAttrSet,
94 [ + - ][ + - ]: 94706 : *rTxtNode.getIDocumentSettingAccess(), pShell, *pFnt, bVertLayout );
[ + - ]
95 : :
96 : 94706 : aMagicNo[SW_LATIN] = aMagicNo[SW_CJK] = aMagicNo[SW_CTL] = NULL;
97 : :
98 : : // determine script changes if not already done for current paragraph
99 : : OSL_ENSURE( pScriptInfo, "No script info available");
100 [ + + ]: 94706 : if ( pScriptInfo->GetInvalidity() != STRING_LEN )
101 [ + - ]: 13592 : pScriptInfo->InitScriptInfo( rTxtNode, bRTL );
102 : :
103 [ + - ][ + - ]: 94706 : if ( pBreakIt->GetBreakIter().is() )
104 : : {
105 [ + - ]: 94706 : pFnt->SetActual( SwScriptInfo::WhichFont( 0, 0, pScriptInfo ) );
106 : :
107 : 94706 : xub_StrLen nChg = 0;
108 : 94706 : sal_uInt16 nCnt = 0;
109 : :
110 [ - + ]: 94706 : do
111 : : {
112 [ + - ]: 94706 : nChg = pScriptInfo->GetScriptChg( nCnt );
113 [ + - ]: 94706 : sal_uInt16 nScript = pScriptInfo->GetScriptType( nCnt++ );
114 : 94706 : sal_uInt8 nTmp = 4;
115 [ + - + ]: 94706 : switch ( nScript ) {
116 : : case i18n::ScriptType::ASIAN :
117 [ + - ]: 48 : if( !aMagicNo[SW_CJK] ) nTmp = SW_CJK; break;
118 : : case i18n::ScriptType::COMPLEX :
119 [ # # ]: 0 : if( !aMagicNo[SW_CTL] ) nTmp = SW_CTL; break;
120 : : default:
121 [ + - ]: 94658 : if( !aMagicNo[SW_LATIN ] ) nTmp = SW_LATIN;
122 : : }
123 [ + - ]: 94706 : if( nTmp < 4 )
124 : : {
125 [ + - ]: 94706 : pFnt->ChkMagic( pShell, nTmp );
126 : 94706 : pFnt->GetMagic( aMagicNo[ nTmp ], aFntIdx[ nTmp ], nTmp );
127 : : }
128 : 94706 : } while( nChg < rTxtNode.GetTxt().Len() );
129 : : }
130 : : else
131 : : {
132 [ # # ]: 0 : pFnt->ChkMagic( pShell, SW_LATIN );
133 : 0 : pFnt->GetMagic( aMagicNo[ SW_LATIN ], aFntIdx[ SW_LATIN ], SW_LATIN );
134 : : }
135 : :
136 : 94706 : nStartIndex = nEndIndex = nPos = nChgCnt = 0;
137 : 94706 : nPropFont = 0;
138 : 94706 : SwDoc* pDoc = rTxtNode.GetDoc();
139 [ + - ]: 94706 : const IDocumentRedlineAccess* pIDRA = rTxtNode.getIDocumentRedlineAccess();
140 : :
141 [ + - ]: 94706 : const SwExtTextInput* pExtInp = pDoc->GetExtTextInput( rTxtNode );
142 [ + - ]: 94706 : const bool bShow = IDocumentRedlineAccess::IsShowChanges( pIDRA->GetRedlineMode() );
143 [ + + ][ + - ]: 94706 : if( pExtInp || bShow )
144 : : {
145 [ + - ]: 94259 : MSHORT nRedlPos = pIDRA->GetRedlinePos( rTxtNode, USHRT_MAX );
146 [ + - ][ - + ]: 94259 : if( pExtInp || MSHRT_MAX != nRedlPos )
147 : : {
148 : 0 : const std::vector<sal_uInt16> *pArr = 0;
149 : 0 : xub_StrLen nInputStt = 0;
150 [ # # ]: 0 : if( pExtInp )
151 : : {
152 : 0 : pArr = &pExtInp->GetAttrs();
153 [ # # ]: 0 : nInputStt = pExtInp->Start()->nContent.GetIndex();
154 [ # # ]: 0 : Seek( 0 );
155 : : }
156 : :
157 : : pRedln = new SwRedlineItr( rTxtNode, *pFnt, aAttrHandler, nRedlPos,
158 [ # # ][ # # ]: 0 : bShow, pArr, nInputStt );
159 : :
160 [ # # ]: 0 : if( pRedln->IsOn() )
161 : 0 : ++nChgCnt;
162 : : }
163 [ + - ]: 94706 : }
164 : 94706 : }
165 : :
166 : : /*************************************************************************
167 : : * SwRedlineItr - Der Redline-Iterator
168 : : *
169 : : * Folgende Informationen/Zustaende gibt es im RedlineIterator:
170 : : *
171 : : * nFirst ist der erste Index der RedlineTbl, der mit dem Absatz ueberlappt.
172 : : *
173 : : * nAct ist der zur Zeit aktive ( wenn bOn gesetzt ist ) oder der naechste
174 : : * in Frage kommende Index.
175 : : * nStart und nEnd geben die Grenzen des Objekts innerhalb des Absatzes an.
176 : : *
177 : : * Wenn bOn gesetzt ist, ist der Font entsprechend manipuliert worden.
178 : : *
179 : : * Wenn nAct auf MSHRT_MAX gesetzt wurde ( durch Reset() ), so ist zur Zeit
180 : : * kein Redline aktiv, nStart und nEnd sind invalid.
181 : : *************************************************************************/
182 : :
183 : 0 : SwRedlineItr::SwRedlineItr( const SwTxtNode& rTxtNd, SwFont& rFnt,
184 : : SwAttrHandler& rAH, MSHORT nRed, sal_Bool bShw,
185 : : const std::vector<sal_uInt16> *pArr,
186 : : xub_StrLen nExtStart )
187 : 0 : : rDoc( *rTxtNd.GetDoc() ), rNd( rTxtNd ), rAttrHandler( rAH ), pSet( 0 ),
188 : 0 : nNdIdx( rTxtNd.GetIndex() ), nFirst( nRed ),
189 : 0 : nAct( MSHRT_MAX ), bOn( sal_False ), bShow( bShw )
190 : : {
191 [ # # ]: 0 : if( pArr )
192 [ # # ]: 0 : pExt = new SwExtend( *pArr, nExtStart );
193 : : else
194 : 0 : pExt = NULL;
195 [ # # ]: 0 : Seek( rFnt, 0, STRING_LEN );
196 : 0 : }
197 : :
198 : 0 : SwRedlineItr::~SwRedlineItr()
199 : : {
200 [ # # ]: 0 : Clear( NULL );
201 [ # # ][ # # ]: 0 : delete pSet;
202 [ # # ][ # # ]: 0 : delete pExt;
203 : 0 : }
204 : :
205 : : // Der Return-Wert von SwRedlineItr::Seek gibt an, ob der aktuelle Font
206 : : // veraendert wurde durch Verlassen (-1) oder Betreten eines Bereichs (+1)
207 : :
208 : 0 : short SwRedlineItr::_Seek( SwFont& rFnt, xub_StrLen nNew, xub_StrLen nOld )
209 : : {
210 : 0 : short nRet = 0;
211 [ # # ]: 0 : if( ExtOn() )
212 : 0 : return 0; // Abkuerzung: wenn wir innerhalb eines ExtendTextInputs sind
213 : : // kann es keine anderen Attributwechsel (auch nicht durch Redlining) geben
214 [ # # ]: 0 : if( bShow )
215 : : {
216 [ # # ]: 0 : if( bOn )
217 : : {
218 [ # # ]: 0 : if( nNew >= nEnd )
219 : : {
220 : 0 : --nRet;
221 : 0 : _Clear( &rFnt ); // Wir gehen hinter den aktuellen Bereich
222 : 0 : ++nAct; // und pruefen gleich den naechsten
223 : : }
224 [ # # ]: 0 : else if( nNew < nStart )
225 : : {
226 : 0 : --nRet;
227 : 0 : _Clear( &rFnt ); // Wir gehen vor den aktuellen Bereich
228 [ # # ]: 0 : if( nAct > nFirst )
229 : 0 : nAct = nFirst; // Die Pruefung muss von vorne beginnen
230 : : else
231 : 0 : return nRet + EnterExtend( rFnt, nNew ); // Es gibt keinen vor uns.
232 : : }
233 : : else
234 : 0 : return nRet + EnterExtend( rFnt, nNew ); // Wir sind im gleichen Bereich geblieben.
235 : : }
236 [ # # ][ # # ]: 0 : if( MSHRT_MAX == nAct || nOld > nNew )
237 : 0 : nAct = nFirst;
238 : :
239 : 0 : nStart = STRING_LEN;
240 : 0 : nEnd = STRING_LEN;
241 : :
242 [ # # ]: 0 : for( ; nAct < rDoc.GetRedlineTbl().size() ; ++nAct )
243 : : {
244 : 0 : rDoc.GetRedlineTbl()[ nAct ]->CalcStartEnd( nNdIdx, nStart, nEnd );
245 : :
246 [ # # ]: 0 : if( nNew < nEnd )
247 : : {
248 [ # # ]: 0 : if( nNew >= nStart ) // der einzig moegliche Kandidat
249 : : {
250 : 0 : bOn = sal_True;
251 [ # # ][ # # ]: 0 : const SwRedline *pRed = rDoc.GetRedlineTbl()[ nAct ];
252 : :
253 [ # # ]: 0 : if (pSet)
254 [ # # ]: 0 : pSet->ClearItem();
255 : : else
256 : : {
257 : : SwAttrPool& rPool =
258 : 0 : const_cast<SwDoc&>(rDoc).GetAttrPool();
259 [ # # ][ # # ]: 0 : pSet = new SfxItemSet(rPool, RES_CHRATR_BEGIN, RES_CHRATR_END-1);
260 : : }
261 : :
262 [ # # ][ # # ]: 0 : if( 1 < pRed->GetStackCount() )
263 [ # # ][ # # ]: 0 : FillHints( pRed->GetAuthor( 1 ), pRed->GetType( 1 ) );
[ # # ]
264 [ # # ][ # # ]: 0 : FillHints( pRed->GetAuthor(), pRed->GetType() );
[ # # ]
265 : :
266 [ # # ]: 0 : SfxWhichIter aIter( *pSet );
267 [ # # ]: 0 : MSHORT nWhich = aIter.FirstWhich();
268 [ # # ]: 0 : while( nWhich )
269 : : {
270 : : const SfxPoolItem* pItem;
271 [ # # ][ # # ]: 0 : if( ( nWhich < RES_CHRATR_END ) &&
[ # # ]
272 [ # # ]: 0 : ( SFX_ITEM_SET == pSet->GetItemState( nWhich, sal_True, &pItem ) ) )
273 : : {
274 : : SwTxtAttr* pAttr = MakeRedlineTxtAttr(
275 : : const_cast<SwDoc&>(rDoc),
276 [ # # ]: 0 : *const_cast<SfxPoolItem*>(pItem) );
277 : 0 : pAttr->SetPriorityAttr( sal_True );
278 [ # # ]: 0 : m_Hints.push_back(pAttr);
279 [ # # ]: 0 : rAttrHandler.PushAndChg( *pAttr, rFnt );
280 [ # # ]: 0 : if( RES_CHRATR_COLOR == nWhich )
281 : 0 : rFnt.SetNoCol( sal_True );
282 : : }
283 [ # # ]: 0 : nWhich = aIter.NextWhich();
284 : : }
285 : :
286 [ # # ]: 0 : ++nRet;
287 : : }
288 : 0 : break;
289 : : }
290 : 0 : nStart = STRING_LEN;
291 : 0 : nEnd = STRING_LEN;
292 : : }
293 : : }
294 : 0 : return nRet + EnterExtend( rFnt, nNew );
295 : : }
296 : :
297 : 0 : void SwRedlineItr::FillHints( MSHORT nAuthor, RedlineType_t eType )
298 : : {
299 [ # # # # ]: 0 : switch ( eType )
300 : : {
301 : : case nsRedlineType_t::REDLINE_INSERT:
302 : 0 : SW_MOD()->GetInsertAuthorAttr(nAuthor, *pSet);
303 : 0 : break;
304 : : case nsRedlineType_t::REDLINE_DELETE:
305 : 0 : SW_MOD()->GetDeletedAuthorAttr(nAuthor, *pSet);
306 : 0 : break;
307 : : case nsRedlineType_t::REDLINE_FORMAT:
308 : : case nsRedlineType_t::REDLINE_FMTCOLL:
309 : 0 : SW_MOD()->GetFormatAuthorAttr(nAuthor, *pSet);
310 : 0 : break;
311 : : default:
312 : 0 : break;
313 : : }
314 : 0 : }
315 : :
316 : 0 : void SwRedlineItr::ChangeTxtAttr( SwFont* pFnt, SwTxtAttr &rHt, sal_Bool bChg )
317 : : {
318 : : OSL_ENSURE( IsOn(), "SwRedlineItr::ChangeTxtAttr: Off?" );
319 : :
320 [ # # ][ # # ]: 0 : if( !bShow && !pExt )
321 : 0 : return;
322 : :
323 [ # # ]: 0 : if( bChg )
324 : : {
325 [ # # ][ # # ]: 0 : if ( pExt && pExt->IsOn() )
[ # # ]
326 : 0 : rAttrHandler.PushAndChg( rHt, *pExt->GetFont() );
327 : : else
328 : 0 : rAttrHandler.PushAndChg( rHt, *pFnt );
329 : : }
330 : : else
331 : : {
332 : : OSL_ENSURE( ! pExt || ! pExt->IsOn(), "Pop of attribute during opened extension" );
333 : 0 : rAttrHandler.PopAndChg( rHt, *pFnt );
334 : : }
335 : : }
336 : :
337 : 0 : void SwRedlineItr::_Clear( SwFont* pFnt )
338 : : {
339 : : OSL_ENSURE( bOn, "SwRedlineItr::Clear: Off?" );
340 : 0 : bOn = sal_False;
341 [ # # ]: 0 : while (!m_Hints.empty())
342 : : {
343 : 0 : SwTxtAttr *pPos = m_Hints.front();
344 : 0 : m_Hints.pop_front();
345 [ # # ]: 0 : if( pFnt )
346 : 0 : rAttrHandler.PopAndChg( *pPos, *pFnt );
347 : : else
348 : 0 : rAttrHandler.Pop( *pPos );
349 : 0 : SwTxtAttr::Destroy(pPos, const_cast<SwDoc&>(rDoc).GetAttrPool() );
350 : : }
351 [ # # ]: 0 : if( pFnt )
352 : 0 : pFnt->SetNoCol( sal_False );
353 : 0 : }
354 : :
355 : 0 : xub_StrLen SwRedlineItr::_GetNextRedln( xub_StrLen nNext )
356 : : {
357 : 0 : nNext = NextExtend( nNext );
358 [ # # ][ # # ]: 0 : if( !bShow || MSHRT_MAX == nFirst )
359 : 0 : return nNext;
360 [ # # ]: 0 : if( MSHRT_MAX == nAct )
361 : : {
362 : 0 : nAct = nFirst;
363 : 0 : rDoc.GetRedlineTbl()[ nAct ]->CalcStartEnd( nNdIdx, nStart, nEnd );
364 : : }
365 [ # # ][ # # ]: 0 : if( bOn || !nStart )
366 : : {
367 [ # # ]: 0 : if( nEnd < nNext )
368 : 0 : nNext = nEnd;
369 : : }
370 [ # # ]: 0 : else if( nStart < nNext )
371 : 0 : nNext = nStart;
372 : 0 : return nNext;
373 : : }
374 : :
375 : 0 : sal_Bool SwRedlineItr::_ChkSpecialUnderline() const
376 : : {
377 : : // Wenn die Unterstreichung oder das Escapement vom Redling kommt,
378 : : // wenden wir immer das SpecialUnderlining, d.h. die Unterstreichung
379 : : // unter der Grundlinie an.
380 [ # # ]: 0 : for (MSHORT i = 0; i < m_Hints.size(); ++i)
381 : : {
382 : 0 : MSHORT nWhich = m_Hints[i]->Which();
383 [ # # ][ # # ]: 0 : if( RES_CHRATR_UNDERLINE == nWhich ||
384 : : RES_CHRATR_ESCAPEMENT == nWhich )
385 : 0 : return sal_True;
386 : : }
387 : 0 : return sal_False;
388 : : }
389 : :
390 : 0 : sal_Bool SwRedlineItr::CheckLine( xub_StrLen nChkStart, xub_StrLen nChkEnd )
391 : : {
392 [ # # ]: 0 : if( nFirst == MSHRT_MAX )
393 : 0 : return sal_False;
394 [ # # ]: 0 : if( nChkEnd == nChkStart ) // Leerzeilen gucken ein Zeichen weiter.
395 : 0 : ++nChkEnd;
396 : 0 : xub_StrLen nOldStart = nStart;
397 : 0 : xub_StrLen nOldEnd = nEnd;
398 : 0 : xub_StrLen nOldAct = nAct;
399 : 0 : sal_Bool bRet = sal_False;
400 : :
401 [ # # ]: 0 : for( nAct = nFirst; nAct < rDoc.GetRedlineTbl().size() ; ++nAct )
402 : : {
403 : 0 : rDoc.GetRedlineTbl()[ nAct ]->CalcStartEnd( nNdIdx, nStart, nEnd );
404 [ # # ]: 0 : if( nChkEnd < nStart )
405 : 0 : break;
406 [ # # ][ # # ]: 0 : if( nChkStart <= nEnd && ( nChkEnd > nStart || STRING_LEN == nEnd ) )
[ # # ]
407 : : {
408 : 0 : bRet = sal_True;
409 : 0 : break;
410 : : }
411 : : }
412 : :
413 : 0 : nStart = nOldStart;
414 : 0 : nEnd = nOldEnd;
415 : 0 : nAct = nOldAct;
416 : 0 : return bRet;
417 : : }
418 : :
419 : 0 : void SwExtend::ActualizeFont( SwFont &rFnt, MSHORT nAttr )
420 : : {
421 [ # # ]: 0 : if ( nAttr & EXTTEXTINPUT_ATTR_UNDERLINE )
422 : 0 : rFnt.SetUnderline( UNDERLINE_SINGLE );
423 [ # # ]: 0 : else if ( nAttr & EXTTEXTINPUT_ATTR_BOLDUNDERLINE )
424 : 0 : rFnt.SetUnderline( UNDERLINE_BOLD );
425 [ # # ]: 0 : else if ( nAttr & EXTTEXTINPUT_ATTR_DOTTEDUNDERLINE )
426 : 0 : rFnt.SetUnderline( UNDERLINE_DOTTED );
427 [ # # ]: 0 : else if ( nAttr & EXTTEXTINPUT_ATTR_DASHDOTUNDERLINE )
428 : 0 : rFnt.SetUnderline( UNDERLINE_DOTTED );
429 : :
430 [ # # ]: 0 : if ( nAttr & EXTTEXTINPUT_ATTR_REDTEXT )
431 [ # # ]: 0 : rFnt.SetColor( Color( COL_RED ) );
432 : :
433 [ # # ]: 0 : if ( nAttr & EXTTEXTINPUT_ATTR_HIGHLIGHT )
434 : : {
435 : 0 : const StyleSettings& rStyleSettings = GetpApp()->GetSettings().GetStyleSettings();
436 : 0 : rFnt.SetColor( rStyleSettings.GetHighlightTextColor() );
437 : 0 : rFnt.SetBackColor( new Color( rStyleSettings.GetHighlightColor() ) );
438 : : }
439 [ # # ]: 0 : if ( nAttr & EXTTEXTINPUT_ATTR_GRAYWAVELINE )
440 : 0 : rFnt.SetGreyWave( sal_True );
441 : 0 : }
442 : :
443 : 0 : short SwExtend::Enter( SwFont& rFnt, xub_StrLen nNew )
444 : : {
445 : : OSL_ENSURE( !Inside(), "SwExtend: Enter without Leave" );
446 : : OSL_ENSURE( !pFnt, "SwExtend: Enter with Font" );
447 : 0 : nPos = nNew;
448 [ # # ]: 0 : if( Inside() )
449 : : {
450 [ # # ]: 0 : pFnt = new SwFont( rFnt );
451 : 0 : ActualizeFont( rFnt, rArr[ nPos - nStart ] );
452 : 0 : return 1;
453 : : }
454 : 0 : return 0;
455 : : }
456 : :
457 : 0 : sal_Bool SwExtend::_Leave( SwFont& rFnt, xub_StrLen nNew )
458 : : {
459 : : OSL_ENSURE( Inside(), "SwExtend: Leave without Enter" );
460 : 0 : MSHORT nOldAttr = rArr[ nPos - nStart ];
461 : 0 : nPos = nNew;
462 [ # # ]: 0 : if( Inside() )
463 : : { // Wir sind innerhalb des ExtendText-Bereichs geblieben
464 : 0 : MSHORT nAttr = rArr[ nPos - nStart ];
465 [ # # ]: 0 : if( nOldAttr != nAttr ) // Gibt es einen (inneren) Attributwechsel?
466 : : {
467 : 0 : rFnt = *pFnt;
468 : 0 : ActualizeFont( rFnt, nAttr );
469 : : }
470 : : }
471 : : else
472 : : {
473 : 0 : rFnt = *pFnt;
474 [ # # ]: 0 : delete pFnt;
475 : 0 : pFnt = NULL;
476 : 0 : return sal_True;
477 : : }
478 : 0 : return sal_False;
479 : : }
480 : :
481 : 0 : xub_StrLen SwExtend::Next( xub_StrLen nNext )
482 : : {
483 [ # # ]: 0 : if( nPos < nStart )
484 : : {
485 [ # # ]: 0 : if( nNext > nStart )
486 : 0 : nNext = nStart;
487 : : }
488 [ # # ]: 0 : else if( nPos < nEnd )
489 : : {
490 : 0 : MSHORT nIdx = nPos - nStart;
491 : 0 : MSHORT nAttr = rArr[ nIdx ];
492 [ # # ][ # # ]: 0 : while( ++nIdx < rArr.size() && nAttr == rArr[ nIdx ] )
[ # # ]
493 : : ; //nothing
494 : 0 : nIdx = nIdx + nStart;
495 [ # # ]: 0 : if( nNext > nIdx )
496 : 0 : nNext = nIdx;
497 : : }
498 : 0 : return nNext;
499 : : }
500 : :
501 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|