merge the formfield patch from ooo-build
[ooovba.git] / sw / source / core / text / porrst.cxx
blob2c74cafc1bea44c71f62b64217ac34d918827f51
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: porrst.cxx,v $
10 * $Revision: 1.44 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
33 #include <hintids.hxx>
34 #include <sfx2/printer.hxx>
35 #include <svx/lspcitem.hxx>
36 #include <svx/adjitem.hxx>
37 #include <svx/escpitem.hxx>
38 #include <svx/lrspitem.hxx>
39 #include <svx/pgrditem.hxx>
40 #include <vcl/window.hxx>
41 #include <vcl/svapp.hxx>
42 #include <viewsh.hxx> // ViewShell
43 #include <viewopt.hxx>
44 #include <ndtxt.hxx> // SwTxtNode
45 #include <pagefrm.hxx> // SwPageFrm
46 #include <paratr.hxx>
47 #include <SwPortionHandler.hxx>
48 #include <txtcfg.hxx>
49 #include <porrst.hxx>
50 #include <inftxt.hxx>
51 #include <txtpaint.hxx> // ClipVout
52 #include <swfntcch.hxx> // SwFontAccess
53 #include <tgrditem.hxx>
54 #include <pagedesc.hxx> // SwPageDesc
55 #include <frmatr.hxx>
56 #include <redlnitr.hxx> // SwRedlineItr
57 #include <porfly.hxx> // SwFlyPortion
58 #include <atrhndl.hxx>
60 #include <IDocumentRedlineAccess.hxx>
61 #include <IDocumentSettingAccess.hxx>
62 #include <IDocumentDeviceAccess.hxx>
64 #include <crsrsh.hxx>
66 /*************************************************************************
67 * class SwTmpEndPortion
68 *************************************************************************/
70 SwTmpEndPortion::SwTmpEndPortion( const SwLinePortion &rPortion )
72 Height( rPortion.Height() );
73 SetAscent( rPortion.GetAscent() );
74 SetWhichPor( POR_TMPEND );
77 /*************************************************************************
78 * virtual SwTmpEndPortion::Paint()
79 *************************************************************************/
81 void SwTmpEndPortion::Paint( const SwTxtPaintInfo &rInf ) const
83 if( rInf.OnWin() && rInf.GetOpt().IsParagraph() )
85 SwDefFontSave aSave( rInf );
86 const XubString aTmp( CH_PAR );
87 rInf.DrawText( aTmp, *this );
91 /*************************************************************************
92 * class SwBreakPortion
93 *************************************************************************/
94 SwBreakPortion::SwBreakPortion( const SwLinePortion &rPortion )
95 : SwLinePortion( rPortion )
97 nLineLength = 1;
98 SetWhichPor( POR_BRK );
101 xub_StrLen SwBreakPortion::GetCrsrOfst( const KSHORT ) const
102 { return 0; }
104 KSHORT SwBreakPortion::GetViewWidth( const SwTxtSizeInfo & ) const
105 { return 0; }
107 SwLinePortion *SwBreakPortion::Compress()
108 { return (GetPortion() && GetPortion()->InTxtGrp() ? 0 : this); }
110 void SwBreakPortion::Paint( const SwTxtPaintInfo &rInf ) const
112 if( rInf.OnWin() && rInf.GetOpt().IsLineBreak() )
113 rInf.DrawLineBreak( *this );
116 /*************************************************************************
117 * virtual SwBreakPortion::Format()
118 *************************************************************************/
120 sal_Bool SwBreakPortion::Format( SwTxtFormatInfo &rInf )
122 const SwLinePortion *pRoot = rInf.GetRoot();
123 Width( 0 );
124 Height( pRoot->Height() );
125 SetAscent( pRoot->GetAscent() );
126 if ( rInf.GetIdx()+1 == rInf.GetTxt().Len() )
127 rInf.SetNewLine( sal_True );
128 return sal_True;
131 /*************************************************************************
132 * virtual SwBreakPortion::HandlePortion()
133 *************************************************************************/
135 void SwBreakPortion::HandlePortion( SwPortionHandler& rPH ) const
137 rPH.Text( GetLen(), GetWhichPor() );
141 SwKernPortion::SwKernPortion( SwLinePortion &rPortion, short nKrn,
142 sal_Bool bBG, sal_Bool bGK ) :
143 nKern( nKrn ), bBackground( bBG ), bGridKern( bGK )
145 Height( rPortion.Height() );
146 SetAscent( rPortion.GetAscent() );
147 nLineLength = 0;
148 SetWhichPor( POR_KERN );
149 if( nKern > 0 )
150 Width( nKern );
151 rPortion.Insert( this );
154 SwKernPortion::SwKernPortion( const SwLinePortion& rPortion ) :
155 nKern( 0 ), bBackground( sal_False ), bGridKern( sal_True )
157 Height( rPortion.Height() );
158 SetAscent( rPortion.GetAscent() );
160 nLineLength = 0;
161 SetWhichPor( POR_KERN );
164 void SwKernPortion::Paint( const SwTxtPaintInfo &rInf ) const
166 if( Width() )
168 // bBackground is set for Kerning Portions between two fields
169 if ( bBackground )
170 rInf.DrawViewOpt( *this, POR_FLD );
172 rInf.DrawBackBrush( *this );
174 // do we have to repaint a post it portion?
175 if( rInf.OnWin() && pPortion && !pPortion->Width() )
176 pPortion->PrePaint( rInf, this );
178 if( rInf.GetFont()->IsPaintBlank() )
180 static sal_Char __READONLY_DATA sDoubleSpace[] = " ";
181 XubString aTxtDouble( sDoubleSpace, RTL_TEXTENCODING_MS_1252 );
182 // --> FME 2006-07-12 #b6439097#
183 SwRect aClipRect;
184 rInf.CalcRect( *this, &aClipRect, 0 );
185 SwSaveClip aClip( (OutputDevice*)rInf.GetOut() );
186 aClip.ChgClip( aClipRect, 0 );
187 // <--
188 rInf.DrawText( aTxtDouble, *this, 0, 2, sal_True );
193 void SwKernPortion::FormatEOL( SwTxtFormatInfo &rInf )
195 if ( bGridKern )
196 return;
198 if( rInf.GetLast() == this )
199 rInf.SetLast( FindPrevPortion( rInf.GetRoot() ) );
200 if( nKern < 0 )
201 Width( -nKern );
202 else
203 Width( 0 );
204 rInf.GetLast()->FormatEOL( rInf );
207 SwArrowPortion::SwArrowPortion( const SwLinePortion &rPortion ) :
208 bLeft( sal_True )
210 Height( rPortion.Height() );
211 SetAscent( rPortion.GetAscent() );
212 nLineLength = 0;
213 SetWhichPor( POR_ARROW );
216 SwArrowPortion::SwArrowPortion( const SwTxtPaintInfo &rInf )
217 : bLeft( sal_False )
219 Height( (USHORT)(rInf.GetTxtFrm()->Prt().Height()) );
220 aPos.X() = rInf.GetTxtFrm()->Frm().Left() +
221 rInf.GetTxtFrm()->Prt().Right();
222 aPos.Y() = rInf.GetTxtFrm()->Frm().Top() +
223 rInf.GetTxtFrm()->Prt().Bottom();
226 void SwArrowPortion::Paint( const SwTxtPaintInfo &rInf ) const
228 ((SwArrowPortion*)this)->aPos = rInf.GetPos();
231 SwLinePortion *SwArrowPortion::Compress() { return this; }
233 SwTwips SwTxtFrm::EmptyHeight() const
235 if (IsCollapse()) {
236 ViewShell *pSh = GetShell();
237 if ( pSh->IsA( TYPE(SwCrsrShell) ) ) {
238 SwCrsrShell *pCrSh=(SwCrsrShell*)pSh;
239 SwCntntFrm *pCurrFrm=pCrSh->GetCurrFrm();
240 if (pCurrFrm==(SwCntntFrm*)this) {
241 // do nothing
242 } else {
243 return 1;
245 } else {
246 return 1;
249 ASSERT( ! IsVertical() || ! IsSwapped(),"SwTxtFrm::EmptyHeight with swapped frame" );
251 SwFont *pFnt;
252 const SwTxtNode& rTxtNode = *GetTxtNode();
253 const IDocumentSettingAccess* pIDSA = rTxtNode.getIDocumentSettingAccess();
254 ViewShell *pSh = GetShell();
255 if ( rTxtNode.HasSwAttrSet() )
257 const SwAttrSet *pAttrSet = &( rTxtNode.GetSwAttrSet() );
258 pFnt = new SwFont( pAttrSet, pIDSA );
260 else
262 SwFontAccess aFontAccess( &rTxtNode.GetAnyFmtColl(), pSh);
263 pFnt = new SwFont( *aFontAccess.Get()->GetFont() );
264 pFnt->ChkMagic( pSh, pFnt->GetActual() );
267 if ( IsVertical() )
268 pFnt->SetVertical( 2700 );
270 OutputDevice* pOut = pSh ? pSh->GetOut() : 0;
271 if ( !pOut || !pIDSA->get(IDocumentSettingAccess::BROWSE_MODE) ||
272 ( pSh->GetViewOptions()->IsPrtFormat() ) )
274 pOut = rTxtNode.getIDocumentDeviceAccess()->getReferenceDevice(true);
277 const IDocumentRedlineAccess* pIDRA = rTxtNode.getIDocumentRedlineAccess();
278 if( IDocumentRedlineAccess::IsShowChanges( pIDRA->GetRedlineMode() ) )
280 MSHORT nRedlPos = pIDRA->GetRedlinePos( rTxtNode, USHRT_MAX );
281 if( MSHRT_MAX != nRedlPos )
283 SwAttrHandler aAttrHandler;
284 aAttrHandler.Init( GetTxtNode()->GetSwAttrSet(),
285 *GetTxtNode()->getIDocumentSettingAccess(), NULL );
286 SwRedlineItr aRedln( rTxtNode, *pFnt, aAttrHandler,
287 nRedlPos, sal_True );
291 SwTwips nRet;
292 if( !pOut )
293 nRet = IsVertical() ?
294 Prt().SSize().Width() + 1 :
295 Prt().SSize().Height() + 1;
296 else
298 pFnt->SetFntChg( sal_True );
299 pFnt->ChgPhysFnt( pSh, *pOut );
300 nRet = pFnt->GetHeight( pSh, *pOut );
302 delete pFnt;
303 return nRet;
306 /*************************************************************************
307 * SwTxtFrm::FormatEmpty()
308 *************************************************************************/
310 sal_Bool SwTxtFrm::FormatEmpty()
312 ASSERT( ! IsVertical() || ! IsSwapped(),"SwTxtFrm::FormatEmpty with swapped frame" );
314 if ( HasFollow() || GetTxtNode()->GetpSwpHints() ||
315 0 != GetTxtNode()->GetNumRule() ||
316 GetTxtNode()->HasHiddenCharAttribute( true ) ||
317 IsInFtn() || ( HasPara() && GetPara()->IsPrepMustFit() ) )
318 return sal_False;
319 const SwAttrSet& aSet = GetTxtNode()->GetSwAttrSet();
320 const SvxAdjust nAdjust = aSet.GetAdjust().GetAdjust();
321 if( ( ( ! IsRightToLeft() && ( SVX_ADJUST_LEFT != nAdjust ) ) ||
322 ( IsRightToLeft() && ( SVX_ADJUST_RIGHT != nAdjust ) ) ) ||
323 aSet.GetRegister().GetValue() )
324 return sal_False;
325 const SvxLineSpacingItem &rSpacing = aSet.GetLineSpacing();
326 if( SVX_LINE_SPACE_MIN == rSpacing.GetLineSpaceRule() ||
327 SVX_LINE_SPACE_FIX == rSpacing.GetLineSpaceRule() ||
328 aSet.GetLRSpace().IsAutoFirst() )
329 return sal_False;
330 else
332 SwTxtFly aTxtFly( this );
333 SwRect aRect;
334 sal_Bool bFirstFlyCheck = 0 != Prt().Height();
335 if ( bFirstFlyCheck &&
336 aTxtFly.IsOn() && aTxtFly.IsAnyObj( aRect ) )
337 return sal_False;
338 else
340 SwTwips nHeight = EmptyHeight();
342 if ( GetTxtNode()->GetSwAttrSet().GetParaGrid().GetValue() &&
343 IsInDocBody() )
345 GETGRID( FindPageFrm() )
346 if ( pGrid )
347 nHeight = pGrid->GetBaseHeight() + pGrid->GetRubyHeight();
350 SWRECTFN( this )
351 const SwTwips nChg = nHeight - (Prt().*fnRect->fnGetHeight)();
353 if( !nChg )
354 SetUndersized( sal_False );
355 AdjustFrm( nChg );
357 if( HasBlinkPor() )
359 ClearPara();
360 ResetBlinkPor();
362 SetCacheIdx( MSHRT_MAX );
363 if( !IsEmpty() )
365 SetEmpty( sal_True );
366 SetCompletePaint();
368 if( !bFirstFlyCheck &&
369 aTxtFly.IsOn() && aTxtFly.IsAnyObj( aRect ) )
370 return sal_False;
372 // --> OD 2004-11-17 #i35635# - call method <HideAndShowObjects()>
373 // to assure that objects anchored at the empty paragraph are
374 // correctly visible resp. invisible.
375 HideAndShowObjects();
376 // <--
377 return sal_True;
382 sal_Bool SwTxtFrm::FillRegister( SwTwips& rRegStart, KSHORT& rRegDiff )
384 const SwFrm *pFrm = this;
385 rRegDiff = 0;
386 while( !( ( FRM_BODY | FRM_FLY )
387 & pFrm->GetType() ) && pFrm->GetUpper() )
388 pFrm = pFrm->GetUpper();
389 if( ( FRM_BODY| FRM_FLY ) & pFrm->GetType() )
391 SWRECTFN( pFrm )
392 rRegStart = (pFrm->*fnRect->fnGetPrtTop)();
393 pFrm = pFrm->FindPageFrm();
394 if( pFrm->IsPageFrm() )
396 SwPageDesc* pDesc = ((SwPageFrm*)pFrm)->FindPageDesc();
397 if( pDesc )
399 rRegDiff = pDesc->GetRegHeight();
400 if( !rRegDiff )
402 const SwTxtFmtColl *pFmt = pDesc->GetRegisterFmtColl();
403 if( pFmt )
405 const SvxLineSpacingItem &rSpace = pFmt->GetLineSpacing();
406 if( SVX_LINE_SPACE_FIX == rSpace.GetLineSpaceRule() )
408 rRegDiff = rSpace.GetLineHeight();
409 pDesc->SetRegHeight( rRegDiff );
410 pDesc->SetRegAscent( ( 4 * rRegDiff ) / 5 );
412 else
414 ViewShell *pSh = GetShell();
415 SwFontAccess aFontAccess( pFmt, pSh );
416 SwFont aFnt( *aFontAccess.Get()->GetFont() );
418 OutputDevice *pOut = 0;
419 if( !GetTxtNode()->getIDocumentSettingAccess()->get(IDocumentSettingAccess::BROWSE_MODE) ||
420 (pSh && pSh->GetViewOptions()->IsPrtFormat()) )
421 pOut = GetTxtNode()->getIDocumentDeviceAccess()->getReferenceDevice( true );
423 if( pSh && !pOut )
424 pOut = pSh->GetWin();
426 if( !pOut )
427 pOut = GetpApp()->GetDefaultDevice();
429 MapMode aOldMap( pOut->GetMapMode() );
430 pOut->SetMapMode( MapMode( MAP_TWIP ) );
432 aFnt.ChgFnt( pSh, *pOut );
433 rRegDiff = aFnt.GetHeight( pSh, *pOut );
434 KSHORT nNettoHeight = rRegDiff;
436 switch( rSpace.GetLineSpaceRule() )
438 case SVX_LINE_SPACE_AUTO:
439 break;
440 case SVX_LINE_SPACE_MIN:
442 if( rRegDiff < KSHORT( rSpace.GetLineHeight() ) )
443 rRegDiff = rSpace.GetLineHeight();
444 break;
446 default: ASSERT(
447 sal_False, ": unknown LineSpaceRule" );
449 switch( rSpace.GetInterLineSpaceRule() )
451 case SVX_INTER_LINE_SPACE_OFF:
452 break;
453 case SVX_INTER_LINE_SPACE_PROP:
455 long nTmp = rSpace.GetPropLineSpace();
456 if( nTmp < 50 )
457 nTmp = nTmp ? 50 : 100;
458 nTmp *= rRegDiff;
459 nTmp /= 100;
460 if( !nTmp )
461 ++nTmp;
462 rRegDiff = (KSHORT)nTmp;
463 nNettoHeight = rRegDiff;
464 break;
466 case SVX_INTER_LINE_SPACE_FIX:
468 rRegDiff = rRegDiff + rSpace.GetInterLineSpace();
469 nNettoHeight = rRegDiff;
470 break;
472 default: ASSERT( sal_False, ": unknown InterLineSpaceRule" );
474 pDesc->SetRegHeight( rRegDiff );
475 pDesc->SetRegAscent( rRegDiff - nNettoHeight +
476 aFnt.GetAscent( pSh, *pOut ) );
477 pOut->SetMapMode( aOldMap );
481 const long nTmpDiff = pDesc->GetRegAscent() - rRegDiff;
482 if ( bVert )
483 rRegStart -= nTmpDiff;
484 else
485 rRegStart += nTmpDiff;
489 return ( 0 != rRegDiff );
492 /*************************************************************************
493 * virtual SwHiddenTextPortion::Paint()
494 *************************************************************************/
496 void SwHiddenTextPortion::Paint( const SwTxtPaintInfo & rInf) const
498 (void)rInf;
499 #if OSL_DEBUG_LEVEL > 1
500 OutputDevice* pOut = (OutputDevice*)rInf.GetOut();
501 Color aCol( SwViewOption::GetFieldShadingsColor() );
502 Color aOldColor( pOut->GetFillColor() );
503 pOut->SetFillColor( aCol );
504 Point aPos( rInf.GetPos() );
505 aPos.Y() -= 150;
506 aPos.X() -= 25;
507 SwRect aRect( aPos, Size( 100, 200 ) );
508 ((OutputDevice*)pOut)->DrawRect( aRect.SVRect() );
509 pOut->SetFillColor( aOldColor );
510 #endif
513 /*************************************************************************
514 * virtual SwHiddenTextPortion::Format()
515 *************************************************************************/
517 sal_Bool SwHiddenTextPortion::Format( SwTxtFormatInfo &rInf )
519 Width( 0 );
520 rInf.GetTxtFrm()->HideFootnotes( rInf.GetIdx(), rInf.GetIdx() + GetLen() );
522 return sal_False;
525 /*************************************************************************
526 * virtual SwControlCharPortion::Paint()
527 *************************************************************************/
529 void SwControlCharPortion::Paint( const SwTxtPaintInfo &rInf ) const
531 if ( Width() ) // is only set during prepaint mode
533 rInf.DrawViewOpt( *this, POR_CONTROLCHAR );
535 if ( !rInf.GetOpt().IsPagePreview() &&
536 !rInf.GetOpt().IsReadonly() &&
537 SwViewOption::IsFieldShadings() &&
538 CHAR_ZWNBSP != mcChar )
540 SwFont aTmpFont( *rInf.GetFont() );
541 aTmpFont.SetEscapement( CHAR_ZWSP == mcChar ? DFLT_ESC_AUTO_SUB : -25 );
542 const USHORT nProp = 40;
543 aTmpFont.SetProportion( nProp ); // a smaller font
544 SwFontSave aFontSave( rInf, &aTmpFont );
546 String aOutString;
548 switch ( mcChar )
550 case CHAR_ZWSP :
551 aOutString = '/'; break;
552 // case CHAR_LRM :
553 // rTxt = sal_Unicode(0x2514); break;
554 // case CHAR_RLM :
555 // rTxt = sal_Unicode(0x2518); break;
558 if ( !mnHalfCharWidth )
559 mnHalfCharWidth = rInf.GetTxtSize( aOutString ).Width() / 2;
561 Point aOldPos = rInf.GetPos();
562 Point aNewPos( aOldPos );
563 aNewPos.X() = aNewPos.X() + ( Width() / 2 ) - mnHalfCharWidth;
564 const_cast< SwTxtPaintInfo& >( rInf ).SetPos( aNewPos );
566 rInf.DrawText( aOutString, *this );
568 const_cast< SwTxtPaintInfo& >( rInf ).SetPos( aOldPos );
573 /*************************************************************************
574 * virtual SwControlCharPortion::Format()
575 *************************************************************************/
577 sal_Bool SwControlCharPortion::Format( SwTxtFormatInfo &rInf )
579 const SwLinePortion* pRoot = rInf.GetRoot();
580 Width( 0 );
581 Height( pRoot->Height() );
582 SetAscent( pRoot->GetAscent() );
584 return sal_False;
587 /*************************************************************************
588 * virtual SwControlCharPortion::GetViewWidth()
589 *************************************************************************/
591 KSHORT SwControlCharPortion::GetViewWidth( const SwTxtSizeInfo& rInf ) const
593 if( !mnViewWidth )
594 mnViewWidth = rInf.GetTxtSize( ' ' ).Width();
596 return mnViewWidth;