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