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 : :
30 : : #include "hintids.hxx"
31 : : #include <editeng/lrspitem.hxx>
32 : : #include <editeng/tstpitem.hxx>
33 : : #include <IDocumentSettingAccess.hxx>
34 : : #include <frmatr.hxx>
35 : : #include <SwPortionHandler.hxx>
36 : :
37 : : #include "viewopt.hxx" // SwViewOptions
38 : : #include "portab.hxx"
39 : : #include "inftxt.hxx"
40 : : #include "itrform2.hxx"
41 : : #include "txtfrm.hxx"
42 : : #include <numrule.hxx>
43 : : // #i89179#
44 : : #include <porfld.hxx>
45 : :
46 : :
47 : : /*************************************************************************
48 : : * SwLineInfo::GetTabStop()
49 : : *************************************************************************/
50 : :
51 : : //#i24363# tab stops relative to indent
52 : : /* Return the first tab stop that is > nSearchPos.
53 : : * If the tab stop is outside the print area, we
54 : : * return 0 if it is not the first tab stop.*/
55 : 3027 : const SvxTabStop *SwLineInfo::GetTabStop( const SwTwips nSearchPos,
56 : : const SwTwips nRight ) const
57 : : {
58 [ + + ]: 3323 : for( MSHORT i = 0; i < pRuler->Count(); ++i )
59 : : {
60 : 3117 : const SvxTabStop &rTabStop = pRuler->operator[](i);
61 [ - + ]: 3117 : if( rTabStop.GetTabPos() > SwTwips(nRight) )
62 [ # # ]: 0 : return i ? 0 : &rTabStop;
63 : :
64 [ + + ]: 3117 : if( rTabStop.GetTabPos() > nSearchPos )
65 : 2821 : return &rTabStop;
66 : : }
67 : 3027 : return 0;
68 : : }
69 : :
70 : : /*************************************************************************
71 : : * SwLineInfo::NumberOfTabStops()
72 : : *************************************************************************/
73 : :
74 : 0 : sal_uInt16 SwLineInfo::NumberOfTabStops() const
75 : : {
76 : 0 : return pRuler->Count();
77 : : }
78 : :
79 : : /*************************************************************************
80 : : * SwTxtFormatter::NewTabPortion()
81 : : *************************************************************************/
82 : 3027 : SwTabPortion *SwTxtFormatter::NewTabPortion( SwTxtFormatInfo &rInf, bool bAuto ) const
83 : : {
84 : 3027 : SwTabPortion *pTabPor = 0;
85 : :
86 : 3027 : xub_Unicode cFill = 0;
87 : 3027 : xub_Unicode cDec = 0;
88 : : SvxTabAdjust eAdj;
89 : :
90 : : KSHORT nNewTabPos;
91 : 3027 : bool bAutoTabStop = true;
92 : : {
93 : 3027 : const bool bRTL = pFrm->IsRightToLeft();
94 : : // #i24363# tab stops relative to indent
95 : : // nTabLeft: The absolute value, the tab stops are relative to: Tabs origin.
96 : : //
97 : : // #i91133#
98 : : const bool bTabsRelativeToIndent =
99 : 3027 : pFrm->GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::TABS_RELATIVE_TO_INDENT);
100 : : const SwTwips nTabLeft = bRTL
101 : 0 : ? pFrm->Frm().Right() -
102 : 0 : ( bTabsRelativeToIndent ? GetTabLeft() : 0 )
103 : 3027 : : pFrm->Frm().Left() +
104 [ + + ]: 6054 : ( bTabsRelativeToIndent ? GetTabLeft() : 0 );
[ - + # # ]
105 : :
106 : : //
107 : : // nLinePos: The absolute position, where we started the line formatting.
108 : : //
109 : 3027 : SwTwips nLinePos = GetLeftMargin();
110 [ - + ]: 3027 : if ( bRTL )
111 : : {
112 : 0 : Point aPoint( nLinePos, 0 );
113 [ # # ]: 0 : pFrm->SwitchLTRtoRTL( aPoint );
114 : 0 : nLinePos = aPoint.X();
115 : : }
116 : :
117 : : //
118 : : // nTabPos: The current position, relative to the line start.
119 : : //
120 [ - + ]: 3027 : SwTwips nTabPos = rInf.GetLastTab() ? rInf.GetLastTab()->GetTabPos() : 0;
121 [ + + ]: 3027 : if( nTabPos < rInf.X() )
122 : : {
123 : 1022 : nTabPos = rInf.X();
124 : : }
125 : :
126 : : //
127 : : // nCurrentAbsPos: The current position in absolute coordinates.
128 : : //
129 : : const SwTwips nCurrentAbsPos = bRTL ?
130 : : nLinePos - nTabPos :
131 [ - + ]: 3027 : nLinePos + nTabPos;
132 : :
133 : : //Badaa: 2008-04-18 * Support for Classical Mongolian Script (SCMS) joint with Jiayanmin
134 : : SwTwips nMyRight;
135 [ - + ]: 3027 : if ( pFrm->IsVertLR() )
136 : 0 : nMyRight = Left();
137 : : else
138 : 3027 : nMyRight = Right();
139 : :
140 [ - + ]: 3027 : if ( pFrm->IsVertical() )
141 : : {
142 : 0 : Point aRightTop( nMyRight, pFrm->Frm().Top() );
143 [ # # ]: 0 : pFrm->SwitchHorizontalToVertical( aRightTop );
144 : 0 : nMyRight = aRightTop.Y();
145 : : }
146 : :
147 : : SwTwips nNextPos;
148 : :
149 : : // #i24363# tab stops relative to indent
150 : : // nSearchPos: The current position relative to the tabs origin.
151 : : //
152 : : const SwTwips nSearchPos = bRTL ?
153 : : nTabLeft - nCurrentAbsPos :
154 [ - + ]: 3027 : nCurrentAbsPos - nTabLeft;
155 : :
156 : : //
157 : : // First, we examine the tab stops set at the paragraph style or
158 : : // any hard set tab stops:
159 : : // Note: If there are no user defined tab stops, there is always a
160 : : // default tab stop.
161 : : //
162 : : const SvxTabStop* pTabStop =
163 : 3027 : aLineInf.GetTabStop( nSearchPos, nMyRight );
164 [ + + ]: 3027 : if( pTabStop )
165 : : {
166 [ + + ]: 2821 : cFill = ' ' != pTabStop->GetFill() ? pTabStop->GetFill() : 0;
167 : 2821 : cDec = pTabStop->GetDecimal();
168 : 2821 : eAdj = pTabStop->GetAdjustment();
169 : 2821 : nNextPos = pTabStop->GetTabPos();
170 [ + + ][ + + ]: 2821 : if(!bTabsRelativeToIndent && eAdj == SVX_TAB_ADJUST_DEFAULT && nSearchPos < 0)
[ + + ]
171 : : {
172 : : //calculate default tab position of default tabs in negative indent
173 : 18 : nNextPos = ( nSearchPos / nNextPos ) * nNextPos;
174 : : }
175 : 2821 : bAutoTabStop = false;
176 : : }
177 : : else
178 : : {
179 : 206 : KSHORT nDefTabDist = aLineInf.GetDefTabStop();
180 [ + + ]: 206 : if( KSHRT_MAX == nDefTabDist )
181 : : {
182 : : const SvxTabStopItem& rTab =
183 : : (const SvxTabStopItem &)pFrm->GetAttrSet()->
184 : 184 : GetPool()->GetDefaultItem( RES_PARATR_TABSTOP );
185 [ + - ]: 184 : if( rTab.Count() )
186 : 184 : nDefTabDist = (KSHORT)rTab[0].GetTabPos();
187 : : else
188 : 0 : nDefTabDist = SVX_TAB_DEFDIST;
189 : 184 : aLineInf.SetDefTabStop( nDefTabDist );
190 : : }
191 : 206 : SwTwips nCount = nSearchPos;
192 : :
193 : : //Minimum tab stop width is 1
194 [ - + ]: 206 : if (nDefTabDist <= 0)
195 : 0 : nDefTabDist = 1;
196 : :
197 : 206 : nCount /= nDefTabDist;
198 [ + - ][ + + ]: 206 : nNextPos = nCount < 0 || (!nCount && nSearchPos <= 0)? nCount * nDefTabDist :( nCount + 1 ) * nDefTabDist ;
[ - + ]
199 : : // --> FME 2004-09-21 #117919 Minimum tab stop width is 1 or 51 twips:
200 [ + - ]: 206 : const SwTwips nMinimumTabWidth = pFrm->GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::TAB_COMPAT) ? 0 : 50;
201 [ - + ][ # # ]: 206 : if( ( bRTL && nTabLeft - nNextPos >= nCurrentAbsPos - nMinimumTabWidth ) ||
[ + - ][ - + ]
202 : 206 : ( !bRTL && nNextPos + nTabLeft <= nCurrentAbsPos + nMinimumTabWidth ) )
203 : : {
204 : 0 : nNextPos += nDefTabDist;
205 : : }
206 : 206 : cFill = 0;
207 : 206 : eAdj = SVX_TAB_ADJUST_LEFT;
208 : : }
209 : :
210 : : // #i115705# - correction and refactoring:
211 : : // overrule determined next tab stop position in order to apply
212 : : // a tab stop at the left margin under the following conditions:
213 : : // - the new tab portion is inside the hanging indent
214 : : // - a tab stop at the left margin is allowed
215 : : // - the determined next tab stop is a default tab stop position OR
216 : : // the determined next tab stop is beyond the left margin
217 : : {
218 : 3027 : long nLeftMarginTabPos = 0;
219 : : {
220 [ + + ]: 3027 : if ( !bTabsRelativeToIndent )
221 : : {
222 [ - + ]: 1404 : if ( bRTL )
223 : : {
224 : 0 : Point aPoint( Left(), 0 );
225 [ # # ]: 0 : pFrm->SwitchLTRtoRTL( aPoint );
226 : 0 : nLeftMarginTabPos = pFrm->Frm().Right() - aPoint.X();
227 : : }
228 : : else
229 : : {
230 : 1404 : nLeftMarginTabPos = Left() - pFrm->Frm().Left();
231 : : }
232 : : }
233 [ - + ]: 3027 : if( pCurr->HasForcedLeftMargin() )
234 : : {
235 : 0 : SwLinePortion* pPor = pCurr->GetPortion();
236 [ # # ][ # # ]: 0 : while( pPor && !pPor->IsFlyPortion() )
[ # # ]
237 : : {
238 : 0 : pPor = pPor->GetPortion();
239 : : }
240 [ # # ]: 0 : if ( pPor )
241 : : {
242 : 0 : nLeftMarginTabPos += pPor->Width();
243 : : }
244 : : }
245 : : }
246 : : const bool bNewTabPortionInsideHangingIndent =
247 : : bRTL ? nCurrentAbsPos > nTabLeft - nLeftMarginTabPos
248 [ - + ]: 3027 : : nCurrentAbsPos < nTabLeft + nLeftMarginTabPos;
249 [ + + ]: 3027 : if ( bNewTabPortionInsideHangingIndent )
250 : : {
251 : : // If the paragraph is not inside a list having a list tab stop following
252 : : // the list label or no further tab stop found in such a paragraph or
253 : : // the next tab stop position does not equal the list tab stop,
254 : : // a tab stop at the left margin can be applied. If this condition is
255 : : // not hold, it is overruled by compatibility option TAB_AT_LEFT_INDENT_FOR_PARA_IN_LIST.
256 : : const bool bTabAtLeftMarginAllowed =
257 : 120 : ( !aLineInf.IsListTabStopIncluded() ||
258 : : !pTabStop ||
259 : 30 : nNextPos != aLineInf.GetListTabStopPosition() ) ||
260 : : // compatibility option TAB_AT_LEFT_INDENT_FOR_PARA_IN_LIST:
261 : 6 : pFrm->GetTxtNode()->getIDocumentSettingAccess()->
262 [ + + + + : 156 : get(IDocumentSettingAccess::TAB_AT_LEFT_INDENT_FOR_PARA_IN_LIST);
- + ][ + + ]
263 [ + + ]: 120 : if ( bTabAtLeftMarginAllowed )
264 : : {
265 [ + + ][ - + ]: 114 : if ( !pTabStop || eAdj == SVX_TAB_ADJUST_DEFAULT ||
[ # # ]
266 : : ( nNextPos > nLeftMarginTabPos ) )
267 : : {
268 : 114 : eAdj = SVX_TAB_ADJUST_DEFAULT;
269 : 114 : cFill = 0;
270 : 114 : nNextPos = nLeftMarginTabPos;
271 : : }
272 : : }
273 : : }
274 : : }
275 : :
276 [ - + ]: 3027 : nNextPos += bRTL ? nLinePos - nTabLeft : nTabLeft - nLinePos;
277 : : OSL_ENSURE( nNextPos >= 0, "GetTabStop: Don't go back!" );
278 : 3027 : nNewTabPos = KSHORT(nNextPos);
279 : : }
280 : :
281 [ + + ]: 3027 : if ( bAuto )
282 : : {
283 [ - + # # ]: 2820 : if ( SVX_TAB_ADJUST_DECIMAL == eAdj &&
[ - + ]
284 : : // #127428#
285 : 0 : 1 == aLineInf.NumberOfTabStops() )
286 [ # # ]: 0 : pTabPor = new SwAutoTabDecimalPortion( nNewTabPos, cDec, cFill );
287 : : }
288 : : else
289 : : {
290 [ + - - + ]: 207 : switch( eAdj )
291 : : {
292 : : case SVX_TAB_ADJUST_RIGHT :
293 : : {
294 [ + - ]: 2 : pTabPor = new SwTabRightPortion( nNewTabPos, cFill );
295 : 2 : break;
296 : : }
297 : : case SVX_TAB_ADJUST_CENTER :
298 : : {
299 [ # # ]: 0 : pTabPor = new SwTabCenterPortion( nNewTabPos, cFill );
300 : 0 : break;
301 : : }
302 : : case SVX_TAB_ADJUST_DECIMAL :
303 : : {
304 [ # # ]: 0 : pTabPor = new SwTabDecimalPortion( nNewTabPos, cDec, cFill );
305 : 0 : break;
306 : : }
307 : : default:
308 : : {
309 : : OSL_ENSURE( SVX_TAB_ADJUST_LEFT == eAdj || SVX_TAB_ADJUST_DEFAULT == eAdj,
310 : : "+SwTxtFormatter::NewTabPortion: unknown adjustment" );
311 [ + - ]: 205 : pTabPor = new SwTabLeftPortion( nNewTabPos, cFill, bAutoTabStop );
312 : 205 : break;
313 : : }
314 : : }
315 : : }
316 : :
317 : : // Vorhandensein von Tabulatoren anzeigen ... ist nicht mehr noetig
318 : : // pCurr->SetTabulation();
319 : : // Aus Sicherheitsgruenden lassen wir uns die Daten errechnen
320 : : // pTabPor->Height( pLast->Height() );
321 : : // pTabPor->SetAscent( pLast->GetAscent() );
322 : 3027 : return pTabPor;
323 : : }
324 : :
325 : : /*************************************************************************
326 : : * SwTabPortion::SwTabPortion()
327 : : *************************************************************************/
328 : :
329 : : // Die Basisklasse wird erstmal ohne alles initialisiert.
330 : :
331 : :
332 : 207 : SwTabPortion::SwTabPortion( const KSHORT nTabPosition, const xub_Unicode cFillChar, const bool bAutoTab )
333 : 207 : : SwFixPortion( 0, 0 ), nTabPos(nTabPosition), cFill(cFillChar), bAutoTabStop( bAutoTab )
334 : : {
335 : 207 : nLineLength = 1;
336 : : OSL_ENSURE(!IsFilled() || ' ' != cFill, "SwTabPortion::CTOR: blanks ?!");
337 : 207 : SetWhichPor( POR_TAB );
338 : 207 : }
339 : :
340 : : /*************************************************************************
341 : : * virtual SwTabPortion::Format()
342 : : *************************************************************************/
343 : :
344 : :
345 : :
346 : 207 : sal_Bool SwTabPortion::Format( SwTxtFormatInfo &rInf )
347 : : {
348 : 207 : SwTabPortion *pLastTab = rInf.GetLastTab();
349 [ - + ]: 207 : if( pLastTab == this )
350 : 0 : return PostFormat( rInf );
351 [ - + ]: 207 : if( pLastTab )
352 : 0 : pLastTab->PostFormat( rInf );
353 : 207 : return PreFormat( rInf );
354 : : }
355 : :
356 : : /*************************************************************************
357 : : * virtual SwTabPortion::FormatEOL()
358 : : *************************************************************************/
359 : :
360 : :
361 : :
362 : 2 : void SwTabPortion::FormatEOL( SwTxtFormatInfo &rInf )
363 : : {
364 [ + - ][ + - ]: 2 : if( rInf.GetLastTab() == this && !IsTabLeftPortion() )
[ + - ]
365 : 2 : PostFormat( rInf );
366 : 2 : }
367 : :
368 : : /*************************************************************************
369 : : * SwTabPortion::PreFormat()
370 : : *************************************************************************/
371 : :
372 : :
373 : :
374 : 207 : sal_Bool SwTabPortion::PreFormat( SwTxtFormatInfo &rInf )
375 : : {
376 : : OSL_ENSURE( rInf.X() <= GetTabPos(), "SwTabPortion::PreFormat: rush hour" );
377 : :
378 : : // Hier lassen wir uns nieder...
379 : 207 : Fix( static_cast<sal_uInt16>(rInf.X()) );
380 : :
381 : 207 : const bool bTabCompat = rInf.GetTxtFrm()->GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::TAB_COMPAT);
382 : 207 : const bool bTabOverflow = rInf.GetTxtFrm()->GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::TAB_OVERFLOW);
383 : :
384 : : // Die Mindestbreite eines Tabs ist immer mindestens ein Blank
385 : : // #i37686# In compatibility mode, the minimum width
386 : : // should be 1, even for non-left tab stops.
387 : 207 : sal_uInt16 nMinimumTabWidth = 1;
388 [ - + ]: 207 : if ( !bTabCompat )
389 : : {
390 : : // #i89179#
391 : : // tab portion representing the list tab of a list label gets the
392 : : // same font as the corresponding number portion
393 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
394 : 0 : std::auto_ptr< SwFontSave > pSave( 0 );
395 : : SAL_WNODEPRECATED_DECLARATIONS_POP
396 [ # # ][ # # : 0 : if ( GetLen() == 0 &&
# # # # #
# ]
397 : 0 : rInf.GetLast() && rInf.GetLast()->InNumberGrp() &&
398 : 0 : static_cast<SwNumberPortion*>(rInf.GetLast())->HasFont() )
399 : : {
400 : : const SwFont* pNumberPortionFont =
401 : 0 : static_cast<SwNumberPortion*>(rInf.GetLast())->GetFont();
402 [ # # ][ # # ]: 0 : pSave.reset( new SwFontSave( rInf, const_cast<SwFont*>(pNumberPortionFont) ) );
403 : : }
404 : 0 : rtl::OUString aTmp( ' ' );
405 [ # # ][ # # ]: 0 : SwTxtSizeInfo aInf( rInf, aTmp );
[ # # ]
406 [ # # ][ # # ]: 0 : nMinimumTabWidth = aInf.GetTxtSize().Width();
407 : : }
408 : 207 : PrtWidth( nMinimumTabWidth );
409 : :
410 : : // Break tab stop to next line if:
411 : : // 1. Minmal width does not fit to line anymore.
412 : : // 2. An underflow event was called for the tab portion.
413 : 207 : sal_Bool bFull = ( bTabCompat && rInf.IsUnderFlow() ) ||
414 [ - + ][ # # ]: 414 : ( rInf.Width() <= rInf.X() + PrtWidth() && rInf.X() <= rInf.Width() ) ;
[ + - + - ]
415 : :
416 : : // #95477# Rotated tab stops get the width of one blank
417 : 207 : const sal_uInt16 nDir = rInf.GetFont()->GetOrientation( rInf.GetTxtFrm()->IsVertical() );
418 : :
419 [ + - ][ + - ]: 207 : if( ! bFull && 0 == nDir )
420 : : {
421 : 207 : const MSHORT nWhich = GetWhichPor();
422 [ + + - ]: 207 : switch( nWhich )
423 : : {
424 : : case POR_TABRIGHT:
425 : : case POR_TABDECIMAL:
426 : : case POR_TABCENTER:
427 : : {
428 [ - + ]: 2 : if( POR_TABDECIMAL == nWhich )
429 : : rInf.SetTabDecimal(
430 : 0 : ((SwTabDecimalPortion*)this)->GetTabDecimal());
431 : 2 : rInf.SetLastTab( this );
432 : 2 : break;
433 : : }
434 : : case POR_TABLEFT:
435 : : {
436 : 205 : PrtWidth( static_cast<sal_uInt16>(GetTabPos() - rInf.X()) );
437 : 205 : bFull = rInf.Width() <= rInf.X() + PrtWidth();
438 : :
439 : : // In tabulator compatibility mode, we reset the bFull flag
440 : : // if the tabulator is at the end of the paragraph and the
441 : : // tab stop position is outside the frame:
442 : 205 : bool bAtParaEnd = rInf.GetIdx() + GetLen() == rInf.GetTxt().Len();
443 [ # # ][ # # : 205 : if ( bFull && bTabCompat &&
# # # # ]
[ # # # # ]
[ - + ][ - + ]
444 : 0 : ( ( bTabOverflow && ( rInf.IsTabOverflow() || !IsAutoTabStop() ) ) || bAtParaEnd ) &&
445 : 0 : GetTabPos() >= rInf.GetTxtFrm()->Frm().Width() )
446 : : {
447 : 0 : bFull = sal_False;
448 [ # # ][ # # ]: 0 : if ( bTabOverflow && !IsAutoTabStop() )
[ # # ]
449 : 0 : rInf.SetTabOverflow( sal_True );
450 : : }
451 : :
452 : 207 : break;
453 : : }
454 : : default: OSL_ENSURE( !this, "SwTabPortion::PreFormat: unknown adjustment" );
455 : : }
456 : : }
457 : :
458 [ - + ]: 207 : if( bFull )
459 : : {
460 : : // Wir muessen aufpassen, dass wir nicht endlos schleifen,
461 : : // wenn die Breite kleiner ist, als ein Blank ...
462 [ # # # # ]: 0 : if( rInf.GetIdx() == rInf.GetLineStart() &&
[ # # ]
463 : : // #119175# TabStop should be forced to current
464 : : // line if there is a fly reducing the line width:
465 : 0 : !rInf.GetFly() )
466 : : {
467 : 0 : PrtWidth( static_cast<sal_uInt16>(rInf.Width() - rInf.X()) );
468 : 0 : SetFixWidth( PrtWidth() );
469 : : }
470 : : else
471 : : {
472 : 0 : Height( 0 );
473 : 0 : Width( 0 );
474 : 0 : SetLen( 0 );
475 : 0 : SetAscent( 0 );
476 : 0 : SetPortion( NULL ); //?????
477 : : }
478 : 0 : return sal_True;
479 : : }
480 : : else
481 : : {
482 : : // Ein Kunstgriff mit Effekt: Die neuen Tabportions verhalten sich nun
483 : : // so, wie FlyFrms, die in der Zeile stehen - inklusive Adjustment !
484 : 207 : SetFixWidth( PrtWidth() );
485 : 207 : return sal_False;
486 : : }
487 : : }
488 : :
489 : : /*************************************************************************
490 : : * SwTabPortion::PostFormat()
491 : : *************************************************************************/
492 : :
493 : :
494 : :
495 : 2 : sal_Bool SwTabPortion::PostFormat( SwTxtFormatInfo &rInf )
496 : : {
497 : 2 : const KSHORT nRight = Min( GetTabPos(), rInf.Width() );
498 : 2 : const SwLinePortion *pPor = GetPortion();
499 : :
500 : 2 : KSHORT nPorWidth = 0;
501 [ + + ]: 4 : while( pPor )
502 : : {
503 : 2 : nPorWidth = nPorWidth + pPor->Width();
504 : 2 : pPor = pPor->GetPortion();
505 : : }
506 : :
507 : 2 : const MSHORT nWhich = GetWhichPor();
508 : : OSL_ENSURE( POR_TABLEFT != nWhich, "SwTabPortion::PostFormat: already formatted" );
509 : 2 : const bool bTabCompat = rInf.GetTxtFrm()->GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::TAB_COMPAT);
510 : :
511 : : // #127428# Abandon dec. tab position if line is full
512 [ - + ][ + - ]: 2 : if ( bTabCompat && POR_TABDECIMAL == nWhich )
513 : : {
514 : 0 : KSHORT nPrePorWidth = static_cast<const SwTabDecimalPortion*>(this)->GetWidthOfPortionsUpToDecimalPosition();
515 : :
516 : : // no value was set => no decimal character was found
517 [ # # ]: 0 : if ( USHRT_MAX != nPrePorWidth )
518 : : {
519 [ # # ][ # # ]: 0 : if ( nPrePorWidth && nPorWidth - nPrePorWidth > rInf.Width() - nRight )
[ # # ]
520 : : {
521 : 0 : nPrePorWidth += nPorWidth - nPrePorWidth - ( rInf.Width() - nRight );
522 : : }
523 : :
524 : 0 : nPorWidth = nPrePorWidth - 1;
525 : : }
526 : : }
527 : :
528 [ - + ]: 2 : if( POR_TABCENTER == nWhich )
529 : : {
530 : : // zentrierte Tabs bereiten Probleme:
531 : : // Wir muessen den Anteil herausfinden, der noch auf die Zeile passt.
532 : 0 : KSHORT nNewWidth = nPorWidth /2;
533 [ # # ]: 0 : if( nNewWidth > rInf.Width() - nRight )
534 : 0 : nNewWidth = nPorWidth - (rInf.Width() - nRight);
535 : 0 : nPorWidth = nNewWidth;
536 : : }
537 : :
538 : 2 : const KSHORT nDiffWidth = nRight - Fix();
539 : :
540 [ + - ]: 2 : if( nDiffWidth > nPorWidth )
541 : : {
542 : 2 : const KSHORT nOldWidth = GetFixWidth();
543 : 2 : const KSHORT nAdjDiff = nDiffWidth - nPorWidth;
544 [ + - ]: 2 : if( nAdjDiff > GetFixWidth() )
545 : 2 : PrtWidth( nAdjDiff );
546 : : // Nicht erschrecken: wir muessen rInf weiterschieben.
547 : : // Immerhin waren wir als Rechtstab bislang nur ein Blank breit.
548 : : // Da wir uns jetzt aufgespannt haben, muss der Differenzbetrag
549 : : // auf rInf.X() addiert werden !
550 : 2 : rInf.X( rInf.X() + PrtWidth() - nOldWidth );
551 : : }
552 : 2 : SetFixWidth( PrtWidth() );
553 : : // letzte Werte zuruecksetzen
554 : 2 : rInf.SetLastTab(0);
555 [ - + ]: 2 : if( POR_TABDECIMAL == nWhich )
556 : 0 : rInf.SetTabDecimal(0);
557 : :
558 : 2 : return rInf.Width() <= rInf.X();
559 : : }
560 : :
561 : : /*************************************************************************
562 : : * virtual SwTabPortion::Paint()
563 : : *
564 : : * Ex: LineIter::DrawTab()
565 : : *************************************************************************/
566 : :
567 : 10 : void SwTabPortion::Paint( const SwTxtPaintInfo &rInf ) const
568 : : {
569 : : #if OSL_DEBUG_LEVEL > 1
570 : : // Wir wollen uns die Fixbreite anzeigen
571 : : if( rInf.OnWin() && OPTDBG( rInf ) &&
572 : : !rInf.GetOpt().IsPagePreview() && \
573 : : !rInf.GetOpt().IsReadonly() && \
574 : : SwViewOption::IsFieldShadings() )
575 : : {
576 : : const KSHORT nTmpWidth = PrtWidth();
577 : : ((SwTabPortion*)this)->PrtWidth( GetFixWidth() );
578 : : rInf.DrawViewOpt( *this, POR_TAB );
579 : : ((SwTabPortion*)this)->PrtWidth( nTmpWidth );
580 : : }
581 : : #endif
582 : :
583 : : // #i89179#
584 : : // tab portion representing the list tab of a list label gets the
585 : : // same font as the corresponding number portion
586 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
587 : 10 : std::auto_ptr< SwFontSave > pSave( 0 );
588 : : SAL_WNODEPRECATED_DECLARATIONS_POP
589 [ - + ]: 10 : if ( GetLen() == 0 )
590 : : {
591 : : const SwLinePortion* pPrevPortion =
592 [ # # ]: 0 : const_cast<SwTabPortion*>(this)->FindPrevPortion( rInf.GetParaPortion() );
593 [ # # # # : 0 : if ( pPrevPortion &&
# # ][ # # ]
594 : 0 : pPrevPortion->InNumberGrp() &&
595 : 0 : static_cast<const SwNumberPortion*>(pPrevPortion)->HasFont() )
596 : : {
597 : : const SwFont* pNumberPortionFont =
598 : 0 : static_cast<const SwNumberPortion*>(pPrevPortion)->GetFont();
599 [ # # ][ # # ]: 0 : pSave.reset( new SwFontSave( rInf, const_cast<SwFont*>(pNumberPortionFont) ) );
600 : : }
601 : : }
602 [ + - ]: 10 : rInf.DrawBackBrush( *this );
603 : :
604 : : // do we have to repaint a post it portion?
605 [ + - ][ + - ]: 10 : if( rInf.OnWin() && pPortion && !pPortion->Width() )
[ - + ][ - + ]
606 [ # # ]: 0 : pPortion->PrePaint( rInf, this );
607 : :
608 : : // Darstellung von Sonderzeichen
609 [ + - ][ - + ]: 10 : if( rInf.OnWin() && rInf.GetOpt().IsTab() )
[ - + ]
610 : : {
611 : : // gefuellte Tabs werden grau hinterlegt.
612 [ # # ]: 0 : if( IsFilled() )
613 [ # # ]: 0 : rInf.DrawViewOpt( *this, POR_TAB );
614 : : else
615 [ # # ]: 0 : rInf.DrawTab( *this );
616 : : }
617 : :
618 : : // 6842: Tabs sollen auf einmal wieder unterstrichen werden.
619 [ - + ]: 10 : if( rInf.GetFont()->IsPaintBlank() )
620 : : {
621 : : // Tabs mit Fuellung
622 [ # # ]: 0 : UniString aTxt = rtl::OUString(' ');
623 [ # # ]: 0 : const KSHORT nCharWidth = rInf.GetTxtSize( aTxt ).Width();
624 : : // robust:
625 [ # # ]: 0 : if( nCharWidth )
626 : : {
627 : : // 6864: immer mit Kerning, auch auf dem Drucker!
628 : 0 : KSHORT nChar = Width() / nCharWidth;
629 [ # # ][ # # ]: 0 : rInf.DrawText( aTxt.Fill( nChar, ' ' ), *this, 0, nChar, sal_True );
630 [ # # ]: 0 : }
631 : : }
632 : :
633 : : // Ausgabe von Fuellzeichen
634 [ + + ]: 10 : if( IsFilled() )
635 : : {
636 : : // Tabs mit Fuellung
637 [ + - ]: 4 : UniString aTxt = rtl::OUString(cFill);
638 [ + - ]: 4 : const KSHORT nCharWidth = rInf.GetTxtSize( aTxt ).Width();
639 : : OSL_ENSURE( nCharWidth, "!SwTabPortion::Paint: sophisticated tabchar" );
640 : : // robust:
641 [ + - ]: 4 : if( nCharWidth )
642 : : {
643 : : // 6864: immer mit Kerning, auch auf dem Drucker!
644 : 4 : KSHORT nChar = Width() / nCharWidth;
645 [ - + ]: 4 : if ( cFill == '_' )
646 : 0 : ++nChar; // damit keine Luecken entstehen (Bug 13430)
647 [ + - ][ + - ]: 4 : rInf.DrawText( aTxt.Fill( nChar, cFill ), *this, 0, nChar, sal_True );
648 [ + - ]: 4 : }
649 [ + - ]: 10 : }
650 : 10 : }
651 : :
652 : : /*************************************************************************
653 : : * virtual SwAutoTabDecimalPortion::Paint()
654 : : *************************************************************************/
655 : :
656 : 0 : void SwAutoTabDecimalPortion::Paint( const SwTxtPaintInfo & ) const
657 : : {
658 : 0 : }
659 : :
660 : : /*************************************************************************
661 : : * virtual SwTabPortion::HandlePortion()
662 : : *************************************************************************/
663 : :
664 : 3 : void SwTabPortion::HandlePortion( SwPortionHandler& rPH ) const
665 : : {
666 : 3 : rPH.Text( GetLen(), GetWhichPor() );
667 : 3 : }
668 : :
669 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|