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