1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <hintids.hxx>
21 #include <vcl/svapp.hxx>
22 #include <svx/svdpage.hxx>
23 #include <svx/svdobj.hxx>
24 #include <svx/svdotext.hxx>
25 #include <svx/sdtagitm.hxx>
26 #include <svx/sdtacitm.hxx>
27 #include <svx/sdtayitm.hxx>
28 #include <svx/sdtaaitm.hxx>
29 #include <svx/sdtaiitm.hxx>
30 #include <svx/sdtmfitm.hxx>
31 #include <editeng/eeitem.hxx>
32 #include <svx/xfillit0.hxx>
33 #include <svx/xflclit.hxx>
34 #include <editeng/colritem.hxx>
35 #include <editeng/brushitem.hxx>
36 #include <editeng/lrspitem.hxx>
37 #include <editeng/ulspitem.hxx>
38 #include <svl/itemiter.hxx>
39 #include <svtools/htmltokn.h>
40 #include <svtools/htmlkywd.hxx>
41 #include <osl/diagnose.h>
43 #include <charatr.hxx>
44 #include <drawdoc.hxx>
45 #include <fmtanchr.hxx>
46 #include <fmtornt.hxx>
47 #include <fmtsrnd.hxx>
50 #include <IDocumentDrawModelAccess.hxx>
51 #include <poolfmt.hxx>
54 #include <shellio.hxx>
58 HTMLOptionEnum
<SdrTextAniKind
> const aHTMLMarqBehaviorTable
[] =
60 { OOO_STRING_SVTOOLS_HTML_BEHAV_scroll
, SdrTextAniKind::Scroll
},
61 { OOO_STRING_SVTOOLS_HTML_BEHAV_alternate
, SdrTextAniKind::Alternate
},
62 { OOO_STRING_SVTOOLS_HTML_BEHAV_slide
, SdrTextAniKind::Slide
},
63 { nullptr, SdrTextAniKind(0) }
66 HTMLOptionEnum
<SdrTextAniDirection
> const aHTMLMarqDirectionTable
[] =
68 { OOO_STRING_SVTOOLS_HTML_AL_left
, SdrTextAniDirection::Left
},
69 { OOO_STRING_SVTOOLS_HTML_AL_right
, SdrTextAniDirection::Right
},
70 { nullptr, SdrTextAniDirection(0) }
73 void SwHTMLParser::InsertDrawObject( SdrObject
* pNewDrawObj
,
74 const Size
& rPixSpace
,
77 SfxItemSet
& rCSS1ItemSet
,
78 SvxCSS1PropertyInfo
& rCSS1PropInfo
)
80 // always on top of text.
81 // but in invisible layer. <ConnectToLayout> will move the object
82 // to the visible layer.
83 pNewDrawObj
->SetLayer( m_xDoc
->getIDocumentDrawModelAccess().GetInvisibleHeavenId() );
85 SfxItemSetFixed
<RES_FRMATR_BEGIN
, RES_FRMATR_END
-1> aFrameSet( m_xDoc
->GetAttrPool() );
87 Reader::ResetFrameFormatAttrs( aFrameSet
);
89 sal_uInt16 nLeftSpace
= 0, nRightSpace
= 0, nUpperSpace
= 0, nLowerSpace
= 0;
90 if( rPixSpace
.Width() || rPixSpace
.Height() )
92 nLeftSpace
= nRightSpace
= o3tl::convert(rPixSpace
.Width(), o3tl::Length::px
, o3tl::Length::twip
);
93 nUpperSpace
= nLowerSpace
= o3tl::convert(rPixSpace
.Height(), o3tl::Length::px
, o3tl::Length::twip
);
96 // set left/right border
97 // note: parser never creates SvxLeftMarginItem! must be converted
98 if (const SvxTextLeftMarginItem
*const pLeft
= rCSS1ItemSet
.GetItemIfSet(RES_MARGIN_TEXTLEFT
))
100 if( rCSS1PropInfo
.m_bLeftMargin
)
102 // should be SvxLeftMarginItem... "cast" it
103 nLeftSpace
= static_cast<sal_uInt16
>(pLeft
->ResolveTextLeft({}));
104 rCSS1PropInfo
.m_bLeftMargin
= false;
106 rCSS1ItemSet
.ClearItem(RES_MARGIN_TEXTLEFT
);
108 if (const SvxRightMarginItem
*const pRight
= rCSS1ItemSet
.GetItemIfSet(RES_MARGIN_RIGHT
))
110 if( rCSS1PropInfo
.m_bRightMargin
)
112 nRightSpace
= static_cast<sal_uInt16
>(pRight
->ResolveRight({}));
113 rCSS1PropInfo
.m_bRightMargin
= false;
115 rCSS1ItemSet
.ClearItem(RES_MARGIN_RIGHT
);
117 if( nLeftSpace
|| nRightSpace
)
119 SvxLRSpaceItem
aLRItem( RES_LR_SPACE
);
120 aLRItem
.SetLeft(SvxIndentValue::twips(nLeftSpace
));
121 aLRItem
.SetRight(SvxIndentValue::twips(nRightSpace
));
122 aFrameSet
.Put( aLRItem
);
125 // set top/bottom border
126 if( const SvxULSpaceItem
* pULItem
= rCSS1ItemSet
.GetItemIfSet( RES_UL_SPACE
) )
128 // maybe flatten the first line indentation
129 if( rCSS1PropInfo
.m_bTopMargin
)
131 nUpperSpace
= pULItem
->GetUpper();
132 rCSS1PropInfo
.m_bTopMargin
= false;
134 if( rCSS1PropInfo
.m_bBottomMargin
)
136 nLowerSpace
= pULItem
->GetLower();
137 rCSS1PropInfo
.m_bBottomMargin
= false;
140 rCSS1ItemSet
.ClearItem( RES_UL_SPACE
);
142 if( nUpperSpace
|| nLowerSpace
)
144 SvxULSpaceItem
aULItem( RES_UL_SPACE
);
145 aULItem
.SetUpper( nUpperSpace
);
146 aULItem
.SetLower( nLowerSpace
);
147 aFrameSet
.Put( aULItem
);
150 SwFormatAnchor
aAnchor( RndStdIds::FLY_AS_CHAR
);
151 if( SVX_CSS1_POS_ABSOLUTE
== rCSS1PropInfo
.m_ePosition
&&
152 SVX_CSS1_LTYPE_TWIP
== rCSS1PropInfo
.m_eLeftType
&&
153 SVX_CSS1_LTYPE_TWIP
== rCSS1PropInfo
.m_eTopType
)
155 const SwStartNode
*pFlySttNd
=
156 m_pPam
->GetPoint()->GetNode().FindFlyStartNode();
160 aAnchor
.SetType( RndStdIds::FLY_AT_FLY
);
161 SwPosition
aPos( *pFlySttNd
);
162 aAnchor
.SetAnchor( &aPos
);
166 aAnchor
.SetType( RndStdIds::FLY_AT_PAGE
);
168 // #i26791# - direct positioning for <SwDoc::Insert(..)>
169 pNewDrawObj
->SetRelativePos( Point(rCSS1PropInfo
.m_nLeft
+ nLeftSpace
,
170 rCSS1PropInfo
.m_nTop
+ nUpperSpace
) );
171 aFrameSet
.Put( SwFormatSurround(css::text::WrapTextMode_THROUGH
) );
173 else if( SvxAdjust::Left
== rCSS1PropInfo
.m_eFloat
||
174 text::HoriOrientation::LEFT
== eHoriOri
)
176 aAnchor
.SetType( RndStdIds::FLY_AT_PARA
);
177 aFrameSet
.Put( SwFormatSurround(css::text::WrapTextMode_RIGHT
) );
178 // #i26791# - direct positioning for <SwDoc::Insert(..)>
179 pNewDrawObj
->SetRelativePos( Point(nLeftSpace
, nUpperSpace
) );
181 else if( text::VertOrientation::NONE
!= eVertOri
)
183 aFrameSet
.Put( SwFormatVertOrient( 0, eVertOri
) );
186 if (RndStdIds::FLY_AT_PAGE
== aAnchor
.GetAnchorId())
188 aAnchor
.SetPageNum( 1 );
190 else if( RndStdIds::FLY_AT_FLY
!= aAnchor
.GetAnchorId() )
192 aAnchor
.SetAnchor( m_pPam
->GetPoint() );
194 aFrameSet
.Put( aAnchor
);
196 m_xDoc
->getIDocumentContentOperations().InsertDrawObj( *m_pPam
, *pNewDrawObj
, aFrameSet
);
199 static void PutEEPoolItem( SfxItemSet
&rEEItemSet
,
200 const SfxPoolItem
& rSwItem
)
203 sal_uInt16 nEEWhich
= 0;
205 switch( rSwItem
.Which() )
207 case RES_CHRATR_COLOR
: nEEWhich
= EE_CHAR_COLOR
; break;
208 case RES_CHRATR_CROSSEDOUT
: nEEWhich
= EE_CHAR_STRIKEOUT
; break;
209 case RES_CHRATR_ESCAPEMENT
: nEEWhich
= EE_CHAR_ESCAPEMENT
; break;
210 case RES_CHRATR_FONT
: nEEWhich
= EE_CHAR_FONTINFO
; break;
211 case RES_CHRATR_CJK_FONT
: nEEWhich
= EE_CHAR_FONTINFO_CJK
; break;
212 case RES_CHRATR_CTL_FONT
: nEEWhich
= EE_CHAR_FONTINFO_CTL
; break;
213 case RES_CHRATR_FONTSIZE
: nEEWhich
= EE_CHAR_FONTHEIGHT
; break;
214 case RES_CHRATR_CJK_FONTSIZE
: nEEWhich
= EE_CHAR_FONTHEIGHT_CJK
; break;
215 case RES_CHRATR_CTL_FONTSIZE
: nEEWhich
= EE_CHAR_FONTHEIGHT_CTL
; break;
216 case RES_CHRATR_KERNING
: nEEWhich
= EE_CHAR_KERNING
; break;
217 case RES_CHRATR_POSTURE
: nEEWhich
= EE_CHAR_ITALIC
; break;
218 case RES_CHRATR_CJK_POSTURE
: nEEWhich
= EE_CHAR_ITALIC_CJK
; break;
219 case RES_CHRATR_CTL_POSTURE
: nEEWhich
= EE_CHAR_ITALIC_CTL
; break;
220 case RES_CHRATR_UNDERLINE
: nEEWhich
= EE_CHAR_UNDERLINE
; break;
221 case RES_CHRATR_WEIGHT
: nEEWhich
= EE_CHAR_WEIGHT
; break;
222 case RES_CHRATR_CJK_WEIGHT
: nEEWhich
= EE_CHAR_WEIGHT_CJK
; break;
223 case RES_CHRATR_CTL_WEIGHT
: nEEWhich
= EE_CHAR_WEIGHT_CTL
; break;
225 case RES_CHRATR_BACKGROUND
:
227 const SvxBrushItem
& rBrushItem
= static_cast<const SvxBrushItem
&>(rSwItem
);
228 rEEItemSet
.Put( XFillStyleItem(drawing::FillStyle_SOLID
) );
229 rEEItemSet
.Put(XFillColorItem(OUString(),
230 rBrushItem
.GetColor()) );
236 rEEItemSet
.Put( rSwItem
.CloneSetWhich(nEEWhich
) );
239 void SwHTMLParser::NewMarquee( HTMLTable
*pCurTable
)
242 OSL_ENSURE( !m_pMarquee
, "Marquee in Marquee???" );
245 OUString aId
, aStyle
, aClass
;
247 tools::Long nWidth
=0, nHeight
=0;
248 bool bPercentWidth
= false, bDirection
= false, bBGColor
= false;
250 sal_Int16 eVertOri
= text::VertOrientation::TOP
;
251 sal_Int16 eHoriOri
= text::HoriOrientation::NONE
;
252 SdrTextAniKind eAniKind
= SdrTextAniKind::Scroll
;
253 SdrTextAniDirection eAniDir
= SdrTextAniDirection::Left
;
254 sal_uInt16 nCount
= 0, nDelay
= 60;
255 sal_Int16 nAmount
= -6;
258 const HTMLOptions
& rHTMLOptions
= GetOptions();
259 for (const auto & rOption
: rHTMLOptions
)
261 switch( rOption
.GetToken() )
263 case HtmlOptionId::ID
:
264 aId
= rOption
.GetString();
266 case HtmlOptionId::STYLE
:
267 aStyle
= rOption
.GetString();
269 case HtmlOptionId::CLASS
:
270 aClass
= rOption
.GetString();
273 case HtmlOptionId::BEHAVIOR
:
274 eAniKind
= rOption
.GetEnum( aHTMLMarqBehaviorTable
, eAniKind
);
277 case HtmlOptionId::BGCOLOR
:
278 rOption
.GetColor( aBGColor
);
282 case HtmlOptionId::DIRECTION
:
283 eAniDir
= rOption
.GetEnum( aHTMLMarqDirectionTable
, eAniDir
);
287 case HtmlOptionId::LOOP
:
288 if (rOption
.GetString().
289 equalsIgnoreAsciiCase(OOO_STRING_SVTOOLS_HTML_LOOP_infinite
))
295 const sal_Int32 nLoop
= rOption
.GetSNumber();
296 nCount
= std::max
<sal_Int32
>(nLoop
, 0);
300 case HtmlOptionId::SCROLLAMOUNT
:
301 nAmount
= - static_cast<sal_Int16
>(rOption
.GetNumber());
304 case HtmlOptionId::SCROLLDELAY
:
305 nDelay
= o3tl::narrowing
<sal_uInt16
>(rOption
.GetNumber());
308 case HtmlOptionId::WIDTH
:
309 // first only save as pixel value!
310 nWidth
= rOption
.GetNumber();
311 bPercentWidth
= rOption
.GetString().indexOf('%') != -1;
312 if( bPercentWidth
&& nWidth
>100 )
316 case HtmlOptionId::HEIGHT
:
317 // first only save as pixel value!
318 nHeight
= rOption
.GetNumber();
319 if( rOption
.GetString().indexOf('%') != -1 )
323 case HtmlOptionId::HSPACE
:
324 // first only save as pixel value!
325 aSpace
.setHeight( rOption
.GetNumber() );
328 case HtmlOptionId::VSPACE
:
329 // first only save as pixel value!
330 aSpace
.setWidth( rOption
.GetNumber() );
333 case HtmlOptionId::ALIGN
:
335 rOption
.GetEnum( aHTMLImgVAlignTable
,
336 text::VertOrientation::TOP
);
338 rOption
.GetEnum( aHTMLImgHAlignTable
);
344 // create a DrawTextobj
345 // #i52858# - method name changed
346 SwDrawModel
& rModel
= m_xDoc
->getIDocumentDrawModelAccess().GetOrCreateDrawModel();
347 SdrPage
* pPg
= rModel
.GetPage( 0 );
348 m_pMarquee
= static_cast<SdrTextObj
*>(SdrObjFactory::MakeNewObject(
350 SdrInventor::Default
,
351 SdrObjKind::Text
).get());
356 pPg
->InsertObject( m_pMarquee
.get() );
359 InsertBookmark( aId
);
361 // (only) Alternate runs from left to right as default
362 if( SdrTextAniKind::Alternate
==eAniKind
&& !bDirection
)
363 eAniDir
= SdrTextAniDirection::Right
;
365 // re set the attributes needed for scrolling
367 XATTR_FILL_FIRST
, XATTR_FILL_LAST
,
368 SDRATTR_MISC_FIRST
, SDRATTR_MISC_LAST
,
369 EE_CHAR_START
, EE_CHAR_END
>
370 aItemSet( rModel
.GetItemPool() );
371 aItemSet
.Put( makeSdrTextAutoGrowWidthItem( false ) );
372 aItemSet
.Put( makeSdrTextAutoGrowHeightItem( true ) );
373 aItemSet
.Put( SdrTextAniKindItem( eAniKind
) );
374 aItemSet
.Put( SdrTextAniDirectionItem( eAniDir
) );
375 aItemSet
.Put( SdrTextAniCountItem( nCount
) );
376 aItemSet
.Put( SdrTextAniDelayItem( nDelay
) );
377 aItemSet
.Put( SdrTextAniAmountItem( nAmount
) );
378 if( SdrTextAniKind::Alternate
==eAniKind
)
380 // (only) Alternate starts and ends Inside as default
381 aItemSet
.Put( SdrTextAniStartInsideItem(true) );
382 aItemSet
.Put( SdrTextAniStopInsideItem(true) );
383 if( SdrTextAniDirection::Left
==eAniDir
)
384 aItemSet
.Put( SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT
) );
387 // set the default colour (from the default template), so that a meaningful
388 // colour is set at all
389 const Color
& rDfltColor
=
390 m_pCSS1Parser
->GetTextCollFromPool( RES_POOLCOLL_STANDARD
)
391 ->GetColor().GetValue();
392 aItemSet
.Put( SvxColorItem( rDfltColor
, EE_CHAR_COLOR
) );
394 // set the attributes of the current paragraph style
395 sal_uInt16 nWhichIds
[] =
397 RES_CHRATR_COLOR
, RES_CHRATR_CROSSEDOUT
, RES_CHRATR_ESCAPEMENT
,
398 RES_CHRATR_FONT
, RES_CHRATR_FONTSIZE
, RES_CHRATR_KERNING
,
399 RES_CHRATR_POSTURE
, RES_CHRATR_UNDERLINE
, RES_CHRATR_WEIGHT
,
400 RES_CHRATR_BACKGROUND
,
401 RES_CHRATR_CJK_FONT
, RES_CHRATR_CJK_FONTSIZE
,
402 RES_CHRATR_CJK_POSTURE
, RES_CHRATR_CJK_WEIGHT
,
403 RES_CHRATR_CTL_FONT
, RES_CHRATR_CTL_FONTSIZE
,
404 RES_CHRATR_CTL_POSTURE
, RES_CHRATR_CTL_WEIGHT
,
407 SwTextNode
const*const pTextNd
=
408 m_pPam
->GetPoint()->GetNode().GetTextNode();
411 const SfxItemSet
& rItemSet
= pTextNd
->GetAnyFormatColl().GetAttrSet();
412 const SfxPoolItem
*pItem
;
413 for( int i
=0; nWhichIds
[i
]; ++i
)
415 if( SfxItemState::SET
== rItemSet
.GetItemState( nWhichIds
[i
], true, &pItem
) )
416 PutEEPoolItem( aItemSet
, *pItem
);
420 // set attribute of environment at the Draw object
421 HTMLAttr
** pHTMLAttributes
= reinterpret_cast<HTMLAttr
**>(m_xAttrTab
.get());
422 for (auto nCnt
= sizeof(HTMLAttrTable
) / sizeof(HTMLAttr
*); nCnt
--; ++pHTMLAttributes
)
424 HTMLAttr
*pAttr
= *pHTMLAttributes
;
426 PutEEPoolItem( aItemSet
, pAttr
->GetItem() );
431 aItemSet
.Put( XFillStyleItem(drawing::FillStyle_SOLID
) );
432 aItemSet
.Put(XFillColorItem(OUString(), aBGColor
));
435 // parse styles (is here only possible for attributes, which also
436 // can be set at character object)
437 SfxItemSet
aStyleItemSet( m_xDoc
->GetAttrPool(),
438 m_pCSS1Parser
->GetWhichMap() );
439 SvxCSS1PropertyInfo aPropInfo
;
440 if( HasStyleOptions( aStyle
, aId
, aClass
) &&
441 ParseStyleOptions( aStyle
, aId
, aClass
, aStyleItemSet
, aPropInfo
) )
443 SfxItemIter
aIter( aStyleItemSet
);
445 for (const SfxPoolItem
* pItem
= aIter
.GetCurItem(); pItem
; pItem
= aIter
.NextItem())
447 PutEEPoolItem( aItemSet
, *pItem
);
452 Size
aTwipSz( bPercentWidth
? 0 : nWidth
, nHeight
);
453 if( aTwipSz
.Width() || aTwipSz
.Height() )
455 aTwipSz
= o3tl::convert(aTwipSz
, o3tl::Length::px
, o3tl::Length::twip
);
458 if( SVX_CSS1_LTYPE_TWIP
== aPropInfo
.m_eWidthType
)
460 aTwipSz
.setWidth( aPropInfo
.m_nWidth
);
462 bPercentWidth
= false;
464 if( SVX_CSS1_LTYPE_TWIP
== aPropInfo
.m_eHeightType
)
465 aTwipSz
.setHeight( aPropInfo
.m_nHeight
);
467 m_bFixMarqueeWidth
= false;
468 if( !nWidth
|| bPercentWidth
)
474 // The marquee is in a table, but not in a cell. Since now no
475 // reasonable mapping to a cell is possible, we adjust here the
476 // width to the content of the marquee.
477 m_bFixMarqueeWidth
= true;
481 // Because we know in which cell the marquee is, we also can
482 // adjust the width. No width specification is treated as
485 bPercentWidth
= true;
487 aTwipSz
.setWidth( MINLAY
);
491 tools::Long nBrowseWidth
= GetCurrentBrowseWidth();
492 aTwipSz
.setWidth( !nWidth
? nBrowseWidth
493 : (nWidth
*nBrowseWidth
) / 100 );
497 // The height is only minimum height
498 if( aTwipSz
.Height() < MINFLY
)
499 aTwipSz
.setHeight( MINFLY
);
500 aItemSet
.Put( makeSdrTextMinFrameHeightItem( aTwipSz
.Height() ) );
502 m_pMarquee
->SetMergedItemSetAndBroadcast(aItemSet
);
504 if( aTwipSz
.Width() < MINFLY
)
505 aTwipSz
.setWidth( MINFLY
);
506 m_pMarquee
->SetLogicRect( tools::Rectangle( 0, 0, aTwipSz
.Width(), aTwipSz
.Height() ) );
508 // and insert the object into the document
509 InsertDrawObject( m_pMarquee
.get(), aSpace
, eVertOri
, eHoriOri
, aStyleItemSet
,
512 // Register the drawing object at the table. Is a little bit complicated,
513 // because it is done via the parser, although the table is known, but
514 // otherwise the table would have to be public and that also isn't pretty.
515 // The global pTable also can't be used, because the marquee can also be
517 if( pCurTable
&& bPercentWidth
)
518 RegisterDrawObjectToTable( pCurTable
, m_pMarquee
.get(), static_cast<sal_uInt8
>(nWidth
) );
521 void SwHTMLParser::EndMarquee()
523 OSL_ENSURE( m_pMarquee
&& SdrObjKind::Text
==m_pMarquee
->GetObjIdentifier(),
524 "no marquee or wrong type" );
526 if( m_bFixMarqueeWidth
)
528 // Because there is no fixed height make the text object wider then
529 // the text, so that there is no line break.
530 const tools::Rectangle
& rOldRect
= m_pMarquee
->GetLogicRect();
531 m_pMarquee
->SetLogicRect( tools::Rectangle( rOldRect
.TopLeft(),
532 Size( USHRT_MAX
, 240 ) ) );
535 // insert the collected text
536 m_pMarquee
->SetText( m_aContents
);
537 m_pMarquee
->SetMergedItemSetAndBroadcast( m_pMarquee
->GetMergedItemSet() );
539 if (m_bFixMarqueeWidth
&& !bFuzzing
)
541 // adjust the size to the text
542 m_pMarquee
->FitFrameToTextSize();
546 m_pMarquee
= nullptr;
549 void SwHTMLParser::InsertMarqueeText()
551 OSL_ENSURE( m_pMarquee
&& SdrObjKind::Text
==m_pMarquee
->GetObjIdentifier(),
552 "no marquee or wrong type" );
554 // append the current text part to the text
555 m_aContents
+= aToken
;
558 void SwHTMLParser::ResizeDrawObject( SdrObject
* pObj
, SwTwips nWidth
)
560 OSL_ENSURE( SdrObjKind::Text
==pObj
->GetObjIdentifier(),
561 "no marquee or wrong type" );
563 if( SdrObjKind::Text
!=pObj
->GetObjIdentifier() )
567 const tools::Rectangle
& rOldRect
= pObj
->GetLogicRect();
568 Size
aNewSz( nWidth
, rOldRect
.GetSize().Height() );
569 pObj
->SetLogicRect( tools::Rectangle( rOldRect
.TopLeft(), aNewSz
) );
572 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */