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 "svx/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 <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 0 : sdr::properties::BaseProperties* SdrObjGroup::CreateObjectSpecificProperties()
56 : {
57 0 : return new sdr::properties::GroupProperties(*this);
58 : }
59 :
60 :
61 : // DrawContact section
62 :
63 0 : sdr::contact::ViewContact* SdrObjGroup::CreateObjectSpecificViewContact()
64 : {
65 0 : return new sdr::contact::ViewContactOfGroup(*this);
66 : }
67 :
68 :
69 :
70 0 : TYPEINIT1(SdrObjGroup,SdrObject);
71 :
72 0 : SdrObjGroup::SdrObjGroup()
73 : {
74 0 : pSub=new SdrObjList(NULL,NULL);
75 0 : pSub->SetOwnerObj(this);
76 0 : pSub->SetListKind(SDROBJLIST_GROUPOBJ);
77 0 : bRefPoint=false;
78 0 : bClosedObj=false;
79 0 : }
80 :
81 :
82 0 : SdrObjGroup::~SdrObjGroup()
83 : {
84 0 : delete pSub;
85 0 : }
86 :
87 0 : void SdrObjGroup::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
88 : {
89 0 : rInfo.bNoContortion=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 =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 0 : void SdrObjGroup::SetBoundRectDirty()
139 : {
140 : // avoid resetting aOutRect which in case of this object is model data,
141 : // not re-creatable view data
142 0 : }
143 :
144 0 : sal_uInt16 SdrObjGroup::GetObjIdentifier() const
145 : {
146 0 : return sal_uInt16(OBJ_GRUP);
147 : }
148 :
149 :
150 0 : SdrLayerID SdrObjGroup::GetLayer() const
151 : {
152 0 : bool b1st = true;
153 0 : SdrLayerID nLay=SdrLayerID(SdrObject::GetLayer());
154 0 : SdrObjList* pOL=pSub;
155 0 : sal_uIntPtr nObjAnz=pOL->GetObjCount();
156 0 : for (sal_uIntPtr i=0; i<nObjAnz; i++) {
157 0 : SdrLayerID nLay1=pOL->GetObj(i)->GetLayer();
158 0 : if (b1st) { nLay=nLay1; b1st = false; }
159 0 : else if (nLay1!=nLay) return 0;
160 : }
161 0 : return nLay;
162 : }
163 :
164 :
165 0 : void SdrObjGroup::NbcSetLayer(SdrLayerID nLayer)
166 : {
167 0 : SdrObject::NbcSetLayer(nLayer);
168 0 : SdrObjList* pOL=pSub;
169 0 : sal_uIntPtr nObjAnz=pOL->GetObjCount();
170 0 : for (sal_uIntPtr i=0; i<nObjAnz; i++) {
171 0 : pOL->GetObj(i)->NbcSetLayer(nLayer);
172 : }
173 0 : }
174 :
175 :
176 0 : void SdrObjGroup::SetObjList(SdrObjList* pNewObjList)
177 : {
178 0 : SdrObject::SetObjList(pNewObjList);
179 0 : pSub->SetUpList(pNewObjList);
180 0 : }
181 :
182 :
183 0 : void SdrObjGroup::SetPage(SdrPage* pNewPage)
184 : {
185 0 : SdrObject::SetPage(pNewPage);
186 0 : pSub->SetPage(pNewPage);
187 0 : }
188 :
189 :
190 0 : void SdrObjGroup::SetModel(SdrModel* pNewModel)
191 : {
192 0 : 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 0 : SdrModel* pOldModel = pModel;
201 :
202 : // test for correct pool in ItemSet; move to new pool if necessary
203 0 : if(pNewModel && GetObjectItemPool() && GetObjectItemPool() != &pNewModel->GetItemPool())
204 : {
205 0 : MigrateItemPool(GetObjectItemPool(), &pNewModel->GetItemPool(), pNewModel);
206 : }
207 :
208 : // call parent
209 0 : SdrObject::SetModel(pNewModel);
210 :
211 : // set new model at content
212 0 : pSub->SetModel(pNewModel);
213 :
214 : // modify properties
215 0 : GetProperties().SetModel(pOldModel, pNewModel);
216 : }
217 0 : }
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 0 : SdrObjList* SdrObjGroup::GetSubList() const
240 : {
241 0 : return pSub;
242 : }
243 :
244 0 : const Rectangle& SdrObjGroup::GetCurrentBoundRect() const
245 : {
246 : // <aOutRect> has to contain the bounding rectangle
247 0 : if ( pSub->GetObjCount()!=0 )
248 : {
249 0 : const_cast<SdrObjGroup*>(this)->aOutRect = pSub->GetAllObjBoundRect();
250 : }
251 :
252 0 : return aOutRect;
253 : }
254 :
255 0 : const Rectangle& SdrObjGroup::GetSnapRect() const
256 : {
257 : // <aOutRect> has to contain the bounding rectangle
258 0 : if ( pSub->GetObjCount()!=0 )
259 : {
260 0 : return pSub->GetAllObjSnapRect();
261 : }
262 : else
263 : {
264 0 : 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 0 : OUString SdrObjGroup::TakeObjNameSingul() const
295 : {
296 0 : OUStringBuffer sName;
297 :
298 0 : if(!pSub->GetObjCount())
299 : {
300 0 : sName.append(ImpGetResStr(STR_ObjNameSingulGRUPEMPTY));
301 : }
302 : else
303 : {
304 0 : sName.append(ImpGetResStr(STR_ObjNameSingulGRUP));
305 : }
306 :
307 0 : const OUString aName(GetName());
308 :
309 0 : if (!aName.isEmpty())
310 : {
311 0 : sName.append(' ');
312 0 : sName.append('\'');
313 0 : sName.append(aName);
314 0 : sName.append('\'');
315 : }
316 :
317 0 : return sName.makeStringAndClear();
318 : }
319 :
320 :
321 0 : OUString SdrObjGroup::TakeObjNamePlural() const
322 : {
323 0 : if (pSub->GetObjCount()==0)
324 0 : return ImpGetResStr(STR_ObjNamePluralGRUPEMPTY);
325 0 : return ImpGetResStr(STR_ObjNamePluralGRUP);
326 : }
327 :
328 :
329 0 : void SdrObjGroup::RecalcSnapRect()
330 : {
331 : // TODO: unnecessary, because we use the Rects from the SubList
332 0 : }
333 :
334 0 : basegfx::B2DPolyPolygon SdrObjGroup::TakeXorPoly() const
335 : {
336 0 : basegfx::B2DPolyPolygon aRetval;
337 0 : const sal_uInt32 nObjCount(pSub->GetObjCount());
338 :
339 0 : for(sal_uInt32 a(0L); 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 0 : long SdrObjGroup::GetRotateAngle() const
367 : {
368 0 : const sal_uInt32 nObjCount(pSub->GetObjCount());
369 0 : long nRetval(0);
370 :
371 0 : if(nObjCount)
372 : {
373 0 : SdrObject* pObj = pSub->GetObj(0);
374 :
375 0 : nRetval = pObj->GetRotateAngle();
376 : }
377 :
378 0 : return nRetval;
379 : }
380 :
381 :
382 0 : long SdrObjGroup::GetShearAngle(bool /*bVertical*/) const
383 : {
384 0 : const sal_uInt32 nObjCount(pSub->GetObjCount());
385 0 : long nRetval(0);
386 :
387 0 : if(nObjCount)
388 : {
389 0 : SdrObject* pObj = pSub->GetObj(0);
390 :
391 0 : nRetval = pObj->GetShearAngle();
392 : }
393 :
394 0 : return nRetval;
395 : }
396 :
397 :
398 0 : void SdrObjGroup::NbcSetSnapRect(const Rectangle& rRect)
399 : {
400 0 : Rectangle aOld(GetSnapRect());
401 0 : long nMulX=rRect.Right()-rRect.Left();
402 0 : long nDivX=aOld.Right()-aOld.Left();
403 0 : long nMulY=rRect.Bottom()-rRect.Top();
404 0 : long nDivY=aOld.Bottom()-aOld.Top();
405 0 : if (nDivX==0) { nMulX=1; nDivX=1; }
406 0 : if (nDivY==0) { nMulY=1; nDivY=1; }
407 0 : if (nMulX!=nDivX || nMulY!=nDivY) {
408 0 : Fraction aX(nMulX,nDivX);
409 0 : Fraction aY(nMulY,nDivY);
410 0 : NbcResize(aOld.TopLeft(),aX,aY);
411 : }
412 0 : if (rRect.Left()!=aOld.Left() || rRect.Top()!=aOld.Top()) {
413 0 : NbcMove(Size(rRect.Left()-aOld.Left(),rRect.Top()-aOld.Top()));
414 : }
415 0 : }
416 :
417 :
418 0 : void SdrObjGroup::NbcSetLogicRect(const Rectangle& rRect)
419 : {
420 0 : NbcSetSnapRect(rRect);
421 0 : }
422 :
423 :
424 0 : void SdrObjGroup::NbcMove(const Size& rSiz)
425 : {
426 0 : MovePoint(aRefPoint,rSiz);
427 0 : if (pSub->GetObjCount()!=0) {
428 0 : SdrObjList* pOL=pSub;
429 0 : sal_uIntPtr nObjAnz=pOL->GetObjCount();
430 0 : for (sal_uIntPtr i=0; i<nObjAnz; i++) {
431 0 : SdrObject* pObj=pOL->GetObj(i);
432 0 : pObj->NbcMove(rSiz);
433 : }
434 : } else {
435 0 : MoveRect(aOutRect,rSiz);
436 0 : SetRectsDirty();
437 : }
438 0 : }
439 :
440 :
441 0 : void SdrObjGroup::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
442 : {
443 0 : bool bXMirr=(xFact.GetNumerator()<0) != (xFact.GetDenominator()<0);
444 0 : bool bYMirr=(yFact.GetNumerator()<0) != (yFact.GetDenominator()<0);
445 0 : if (bXMirr || bYMirr) {
446 0 : Point aRef1(GetSnapRect().Center());
447 0 : if (bXMirr) {
448 0 : Point aRef2(aRef1);
449 0 : aRef2.Y()++;
450 0 : NbcMirrorGluePoints(aRef1,aRef2);
451 : }
452 0 : if (bYMirr) {
453 0 : Point aRef2(aRef1);
454 0 : aRef2.X()++;
455 0 : NbcMirrorGluePoints(aRef1,aRef2);
456 : }
457 : }
458 0 : ResizePoint(aRefPoint,rRef,xFact,yFact);
459 0 : if (pSub->GetObjCount()!=0) {
460 0 : SdrObjList* pOL=pSub;
461 0 : sal_uIntPtr nObjAnz=pOL->GetObjCount();
462 0 : for (sal_uIntPtr i=0; i<nObjAnz; i++) {
463 0 : SdrObject* pObj=pOL->GetObj(i);
464 0 : pObj->NbcResize(rRef,xFact,yFact);
465 : }
466 : } else {
467 0 : ResizeRect(aOutRect,rRef,xFact,yFact);
468 0 : SetRectsDirty();
469 : }
470 0 : }
471 :
472 :
473 0 : void SdrObjGroup::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
474 : {
475 0 : SetGlueReallyAbsolute(true);
476 0 : RotatePoint(aRefPoint,rRef,sn,cs);
477 0 : SdrObjList* pOL=pSub;
478 0 : sal_uIntPtr nObjAnz=pOL->GetObjCount();
479 0 : for (sal_uIntPtr i=0; i<nObjAnz; i++) {
480 0 : SdrObject* pObj=pOL->GetObj(i);
481 0 : pObj->NbcRotate(rRef,nWink,sn,cs);
482 : }
483 0 : NbcRotateGluePoints(rRef,nWink,sn,cs);
484 0 : SetGlueReallyAbsolute(false);
485 0 : }
486 :
487 :
488 0 : void SdrObjGroup::NbcMirror(const Point& rRef1, const Point& rRef2)
489 : {
490 0 : SetGlueReallyAbsolute(true);
491 0 : MirrorPoint(aRefPoint,rRef1,rRef2); // implementation missing in SvdEtc!
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->NbcMirror(rRef1,rRef2);
497 : }
498 0 : NbcMirrorGluePoints(rRef1,rRef2);
499 0 : SetGlueReallyAbsolute(false);
500 0 : }
501 :
502 :
503 0 : void SdrObjGroup::NbcShear(const Point& rRef, long nWink, double tn, bool bVShear)
504 : {
505 0 : SetGlueReallyAbsolute(true);
506 0 : ShearPoint(aRefPoint,rRef,tn);
507 0 : SdrObjList* pOL=pSub;
508 0 : sal_uIntPtr nObjAnz=pOL->GetObjCount();
509 0 : for (sal_uIntPtr i=0; i<nObjAnz; i++) {
510 0 : SdrObject* pObj=pOL->GetObj(i);
511 0 : pObj->NbcShear(rRef,nWink,tn,bVShear);
512 : }
513 0 : NbcShearGluePoints(rRef,nWink,tn,bVShear);
514 0 : SetGlueReallyAbsolute(false);
515 0 : }
516 :
517 :
518 0 : void SdrObjGroup::NbcSetAnchorPos(const Point& rPnt)
519 : {
520 0 : aAnchor=rPnt;
521 0 : Size aSiz(rPnt.X()-aAnchor.X(),rPnt.Y()-aAnchor.Y());
522 0 : MovePoint(aRefPoint,aSiz);
523 0 : SdrObjList* pOL=pSub;
524 0 : sal_uIntPtr nObjAnz=pOL->GetObjCount();
525 0 : for (sal_uIntPtr i=0; i<nObjAnz; i++) {
526 0 : SdrObject* pObj=pOL->GetObj(i);
527 0 : pObj->NbcSetAnchorPos(rPnt);
528 : }
529 0 : }
530 :
531 :
532 0 : void SdrObjGroup::SetSnapRect(const Rectangle& rRect)
533 : {
534 0 : Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
535 0 : Rectangle aOld(GetSnapRect());
536 0 : long nMulX=rRect.Right()-rRect.Left();
537 0 : long nDivX=aOld.Right()-aOld.Left();
538 0 : long nMulY=rRect.Bottom()-rRect.Top();
539 0 : long nDivY=aOld.Bottom()-aOld.Top();
540 0 : if (nDivX==0) { nMulX=1; nDivX=1; }
541 0 : if (nDivY==0) { nMulY=1; nDivY=1; }
542 0 : if (nMulX!=nDivX || nMulY!=nDivY) {
543 0 : Fraction aX(nMulX,nDivX);
544 0 : Fraction aY(nMulY,nDivY);
545 0 : Resize(aOld.TopLeft(),aX,aY);
546 : }
547 0 : if (rRect.Left()!=aOld.Left() || rRect.Top()!=aOld.Top()) {
548 0 : Move(Size(rRect.Left()-aOld.Left(),rRect.Top()-aOld.Top()));
549 : }
550 :
551 0 : SetChanged();
552 0 : BroadcastObjectChange();
553 0 : SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
554 0 : }
555 :
556 :
557 0 : void SdrObjGroup::SetLogicRect(const Rectangle& rRect)
558 : {
559 0 : SetSnapRect(rRect);
560 0 : }
561 :
562 :
563 0 : void SdrObjGroup::Move(const Size& rSiz)
564 : {
565 0 : if (rSiz.Width()!=0 || rSiz.Height()!=0) {
566 0 : Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
567 0 : MovePoint(aRefPoint,rSiz);
568 0 : if (pSub->GetObjCount()!=0) {
569 : // first move the connectors, then everything else
570 0 : SdrObjList* pOL=pSub;
571 0 : sal_uIntPtr nObjAnz=pOL->GetObjCount();
572 : sal_uIntPtr i;
573 0 : for (i=0; i<nObjAnz; i++) {
574 0 : SdrObject* pObj=pOL->GetObj(i);
575 0 : if (pObj->IsEdgeObj()) pObj->Move(rSiz);
576 : }
577 0 : for (i=0; i<nObjAnz; i++) {
578 0 : SdrObject* pObj=pOL->GetObj(i);
579 0 : if (!pObj->IsEdgeObj()) pObj->Move(rSiz);
580 : }
581 : } else {
582 0 : MoveRect(aOutRect,rSiz);
583 0 : SetRectsDirty();
584 : }
585 :
586 0 : SetChanged();
587 0 : BroadcastObjectChange();
588 0 : SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0);
589 : }
590 0 : }
591 :
592 :
593 0 : void SdrObjGroup::Resize(const Point& rRef, const Fraction& xFact, const Fraction& yFact, bool bUnsetRelative)
594 : {
595 0 : if (xFact.GetNumerator()!=xFact.GetDenominator() || yFact.GetNumerator()!=yFact.GetDenominator()) {
596 0 : bool bXMirr=(xFact.GetNumerator()<0) != (xFact.GetDenominator()<0);
597 0 : bool bYMirr=(yFact.GetNumerator()<0) != (yFact.GetDenominator()<0);
598 0 : if (bXMirr || bYMirr) {
599 0 : Point aRef1(GetSnapRect().Center());
600 0 : if (bXMirr) {
601 0 : Point aRef2(aRef1);
602 0 : aRef2.Y()++;
603 0 : NbcMirrorGluePoints(aRef1,aRef2);
604 : }
605 0 : if (bYMirr) {
606 0 : Point aRef2(aRef1);
607 0 : aRef2.X()++;
608 0 : NbcMirrorGluePoints(aRef1,aRef2);
609 : }
610 : }
611 0 : Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
612 0 : ResizePoint(aRefPoint,rRef,xFact,yFact);
613 0 : if (pSub->GetObjCount()!=0) {
614 : // move the connectors first, everything else afterwards
615 0 : SdrObjList* pOL=pSub;
616 0 : sal_uIntPtr nObjAnz=pOL->GetObjCount();
617 : sal_uIntPtr i;
618 0 : for (i=0; i<nObjAnz; i++) {
619 0 : SdrObject* pObj=pOL->GetObj(i);
620 0 : if (pObj->IsEdgeObj()) pObj->Resize(rRef,xFact,yFact,bUnsetRelative);
621 : }
622 0 : for (i=0; i<nObjAnz; i++) {
623 0 : SdrObject* pObj=pOL->GetObj(i);
624 0 : if (!pObj->IsEdgeObj()) pObj->Resize(rRef,xFact,yFact,bUnsetRelative);
625 : }
626 : } else {
627 0 : ResizeRect(aOutRect,rRef,xFact,yFact);
628 0 : SetRectsDirty();
629 : }
630 :
631 0 : SetChanged();
632 0 : BroadcastObjectChange();
633 0 : SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
634 : }
635 0 : }
636 :
637 :
638 0 : void SdrObjGroup::Rotate(const Point& rRef, long nWink, double sn, double cs)
639 : {
640 0 : if (nWink!=0) {
641 0 : SetGlueReallyAbsolute(true);
642 0 : Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
643 0 : RotatePoint(aRefPoint,rRef,sn,cs);
644 : // move the connectors first, everything else afterwards
645 0 : SdrObjList* pOL=pSub;
646 0 : sal_uIntPtr nObjAnz=pOL->GetObjCount();
647 : sal_uIntPtr i;
648 0 : for (i=0; i<nObjAnz; i++) {
649 0 : SdrObject* pObj=pOL->GetObj(i);
650 0 : if (pObj->IsEdgeObj()) pObj->Rotate(rRef,nWink,sn,cs);
651 : }
652 0 : for (i=0; i<nObjAnz; i++) {
653 0 : SdrObject* pObj=pOL->GetObj(i);
654 0 : if (!pObj->IsEdgeObj()) pObj->Rotate(rRef,nWink,sn,cs);
655 : }
656 0 : NbcRotateGluePoints(rRef,nWink,sn,cs);
657 0 : SetGlueReallyAbsolute(false);
658 0 : SetChanged();
659 0 : BroadcastObjectChange();
660 0 : SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
661 : }
662 0 : }
663 :
664 :
665 0 : void SdrObjGroup::Mirror(const Point& rRef1, const Point& rRef2)
666 : {
667 0 : SetGlueReallyAbsolute(true);
668 0 : Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
669 0 : MirrorPoint(aRefPoint,rRef1,rRef2); // implementation missing in SvdEtc!
670 : // move the connectors first, everything else afterwards
671 0 : SdrObjList* pOL=pSub;
672 0 : sal_uIntPtr nObjAnz=pOL->GetObjCount();
673 : sal_uIntPtr i;
674 0 : for (i=0; i<nObjAnz; i++) {
675 0 : SdrObject* pObj=pOL->GetObj(i);
676 0 : if (pObj->IsEdgeObj()) pObj->Mirror(rRef1,rRef2);
677 : }
678 0 : for (i=0; i<nObjAnz; i++) {
679 0 : SdrObject* pObj=pOL->GetObj(i);
680 0 : if (!pObj->IsEdgeObj()) pObj->Mirror(rRef1,rRef2);
681 : }
682 0 : NbcMirrorGluePoints(rRef1,rRef2);
683 0 : SetGlueReallyAbsolute(false);
684 0 : SetChanged();
685 0 : BroadcastObjectChange();
686 0 : SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
687 0 : }
688 :
689 :
690 0 : void SdrObjGroup::Shear(const Point& rRef, long nWink, double tn, bool bVShear)
691 : {
692 0 : if (nWink!=0) {
693 0 : SetGlueReallyAbsolute(true);
694 0 : Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
695 0 : ShearPoint(aRefPoint,rRef,tn);
696 : // move the connectors first, everything else afterwards
697 0 : SdrObjList* pOL=pSub;
698 0 : sal_uIntPtr nObjAnz=pOL->GetObjCount();
699 : sal_uIntPtr i;
700 0 : for (i=0; i<nObjAnz; i++) {
701 0 : SdrObject* pObj=pOL->GetObj(i);
702 0 : if (pObj->IsEdgeObj()) pObj->Shear(rRef,nWink,tn,bVShear);
703 : }
704 0 : for (i=0; i<nObjAnz; i++) {
705 0 : SdrObject* pObj=pOL->GetObj(i);
706 0 : if (!pObj->IsEdgeObj()) pObj->Shear(rRef,nWink,tn,bVShear);
707 : }
708 0 : NbcShearGluePoints(rRef,nWink,tn,bVShear);
709 0 : SetGlueReallyAbsolute(false);
710 0 : SetChanged();
711 0 : BroadcastObjectChange();
712 0 : SendUserCall(SDRUSERCALL_RESIZE,aBoundRect0);
713 : }
714 0 : }
715 :
716 :
717 0 : void SdrObjGroup::SetAnchorPos(const Point& rPnt)
718 : {
719 0 : Rectangle aBoundRect0; if (pUserCall!=NULL) aBoundRect0=GetLastBoundRect();
720 0 : bool bChg=aAnchor!=rPnt;
721 0 : aAnchor=rPnt;
722 0 : Size aSiz(rPnt.X()-aAnchor.X(),rPnt.Y()-aAnchor.Y());
723 0 : MovePoint(aRefPoint,aSiz);
724 : // move the connectors first, everything else afterwards
725 0 : SdrObjList* pOL=pSub;
726 0 : sal_uIntPtr nObjAnz=pOL->GetObjCount();
727 : sal_uIntPtr i;
728 0 : for (i=0; i<nObjAnz; i++) {
729 0 : SdrObject* pObj=pOL->GetObj(i);
730 0 : if (pObj->IsEdgeObj()) pObj->SetAnchorPos(rPnt);
731 : }
732 0 : for (i=0; i<nObjAnz; i++) {
733 0 : SdrObject* pObj=pOL->GetObj(i);
734 0 : if (!pObj->IsEdgeObj()) pObj->SetAnchorPos(rPnt);
735 : }
736 0 : if (bChg) {
737 0 : SetChanged();
738 0 : BroadcastObjectChange();
739 0 : SendUserCall(SDRUSERCALL_MOVEONLY,aBoundRect0);
740 : }
741 0 : }
742 :
743 :
744 :
745 0 : void SdrObjGroup::NbcSetRelativePos(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 : NbcMove(aSiz); // this also calls SetRectsDirty()
750 0 : }
751 :
752 0 : void SdrObjGroup::SetRelativePos(const Point& rPnt)
753 : {
754 0 : Point aRelPos0(GetSnapRect().TopLeft()-aAnchor);
755 0 : Size aSiz(rPnt.X()-aRelPos0.X(),rPnt.Y()-aRelPos0.Y());
756 0 : if (aSiz.Width()!=0 || aSiz.Height()!=0) Move(aSiz); // this also calls SetRectsDirty() and Broadcast, ...
757 0 : }
758 :
759 0 : void SdrObjGroup::NbcReformatText()
760 : {
761 0 : pSub->NbcReformatAllTextObjects();
762 0 : }
763 :
764 0 : void SdrObjGroup::ReformatText()
765 : {
766 0 : pSub->ReformatAllTextObjects();
767 0 : }
768 :
769 0 : SdrObject* SdrObjGroup::DoConvertToPolyObj(bool bBezier, bool bAddText) const
770 : {
771 0 : SdrObject* pGroup = new SdrObjGroup;
772 0 : pGroup->SetModel(GetModel());
773 :
774 0 : for(sal_uInt32 a=0;a<pSub->GetObjCount();a++)
775 : {
776 0 : SdrObject* pIterObj = pSub->GetObj(a);
777 0 : SdrObject* pResult = pIterObj->DoConvertToPolyObj(bBezier, bAddText);
778 :
779 : // pResult can be NULL e.g. for empty objects
780 0 : if( pResult )
781 0 : pGroup->GetSubList()->NbcInsertObject(pResult);
782 : }
783 :
784 0 : return pGroup;
785 : }
786 :
787 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|