/src/libreoffice/svx/source/sdr/properties/attributeproperties.cxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
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/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
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 . |
18 | | */ |
19 | | |
20 | | #include <sal/config.h> |
21 | | |
22 | | #include <sdr/properties/attributeproperties.hxx> |
23 | | #include <tools/debug.hxx> |
24 | | #include <svl/itemset.hxx> |
25 | | #include <svl/style.hxx> |
26 | | #include <svl/whiter.hxx> |
27 | | #include <svl/poolitem.hxx> |
28 | | #include <svx/svdobj.hxx> |
29 | | #include <svx/fillbitmaplink.hxx> |
30 | | #include <svx/xbtmpit.hxx> |
31 | | #include <svx/xlndsit.hxx> |
32 | | #include <svx/xlnstit.hxx> |
33 | | #include <svx/xlnedit.hxx> |
34 | | #include <svx/xflgrit.hxx> |
35 | | #include <svx/xflftrit.hxx> |
36 | | #include <svx/xflhtit.hxx> |
37 | | #include <svx/svdmodel.hxx> |
38 | | #include <svx/svdpage.hxx> |
39 | | #include <svx/diagram/DiagramHelper_svx.hxx> |
40 | | #include <osl/diagnose.h> |
41 | | |
42 | | namespace sdr::properties |
43 | | { |
44 | | void AttributeProperties::ImpSetParentAtSfxItemSet(bool bDontRemoveHardAttr) |
45 | 484k | { |
46 | 484k | if(HasSfxItemSet() && mpStyleSheet) |
47 | 484k | { |
48 | | // Delete hard attributes where items are set in the style sheet |
49 | 484k | if(!bDontRemoveHardAttr) |
50 | 173k | { |
51 | 173k | const SfxItemSet& rStyle = mpStyleSheet->GetItemSet(); |
52 | 173k | SfxWhichIter aIter(rStyle); |
53 | 173k | sal_uInt16 nWhich = aIter.FirstWhich(); |
54 | | |
55 | 37.9M | while(nWhich) |
56 | 37.7M | { |
57 | 37.7M | if(SfxItemState::SET == aIter.GetItemState()) |
58 | 3.22M | { |
59 | 3.22M | moItemSet->ClearItem(nWhich); |
60 | 3.22M | } |
61 | | |
62 | 37.7M | nWhich = aIter.NextWhich(); |
63 | 37.7M | } |
64 | 173k | } |
65 | | |
66 | | // set new stylesheet as parent |
67 | 484k | moItemSet->SetParent(&mpStyleSheet->GetItemSet()); |
68 | 484k | } |
69 | 0 | else |
70 | 0 | { |
71 | 0 | OSL_ENSURE(false, "ImpSetParentAtSfxItemSet called without SfxItemSet/SfxStyleSheet (!)"); |
72 | 0 | } |
73 | 484k | } |
74 | | |
75 | | void AttributeProperties::ImpAddStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr) |
76 | 576k | { |
77 | | // test if old StyleSheet is cleared, else it would be lost |
78 | | // after this method -> memory leak (!) |
79 | 576k | DBG_ASSERT(!mpStyleSheet, "Old style sheet not deleted before setting new one (!)"); |
80 | | |
81 | 576k | if(!pNewStyleSheet) |
82 | 91.3k | return; |
83 | | |
84 | | // local remember |
85 | 484k | mpStyleSheet = pNewStyleSheet; |
86 | | |
87 | 484k | if(HasSfxItemSet()) |
88 | 484k | { |
89 | | // register as listener |
90 | 484k | StartListening(*pNewStyleSheet->GetPool()); |
91 | 484k | StartListening(*pNewStyleSheet); |
92 | | |
93 | | // only apply the following when we have an SfxItemSet already, else |
94 | 484k | if(GetStyleSheet()) |
95 | 484k | { |
96 | 484k | ImpSetParentAtSfxItemSet(bDontRemoveHardAttr); |
97 | 484k | } |
98 | 484k | } |
99 | 484k | } |
100 | | |
101 | | void AttributeProperties::ImpRemoveStyleSheet() |
102 | 1.81M | { |
103 | | // Check type since it is destroyed when the type is deleted |
104 | 1.81M | if(GetStyleSheet() && mpStyleSheet) |
105 | 484k | { |
106 | 484k | EndListening(*mpStyleSheet); |
107 | 484k | if (auto const pool = mpStyleSheet->GetPool()) { // TTTT |
108 | 484k | EndListening(*pool); |
109 | 484k | } |
110 | | |
111 | | // reset parent of ItemSet |
112 | 484k | if(HasSfxItemSet()) |
113 | 484k | { |
114 | 484k | moItemSet->SetParent(nullptr); |
115 | 484k | } |
116 | | |
117 | 484k | SdrObject& rObj = GetSdrObject(); |
118 | 484k | rObj.SetBoundRectDirty(); |
119 | 484k | rObj.SetBoundAndSnapRectsDirty(/*bNotMyself*/true); |
120 | 484k | } |
121 | | |
122 | 1.81M | mpStyleSheet = nullptr; |
123 | 1.81M | } |
124 | | |
125 | | // create a new itemset |
126 | | SfxItemSet AttributeProperties::CreateObjectSpecificItemSet(SfxItemPool&) |
127 | 0 | { |
128 | 0 | assert(false && "this class is effectively abstract, should only be instantiating subclasses"); |
129 | 0 | abort(); |
130 | 0 | } |
131 | | |
132 | | AttributeProperties::AttributeProperties(SdrObject& rObj) |
133 | 1.23M | : DefaultProperties(rObj), |
134 | 1.23M | mpStyleSheet(nullptr) |
135 | 1.23M | { |
136 | | // Do nothing else, esp. do *not* try to get and set |
137 | | // a default SfxStyle sheet. Nothing is allowed to be done |
138 | | // that may lead to calls to virtual functions like |
139 | | // CreateObjectSpecificItemSet - these would go *wrong*. |
140 | | // Thus the rest is lazy-init from here. |
141 | 1.23M | } |
142 | | |
143 | | AttributeProperties::AttributeProperties(const AttributeProperties& rProps, SdrObject& rObj) |
144 | 25.1k | : DefaultProperties(rProps, rObj), |
145 | 25.1k | mpStyleSheet(nullptr) |
146 | 25.1k | { |
147 | 25.1k | const bool bModelChange(&rObj.getSdrModelFromSdrObject() != &rProps.GetSdrObject().getSdrModelFromSdrObject()); |
148 | | |
149 | 25.1k | if (bModelChange) |
150 | 0 | { |
151 | | // use default; will be corrected/handled in call to |
152 | | // postProcessAfterCloneToDifferentModel below. Thus, |
153 | | // also do not yet call ImpAddStyleSheet here |
154 | 0 | mpStyleSheet = GetSdrObject().getSdrModelFromSdrObject().GetDefaultStyleSheet(); |
155 | 0 | } |
156 | 25.1k | else |
157 | 25.1k | { |
158 | | // copy existing one |
159 | 25.1k | mpStyleSheet = rProps.GetStyleSheet(); |
160 | | |
161 | | // add StyleSheet && establish the parent-links in the SfxItemSet |
162 | 25.1k | ImpAddStyleSheet(mpStyleSheet, true); |
163 | 25.1k | } |
164 | 25.1k | } |
165 | | |
166 | | void AttributeProperties::postProcessAfterCloneToDifferentModel(const SdrObject& rSrcObj) |
167 | 0 | { |
168 | 0 | SdrModel& rDstModel(GetSdrObject().getSdrModelFromSdrObject()); |
169 | 0 | const bool bModelChange(&rSrcObj.getSdrModelFromSdrObject() != &rDstModel); |
170 | |
|
171 | 0 | if (!bModelChange) |
172 | 0 | return; |
173 | | |
174 | | // guarantee SfxItemSet existence |
175 | 0 | DefaultProperties::GetObjectItemSet(); |
176 | 0 | const sdr::properties::BaseProperties& rSource(rSrcObj.GetProperties()); |
177 | 0 | SfxStyleSheet* pNewStyleSheet(nullptr); |
178 | |
|
179 | 0 | if (rDstModel.GetStyleSheetPool()) |
180 | 0 | { |
181 | 0 | SfxStyleSheet* pSourceStyleSheet(rSource.GetStyleSheet()); |
182 | |
|
183 | 0 | if (pSourceStyleSheet) |
184 | 0 | { |
185 | | // If we have a TargetStyleSheetPool, search for the used StyleSheet |
186 | | // in the target SdrModel using the Name from the original StyleSheet |
187 | | // in the source-SdrModel. |
188 | | // That will/should work always since Paste from another model will |
189 | | // in a 1st step copy non-existing StyleSheets to destination model |
190 | 0 | pNewStyleSheet = dynamic_cast< SfxStyleSheet* >( |
191 | 0 | rDstModel.GetStyleSheetPool()->Find( |
192 | 0 | pSourceStyleSheet->GetName(), |
193 | 0 | pSourceStyleSheet->GetFamily())); |
194 | 0 | } |
195 | 0 | } |
196 | | |
197 | | // fallback: every SdrObject *should* have a StyleSheet, use |
198 | | // default from the model |
199 | 0 | if(!pNewStyleSheet) |
200 | 0 | pNewStyleSheet = rDstModel.GetDefaultStyleSheet(); |
201 | |
|
202 | 0 | if(!pNewStyleSheet) |
203 | | // may still have no StyleSheet, was so before, too, but |
204 | | // should not happen since a DefaultStyleSheet should |
205 | | // always be there |
206 | 0 | return; |
207 | | |
208 | | // add StyleSheet && establish the parent-links in the SfxItemSet |
209 | 0 | if (GetStyleSheet() != pNewStyleSheet) |
210 | 0 | { |
211 | 0 | ImpRemoveStyleSheet(); |
212 | 0 | ImpAddStyleSheet(pNewStyleSheet, true); |
213 | 0 | } |
214 | |
|
215 | 0 | if (HasSfxItemSet()) |
216 | 0 | { |
217 | | // here we have a model change and a StyleSheet set,. but that |
218 | | // StyleSheet was found by looking for name & type. It may |
219 | | // *not* be identical to the StyleSheet from the Source. |
220 | | |
221 | | // What to do? We could... |
222 | | // (a) the Style-friendly way: |
223 | | // - check if StyleSheet is identical |
224 | | // - if not, create a new in-between StyleSheet hosting missing Items |
225 | | // - if yes, use, done. |
226 | | // (b) the pragmatic/practical way: |
227 | | // - Just hard-attribute the Items that are detected as different |
228 | | // similar to what BurnInStyleSheetAttributes does/did, but only |
229 | | // for differing Items here |
230 | | // |
231 | | // (b)) is the most simple for now, but will lead to more hard |
232 | | // attributes. The other possibilities will be better in the |
233 | | // long term. For now, I will use (b). |
234 | 0 | SfxWhichIter aIter(rSource.GetObjectItemSet()); |
235 | |
|
236 | 0 | for (sal_uInt16 nWhich = aIter.FirstWhich(); nWhich; nWhich = aIter.NextWhich()) |
237 | 0 | { |
238 | 0 | const SfxPoolItem& rOld(rSource.GetItem(nWhich)); |
239 | 0 | const SfxPoolItem& rNew(GetItem(nWhich)); |
240 | |
|
241 | 0 | if (!SfxPoolItem::areSame(rOld, rNew)) |
242 | 0 | SetObjectItemDirect(rOld); |
243 | 0 | } |
244 | 0 | } |
245 | 0 | } |
246 | | |
247 | | AttributeProperties::~AttributeProperties() |
248 | 1.26M | { |
249 | 1.26M | ImpRemoveStyleSheet(); |
250 | 1.26M | } |
251 | | |
252 | | std::unique_ptr<BaseProperties> AttributeProperties::implCloneProperties(SdrObject&) const |
253 | 0 | { |
254 | 0 | assert(false && "this class is effectively abstract, should only be instantiating subclasses"); |
255 | 0 | abort(); |
256 | 0 | } |
257 | | |
258 | | const SfxItemSet& AttributeProperties::GetObjectItemSet() const |
259 | 63.1M | { |
260 | | // remember if we had a SfxItemSet already |
261 | 63.1M | const bool bHadSfxItemSet(HasSfxItemSet()); |
262 | | |
263 | | // call parent - this will guarantee SfxItemSet existence |
264 | 63.1M | DefaultProperties::GetObjectItemSet(); |
265 | | |
266 | 63.1M | if(!bHadSfxItemSet) |
267 | 1.20M | { |
268 | | // need to take care for SfxStyleSheet for newly |
269 | | // created SfxItemSet |
270 | 1.20M | if(nullptr == mpStyleSheet) |
271 | 1.20M | { |
272 | | // Set missing defaults without removal of hard attributes. |
273 | | // This is more complicated historically than I first thought: |
274 | | // Originally for GetDefaultStyleSheetForSdrGrafObjAndSdrOle2Obj |
275 | | // SetStyleSheet(..., false) was used, while for GetDefaultStyleSheet |
276 | | // SetStyleSheet(..., true) was used. Thus, for SdrGrafObj and SdrOle2Obj |
277 | | // bDontRemoveHardAttr == false -> *do* delete hard attributes was used. |
278 | | // This was probably not done by purpose, adding the method |
279 | | // GetDefaultStyleSheetForSdrGrafObjAndSdrOle2Obj additionally to |
280 | | // GetDefaultStyleSheet was an enhancement to allow for SdrGrafObj/SdrOle2Obj |
281 | | // with full AttributeSet (adding e.g. FillAttributes). To stay as compatible |
282 | | // as possible these SdrObjects got a new default-StyleSheet. |
283 | | // There is no reason to delete the HardAttributes and it anyways has only |
284 | | // AFAIK effects on a single Item - the SdrTextHorzAdjustItem. To get things |
285 | | // unified I will stay with not deleting the HardAttributes and adapt the |
286 | | // UnitTests in CppunitTest_sd_import_tests accordingly. |
287 | 1.20M | const_cast< AttributeProperties* >(this)->applyDefaultStyleSheetFromSdrModel(); |
288 | 1.20M | } |
289 | 0 | else |
290 | 0 | { |
291 | | // Late-Init of setting parent to SfxStyleSheet after |
292 | | // it's creation. Can only happen from copy-constructor |
293 | | // (where creation of SfxItemSet is avoided due to the |
294 | | // problem with constructors and virtual functions in C++), |
295 | | // thus DontRemoveHardAttr is not needed. |
296 | 0 | const_cast< AttributeProperties* >(this)->SetStyleSheet( |
297 | 0 | mpStyleSheet, true, true); |
298 | 0 | } |
299 | 1.20M | } |
300 | | |
301 | 63.1M | return *moItemSet; |
302 | 63.1M | } |
303 | | |
304 | | void AttributeProperties::ItemSetChanged(std::span< const SfxPoolItem* const > aChangedItems, sal_uInt16 /*nDeletedWhich*/, bool /*bAdjustTextFrameWidthAndHeight*/) |
305 | 5.91M | { |
306 | | // own modifications |
307 | 5.91M | SdrObject& rObj = GetSdrObject(); |
308 | | |
309 | 5.91M | rObj.SetBoundRectDirty(); |
310 | 5.91M | rObj.SetBoundAndSnapRectsDirty(/*bNotMyself*/true); |
311 | 5.91M | rObj.SetChanged(); |
312 | | |
313 | 5.91M | if (!rObj.getDiagramDataModelID().isEmpty() && !rObj.getSdrModelFromSdrObject().isInImportExport()) |
314 | 1.46M | { |
315 | 1.46M | const std::shared_ptr< svx::diagram::DiagramHelper_svx >& pDiagramHelper(rObj.getDiagramHelper()); |
316 | 1.46M | if (pDiagramHelper) |
317 | 4 | pDiagramHelper->ItemSetInformationChange(aChangedItems); |
318 | 1.46M | } |
319 | 5.91M | } |
320 | | |
321 | | void AttributeProperties::ItemChange(const sal_uInt16 nWhich, const SfxPoolItem* pNewItem) |
322 | 20.6M | { |
323 | 20.6M | if(pNewItem) |
324 | 20.6M | { |
325 | 20.6M | std::unique_ptr<SfxPoolItem> pResultItem; |
326 | 20.6M | SdrModel& rModel(GetSdrObject().getSdrModelFromSdrObject()); |
327 | | |
328 | 20.6M | switch( nWhich ) |
329 | 20.6M | { |
330 | 10.8k | case XATTR_FILLBITMAP: |
331 | 10.8k | { |
332 | 10.8k | pResultItem = static_cast<const XFillBitmapItem*>(pNewItem)->checkForUniqueItem( rModel ); |
333 | 10.8k | break; |
334 | 0 | } |
335 | 19.3k | case XATTR_LINEDASH: |
336 | 19.3k | { |
337 | 19.3k | pResultItem = static_cast<const XLineDashItem*>(pNewItem)->checkForUniqueItem( rModel ); |
338 | 19.3k | break; |
339 | 0 | } |
340 | 12.0k | case XATTR_LINESTART: |
341 | 12.0k | { |
342 | 12.0k | pResultItem = static_cast<const XLineStartItem*>(pNewItem)->checkForUniqueItem( rModel ); |
343 | 12.0k | break; |
344 | 0 | } |
345 | 26.2k | case XATTR_LINEEND: |
346 | 26.2k | { |
347 | 26.2k | pResultItem = static_cast<const XLineEndItem*>(pNewItem)->checkForUniqueItem( rModel ); |
348 | 26.2k | break; |
349 | 0 | } |
350 | 12.5k | case XATTR_FILLGRADIENT: |
351 | 12.5k | { |
352 | 12.5k | pResultItem = static_cast<const XFillGradientItem*>(pNewItem)->checkForUniqueItem( rModel ); |
353 | 12.5k | break; |
354 | 0 | } |
355 | 111 | case XATTR_FILLFLOATTRANSPARENCE: |
356 | 111 | { |
357 | | // #85953# allow all kinds of XFillFloatTransparenceItem to be set |
358 | 111 | pResultItem = static_cast<const XFillFloatTransparenceItem*>(pNewItem)->checkForUniqueItem( rModel ); |
359 | 111 | break; |
360 | 0 | } |
361 | 0 | case XATTR_FILLHATCH: |
362 | 0 | { |
363 | 0 | pResultItem = static_cast<const XFillHatchItem*>(pNewItem)->checkForUniqueItem( rModel ); |
364 | 0 | break; |
365 | 0 | } |
366 | 20.6M | } |
367 | | |
368 | | // guarantee SfxItemSet existence |
369 | 20.6M | GetObjectItemSet(); |
370 | | |
371 | 20.6M | if(pResultItem) |
372 | 53.8k | { |
373 | | // force ItemSet |
374 | 53.8k | moItemSet->Put(std::move(pResultItem)); |
375 | 53.8k | } |
376 | 20.5M | else |
377 | 20.5M | { |
378 | 20.5M | moItemSet->Put(*pNewItem); |
379 | 20.5M | } |
380 | 20.6M | } |
381 | 14.3k | else |
382 | 14.3k | { |
383 | | // clear item if ItemSet exists |
384 | 14.3k | if(HasSfxItemSet()) |
385 | 12.9k | { |
386 | 12.9k | moItemSet->ClearItem(nWhich); |
387 | 12.9k | } |
388 | 14.3k | } |
389 | | |
390 | | // route a deferred remote fill bitmap appearing/changing/clearing on |
391 | | // this object to the model's link tracker, so the link is registered |
392 | | // as the item is set rather than by a later pool scan |
393 | 20.6M | if (nWhich == XATTR_FILLBITMAP) |
394 | 10.8k | { |
395 | 10.8k | SdrModel& rFillModel(GetSdrObject().getSdrModelFromSdrObject()); |
396 | 10.8k | if (sdr::FillBitmapLinkTracker* pTracker = rFillModel.GetFillBitmapLinkTracker()) |
397 | 10.8k | { |
398 | 10.8k | OUString aURL; |
399 | 10.8k | if (pNewItem) |
400 | 10.8k | aURL = getDeferredOriginURL(static_cast<const XFillBitmapItem&>(*pNewItem)); |
401 | 10.8k | pTracker->onFillBitmapURLChanged(GetSdrObject(), aURL); |
402 | 10.8k | } |
403 | 10.8k | } |
404 | 20.6M | } |
405 | | |
406 | | void AttributeProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr, |
407 | | bool /*bBroadcast*/, bool /*bAdjustTextFrameWidthAndHeight*/) |
408 | 551k | { |
409 | | // Make sure we have a SfxItemSet. We are deliberately bypassing our |
410 | | // own AttributeProperties::GetObjectItemSet here, because we don't want to set a default stylesheet, |
411 | | // and then immediately remove it, which is costly. |
412 | 551k | DefaultProperties::GetObjectItemSet(); |
413 | | |
414 | 551k | ImpRemoveStyleSheet(); |
415 | 551k | ImpAddStyleSheet(pNewStyleSheet, bDontRemoveHardAttr); |
416 | | |
417 | 551k | SdrObject& rObj = GetSdrObject(); |
418 | 551k | rObj.SetBoundRectDirty(); |
419 | 551k | rObj.SetBoundAndSnapRectsDirty(true); |
420 | 551k | } |
421 | | |
422 | | SfxStyleSheet* AttributeProperties::GetStyleSheet() const |
423 | 22.3M | { |
424 | 22.3M | return mpStyleSheet; |
425 | 22.3M | } |
426 | | |
427 | | void AttributeProperties::ForceStyleToHardAttributes() |
428 | 0 | { |
429 | 0 | if(!GetStyleSheet() || mpStyleSheet == nullptr) |
430 | 0 | return; |
431 | | |
432 | | // guarantee SfxItemSet existence |
433 | 0 | GetObjectItemSet(); |
434 | | |
435 | | // prepare copied, new itemset, but WITHOUT parent |
436 | 0 | SfxItemSet aDestItemSet(*moItemSet); |
437 | 0 | aDestItemSet.SetParent(nullptr); |
438 | | |
439 | | // prepare forgetting the current stylesheet like in RemoveStyleSheet() |
440 | 0 | EndListening(*mpStyleSheet); |
441 | 0 | EndListening(*mpStyleSheet->GetPool()); |
442 | | |
443 | | // prepare the iter; use the mpObjectItemSet which may have less |
444 | | // WhichIDs than the style. |
445 | 0 | SfxWhichIter aIter(aDestItemSet); |
446 | 0 | sal_uInt16 nWhich(aIter.FirstWhich()); |
447 | 0 | const SfxPoolItem *pItem = nullptr; |
448 | | |
449 | | // now set all hard attributes of the current at the new itemset |
450 | 0 | while(nWhich) |
451 | 0 | { |
452 | | // #i61284# use mpItemSet with parents, makes things easier and reduces to |
453 | | // one loop |
454 | 0 | if(SfxItemState::SET == moItemSet->GetItemState(nWhich, true, &pItem)) |
455 | 0 | { |
456 | 0 | aDestItemSet.Put(*pItem); |
457 | 0 | } |
458 | |
|
459 | 0 | nWhich = aIter.NextWhich(); |
460 | 0 | } |
461 | | |
462 | | // replace itemsets |
463 | 0 | moItemSet.emplace(std::move(aDestItemSet)); |
464 | | |
465 | | // set necessary changes like in RemoveStyleSheet() |
466 | 0 | GetSdrObject().SetBoundRectDirty(); |
467 | 0 | GetSdrObject().SetBoundAndSnapRectsDirty(/*bNotMyself*/true); |
468 | |
|
469 | 0 | mpStyleSheet = nullptr; |
470 | 0 | } |
471 | | |
472 | | void AttributeProperties::Notify(SfxBroadcaster& rBC, const SfxHint& rHint) |
473 | 16.3M | { |
474 | 16.3M | bool bHintUsed(false); |
475 | | |
476 | 16.3M | SfxHintId id = rHint.GetId(); |
477 | 16.3M | if (id == SfxHintId::StyleSheetChanged |
478 | 16.3M | || id == SfxHintId::StyleSheetErased |
479 | 16.3M | || id == SfxHintId::StyleSheetModified |
480 | 9.30M | || id == SfxHintId::StyleSheetInDestruction |
481 | 9.30M | || id == SfxHintId::StyleSheetModifiedExtended) |
482 | 15.9M | { |
483 | 15.9M | const SfxStyleSheetHint* pStyleHint = static_cast<const SfxStyleSheetHint*>(&rHint); |
484 | | |
485 | 15.9M | if(pStyleHint->GetStyleSheet() == GetStyleSheet()) |
486 | 68.8k | { |
487 | 68.8k | SdrObject& rObj = GetSdrObject(); |
488 | | //SdrPage* pPage = rObj.GetPage(); |
489 | | |
490 | 68.8k | switch(id) |
491 | 68.8k | { |
492 | 0 | case SfxHintId::StyleSheetModified : |
493 | 68.8k | case SfxHintId::StyleSheetModifiedExtended: |
494 | 68.8k | case SfxHintId::StyleSheetChanged : |
495 | 68.8k | { |
496 | | // notify change |
497 | 68.8k | break; |
498 | 68.8k | } |
499 | 0 | case SfxHintId::StyleSheetErased : |
500 | 0 | case SfxHintId::StyleSheetInDestruction : |
501 | 0 | { |
502 | | // Style needs to be exchanged |
503 | 0 | SfxStyleSheet* pNewStSh = nullptr; |
504 | 0 | SdrModel& rModel(rObj.getSdrModelFromSdrObject()); |
505 | | |
506 | | // Do nothing if object is in destruction, else a StyleSheet may be found from |
507 | | // a StyleSheetPool which is just being deleted itself. and thus it would be fatal |
508 | | // to register as listener to that new StyleSheet. |
509 | 0 | if(!rObj.IsInDestruction()) |
510 | 0 | { |
511 | 0 | if(SfxStyleSheet* pStyleSheet = GetStyleSheet()) |
512 | 0 | { |
513 | 0 | pNewStSh = static_cast<SfxStyleSheet*>(rModel.GetStyleSheetPool()->Find( |
514 | 0 | pStyleSheet->GetParent(), pStyleSheet->GetFamily())); |
515 | 0 | } |
516 | |
|
517 | 0 | if(!pNewStSh) |
518 | 0 | { |
519 | 0 | pNewStSh = rModel.GetDefaultStyleSheet(); |
520 | 0 | } |
521 | 0 | } |
522 | | |
523 | | // remove used style, it's erased or in destruction |
524 | 0 | ImpRemoveStyleSheet(); |
525 | |
|
526 | 0 | if(pNewStSh) |
527 | 0 | { |
528 | 0 | ImpAddStyleSheet(pNewStSh, true); |
529 | 0 | } |
530 | |
|
531 | 0 | break; |
532 | 0 | } |
533 | 0 | default: break; |
534 | 68.8k | } |
535 | | |
536 | | // Get old BoundRect. Do this after the style change is handled |
537 | | // in the ItemSet parts because GetBoundRect() may calculate a new |
538 | 68.8k | tools::Rectangle aBoundRect = rObj.GetLastBoundRect(); |
539 | | |
540 | 68.8k | rObj.SetBoundAndSnapRectsDirty(/*bNotMyself*/true); |
541 | | |
542 | | // tell the object about the change |
543 | 68.8k | rObj.SetChanged(); |
544 | 68.8k | rObj.BroadcastObjectChange(); |
545 | | |
546 | | //if(pPage && pPage->IsInserted()) |
547 | | //{ |
548 | | // rObj.BroadcastObjectChange(); |
549 | | //} |
550 | | |
551 | 68.8k | rObj.SendUserCall(SdrUserCallType::ChangeAttr, aBoundRect); |
552 | | |
553 | 68.8k | bHintUsed = true; |
554 | 68.8k | } |
555 | 15.9M | } |
556 | 16.3M | if(!bHintUsed) |
557 | 16.2M | { |
558 | | // forward to SdrObject ATM. Not sure if this will be necessary |
559 | | // in the future. |
560 | 16.2M | GetSdrObject().Notify(rBC, rHint); |
561 | 16.2M | } |
562 | 16.3M | } |
563 | | |
564 | | bool AttributeProperties::isUsedByModel() const |
565 | 98 | { |
566 | 98 | const SdrObject& rObj(GetSdrObject()); |
567 | 98 | if (rObj.IsInserted()) |
568 | 98 | { |
569 | 98 | const SdrPage* const pPage(rObj.getSdrPageFromSdrObject()); |
570 | 98 | if (pPage && pPage->IsInserted()) |
571 | 98 | return true; |
572 | 98 | } |
573 | 0 | return false; |
574 | 98 | } |
575 | | |
576 | | void AttributeProperties::applyDefaultStyleSheetFromSdrModel() |
577 | 1.20M | { |
578 | 1.20M | SfxStyleSheet* pDefaultStyleSheet(GetSdrObject().getSdrModelFromSdrObject().GetDefaultStyleSheet()); |
579 | | |
580 | | // tdf#118139 Only do this when StyleSheet really differs. It may e.g. |
581 | | // be the case that nullptr == pDefaultStyleSheet and there is none set yet, |
582 | | // so indeed no need to set it (needed for some strange old MSWord2003 |
583 | | // documents with CustomShape-'Group' and added Text-Frames, see task description) |
584 | 1.20M | if(pDefaultStyleSheet != GetStyleSheet()) |
585 | 282k | { |
586 | | // do not delete hard attributes when setting default Style |
587 | 282k | SetStyleSheet(pDefaultStyleSheet, true, true); |
588 | 282k | } |
589 | 1.20M | } |
590 | | |
591 | | } // end of namespace |
592 | | |
593 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |