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