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