Bump version to 6.4-15
[LibreOffice.git] / svx / source / sdr / properties / textproperties.cxx
blob1ba561ef527ce6332bae46d5f04d391189d470f5
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <sal/config.h>
22 #include <sdr/properties/textproperties.hxx>
23 #include <svl/itemset.hxx>
24 #include <svl/style.hxx>
25 #include <svl/itemiter.hxx>
26 #include <svl/hint.hxx>
27 #include <svx/svddef.hxx>
28 #include <svx/svdotext.hxx>
29 #include <svx/svdoutl.hxx>
30 #include <svx/sdmetitm.hxx>
31 #include <svx/sdtditm.hxx>
32 #include <editeng/writingmodeitem.hxx>
33 #include <svx/svdmodel.hxx>
34 #include <editeng/eeitem.hxx>
35 #include <editeng/outlobj.hxx>
36 #include <svx/xfillit0.hxx>
37 #include <svx/xflclit.hxx>
38 #include <editeng/adjustitem.hxx>
39 #include <svx/svdetc.hxx>
40 #include <editeng/editeng.hxx>
41 #include <editeng/flditem.hxx>
42 #include <svx/xlineit0.hxx>
43 #include <svx/xlnwtit.hxx>
44 #include <svx/svdpool.hxx>
46 using namespace com::sun::star;
48 namespace sdr
50 namespace properties
52 std::unique_ptr<SfxItemSet> TextProperties::CreateObjectSpecificItemSet(SfxItemPool& rPool)
54 return std::make_unique<SfxItemSet>(rPool,
56 // range from SdrAttrObj
57 svl::Items<SDRATTR_START, SDRATTR_SHADOW_LAST,
58 SDRATTR_MISC_FIRST, SDRATTR_MISC_LAST,
59 SDRATTR_TEXTDIRECTION, SDRATTR_TEXTDIRECTION,
61 // range from SdrTextObj
62 EE_ITEMS_START, EE_ITEMS_END>{});
65 TextProperties::TextProperties(SdrObject& rObj)
66 : AttributeProperties(rObj),
67 maVersion(0)
71 TextProperties::TextProperties(const TextProperties& rProps, SdrObject& rObj)
72 : AttributeProperties(rProps, rObj),
73 maVersion(rProps.getVersion())
77 TextProperties::~TextProperties()
81 std::unique_ptr<BaseProperties> TextProperties::Clone(SdrObject& rObj) const
83 return std::unique_ptr<BaseProperties>(new TextProperties(*this, rObj));
86 void TextProperties::ItemSetChanged(const SfxItemSet& rSet)
88 SdrTextObj& rObj = static_cast<SdrTextObj&>(GetSdrObject());
90 // #i101556# ItemSet has changed -> new version
91 maVersion++;
93 const svx::ITextProvider& rTextProvider(getTextProvider());
94 sal_Int32 nText = rTextProvider.getTextCount();
95 while (nText--)
97 SdrText* pText = rTextProvider.getText( nText );
99 OutlinerParaObject* pParaObj = pText ? pText->GetOutlinerParaObject() : nullptr;
101 if(pParaObj)
103 const bool bTextEdit = rObj.IsTextEditActive() && (rObj.getActiveText() == pText);
105 // handle outliner attributes
106 GetObjectItemSet();
107 Outliner* pOutliner = rObj.GetTextEditOutliner();
109 if(!bTextEdit)
111 pOutliner = &rObj.ImpGetDrawOutliner();
112 pOutliner->SetText(*pParaObj);
115 sal_Int32 nParaCount(pOutliner->GetParagraphCount());
117 for(sal_Int32 nPara = 0; nPara < nParaCount; nPara++)
119 SfxItemSet aSet(pOutliner->GetParaAttribs(nPara));
120 aSet.Put(rSet);
121 pOutliner->SetParaAttribs(nPara, aSet);
124 if(!bTextEdit)
126 if(nParaCount)
128 // force ItemSet
129 GetObjectItemSet();
131 SfxItemSet aNewSet(pOutliner->GetParaAttribs(0));
132 mpItemSet->Put(aNewSet);
135 std::unique_ptr<OutlinerParaObject> pTemp = pOutliner->CreateParaObject(0, nParaCount);
136 pOutliner->Clear();
138 rObj.NbcSetOutlinerParaObjectForText(std::move(pTemp),pText);
143 // Extra-Repaint for radical layout changes (#43139#)
144 if(SfxItemState::SET == rSet.GetItemState(SDRATTR_TEXT_CONTOURFRAME))
146 // Here only repaint wanted
147 rObj.ActionChanged();
148 //rObj.BroadcastObjectChange();
151 // call parent
152 AttributeProperties::ItemSetChanged(rSet);
155 void TextProperties::ItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem)
157 SdrTextObj& rObj = static_cast<SdrTextObj&>(GetSdrObject());
159 // #i25616#
160 sal_Int32 nOldLineWidth(0);
162 if(XATTR_LINEWIDTH == nWhich && rObj.DoesSupportTextIndentingOnLineWidthChange())
164 nOldLineWidth = GetItem(XATTR_LINEWIDTH).GetValue();
167 if(pNewItem && (SDRATTR_TEXTDIRECTION == nWhich))
169 bool bVertical(css::text::WritingMode_TB_RL == static_cast<const SvxWritingModeItem*>(pNewItem)->GetValue());
170 rObj.SetVerticalWriting(bVertical);
173 // #95501# reset to default
174 if(!pNewItem && !nWhich && rObj.HasText() )
176 SdrOutliner& rOutliner = rObj.ImpGetDrawOutliner();
178 const svx::ITextProvider& rTextProvider(getTextProvider());
179 sal_Int32 nCount = rTextProvider.getTextCount();
180 while (nCount--)
182 SdrText* pText = rTextProvider.getText( nCount );
183 OutlinerParaObject* pParaObj = pText->GetOutlinerParaObject();
184 if( pParaObj )
186 rOutliner.SetText(*pParaObj);
187 sal_Int32 nParaCount(rOutliner.GetParagraphCount());
189 if(nParaCount)
191 ESelection aSelection( 0, 0, EE_PARA_ALL, EE_TEXTPOS_ALL);
192 rOutliner.RemoveAttribs(aSelection, true, 0);
194 std::unique_ptr<OutlinerParaObject> pTemp = rOutliner.CreateParaObject(0, nParaCount);
195 rOutliner.Clear();
197 rObj.NbcSetOutlinerParaObjectForText( std::move(pTemp), pText );
203 // call parent
204 AttributeProperties::ItemChange( nWhich, pNewItem );
206 // #i25616#
207 if(XATTR_LINEWIDTH == nWhich && rObj.DoesSupportTextIndentingOnLineWidthChange())
209 const sal_Int32 nNewLineWidth(GetItem(XATTR_LINEWIDTH).GetValue());
210 const sal_Int32 nDifference((nNewLineWidth - nOldLineWidth) / 2);
212 if(nDifference)
214 const bool bLineVisible(drawing::LineStyle_NONE != GetItem(XATTR_LINESTYLE).GetValue());
216 if(bLineVisible)
218 const sal_Int32 nLeftDist(GetItem(SDRATTR_TEXT_LEFTDIST).GetValue());
219 const sal_Int32 nRightDist(GetItem(SDRATTR_TEXT_RIGHTDIST).GetValue());
220 const sal_Int32 nUpperDist(GetItem(SDRATTR_TEXT_UPPERDIST).GetValue());
221 const sal_Int32 nLowerDist(GetItem(SDRATTR_TEXT_LOWERDIST).GetValue());
223 SetObjectItemDirect(makeSdrTextLeftDistItem(nLeftDist + nDifference));
224 SetObjectItemDirect(makeSdrTextRightDistItem(nRightDist + nDifference));
225 SetObjectItemDirect(makeSdrTextUpperDistItem(nUpperDist + nDifference));
226 SetObjectItemDirect(makeSdrTextLowerDistItem(nLowerDist + nDifference));
232 const svx::ITextProvider& TextProperties::getTextProvider() const
234 return static_cast<const SdrTextObj&>(GetSdrObject());
237 void TextProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr)
239 // call parent (always first thing to do, may create the SfxItemSet)
240 AttributeProperties::SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
242 // #i101556# StyleSheet has changed -> new version
243 SdrTextObj& rObj = static_cast<SdrTextObj&>(GetSdrObject());
244 maVersion++;
246 if(!rObj.IsLinkedText() )
248 SdrOutliner& rOutliner = rObj.ImpGetDrawOutliner();
250 const svx::ITextProvider& rTextProvider(getTextProvider());
251 sal_Int32 nText = rTextProvider.getTextCount();
252 while (nText--)
254 SdrText* pText = rTextProvider.getText( nText );
256 OutlinerParaObject* pParaObj = pText ? pText->GetOutlinerParaObject() : nullptr;
257 if( !pParaObj )
258 continue;
260 // apply StyleSheet to all paragraphs
261 rOutliner.SetText(*pParaObj);
262 sal_Int32 nParaCount(rOutliner.GetParagraphCount());
264 if(nParaCount)
266 for(sal_Int32 nPara = 0; nPara < nParaCount; nPara++)
268 std::unique_ptr<SfxItemSet> pTempSet;
270 // since setting the stylesheet removes all para attributes
271 if(bDontRemoveHardAttr)
273 // we need to remember them if we want to keep them
274 pTempSet.reset(new SfxItemSet(rOutliner.GetParaAttribs(nPara)));
277 if(GetStyleSheet())
279 if((OBJ_OUTLINETEXT == rObj.GetTextKind()) && (SdrInventor::Default == rObj.GetObjInventor()))
281 OUString aNewStyleSheetName(GetStyleSheet()->GetName());
282 aNewStyleSheetName = aNewStyleSheetName.copy(0, aNewStyleSheetName.getLength() - 1);
283 sal_Int16 nDepth = rOutliner.GetDepth(nPara);
284 aNewStyleSheetName += OUString::number( nDepth <= 0 ? 1 : nDepth + 1);
285 SfxStyleSheetBasePool* pStylePool(rObj.getSdrModelFromSdrObject().GetStyleSheetPool());
286 SfxStyleSheet* pNewStyle = nullptr;
287 if(pStylePool)
288 pNewStyle = static_cast<SfxStyleSheet*>(pStylePool->Find(aNewStyleSheetName, GetStyleSheet()->GetFamily()));
289 DBG_ASSERT( pNewStyle, "AutoStyleSheetName - Style not found!" );
291 if(pNewStyle)
293 rOutliner.SetStyleSheet(nPara, pNewStyle);
296 else
298 rOutliner.SetStyleSheet(nPara, GetStyleSheet());
301 else
303 // remove StyleSheet
304 rOutliner.SetStyleSheet(nPara, nullptr);
307 if(bDontRemoveHardAttr)
309 if(pTempSet)
311 // restore para attributes
312 rOutliner.SetParaAttribs(nPara, *pTempSet);
315 else
317 if(pNewStyleSheet)
319 // remove all hard paragraph attributes
320 // which occur in StyleSheet, take care of
321 // parents (!)
322 SfxItemIter aIter(pNewStyleSheet->GetItemSet());
324 for (const SfxPoolItem* pItem = aIter.GetCurItem(); pItem;
325 pItem = aIter.NextItem())
327 if(!IsInvalidItem(pItem))
329 sal_uInt16 nW(pItem->Which());
331 if(nW >= EE_ITEMS_START && nW <= EE_ITEMS_END)
333 rOutliner.RemoveCharAttribs(nPara, nW);
341 std::unique_ptr<OutlinerParaObject> pTemp = rOutliner.CreateParaObject(0, nParaCount);
342 rOutliner.Clear();
343 rObj.NbcSetOutlinerParaObjectForText(std::move(pTemp), pText);
348 if(rObj.IsTextFrame())
350 rObj.NbcAdjustTextFrameWidthAndHeight();
354 void TextProperties::ForceDefaultAttributes()
356 SdrTextObj& rObj = static_cast<SdrTextObj&>(GetSdrObject());
358 if( rObj.GetObjInventor() == SdrInventor::Default )
360 const sal_uInt16 nSdrObjKind = rObj.GetObjIdentifier();
362 if( nSdrObjKind == OBJ_TITLETEXT || nSdrObjKind == OBJ_OUTLINETEXT )
363 return; // no defaults for presentation objects
366 bool bTextFrame(rObj.IsTextFrame());
368 // force ItemSet
369 GetObjectItemSet();
371 if(bTextFrame)
373 mpItemSet->Put(XLineStyleItem(drawing::LineStyle_NONE));
374 mpItemSet->Put(XFillColorItem(OUString(), COL_WHITE));
375 mpItemSet->Put(XFillStyleItem(drawing::FillStyle_NONE));
377 else
379 mpItemSet->Put(SvxAdjustItem(SvxAdjust::Center, EE_PARA_JUST));
380 mpItemSet->Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_CENTER));
381 mpItemSet->Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_CENTER));
385 void TextProperties::ForceStyleToHardAttributes()
387 // #i61284# call parent first to get the hard ObjectItemSet
388 AttributeProperties::ForceStyleToHardAttributes();
390 // #i61284# push hard ObjectItemSet to OutlinerParaObject attributes
391 // using existing functionality
392 GetObjectItemSet(); // force ItemSet
393 ItemSetChanged(*mpItemSet);
395 // now the standard TextProperties stuff
396 SdrTextObj& rObj = static_cast<SdrTextObj&>(GetSdrObject());
398 if(!rObj.IsTextEditActive() && !rObj.IsLinkedText())
400 std::unique_ptr<Outliner> pOutliner = SdrMakeOutliner(OutlinerMode::OutlineObject, rObj.getSdrModelFromSdrObject());
401 const svx::ITextProvider& rTextProvider(getTextProvider());
402 sal_Int32 nText = rTextProvider.getTextCount();
403 while (nText--)
405 SdrText* pText = rTextProvider.getText( nText );
407 OutlinerParaObject* pParaObj = pText ? pText->GetOutlinerParaObject() : nullptr;
408 if( !pParaObj )
409 continue;
411 pOutliner->SetText(*pParaObj);
413 sal_Int32 nParaCount(pOutliner->GetParagraphCount());
415 if(nParaCount)
417 bool bBurnIn(false);
419 for(sal_Int32 nPara = 0; nPara < nParaCount; nPara++)
421 SfxStyleSheet* pSheet = pOutliner->GetStyleSheet(nPara);
423 if(pSheet)
425 SfxItemSet aParaSet(pOutliner->GetParaAttribs(nPara));
426 SfxItemSet aSet(*aParaSet.GetPool());
427 aSet.Put(pSheet->GetItemSet());
429 /** the next code handles a special case for paragraphs that contain a
430 url field. The color for URL fields is either the system color for
431 urls or the char color attribute that formats the portion in which the
432 url field is contained.
433 When we set a char color attribute to the paragraphs item set from the
434 styles item set, we would have this char color attribute as an attribute
435 that is spanned over the complete paragraph after xml import due to some
436 problems in the xml import (using a XCursor on import so it does not know
437 the paragraphs and can't set char attributes to paragraphs ).
439 To avoid this, as soon as we try to set a char color attribute from the style
441 1. check if we have at least one url field in this paragraph
442 2. if we found at least one url field, we span the char color attribute over
443 all portions that are not url fields and remove the char color attribute
444 from the paragraphs item set
447 bool bHasURL(false);
449 if(aSet.GetItemState(EE_CHAR_COLOR) == SfxItemState::SET)
451 EditEngine* pEditEngine = const_cast<EditEngine*>(&(pOutliner->GetEditEngine()));
452 std::vector<EECharAttrib> aAttribs;
453 pEditEngine->GetCharAttribs(nPara, aAttribs);
455 for(const auto& rAttrib : aAttribs)
457 if(rAttrib.pAttr && EE_FEATURE_FIELD == rAttrib.pAttr->Which())
459 const SvxFieldItem* pFieldItem = static_cast<const SvxFieldItem*>(rAttrib.pAttr);
461 if(pFieldItem)
463 const SvxFieldData* pData = pFieldItem->GetField();
465 if(dynamic_cast<const SvxURLField*>( pData))
467 bHasURL = true;
468 break;
474 if(bHasURL)
476 SfxItemSet aColorSet(*aSet.GetPool(), svl::Items<EE_CHAR_COLOR, EE_CHAR_COLOR>{} );
477 aColorSet.Put(aSet, false);
479 ESelection aSel(nPara, 0);
481 for(const auto& rAttrib : aAttribs)
483 if(EE_FEATURE_FIELD == rAttrib.pAttr->Which())
485 aSel.nEndPos = rAttrib.nStart;
487 if(aSel.nStartPos != aSel.nEndPos)
488 pEditEngine->QuickSetAttribs(aColorSet, aSel);
490 aSel.nStartPos = rAttrib.nEnd;
494 aSel.nEndPos = pEditEngine->GetTextLen(nPara);
496 if(aSel.nStartPos != aSel.nEndPos)
498 pEditEngine->QuickSetAttribs( aColorSet, aSel );
504 aSet.Put(aParaSet, false);
506 if(bHasURL)
508 aSet.ClearItem(EE_CHAR_COLOR);
511 pOutliner->SetParaAttribs(nPara, aSet);
512 bBurnIn = true; // #i51163# Flag was set wrong
516 if(bBurnIn)
518 std::unique_ptr<OutlinerParaObject> pTemp = pOutliner->CreateParaObject(0, nParaCount);
519 rObj.NbcSetOutlinerParaObjectForText(std::move(pTemp),pText);
523 pOutliner->Clear();
528 void TextProperties::SetObjectItemNoBroadcast(const SfxPoolItem& rItem)
530 GetObjectItemSet();
531 mpItemSet->Put(rItem);
535 void TextProperties::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
537 // call parent
538 AttributeProperties::Notify(rBC, rHint);
540 SdrTextObj& rObj = static_cast<SdrTextObj&>(GetSdrObject());
541 if(rObj.HasText())
543 const svx::ITextProvider& rTextProvider(getTextProvider());
544 if(dynamic_cast<const SfxStyleSheet *>(&rBC) != nullptr)
546 SfxHintId nId(rHint.GetId());
548 if(SfxHintId::DataChanged == nId)
550 sal_Int32 nText = rTextProvider.getTextCount();
551 while (nText--)
553 OutlinerParaObject* pParaObj = rTextProvider.getText( nText )->GetOutlinerParaObject();
554 if( pParaObj )
555 pParaObj->ClearPortionInfo();
557 rObj.SetTextSizeDirty();
559 if(rObj.IsTextFrame() && rObj.NbcAdjustTextFrameWidthAndHeight())
561 // here only repaint wanted
562 rObj.ActionChanged();
563 //rObj.BroadcastObjectChange();
566 // #i101556# content of StyleSheet has changed -> new version
567 maVersion++;
570 if(SfxHintId::Dying == nId)
572 sal_Int32 nText = rTextProvider.getTextCount();
573 while (nText--)
575 OutlinerParaObject* pParaObj = rTextProvider.getText( nText )->GetOutlinerParaObject();
576 if( pParaObj )
577 pParaObj->ClearPortionInfo();
581 else if(dynamic_cast<const SfxStyleSheetBasePool *>(&rBC) != nullptr)
583 const SfxStyleSheetModifiedHint* pExtendedHint = dynamic_cast<const SfxStyleSheetModifiedHint*>(&rHint);
585 if(pExtendedHint
586 && SfxHintId::StyleSheetModified == pExtendedHint->GetId())
588 const OUString& aOldName(pExtendedHint->GetOldName());
589 OUString aNewName(pExtendedHint->GetStyleSheet()->GetName());
590 SfxStyleFamily eFamily = pExtendedHint->GetStyleSheet()->GetFamily();
592 if(aOldName != aNewName)
594 sal_Int32 nText = rTextProvider.getTextCount();
595 while (nText--)
597 OutlinerParaObject* pParaObj = rTextProvider.getText( nText )->GetOutlinerParaObject();
598 if( pParaObj )
599 pParaObj->ChangeStyleSheetName(eFamily, aOldName, aNewName);
607 // #i101556# Handout version information
608 sal_uInt32 TextProperties::getVersion() const
610 return maVersion;
612 } // end of namespace properties
613 } // end of namespace sdr
615 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */