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/groupproperties.hxx>
23 #include <svl/itemset.hxx>
24 #include <svl/whiter.hxx>
25 #include <svx/svdogrp.hxx>
26 #include <svx/svdpage.hxx>
27 #include <osl/diagnose.h>
28 
29 
30 namespace sdr::properties
31 {
32         // create a new itemset
CreateObjectSpecificItemSet(SfxItemPool & rPool)33         SfxItemSet GroupProperties::CreateObjectSpecificItemSet(SfxItemPool& rPool)
34         {
35             // Groups have in principle no ItemSet. To support methods like
36             // GetMergedItemSet() the local one is used. Thus, all items in the pool
37             // may be used and a pool itemset is created.
38             return SfxItemSet(rPool);
39         }
40 
GroupProperties(SdrObject & rObj)41         GroupProperties::GroupProperties(SdrObject& rObj)
42         :   DefaultProperties(rObj)
43         {
44         }
45 
GroupProperties(const GroupProperties & rProps,SdrObject & rObj)46         GroupProperties::GroupProperties(const GroupProperties& rProps, SdrObject& rObj)
47         :   DefaultProperties(rProps, rObj)
48         {
49         }
50 
~GroupProperties()51         GroupProperties::~GroupProperties()
52         {
53         }
54 
Clone(SdrObject & rObj) const55         std::unique_ptr<BaseProperties> GroupProperties::Clone(SdrObject& rObj) const
56         {
57             return std::unique_ptr<BaseProperties>(new GroupProperties(*this, rObj));
58         }
59 
GetObjectItemSet() const60         const SfxItemSet& GroupProperties::GetObjectItemSet() const
61         {
62             assert(!"GroupProperties::GetObjectItemSet() should never be called");
63             return DefaultProperties::GetObjectItemSet();
64         }
65 
GetMergedItemSet() const66         const SfxItemSet& GroupProperties::GetMergedItemSet() const
67         {
68             // prepare ItemSet
69             if(mxItemSet)
70             {
71                 // clear local itemset for merge
72                 mxItemSet->ClearItem();
73             }
74             else
75             {
76                 // force local itemset
77                 DefaultProperties::GetObjectItemSet();
78             }
79 
80             // collect all ItemSets in mpItemSet
81             const SdrObjList* pSub(static_cast<const SdrObjGroup&>(GetSdrObject()).GetSubList());
82             OSL_ENSURE(nullptr != pSub, "Children of SdrObject expected (!)");
83             const size_t nCount(nullptr == pSub ? 0 : pSub->GetObjCount());
84 
85             for(size_t a = 0; a < nCount; ++a)
86             {
87                 const SfxItemSet& rSet = pSub->GetObj(a)->GetMergedItemSet();
88                 SfxWhichIter aIter(rSet);
89                 sal_uInt16 nWhich(aIter.FirstWhich());
90 
91                 while(nWhich)
92                 {
93                     if(SfxItemState::DONTCARE == rSet.GetItemState(nWhich, false))
94                     {
95                         mxItemSet->InvalidateItem(nWhich);
96                     }
97                     else
98                     {
99                         mxItemSet->MergeValue(rSet.Get(nWhich), true);
100                     }
101 
102                     nWhich = aIter.NextWhich();
103                 }
104             }
105 
106             // For group properties, do not call parent since groups do
107             // not have local ItemSets.
108             return *mxItemSet;
109         }
110 
SetMergedItemSet(const SfxItemSet & rSet,bool bClearAllItems)111         void GroupProperties::SetMergedItemSet(const SfxItemSet& rSet, bool bClearAllItems)
112         {
113             // iterate over contained SdrObjects
114             const SdrObjList* pSub(static_cast<const SdrObjGroup&>(GetSdrObject()).GetSubList());
115             OSL_ENSURE(nullptr != pSub, "Children of SdrObject expected (!)");
116             const size_t nCount(nullptr == pSub ? 0 : pSub->GetObjCount());
117 
118             for(size_t a = 0; a < nCount; ++a)
119             {
120                 SdrObject* pObj = pSub->GetObj(a);
121 
122                 if(pObj)
123                 {
124                     // Set merged ItemSet at contained object
125                     pObj->SetMergedItemSet(rSet, bClearAllItems);
126                 }
127             }
128 
129             // Do not call parent here. Group objects do not have local ItemSets
130             // where items need to be set.
131             // DefaultProperties::SetMergedItemSet(rSet, bClearAllItems);
132         }
133 
SetObjectItem(const SfxPoolItem &)134         void GroupProperties::SetObjectItem(const SfxPoolItem& /*rItem*/)
135         {
136             assert(!"GroupProperties::SetObjectItem() should never be called");
137         }
138 
SetObjectItemDirect(const SfxPoolItem &)139         void GroupProperties::SetObjectItemDirect(const SfxPoolItem& /*rItem*/)
140         {
141             assert(!"GroupProperties::SetObjectItemDirect() should never be called");
142         }
143 
ClearObjectItem(const sal_uInt16 nWhich)144         void GroupProperties::ClearObjectItem(const sal_uInt16 nWhich)
145         {
146             // iterate over contained SdrObjects
147             const SdrObjList* pSub(static_cast<const SdrObjGroup&>(GetSdrObject()).GetSubList());
148             OSL_ENSURE(nullptr != pSub, "Children of SdrObject expected (!)");
149             const size_t nCount(nullptr == pSub ? 0 : pSub->GetObjCount());
150 
151             for(size_t a = 0; a < nCount; ++a)
152             {
153                 SdrObject* pObj = pSub->GetObj(a);
154 
155                 if(pObj)
156                 {
157                     pObj->GetProperties().ClearObjectItem(nWhich);
158                 }
159             }
160         }
161 
ClearObjectItemDirect(const sal_uInt16)162         void GroupProperties::ClearObjectItemDirect(const sal_uInt16 /*nWhich*/)
163         {
164             assert(!"GroupProperties::ClearObjectItemDirect() should never be called");
165         }
166 
SetMergedItem(const SfxPoolItem & rItem)167         void GroupProperties::SetMergedItem(const SfxPoolItem& rItem)
168         {
169             const SdrObjList* pSub(static_cast<const SdrObjGroup&>(GetSdrObject()).GetSubList());
170             OSL_ENSURE(nullptr != pSub, "Children of SdrObject expected (!)");
171             const size_t nCount(nullptr == pSub ? 0 : pSub->GetObjCount());
172 
173             for(size_t a = 0; a < nCount; ++a)
174             {
175                 pSub->GetObj(a)->GetProperties().SetMergedItem(rItem);
176             }
177         }
178 
ClearMergedItem(const sal_uInt16 nWhich)179         void GroupProperties::ClearMergedItem(const sal_uInt16 nWhich)
180         {
181             const SdrObjList* pSub(static_cast<const SdrObjGroup&>(GetSdrObject()).GetSubList());
182             OSL_ENSURE(nullptr != pSub, "Children of SdrObject expected (!)");
183             const size_t nCount(nullptr == pSub ? 0 : pSub->GetObjCount());
184 
185             for(size_t a = 0; a < nCount; ++a)
186             {
187                 pSub->GetObj(a)->GetProperties().ClearMergedItem(nWhich);
188             }
189         }
190 
SetObjectItemSet(const SfxItemSet &)191         void GroupProperties::SetObjectItemSet(const SfxItemSet& /*rSet*/)
192         {
193             assert(!"GroupProperties::SetObjectItemSet() should never be called");
194         }
195 
ItemSetChanged(const SfxItemSet &)196         void GroupProperties::ItemSetChanged(const SfxItemSet& /*rSet*/)
197         {
198             assert(!"GroupProperties::ItemSetChanged() should never be called");
199         }
200 
AllowItemChange(const sal_uInt16,const SfxPoolItem *) const201         bool GroupProperties::AllowItemChange(const sal_uInt16 /*nWhich*/, const SfxPoolItem* /*pNewItem*/) const
202         {
203             assert(!"GroupProperties::AllowItemChange() should never be called");
204             return false;
205         }
206 
ItemChange(const sal_uInt16,const SfxPoolItem *)207         void GroupProperties::ItemChange(const sal_uInt16 /*nWhich*/, const SfxPoolItem* /*pNewItem*/)
208         {
209             assert(!"GroupProperties::ItemChange() should never be called");
210         }
211 
PostItemChange(const sal_uInt16)212         void GroupProperties::PostItemChange(const sal_uInt16 /*nWhich*/)
213         {
214             assert(!"GroupProperties::PostItemChange() should never be called");
215         }
216 
GetStyleSheet() const217         SfxStyleSheet* GroupProperties::GetStyleSheet() const
218         {
219             SfxStyleSheet* pRetval = nullptr;
220 
221             const SdrObjList* pSub(static_cast<const SdrObjGroup&>(GetSdrObject()).GetSubList());
222             OSL_ENSURE(nullptr != pSub, "Children of SdrObject expected (!)");
223             const size_t nCount(nullptr == pSub ? 0 : pSub->GetObjCount());
224 
225             for(size_t a = 0; a < nCount; ++a)
226             {
227                 SfxStyleSheet* pCandidate = pSub->GetObj(a)->GetStyleSheet();
228 
229                 if(pRetval)
230                 {
231                     if(pCandidate != pRetval)
232                     {
233                         // different StyleSheelts, return none
234                         return nullptr;
235                     }
236                 }
237                 else
238                 {
239                     pRetval = pCandidate;
240                 }
241             }
242 
243             return pRetval;
244         }
245 
SetStyleSheet(SfxStyleSheet * pNewStyleSheet,bool bDontRemoveHardAttr)246         void GroupProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, bool bDontRemoveHardAttr)
247         {
248             const SdrObjList* pSub(static_cast<const SdrObjGroup&>(GetSdrObject()).GetSubList());
249             OSL_ENSURE(nullptr != pSub, "Children of SdrObject expected (!)");
250             const size_t nCount(nullptr == pSub ? 0 : pSub->GetObjCount());
251 
252             for(size_t a = 0; a < nCount; ++a)
253             {
254                 pSub->GetObj(a)->SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
255             }
256         }
257 
ForceDefaultAttributes()258         void GroupProperties::ForceDefaultAttributes()
259         {
260             // nothing to do here, groups have no items and thus no default items, too.
261         }
262 
ForceStyleToHardAttributes()263         void GroupProperties::ForceStyleToHardAttributes()
264         {
265             const SdrObjList* pSub(static_cast<const SdrObjGroup&>(GetSdrObject()).GetSubList());
266             OSL_ENSURE(nullptr != pSub, "Children of SdrObject expected (!)");
267             const size_t nCount(nullptr == pSub ? 0 : pSub->GetObjCount());
268 
269             for(size_t a = 0; a < nCount; ++a)
270             {
271                 pSub->GetObj(a)->GetProperties().ForceStyleToHardAttributes();
272             }
273         }
274 } // end of namespace
275 
276 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
277