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 <hints.hxx>
31 : : #include <svl/ctloptions.hxx>
32 : : #include <sfx2/printer.hxx>
33 : : #include <sfx2/sfxuno.hxx>
34 : : #include <editeng/langitem.hxx>
35 : : #include <editeng/lspcitem.hxx>
36 : : #include <editeng/lrspitem.hxx>
37 : : #include <editeng/ulspitem.hxx>
38 : : #include <editeng/brshitem.hxx>
39 : : #include <editeng/pgrditem.hxx>
40 : : #include <swmodule.hxx>
41 : : #include <SwSmartTagMgr.hxx>
42 : : #include <doc.hxx> // GetDoc()
43 : : #include "rootfrm.hxx"
44 : : #include <pagefrm.hxx> // InvalidateSpelling
45 : : #include <rootfrm.hxx>
46 : : #include <viewsh.hxx> // ViewShell
47 : : #include <pam.hxx> // SwPosition
48 : : #include <ndtxt.hxx> // SwTxtNode
49 : : #include <txtatr.hxx>
50 : : #include <paratr.hxx>
51 : : #include <viewopt.hxx>
52 : : #include <dflyobj.hxx>
53 : : #include <flyfrm.hxx>
54 : : #include <tabfrm.hxx>
55 : : #include <frmtool.hxx>
56 : : #include <pagedesc.hxx> // SwPageDesc
57 : : #include <tgrditem.hxx>
58 : : #include <dbg_lay.hxx>
59 : : #include <fmtfld.hxx>
60 : : #include <fmtftn.hxx>
61 : : #include <txtfld.hxx>
62 : : #include <txtftn.hxx>
63 : : #include <charatr.hxx>
64 : : #include <ftninfo.hxx>
65 : : #include <fmtline.hxx>
66 : : #include <txtfrm.hxx> // SwTxtFrm
67 : : #include <sectfrm.hxx> // SwSectFrm
68 : : #include <itrform2.hxx> // Iteratoren
69 : : #include <widorp.hxx> // SwFrmBreak
70 : : #include <txtcache.hxx>
71 : : #include <fntcache.hxx> // GetLineSpace benutzt pLastFont
72 : : #include <SwGrammarMarkUp.hxx>
73 : : #include <lineinfo.hxx>
74 : : #include <SwPortionHandler.hxx>
75 : : #include <dcontact.hxx>
76 : : #include <sortedobjs.hxx>
77 : : #include <txtflcnt.hxx> // SwTxtFlyCnt
78 : : #include <fmtflcnt.hxx> // SwFmtFlyCnt
79 : : #include <fmtcntnt.hxx> // SwFmtCntnt
80 : : #include <numrule.hxx>
81 : : #include <swtable.hxx>
82 : : #include <fldupde.hxx>
83 : : #include <IGrammarContact.hxx>
84 : : #include <switerator.hxx>
85 : :
86 : :
87 [ + + ][ + + ]: 3588825 : TYPEINIT1( SwTxtFrm, SwCntntFrm );
88 : :
89 : : // Switches width and height of the text frame
90 : 40 : void SwTxtFrm::SwapWidthAndHeight()
91 : : {
92 [ + + ]: 40 : if ( ! bIsSwapped )
93 : : {
94 : 20 : const long nPrtOfstX = Prt().Pos().X();
95 : 20 : Prt().Pos().X() = Prt().Pos().Y();
96 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
97 [ - + ]: 20 : if( IsVertLR() )
98 : 0 : Prt().Pos().Y() = nPrtOfstX;
99 : : else
100 : 20 : Prt().Pos().Y() = Frm().Width() - ( nPrtOfstX + Prt().Width() );
101 : :
102 : : }
103 : : else
104 : : {
105 : 20 : const long nPrtOfstY = Prt().Pos().Y();
106 : 20 : Prt().Pos().Y() = Prt().Pos().X();
107 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
108 [ - + ]: 20 : if( IsVertLR() )
109 : 0 : Prt().Pos().X() = nPrtOfstY;
110 : : else
111 : 20 : Prt().Pos().X() = Frm().Height() - ( nPrtOfstY + Prt().Height() );
112 : : }
113 : :
114 : 40 : const long nFrmWidth = Frm().Width();
115 : 40 : Frm().Width( Frm().Height() );
116 : 40 : Frm().Height( nFrmWidth );
117 : 40 : const long nPrtWidth = Prt().Width();
118 : 40 : Prt().Width( Prt().Height() );
119 : 40 : Prt().Height( nPrtWidth );
120 : :
121 : 40 : bIsSwapped = ! bIsSwapped;
122 : 40 : }
123 : :
124 : : // Calculates the coordinates of a rectangle when switching from
125 : : // horizontal to vertical layout.
126 : 0 : void SwTxtFrm::SwitchHorizontalToVertical( SwRect& rRect ) const
127 : : {
128 : : // calc offset inside frame
129 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
130 : : long nOfstX, nOfstY;
131 [ # # ]: 0 : if ( IsVertLR() )
132 : : {
133 : 0 : nOfstX = rRect.Left() - Frm().Left();
134 : 0 : nOfstY = rRect.Top() - Frm().Top();
135 : : }
136 : : else
137 : : {
138 : 0 : nOfstX = rRect.Left() - Frm().Left();
139 : 0 : nOfstY = rRect.Top() + rRect.Height() - Frm().Top();
140 : : }
141 : :
142 : 0 : const long nWidth = rRect.Width();
143 : 0 : const long nHeight = rRect.Height();
144 : :
145 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
146 [ # # ]: 0 : if ( IsVertLR() )
147 : 0 : rRect.Left(Frm().Left() + nOfstY);
148 : : else
149 : : {
150 [ # # ]: 0 : if ( bIsSwapped )
151 : 0 : rRect.Left( Frm().Left() + Frm().Height() - nOfstY );
152 : : else
153 : : // frame is rotated
154 : 0 : rRect.Left( Frm().Left() + Frm().Width() - nOfstY );
155 : : }
156 : :
157 : 0 : rRect.Top( Frm().Top() + nOfstX );
158 : 0 : rRect.Width( nHeight );
159 : 0 : rRect.Height( nWidth );
160 : 0 : }
161 : :
162 : : // Calculates the coordinates of a point when switching from
163 : : // horizontal to vertical layout.
164 : 0 : void SwTxtFrm::SwitchHorizontalToVertical( Point& rPoint ) const
165 : : {
166 : : // calc offset inside frame
167 : 0 : const long nOfstX = rPoint.X() - Frm().Left();
168 : 0 : const long nOfstY = rPoint.Y() - Frm().Top();
169 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
170 [ # # ]: 0 : if ( IsVertLR() )
171 : 0 : rPoint.X() = Frm().Left() + nOfstY;
172 : : else
173 : : {
174 [ # # ]: 0 : if ( bIsSwapped )
175 : 0 : rPoint.X() = Frm().Left() + Frm().Height() - nOfstY;
176 : : else
177 : : // calc rotated coords
178 : 0 : rPoint.X() = Frm().Left() + Frm().Width() - nOfstY;
179 : : }
180 : :
181 : 0 : rPoint.Y() = Frm().Top() + nOfstX;
182 : 0 : }
183 : :
184 : : // Calculates the a limit value when switching from
185 : : // horizontal to vertical layout.
186 : 0 : long SwTxtFrm::SwitchHorizontalToVertical( long nLimit ) const
187 : : {
188 : 0 : Point aTmp( 0, nLimit );
189 : 0 : SwitchHorizontalToVertical( aTmp );
190 : 0 : return aTmp.X();
191 : : }
192 : :
193 : : // Calculates the coordinates of a rectangle when switching from
194 : : // vertical to horizontal layout.
195 : 0 : void SwTxtFrm::SwitchVerticalToHorizontal( SwRect& rRect ) const
196 : : {
197 : : long nOfstX;
198 : :
199 : : // calc offset inside frame
200 : :
201 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
202 [ # # ]: 0 : if ( IsVertLR() )
203 : 0 : nOfstX = rRect.Left() - Frm().Left();
204 : : else
205 : : {
206 [ # # ]: 0 : if ( bIsSwapped )
207 : 0 : nOfstX = Frm().Left() + Frm().Height() - ( rRect.Left() + rRect.Width() );
208 : : else
209 : 0 : nOfstX = Frm().Left() + Frm().Width() - ( rRect.Left() + rRect.Width() );
210 : : }
211 : :
212 : 0 : const long nOfstY = rRect.Top() - Frm().Top();
213 : 0 : const long nWidth = rRect.Height();
214 : 0 : const long nHeight = rRect.Width();
215 : :
216 : : // calc rotated coords
217 : 0 : rRect.Left( Frm().Left() + nOfstY );
218 : 0 : rRect.Top( Frm().Top() + nOfstX );
219 : 0 : rRect.Width( nWidth );
220 : 0 : rRect.Height( nHeight );
221 : 0 : }
222 : :
223 : : // Calculates the coordinates of a point when switching from
224 : : // vertical to horizontal layout.
225 : 0 : void SwTxtFrm::SwitchVerticalToHorizontal( Point& rPoint ) const
226 : : {
227 : : long nOfstX;
228 : :
229 : : // calc offset inside frame
230 : :
231 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
232 [ # # ]: 0 : if ( IsVertLR() )
233 : 0 : nOfstX = rPoint.X() - Frm().Left();
234 : : else
235 : : {
236 [ # # ]: 0 : if ( bIsSwapped )
237 : 0 : nOfstX = Frm().Left() + Frm().Height() - rPoint.X();
238 : : else
239 : 0 : nOfstX = Frm().Left() + Frm().Width() - rPoint.X();
240 : : }
241 : :
242 : 0 : const long nOfstY = rPoint.Y() - Frm().Top();
243 : :
244 : : // calc rotated coords
245 : 0 : rPoint.X() = Frm().Left() + nOfstY;
246 : 0 : rPoint.Y() = Frm().Top() + nOfstX;
247 : 0 : }
248 : :
249 : : // Calculates the a limit value when switching from
250 : : // vertical to horizontal layout.
251 : 0 : long SwTxtFrm::SwitchVerticalToHorizontal( long nLimit ) const
252 : : {
253 : 0 : Point aTmp( nLimit, 0 );
254 : 0 : SwitchVerticalToHorizontal( aTmp );
255 : 0 : return aTmp.Y();
256 : : }
257 : :
258 : 338955 : SwFrmSwapper::SwFrmSwapper( const SwTxtFrm* pTxtFrm, sal_Bool bSwapIfNotSwapped )
259 : 338955 : : pFrm( pTxtFrm ), bUndo( sal_False )
260 : : {
261 [ + + ]: 338987 : if ( pFrm->IsVertical() &&
[ + + - + ]
[ + - - + ]
[ + + ]
262 : 20 : ( ( bSwapIfNotSwapped && ! pFrm->IsSwapped() ) ||
263 : 12 : ( ! bSwapIfNotSwapped && pFrm->IsSwapped() ) ) )
264 : : {
265 : 20 : bUndo = sal_True;
266 : 20 : ((SwTxtFrm*)pFrm)->SwapWidthAndHeight();
267 : : }
268 : 338955 : }
269 : :
270 : 338955 : SwFrmSwapper::~SwFrmSwapper()
271 : : {
272 [ + + ]: 338955 : if ( bUndo )
273 : 20 : ((SwTxtFrm*)pFrm)->SwapWidthAndHeight();
274 : 338955 : }
275 : :
276 : 0 : void SwTxtFrm::SwitchLTRtoRTL( SwRect& rRect ) const
277 : : {
278 [ # # ][ # # ]: 0 : SWAP_IF_NOT_SWAPPED( this )
[ # # ]
279 : :
280 : 0 : long nWidth = rRect.Width();
281 : 0 : rRect.Left( 2 * ( Frm().Left() + Prt().Left() ) +
282 : 0 : Prt().Width() - rRect.Right() - 1 );
283 : :
284 : 0 : rRect.Width( nWidth );
285 : :
286 [ # # ]: 0 : UNDO_SWAP( this )
287 : 0 : }
288 : :
289 : 0 : void SwTxtFrm::SwitchLTRtoRTL( Point& rPoint ) const
290 : : {
291 [ # # ][ # # ]: 0 : SWAP_IF_NOT_SWAPPED( this )
[ # # ]
292 : :
293 : 0 : rPoint.X() = 2 * ( Frm().Left() + Prt().Left() ) + Prt().Width() - rPoint.X() - 1;
294 : :
295 [ # # ]: 0 : UNDO_SWAP( this )
296 : 0 : }
297 : :
298 : 5015 : SwLayoutModeModifier::SwLayoutModeModifier( const OutputDevice& rOutp ) :
299 : 5015 : rOut( rOutp ), nOldLayoutMode( rOutp.GetLayoutMode() )
300 : : {
301 : 5015 : }
302 : :
303 : 5015 : SwLayoutModeModifier::~SwLayoutModeModifier()
304 : : {
305 : 5015 : ((OutputDevice&)rOut).SetLayoutMode( nOldLayoutMode );
306 : 5015 : }
307 : :
308 : 81 : void SwLayoutModeModifier::Modify( sal_Bool bChgToRTL )
309 : : {
310 : : ((OutputDevice&)rOut).SetLayoutMode( bChgToRTL ?
311 : : TEXT_LAYOUT_BIDI_STRONG | TEXT_LAYOUT_BIDI_RTL :
312 [ - + ]: 81 : TEXT_LAYOUT_BIDI_STRONG );
313 : 81 : }
314 : :
315 : 3575 : void SwLayoutModeModifier::SetAuto()
316 : : {
317 : 3575 : const sal_uLong nNewLayoutMode = nOldLayoutMode & ~TEXT_LAYOUT_BIDI_STRONG;
318 : 3575 : ((OutputDevice&)rOut).SetLayoutMode( nNewLayoutMode );
319 : 3575 : }
320 : :
321 : 81142 : SwDigitModeModifier::SwDigitModeModifier( const OutputDevice& rOutp, LanguageType eCurLang ) :
322 : 81142 : rOut( rOutp ), nOldLanguageType( rOutp.GetDigitLanguage() )
323 : : {
324 : 81142 : LanguageType eLang = eCurLang;
325 : 81142 : const SvtCTLOptions::TextNumerals nTextNumerals = SW_MOD()->GetCTLOptions().GetCTLTextNumerals();
326 : :
327 [ - + ]: 81142 : if ( SvtCTLOptions::NUMERALS_HINDI == nTextNumerals )
328 : 0 : eLang = LANGUAGE_ARABIC_SAUDI_ARABIA;
329 [ + - ]: 81142 : else if ( SvtCTLOptions::NUMERALS_ARABIC == nTextNumerals )
330 : 81142 : eLang = LANGUAGE_ENGLISH;
331 [ # # ]: 0 : else if ( SvtCTLOptions::NUMERALS_SYSTEM == nTextNumerals )
332 : 0 : eLang = (LanguageType)::GetAppLanguage();
333 : :
334 : 81142 : ((OutputDevice&)rOut).SetDigitLanguage( eLang );
335 : 81142 : }
336 : :
337 : 81142 : SwDigitModeModifier::~SwDigitModeModifier()
338 : : {
339 : 81142 : ((OutputDevice&)rOut).SetDigitLanguage( nOldLanguageType );
340 : 81142 : }
341 : :
342 : : /*************************************************************************
343 : : * SwTxtFrm::Init()
344 : : *************************************************************************/
345 : :
346 : 1864 : void SwTxtFrm::Init()
347 : : {
348 : : OSL_ENSURE( !IsLocked(), "+SwTxtFrm::Init: this ist locked." );
349 [ + - ]: 1864 : if( !IsLocked() )
350 : : {
351 : 1864 : ClearPara();
352 : 1864 : ResetBlinkPor();
353 : : //Die Flags direkt setzen um ResetPreps und damit ein unnuetzes GetPara
354 : : //einzusparen.
355 : : // Nicht bOrphan, bLocked oder bWait auf sal_False setzen !
356 : : // bOrphan = bFlag7 = bFlag8 = sal_False;
357 : : }
358 : 1864 : }
359 : :
360 : : /*************************************************************************
361 : : * SwTxtFrm::SwTxtFrm()
362 : : *************************************************************************/
363 : 5299 : SwTxtFrm::SwTxtFrm(SwTxtNode * const pNode, SwFrm* pSib )
364 : : : SwCntntFrm( pNode, pSib )
365 : : , nAllLines( 0 )
366 : : , nThisLines( 0 )
367 : : , mnFlyAnchorOfst( 0 )
368 : : , mnFlyAnchorOfstNoWrap( 0 )
369 : : , mnFtnLine( 0 )
370 : : , mnHeightOfLastLine( 0 ) // OD 2004-03-17 #i11860#
371 : : , mnAdditionalFirstLineOffset( 0 )
372 : : , nOfst( 0 )
373 : : , nCacheIdx( MSHRT_MAX )
374 : : , bLocked( false )
375 : : , bFormatted( false )
376 : : , bWidow( false )
377 : : , bJustWidow( false )
378 : : , bEmpty( false )
379 : : , bInFtnConnect( false )
380 : : , bFtn( false )
381 : : , bRepaint( false )
382 : : , bBlinkPor( false )
383 : : , bFieldFollow( false )
384 : : , bHasAnimation( false )
385 : : , bIsSwapped( false )
386 : 5299 : , mbFollowFormatAllowed( true ) // OD 14.03.2003 #i11760#
387 : : {
388 : 5299 : nType = FRMC_TXT;
389 : 5299 : }
390 : :
391 : : /*************************************************************************
392 : : * SwTxtFrm::~SwTxtFrm()
393 : : *************************************************************************/
394 : 5101 : SwTxtFrm::~SwTxtFrm()
395 : : {
396 : : // Remove associated SwParaPortion from pTxtCache
397 [ + - ]: 5101 : ClearPara();
398 [ - + ]: 10202 : }
399 : :
400 : 40449 : const XubString& SwTxtFrm::GetTxt() const
401 : : {
402 : 40449 : return GetTxtNode()->GetTxt();
403 : : }
404 : :
405 : 10375 : void SwTxtFrm::ResetPreps()
406 : : {
407 [ + - ]: 10375 : if ( GetCacheIdx() != MSHRT_MAX )
408 : : {
409 : : SwParaPortion *pPara;
410 [ + - ]: 10375 : if( 0 != (pPara = GetPara()) )
411 : 10375 : pPara->ResetPreps();
412 : : }
413 : 10375 : }
414 : :
415 : : /*************************************************************************
416 : : * SwTxtFrm::IsHiddenNow()
417 : : *************************************************************************/
418 : 252803 : sal_Bool SwTxtFrm::IsHiddenNow() const
419 : : {
420 [ + - ]: 252803 : SwFrmSwapper aSwapper( this, sal_True );
421 : :
422 [ + + ][ + + ]: 252803 : if( !Frm().Width() && IsValid() && GetUpper()->IsValid() )
[ + - ][ + + ]
423 : : //bei Stackueberlauf (StackHack) invalid!
424 : : {
425 : : // OSL_FAIL( "SwTxtFrm::IsHiddenNow: thin frame" );
426 : 16 : return sal_True;
427 : : }
428 : :
429 [ + - ]: 252787 : const bool bHiddenCharsHidePara = GetTxtNode()->HasHiddenCharAttribute( true );
430 [ + - ]: 252787 : const bool bHiddenParaField = GetTxtNode()->HasHiddenParaField();
431 : 252787 : const ViewShell* pVsh = getRootFrm()->GetCurrShell();
432 : :
433 [ + + ][ - + ]: 252787 : if ( pVsh && ( bHiddenCharsHidePara || bHiddenParaField ) )
[ + - ]
434 : : {
435 [ - + # # : 1844 : if (
# # ]
[ + - + - ]
[ + - ]
436 : : ( bHiddenParaField &&
437 : 0 : ( !pVsh->GetViewOptions()->IsShowHiddenPara() &&
438 : 0 : !pVsh->GetViewOptions()->IsFldName() ) ) ||
439 : : ( bHiddenCharsHidePara &&
440 : 922 : !pVsh->GetViewOptions()->IsShowHiddenChar() ) )
441 : : {
442 : 922 : return sal_True;
443 : : }
444 : : }
445 : :
446 : 252803 : return sal_False;
447 : : }
448 : :
449 : :
450 : : /*************************************************************************
451 : : * SwTxtFrm::HideHidden()
452 : : *************************************************************************/
453 : : // Entfernt die Anhaengsel des Textfrms wenn dieser hidden ist
454 : :
455 : 46 : void SwTxtFrm::HideHidden()
456 : : {
457 : : OSL_ENSURE( !GetFollow() && IsHiddenNow(),
458 : : "HideHidden on visible frame of hidden frame has follow" );
459 : :
460 : 46 : const xub_StrLen nEnd = STRING_LEN;
461 : 46 : HideFootnotes( GetOfst(), nEnd );
462 : : // OD 2004-01-15 #110582#
463 : 46 : HideAndShowObjects();
464 : :
465 : : //Die Formatinfos sind jetzt obsolete
466 : 46 : ClearPara();
467 : 46 : }
468 : :
469 : : /*************************************************************************
470 : : * SwTxtFrm::HideFootnotes()
471 : : *************************************************************************/
472 : 46 : void SwTxtFrm::HideFootnotes( xub_StrLen nStart, xub_StrLen nEnd )
473 : : {
474 : 46 : const SwpHints *pHints = GetTxtNode()->GetpSwpHints();
475 [ + - ]: 46 : if( pHints )
476 : : {
477 : 46 : const sal_uInt16 nSize = pHints->Count();
478 : 46 : SwPageFrm *pPage = 0;
479 [ + + ]: 104 : for ( sal_uInt16 i = 0; i < nSize; ++i )
480 : : {
481 : 58 : const SwTxtAttr *pHt = (*pHints)[i];
482 [ - + ]: 58 : if ( pHt->Which() == RES_TXTATR_FTN )
483 : : {
484 : 0 : const xub_StrLen nIdx = *pHt->GetStart();
485 [ # # ]: 0 : if ( nEnd < nIdx )
486 : 0 : break;
487 [ # # ]: 0 : if( nStart <= nIdx )
488 : : {
489 [ # # ]: 0 : if( !pPage )
490 : 0 : pPage = FindPageFrm();
491 : 0 : pPage->RemoveFtn( this, (SwTxtFtn*)pHt );
492 : : }
493 : : }
494 : : }
495 : : }
496 : 46 : }
497 : :
498 : : // #120729# - hotfix
499 : : // as-character anchored graphics, which are used for a graphic bullet list.
500 : : // As long as these graphic bullet list aren't imported, do not hide a
501 : : // at-character anchored object, if
502 : : // (a) the document is an imported WW8 document -
503 : : // checked by checking certain compatibility options -,
504 : : // (b) the paragraph is the last content in the document and
505 : : // (c) the anchor character is an as-character anchored graphic.
506 : 0 : bool lcl_HideObj( const SwTxtFrm& _rFrm,
507 : : const RndStdIds _eAnchorType,
508 : : const xub_StrLen _nObjAnchorPos,
509 : : SwAnchoredObject* _pAnchoredObj )
510 : : {
511 : 0 : bool bRet( true );
512 : :
513 [ # # ]: 0 : if (_eAnchorType == FLY_AT_CHAR)
514 : : {
515 : 0 : const IDocumentSettingAccess* pIDSA = _rFrm.GetTxtNode()->getIDocumentSettingAccess();
516 [ # # ][ # # : 0 : if ( !pIDSA->get(IDocumentSettingAccess::USE_FORMER_TEXT_WRAPPING) &&
# # # # #
# # # #
# ]
517 : 0 : !pIDSA->get(IDocumentSettingAccess::OLD_LINE_SPACING) &&
518 : 0 : !pIDSA->get(IDocumentSettingAccess::USE_FORMER_OBJECT_POS) &&
519 : 0 : pIDSA->get(IDocumentSettingAccess::CONSIDER_WRAP_ON_OBJECT_POSITION) &&
520 : 0 : _rFrm.IsInDocBody() && !_rFrm.FindNextCnt() )
521 : : {
522 : : const xub_Unicode cAnchorChar =
523 : 0 : _rFrm.GetTxtNode()->GetTxt().GetChar( _nObjAnchorPos );
524 [ # # ]: 0 : if ( cAnchorChar == CH_TXTATR_BREAKWORD )
525 : : {
526 : : const SwTxtAttr* const pHint(
527 : : _rFrm.GetTxtNode()->GetTxtAttrForCharAt(_nObjAnchorPos,
528 : 0 : RES_TXTATR_FLYCNT) );
529 [ # # ]: 0 : if ( pHint )
530 : : {
531 : : const SwFrmFmt* pFrmFmt =
532 : 0 : static_cast<const SwTxtFlyCnt*>(pHint)->GetFlyCnt().GetFrmFmt();
533 [ # # ]: 0 : if ( pFrmFmt->Which() == RES_FLYFRMFMT )
534 : : {
535 [ # # ][ # # ]: 0 : SwNodeIndex nCntntIndex = *(pFrmFmt->GetCntnt().GetCntntIdx());
536 [ # # ]: 0 : nCntntIndex++;
537 [ # # ]: 0 : if ( nCntntIndex.GetNode().IsNoTxtNode() )
538 : : {
539 : 0 : bRet = false;
540 : : // set needed data structure values for object positioning
541 [ # # ][ # # ]: 0 : SWRECTFN( (&_rFrm) );
[ # # ][ # # ]
[ # # ]
542 : 0 : SwRect aLastCharRect( _rFrm.Frm() );
543 [ # # ][ # # ]: 0 : (aLastCharRect.*fnRect->fnSetWidth)( 1 );
544 : 0 : _pAnchoredObj->maLastCharRect = aLastCharRect;
545 [ # # ][ # # ]: 0 : _pAnchoredObj->mnLastTopOfLine = (aLastCharRect.*fnRect->fnGetTop)();
546 [ # # ]: 0 : }
547 : : }
548 : : }
549 : : }
550 : : }
551 : : }
552 : :
553 : 0 : return bRet;
554 : : }
555 : : /*************************************************************************
556 : : * SwTxtFrm::HideAndShowObjects()
557 : : *************************************************************************/
558 : : /** method to hide/show objects
559 : :
560 : : OD 2004-01-15 #110582#
561 : : method hides respectively shows objects, which are anchored at paragraph,
562 : : at/as a character of the paragraph, corresponding to the paragraph and
563 : : paragraph portion visibility.
564 : :
565 : : - is called from HideHidden() - should hide objects in hidden paragraphs and
566 : : - from _Format() - should hide/show objects in partly visible paragraphs
567 : : */
568 : 21308 : void SwTxtFrm::HideAndShowObjects()
569 : : {
570 [ + + ]: 21308 : if ( GetDrawObjs() )
571 : : {
572 [ - + ]: 903 : if ( IsHiddenNow() )
573 : : {
574 : : // complete paragraph is hidden. Thus, hide all objects
575 [ # # ]: 0 : for ( sal_uInt32 i = 0; i < GetDrawObjs()->Count(); ++i )
576 : : {
577 : 0 : SdrObject* pObj = (*GetDrawObjs())[i]->DrawObj();
578 : 0 : SwContact* pContact = static_cast<SwContact*>(pObj->GetUserCall());
579 : : // #120729# - hotfix
580 : : // under certain conditions
581 : 0 : const RndStdIds eAnchorType( pContact->GetAnchorId() );
582 : 0 : const xub_StrLen nObjAnchorPos = pContact->GetCntntAnchorIndex().GetIndex();
583 [ # # ]: 0 : if ((eAnchorType != FLY_AT_CHAR) ||
[ # # # # ]
584 : : lcl_HideObj( *this, eAnchorType, nObjAnchorPos,
585 : 0 : (*GetDrawObjs())[i] ))
586 : : {
587 : 0 : pContact->MoveObjToInvisibleLayer( pObj );
588 : : }
589 : : }
590 : : }
591 : : else
592 : : {
593 : : // paragraph is visible, but can contain hidden text portion.
594 : : // first we check if objects are allowed to be hidden:
595 : 903 : const SwTxtNode& rNode = *GetTxtNode();
596 : 903 : const ViewShell* pVsh = getRootFrm()->GetCurrShell();
597 : 903 : const bool bShouldBeHidden = !pVsh || !pVsh->GetWin() ||
598 [ + - ]: 1806 : !pVsh->GetViewOptions()->IsShowHiddenChar();
[ + - + - ]
599 : :
600 : : // Thus, show all objects, which are anchored at paragraph and
601 : : // hide/show objects, which are anchored at/as character, according
602 : : // to the visibility of the anchor character.
603 [ + + ]: 2293 : for ( sal_uInt32 i = 0; i < GetDrawObjs()->Count(); ++i )
604 : : {
605 : 1390 : SdrObject* pObj = (*GetDrawObjs())[i]->DrawObj();
606 : 1390 : SwContact* pContact = static_cast<SwContact*>(pObj->GetUserCall());
607 : : // #120729# - determine anchor type only once
608 : 1390 : const RndStdIds eAnchorType( pContact->GetAnchorId() );
609 : :
610 [ + + ]: 1390 : if (eAnchorType == FLY_AT_PARA)
611 : : {
612 : 344 : pContact->MoveObjToVisibleLayer( pObj );
613 : : }
614 [ + + ][ + - ]: 1046 : else if ((eAnchorType == FLY_AT_CHAR) ||
615 : : (eAnchorType == FLY_AS_CHAR))
616 : : {
617 : : xub_StrLen nHiddenStart;
618 : : xub_StrLen nHiddenEnd;
619 [ + - ]: 1046 : xub_StrLen nObjAnchorPos = pContact->GetCntntAnchorIndex().GetIndex();
620 [ + - ]: 1046 : SwScriptInfo::GetBoundsOfHiddenRange( rNode, nObjAnchorPos, nHiddenStart, nHiddenEnd, 0 );
621 : : // #120729# - hotfix
622 : : // under certain conditions
623 [ - + ][ # # ]: 1046 : if ( nHiddenStart != STRING_LEN && bShouldBeHidden &&
[ # # ][ - + ]
624 [ # # ][ # # ]: 0 : lcl_HideObj( *this, eAnchorType, nObjAnchorPos, (*GetDrawObjs())[i] ) )
625 [ # # ]: 0 : pContact->MoveObjToInvisibleLayer( pObj );
626 : : else
627 [ + - ]: 1046 : pContact->MoveObjToVisibleLayer( pObj );
628 : : }
629 : : else
630 : : {
631 : : OSL_FAIL( "<SwTxtFrm::HideAndShowObjects()> - object not anchored at/inside paragraph!?" );
632 : : }
633 : : }
634 : : }
635 : : }
636 : :
637 [ + + ]: 21308 : if (IsFollow())
638 : : {
639 : 2036 : SwTxtFrm *pMaster = FindMaster();
640 : : OSL_ENSURE(pMaster, "SwTxtFrm without master");
641 [ + - ]: 2036 : if (pMaster)
642 : 2036 : pMaster->HideAndShowObjects();
643 : : }
644 : 21308 : }
645 : :
646 : : /*************************************************************************
647 : : * SwTxtFrm::FindBrk()
648 : : *
649 : : * Liefert die erste Trennmoeglichkeit in der aktuellen Zeile zurueck.
650 : : * Die Methode wird in SwTxtFrm::Format() benutzt, um festzustellen, ob
651 : : * die Vorgaengerzeile mitformatiert werden muss.
652 : : * nFound ist <= nEndLine.
653 : : *************************************************************************/
654 : :
655 : 2868 : xub_StrLen SwTxtFrm::FindBrk( const XubString &rTxt,
656 : : const xub_StrLen nStart,
657 : : const xub_StrLen nEnd ) const
658 : : {
659 : : // #i104291# - applying patch to avoid overflow.
660 : 2868 : unsigned long nFound = nStart;
661 : 2868 : const xub_StrLen nEndLine = Min( nEnd, rTxt.Len() );
662 : :
663 : : // Wir ueberlesen erst alle Blanks am Anfang der Zeile (vgl. Bug 2235).
664 [ + - - + ]: 5736 : while( nFound <= nEndLine &&
[ - + ]
665 : 2868 : ' ' == rTxt.GetChar( static_cast<xub_StrLen>(nFound) ) )
666 : : {
667 : 0 : nFound++;
668 : : }
669 : :
670 : : // Eine knifflige Sache mit den TxtAttr-Dummy-Zeichen (hier "$"):
671 : : // "Dr.$Meyer" am Anfang der zweiten Zeile. Dahinter ein Blank eingegeben
672 : : // und das Wort rutscht nicht in die erste Zeile, obwohl es ginge.
673 : : // Aus diesem Grund nehmen wir das Dummy-Zeichen noch mit.
674 [ + + + + ]: 131628 : while( nFound <= nEndLine &&
[ + + ]
675 : 65200 : ' ' != rTxt.GetChar( static_cast<xub_StrLen>(nFound) ) )
676 : : {
677 : 63560 : nFound++;
678 : : }
679 : :
680 : : return nFound <= STRING_LEN
681 : : ? static_cast<xub_StrLen>(nFound)
682 [ + - ]: 2868 : : STRING_LEN;
683 : : }
684 : :
685 : : /*************************************************************************
686 : : * SwTxtFrm::IsIdxInside()
687 : : *************************************************************************/
688 : :
689 : 15771 : sal_Bool SwTxtFrm::IsIdxInside( const xub_StrLen nPos, const xub_StrLen nLen ) const
690 : : {
691 [ + + ]: 15771 : if( GetOfst() > nPos + nLen ) // d.h., der Bereich liegt komplett vor uns.
692 : 331 : return sal_False;
693 : :
694 [ + + ]: 15440 : if( !GetFollow() ) // der Bereich liegt nicht komplett vor uns,
695 : 13613 : return sal_True; // nach uns kommt niemand mehr.
696 : :
697 : 1827 : const xub_StrLen nMax = GetFollow()->GetOfst();
698 : :
699 : : // der Bereich liegt nicht komplett hinter uns bzw.
700 : : // unser Text ist geloescht worden.
701 [ - + ][ + + ]: 1827 : if( nMax > nPos || nMax > GetTxt().Len() )
[ + + ]
702 : 501 : return sal_True;
703 : :
704 : : // changes made in the first line of a follow can modify the master
705 : 1326 : const SwParaPortion* pPara = GetFollow()->GetPara();
706 [ + + ][ + + ]: 15771 : return pPara && ( nPos <= nMax + pPara->GetLen() );
707 : : }
708 : :
709 : : /*************************************************************************
710 : : * SwTxtFrm::InvalidateRange()
711 : : *************************************************************************/
712 : 2938 : inline void SwTxtFrm::InvalidateRange(const SwCharRange &aRange, const long nD)
713 : : {
714 [ + + ]: 2938 : if ( IsIdxInside( aRange.Start(), aRange.Len() ) )
715 : 2918 : _InvalidateRange( aRange, nD );
716 : 2938 : }
717 : :
718 : : /*************************************************************************
719 : : * SwTxtFrm::_InvalidateRange()
720 : : *************************************************************************/
721 : :
722 : 13032 : void SwTxtFrm::_InvalidateRange( const SwCharRange &aRange, const long nD)
723 : : {
724 [ + + ]: 13032 : if ( !HasPara() )
725 : 1662 : { InvalidateSize();
726 : 13032 : return;
727 : : }
728 : :
729 : 11370 : SetWidow( sal_False );
730 : 11370 : SwParaPortion *pPara = GetPara();
731 : :
732 : 11370 : sal_Bool bInv = sal_False;
733 [ + + ]: 11370 : if( 0 != nD )
734 : : {
735 : : //Auf nDelta werden die Differenzen zwischen alter und
736 : : //neuer Zeilenlaenge aufaddiert, deshalb ist es negativ,
737 : : //wenn Zeichen eingefuegt wurden, positiv, wenn Zeichen
738 : : //geloescht wurden.
739 : 8828 : *(pPara->GetDelta()) += nD;
740 : 8828 : bInv = sal_True;
741 : : }
742 : 11370 : SwCharRange &rReformat = *(pPara->GetReformat());
743 [ + + ]: 11370 : if(aRange != rReformat) {
744 [ - + ]: 9701 : if( STRING_LEN == rReformat.Len() )
745 : 0 : rReformat = aRange;
746 : : else
747 : 9701 : rReformat += aRange;
748 : 9701 : bInv = sal_True;
749 : : }
750 [ + + ]: 11370 : if(bInv)
751 : : {
752 : 10038 : InvalidateSize();
753 : : }
754 : : }
755 : :
756 : : /*************************************************************************
757 : : * SwTxtFrm::CalcLineSpace()
758 : : *************************************************************************/
759 : :
760 : 0 : void SwTxtFrm::CalcLineSpace()
761 : : {
762 : : OSL_ENSURE( ! IsVertical() || ! IsSwapped(),
763 : : "SwTxtFrm::CalcLineSpace with swapped frame!" );
764 : :
765 [ # # ][ # # ]: 0 : if( IsLocked() || !HasPara() )
[ # # ][ # # ]
766 : : return;
767 : :
768 : : SwParaPortion *pPara;
769 [ # # # # ]: 0 : if( GetDrawObjs() ||
[ # # # # ]
[ # # ]
770 [ # # ][ # # ]: 0 : GetTxtNode()->GetSwAttrSet().GetLRSpace().IsAutoFirst() ||
771 : 0 : ( pPara = GetPara() )->IsFixLineHeight() )
772 : : {
773 [ # # ]: 0 : Init();
774 : : return;
775 : : }
776 : :
777 : 0 : Size aNewSize( Prt().SSize() );
778 : :
779 [ # # ]: 0 : SwTxtFormatInfo aInf( this );
780 [ # # ]: 0 : SwTxtFormatter aLine( this, &aInf );
781 [ # # ]: 0 : if( aLine.GetDropLines() )
782 : : {
783 [ # # ]: 0 : Init();
784 : : return;
785 : : }
786 : :
787 [ # # ]: 0 : aLine.Top();
788 [ # # ]: 0 : aLine.RecalcRealHeight();
789 : :
790 : 0 : aNewSize.Height() = (aLine.Y() - Frm().Top()) + aLine.GetLineHeight();
791 : :
792 : 0 : SwTwips nDelta = aNewSize.Height() - Prt().Height();
793 : : // 4291: Unterlauf bei Flys
794 [ # # ]: 0 : if( aInf.GetTxtFly()->IsOn() )
795 : : {
796 : 0 : SwRect aTmpFrm( Frm() );
797 [ # # ]: 0 : if( nDelta < 0 )
798 : 0 : aTmpFrm.Height( Prt().Height() );
799 : : else
800 : 0 : aTmpFrm.Height( aNewSize.Height() );
801 [ # # ][ # # ]: 0 : if( aInf.GetTxtFly()->Relax( aTmpFrm ) )
802 : : {
803 [ # # ]: 0 : Init();
804 : : return;
805 : : }
806 : : }
807 : :
808 [ # # ]: 0 : if( nDelta )
809 : : {
810 [ # # ]: 0 : SwTxtFrmBreak aBreak( this );
811 [ # # ][ # # ]: 0 : if( GetFollow() || aBreak.IsBreakNow( aLine ) )
[ # # ][ # # ]
812 : : {
813 : : // Wenn es einen Follow() gibt, oder wenn wir an dieser
814 : : // Stelle aufbrechen muessen, so wird neu formatiert.
815 [ # # ]: 0 : Init();
816 : : }
817 : : else
818 : : {
819 : : // Alles nimmt seinen gewohnten Gang ...
820 : 0 : pPara->SetPrepAdjust();
821 : 0 : pPara->SetPrep();
822 : : }
823 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
824 : : }
825 : :
826 : : //
827 : : // SET_WRONG( nPos, nCnt, bMove )
828 : : //
829 : : #define SET_WRONG( nPos, nCnt, bMove ) \
830 : : { \
831 : : lcl_SetWrong( *this, nPos, nCnt, bMove ); \
832 : : }
833 : :
834 : 12107 : void lcl_SetWrong( SwTxtFrm& rFrm, xub_StrLen nPos, long nCnt, bool bMove )
835 : : {
836 [ + + ]: 12107 : if ( !rFrm.IsFollow() )
837 : : {
838 : 10458 : SwTxtNode* pTxtNode = rFrm.GetTxtNode();
839 : 10458 : IGrammarContact* pGrammarContact = getGrammarContact( *pTxtNode );
840 : : SwGrammarMarkUp* pWrongGrammar = pGrammarContact ?
841 : 10458 : pGrammarContact->getGrammarCheck( *pTxtNode, false ) :
842 [ + - ]: 10458 : pTxtNode->GetGrammarCheck();
843 : 10458 : bool bGrammarProxy = pWrongGrammar != pTxtNode->GetGrammarCheck();
844 [ + + ]: 10458 : if( bMove )
845 : : {
846 [ + + ]: 9702 : if( pTxtNode->GetWrong() )
847 : 7649 : pTxtNode->GetWrong()->Move( nPos, nCnt );
848 [ + + ]: 9702 : if( pWrongGrammar )
849 : 8172 : pWrongGrammar->MoveGrammar( nPos, nCnt );
850 [ + + ][ + + ]: 9702 : if( bGrammarProxy && pTxtNode->GetGrammarCheck() )
[ + + ]
851 : 2097 : pTxtNode->GetGrammarCheck()->MoveGrammar( nPos, nCnt );
852 [ - + ]: 9702 : if( pTxtNode->GetSmartTags() )
853 : 0 : pTxtNode->GetSmartTags()->Move( nPos, nCnt );
854 : : }
855 : : else
856 : : {
857 : 756 : xub_StrLen nLen = (xub_StrLen)nCnt;
858 [ + + ]: 756 : if( pTxtNode->GetWrong() )
859 : 434 : pTxtNode->GetWrong()->Invalidate( nPos, nLen );
860 [ + + ]: 756 : if( pWrongGrammar )
861 : 448 : pWrongGrammar->Invalidate( nPos, nLen );
862 [ - + ]: 756 : if( pTxtNode->GetSmartTags() )
863 : 0 : pTxtNode->GetSmartTags()->Invalidate( nPos, nLen );
864 : : }
865 [ + + ][ + + ]: 10458 : if ( !pTxtNode->GetWrong() && !pTxtNode->IsWrongDirty() )
[ + + ]
866 : : {
867 [ + - ]: 1695 : pTxtNode->SetWrong( new SwWrongList( WRONGLIST_SPELL ) );
868 : 1695 : pTxtNode->GetWrong()->SetInvalid( nPos, nPos + (sal_uInt16)( nCnt > 0 ? nCnt : 1 ) );
869 : : }
870 [ + - ][ - + ]: 10458 : if ( !pTxtNode->GetSmartTags() && !pTxtNode->IsSmartTagDirty() )
[ - + ]
871 : : {
872 : : // SMARTTAGS
873 [ # # ]: 0 : pTxtNode->SetSmartTags( new SwWrongList( WRONGLIST_SMARTTAG ) );
874 : 0 : pTxtNode->GetSmartTags()->SetInvalid( nPos, nPos + (sal_uInt16)( nCnt > 0 ? nCnt : 1 ) );
875 : : }
876 : 10458 : pTxtNode->SetWrongDirty( true );
877 : 10458 : pTxtNode->SetGrammarCheckDirty( true );
878 : 10458 : pTxtNode->SetWordCountDirty( true );
879 : 10458 : pTxtNode->SetAutoCompleteWordDirty( true );
880 : : // SMARTTAGS
881 : 10458 : pTxtNode->SetSmartTagDirty( true );
882 : : }
883 : :
884 : 12107 : SwRootFrm *pRootFrm = rFrm.getRootFrm();
885 [ + - ]: 12107 : if (pRootFrm)
886 : : {
887 : 12107 : pRootFrm->SetNeedGrammarCheck( sal_True );
888 : : }
889 : :
890 : 12107 : SwPageFrm *pPage = rFrm.FindPageFrm();
891 [ + - ]: 12107 : if( pPage )
892 : : {
893 : 12107 : pPage->InvalidateSpelling();
894 : 12107 : pPage->InvalidateAutoCompleteWords();
895 : 12107 : pPage->InvalidateWordCount();
896 : 12107 : pPage->InvalidateSmartTags();
897 : : }
898 : 12107 : }
899 : :
900 : : //
901 : : // SET_SCRIPT_INVAL( nPos )
902 : : //
903 : :
904 : : #define SET_SCRIPT_INVAL( nPos )\
905 : : lcl_SetScriptInval( *this, nPos );
906 : :
907 : 12527 : void lcl_SetScriptInval( SwTxtFrm& rFrm, xub_StrLen nPos )
908 : : {
909 [ + + ]: 12527 : if( rFrm.GetPara() )
910 : 10693 : rFrm.GetPara()->GetScriptInfo().SetInvalidity( nPos );
911 : 12527 : }
912 : :
913 : 1649 : void lcl_ModifyOfst( SwTxtFrm* pFrm, xub_StrLen nPos, xub_StrLen nLen )
914 : : {
915 [ + + ][ + + ]: 4830 : while( pFrm && pFrm->GetOfst() <= nPos )
[ + + ]
916 : 3181 : pFrm = pFrm->GetFollow();
917 [ + + ]: 2078 : while( pFrm )
918 : : {
919 : 429 : pFrm->ManipOfst( pFrm->GetOfst() + nLen );
920 : 429 : pFrm = pFrm->GetFollow();
921 : : }
922 : 1649 : }
923 : :
924 : : /*************************************************************************
925 : : * SwTxtFrm::Modify()
926 : : *************************************************************************/
927 : :
928 : 16165 : void SwTxtFrm::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
929 : : {
930 [ + + ][ + - ]: 16165 : const MSHORT nWhich = pOld ? pOld->Which() : pNew ? pNew->Which() : 0;
931 : :
932 : : //Wuensche die FrmAttribute betreffen werden von der Basisklasse
933 : : //verarbeitet.
934 [ + + ][ + + ]: 16165 : if( IsInRange( aFrmFmtSetRange, nWhich ) || RES_FMT_CHG == nWhich )
[ + + ]
935 : : {
936 : 103 : SwCntntFrm::Modify( pOld, pNew );
937 [ + - ][ + + ]: 103 : if( nWhich == RES_FMT_CHG && getRootFrm()->GetCurrShell() )
[ + + ]
938 : : {
939 : : // Collection hat sich geaendert
940 : 50 : Prepare( PREP_CLEAR );
941 : 50 : _InvalidatePrt();
942 : 50 : SET_WRONG( 0, STRING_LEN, false );
943 : 50 : SetDerivedR2L( sal_False );
944 : 50 : CheckDirChange();
945 : : // OD 09.12.2002 #105576# - Force complete paint due to existing
946 : : // indents.
947 : 50 : SetCompletePaint();
948 : 50 : InvalidateLineNum();
949 : : }
950 : 103 : return;
951 : : }
952 : :
953 : : // Im gelockten Zustand werden keine Bestellungen angenommen.
954 [ - + ]: 16062 : if( IsLocked() )
955 : 0 : return;
956 : :
957 : : // Dies spart Stack, man muss nur aufpassen,
958 : : // dass sie Variablen gesetzt werden.
959 : : xub_StrLen nPos, nLen;
960 : 16062 : sal_Bool bSetFldsDirty = sal_False;
961 : 16062 : sal_Bool bRecalcFtnFlag = sal_False;
962 : :
963 [ - + + + : 16062 : switch( nWhich )
+ - - + +
+ + - -
- ]
964 : : {
965 : : case RES_LINENUMBER:
966 : : {
967 : 0 : InvalidateLineNum();
968 : : }
969 : 0 : break;
970 : : case RES_INS_TXT:
971 : : {
972 : 9541 : nPos = ((SwInsTxt*)pNew)->nPos;
973 : 9541 : nLen = ((SwInsTxt*)pNew)->nLen;
974 [ + + ]: 9541 : if( IsIdxInside( nPos, nLen ) )
975 : : {
976 [ - + ]: 8392 : if( !nLen )
977 : : {
978 : : // 6969: Aktualisierung der NumPortions auch bei leeren Zeilen!
979 [ # # ]: 0 : if( nPos )
980 : 0 : InvalidateSize();
981 : : else
982 : 0 : Prepare( PREP_CLEAR );
983 : : }
984 : : else
985 [ + - ]: 8392 : _InvalidateRange( SwCharRange( nPos, nLen ), nLen );
986 : : }
987 : 9541 : SET_WRONG( nPos, nLen, true )
988 : 9541 : SET_SCRIPT_INVAL( nPos )
989 : 9541 : bSetFldsDirty = sal_True;
990 [ + + ]: 9541 : if( HasFollow() )
991 : 1191 : lcl_ModifyOfst( this, nPos, nLen );
992 : : }
993 : 9541 : break;
994 : : case RES_DEL_CHR:
995 : : {
996 : 306 : nPos = ((SwDelChr*)pNew)->nPos;
997 [ + - ]: 306 : InvalidateRange( SwCharRange( nPos, 1 ), -1 );
998 : 306 : SET_WRONG( nPos, -1, true )
999 : 306 : SET_SCRIPT_INVAL( nPos )
1000 : 306 : bSetFldsDirty = bRecalcFtnFlag = sal_True;
1001 [ + + ]: 306 : if( HasFollow() )
1002 : 26 : lcl_ModifyOfst( this, nPos, STRING_LEN );
1003 : : }
1004 : 306 : break;
1005 : : case RES_DEL_TXT:
1006 : : {
1007 : 1504 : nPos = ((SwDelTxt*)pNew)->nStart;
1008 : 1504 : nLen = ((SwDelTxt*)pNew)->nLen;
1009 : 1504 : long m = nLen;
1010 : 1504 : m *= -1;
1011 [ + + ]: 1504 : if( IsIdxInside( nPos, nLen ) )
1012 : : {
1013 [ + + ]: 1076 : if( !nLen )
1014 : 8 : InvalidateSize();
1015 : : else
1016 [ + - ]: 1068 : InvalidateRange( SwCharRange( nPos, 1 ), m );
1017 : : }
1018 : 1504 : SET_WRONG( nPos, m, true )
1019 : 1504 : SET_SCRIPT_INVAL( nPos )
1020 : 1504 : bSetFldsDirty = bRecalcFtnFlag = sal_True;
1021 [ + + ]: 1504 : if( HasFollow() )
1022 : 432 : lcl_ModifyOfst( this, nPos, nLen );
1023 : : }
1024 : 1504 : break;
1025 : : case RES_UPDATE_ATTR:
1026 : : {
1027 : 1674 : nPos = ((SwUpdateAttr*)pNew)->nStart;
1028 : 1674 : nLen = ((SwUpdateAttr*)pNew)->nEnd - nPos;
1029 [ + - ]: 1674 : if( IsIdxInside( nPos, nLen ) )
1030 : : {
1031 : : // Es muss in jedem Fall neu formatiert werden,
1032 : : // auch wenn der invalidierte Bereich null ist.
1033 : : // Beispiel: leere Zeile, 14Pt einstellen !
1034 : : // if( !nLen ) nLen = 1;
1035 : :
1036 : : // 6680: FtnNummern muessen formatiert werden.
1037 [ + + ]: 1674 : if( !nLen )
1038 : 954 : nLen = 1;
1039 : :
1040 [ + - ]: 1674 : _InvalidateRange( SwCharRange( nPos, nLen) );
1041 : 1674 : MSHORT nTmp = ((SwUpdateAttr*)pNew)->nWhichAttr;
1042 : :
1043 [ + + ][ + + ]: 1674 : if( ! nTmp || RES_TXTATR_CHARFMT == nTmp || RES_TXTATR_AUTOFMT == nTmp ||
[ + + ][ + + ]
[ + + ]
1044 : : RES_FMT_CHG == nTmp || RES_ATTRSET_CHG == nTmp )
1045 : : {
1046 : 486 : SET_WRONG( nPos, nPos + nLen, false )
1047 : 486 : SET_SCRIPT_INVAL( nPos )
1048 : : }
1049 : : }
1050 : :
1051 : : // #i104008#
1052 [ + - ]: 1674 : ViewShell* pViewSh = getRootFrm() ? getRootFrm()->GetCurrShell() : 0;
1053 [ + - ]: 1674 : if ( pViewSh )
1054 : : {
1055 : 1674 : pViewSh->InvalidateAccessibleParaAttrs( *this );
1056 : : }
1057 : : }
1058 : 1674 : break;
1059 : : case RES_OBJECTDYING:
1060 : 0 : break;
1061 : :
1062 : : case RES_PARATR_LINESPACING:
1063 : : {
1064 : 0 : CalcLineSpace();
1065 : 0 : InvalidateSize();
1066 : 0 : _InvalidatePrt();
1067 [ # # ][ # # ]: 0 : if( IsInSct() && !GetPrev() )
[ # # ]
1068 : : {
1069 : 0 : SwSectionFrm *pSect = FindSctFrm();
1070 [ # # ]: 0 : if( pSect->ContainsAny() == this )
1071 : 0 : pSect->InvalidatePrt();
1072 : : }
1073 : :
1074 : : // OD 09.01.2004 #i11859# - correction:
1075 : : // (1) Also invalidate next frame on next page/column.
1076 : : // (2) Skip empty sections and hidden paragraphs
1077 : : // Thus, use method <InvalidateNextPrtArea()>
1078 : 0 : InvalidateNextPrtArea();
1079 : :
1080 : 0 : SetCompletePaint();
1081 : : }
1082 : 0 : break;
1083 : : case RES_TXTATR_FIELD:
1084 : : {
1085 : 42 : nPos = *((SwFmtFld*)pNew)->GetTxtFld()->GetStart();
1086 [ + - ]: 42 : if( IsIdxInside( nPos, 1 ) )
1087 : : {
1088 [ - + ]: 42 : if( pNew == pOld )
1089 : : {
1090 : : // Nur repainten
1091 : : // opt: invalidate aufs Window ?
1092 : 0 : InvalidatePage();
1093 : 0 : SetCompletePaint();
1094 : : }
1095 : : else
1096 [ + - ]: 42 : _InvalidateRange( SwCharRange( nPos, 1 ) );
1097 : : }
1098 : 42 : bSetFldsDirty = sal_True;
1099 : : // ST2
1100 [ - + ]: 42 : if ( SwSmartTagMgr::Get().IsSmartTagsEnabled() )
1101 : 0 : SET_WRONG( nPos, nPos + 1, false )
1102 : : }
1103 : 42 : break;
1104 : : case RES_TXTATR_FTN :
1105 : : {
1106 : 124 : nPos = *((SwFmtFtn*)pNew)->GetTxtFtn()->GetStart();
1107 [ + - ][ + - ]: 124 : if( IsInFtn() || IsIdxInside( nPos, 1 ) )
[ + + ]
1108 : 124 : Prepare( PREP_FTN, ((SwFmtFtn*)pNew)->GetTxtFtn() );
1109 : 124 : break;
1110 : : }
1111 : :
1112 : : case RES_ATTRSET_CHG:
1113 : : {
1114 [ + - ]: 2856 : InvalidateLineNum();
1115 : :
1116 : 2856 : SwAttrSet& rNewSet = *((SwAttrSetChg*)pNew)->GetChgSet();
1117 : : const SfxPoolItem* pItem;
1118 : 2856 : int nClear = 0;
1119 : 2856 : MSHORT nCount = rNewSet.Count();
1120 : :
1121 [ - + ]: 2856 : if( SFX_ITEM_SET == rNewSet.GetItemState( RES_TXTATR_FTN,
1122 [ + - ]: 2856 : sal_False, &pItem ))
1123 : : {
1124 : 0 : nPos = *((SwFmtFtn*)pItem)->GetTxtFtn()->GetStart();
1125 [ # # ][ # # ]: 0 : if( IsIdxInside( nPos, 1 ) )
1126 [ # # ]: 0 : Prepare( PREP_FTN, pNew );
1127 : 0 : nClear = 0x01;
1128 : 0 : --nCount;
1129 : : }
1130 : :
1131 [ - + ]: 2856 : if( SFX_ITEM_SET == rNewSet.GetItemState( RES_TXTATR_FIELD,
1132 [ + - ]: 2856 : sal_False, &pItem ))
1133 : : {
1134 : 0 : nPos = *((SwFmtFld*)pItem)->GetTxtFld()->GetStart();
1135 [ # # ][ # # ]: 0 : if( IsIdxInside( nPos, 1 ) )
1136 : : {
1137 : : const SfxPoolItem& rOldItem = ((SwAttrSetChg*)pOld)->
1138 [ # # ]: 0 : GetChgSet()->Get( RES_TXTATR_FIELD );
1139 [ # # ]: 0 : if( pItem == &rOldItem )
1140 : : {
1141 : : // Nur repainten
1142 : : // opt: invalidate aufs Window ?
1143 [ # # ]: 0 : InvalidatePage();
1144 : 0 : SetCompletePaint();
1145 : : }
1146 : : else
1147 [ # # ]: 0 : _InvalidateRange( SwCharRange( nPos, 1 ) );
1148 : : }
1149 : 0 : nClear |= 0x02;
1150 : 0 : --nCount;
1151 : : }
1152 : : sal_Bool bLineSpace = SFX_ITEM_SET == rNewSet.GetItemState(
1153 [ + - ]: 2856 : RES_PARATR_LINESPACING, sal_False ),
1154 : : bRegister = SFX_ITEM_SET == rNewSet.GetItemState(
1155 [ + - ]: 2856 : RES_PARATR_REGISTER, sal_False );
1156 [ + - ][ - + ]: 2856 : if ( bLineSpace || bRegister )
1157 : : {
1158 [ # # ][ # # ]: 0 : Prepare( bRegister ? PREP_REGISTER : PREP_ADJUST_FRM );
1159 [ # # ]: 0 : CalcLineSpace();
1160 [ # # ]: 0 : InvalidateSize();
1161 [ # # ]: 0 : _InvalidatePrt();
1162 : :
1163 : : // OD 09.01.2004 #i11859# - correction:
1164 : : // (1) Also invalidate next frame on next page/column.
1165 : : // (2) Skip empty sections and hidden paragraphs
1166 : : // Thus, use method <InvalidateNextPrtArea()>
1167 [ # # ]: 0 : InvalidateNextPrtArea();
1168 : :
1169 : 0 : SetCompletePaint();
1170 : 0 : nClear |= 0x04;
1171 [ # # ]: 0 : if ( bLineSpace )
1172 : : {
1173 : 0 : --nCount;
1174 [ # # ][ # # ]: 0 : if( IsInSct() && !GetPrev() )
[ # # ][ # # ]
1175 : : {
1176 [ # # ]: 0 : SwSectionFrm *pSect = FindSctFrm();
1177 [ # # ][ # # ]: 0 : if( pSect->ContainsAny() == this )
1178 [ # # ]: 0 : pSect->InvalidatePrt();
1179 : : }
1180 : : }
1181 [ # # ]: 0 : if ( bRegister )
1182 : 0 : --nCount;
1183 : : }
1184 [ - + ]: 2856 : if ( SFX_ITEM_SET == rNewSet.GetItemState( RES_PARATR_SPLIT,
1185 [ + - ]: 2856 : sal_False ))
1186 : : {
1187 [ # # ]: 0 : if ( GetPrev() )
1188 [ # # ]: 0 : CheckKeep();
1189 [ # # ]: 0 : Prepare( PREP_CLEAR );
1190 [ # # ]: 0 : InvalidateSize();
1191 : 0 : nClear |= 0x08;
1192 : 0 : --nCount;
1193 : : }
1194 : :
1195 [ + - ][ + + : 2880 : if( SFX_ITEM_SET == rNewSet.GetItemState( RES_BACKGROUND, sal_False)
+ - - + ]
[ - + ]
1196 : 24 : && !IsFollow() && GetDrawObjs() )
1197 : : {
1198 : 0 : SwSortedObjs *pObjs = GetDrawObjs();
1199 [ # # ][ # # ]: 0 : for ( int i = 0; GetDrawObjs() && i < int(pObjs->Count()); ++i )
[ # # ][ # # ]
1200 : : {
1201 [ # # ]: 0 : SwAnchoredObject* pAnchoredObj = (*pObjs)[MSHORT(i)];
1202 [ # # ][ # # ]: 0 : if ( pAnchoredObj->ISA(SwFlyFrm) )
[ # # ]
1203 : : {
1204 [ # # ]: 0 : SwFlyFrm *pFly = static_cast<SwFlyFrm*>(pAnchoredObj);
1205 [ # # ]: 0 : if( !pFly->IsFlyInCntFrm() )
1206 : : {
1207 : : const SvxBrushItem &rBack =
1208 [ # # ][ # # ]: 0 : pFly->GetAttrSet()->GetBackground();
1209 : : // OD 20.08.2002 #99657# #GetTransChg#
1210 : : // following condition determines, if the fly frame
1211 : : // "inherites" the background color of text frame.
1212 : : // This is the case, if fly frame background
1213 : : // color is "no fill"/"auto fill" and if the fly frame
1214 : : // has no background graphic.
1215 : : // Thus, check complete fly frame background
1216 : : // color and *not* only its transparency value
1217 [ # # # # ]: 0 : if ( (rBack.GetColor() == COL_TRANSPARENT) &&
[ # # ][ # # ]
1218 : 0 : rBack.GetGraphicPos() == GPOS_NONE )
1219 : : {
1220 : 0 : pFly->SetCompletePaint();
1221 [ # # ]: 0 : pFly->InvalidatePage();
1222 : : }
1223 : : }
1224 : : }
1225 : : }
1226 : : }
1227 : :
1228 [ - + ]: 2856 : if ( SFX_ITEM_SET ==
1229 [ + - ]: 2856 : rNewSet.GetItemState( RES_TXTATR_CHARFMT, sal_False ) )
1230 : : {
1231 [ # # ]: 0 : SET_WRONG( 0, STRING_LEN, false )
1232 [ # # ]: 0 : SET_SCRIPT_INVAL( 0 )
1233 : : }
1234 [ + + ][ + + ]: 8266 : else if ( SFX_ITEM_SET ==
[ + + ][ + + ]
1235 [ + - ]: 2856 : rNewSet.GetItemState( RES_CHRATR_LANGUAGE, sal_False ) ||
1236 : : SFX_ITEM_SET ==
1237 [ + - ]: 2728 : rNewSet.GetItemState( RES_CHRATR_CJK_LANGUAGE, sal_False ) ||
1238 : : SFX_ITEM_SET ==
1239 [ + - ]: 2682 : rNewSet.GetItemState( RES_CHRATR_CTL_LANGUAGE, sal_False ) )
1240 [ + - ]: 220 : SET_WRONG( 0, STRING_LEN, false )
1241 [ + + ][ + + ]: 7218 : else if ( SFX_ITEM_SET ==
[ + + ][ + + ]
1242 [ + - ]: 2636 : rNewSet.GetItemState( RES_CHRATR_FONT, sal_False ) ||
1243 : : SFX_ITEM_SET ==
1244 [ + - ]: 2406 : rNewSet.GetItemState( RES_CHRATR_CJK_FONT, sal_False ) ||
1245 : : SFX_ITEM_SET ==
1246 [ + - ]: 2176 : rNewSet.GetItemState( RES_CHRATR_CTL_FONT, sal_False ) )
1247 [ + - ]: 690 : SET_SCRIPT_INVAL( 0 )
1248 [ + + ]: 1946 : else if ( SFX_ITEM_SET ==
1249 [ + - ]: 1946 : rNewSet.GetItemState( RES_FRAMEDIR, sal_False ) )
1250 : : {
1251 : 50 : SetDerivedR2L( sal_False );
1252 [ + - ]: 50 : CheckDirChange();
1253 : : // OD 09.12.2002 #105576# - Force complete paint due to existing
1254 : : // indents.
1255 : 50 : SetCompletePaint();
1256 : : }
1257 : :
1258 : :
1259 [ + - ]: 2856 : if( nCount )
1260 : : {
1261 [ + - ]: 2856 : if( getRootFrm()->GetCurrShell() )
1262 : : {
1263 [ + - ]: 2856 : Prepare( PREP_CLEAR );
1264 [ + - ]: 2856 : _InvalidatePrt();
1265 : : }
1266 : :
1267 [ - + ]: 2856 : if( nClear )
1268 : : {
1269 [ # # ]: 0 : SwAttrSetChg aOldSet( *(SwAttrSetChg*)pOld );
1270 [ # # ]: 0 : SwAttrSetChg aNewSet( *(SwAttrSetChg*)pNew );
1271 : :
1272 [ # # ]: 0 : if( 0x01 & nClear )
1273 : : {
1274 [ # # ]: 0 : aOldSet.ClearItem( RES_TXTATR_FTN );
1275 [ # # ]: 0 : aNewSet.ClearItem( RES_TXTATR_FTN );
1276 : : }
1277 [ # # ]: 0 : if( 0x02 & nClear )
1278 : : {
1279 [ # # ]: 0 : aOldSet.ClearItem( RES_TXTATR_FIELD );
1280 [ # # ]: 0 : aNewSet.ClearItem( RES_TXTATR_FIELD );
1281 : : }
1282 [ # # ]: 0 : if ( 0x04 & nClear )
1283 : : {
1284 [ # # ]: 0 : if ( bLineSpace )
1285 : : {
1286 [ # # ]: 0 : aOldSet.ClearItem( RES_PARATR_LINESPACING );
1287 [ # # ]: 0 : aNewSet.ClearItem( RES_PARATR_LINESPACING );
1288 : : }
1289 [ # # ]: 0 : if ( bRegister )
1290 : : {
1291 [ # # ]: 0 : aOldSet.ClearItem( RES_PARATR_REGISTER );
1292 [ # # ]: 0 : aNewSet.ClearItem( RES_PARATR_REGISTER );
1293 : : }
1294 : : }
1295 [ # # ]: 0 : if ( 0x08 & nClear )
1296 : : {
1297 [ # # ]: 0 : aOldSet.ClearItem( RES_PARATR_SPLIT );
1298 [ # # ]: 0 : aNewSet.ClearItem( RES_PARATR_SPLIT );
1299 : : }
1300 [ # # ][ # # ]: 0 : SwCntntFrm::Modify( &aOldSet, &aNewSet );
[ # # ]
1301 : : }
1302 : : else
1303 [ + - ]: 2856 : SwCntntFrm::Modify( pOld, pNew );
1304 : : }
1305 : :
1306 : : // #i88069#
1307 [ + - ]: 2856 : ViewShell* pViewSh = getRootFrm() ? getRootFrm()->GetCurrShell() : 0;
1308 [ + - ]: 2856 : if ( pViewSh )
1309 : : {
1310 [ + - ]: 2856 : pViewSh->InvalidateAccessibleParaAttrs( *this );
1311 : : }
1312 : : }
1313 : 2856 : break;
1314 : :
1315 : : // 6870: SwDocPosUpdate auswerten.
1316 : : case RES_DOCPOS_UPDATE:
1317 : : {
1318 [ + - ][ + - ]: 15 : if( pOld && pNew )
1319 : : {
1320 : 15 : const SwDocPosUpdate *pDocPos = (const SwDocPosUpdate*)pOld;
1321 [ + - ]: 15 : if( pDocPos->nDocPos <= aFrm.Top() )
1322 : : {
1323 : 15 : const SwFmtFld *pFld = (const SwFmtFld *)pNew;
1324 : : InvalidateRange(
1325 [ + - ]: 15 : SwCharRange( *pFld->GetTxtFld()->GetStart(), 1 ) );
1326 : : }
1327 : : }
1328 : 15 : break;
1329 : : }
1330 : : case RES_PARATR_SPLIT:
1331 [ # # ]: 0 : if ( GetPrev() )
1332 : 0 : CheckKeep();
1333 : 0 : Prepare( PREP_CLEAR );
1334 : 0 : bSetFldsDirty = sal_True;
1335 : 0 : break;
1336 : : case RES_FRAMEDIR :
1337 : 0 : SetDerivedR2L( sal_False );
1338 : 0 : CheckDirChange();
1339 : 0 : break;
1340 : : default:
1341 : : {
1342 : 0 : Prepare( PREP_CLEAR );
1343 : 0 : _InvalidatePrt();
1344 [ # # ]: 0 : if ( !nWhich )
1345 : : {
1346 : : //Wird z.B. bei HiddenPara mit 0 gerufen.
1347 : : SwFrm *pNxt;
1348 [ # # ]: 0 : if ( 0 != (pNxt = FindNext()) )
1349 : 0 : pNxt->InvalidatePrt();
1350 : : }
1351 : : }
1352 : : } // switch
1353 : :
1354 [ + + ]: 16062 : if( bSetFldsDirty )
1355 [ + - ]: 11393 : GetNode()->getIDocumentFieldsAccess()->SetFieldsDirty( sal_True, GetNode(), 1 );
1356 : :
1357 [ + + ]: 16062 : if ( bRecalcFtnFlag )
1358 : 16165 : CalcFtnFlag();
1359 : : }
1360 : :
1361 : 0 : sal_Bool SwTxtFrm::GetInfo( SfxPoolItem &rHnt ) const
1362 : : {
1363 [ # # ][ # # ]: 0 : if ( RES_VIRTPAGENUM_INFO == rHnt.Which() && IsInDocBody() && ! IsFollow() )
[ # # ][ # # ]
1364 : : {
1365 : 0 : SwVirtPageNumInfo &rInfo = (SwVirtPageNumInfo&)rHnt;
1366 : 0 : const SwPageFrm *pPage = FindPageFrm();
1367 [ # # ]: 0 : if ( pPage )
1368 : : {
1369 [ # # ][ # # ]: 0 : if ( pPage == rInfo.GetOrigPage() && !GetPrev() )
[ # # ]
1370 : : {
1371 : : //Das sollte er sein (kann allenfalls temporaer anders sein,
1372 : : // sollte uns das beunruhigen?)
1373 : 0 : rInfo.SetInfo( pPage, this );
1374 : 0 : return sal_False;
1375 : : }
1376 [ # # # # : 0 : if ( pPage->GetPhyPageNum() < rInfo.GetOrigPage()->GetPhyPageNum() &&
# # ][ # # ]
1377 : 0 : (!rInfo.GetPage() || pPage->GetPhyPageNum() > rInfo.GetPage()->GetPhyPageNum()))
1378 : : {
1379 : : //Das koennte er sein.
1380 : 0 : rInfo.SetInfo( pPage, this );
1381 : : }
1382 : : }
1383 : : }
1384 : 0 : return sal_True;
1385 : : }
1386 : :
1387 : : /*************************************************************************
1388 : : * SwTxtFrm::PrepWidows()
1389 : : *************************************************************************/
1390 : :
1391 : 0 : void SwTxtFrm::PrepWidows( const MSHORT nNeed, sal_Bool bNotify )
1392 : : {
1393 : : OSL_ENSURE(GetFollow() && nNeed, "+SwTxtFrm::Prepare: lost all friends");
1394 : :
1395 [ # # ]: 0 : SwParaPortion *pPara = GetPara();
1396 [ # # ]: 0 : if ( !pPara )
1397 : 0 : return;
1398 : 0 : pPara->SetPrepWidows( sal_True );
1399 : :
1400 : 0 : MSHORT nHave = nNeed;
1401 : :
1402 : : // Wir geben ein paar Zeilen ab und schrumpfen im CalcPreps()
1403 [ # # ][ # # ]: 0 : SWAP_IF_NOT_SWAPPED( this )
[ # # ][ # # ]
1404 : :
1405 [ # # ]: 0 : SwTxtSizeInfo aInf( this );
1406 [ # # ]: 0 : SwTxtMargin aLine( this, &aInf );
1407 [ # # ]: 0 : aLine.Bottom();
1408 : 0 : xub_StrLen nTmpLen = aLine.GetCurr()->GetLen();
1409 [ # # ][ # # ]: 0 : while( nHave && aLine.PrevLine() )
[ # # ][ # # ]
1410 : : {
1411 [ # # ]: 0 : if( nTmpLen )
1412 : 0 : --nHave;
1413 : 0 : nTmpLen = aLine.GetCurr()->GetLen();
1414 : : }
1415 : : // In dieser Ecke tummelten sich einige Bugs: 7513, 7606.
1416 : : // Wenn feststeht, dass Zeilen abgegeben werden koennen,
1417 : : // muss der Master darueber hinaus die Widow-Regel ueberpruefen.
1418 [ # # ]: 0 : if( !nHave )
1419 : : {
1420 : : sal_Bool bSplit;
1421 [ # # ]: 0 : if( !IsFollow() ) //Nur ein Master entscheidet ueber Orphans
1422 : : {
1423 [ # # ]: 0 : const WidowsAndOrphans aWidOrp( this );
1424 : 0 : bSplit = ( aLine.GetLineNr() >= aWidOrp.GetOrphansLines() &&
1425 [ # # ][ # # ]: 0 : aLine.GetLineNr() >= aLine.GetDropLines() );
1426 : : }
1427 : : else
1428 : 0 : bSplit = sal_True;
1429 : :
1430 [ # # ]: 0 : if( bSplit )
1431 : : {
1432 [ # # ]: 0 : GetFollow()->SetOfst( aLine.GetEnd() );
1433 [ # # ]: 0 : aLine.TruncLines( sal_True );
1434 [ # # ]: 0 : if( pPara->IsFollowField() )
1435 : 0 : GetFollow()->SetFieldFollow( sal_True );
1436 : : }
1437 : : }
1438 [ # # ]: 0 : if ( bNotify )
1439 : : {
1440 [ # # ]: 0 : _InvalidateSize();
1441 [ # # ]: 0 : InvalidatePage();
1442 : : }
1443 : :
1444 [ # # ][ # # ]: 0 : UNDO_SWAP( this )
1445 : : }
1446 : :
1447 : : /*************************************************************************
1448 : : * SwTxtFrm::Prepare
1449 : : *************************************************************************/
1450 : :
1451 : 10 : sal_Bool lcl_ErgoVadis( SwTxtFrm* pFrm, xub_StrLen &rPos, const PrepareHint ePrep )
1452 : : {
1453 : 10 : const SwFtnInfo &rFtnInfo = pFrm->GetNode()->GetDoc()->GetFtnInfo();
1454 [ + + ]: 10 : if( ePrep == PREP_ERGOSUM )
1455 : : {
1456 [ + - ]: 2 : if( !rFtnInfo.aErgoSum.Len() )
1457 : 2 : return sal_False;;
1458 : 0 : rPos = pFrm->GetOfst();
1459 : : }
1460 : : else
1461 : : {
1462 [ + - ]: 8 : if( !rFtnInfo.aQuoVadis.Len() )
1463 : 8 : return sal_False;
1464 [ # # ]: 0 : if( pFrm->HasFollow() )
1465 : 0 : rPos = pFrm->GetFollow()->GetOfst();
1466 : : else
1467 : 0 : rPos = pFrm->GetTxt().Len();
1468 [ # # ]: 0 : if( rPos )
1469 : 0 : --rPos; // unser letztes Zeichen
1470 : : }
1471 : 10 : return sal_True;
1472 : : }
1473 : :
1474 : 29292 : void SwTxtFrm::Prepare( const PrepareHint ePrep, const void* pVoid,
1475 : : sal_Bool bNotify )
1476 : : {
1477 [ + - ]: 29292 : SwFrmSwapper aSwapper( this, sal_False );
1478 : :
1479 : : #if OSL_DEBUG_LEVEL > 1
1480 : : const SwTwips nDbgY = Frm().Top();
1481 : : (void)nDbgY;
1482 : : #endif
1483 : :
1484 [ + + ]: 29292 : if ( IsEmpty() )
1485 : : {
1486 [ + + + + ]: 3934 : switch ( ePrep )
1487 : : {
1488 : : case PREP_BOSS_CHGD:
1489 : 174 : SetInvalidVert( sal_True ); // Test
1490 : : case PREP_WIDOWS_ORPHANS:
1491 : : case PREP_WIDOWS:
1492 : : case PREP_FTN_GONE : return;
1493 : :
1494 : : case PREP_POS_CHGD :
1495 : : {
1496 : : // Auch in (spaltigen) Bereichen ist ein InvalidateSize notwendig,
1497 : : // damit formatiert wird und ggf. das bUndersized gesetzt wird.
1498 [ + - ][ + + ]: 1137 : if( IsInFly() || IsInSct() )
[ + - ][ + + ]
[ + + ]
1499 : : {
1500 : 114 : SwTwips nTmpBottom = GetUpper()->Frm().Top() +
1501 : 114 : GetUpper()->Prt().Bottom();
1502 [ + + ]: 114 : if( nTmpBottom < Frm().Bottom() )
1503 : : break;
1504 : : }
1505 : : // Gibt es ueberhaupt Flys auf der Seite ?
1506 [ + - ]: 1061 : SwTxtFly aTxtFly( this );
1507 [ + + ]: 1061 : if( aTxtFly.IsOn() )
1508 : : {
1509 : : // Ueberlappt irgendein Fly ?
1510 [ + - ]: 18 : aTxtFly.Relax();
1511 [ + - ][ + + ]: 18 : if ( aTxtFly.IsOn() || IsUndersized() )
[ + + ]
1512 : : break;
1513 : : }
1514 [ + - ][ + - ]: 1055 : if( GetTxtNode()->GetSwAttrSet().GetRegister().GetValue())
[ - + ]
1515 : : break;
1516 : :
1517 [ + - ][ + - ]: 1055 : GETGRID( FindPageFrm() )
[ + - ][ - + ]
[ # # ][ # # ]
[ # # ][ - + ]
1518 [ - + ][ # # ]: 1055 : if ( pGrid && GetTxtNode()->GetSwAttrSet().GetParaGrid().GetValue() )
[ # # ][ # # ]
[ - + ]
1519 : : break;
1520 : :
1521 : : // #i28701# - consider anchored objects
1522 [ - + ]: 1055 : if ( GetDrawObjs() )
1523 : : break;
1524 : :
1525 [ + - ][ + + ]: 1137 : return;
1526 : : }
1527 : : default:
1528 : 2705 : break;
1529 : : }
1530 : : }
1531 : :
1532 [ + - ][ + + ]: 28063 : if( !HasPara() && PREP_MUST_FIT != ePrep )
[ + + ][ + + ]
1533 : : {
1534 : 21058 : SetInvalidVert( sal_True ); // Test
1535 : : OSL_ENSURE( !IsLocked(), "SwTxtFrm::Prepare: three of a perfect pair" );
1536 [ + + ]: 21058 : if ( bNotify )
1537 [ + - ]: 15519 : InvalidateSize();
1538 : : else
1539 [ + - ]: 21058 : _InvalidateSize();
1540 : : return;
1541 : : }
1542 : :
1543 : : //Objekt mit Locking aus dem Cache holen.
1544 [ + - ]: 7005 : SwTxtLineAccess aAccess( this );
1545 [ + - ]: 7005 : SwParaPortion *pPara = aAccess.GetPara();
1546 : :
1547 [ - + + + : 7005 : switch( ePrep )
- + + + -
- + + + ]
1548 : : {
1549 : 0 : case PREP_MOVEFTN : Frm().Height(0);
1550 : 0 : Prt().Height(0);
1551 [ # # ]: 0 : _InvalidatePrt();
1552 [ # # ]: 0 : _InvalidateSize();
1553 : : // KEIN break
1554 : 500 : case PREP_ADJUST_FRM : pPara->SetPrepAdjust( sal_True );
1555 [ + + + + ]: 998 : if( IsFtnNumFrm() != pPara->IsFtnNum() ||
[ + + ][ + - ]
1556 : 498 : IsUndersized() )
1557 : : {
1558 [ + - ]: 44 : InvalidateRange( SwCharRange( 0, 1 ), 1);
1559 [ - + ][ # # ]: 44 : if( GetOfst() && !IsFollow() )
[ - + ]
1560 [ # # ]: 0 : _SetOfst( 0 );
1561 : : }
1562 : 500 : break;
1563 : 78 : case PREP_MUST_FIT : pPara->SetPrepMustFit( sal_True );
1564 : : /* no break here */
1565 : 833 : case PREP_WIDOWS_ORPHANS : pPara->SetPrepAdjust( sal_True );
1566 : 833 : break;
1567 : :
1568 : : case PREP_WIDOWS :
1569 : : // MustFit ist staerker als alles anderes
1570 [ # # ]: 0 : if( pPara->IsPrepMustFit() )
1571 : : return;
1572 : : // Siehe Kommentar in WidowsAndOrphans::FindOrphans und CalcPreps()
1573 [ # # ]: 0 : PrepWidows( *(const MSHORT *)pVoid, bNotify );
1574 : 0 : break;
1575 : :
1576 : : case PREP_FTN :
1577 : : {
1578 : 148 : SwTxtFtn *pFtn = (SwTxtFtn *)pVoid;
1579 [ + - ][ + + ]: 148 : if( IsInFtn() )
1580 : : {
1581 : : // Bin ich der erste TxtFrm einer Fussnote ?
1582 [ + + ]: 56 : if( !GetPrev() )
1583 : : // Wir sind also ein TxtFrm der Fussnote, die
1584 : : // die Fussnotenzahl zur Anzeige bringen muss.
1585 : : // Oder den ErgoSum-Text...
1586 [ + - ]: 52 : InvalidateRange( SwCharRange( 0, 1 ), 1);
1587 : :
1588 [ + + ]: 56 : if( !GetNext() )
1589 : : {
1590 : : // Wir sind der letzte Ftn, jetzt muessten die
1591 : : // QuoVadis-Texte geupdated werden.
1592 : 54 : const SwFtnInfo &rFtnInfo = GetNode()->GetDoc()->GetFtnInfo();
1593 [ + - ][ + - ]: 54 : if( !pPara->UpdateQuoVadis( rFtnInfo.aQuoVadis ) )
1594 : : {
1595 [ + - ]: 54 : xub_StrLen nPos = pPara->GetParLen();
1596 [ + + ]: 54 : if( nPos )
1597 : 12 : --nPos;
1598 [ + - ]: 54 : InvalidateRange( SwCharRange( nPos, 1 ), 1);
1599 : : }
1600 : : }
1601 : : }
1602 : : else
1603 : : {
1604 : : // Wir sind also der TxtFrm _mit_ der Fussnote
1605 : 92 : const xub_StrLen nPos = *pFtn->GetStart();
1606 [ + - ]: 92 : InvalidateRange( SwCharRange( nPos, 1 ), 1);
1607 : : }
1608 : 148 : break;
1609 : : }
1610 : : case PREP_BOSS_CHGD :
1611 : : {
1612 : : // Test
1613 : : {
1614 : 54 : SetInvalidVert( sal_False );
1615 [ + - ]: 54 : sal_Bool bOld = IsVertical();
1616 : 54 : SetInvalidVert( sal_True );
1617 [ - + ][ + - ]: 54 : if( bOld != IsVertical() )
1618 [ # # ]: 0 : InvalidateRange( SwCharRange( GetOfst(), STRING_LEN ) );
1619 : : }
1620 : :
1621 [ - + ]: 54 : if( HasFollow() )
1622 : : {
1623 : 0 : xub_StrLen nNxtOfst = GetFollow()->GetOfst();
1624 [ # # ]: 0 : if( nNxtOfst )
1625 : 0 : --nNxtOfst;
1626 [ # # ]: 0 : InvalidateRange( SwCharRange( nNxtOfst, 1 ), 1);
1627 : : }
1628 [ + - ][ - + ]: 54 : if( IsInFtn() )
1629 : : {
1630 : : xub_StrLen nPos;
1631 [ # # ]: 0 : if( lcl_ErgoVadis( this, nPos, PREP_QUOVADIS ) )
1632 [ # # ]: 0 : InvalidateRange( SwCharRange( nPos, 1 ), 0 );
1633 [ # # ]: 0 : if( lcl_ErgoVadis( this, nPos, PREP_ERGOSUM ) )
1634 [ # # ]: 0 : InvalidateRange( SwCharRange( nPos, 1 ), 0 );
1635 : : }
1636 : : // 4739: Wenn wir ein Seitennummernfeld besitzen, muessen wir
1637 : : // die Stellen invalidieren.
1638 : 54 : SwpHints *pHints = GetTxtNode()->GetpSwpHints();
1639 [ - + ]: 54 : if( pHints )
1640 : : {
1641 : 0 : const sal_uInt16 nSize = pHints->Count();
1642 : 0 : const xub_StrLen nEnd = GetFollow() ?
1643 [ # # ]: 0 : GetFollow()->GetOfst() : STRING_LEN;
1644 [ # # ]: 0 : for ( sal_uInt16 i = 0; i < nSize; ++i )
1645 : : {
1646 [ # # ]: 0 : const SwTxtAttr *pHt = (*pHints)[i];
1647 : 0 : const xub_StrLen nStart = *pHt->GetStart();
1648 [ # # ]: 0 : if( nStart >= GetOfst() )
1649 : : {
1650 [ # # ]: 0 : if( nStart >= nEnd )
1651 : 0 : i = nSize; // fuehrt das Ende herbei
1652 : : else
1653 : : {
1654 : : // 4029: wenn wir zurueckfliessen und eine Ftn besitzen, so
1655 : : // fliesst die Ftn in jedem Fall auch mit. Damit sie nicht im
1656 : : // Weg steht, schicken wir uns ein ADJUST_FRM.
1657 : : // pVoid != 0 bedeutet MoveBwd()
1658 [ # # ]: 0 : const MSHORT nWhich = pHt->Which();
1659 [ # # # # ]: 0 : if( RES_TXTATR_FIELD == nWhich ||
[ # # ][ # # ]
[ # # ]
1660 : 0 : (HasFtn() && pVoid && RES_TXTATR_FTN == nWhich))
1661 [ # # ]: 0 : InvalidateRange( SwCharRange( nStart, 1 ), 1 );
1662 : : }
1663 : : }
1664 : : }
1665 : : }
1666 : : // A new boss, a new chance for growing
1667 [ + + ]: 54 : if( IsUndersized() )
1668 : : {
1669 [ + - ]: 26 : _InvalidateSize();
1670 [ + - ]: 26 : InvalidateRange( SwCharRange( GetOfst(), 1 ), 1);
1671 : : }
1672 : 54 : break;
1673 : : }
1674 : :
1675 : : case PREP_POS_CHGD :
1676 : : {
1677 [ + + ]: 2309 : if ( GetValidPrtAreaFlag() )
1678 : : {
1679 [ + - ][ + - ]: 2214 : GETGRID( FindPageFrm() )
[ + - ][ - + ]
[ # # ][ # # ]
[ # # ][ - + ]
1680 [ - + ][ # # ]: 2214 : if ( pGrid && GetTxtNode()->GetSwAttrSet().GetParaGrid().GetValue() )
[ # # ][ # # ]
[ - + ]
1681 [ # # ]: 0 : InvalidatePrt();
1682 : : }
1683 : :
1684 : : // Falls wir mit niemandem ueberlappen:
1685 : : // Ueberlappte irgendein Fly _vor_ der Positionsaenderung ?
1686 : 2309 : sal_Bool bFormat = pPara->HasFly();
1687 [ + - ]: 2309 : if( !bFormat )
1688 : : {
1689 [ + - ][ + + ]: 2309 : if( IsInFly() )
1690 : : {
1691 : 76 : SwTwips nTmpBottom = GetUpper()->Frm().Top() +
1692 : 76 : GetUpper()->Prt().Bottom();
1693 [ - + ]: 76 : if( nTmpBottom < Frm().Bottom() )
1694 : 0 : bFormat = sal_True;
1695 : : }
1696 [ + - ]: 2309 : if( !bFormat )
1697 : : {
1698 [ + + ]: 2309 : if ( GetDrawObjs() )
1699 : : {
1700 [ + - ]: 8 : const sal_uInt32 nCnt = GetDrawObjs()->Count();
1701 [ + + ]: 16 : for ( MSHORT i = 0; i < nCnt; ++i )
1702 : : {
1703 [ + - ]: 8 : SwAnchoredObject* pAnchoredObj = (*GetDrawObjs())[i];
1704 : : // #i28701# - consider all
1705 : : // to-character anchored objects
1706 [ + - ][ + - ]: 8 : if ( pAnchoredObj->GetFrmFmt().GetAnchor().GetAnchorId()
[ - + ]
1707 : : == FLY_AT_CHAR )
1708 : : {
1709 : 0 : bFormat = sal_True;
1710 : 0 : break;
1711 : : }
1712 : : }
1713 : : }
1714 [ + - ]: 2309 : if( !bFormat )
1715 : : {
1716 : : // Gibt es ueberhaupt Flys auf der Seite ?
1717 [ + - ]: 2309 : SwTxtFly aTxtFly( this );
1718 [ + + ]: 2309 : if( aTxtFly.IsOn() )
1719 : : {
1720 : : // Ueberlappt irgendein Fly ?
1721 [ + - ]: 188 : aTxtFly.Relax();
1722 [ + + ][ + + ]: 188 : bFormat = aTxtFly.IsOn() || IsUndersized();
1723 [ + - ]: 2309 : }
1724 : : }
1725 : : }
1726 : : }
1727 : :
1728 [ + + ]: 2309 : if( bFormat )
1729 : : {
1730 [ + - ]: 20 : if( !IsLocked() )
1731 : : {
1732 [ + - ][ + - ]: 20 : if( pPara->GetRepaint()->HasArea() )
1733 : 20 : SetCompletePaint();
1734 [ + - ]: 20 : Init();
1735 : 20 : pPara = 0;
1736 [ + - ]: 20 : _InvalidateSize();
1737 : : }
1738 : : }
1739 : : else
1740 : : {
1741 [ + - ][ + - ]: 2289 : if( GetTxtNode()->GetSwAttrSet().GetRegister().GetValue() )
[ - + ]
1742 [ # # ]: 0 : Prepare( PREP_REGISTER, 0, bNotify );
1743 : : // Durch Positionsverschiebungen mit Ftns muessen die
1744 : : // Frames neu adjustiert werden.
1745 [ - + ]: 2289 : else if( HasFtn() )
1746 : : {
1747 [ # # ]: 0 : Prepare( PREP_ADJUST_FRM, 0, bNotify );
1748 [ # # ]: 2289 : _InvalidateSize();
1749 : : }
1750 : : else
1751 : : return; // damit kein SetPrep() erfolgt.
1752 : : }
1753 : 20 : break;
1754 : : }
1755 : : case PREP_REGISTER:
1756 [ # # ][ # # ]: 0 : if( GetTxtNode()->GetSwAttrSet().GetRegister().GetValue() )
[ # # ]
1757 : : {
1758 : 0 : pPara->SetPrepAdjust( sal_True );
1759 [ # # ]: 0 : CalcLineSpace();
1760 [ # # ]: 0 : InvalidateSize();
1761 [ # # ]: 0 : _InvalidatePrt();
1762 : : SwFrm* pNxt;
1763 [ # # ][ # # ]: 0 : if ( 0 != ( pNxt = GetIndNext() ) )
1764 : : {
1765 [ # # ]: 0 : pNxt->_InvalidatePrt();
1766 [ # # ]: 0 : if ( pNxt->IsLayoutFrm() )
1767 [ # # ]: 0 : pNxt->InvalidatePage();
1768 : : }
1769 : 0 : SetCompletePaint();
1770 : : }
1771 : 0 : break;
1772 : : case PREP_FTN_GONE :
1773 : : {
1774 : : // Wenn ein Follow uns ruft, weil eine Fussnote geloescht wird, muss unsere
1775 : : // letzte Zeile formatiert werden, damit ggf. die erste Zeile des Follows
1776 : : // hochrutschen kann, die extra auf die naechste Seite gerutscht war, um mit
1777 : : // der Fussnote zusammen zu sein, insbesondere bei spaltigen Bereichen.
1778 : : OSL_ENSURE( GetFollow(), "PREP_FTN_GONE darf nur vom Follow gerufen werden" );
1779 : 0 : xub_StrLen nPos = GetFollow()->GetOfst();
1780 [ # # ][ # # ]: 0 : if( IsFollow() && GetOfst() == nPos ) // falls wir gar keine Textmasse besitzen,
[ # # ]
1781 [ # # ][ # # ]: 0 : FindMaster()->Prepare( PREP_FTN_GONE ); // rufen wir das Prepare unseres Masters
1782 [ # # ]: 0 : if( nPos )
1783 : 0 : --nPos; // das Zeichen vor unserem Follow
1784 [ # # ]: 0 : InvalidateRange( SwCharRange( nPos, 1 ), 0 );
1785 : : return;
1786 : : }
1787 : : case PREP_ERGOSUM:
1788 : : case PREP_QUOVADIS:
1789 : : {
1790 : : xub_StrLen nPos;
1791 [ - + ]: 10 : if( lcl_ErgoVadis( this, nPos, ePrep ) )
1792 [ # # ]: 0 : InvalidateRange( SwCharRange( nPos, 1 ), 0 );
1793 : : }
1794 : 10 : break;
1795 : : case PREP_FLY_ATTR_CHG:
1796 : : {
1797 [ + + ]: 89 : if( pVoid )
1798 : : {
1799 [ + - ]: 70 : xub_StrLen nWhere = CalcFlyPos( (SwFrmFmt*)pVoid );
1800 : : OSL_ENSURE( STRING_LEN != nWhere, "Prepare: Why me?" );
1801 [ + - ]: 70 : InvalidateRange( SwCharRange( nWhere, 1 ) );
1802 : : return;
1803 : : }
1804 : : // else ... Laufe in den Default-Switch
1805 : : }
1806 : : case PREP_CLEAR:
1807 : : default:
1808 : : {
1809 [ + + ]: 3081 : if( IsLocked() )
1810 : : {
1811 [ + + ][ + + ]: 1298 : if( PREP_FLY_ARRIVE == ePrep || PREP_FLY_LEAVE == ePrep )
1812 : : {
1813 : 1211 : xub_StrLen nLen = ( GetFollow() ? GetFollow()->GetOfst() :
1814 [ - + ]: 1211 : STRING_LEN ) - GetOfst();
1815 [ + - ]: 1211 : InvalidateRange( SwCharRange( GetOfst(), nLen ), 0 );
1816 : : }
1817 : : }
1818 : : else
1819 : : {
1820 [ + - ][ + + ]: 1783 : if( pPara->GetRepaint()->HasArea() )
1821 : 534 : SetCompletePaint();
1822 [ + - ]: 1783 : Init();
1823 : 1783 : pPara = 0;
1824 [ + + ][ - + ]: 1783 : if( GetOfst() && !IsFollow() )
[ - + ]
1825 [ # # ]: 0 : _SetOfst( 0 );
1826 [ + + ]: 1783 : if ( bNotify )
1827 [ + - ]: 1773 : InvalidateSize();
1828 : : else
1829 [ + - ]: 3081 : _InvalidateSize();
1830 : : }
1831 : : return; // damit kein SetPrep() erfolgt.
1832 : : }
1833 : : }
1834 [ + + ]: 1565 : if( pPara )
1835 [ + - ][ + + ]: 29292 : pPara->SetPrep( sal_True );
[ + + ]
1836 : : }
1837 : :
1838 : : /* --------------------------------------------------
1839 : : * Kleine Hilfsklasse mit folgender Funktion:
1840 : : * Sie soll eine Probeformatierung vorbereiten.
1841 : : * Der Frame wird in Groesse und Position angepasst, sein SwParaPortion zur Seite
1842 : : * gestellt und eine neue erzeugt, dazu wird formatiert mit gesetztem bTestFormat.
1843 : : * Im Dtor wird der TxtFrm wieder in seinen alten Zustand zurueckversetzt.
1844 : : *
1845 : : * --------------------------------------------------*/
1846 : :
1847 : : class SwTestFormat
1848 : : {
1849 : : SwTxtFrm *pFrm;
1850 : : SwParaPortion *pOldPara;
1851 : : SwRect aOldFrm, aOldPrt;
1852 : : public:
1853 : : SwTestFormat( SwTxtFrm* pTxtFrm, const SwFrm* pPrv, SwTwips nMaxHeight );
1854 : : ~SwTestFormat();
1855 : : };
1856 : :
1857 : 2 : SwTestFormat::SwTestFormat( SwTxtFrm* pTxtFrm, const SwFrm* pPre, SwTwips nMaxHeight )
1858 : 2 : : pFrm( pTxtFrm )
1859 : : {
1860 : 2 : aOldFrm = pFrm->Frm();
1861 : 2 : aOldPrt = pFrm->Prt();
1862 : :
1863 [ - + ][ # # ]: 2 : SWRECTFN( pFrm )
[ # # ][ - + ]
[ + - ]
1864 [ + - ][ + - ]: 2 : SwTwips nLower = (pFrm->*fnRect->fnGetBottomMargin)();
1865 : :
1866 : 2 : pFrm->Frm() = pFrm->GetUpper()->Prt();
1867 : 2 : pFrm->Frm() += pFrm->GetUpper()->Frm().Pos();
1868 : :
1869 [ + - ][ + - ]: 2 : (pFrm->Frm().*fnRect->fnSetHeight)( nMaxHeight );
1870 [ + - ]: 2 : if( pFrm->GetPrev() )
1871 : 2 : (pFrm->Frm().*fnRect->fnSetPosY)(
1872 [ + - ][ + - ]: 2 : (pFrm->GetPrev()->Frm().*fnRect->fnGetBottom)() -
1873 [ - + ][ + - ]: 4 : ( bVert ? nMaxHeight + 1 : 0 ) );
[ + - ]
1874 : :
1875 [ + - ]: 2 : SwBorderAttrAccess aAccess( SwFrm::GetCache(), pFrm );
1876 [ + - ]: 2 : const SwBorderAttrs &rAttrs = *aAccess.Get();
1877 [ + - ][ + - ]: 2 : (pFrm->Prt().*fnRect->fnSetPosX)( rAttrs.CalcLeft( pFrm ) );
[ + - ]
1878 : :
1879 [ + - ]: 2 : if( pPre )
1880 : : {
1881 [ + - ]: 2 : SwTwips nUpper = pFrm->CalcUpperSpace( &rAttrs, pPre );
1882 [ + - ][ + - ]: 2 : (pFrm->Prt().*fnRect->fnSetPosY)( nUpper );
1883 : : }
1884 : 2 : (pFrm->Prt().*fnRect->fnSetHeight)(
1885 [ + - ][ + - ]: 2 : Max( 0L , (pFrm->Frm().*fnRect->fnGetHeight)() -
1886 [ + - ][ + - ]: 4 : (pFrm->Prt().*fnRect->fnGetTop)() - nLower ) );
[ + - ][ + - ]
1887 : 2 : (pFrm->Prt().*fnRect->fnSetWidth)(
1888 [ + - ][ + - ]: 2 : (pFrm->Frm().*fnRect->fnGetWidth)() -
1889 [ + - ][ + - ]: 4 : ( rAttrs.CalcLeft( pFrm ) + rAttrs.CalcRight( pFrm ) ) );
[ + - ][ + - ]
1890 [ + - ][ + - ]: 2 : pOldPara = pFrm->HasPara() ? pFrm->GetPara() : NULL;
[ + - ]
1891 [ + - ][ + - ]: 2 : pFrm->SetPara( new SwParaPortion(), sal_False );
[ + - ]
1892 : :
1893 : : OSL_ENSURE( ! pFrm->IsSwapped(), "A frame is swapped before _Format" );
1894 : :
1895 [ + - ][ - + ]: 2 : if ( pFrm->IsVertical() )
1896 : 0 : pFrm->SwapWidthAndHeight();
1897 : :
1898 [ + - ]: 2 : SwTxtFormatInfo aInf( pFrm, sal_False, sal_True, sal_True );
1899 [ + - ]: 2 : SwTxtFormatter aLine( pFrm, &aInf );
1900 : :
1901 [ + - ]: 2 : pFrm->_Format( aLine, aInf );
1902 : :
1903 [ + - ][ - + ]: 2 : if ( pFrm->IsVertical() )
1904 : 0 : pFrm->SwapWidthAndHeight();
1905 : :
1906 [ + - ][ + - ]: 2 : OSL_ENSURE( ! pFrm->IsSwapped(), "A frame is swapped after _Format" );
[ + - ]
1907 : 2 : }
1908 : :
1909 : 2 : SwTestFormat::~SwTestFormat()
1910 : : {
1911 : 2 : pFrm->Frm() = aOldFrm;
1912 : 2 : pFrm->Prt() = aOldPrt;
1913 : 2 : pFrm->SetPara( pOldPara );
1914 : 2 : }
1915 : :
1916 : 2 : sal_Bool SwTxtFrm::TestFormat( const SwFrm* pPrv, SwTwips &rMaxHeight, sal_Bool &bSplit )
1917 : : {
1918 : : PROTOCOL_ENTER( this, PROT_TESTFORMAT, 0, 0 )
1919 : :
1920 [ - + ][ # # ]: 2 : if( IsLocked() && GetUpper()->Prt().Width() <= 0 )
[ - + ]
1921 : 0 : return sal_False;
1922 : :
1923 [ + - ]: 2 : SwTestFormat aSave( this, pPrv, rMaxHeight );
1924 : :
1925 [ + - ][ + - ]: 2 : return SwTxtFrm::WouldFit( rMaxHeight, bSplit, sal_True );
1926 : : }
1927 : :
1928 : :
1929 : : /*************************************************************************
1930 : : * SwTxtFrm::WouldFit()
1931 : : *************************************************************************/
1932 : :
1933 : : /* SwTxtFrm::WouldFit()
1934 : : * sal_True: wenn ich aufspalten kann.
1935 : : * Es soll und braucht nicht neu formatiert werden.
1936 : : * Wir gehen davon aus, dass bereits formatiert wurde und dass
1937 : : * die Formatierungsdaten noch aktuell sind.
1938 : : * Wir gehen davon aus, dass die Framebreiten des evtl. Masters und
1939 : : * Follows gleich sind. Deswegen wird kein FindBreak() mit FindOrphans()
1940 : : * gerufen.
1941 : : * Die benoetigte Hoehe wird von nMaxHeight abgezogen!
1942 : : */
1943 : :
1944 : 110 : sal_Bool SwTxtFrm::WouldFit( SwTwips &rMaxHeight, sal_Bool &bSplit, sal_Bool bTst )
1945 : : {
1946 : : OSL_ENSURE( ! IsVertical() || ! IsSwapped(),
1947 : : "SwTxtFrm::WouldFit with swapped frame" );
1948 [ + - ][ - + ]: 110 : SWRECTFN( this );
[ # # ][ # # ]
[ - + ]
1949 : :
1950 [ - + ]: 110 : if( IsLocked() )
1951 : 0 : return sal_False;
1952 : :
1953 : : //Kann gut sein, dass mir der IdleCollector mir die gecachten
1954 : : //Informationen entzogen hat.
1955 [ + + ]: 110 : if( !IsEmpty() )
1956 [ + - ]: 88 : GetFormatted();
1957 : :
1958 : : // OD 2004-05-24 #i27801# - correction: 'short cut' for empty paragraph
1959 : : // can *not* be applied, if test format is in progress. The test format doesn't
1960 : : // adjust the frame and the printing area - see method <SwTxtFrm::_Format(..)>,
1961 : : // which is called in <SwTxtFrm::TestFormat(..)>
1962 [ + + ][ + - ]: 110 : if ( IsEmpty() && !bTst )
[ + + ]
1963 : : {
1964 : 22 : bSplit = sal_False;
1965 [ - + ]: 22 : SwTwips nHeight = bVert ? Prt().SSize().Width() : Prt().SSize().Height();
1966 [ + + ]: 22 : if( rMaxHeight < nHeight )
1967 : 4 : return sal_False;
1968 : : else
1969 : : {
1970 : 18 : rMaxHeight -= nHeight;
1971 : 18 : return sal_True;
1972 : : }
1973 : : }
1974 : :
1975 : : // In sehr unguenstigen Faellen kann GetPara immer noch 0 sein.
1976 : : // Dann returnen wir sal_True, um auf der neuen Seite noch einmal
1977 : : // anformatiert zu werden.
1978 : : OSL_ENSURE( HasPara() || IsHiddenNow(), "WouldFit: GetFormatted() and then !HasPara()" );
1979 [ + - ][ + - ]: 88 : if( !HasPara() || ( !(Frm().*fnRect->fnGetHeight)() && IsHiddenNow() ) )
[ + - ][ + - ]
[ - + ][ # # ]
[ # # ][ - + ]
1980 : 0 : return sal_True;
1981 : :
1982 : : // Da das Orphan-Flag nur sehr fluechtig existiert, wird als zweite
1983 : : // Bedingung ueberprueft, ob die Rahmengroesse durch CalcPreps
1984 : : // auf riesengross gesetzt wird, um ein MoveFwd zu erzwingen.
1985 [ + - ][ - + : 176 : if( IsWidow() || ( bVert ?
# # - + ]
[ - + ]
1986 : 0 : ( 0 == Frm().Left() ) :
1987 : 88 : ( LONG_MAX - 20000 < Frm().Bottom() ) ) )
1988 : : {
1989 : 0 : SetWidow(sal_False);
1990 [ # # ]: 0 : if ( GetFollow() )
1991 : : {
1992 : : // Wenn wir hier durch eine Widow-Anforderung unseres Follows gelandet
1993 : : // sind, wird ueberprueft, ob es ueberhaupt einen Follow mit einer
1994 : : // echten Hoehe gibt, andernfalls (z.B. in neu angelegten SctFrms)
1995 : : // ignorieren wir das IsWidow() und pruefen doch noch, ob wir
1996 : : // genung Platz finden.
1997 [ # # ][ # # ]: 0 : if( ( ( ! bVert && LONG_MAX - 20000 >= Frm().Bottom() ) ||
[ # # # # ]
[ # # # #
# # ][ # # ]
1998 : 0 : ( bVert && 0 < Frm().Left() ) ) &&
1999 [ # # ]: 0 : ( GetFollow()->IsVertical() ?
2000 : 0 : !GetFollow()->Frm().Width() :
2001 : 0 : !GetFollow()->Frm().Height() ) )
2002 : : {
2003 : 0 : SwTxtFrm* pFoll = GetFollow()->GetFollow();
2004 [ # # ][ # # : 0 : while( pFoll &&
# # # # ]
[ # # ]
2005 [ # # ]: 0 : ( pFoll->IsVertical() ?
2006 : 0 : !pFoll->Frm().Width() :
2007 : 0 : !pFoll->Frm().Height() ) )
2008 : 0 : pFoll = pFoll->GetFollow();
2009 [ # # ]: 0 : if( pFoll )
2010 : 0 : return sal_False;
2011 : : }
2012 : : else
2013 : 0 : return sal_False;
2014 : : }
2015 : : }
2016 : :
2017 [ + - ][ - + ]: 88 : SWAP_IF_NOT_SWAPPED( this );
[ # # ][ - + ]
2018 : :
2019 [ + - ]: 88 : SwTxtSizeInfo aInf( this );
2020 [ + - ]: 88 : SwTxtMargin aLine( this, &aInf );
2021 : :
2022 [ + - ]: 88 : WidowsAndOrphans aFrmBreak( this, rMaxHeight, bSplit );
2023 : :
2024 : 88 : sal_Bool bRet = sal_True;
2025 : :
2026 [ + - ]: 88 : aLine.Bottom();
2027 : : // Ist Aufspalten ueberhaupt notwendig?
2028 [ + - ][ + + ]: 88 : if ( 0 != ( bSplit = !aFrmBreak.IsInside( aLine ) ) )
2029 [ + - ][ + - ]: 60 : bRet = !aFrmBreak.IsKeepAlways() && aFrmBreak.WouldFit( aLine, rMaxHeight, bTst );
[ + + ]
2030 : : else
2031 : : {
2032 : : //Wir brauchen die Gesamthoehe inklusive der aktuellen Zeile
2033 [ + - ]: 28 : aLine.Top();
2034 [ + + ]: 40 : do
2035 : : {
2036 : 40 : rMaxHeight -= aLine.GetLineHeight();
2037 [ + - ]: 40 : } while ( aLine.Next() );
2038 : : }
2039 : :
2040 [ - + ]: 88 : UNDO_SWAP( this )
2041 : :
2042 [ + - ]: 110 : return bRet;
2043 : : }
2044 : :
2045 : :
2046 : : /*************************************************************************
2047 : : * SwTxtFrm::GetParHeight()
2048 : : *************************************************************************/
2049 : :
2050 : 90 : KSHORT SwTxtFrm::GetParHeight() const
2051 : : {
2052 : : OSL_ENSURE( ! IsVertical() || ! IsSwapped(),
2053 : : "SwTxtFrm::GetParHeight with swapped frame" );
2054 : :
2055 [ + + ]: 90 : if( !HasPara() )
2056 : : { // Fuer nichtleere Absaetze ist dies ein Sonderfall, da koennen wir
2057 : : // bei UnderSized ruhig nur 1 Twip mehr anfordern.
2058 : 28 : KSHORT nRet = (KSHORT)Prt().SSize().Height();
2059 [ + - ]: 28 : if( IsUndersized() )
2060 : : {
2061 [ + + ]: 28 : if( IsEmpty() )
2062 : 24 : nRet = (KSHORT)EmptyHeight();
2063 : : else
2064 : 4 : ++nRet;
2065 : : }
2066 : 28 : return nRet;
2067 : : }
2068 : :
2069 : : // FME, OD 08.01.2004 #i11859# - refactoring and improve code
2070 : 62 : const SwLineLayout* pLineLayout = GetPara();
2071 : 62 : KSHORT nHeight = pLineLayout->GetRealHeight();
2072 [ # # ][ - + ]: 62 : if( GetOfst() && !IsFollow() ) // Ist dieser Absatz gescrollt? Dann ist unsere
[ - + ]
2073 : 0 : nHeight *= 2; // bisherige Hoehe mind. eine Zeilenhoehe zu gering
2074 : : // OD 2004-03-04 #115793#
2075 [ + - ][ + + ]: 1516 : while ( pLineLayout && pLineLayout->GetNext() )
[ + + ]
2076 : : {
2077 : 1454 : pLineLayout = pLineLayout->GetNext();
2078 : 1454 : nHeight = nHeight + pLineLayout->GetRealHeight();
2079 : : }
2080 : :
2081 : 90 : return nHeight;
2082 : : }
2083 : :
2084 : :
2085 : : /*************************************************************************
2086 : : * SwTxtFrm::GetFormatted()
2087 : : *************************************************************************/
2088 : :
2089 : : // returnt this _immer_ im formatierten Zustand!
2090 : 71836 : SwTxtFrm* SwTxtFrm::GetFormatted( bool bForceQuickFormat )
2091 : : {
2092 [ - + ][ # # ]: 71836 : SWAP_IF_SWAPPED( this )
[ - + ]
2093 : :
2094 : : //Kann gut sein, dass mir der IdleCollector mir die gecachten
2095 : : //Informationen entzogen hat. Calc() ruft unser Format.
2096 : : //Nicht bei leeren Absaetzen!
2097 [ + + ][ + + ]: 71836 : if( !HasPara() && !(IsValid() && IsEmpty()) )
[ - + ][ + + ]
2098 : : {
2099 : : // Calc() muss gerufen werden, weil unsere Frameposition
2100 : : // nicht stimmen muss.
2101 : 237 : const sal_Bool bFormat = GetValidSizeFlag();
2102 : 237 : Calc();
2103 : : // Es kann durchaus sein, dass Calc() das Format()
2104 : : // nicht anstiess (weil wir einst vom Idle-Zerstoerer
2105 : : // aufgefordert wurden unsere Formatinformationen wegzuschmeissen).
2106 : : // 6995: Optimierung mit FormatQuick()
2107 [ # # ][ - + ]: 237 : if( bFormat && !FormatQuick( bForceQuickFormat ) )
[ - + ]
2108 : 0 : Format();
2109 : : }
2110 : :
2111 [ - + ]: 71836 : UNDO_SWAP( this )
2112 : :
2113 : 71836 : return this;
2114 : : }
2115 : :
2116 : : /*************************************************************************
2117 : : * SwTxtFrm::CalcFitToContent()
2118 : : *************************************************************************/
2119 : :
2120 : 0 : SwTwips SwTxtFrm::CalcFitToContent()
2121 : : {
2122 : : // #i31490#
2123 : : // If we are currently locked, we better return with a
2124 : : // fairly reasonable value:
2125 [ # # ]: 0 : if ( IsLocked() )
2126 : 0 : return Prt().Width();
2127 : :
2128 [ # # ]: 0 : SwParaPortion* pOldPara = GetPara();
2129 [ # # ][ # # ]: 0 : SwParaPortion *pDummy = new SwParaPortion();
2130 [ # # ]: 0 : SetPara( pDummy, false );
2131 [ # # ]: 0 : const SwPageFrm* pPage = FindPageFrm();
2132 : :
2133 : 0 : const Point aOldFrmPos = Frm().Pos();
2134 : 0 : const SwTwips nOldFrmWidth = Frm().Width();
2135 : 0 : const SwTwips nOldPrtWidth = Prt().Width();
2136 [ # # ]: 0 : const SwTwips nPageWidth = GetUpper()->IsVertical() ?
2137 : 0 : pPage->Prt().Height() :
2138 [ # # ]: 0 : pPage->Prt().Width();
2139 : :
2140 : 0 : Frm().Width( nPageWidth );
2141 : 0 : Prt().Width( nPageWidth );
2142 : :
2143 : : // #i25422# objects anchored as character in RTL
2144 [ # # ][ # # ]: 0 : if ( IsRightToLeft() )
2145 : 0 : Frm().Pos().X() += nOldFrmWidth - nPageWidth;
2146 : :
2147 : : // #i31490#
2148 : 0 : SwTxtFrmLocker aLock( this );
2149 : :
2150 [ # # ]: 0 : SwTxtFormatInfo aInf( this, sal_False, sal_True, sal_True );
2151 : 0 : aInf.SetIgnoreFly( sal_True );
2152 [ # # ]: 0 : SwTxtFormatter aLine( this, &aInf );
2153 [ # # ]: 0 : SwHookOut aHook( aInf );
2154 : :
2155 : : // #i54031# - assure mininum of MINLAY twips.
2156 : : const SwTwips nMax = Max( (SwTwips)MINLAY,
2157 [ # # ]: 0 : aLine._CalcFitToContent() + 1 );
2158 : :
2159 : 0 : Frm().Width( nOldFrmWidth );
2160 : 0 : Prt().Width( nOldPrtWidth );
2161 : :
2162 : : // #i25422# objects anchored as character in RTL
2163 [ # # ][ # # ]: 0 : if ( IsRightToLeft() )
2164 : 0 : Frm().Pos() = aOldFrmPos;
2165 : :
2166 : :
2167 [ # # ]: 0 : SetPara( pOldPara );
2168 : :
2169 [ # # ][ # # ]: 0 : return nMax;
[ # # ]
2170 : : }
2171 : :
2172 : : /** simulate format for a list item paragraph, whose list level attributes
2173 : : are in LABEL_ALIGNMENT mode, in order to determine additional first
2174 : : line offset for the real text formatting due to the value of label
2175 : : adjustment attribute of the list level.
2176 : : */
2177 : 20402 : void SwTxtFrm::CalcAdditionalFirstLineOffset()
2178 : : {
2179 [ - + ]: 20402 : if ( IsLocked() )
2180 : 20402 : return;
2181 : :
2182 : : // reset additional first line offset
2183 : 20402 : mnAdditionalFirstLineOffset = 0;
2184 : :
2185 : 20402 : const SwTxtNode* pTxtNode( GetTxtNode() );
2186 [ + + ]: 20556 : if ( pTxtNode && pTxtNode->IsNumbered() && pTxtNode->IsCountedInList() &&
[ + - + - ]
[ + + ][ + - ]
2187 : 154 : pTxtNode->GetNumRule() )
2188 : : {
2189 : : const SwNumFmt& rNumFmt =
2190 : 154 : pTxtNode->GetNumRule()->Get( static_cast<sal_uInt16>(pTxtNode->GetActualListLevel()) );
2191 [ + + ]: 154 : if ( rNumFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_ALIGNMENT )
2192 : : {
2193 : : // keep current paragraph portion and apply dummy paragraph portion
2194 [ + - ]: 90 : SwParaPortion* pOldPara = GetPara();
2195 [ + - ][ + - ]: 90 : SwParaPortion *pDummy = new SwParaPortion();
2196 [ + - ]: 90 : SetPara( pDummy, false );
2197 : :
2198 : : // lock paragraph
2199 : 90 : SwTxtFrmLocker aLock( this );
2200 : :
2201 : : // simulate text formatting
2202 [ + - ]: 90 : SwTxtFormatInfo aInf( this, sal_False, sal_True, sal_True );
2203 : 90 : aInf.SetIgnoreFly( sal_True );
2204 [ + - ]: 90 : SwTxtFormatter aLine( this, &aInf );
2205 [ + - ]: 90 : SwHookOut aHook( aInf );
2206 [ + - ]: 90 : aLine._CalcFitToContent();
2207 : :
2208 : : // determine additional first line offset
2209 : 90 : const SwLinePortion* pFirstPortion = aLine.GetCurr()->GetFirstPortion();
2210 [ + - ][ + + ]: 90 : if ( pFirstPortion->InNumberGrp() && !pFirstPortion->IsFtnNumPortion() )
[ + + ]
2211 : : {
2212 : 87 : SwTwips nNumberPortionWidth( pFirstPortion->Width() );
2213 : :
2214 : 87 : const SwLinePortion* pPortion = pFirstPortion->GetPortion();
2215 [ + - - + : 174 : while ( pPortion &&
# # ][ - + ]
2216 : 87 : pPortion->InNumberGrp() && !pPortion->IsFtnNumPortion())
2217 : : {
2218 : 0 : nNumberPortionWidth += pPortion->Width();
2219 : 0 : pPortion = pPortion->GetPortion();
2220 : : }
2221 : :
2222 [ + - ]: 261 : if ( ( IsRightToLeft() &&
[ - + # # ]
[ + - - + ]
[ - + ]
2223 : 0 : rNumFmt.GetNumAdjust() == SVX_ADJUST_LEFT ) ||
2224 [ + - ]: 87 : ( !IsRightToLeft() &&
2225 : 87 : rNumFmt.GetNumAdjust() == SVX_ADJUST_RIGHT ) )
2226 : : {
2227 : 0 : mnAdditionalFirstLineOffset = -nNumberPortionWidth;
2228 : : }
2229 [ - + ]: 87 : else if ( rNumFmt.GetNumAdjust() == SVX_ADJUST_CENTER )
2230 : : {
2231 : 0 : mnAdditionalFirstLineOffset = -(nNumberPortionWidth/2);
2232 : : }
2233 : : }
2234 : :
2235 : : // restore paragraph portion
2236 [ + - ][ + - ]: 90 : SetPara( pOldPara );
[ + - ][ + - ]
2237 : : }
2238 : : }
2239 : : }
2240 : :
2241 : : /** determine height of last line for the calculation of the proportional line
2242 : : spacing
2243 : :
2244 : : OD 08.01.2004 #i11859#
2245 : : OD 2004-03-17 #i11860# - method <GetHeightOfLastLineForPropLineSpacing()>
2246 : : replace by method <_CalcHeightOfLastLine()>. Height of last line will be
2247 : : stored in new member <mnHeightOfLastLine> and can be accessed via method
2248 : : <GetHeightOfLastLine()>
2249 : : OD 2005-05-20 #i47162# - introduce new optional parameter <_bUseFont>
2250 : : in order to force the usage of the former algorithm to determine the
2251 : : height of the last line, which uses the font.
2252 : : */
2253 : 21145 : void SwTxtFrm::_CalcHeightOfLastLine( const bool _bUseFont )
2254 : : {
2255 : : // #i71281#
2256 : : // invalidate printing area, if height of last line changes
2257 : 21145 : const SwTwips mnOldHeightOfLastLine( mnHeightOfLastLine );
2258 : : // determine output device
2259 : 21145 : ViewShell* pVsh = getRootFrm()->GetCurrShell();
2260 : : OSL_ENSURE( pVsh, "<SwTxtFrm::_GetHeightOfLastLineForPropLineSpacing()> - no ViewShell" );
2261 : : // #i78921# - make code robust, according to provided patch
2262 : : // There could be no <ViewShell> instance in the case of loading a binary
2263 : : // StarOffice file format containing an embedded Writer document.
2264 [ - + ]: 21145 : if ( !pVsh )
2265 : : {
2266 : 0 : return;
2267 : : }
2268 : 21145 : OutputDevice* pOut = pVsh->GetOut();
2269 : 21145 : const IDocumentSettingAccess* pIDSA = GetTxtNode()->getIDocumentSettingAccess();
2270 [ + + ]: 21201 : if ( !pVsh->GetViewOptions()->getBrowseMode() ||
[ + + - + ]
2271 : 56 : pVsh->GetViewOptions()->IsPrtFormat() )
2272 : : {
2273 : 21089 : pOut = GetTxtNode()->getIDocumentDeviceAccess()->getReferenceDevice( true );
2274 : : }
2275 : : OSL_ENSURE( pOut, "<SwTxtFrm::_GetHeightOfLastLineForPropLineSpacing()> - no OutputDevice" );
2276 : : // #i78921# - make code robust, according to provided patch
2277 [ - + ]: 21145 : if ( !pOut )
2278 : : {
2279 : 0 : return;
2280 : : }
2281 : :
2282 : : // determine height of last line
2283 : :
2284 [ + + ][ + + ]: 21145 : if ( _bUseFont || pIDSA->get(IDocumentSettingAccess::OLD_LINE_SPACING ) )
[ + + ]
2285 : : {
2286 : : // former determination of last line height for proprotional line
2287 : : // spacing - take height of font set at the paragraph
2288 [ + - ][ + - ]: 1301 : SwFont aFont( GetAttrSet(), pIDSA );
2289 : :
2290 : : // Wir muessen dafuer sorgen, dass am OutputDevice der Font
2291 : : // korrekt restauriert wird, sonst droht ein Last!=Owner.
2292 [ + - ]: 1301 : if ( pLastFont )
2293 : : {
2294 : 1301 : SwFntObj *pOldFont = pLastFont;
2295 : 1301 : pLastFont = NULL;
2296 : 1301 : aFont.SetFntChg( sal_True );
2297 [ + - ]: 1301 : aFont.ChgPhysFnt( pVsh, *pOut );
2298 [ + - ]: 1301 : mnHeightOfLastLine = aFont.GetHeight( pVsh, *pOut );
2299 : 1301 : pLastFont->Unlock();
2300 : 1301 : pLastFont = pOldFont;
2301 [ + - ]: 1301 : pLastFont->SetDevFont( pVsh, *pOut );
2302 : : }
2303 : : else
2304 : : {
2305 [ # # ]: 0 : Font aOldFont = pOut->GetFont();
2306 : 0 : aFont.SetFntChg( sal_True );
2307 [ # # ]: 0 : aFont.ChgPhysFnt( pVsh, *pOut );
2308 [ # # ]: 0 : mnHeightOfLastLine = aFont.GetHeight( pVsh, *pOut );
2309 : 0 : pLastFont->Unlock();
2310 : 0 : pLastFont = NULL;
2311 [ # # ][ # # ]: 0 : pOut->SetFont( aOldFont );
2312 [ + - ]: 1301 : }
2313 : : }
2314 : : else
2315 : : {
2316 : : // new determination of last line height - take actually height of last line
2317 : : // #i89000#
2318 : : // assure same results, if paragraph is undersized
2319 [ + + ]: 19844 : if ( IsUndersized() )
2320 : : {
2321 : 225 : mnHeightOfLastLine = 0;
2322 : : }
2323 : : else
2324 : : {
2325 : 19619 : bool bCalcHeightOfLastLine = true;
2326 [ + + ]: 19619 : if ( !HasPara() )
2327 : : {
2328 [ + - ]: 4636 : if ( IsEmpty() )
2329 : : {
2330 : 4636 : mnHeightOfLastLine = EmptyHeight();
2331 : 4636 : bCalcHeightOfLastLine = false;
2332 : : }
2333 : : }
2334 : :
2335 [ + + ]: 19619 : if ( bCalcHeightOfLastLine )
2336 : : {
2337 : : OSL_ENSURE( HasPara(),
2338 : : "<SwTxtFrm::_CalcHeightOfLastLine()> - missing paragraph portions." );
2339 : 14983 : const SwLineLayout* pLineLayout = GetPara();
2340 [ + - ][ + + ]: 101550 : while ( pLineLayout && pLineLayout->GetNext() )
[ + + ]
2341 : : {
2342 : : // iteration to last line
2343 : 86567 : pLineLayout = pLineLayout->GetNext();
2344 : : }
2345 [ + - ]: 14983 : if ( pLineLayout )
2346 : : {
2347 : : SwTwips nAscent, nDescent, nDummy1, nDummy2;
2348 : : // #i47162# - suppress consideration of
2349 : : // fly content portions and the line portion.
2350 : : pLineLayout->MaxAscentDescent( nAscent, nDescent,
2351 : : nDummy1, nDummy2,
2352 [ + - ]: 14983 : 0, true );
2353 : : // #i71281#
2354 : : // Suppress wrong invalidation of printing area, if method is
2355 : : // called recursive.
2356 : : // Thus, member <mnHeightOfLastLine> is only set directly, if
2357 : : // no recursive call is needed.
2358 : 14983 : const SwTwips nNewHeightOfLastLine = nAscent + nDescent;
2359 : : // #i47162# - if last line only contains
2360 : : // fly content portions, <mnHeightOfLastLine> is zero.
2361 : : // In this case determine height of last line by the font
2362 [ + + ]: 14983 : if ( nNewHeightOfLastLine == 0 )
2363 : : {
2364 [ + - ]: 1299 : _CalcHeightOfLastLine( true );
2365 : : }
2366 : : else
2367 : : {
2368 : 14983 : mnHeightOfLastLine = nNewHeightOfLastLine;
2369 : : }
2370 : : }
2371 : : }
2372 : : }
2373 : : }
2374 : : // #i71281#
2375 : : // invalidate printing area, if height of last line changes
2376 [ + + ]: 21145 : if ( mnHeightOfLastLine != mnOldHeightOfLastLine )
2377 : : {
2378 : 21145 : InvalidatePrt();
2379 : : }
2380 : : }
2381 : :
2382 : : /*************************************************************************
2383 : : * SwTxtFrm::GetLineSpace()
2384 : : *************************************************************************/
2385 : : // OD 07.01.2004 #i11859# - change return data type
2386 : : // add default parameter <_bNoPropLineSpacing> to control, if the
2387 : : // value of a proportional line spacing is returned or not
2388 : : // OD 07.01.2004 - trying to describe purpose of method:
2389 : : // Method returns the value of the inter line spacing for a text frame.
2390 : : // Such a value exists for proportional line spacings ("1,5 Lines",
2391 : : // "Double", "Proportional" and for leading line spacing ("Leading").
2392 : : // By parameter <_bNoPropLineSpace> (default value false) it can be
2393 : : // controlled, if the value of a proportional line spacing is returned.
2394 : 9093 : long SwTxtFrm::GetLineSpace( const bool _bNoPropLineSpace ) const
2395 : : {
2396 : 9093 : long nRet = 0;
2397 : :
2398 : 9093 : const SwAttrSet* pSet = GetAttrSet();
2399 : 9093 : const SvxLineSpacingItem &rSpace = pSet->GetLineSpacing();
2400 : :
2401 [ + - + ]: 9093 : switch( rSpace.GetInterLineSpaceRule() )
2402 : : {
2403 : : case SVX_INTER_LINE_SPACE_PROP:
2404 : : {
2405 : : // OD 07.01.2004 #i11859#
2406 [ + + ]: 1056 : if ( _bNoPropLineSpace )
2407 : : {
2408 : 687 : break;
2409 : : }
2410 : :
2411 : : // OD 2004-03-17 #i11860# - use method <GetHeightOfLastLine()>
2412 : 369 : nRet = GetHeightOfLastLine();
2413 : :
2414 : 369 : long nTmp = nRet;
2415 : 369 : nTmp *= rSpace.GetPropLineSpace();
2416 : 369 : nTmp /= 100;
2417 : 369 : nTmp -= nRet;
2418 [ + + ]: 369 : if ( nTmp > 0 )
2419 : 318 : nRet = nTmp;
2420 : : else
2421 : 51 : nRet = 0;
2422 : : }
2423 : 369 : break;
2424 : : case SVX_INTER_LINE_SPACE_FIX:
2425 : : {
2426 [ # # ]: 0 : if ( rSpace.GetInterLineSpace() > 0 )
2427 : 0 : nRet = rSpace.GetInterLineSpace();
2428 : : }
2429 : 0 : break;
2430 : : default:
2431 : 8037 : break;
2432 : : }
2433 : 9093 : return nRet;
2434 : : }
2435 : :
2436 : : /*************************************************************************
2437 : : * SwTxtFrm::FirstLineHeight()
2438 : : *************************************************************************/
2439 : :
2440 : 66 : KSHORT SwTxtFrm::FirstLineHeight() const
2441 : : {
2442 [ + - ]: 66 : if ( !HasPara() )
2443 : : {
2444 [ + - ][ + - ]: 66 : if( IsEmpty() && IsValid() )
[ + - ]
2445 [ - + ]: 66 : return IsVertical() ? (KSHORT)Prt().Width() : (KSHORT)Prt().Height();
2446 : 0 : return KSHRT_MAX;
2447 : : }
2448 : 0 : const SwParaPortion *pPara = GetPara();
2449 [ # # ]: 0 : if ( !pPara )
2450 : 0 : return KSHRT_MAX;
2451 : :
2452 : 66 : return pPara->Height();
2453 : : }
2454 : :
2455 : 0 : MSHORT SwTxtFrm::GetLineCount( xub_StrLen nPos )
2456 : : {
2457 : 0 : MSHORT nRet = 0;
2458 : 0 : SwTxtFrm *pFrm = this;
2459 [ # # ][ # # ]: 0 : do
[ # # ]
2460 : : {
2461 [ # # ]: 0 : pFrm->GetFormatted();
2462 [ # # ][ # # ]: 0 : if( !pFrm->HasPara() )
2463 : : break;
2464 [ # # ]: 0 : SwTxtSizeInfo aInf( pFrm );
2465 [ # # ]: 0 : SwTxtMargin aLine( pFrm, &aInf );
2466 [ # # ]: 0 : if( STRING_LEN == nPos )
2467 [ # # ]: 0 : aLine.Bottom();
2468 : : else
2469 [ # # ]: 0 : aLine.CharToLine( nPos );
2470 : 0 : nRet = nRet + aLine.GetLineNr();
2471 [ # # ]: 0 : pFrm = pFrm->GetFollow();
2472 : 0 : } while ( pFrm && pFrm->GetOfst() <= nPos );
2473 : 0 : return nRet;
2474 : : }
2475 : :
2476 : 20284 : void SwTxtFrm::ChgThisLines()
2477 : : {
2478 : : //not necassary to format here (GerFormatted etc.), because we have to come from there!
2479 : :
2480 : 20284 : sal_uLong nNew = 0;
2481 : 20284 : const SwLineNumberInfo &rInf = GetNode()->getIDocumentLineNumberAccess()->GetLineNumberInfo();
2482 [ + + ][ + + ]: 20284 : if ( GetTxt().Len() && HasPara() )
[ + + ]
2483 : : {
2484 [ + - ]: 13138 : SwTxtSizeInfo aInf( this );
2485 [ + - ]: 13138 : SwTxtMargin aLine( this, &aInf );
2486 [ + - ]: 13138 : if ( rInf.IsCountBlankLines() )
2487 : : {
2488 [ + - ]: 13138 : aLine.Bottom();
2489 : 13138 : nNew = (sal_uLong)aLine.GetLineNr();
2490 : : }
2491 : : else
2492 : : {
2493 [ # # ]: 0 : do
2494 : : {
2495 [ # # ]: 0 : if( aLine.GetCurr()->HasCntnt() )
2496 : 0 : ++nNew;
2497 [ # # ]: 0 : } while ( aLine.NextLine() );
2498 [ + - ]: 13138 : }
2499 : : }
2500 [ + - ]: 7146 : else if ( rInf.IsCountBlankLines() )
2501 : 7146 : nNew = 1;
2502 : :
2503 [ + + ]: 20284 : if ( nNew != nThisLines )
2504 : : {
2505 [ + + ][ + + ]: 6754 : if ( !IsInTab() && GetAttrSet()->GetLineNumber().IsCount() )
[ + + ]
2506 : : {
2507 : 4777 : nAllLines -= nThisLines;
2508 : 4777 : nThisLines = nNew;
2509 : 4777 : nAllLines += nThisLines;
2510 : 4777 : SwFrm *pNxt = GetNextCntntFrm();
2511 [ + + ][ + + ]: 4865 : while( pNxt && pNxt->IsInTab() )
[ + + ]
2512 : : {
2513 [ + - ]: 88 : if( 0 != (pNxt = pNxt->FindTabFrm()) )
2514 : 88 : pNxt = pNxt->FindNextCnt();
2515 : : }
2516 [ + + ]: 4777 : if( pNxt )
2517 : 2357 : pNxt->InvalidateLineNum();
2518 : :
2519 : : //Extend repaint to the bottom.
2520 [ + + ]: 4777 : if ( HasPara() )
2521 : : {
2522 : 3399 : SwRepaint *pRepaint = GetPara()->GetRepaint();
2523 : : pRepaint->Bottom( Max( pRepaint->Bottom(),
2524 : 3399 : Frm().Top()+Prt().Bottom()));
2525 : : }
2526 : : }
2527 : : else //Paragraphs which are not counted should not manipulate the AllLines.
2528 : 1977 : nThisLines = nNew;
2529 : : }
2530 : 20284 : }
2531 : :
2532 : :
2533 : 10346 : void SwTxtFrm::RecalcAllLines()
2534 : : {
2535 : 10346 : ValidateLineNum();
2536 : :
2537 : 10346 : const SwAttrSet *pAttrSet = GetAttrSet();
2538 : :
2539 [ + + ]: 10346 : if ( !IsInTab() )
2540 : : {
2541 : 5873 : const sal_uLong nOld = GetAllLines();
2542 : 5873 : const SwFmtLineNumber &rLineNum = pAttrSet->GetLineNumber();
2543 : : sal_uLong nNewNum;
2544 : 5873 : const bool bRestart = GetTxtNode()->getIDocumentLineNumberAccess()->GetLineNumberInfo().IsRestartEachPage();
2545 : :
2546 [ - + ][ # # ]: 5873 : if ( !IsFollow() && rLineNum.GetStartValue() && rLineNum.IsCount() )
[ - + ][ + + ]
2547 : 0 : nNewNum = rLineNum.GetStartValue() - 1;
2548 : : //If it is a follow or not has not be considered if it is a restart at each page; the
2549 : : //restart should also take affekt at follows.
2550 [ - + ][ # # ]: 5873 : else if ( bRestart && FindPageFrm()->FindFirstBodyCntnt() == this )
[ - + ]
2551 : : {
2552 : 0 : nNewNum = 0;
2553 : : }
2554 : : else
2555 : : {
2556 : 5873 : SwCntntFrm *pPrv = GetPrevCntntFrm();
2557 [ + + + + : 17226 : while ( pPrv &&
+ + ][ + + ]
2558 : 9615 : (pPrv->IsInTab() || pPrv->IsInDocBody() != IsInDocBody()) )
2559 : 1738 : pPrv = pPrv->GetPrevCntntFrm();
2560 : :
2561 : : // #i78254# Restart line numbering at page change
2562 : : // First body content may be in table!
2563 [ - + ][ # # ]: 5873 : if ( bRestart && pPrv && pPrv->FindPageFrm() != FindPageFrm() )
[ # # ][ - + ]
2564 : 0 : pPrv = 0;
2565 : :
2566 [ + + ]: 5873 : nNewNum = pPrv ? ((SwTxtFrm*)pPrv)->GetAllLines() : 0;
2567 : : }
2568 [ + + ]: 5873 : if ( rLineNum.IsCount() )
2569 : 5756 : nNewNum += GetThisLines();
2570 : :
2571 [ + + ]: 5873 : if ( nOld != nNewNum )
2572 : : {
2573 : 3416 : nAllLines = nNewNum;
2574 : 3416 : SwCntntFrm *pNxt = GetNextCntntFrm();
2575 [ + + + + : 9627 : while ( pNxt &&
+ + ][ + + ]
2576 : 5664 : (pNxt->IsInTab() || pNxt->IsInDocBody() != IsInDocBody()) )
2577 : 547 : pNxt = pNxt->GetNextCntntFrm();
2578 [ + + ]: 3416 : if ( pNxt )
2579 : : {
2580 [ + + ]: 2542 : if ( pNxt->GetUpper() != GetUpper() )
2581 : 477 : pNxt->InvalidateLineNum();
2582 : : else
2583 : 2065 : pNxt->_InvalidateLineNum();
2584 : : }
2585 : : }
2586 : : }
2587 : 10346 : }
2588 : :
2589 : 82 : void SwTxtFrm::VisitPortions( SwPortionHandler& rPH ) const
2590 : : {
2591 : 82 : const SwParaPortion* pPara = GetPara();
2592 : :
2593 [ + + ]: 82 : if( pPara )
2594 : : {
2595 [ - + ]: 71 : if ( IsFollow() )
2596 : 0 : rPH.Skip( GetOfst() );
2597 : :
2598 : 71 : const SwLineLayout* pLine = pPara;
2599 [ + + ]: 142 : while ( pLine )
2600 : : {
2601 : 71 : const SwLinePortion* pPor = pLine->GetFirstPortion();
2602 [ + + ]: 152 : while ( pPor )
2603 : : {
2604 : 81 : pPor->HandlePortion( rPH );
2605 : 81 : pPor = pPor->GetPortion();
2606 : : }
2607 : :
2608 : 71 : rPH.LineBreak();
2609 : 71 : pLine = pLine->GetNext();
2610 : : }
2611 : : }
2612 : :
2613 : 82 : rPH.Finish();
2614 : 82 : }
2615 : :
2616 : :
2617 : : /*************************************************************************
2618 : : * SwTxtFrm::GetScriptInfo()
2619 : : *************************************************************************/
2620 : :
2621 : 60044 : const SwScriptInfo* SwTxtFrm::GetScriptInfo() const
2622 : : {
2623 : 60044 : const SwParaPortion* pPara = GetPara();
2624 [ + + ]: 60044 : return pPara ? &pPara->GetScriptInfo() : 0;
2625 : : }
2626 : :
2627 : : /*************************************************************************
2628 : : * lcl_CalcFlyBasePos()
2629 : : * Helper function for SwTxtFrm::CalcBasePosForFly()
2630 : : *************************************************************************/
2631 : :
2632 : 942 : SwTwips lcl_CalcFlyBasePos( const SwTxtFrm& rFrm, SwRect aFlyRect,
2633 : : SwTxtFly& rTxtFly )
2634 : : {
2635 [ - + ][ # # ]: 942 : SWRECTFN( (&rFrm) )
[ # # ][ - + ]
2636 : 942 : SwTwips nRet = rFrm.IsRightToLeft() ?
2637 [ # # ]: 0 : (rFrm.Frm().*fnRect->fnGetRight)() :
2638 [ + - ][ - + ]: 942 : (rFrm.Frm().*fnRect->fnGetLeft)();
2639 : :
2640 [ # # ]: 0 : do
2641 : : {
2642 [ + - ]: 942 : SwRect aRect = rTxtFly.GetFrm( aFlyRect );
2643 [ + - ][ + - ]: 942 : if ( 0 != (aRect.*fnRect->fnGetWidth)() )
[ - + ]
2644 : : {
2645 [ # # ][ # # ]: 0 : if ( rFrm.IsRightToLeft() )
2646 : : {
2647 [ # # ][ # # ]: 0 : if ( (aRect.*fnRect->fnGetRight)() -
[ # # ]
2648 [ # # ][ # # ]: 0 : (aFlyRect.*fnRect->fnGetRight)() >= 0 )
2649 : : {
2650 : : (aFlyRect.*fnRect->fnSetRight)(
2651 [ # # ][ # # ]: 0 : (aRect.*fnRect->fnGetLeft)() );
[ # # ][ # # ]
2652 [ # # ][ # # ]: 0 : nRet = (aRect.*fnRect->fnGetLeft)();
2653 : : }
2654 : : else
2655 : : break;
2656 : : }
2657 : : else
2658 : : {
2659 [ # # ][ # # ]: 0 : if ( (aFlyRect.*fnRect->fnGetLeft)() -
[ # # ]
2660 [ # # ][ # # ]: 0 : (aRect.*fnRect->fnGetLeft)() >= 0 )
2661 : : {
2662 : : (aFlyRect.*fnRect->fnSetLeft)(
2663 [ # # ][ # # ]: 0 : (aRect.*fnRect->fnGetRight)() + 1 );
[ # # ][ # # ]
2664 [ # # ][ # # ]: 0 : nRet = (aRect.*fnRect->fnGetRight)();
2665 : : }
2666 : : else
2667 : : break;
2668 : : }
2669 : : }
2670 : : else
2671 : : break;
2672 : : }
2673 [ # # ]: 942 : while ( (aFlyRect.*fnRect->fnGetWidth)() > 0 );
2674 : :
2675 : 942 : return nRet;
2676 : : }
2677 : :
2678 : : /*************************************************************************
2679 : : * SwTxtFrm::CalcBasePosForFly()
2680 : : *************************************************************************/
2681 : :
2682 : 19846 : void SwTxtFrm::CalcBaseOfstForFly()
2683 : : {
2684 : : OSL_ENSURE( !IsVertical() || !IsSwapped(),
2685 : : "SwTxtFrm::CalcBasePosForFly with swapped frame!" );
2686 : :
2687 [ + - ]: 19846 : const SwNode* pNode = GetTxtNode();
2688 [ + - ][ + - ]: 19846 : if ( !pNode->getIDocumentSettingAccess()->get(IDocumentSettingAccess::ADD_FLY_OFFSETS) )
[ + + ]
2689 : 19846 : return;
2690 : :
2691 [ + - ][ - + ]: 471 : SWRECTFN( this )
[ # # ][ # # ]
[ - + ]
2692 : :
2693 : 471 : SwRect aFlyRect( Frm().Pos() + Prt().Pos(), Prt().SSize() );
2694 : :
2695 : : // Get first 'real' line and adjust position and height of line rectangle
2696 : : // OD 08.09.2003 #110978#, #108749#, #110354# - correct behaviour,
2697 : : // if no 'real' line exists (empty paragraph with and without a dummy portion)
2698 : : {
2699 [ + - ][ + - ]: 471 : SwTwips nTop = (aFlyRect.*fnRect->fnGetTop)();
2700 [ + - ]: 471 : const SwLineLayout* pLay = GetPara();
2701 : 471 : SwTwips nLineHeight = 200;
2702 [ + + ][ + + ]: 471 : while( pLay && pLay->IsDummy() && pLay->GetNext() )
[ - + ][ - + ]
2703 : : {
2704 : 0 : nTop += pLay->Height();
2705 : 0 : pLay = pLay->GetNext();
2706 : : }
2707 [ + + ]: 471 : if ( pLay )
2708 : : {
2709 : 396 : nLineHeight = pLay->Height();
2710 : : }
2711 [ + - ][ + - ]: 471 : (aFlyRect.*fnRect->fnSetTopAndHeight)( nTop, nLineHeight );
2712 : : }
2713 : :
2714 [ + - ]: 471 : SwTxtFly aTxtFly( this );
2715 : 471 : aTxtFly.SetIgnoreCurrentFrame( sal_True );
2716 : 471 : aTxtFly.SetIgnoreContour( sal_True );
2717 : : // #118809# - ignore objects in page header|footer for
2718 : : // text frames not in page header|footer
2719 : 471 : aTxtFly.SetIgnoreObjsInHeaderFooter( sal_True );
2720 [ + - ]: 471 : SwTwips nRet1 = lcl_CalcFlyBasePos( *this, aFlyRect, aTxtFly );
2721 : 471 : aTxtFly.SetIgnoreCurrentFrame( sal_False );
2722 [ + - ]: 471 : SwTwips nRet2 = lcl_CalcFlyBasePos( *this, aFlyRect, aTxtFly );
2723 : :
2724 : : // make values relative to frame start position
2725 [ + - ]: 471 : SwTwips nLeft = IsRightToLeft() ?
2726 [ # # ]: 0 : (Frm().*fnRect->fnGetRight)() :
2727 [ - + ][ # # ]: 471 : (Frm().*fnRect->fnGetLeft)();
[ + - ][ + - ]
2728 : :
2729 : 471 : mnFlyAnchorOfst = nRet1 - nLeft;
2730 [ + - ]: 19846 : mnFlyAnchorOfstNoWrap = nRet2 - nLeft;
2731 : : }
2732 : :
2733 : : /* repaint all text frames of the given text node */
2734 : 2628 : void SwTxtFrm::repaintTextFrames( const SwTxtNode& rNode )
2735 : : {
2736 [ + - ]: 2628 : SwIterator<SwTxtFrm,SwTxtNode> aIter( rNode );
2737 [ + - ][ + - ]: 5365 : for( const SwTxtFrm *pFrm = aIter.First(); pFrm; pFrm = aIter.Next() )
[ + + ]
2738 : : {
2739 [ + - ]: 2737 : SwRect aRec( pFrm->PaintArea() );
2740 : 2737 : const SwRootFrm *pRootFrm = pFrm->getRootFrm();
2741 [ + - ]: 2737 : ViewShell *pCurShell = pRootFrm ? pRootFrm->GetCurrShell() : NULL;
2742 [ + - ]: 2737 : if( pCurShell )
2743 [ + - ]: 2737 : pCurShell->InvalidateWindows( aRec );
2744 [ + - ]: 2628 : }
2745 : 2628 : }
2746 : :
2747 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|