1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26 #include <svx/sdr/properties/e3dsceneproperties.hxx>
27 #include <svl/itemset.hxx>
28 #include <svl/whiter.hxx>
29 #include <svx/svddef.hxx>
30 #include <svx/scene3d.hxx>
31 #include <svx/svditer.hxx>
32 
33 //////////////////////////////////////////////////////////////////////////////
34 
35 namespace sdr
36 {
37 	namespace properties
38 	{
E3dSceneProperties(SdrObject & rObj)39 		E3dSceneProperties::E3dSceneProperties(SdrObject& rObj)
40 		:	E3dProperties(rObj)
41 		{
42 		}
43 
E3dSceneProperties(const E3dSceneProperties & rProps,SdrObject & rObj)44 		E3dSceneProperties::E3dSceneProperties(const E3dSceneProperties& rProps, SdrObject& rObj)
45 		:	E3dProperties(rProps, rObj)
46 		{
47 		}
48 
~E3dSceneProperties()49 		E3dSceneProperties::~E3dSceneProperties()
50 		{
51 		}
52 
Clone(SdrObject & rObj) const53 		BaseProperties& E3dSceneProperties::Clone(SdrObject& rObj) const
54 		{
55 			return *(new E3dSceneProperties(*this, rObj));
56 		}
57 
GetObjectItemSet() const58 		const SfxItemSet& E3dSceneProperties::GetObjectItemSet() const
59 		{
60 			//DBG_ASSERT(sal_False, "E3dSceneProperties::GetObjectItemSet() maybe the wrong call (!)");
61 			return E3dProperties::GetObjectItemSet();
62 		}
63 
GetMergedItemSet() const64 		const SfxItemSet& E3dSceneProperties::GetMergedItemSet() const
65 		{
66 			// prepare ItemSet
67 			if(mpItemSet)
68 			{
69 				// filter for SDRATTR_3DSCENE_ items, only keep those items
70 				SfxItemSet aNew(*mpItemSet->GetPool(), SDRATTR_3DSCENE_FIRST, SDRATTR_3DSCENE_LAST);
71 				aNew.Put(*mpItemSet);
72 				mpItemSet->ClearItem();
73 				mpItemSet->Put(aNew);
74 			}
75 			else
76 			{
77 				// No ItemSet yet, force local ItemSet
78 				GetObjectItemSet();
79 			}
80 
81 			// collect all ItemSets of contained 3d objects
82 			const SdrObjList* pSub = ((const E3dScene&)GetSdrObject()).GetSubList();
83 			const sal_uInt32 nCount(pSub->GetObjCount());
84 
85 			for(sal_uInt32 a(0L); a < nCount; a++)
86 			{
87 				SdrObject* pObj = pSub->GetObj(a);
88 
89 				if(pObj && pObj->ISA(E3dCompoundObject))
90 				{
91 					const SfxItemSet& rSet = pObj->GetMergedItemSet();
92 					SfxWhichIter aIter(rSet);
93 					sal_uInt16 nWhich(aIter.FirstWhich());
94 
95 					while(nWhich)
96 					{
97 						// Leave out the SDRATTR_3DSCENE_ range, this would only be double
98 						// and always equal.
99 						if(nWhich <= SDRATTR_3DSCENE_FIRST || nWhich >= SDRATTR_3DSCENE_LAST)
100 						{
101 							if(SFX_ITEM_DONTCARE == rSet.GetItemState(nWhich, sal_False))
102 							{
103 								mpItemSet->InvalidateItem(nWhich);
104 							}
105 							else
106 							{
107 								mpItemSet->MergeValue(rSet.Get(nWhich), sal_True);
108 							}
109 						}
110 
111 						nWhich = aIter.NextWhich();
112 					}
113 				}
114 			}
115 
116 			// call parent
117 			return E3dProperties::GetMergedItemSet();
118 		}
119 
SetMergedItemSet(const SfxItemSet & rSet,sal_Bool bClearAllItems)120 		void E3dSceneProperties::SetMergedItemSet(const SfxItemSet& rSet, sal_Bool bClearAllItems)
121 		{
122 			// Set SDRATTR_3DOBJ_ range at contained objects.
123 			const SdrObjList* pSub = ((const E3dScene&)GetSdrObject()).GetSubList();
124 			const sal_uInt32 nCount(pSub->GetObjCount());
125 
126 			if(nCount)
127 			{
128 				// Generate filtered ItemSet which contains all but the SDRATTR_3DSCENE items.
129 				// #i50808# Leak fix, Clone produces a new instance and we get ownership here
130 				SfxItemSet* pNewSet = rSet.Clone(sal_True);
131 				DBG_ASSERT(pNewSet, "E3dSceneProperties::SetMergedItemSet(): Could not clone ItemSet (!)");
132 
133 				for(sal_uInt16 b(SDRATTR_3DSCENE_FIRST); b <= SDRATTR_3DSCENE_LAST; b++)
134 				{
135 					pNewSet->ClearItem(b);
136 				}
137 
138 				if(pNewSet->Count())
139 				{
140 					for(sal_uInt32 a(0L); a < nCount; a++)
141 					{
142 						SdrObject* pObj = pSub->GetObj(a);
143 
144 						if(pObj && pObj->ISA(E3dCompoundObject))
145 						{
146 							// set merged ItemSet at contained 3d object.
147 							pObj->SetMergedItemSet(*pNewSet, bClearAllItems);
148 						}
149 					}
150 				}
151 
152 				delete pNewSet;
153 			}
154 
155 			// call parent. This will set items on local object, too.
156 			E3dProperties::SetMergedItemSet(rSet, bClearAllItems);
157 		}
158 
SetMergedItem(const SfxPoolItem & rItem)159 		void E3dSceneProperties::SetMergedItem(const SfxPoolItem& rItem)
160 		{
161 			const SdrObjList* pSub = ((const E3dScene&)GetSdrObject()).GetSubList();
162 			const sal_uInt32 nCount(pSub->GetObjCount());
163 
164 			for(sal_uInt32 a(0L); a < nCount; a++)
165 			{
166 				pSub->GetObj(a)->SetMergedItem(rItem);
167 			}
168 
169 			// #i43809# call parent. This will set items on local object, too.
170 			E3dProperties::SetMergedItem(rItem);
171 		}
172 
ClearMergedItem(const sal_uInt16 nWhich)173 		void E3dSceneProperties::ClearMergedItem(const sal_uInt16 nWhich)
174 		{
175 			const SdrObjList* pSub = ((const E3dScene&)GetSdrObject()).GetSubList();
176 			const sal_uInt32 nCount(pSub->GetObjCount());
177 
178 			for(sal_uInt32 a(0L); a < nCount; a++)
179 			{
180 				pSub->GetObj(a)->ClearMergedItem(nWhich);
181 			}
182 
183 			// #i43809# call parent. This will clear items on local object, too.
184 			E3dProperties::ClearMergedItem(nWhich);
185 		}
186 
PostItemChange(const sal_uInt16 nWhich)187 		void E3dSceneProperties::PostItemChange(const sal_uInt16 nWhich)
188 		{
189 			// call parent
190 			E3dProperties::PostItemChange(nWhich);
191 
192 			// local changes
193 			E3dScene& rObj = (E3dScene&)GetSdrObject();
194 			rObj.StructureChanged();
195 
196 			switch(nWhich)
197 			{
198 				case SDRATTR_3DSCENE_PERSPECTIVE			:
199 				case SDRATTR_3DSCENE_DISTANCE				:
200 				case SDRATTR_3DSCENE_FOCAL_LENGTH			:
201 				{
202 					// #83387#, #83391#
203 					// one common function for the camera attributes
204 					// since SetCamera() sets all three back to the ItemSet
205 					Camera3D aSceneCam(rObj.GetCamera());
206 					sal_Bool bChange(sal_False);
207 
208 					// for SDRATTR_3DSCENE_PERSPECTIVE:
209 					if(aSceneCam.GetProjection() != rObj.GetPerspective())
210 					{
211 						aSceneCam.SetProjection(rObj.GetPerspective());
212 						bChange = sal_True;
213 					}
214 
215 					// for SDRATTR_3DSCENE_DISTANCE:
216 					basegfx::B3DPoint aActualPosition(aSceneCam.GetPosition());
217 					double fNew = rObj.GetDistance();
218 
219 					if(fNew != aActualPosition.getZ())
220 					{
221 						aSceneCam.SetPosition(basegfx::B3DPoint(aActualPosition.getX(), aActualPosition.getY(), fNew));
222 						bChange = sal_True;
223 					}
224 
225 					// for SDRATTR_3DSCENE_FOCAL_LENGTH:
226 					fNew = rObj.GetFocalLength() / 100.0;
227 
228 					if(aSceneCam.GetFocalLength() != fNew)
229 					{
230 						aSceneCam.SetFocalLength(fNew);
231 						bChange = sal_True;
232 					}
233 
234 					// for all
235 					if(bChange)
236 					{
237 						rObj.SetCamera(aSceneCam);
238 					}
239 
240 					break;
241 				}
242 			}
243 		}
244 
SetStyleSheet(SfxStyleSheet * pNewStyleSheet,sal_Bool bDontRemoveHardAttr)245 		void E3dSceneProperties::SetStyleSheet(SfxStyleSheet* pNewStyleSheet, sal_Bool bDontRemoveHardAttr)
246 		{
247 			const SdrObjList* pSub = ((const E3dScene&)GetSdrObject()).GetSubList();
248 			const sal_uInt32 nCount(pSub->GetObjCount());
249 
250 			for(sal_uInt32 a(0L); a < nCount; a++)
251 			{
252 				pSub->GetObj(a)->SetStyleSheet(pNewStyleSheet, bDontRemoveHardAttr);
253 			}
254 		}
255 
GetStyleSheet() const256 		SfxStyleSheet* E3dSceneProperties::GetStyleSheet() const
257 		{
258 			SfxStyleSheet* pRetval = 0L;
259 
260 			const SdrObjList* pSub = ((const E3dScene&)GetSdrObject()).GetSubList();
261 			const sal_uInt32 nCount(pSub->GetObjCount());
262 
263 			for(sal_uInt32 a(0L); a < nCount; a++)
264 			{
265 				SfxStyleSheet* pCandidate = pSub->GetObj(a)->GetStyleSheet();
266 
267 				if(pRetval)
268 				{
269 					if(pCandidate != pRetval)
270 					{
271 						// different StyleSheelts, return none
272 						return 0L;
273 					}
274 				}
275 				else
276 				{
277 					pRetval = pCandidate;
278 				}
279 			}
280 
281 			return pRetval;
282 		}
283 
MoveToItemPool(SfxItemPool * pSrcPool,SfxItemPool * pDestPool,SdrModel * pNewModel)284 		void E3dSceneProperties::MoveToItemPool(SfxItemPool* pSrcPool, SfxItemPool* pDestPool, SdrModel* pNewModel)
285 		{
286 			if(pSrcPool && pDestPool && (pSrcPool != pDestPool))
287 			{
288 				// call parent
289 				E3dProperties::MoveToItemPool(pSrcPool, pDestPool, pNewModel);
290 
291 				// own reaction, but only with outmost scene
292 				E3dScene& rObj = (E3dScene&)GetSdrObject();
293 				const SdrObjList* pSubList = rObj.GetSubList();
294 
295 				if(pSubList && rObj.GetScene() == &rObj)
296 				{
297 					SdrObjListIter a3DIterator(*pSubList, IM_DEEPWITHGROUPS);
298 
299 					while(a3DIterator.IsMore())
300 					{
301 						E3dObject* pObj = (E3dObject*)a3DIterator.Next();
302 						DBG_ASSERT(pObj->ISA(E3dObject), "In scenes there are only 3D objects allowed (!)");
303 						pObj->GetProperties().MoveToItemPool(pSrcPool, pDestPool, pNewModel);
304 					}
305 				}
306 			}
307 		}
308 
SetSceneItemsFromCamera()309 		void E3dSceneProperties::SetSceneItemsFromCamera()
310 		{
311 			// force ItemSet
312 			GetObjectItemSet();
313 
314 			E3dScene& rObj = (E3dScene&)GetSdrObject();
315 			Camera3D aSceneCam(rObj.GetCamera());
316 
317 			// ProjectionType
318 			mpItemSet->Put(Svx3DPerspectiveItem((sal_uInt16)aSceneCam.GetProjection()));
319 
320 			// CamPos
321 			mpItemSet->Put(Svx3DDistanceItem((sal_uInt32)(aSceneCam.GetPosition().getZ() + 0.5)));
322 
323 			// FocalLength
324 			mpItemSet->Put(Svx3DFocalLengthItem((sal_uInt32)((aSceneCam.GetFocalLength() * 100.0) + 0.5)));
325 		}
326 	} // end of namespace properties
327 } // end of namespace sdr
328 
329 //////////////////////////////////////////////////////////////////////////////
330 // eof
331