xref: /trunk/main/svx/source/svdraw/svdogrp.cxx (revision 35252cc9)
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 <sfx2/linkmgr.hxx>
27 
28 #include <ucbhelper/content.hxx>
29 #include <ucbhelper/contentbroker.hxx>
30 #include <unotools/datetime.hxx>
31 
32 #include <svx/svdogrp.hxx>
33 
34 #include <sfx2/lnkbase.hxx>
35 #include <tools/urlobj.hxx>
36 
37 #include <svl/urihelper.hxx>
38 
39 #include <svx/xpool.hxx>
40 #include <svx/xpoly.hxx>
41 
42 #include <svx/svdmodel.hxx>
43 #include <svx/svdpage.hxx>
44 #include "svx/svditer.hxx"
45 #include <svx/svdobj.hxx>
46 #include <svx/svdtrans.hxx>
47 #include <svx/svdetc.hxx>
48 #include <svx/svdattrx.hxx>  // NotPersistItems
49 #include <svx/svdoedge.hxx>  // #32383# Die Verbinder nach Move nochmal anbroadcasten
50 #include "svx/svdglob.hxx"   // StringCache
51 #include "svx/svdstr.hrc"    // Objektname
52 
53 #include <svx/svxids.hrc>
54 #include <svl/whiter.hxx>
55 #include <svx/svdpool.hxx>
56 #include <svx/sdr/properties/groupproperties.hxx>
57 
58 // #110094#
59 #include <svx/sdr/contact/viewcontactofgroup.hxx>
60 #include <basegfx/range/b2drange.hxx>
61 #include <basegfx/polygon/b2dpolygontools.hxx>
62 #include <basegfx/polygon/b2dpolygon.hxx>
63 
64 ////////////////////////////////////////////////////////////////////////////////////////////////////
65 //
66 //   @@@@  @@@@@  @@@@@@   @@@@  @@@@@   @@@@  @@  @@ @@@@@
67 //  @@  @@ @@  @@     @@  @@     @@  @@ @@  @@ @@  @@ @@  @@
68 //  @@  @@ @@@@@      @@  @@ @@@ @@@@@  @@  @@ @@  @@ @@@@@
69 //  @@  @@ @@  @@ @@  @@  @@  @@ @@  @@ @@  @@ @@  @@ @@
70 //   @@@@  @@@@@   @@@@    @@@@@ @@  @@  @@@@   @@@@  @@
71 //
72 ////////////////////////////////////////////////////////////////////////////////////////////////////
73 
74 //////////////////////////////////////////////////////////////////////////////
75 // BaseProperties section
76 
CreateObjectSpecificProperties()77 sdr::properties::BaseProperties* SdrObjGroup::CreateObjectSpecificProperties()
78 {
79 	return new sdr::properties::GroupProperties(*this);
80 }
81 
82 //////////////////////////////////////////////////////////////////////////////
83 // #110094# DrawContact section
84 
CreateObjectSpecificViewContact()85 sdr::contact::ViewContact* SdrObjGroup::CreateObjectSpecificViewContact()
86 {
87 	return new sdr::contact::ViewContactOfGroup(*this);
88 }
89 
90 //////////////////////////////////////////////////////////////////////////////
91 
92 TYPEINIT1(SdrObjGroup,SdrObject);
93 
SdrObjGroup()94 SdrObjGroup::SdrObjGroup()
95 {
96 	pSub=new SdrObjList(NULL,NULL);
97 	pSub->SetOwnerObj(this);
98 	pSub->SetListKind(SDROBJLIST_GROUPOBJ);
99 	bRefPoint=sal_False;
100 	bClosedObj=sal_False;
101 }
102 
103 
~SdrObjGroup()104 SdrObjGroup::~SdrObjGroup()
105 {
106 	delete pSub;
107 }
108 
TakeObjInfo(SdrObjTransformInfoRec & rInfo) const109 void SdrObjGroup::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
110 {
111 	rInfo.bNoContortion=sal_False;
112 	SdrObjList* pOL=pSub;
113 	sal_uIntPtr nObjAnz=pOL->GetObjCount();
114 	for (sal_uIntPtr i=0; i<nObjAnz; i++) {
115 		SdrObject* pObj=pOL->GetObj(i);
116 		SdrObjTransformInfoRec aInfo;
117 		pObj->TakeObjInfo(aInfo);
118 		if (!aInfo.bMoveAllowed            ) rInfo.bMoveAllowed            =sal_False;
119 		if (!aInfo.bResizeFreeAllowed      ) rInfo.bResizeFreeAllowed      =sal_False;
120 		if (!aInfo.bResizePropAllowed      ) rInfo.bResizePropAllowed      =sal_False;
121 		if (!aInfo.bRotateFreeAllowed      ) rInfo.bRotateFreeAllowed      =sal_False;
122 		if (!aInfo.bRotate90Allowed        ) rInfo.bRotate90Allowed        =sal_False;
123 		if (!aInfo.bMirrorFreeAllowed      ) rInfo.bMirrorFreeAllowed      =sal_False;
124 		if (!aInfo.bMirror45Allowed        ) rInfo.bMirror45Allowed        =sal_False;
125 		if (!aInfo.bMirror90Allowed        ) rInfo.bMirror90Allowed        =sal_False;
126 		if (!aInfo.bShearAllowed           ) rInfo.bShearAllowed           =sal_False;
127 		if (!aInfo.bEdgeRadiusAllowed	   ) rInfo.bEdgeRadiusAllowed	   =sal_False;
128 		if (!aInfo.bNoOrthoDesired         ) rInfo.bNoOrthoDesired         =sal_False;
129 		if (aInfo.bNoContortion            ) rInfo.bNoContortion           =sal_True;
130 		if (!aInfo.bCanConvToPath          ) rInfo.bCanConvToPath          =sal_False;
131 
132 		if(!aInfo.bCanConvToContour)
133 			rInfo.bCanConvToContour = sal_False;
134 
135 		if (!aInfo.bCanConvToPoly          ) rInfo.bCanConvToPoly          =sal_False;
136 		if (!aInfo.bCanConvToPathLineToArea) rInfo.bCanConvToPathLineToArea=sal_False;
137 		if (!aInfo.bCanConvToPolyLineToArea) rInfo.bCanConvToPolyLineToArea=sal_False;
138 	}
139 	if (nObjAnz==0) {
140 		rInfo.bRotateFreeAllowed=sal_False;
141 		rInfo.bRotate90Allowed  =sal_False;
142 		rInfo.bMirrorFreeAllowed=sal_False;
143 		rInfo.bMirror45Allowed  =sal_False;
144 		rInfo.bMirror90Allowed  =sal_False;
145 		rInfo.bTransparenceAllowed = sal_False;
146 		rInfo.bGradientAllowed = sal_False;
147 		rInfo.bShearAllowed     =sal_False;
148 		rInfo.bEdgeRadiusAllowed=sal_False;
149 		rInfo.bNoContortion     =sal_True;
150 	}
151 	if(nObjAnz != 1)
152 	{
153 		// only allowed if single object selected
154 		rInfo.bTransparenceAllowed = sal_False;
155 		rInfo.bGradientAllowed = sal_False;
156 	}
157 }
158 
159 
SetBoundRectDirty()160 void SdrObjGroup::SetBoundRectDirty()
161 {
162     // avoid resetting aOutRect which in case of this object is model data,
163     // not re-creatable view data
164 }
165 
GetObjIdentifier() const166 sal_uInt16 SdrObjGroup::GetObjIdentifier() const
167 {
168 	return sal_uInt16(OBJ_GRUP);
169 }
170 
171 
GetLayer() const172 SdrLayerID SdrObjGroup::GetLayer() const
173 {
174 	FASTBOOL b1st=sal_True;
175 	SdrLayerID nLay=SdrLayerID(SdrObject::GetLayer());
176 	SdrObjList* pOL=pSub;
177 	sal_uIntPtr nObjAnz=pOL->GetObjCount();
178 	for (sal_uIntPtr i=0; i<nObjAnz; i++) {
179 		SdrLayerID nLay1=pOL->GetObj(i)->GetLayer();
180 		if (b1st) { nLay=nLay1; b1st=sal_False; }
181 		else if (nLay1!=nLay) return 0;
182 	}
183 	return nLay;
184 }
185 
186 
NbcSetLayer(SdrLayerID nLayer)187 void SdrObjGroup::NbcSetLayer(SdrLayerID nLayer)
188 {
189 	SdrObject::NbcSetLayer(nLayer);
190 	SdrObjList* pOL=pSub;
191 	sal_uIntPtr nObjAnz=pOL->GetObjCount();
192 	for (sal_uIntPtr i=0; i<nObjAnz; i++) {
193 		pOL->GetObj(i)->NbcSetLayer(nLayer);
194 	}
195 }
196 
197 
SetObjList(SdrObjList * pNewObjList)198 void SdrObjGroup::SetObjList(SdrObjList* pNewObjList)
199 {
200 	SdrObject::SetObjList(pNewObjList);
201 	pSub->SetUpList(pNewObjList);
202 }
203 
204 
SetPage(SdrPage * pNewPage)205 void SdrObjGroup::SetPage(SdrPage* pNewPage)
206 {
207 	SdrObject::SetPage(pNewPage);
208 	pSub->SetPage(pNewPage);
209 }
210 
211 
SetModel(SdrModel * pNewModel)212 void SdrObjGroup::SetModel(SdrModel* pNewModel)
213 {
214 	if(pNewModel!=pModel)
215 	{
216 		// #i30648#
217 		// This method also needs to migrate the used ItemSet
218 		// when the destination model uses a different pool
219 		// than the current one. Else it is possible to create
220 		// SdrObjGroups which reference the old pool which might
221 		// be destroyed (as the bug shows).
222 		SdrModel* pOldModel = pModel;
223 
224 		// test for correct pool in ItemSet; move to new pool if necessary
225 		if(pNewModel && GetObjectItemPool() && GetObjectItemPool() != &pNewModel->GetItemPool())
226 		{
227 			MigrateItemPool(GetObjectItemPool(), &pNewModel->GetItemPool(), pNewModel);
228 		}
229 
230 		// call parent
231 		SdrObject::SetModel(pNewModel);
232 
233 		// set new model at content
234 		pSub->SetModel(pNewModel);
235 
236 		// modify properties
237 		GetProperties().SetModel(pOldModel, pNewModel);
238 	}
239 }
240 
241 
HasRefPoint() const242 FASTBOOL SdrObjGroup::HasRefPoint() const
243 {
244 	return bRefPoint;
245 }
246 
247 
GetRefPoint() const248 Point SdrObjGroup::GetRefPoint() const
249 {
250 	return aRefPoint;
251 }
252 
253 
SetRefPoint(const Point & rPnt)254 void SdrObjGroup::SetRefPoint(const Point& rPnt)
255 {
256 	bRefPoint=sal_True;
257 	aRefPoint=rPnt;
258 }
259 
260 
GetSubList() const261 SdrObjList* SdrObjGroup::GetSubList() const
262 {
263 	return pSub;
264 }
265 
GetCurrentBoundRect() const266 const Rectangle& SdrObjGroup::GetCurrentBoundRect() const
267 {
268     // --> OD 2007-02-01 #144962#
269     // <aOutRect> has to contain the bounding rectangle
270     if ( pSub->GetObjCount()!=0 )
271     {
272         const_cast<SdrObjGroup*>(this)->aOutRect = pSub->GetAllObjBoundRect();
273     }
274 
275     return aOutRect;
276     // <--
277 }
278 
GetSnapRect() const279 const Rectangle& SdrObjGroup::GetSnapRect() const
280 {
281     // --> OD 2007-02-01 #144962#
282     // <aOutRect> has to contain the bounding rectangle
283     if ( pSub->GetObjCount()!=0 )
284     {
285         return pSub->GetAllObjSnapRect();
286     }
287     else
288     {
289         return aOutRect;
290     }
291     // <--
292 }
293 
operator =(const SdrObject & rObj)294 void SdrObjGroup::operator=(const SdrObject& rObj)
295 {
296 	if(rObj.IsGroupObject())
297 	{
298 		// copy SdrObject stuff
299 		SdrObject::operator=(rObj);
300 
301 		// #i36404#
302 		// copy SubList, init model and page first
303 		SdrObjList& rSourceSubList = *rObj.GetSubList();
304 		pSub->SetPage(rSourceSubList.GetPage());
305 		pSub->SetModel(rSourceSubList.GetModel());
306 		pSub->CopyObjects(*rObj.GetSubList());
307 
308 		// copy local paremeters
309 		aRefPoint  =((SdrObjGroup&)rObj).aRefPoint;
310 		bRefPoint  =((SdrObjGroup&)rObj).bRefPoint;
311 	}
312 }
313 
314 
TakeObjNameSingul(XubString & rName) const315 void SdrObjGroup::TakeObjNameSingul(XubString& rName) const
316 {
317 	if(!pSub->GetObjCount())
318 	{
319 		rName = ImpGetResStr(STR_ObjNameSingulGRUPEMPTY);
320 	}
321 	else
322 	{
323 		rName = ImpGetResStr(STR_ObjNameSingulGRUP);
324 	}
325 
326 	const String aName(GetName());
327 
328 	if(aName.Len())
329 	{
330 		rName += sal_Unicode(' ');
331 		rName += sal_Unicode('\'');
332 		rName += aName;
333 		rName += sal_Unicode('\'');
334 	}
335 }
336 
337 
TakeObjNamePlural(XubString & rName) const338 void SdrObjGroup::TakeObjNamePlural(XubString& rName) const
339 {
340 	if (pSub->GetObjCount()==0) {
341 		rName=ImpGetResStr(STR_ObjNamePluralGRUPEMPTY);
342 	} else {
343 		rName=ImpGetResStr(STR_ObjNamePluralGRUP);
344 	}
345 }
346 
347 
RecalcSnapRect()348 void SdrObjGroup::RecalcSnapRect()
349 {
350 	// nicht erforderlich, da die Rects von der SubList verwendet werden.
351 }
352 
TakeXorPoly() const353 basegfx::B2DPolyPolygon SdrObjGroup::TakeXorPoly() const
354 {
355 	basegfx::B2DPolyPolygon aRetval;
356 	const sal_uInt32 nObjCount(pSub->GetObjCount());
357 
358 	for(sal_uInt32 a(0L); a < nObjCount; a++)
359 	{
360 		SdrObject* pObj = pSub->GetObj(a);
361 		aRetval.append(pObj->TakeXorPoly());
362 	}
363 
364 	if(!aRetval.count())
365 	{
366 		const basegfx::B2DRange aRange(aOutRect.Left(), aOutRect.Top(), aOutRect.Right(), aOutRect.Bottom());
367 		aRetval.append(basegfx::tools::createPolygonFromRect(aRange));
368 	}
369 
370 	return aRetval;
371 }
372 
beginSpecialDrag(SdrDragStat &) const373 bool SdrObjGroup::beginSpecialDrag(SdrDragStat& /*rDrag*/) const
374 {
375 	return false;
376 }
377 
378 
BegCreate(SdrDragStat &)379 FASTBOOL SdrObjGroup::BegCreate(SdrDragStat& /*rStat*/)
380 {
381 	return sal_False;
382 }
383 
384 
GetRotateAngle() const385 long SdrObjGroup::GetRotateAngle() const
386 {
387     const sal_uInt32 nObjCount(pSub->GetObjCount());
388     long nRetval(0);
389 
390     if(nObjCount)
391     {
392         SdrObject* pObj = pSub->GetObj(0);
393 
394         nRetval = pObj->GetRotateAngle();
395     }
396 
397     return nRetval;
398 }
399 
400 
GetShearAngle(FASTBOOL) const401 long SdrObjGroup::GetShearAngle(FASTBOOL /*bVertical*/) const
402 {
403     const sal_uInt32 nObjCount(pSub->GetObjCount());
404     long nRetval(0);
405 
406     if(nObjCount)
407     {
408         SdrObject* pObj = pSub->GetObj(0);
409 
410         nRetval = pObj->GetShearAngle();
411     }
412 
413     return nRetval;
414 }
415 
416 
NbcSetSnapRect(const Rectangle & rRect)417 void SdrObjGroup::NbcSetSnapRect(const Rectangle& rRect)
418 {
419 	Rectangle aOld(GetSnapRect());
420 	long nMulX=rRect.Right()-rRect.Left();
421 	long nDivX=aOld.Right()-aOld.Left();
422 	long nMulY=rRect.Bottom()-rRect.Top();
423 	long nDivY=aOld.Bottom()-aOld.Top();
424 	if (nDivX==0) { nMulX=1; nDivX=1; }
425 	if (nDivY==0) { nMulY=1; nDivY=1; }
426 	if (nMulX!=nDivX || nMulY!=nDivY) {
427 		Fraction aX(nMulX,nDivX);
428 		Fraction aY(nMulY,nDivY);
429 		NbcResize(aOld.TopLeft(),aX,aY);
430 	}
431 	if (rRect.Left()!=aOld.Left() || rRect.Top()!=aOld.Top()) {
432 		NbcMove(Size(rRect.Left()-aOld.Left(),rRect.Top()-aOld.Top()));
433 	}
434 }
435 
436 
NbcSetLogicRect(const Rectangle & rRect)437 void SdrObjGroup::NbcSetLogicRect(const Rectangle& rRect)
438 {
439 	NbcSetSnapRect(rRect);
440 }
441 
442 
NbcMove(const Size & rSiz)443 void SdrObjGroup::NbcMove(const Size& rSiz)
444 {
445 	MovePoint(aRefPoint,rSiz);
446 	if (pSub->GetObjCount()!=0) {
447 		SdrObjList* pOL=pSub;
448 		sal_uIntPtr nObjAnz=pOL->GetObjCount();
449 		for (sal_uIntPtr i=0; i<nObjAnz; i++) {
450 			SdrObject* pObj=pOL->GetObj(i);
451 			pObj->NbcMove(rSiz);
452 		}
453 	} else {
454 		MoveRect(aOutRect,rSiz);
455 		SetRectsDirty();
456 	}
457 }
458 
459 
NbcResize(const Point & rRef,const Fraction & xFact,const Fraction & yFact)460 void SdrObjGroup::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
461 {
462 	FASTBOOL bXMirr=(xFact.GetNumerator()<0) != (xFact.GetDenominator()<0);
463 	FASTBOOL bYMirr=(yFact.GetNumerator()<0) != (yFact.GetDenominator()<0);
464 	if (bXMirr || bYMirr) {
465 		Point aRef1(GetSnapRect().Center());
466 		if (bXMirr) {
467 			Point aRef2(aRef1);
468 			aRef2.Y()++;
469 			NbcMirrorGluePoints(aRef1,aRef2);
470 		}
471 		if (bYMirr) {
472 			Point aRef2(aRef1);
473 			aRef2.X()++;
474 			NbcMirrorGluePoints(aRef1,aRef2);
475 		}
476 	}
477 	ResizePoint(aRefPoint,rRef,xFact,yFact);
478 	if (pSub->GetObjCount()!=0) {
479 		SdrObjList* pOL=pSub;
480 		sal_uIntPtr nObjAnz=pOL->GetObjCount();
481 		for (sal_uIntPtr i=0; i<nObjAnz; i++) {
482 			SdrObject* pObj=pOL->GetObj(i);
483 			pObj->NbcResize(rRef,xFact,yFact);
484 		}
485 	} else {
486 		ResizeRect(aOutRect,rRef,xFact,yFact);
487 		SetRectsDirty();
488 	}
489 }
490 
491 
NbcRotate(const Point & rRef,long nWink,double sn,double cs)492 void SdrObjGroup::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
493 {
494 	SetGlueReallyAbsolute(sal_True);
495 	RotatePoint(aRefPoint,rRef,sn,cs);
496 	SdrObjList* pOL=pSub;
497 	sal_uIntPtr nObjAnz=pOL->GetObjCount();
498 	for (sal_uIntPtr i=0; i<nObjAnz; i++) {
499 		SdrObject* pObj=pOL->GetObj(i);
500 		pObj->NbcRotate(rRef,nWink,sn,cs);
501 	}
502 	NbcRotateGluePoints(rRef,nWink,sn,cs);
503 	SetGlueReallyAbsolute(sal_False);
504 }
505 
506 
NbcMirror(const Point & rRef1,const Point & rRef2)507 void SdrObjGroup::NbcMirror(const Point& rRef1, const Point& rRef2)
508 {
509 	SetGlueReallyAbsolute(sal_True);
510 	MirrorPoint(aRefPoint,rRef1,rRef2); // fehlende Implementation in SvdEtc !!!
511 	SdrObjList* pOL=pSub;
512 	sal_uIntPtr nObjAnz=pOL->GetObjCount();
513 	for (sal_uIntPtr i=0; i<nObjAnz; i++) {
514 		SdrObject* pObj=pOL->GetObj(i);
515 		pObj->NbcMirror(rRef1,rRef2);
516 	}
517 	NbcMirrorGluePoints(rRef1,rRef2);
518 	SetGlueReallyAbsolute(sal_False);
519 }
520 
521 
NbcShear(const Point & rRef,long nWink,double tn,FASTBOOL bVShear)522 void SdrObjGroup::NbcShear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
523 {
524 	SetGlueReallyAbsolute(sal_True);
525 	ShearPoint(aRefPoint,rRef,tn);
526 	SdrObjList* pOL=pSub;
527 	sal_uIntPtr nObjAnz=pOL->GetObjCount();
528 	for (sal_uIntPtr i=0; i<nObjAnz; i++) {
529 		SdrObject* pObj=pOL->GetObj(i);
530 		pObj->NbcShear(rRef,nWink,tn,bVShear);
531 	}
532 	NbcShearGluePoints(rRef,nWink,tn,bVShear);
533 	SetGlueReallyAbsolute(sal_False);
534 }
535 
536 
NbcSetAnchorPos(const Point & rPnt)537 void SdrObjGroup::NbcSetAnchorPos(const Point& rPnt)
538 {
539 	aAnchor=rPnt;
540 	Size aSiz(rPnt.X()-aAnchor.X(),rPnt.Y()-aAnchor.Y());
541 	MovePoint(aRefPoint,aSiz);
542 	SdrObjList* pOL=pSub;
543 	sal_uIntPtr nObjAnz=pOL->GetObjCount();
544 	for (sal_uIntPtr i=0; i<nObjAnz; i++) {
545 		SdrObject* pObj=pOL->GetObj(i);
546 		pObj->NbcSetAnchorPos(rPnt);
547 	}
548 }
549 
550 
SetSnapRect(const Rectangle & rRect)551 void SdrObjGroup::SetSnapRect(const Rectangle& rRect)
552 {
553 	Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
554 	Rectangle aOld(GetSnapRect());
555 	long nMulX=rRect.Right()-rRect.Left();
556 	long nDivX=aOld.Right()-aOld.Left();
557 	long nMulY=rRect.Bottom()-rRect.Top();
558 	long nDivY=aOld.Bottom()-aOld.Top();
559 	if (nDivX==0) { nMulX=1; nDivX=1; }
560 	if (nDivY==0) { nMulY=1; nDivY=1; }
561 	if (nMulX!=nDivX || nMulY!=nDivY) {
562 		Fraction aX(nMulX,nDivX);
563 		Fraction aY(nMulY,nDivY);
564 		Resize(aOld.TopLeft(),aX,aY);
565 	}
566 	if (rRect.Left()!=aOld.Left() || rRect.Top()!=aOld.Top()) {
567 		Move(Size(rRect.Left()-aOld.Left(),rRect.Top()-aOld.Top()));
568 	}
569 
570 	SetChanged();
571 	BroadcastObjectChange();
572 	SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
573 }
574 
575 
SetLogicRect(const Rectangle & rRect)576 void SdrObjGroup::SetLogicRect(const Rectangle& rRect)
577 {
578 	SetSnapRect(rRect);
579 }
580 
581 
Move(const Size & rSiz)582 void SdrObjGroup::Move(const Size& rSiz)
583 {
584 	if (rSiz.Width()!=0 || rSiz.Height()!=0) {
585 		Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
586 		MovePoint(aRefPoint,rSiz);
587 		if (pSub->GetObjCount()!=0) {
588 			// #32383# Erst die Verbinder verschieben, dann den Rest
589 			SdrObjList* pOL=pSub;
590 			sal_uIntPtr nObjAnz=pOL->GetObjCount();
591 			sal_uIntPtr i;
592 			for (i=0; i<nObjAnz; i++) {
593 				SdrObject* pObj=pOL->GetObj(i);
594 				if (pObj->IsEdgeObj()) pObj->Move(rSiz);
595 			}
596 			for (i=0; i<nObjAnz; i++) {
597 				SdrObject* pObj=pOL->GetObj(i);
598 				if (!pObj->IsEdgeObj()) pObj->Move(rSiz);
599 			}
600 		} else {
601 			// #110094#-14 SendRepaintBroadcast();
602 			MoveRect(aOutRect,rSiz);
603 			SetRectsDirty();
604 		}
605 
606 		SetChanged();
607 		BroadcastObjectChange();
608 		SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0);
609 	}
610 }
611 
612 
Resize(const Point & rRef,const Fraction & xFact,const Fraction & yFact)613 void SdrObjGroup::Resize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
614 {
615 	if (xFact.GetNumerator()!=xFact.GetDenominator() || yFact.GetNumerator()!=yFact.GetDenominator()) {
616 		FASTBOOL bXMirr=(xFact.GetNumerator()<0) != (xFact.GetDenominator()<0);
617 		FASTBOOL bYMirr=(yFact.GetNumerator()<0) != (yFact.GetDenominator()<0);
618 		if (bXMirr || bYMirr) {
619 			Point aRef1(GetSnapRect().Center());
620 			if (bXMirr) {
621 				Point aRef2(aRef1);
622 				aRef2.Y()++;
623 				NbcMirrorGluePoints(aRef1,aRef2);
624 			}
625 			if (bYMirr) {
626 				Point aRef2(aRef1);
627 				aRef2.X()++;
628 				NbcMirrorGluePoints(aRef1,aRef2);
629 			}
630 		}
631 		Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
632 		ResizePoint(aRefPoint,rRef,xFact,yFact);
633 		if (pSub->GetObjCount()!=0) {
634 			// #32383# Erst die Verbinder verschieben, dann den Rest
635 			SdrObjList* pOL=pSub;
636 			sal_uIntPtr nObjAnz=pOL->GetObjCount();
637 			sal_uIntPtr i;
638 			for (i=0; i<nObjAnz; i++) {
639 				SdrObject* pObj=pOL->GetObj(i);
640 				if (pObj->IsEdgeObj()) pObj->Resize(rRef,xFact,yFact);
641 			}
642 			for (i=0; i<nObjAnz; i++) {
643 				SdrObject* pObj=pOL->GetObj(i);
644 				if (!pObj->IsEdgeObj()) pObj->Resize(rRef,xFact,yFact);
645 			}
646 		} else {
647 			// #110094#-14 SendRepaintBroadcast();
648 			ResizeRect(aOutRect,rRef,xFact,yFact);
649 			SetRectsDirty();
650 		}
651 
652 		SetChanged();
653 		BroadcastObjectChange();
654 		SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
655 	}
656 }
657 
658 
Rotate(const Point & rRef,long nWink,double sn,double cs)659 void SdrObjGroup::Rotate(const Point& rRef, long nWink, double sn, double cs)
660 {
661 	if (nWink!=0) {
662 		SetGlueReallyAbsolute(sal_True);
663 		Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
664 		RotatePoint(aRefPoint,rRef,sn,cs);
665 		// #32383# Erst die Verbinder verschieben, dann den Rest
666 		SdrObjList* pOL=pSub;
667 		sal_uIntPtr nObjAnz=pOL->GetObjCount();
668 		sal_uIntPtr i;
669 		for (i=0; i<nObjAnz; i++) {
670 			SdrObject* pObj=pOL->GetObj(i);
671 			if (pObj->IsEdgeObj()) pObj->Rotate(rRef,nWink,sn,cs);
672 		}
673 		for (i=0; i<nObjAnz; i++) {
674 			SdrObject* pObj=pOL->GetObj(i);
675 			if (!pObj->IsEdgeObj()) pObj->Rotate(rRef,nWink,sn,cs);
676 		}
677 		NbcRotateGluePoints(rRef,nWink,sn,cs);
678 		SetGlueReallyAbsolute(sal_False);
679 		SetChanged();
680 		BroadcastObjectChange();
681 		SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
682 	}
683 }
684 
685 
Mirror(const Point & rRef1,const Point & rRef2)686 void SdrObjGroup::Mirror(const Point& rRef1, const Point& rRef2)
687 {
688 	SetGlueReallyAbsolute(sal_True);
689 	Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
690 	MirrorPoint(aRefPoint,rRef1,rRef2); // fehlende Implementation in SvdEtc !!!
691 	// #32383# Erst die Verbinder verschieben, dann den Rest
692 	SdrObjList* pOL=pSub;
693 	sal_uIntPtr nObjAnz=pOL->GetObjCount();
694 	sal_uIntPtr i;
695 	for (i=0; i<nObjAnz; i++) {
696 		SdrObject* pObj=pOL->GetObj(i);
697 		if (pObj->IsEdgeObj()) pObj->Mirror(rRef1,rRef2);
698 	}
699 	for (i=0; i<nObjAnz; i++) {
700 		SdrObject* pObj=pOL->GetObj(i);
701 		if (!pObj->IsEdgeObj()) pObj->Mirror(rRef1,rRef2);
702 	}
703 	NbcMirrorGluePoints(rRef1,rRef2);
704 	SetGlueReallyAbsolute(sal_False);
705 	SetChanged();
706 	BroadcastObjectChange();
707 	SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
708 }
709 
710 
Shear(const Point & rRef,long nWink,double tn,FASTBOOL bVShear)711 void SdrObjGroup::Shear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
712 {
713 	if (nWink!=0) {
714 		SetGlueReallyAbsolute(sal_True);
715 		Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
716 		ShearPoint(aRefPoint,rRef,tn);
717 		// #32383# Erst die Verbinder verschieben, dann den Rest
718 		SdrObjList* pOL=pSub;
719 		sal_uIntPtr nObjAnz=pOL->GetObjCount();
720 		sal_uIntPtr i;
721 		for (i=0; i<nObjAnz; i++) {
722 			SdrObject* pObj=pOL->GetObj(i);
723 			if (pObj->IsEdgeObj()) pObj->Shear(rRef,nWink,tn,bVShear);
724 		}
725 		for (i=0; i<nObjAnz; i++) {
726 			SdrObject* pObj=pOL->GetObj(i);
727 			if (!pObj->IsEdgeObj()) pObj->Shear(rRef,nWink,tn,bVShear);
728 		}
729 		NbcShearGluePoints(rRef,nWink,tn,bVShear);
730 		SetGlueReallyAbsolute(sal_False);
731 		SetChanged();
732 		BroadcastObjectChange();
733 		SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
734 	}
735 }
736 
737 
SetAnchorPos(const Point & rPnt)738 void SdrObjGroup::SetAnchorPos(const Point& rPnt)
739 {
740 	Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
741 	FASTBOOL bChg=aAnchor!=rPnt;
742 	aAnchor=rPnt;
743 	Size aSiz(rPnt.X()-aAnchor.X(),rPnt.Y()-aAnchor.Y());
744 	MovePoint(aRefPoint,aSiz);
745 	// #32383# Erst die Verbinder verschieben, dann den Rest
746 	SdrObjList* pOL=pSub;
747 	sal_uIntPtr nObjAnz=pOL->GetObjCount();
748 	sal_uIntPtr i;
749 	for (i=0; i<nObjAnz; i++) {
750 		SdrObject* pObj=pOL->GetObj(i);
751 		if (pObj->IsEdgeObj()) pObj->SetAnchorPos(rPnt);
752 	}
753 	for (i=0; i<nObjAnz; i++) {
754 		SdrObject* pObj=pOL->GetObj(i);
755 		if (!pObj->IsEdgeObj()) pObj->SetAnchorPos(rPnt);
756 	}
757 	if (bChg) {
758 		SetChanged();
759 		BroadcastObjectChange();
760 		SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0);
761 	}
762 }
763 
764 
765 
NbcSetRelativePos(const Point & rPnt)766 void SdrObjGroup::NbcSetRelativePos(const Point& rPnt)
767 {
768 	Point aRelPos0(GetSnapRect().TopLeft()-aAnchor);
769 	Size aSiz(rPnt.X()-aRelPos0.X(),rPnt.Y()-aRelPos0.Y());
770 	NbcMove(aSiz); // Der ruft auch das SetRectsDirty()
771 }
772 
SetRelativePos(const Point & rPnt)773 void SdrObjGroup::SetRelativePos(const Point& rPnt)
774 {
775 	Point aRelPos0(GetSnapRect().TopLeft()-aAnchor);
776 	Size aSiz(rPnt.X()-aRelPos0.X(),rPnt.Y()-aRelPos0.Y());
777 	if (aSiz.Width()!=0 || aSiz.Height()!=0) Move(aSiz); // Der ruft auch das SetRectsDirty() und Broadcast, ...
778 }
779 
NbcReformatText()780 void SdrObjGroup::NbcReformatText()
781 {
782 	pSub->NbcReformatAllTextObjects();
783 }
784 
ReformatText()785 void SdrObjGroup::ReformatText()
786 {
787 	pSub->ReformatAllTextObjects();
788 }
789 
DoConvertToPolyObj(sal_Bool bBezier,bool bAddText) const790 SdrObject* SdrObjGroup::DoConvertToPolyObj(sal_Bool bBezier, bool bAddText) const
791 {
792 	SdrObject* pGroup = new SdrObjGroup;
793 	pGroup->SetModel(GetModel());
794 
795 	for(sal_uInt32 a=0;a<pSub->GetObjCount();a++)
796 	{
797 		SdrObject* pIterObj = pSub->GetObj(a);
798         SdrObject* pResult = pIterObj->DoConvertToPolyObj(bBezier, bAddText);
799 
800         // pResult can be NULL e.g. for empty objects
801         if( pResult )
802             pGroup->GetSubList()->NbcInsertObject(pResult);
803 	}
804 
805 	return pGroup;
806 }
807 
808 // eof
809