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 <svx/sdr/properties/textproperties.hxx>
21 #include <svl/itemset.hxx>
22 #include <svl/style.hxx>
23 #include <svl/itemiter.hxx>
24 #include <svl/smplhint.hxx>
25 #include <svx/svddef.hxx>
26 #include <svx/svdotext.hxx>
27 #include <svx/svdoutl.hxx>
28 #include <editeng/writingmodeitem.hxx>
29 #include <svx/svdmodel.hxx>
30 #include <editeng/outlobj.hxx>
31 #include <svx/xflclit.hxx>
32 #include <editeng/adjustitem.hxx>
33 #include <svx/svdetc.hxx>
34 #include <editeng/editeng.hxx>
35 #include <editeng/flditem.hxx>
36 #include <svx/xlnwtit.hxx>
37 #include <svx/svdpool.hxx>
39 //////////////////////////////////////////////////////////////////////////////
45 SfxItemSet
& TextProperties::CreateObjectSpecificItemSet(SfxItemPool
& rPool
)
47 return *(new SfxItemSet(rPool
,
49 // range from SdrAttrObj
50 SDRATTR_START
, SDRATTR_SHADOW_LAST
,
51 SDRATTR_MISC_FIRST
, SDRATTR_MISC_LAST
,
52 SDRATTR_TEXTDIRECTION
, SDRATTR_TEXTDIRECTION
,
54 // range from SdrTextObj
55 EE_ITEMS_START
, EE_ITEMS_END
,
61 TextProperties::TextProperties(SdrObject
& rObj
)
62 : AttributeProperties(rObj
),
67 TextProperties::TextProperties(const TextProperties
& rProps
, SdrObject
& rObj
)
68 : AttributeProperties(rProps
, rObj
),
69 maVersion(rProps
.getVersion())
73 TextProperties::~TextProperties()
77 BaseProperties
& TextProperties::Clone(SdrObject
& rObj
) const
79 return *(new TextProperties(*this, rObj
));
82 void TextProperties::ItemSetChanged(const SfxItemSet
& rSet
)
84 SdrTextObj
& rObj
= (SdrTextObj
&)GetSdrObject();
85 const svx::ITextProvider
& rTextProvider(getTextProvider());
86 sal_Int32 nText
= rTextProvider
.getTextCount();
88 // #i101556# ItemSet has changed -> new version
93 SdrText
* pText
= rTextProvider
.getText( nText
);
95 OutlinerParaObject
* pParaObj
= pText
? pText
->GetOutlinerParaObject() : 0;
99 const bool bTextEdit
= rObj
.IsTextEditActive() && (rObj
.getActiveText() == pText
);
101 // handle outliner attributes
103 Outliner
* pOutliner
= rObj
.GetTextEditOutliner();
107 pOutliner
= &rObj
.ImpGetDrawOutliner();
108 pOutliner
->SetText(*pParaObj
);
111 sal_Int32
nParaCount(pOutliner
->GetParagraphCount());
113 for(sal_Int32 nPara
= 0; nPara
< nParaCount
; nPara
++)
115 SfxItemSet
aSet(pOutliner
->GetParaAttribs(nPara
));
117 pOutliner
->SetParaAttribs(nPara
, aSet
);
127 SfxItemSet
aNewSet(pOutliner
->GetParaAttribs(0L));
128 mpItemSet
->Put(aNewSet
);
131 OutlinerParaObject
* pTemp
= pOutliner
->CreateParaObject(0, nParaCount
);
134 rObj
.NbcSetOutlinerParaObjectForText(pTemp
,pText
);
139 // Extra-Repaint for radical layout changes (#43139#)
140 if(SFX_ITEM_SET
== rSet
.GetItemState(SDRATTR_TEXT_CONTOURFRAME
))
142 // Here only repaint wanted
143 rObj
.ActionChanged();
144 //rObj.BroadcastObjectChange();
148 AttributeProperties::ItemSetChanged(rSet
);
151 void TextProperties::ItemChange(const sal_uInt16 nWhich
, const SfxPoolItem
* pNewItem
)
153 SdrTextObj
& rObj
= (SdrTextObj
&)GetSdrObject();
156 sal_Int32
nOldLineWidth(0L);
158 if(XATTR_LINEWIDTH
== nWhich
&& rObj
.DoesSupportTextIndentingOnLineWidthChange())
160 nOldLineWidth
= ((const XLineWidthItem
&)GetItem(XATTR_LINEWIDTH
)).GetValue();
163 if(pNewItem
&& (SDRATTR_TEXTDIRECTION
== nWhich
))
165 sal_Bool
bVertical(com::sun::star::text::WritingMode_TB_RL
== ((SvxWritingModeItem
*)pNewItem
)->GetValue());
166 rObj
.SetVerticalWriting(bVertical
);
169 // #95501# reset to default
170 if(!pNewItem
&& !nWhich
&& rObj
.HasText() )
172 SdrOutliner
& rOutliner
= rObj
.ImpGetDrawOutliner();
174 const svx::ITextProvider
& rTextProvider(getTextProvider());
175 sal_Int32 nCount
= rTextProvider
.getTextCount();
178 SdrText
* pText
= rTextProvider
.getText( nCount
);
179 OutlinerParaObject
* pParaObj
= pText
->GetOutlinerParaObject();
182 rOutliner
.SetText(*pParaObj
);
183 sal_Int32
nParaCount(rOutliner
.GetParagraphCount());
187 ESelection
aSelection( 0, 0, EE_PARA_ALL
, EE_TEXTPOS_ALL
);
188 rOutliner
.RemoveAttribs(aSelection
, sal_True
, 0);
190 OutlinerParaObject
* pTemp
= rOutliner
.CreateParaObject(0, nParaCount
);
193 rObj
.NbcSetOutlinerParaObjectForText( pTemp
, pText
);
200 AttributeProperties::ItemChange( nWhich
, pNewItem
);
203 if(XATTR_LINEWIDTH
== nWhich
&& rObj
.DoesSupportTextIndentingOnLineWidthChange())
205 const sal_Int32
nNewLineWidth(((const XLineWidthItem
&)GetItem(XATTR_LINEWIDTH
)).GetValue());
206 const sal_Int32
nDifference((nNewLineWidth
- nOldLineWidth
) / 2);
210 const bool bLineVisible(XLINE_NONE
!= ((const XLineStyleItem
&)(GetItem(XATTR_LINESTYLE
))).GetValue());
214 const sal_Int32
nLeftDist(((const SdrTextLeftDistItem
&)GetItem(SDRATTR_TEXT_LEFTDIST
)).GetValue());
215 const sal_Int32
nRightDist(((const SdrTextRightDistItem
&)GetItem(SDRATTR_TEXT_RIGHTDIST
)).GetValue());
216 const sal_Int32
nUpperDist(((const SdrTextUpperDistItem
&)GetItem(SDRATTR_TEXT_UPPERDIST
)).GetValue());
217 const sal_Int32
nLowerDist(((const SdrTextLowerDistItem
&)GetItem(SDRATTR_TEXT_LOWERDIST
)).GetValue());
219 SetObjectItemDirect(SdrTextLeftDistItem(nLeftDist
+ nDifference
));
220 SetObjectItemDirect(SdrTextRightDistItem(nRightDist
+ nDifference
));
221 SetObjectItemDirect(SdrTextUpperDistItem(nUpperDist
+ nDifference
));
222 SetObjectItemDirect(SdrTextLowerDistItem(nLowerDist
+ nDifference
));
228 const svx::ITextProvider
& TextProperties::getTextProvider() const
230 return static_cast<const SdrTextObj
&>(GetSdrObject());
233 void TextProperties::SetStyleSheet(SfxStyleSheet
* pNewStyleSheet
, sal_Bool bDontRemoveHardAttr
)
235 SdrTextObj
& rObj
= (SdrTextObj
&)GetSdrObject();
238 AttributeProperties::SetStyleSheet(pNewStyleSheet
, bDontRemoveHardAttr
);
240 // #i101556# StyleSheet has changed -> new version
243 if( rObj
.GetModel() /*&& !rObj.IsTextEditActive()*/ && !rObj
.IsLinkedText() )
245 SdrOutliner
& rOutliner
= rObj
.ImpGetDrawOutliner();
247 const svx::ITextProvider
& rTextProvider(getTextProvider());
248 sal_Int32 nText
= rTextProvider
.getTextCount();
250 while( --nText
>= 0 )
252 SdrText
* pText
= rTextProvider
.getText( nText
);
254 OutlinerParaObject
* pParaObj
= pText
? pText
->GetOutlinerParaObject() : 0;
258 // apply StyleSheet to all paragraphs
259 rOutliner
.SetText(*pParaObj
);
260 sal_Int32
nParaCount(rOutliner
.GetParagraphCount());
264 for(sal_Int32 nPara
= 0; nPara
< nParaCount
; nPara
++)
266 SfxItemSet
* pTempSet
= 0L;
268 // since setting the stylesheet removes all para attributes
269 if(bDontRemoveHardAttr
)
271 // we need to remember them if we want to keep them
272 pTempSet
= new SfxItemSet(rOutliner
.GetParaAttribs(nPara
));
277 if((OBJ_OUTLINETEXT
== rObj
.GetTextKind()) && (SdrInventor
== rObj
.GetObjInventor()))
279 String
aNewStyleSheetName(GetStyleSheet()->GetName());
280 aNewStyleSheetName
.Erase(aNewStyleSheetName
.Len() - 1, 1);
281 sal_Int16 nDepth
= rOutliner
.GetDepth(nPara
);
282 aNewStyleSheetName
+= OUString::number( nDepth
<= 0 ? 1 : nDepth
+ 1);
284 SdrModel
* pModel
= rObj
.GetModel();
285 SfxStyleSheetBasePool
* pStylePool
= (pModel
!= NULL
) ? pModel
->GetStyleSheetPool() : 0L;
286 SfxStyleSheet
* pNewStyle
= (SfxStyleSheet
*)pStylePool
->Find(aNewStyleSheetName
, GetStyleSheet()->GetFamily());
287 DBG_ASSERT( pNewStyle
, "AutoStyleSheetName - Style not found!" );
291 rOutliner
.SetStyleSheet(nPara
, pNewStyle
);
296 rOutliner
.SetStyleSheet(nPara
, GetStyleSheet());
302 rOutliner
.SetStyleSheet(nPara
, 0L);
305 if(bDontRemoveHardAttr
)
309 // restore para attributes
310 rOutliner
.SetParaAttribs(nPara
, *pTempSet
);
317 // remove all hard paragraph attributes
318 // which occur in StyleSheet, take care of
320 SfxItemIter
aIter(pNewStyleSheet
->GetItemSet());
321 const SfxPoolItem
* pItem
= aIter
.FirstItem();
325 if(!IsInvalidItem(pItem
))
327 sal_uInt16
nW(pItem
->Which());
329 if(nW
>= EE_ITEMS_START
&& nW
<= EE_ITEMS_END
)
331 rOutliner
.QuickRemoveCharAttribs(nPara
, nW
);
334 pItem
= aIter
.NextItem();
345 OutlinerParaObject
* pTemp
= rOutliner
.CreateParaObject(0, nParaCount
);
347 rObj
.NbcSetOutlinerParaObjectForText(pTemp
, pText
);
352 if(rObj
.IsTextFrame())
354 rObj
.NbcAdjustTextFrameWidthAndHeight();
358 void TextProperties::ForceDefaultAttributes()
360 SdrTextObj
& rObj
= (SdrTextObj
&)GetSdrObject();
362 if( rObj
.GetObjInventor() == SdrInventor
)
364 const sal_uInt16 nSdrObjKind
= rObj
.GetObjIdentifier();
366 if( nSdrObjKind
== OBJ_TITLETEXT
|| nSdrObjKind
== OBJ_OUTLINETEXT
)
367 return; // no defaults for presentation objects
370 bool bTextFrame(rObj
.IsTextFrame());
377 mpItemSet
->Put(XLineStyleItem(XLINE_NONE
));
378 mpItemSet
->Put(XFillColorItem(String(), Color(COL_WHITE
)));
379 mpItemSet
->Put(XFillStyleItem(XFILL_NONE
));
383 mpItemSet
->Put(SvxAdjustItem(SVX_ADJUST_CENTER
, EE_PARA_JUST
));
384 mpItemSet
->Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_CENTER
));
385 mpItemSet
->Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_CENTER
));
389 void TextProperties::ForceStyleToHardAttributes()
391 // #i61284# call parent first to get the hard ObjectItemSet
392 AttributeProperties::ForceStyleToHardAttributes();
394 // #i61284# push hard ObjectItemSet to OutlinerParaObject attributes
395 // using existing functionality
396 GetObjectItemSet(); // force ItemSet
397 ItemSetChanged(*mpItemSet
);
399 // now the standard TextProperties stuff
400 SdrTextObj
& rObj
= (SdrTextObj
&)GetSdrObject();
403 && !rObj
.IsTextEditActive()
404 && !rObj
.IsLinkedText())
406 Outliner
* pOutliner
= SdrMakeOutliner(OUTLINERMODE_OUTLINEOBJECT
, rObj
.GetModel());
407 const svx::ITextProvider
& rTextProvider(getTextProvider());
408 sal_Int32 nText
= rTextProvider
.getTextCount();
410 while( --nText
>= 0 )
412 SdrText
* pText
= rTextProvider
.getText( nText
);
414 OutlinerParaObject
* pParaObj
= pText
? pText
->GetOutlinerParaObject() : 0;
418 pOutliner
->SetText(*pParaObj
);
420 sal_Int32
nParaCount(pOutliner
->GetParagraphCount());
426 for(sal_Int32 nPara
= 0; nPara
< nParaCount
; nPara
++)
428 SfxStyleSheet
* pSheet
= pOutliner
->GetStyleSheet(nPara
);
432 SfxItemSet
aParaSet(pOutliner
->GetParaAttribs(nPara
));
433 SfxItemSet
aSet(*aParaSet
.GetPool());
434 aSet
.Put(pSheet
->GetItemSet());
436 /** the next code handles a special case for paragraphs that contain a
437 url field. The color for URL fields is either the system color for
438 urls or the char color attribute that formats the portion in which the
439 url field is contained.
440 When we set a char color attribute to the paragraphs item set from the
441 styles item set, we would have this char color attribute as an attribute
442 that is spanned over the complete paragraph after xml import due to some
443 problems in the xml import (using a XCursor on import so it does not know
444 the paragraphs and can't set char attributes to paragraphs ).
446 To avoid this, as soon as we try to set a char color attribute from the style
448 1. check if we have at least one url field in this paragraph
449 2. if we found at least one url field, we span the char color attribute over
450 all portions that are not url fields and remove the char color attribute
451 from the paragraphs item set
456 if(aSet
.GetItemState(EE_CHAR_COLOR
) == SFX_ITEM_SET
)
458 EditEngine
* pEditEngine
= const_cast<EditEngine
*>(&(pOutliner
->GetEditEngine()));
459 std::vector
<EECharAttrib
> aAttribs
;
460 pEditEngine
->GetCharAttribs(nPara
, aAttribs
);
462 for(std::vector
<EECharAttrib
>::iterator i
= aAttribs
.begin(); i
< aAttribs
.end(); ++i
)
464 if(EE_FEATURE_FIELD
== i
->pAttr
->Which())
468 SvxFieldItem
* pFieldItem
= (SvxFieldItem
*)(i
->pAttr
);
472 const SvxFieldData
* pData
= pFieldItem
->GetField();
474 if(pData
&& pData
->ISA(SvxURLField
))
486 SfxItemSet
aColorSet(*aSet
.GetPool(), EE_CHAR_COLOR
, EE_CHAR_COLOR
);
487 aColorSet
.Put(aSet
, sal_False
);
489 ESelection
aSel(nPara
, 0);
491 for(std::vector
<EECharAttrib
>::iterator i
= aAttribs
.begin(); i
< aAttribs
.end(); ++i
)
493 if(EE_FEATURE_FIELD
== i
->pAttr
->Which())
495 aSel
.nEndPos
= i
->nStart
;
497 if(aSel
.nStartPos
!= aSel
.nEndPos
)
498 pEditEngine
->QuickSetAttribs(aColorSet
, aSel
);
500 aSel
.nStartPos
= i
->nEnd
;
504 aSel
.nEndPos
= pEditEngine
->GetTextLen(nPara
);
506 if(aSel
.nStartPos
!= aSel
.nEndPos
)
508 pEditEngine
->QuickSetAttribs( aColorSet
, aSel
);
514 aSet
.Put(aParaSet
, sal_False
);
518 aSet
.ClearItem(EE_CHAR_COLOR
);
521 pOutliner
->SetParaAttribs(nPara
, aSet
);
522 bBurnIn
= true; // #i51163# Flag was set wrong
528 OutlinerParaObject
* pTemp
= pOutliner
->CreateParaObject(0, nParaCount
);
529 rObj
.NbcSetOutlinerParaObjectForText(pTemp
,pText
);
539 void TextProperties::SetObjectItemNoBroadcast(const SfxPoolItem
& rItem
)
542 mpItemSet
->Put(rItem
);
546 void TextProperties::Notify(SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
549 AttributeProperties::Notify(rBC
, rHint
);
551 SdrTextObj
& rObj
= (SdrTextObj
&)GetSdrObject();
554 const svx::ITextProvider
& rTextProvider(getTextProvider());
555 if(HAS_BASE(SfxStyleSheet
, &rBC
))
557 SfxSimpleHint
* pSimple
= PTR_CAST(SfxSimpleHint
, &rHint
);
558 sal_uInt32
nId(pSimple
? pSimple
->GetId() : 0L);
560 if(SFX_HINT_DATACHANGED
== nId
)
562 rObj
.SetPortionInfoChecked(sal_False
);
564 sal_Int32 nText
= rTextProvider
.getTextCount();
567 OutlinerParaObject
* pParaObj
= rTextProvider
.getText( nText
)->GetOutlinerParaObject();
569 pParaObj
->ClearPortionInfo();
571 rObj
.SetTextSizeDirty();
573 if(rObj
.IsTextFrame() && rObj
.NbcAdjustTextFrameWidthAndHeight())
575 // here only repaint wanted
576 rObj
.ActionChanged();
577 //rObj.BroadcastObjectChange();
580 // #i101556# content of StyleSheet has changed -> new version
584 if(SFX_HINT_DYING
== nId
)
586 rObj
.SetPortionInfoChecked(sal_False
);
587 sal_Int32 nText
= rTextProvider
.getTextCount();
590 OutlinerParaObject
* pParaObj
= rTextProvider
.getText( nText
)->GetOutlinerParaObject();
592 pParaObj
->ClearPortionInfo();
596 else if(HAS_BASE(SfxStyleSheetBasePool
, &rBC
))
598 SfxStyleSheetHintExtended
* pExtendedHint
= PTR_CAST(SfxStyleSheetHintExtended
, &rHint
);
601 && SFX_STYLESHEET_MODIFIED
== pExtendedHint
->GetHint())
603 String
aOldName(pExtendedHint
->GetOldName());
604 String
aNewName(pExtendedHint
->GetStyleSheet()->GetName());
605 SfxStyleFamily eFamily
= pExtendedHint
->GetStyleSheet()->GetFamily();
607 if(!aOldName
.Equals(aNewName
))
609 sal_Int32 nText
= rTextProvider
.getTextCount();
612 OutlinerParaObject
* pParaObj
= rTextProvider
.getText( nText
)->GetOutlinerParaObject();
614 pParaObj
->ChangeStyleSheetName(eFamily
, aOldName
, aNewName
);
622 // #i101556# Handout version information
623 sal_uInt32
TextProperties::getVersion() const
627 } // end of namespace properties
628 } // end of namespace sdr
630 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */