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 :
21 : #include <svx/svdedtv.hxx>
22 : #include <math.h>
23 :
24 : #ifndef _MATH_H
25 : #define _MATH_H
26 : #endif
27 : #include <tools/bigint.hxx>
28 : #include <svl/itemiter.hxx>
29 : #include <vcl/msgbox.hxx>
30 : #include <svx/rectenum.hxx>
31 : #include <svx/svxids.hrc> // for SID_ATTR_TRANSFORM_...
32 : #include <svx/svdattr.hxx> // for Get/SetGeoAttr
33 : #include "svx/svditext.hxx"
34 : #include "svx/svditer.hxx"
35 : #include <svx/svdtrans.hxx>
36 : #include <svx/svdundo.hxx>
37 : #include <svx/svdpage.hxx>
38 : #include <svx/svdpagv.hxx>
39 : #include <svx/svdlayer.hxx> // for MergeNotPersistAttr
40 : #include <svx/svdattrx.hxx> // for MergeNotPersistAttr
41 : #include <svx/svdetc.hxx> // for SearchOutlinerItems
42 : #include <svx/svdopath.hxx> // for Crook
43 : #include "svx/svdstr.hrc" // names taken from the resource
44 : #include "svx/svdglob.hxx" // StringCache
45 : #include <editeng/eeitem.hxx>
46 : #include <svl/aeitem.hxx>
47 : #include <svl/whiter.hxx>
48 : #include <svx/sdr/contact/objectcontact.hxx>
49 : #include <svx/sdr/contact/viewcontact.hxx>
50 : #include <svx/e3dsceneupdater.hxx>
51 : #include <svx/obj3d.hxx>
52 :
53 : ////////////////////////////////////////////////////////////////////////////////////////////////////
54 : ////////////////////////////////////////////////////////////////////////////////////////////////////
55 : // EditView
56 : ////////////////////////////////////////////////////////////////////////////////////////////////////
57 : ////////////////////////////////////////////////////////////////////////////////////////////////////
58 :
59 0 : void SdrEditView::SetMarkedObjRect(const Rectangle& rRect, sal_Bool bCopy)
60 : {
61 : DBG_ASSERT(!rRect.IsEmpty(),"SetMarkedObjRect() with an empty Rect does not make sense.");
62 0 : if (rRect.IsEmpty()) return;
63 0 : sal_uIntPtr nAnz=GetMarkedObjectCount();
64 0 : if (nAnz==0) return;
65 0 : Rectangle aR0(GetMarkedObjRect());
66 : DBG_ASSERT(!aR0.IsEmpty(),"SetMarkedObjRect(): GetMarkedObjRect() is empty.");
67 0 : if (aR0.IsEmpty()) return;
68 0 : long x0=aR0.Left();
69 0 : long y0=aR0.Top();
70 0 : long w0=aR0.Right()-x0;
71 0 : long h0=aR0.Bottom()-y0;
72 0 : long x1=rRect.Left();
73 0 : long y1=rRect.Top();
74 0 : long w1=rRect.Right()-x1;
75 0 : long h1=rRect.Bottom()-y1;
76 0 : XubString aStr;
77 0 : ImpTakeDescriptionStr(STR_EditPosSize,aStr);
78 0 : if (bCopy)
79 0 : aStr+=ImpGetResStr(STR_EditWithCopy);
80 :
81 0 : const bool bUndo = IsUndoEnabled();
82 0 : if( bUndo )
83 0 : BegUndo(aStr);
84 :
85 0 : if (bCopy)
86 0 : CopyMarkedObj();
87 :
88 0 : for (sal_uIntPtr nm=0; nm<nAnz; nm++)
89 : {
90 0 : SdrMark* pM=GetSdrMarkByIndex(nm);
91 0 : SdrObject* pO=pM->GetMarkedSdrObj();
92 0 : if( bUndo )
93 0 : AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO));
94 :
95 0 : Rectangle aR1(pO->GetSnapRect());
96 0 : if (!aR1.IsEmpty())
97 : {
98 0 : if (aR1==aR0)
99 : {
100 0 : aR1=rRect;
101 : }
102 : else
103 : { // transform aR1 to aR0 after rRect
104 0 : aR1.Move(-x0,-y0);
105 0 : BigInt l(aR1.Left());
106 0 : BigInt r(aR1.Right());
107 0 : BigInt t(aR1.Top());
108 0 : BigInt b(aR1.Bottom());
109 0 : if (w0!=0) {
110 0 : l*=w1; l/=w0;
111 0 : r*=w1; r/=w0;
112 : } else {
113 0 : l=0; r=w1;
114 : }
115 0 : if (h0!=0) {
116 0 : t*=h1; t/=h0;
117 0 : b*=h1; b/=h0;
118 : } else {
119 0 : t=0; b=h1;
120 : }
121 0 : aR1.Left ()=long(l);
122 0 : aR1.Right ()=long(r);
123 0 : aR1.Top ()=long(t);
124 0 : aR1.Bottom()=long(b);
125 0 : aR1.Move(x1,y1);
126 : }
127 0 : pO->SetSnapRect(aR1);
128 : } else {
129 : OSL_FAIL("SetMarkedObjRect(): pObj->GetSnapRect() returns empty Rect");
130 : }
131 : }
132 0 : if( bUndo )
133 0 : EndUndo();
134 : }
135 :
136 0 : std::vector< SdrUndoAction* > SdrEditView::CreateConnectorUndo( SdrObject& rO )
137 : {
138 0 : std::vector< SdrUndoAction* > vUndoActions;
139 :
140 0 : if ( rO.GetBroadcaster() )
141 : {
142 0 : const SdrPage* pPage = rO.GetPage();
143 0 : if ( pPage )
144 : {
145 0 : SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS );
146 0 : while( aIter.IsMore() )
147 : {
148 0 : SdrObject* pPartObj = aIter.Next();
149 0 : if ( pPartObj->ISA( SdrEdgeObj ) )
150 : {
151 0 : if ( ( pPartObj->GetConnectedNode( sal_False ) == &rO ) ||
152 0 : ( pPartObj->GetConnectedNode( sal_True ) == &rO ) )
153 : {
154 0 : vUndoActions.push_back( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject( *pPartObj ) );
155 : }
156 : }
157 0 : }
158 : }
159 : }
160 0 : return vUndoActions;
161 : }
162 :
163 0 : void SdrEditView::AddUndoActions( std::vector< SdrUndoAction* >& rUndoActions )
164 : {
165 0 : std::vector< SdrUndoAction* >::iterator aUndoActionIter( rUndoActions.begin() );
166 0 : while( aUndoActionIter != rUndoActions.end() )
167 0 : AddUndo( *aUndoActionIter++ );
168 0 : }
169 :
170 0 : void SdrEditView::MoveMarkedObj(const Size& rSiz, bool bCopy)
171 : {
172 0 : const bool bUndo = IsUndoEnabled();
173 :
174 0 : if( bUndo )
175 : {
176 0 : XubString aStr(ImpGetResStr(STR_EditMove));
177 0 : if (bCopy)
178 0 : aStr+=ImpGetResStr(STR_EditWithCopy);
179 : // meeds its own UndoGroup because of its parameters
180 0 : BegUndo(aStr,GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_MOVE);
181 : }
182 :
183 0 : if (bCopy)
184 0 : CopyMarkedObj();
185 :
186 0 : sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
187 0 : for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++)
188 : {
189 0 : SdrMark* pM=GetSdrMarkByIndex(nm);
190 0 : SdrObject* pO=pM->GetMarkedSdrObj();
191 0 : if( bUndo )
192 : {
193 0 : std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pO ) );
194 0 : AddUndoActions( vConnectorUndoActions );
195 0 : AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoMoveObject(*pO,rSiz));
196 : }
197 0 : pO->Move(rSiz);
198 : }
199 :
200 0 : if( bUndo )
201 0 : EndUndo();
202 0 : }
203 :
204 0 : void SdrEditView::ResizeMarkedObj(const Point& rRef, const Fraction& xFact, const Fraction& yFact, bool bCopy)
205 : {
206 0 : const bool bUndo = IsUndoEnabled();
207 0 : if( bUndo )
208 : {
209 0 : XubString aStr;
210 0 : ImpTakeDescriptionStr(STR_EditResize,aStr);
211 0 : if (bCopy)
212 0 : aStr+=ImpGetResStr(STR_EditWithCopy);
213 0 : BegUndo(aStr);
214 : }
215 :
216 0 : if (bCopy)
217 0 : CopyMarkedObj();
218 :
219 0 : sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
220 0 : for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++)
221 : {
222 0 : SdrMark* pM=GetSdrMarkByIndex(nm);
223 0 : SdrObject* pO=pM->GetMarkedSdrObj();
224 0 : if( bUndo )
225 : {
226 0 : std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pO ) );
227 0 : AddUndoActions( vConnectorUndoActions );
228 0 : AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO));
229 : }
230 0 : pO->Resize(rRef,xFact,yFact);
231 : }
232 :
233 0 : if( bUndo )
234 0 : EndUndo();
235 0 : }
236 :
237 0 : long SdrEditView::GetMarkedObjRotate() const
238 : {
239 0 : sal_Bool b1st=sal_True;
240 0 : sal_Bool bOk=sal_True;
241 0 : long nWink=0;
242 0 : sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
243 0 : for (sal_uIntPtr nm=0; nm<nMarkAnz && bOk; nm++) {
244 0 : SdrMark* pM=GetSdrMarkByIndex(nm);
245 0 : SdrObject* pO=pM->GetMarkedSdrObj();
246 0 : long nWink2=pO->GetRotateAngle();
247 0 : if (b1st) nWink=nWink2;
248 0 : else if (nWink2!=nWink) bOk=sal_False;
249 0 : b1st=sal_False;
250 : }
251 0 : if (!bOk) nWink=0;
252 0 : return nWink;
253 : }
254 :
255 0 : void SdrEditView::RotateMarkedObj(const Point& rRef, long nWink, bool bCopy)
256 : {
257 0 : const bool bUndo = IsUndoEnabled();
258 0 : if( bUndo )
259 : {
260 0 : XubString aStr;
261 0 : ImpTakeDescriptionStr(STR_EditRotate,aStr);
262 0 : if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy);
263 0 : BegUndo(aStr);
264 : }
265 :
266 0 : if (bCopy)
267 0 : CopyMarkedObj();
268 :
269 0 : double nSin=sin(nWink*nPi180);
270 0 : double nCos=cos(nWink*nPi180);
271 0 : const sal_uInt32 nMarkAnz(GetMarkedObjectCount());
272 :
273 0 : if(nMarkAnz)
274 : {
275 0 : std::vector< E3DModifySceneSnapRectUpdater* > aUpdaters;
276 :
277 0 : for(sal_uInt32 nm(0); nm < nMarkAnz; nm++)
278 : {
279 0 : SdrMark* pM = GetSdrMarkByIndex(nm);
280 0 : SdrObject* pO = pM->GetMarkedSdrObj();
281 :
282 0 : if( bUndo )
283 : {
284 : // extra undo actions for changed connector which now may hold its laid out path (SJ)
285 0 : std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pO ) );
286 0 : AddUndoActions( vConnectorUndoActions );
287 :
288 0 : AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO));
289 : }
290 :
291 : // set up a scene updater if object is a 3d object
292 0 : if(dynamic_cast< E3dObject* >(pO))
293 : {
294 0 : aUpdaters.push_back(new E3DModifySceneSnapRectUpdater(pO));
295 : }
296 :
297 0 : pO->Rotate(rRef,nWink,nSin,nCos);
298 : }
299 :
300 : // fire scene updaters
301 0 : while(!aUpdaters.empty())
302 : {
303 0 : delete aUpdaters.back();
304 0 : aUpdaters.pop_back();
305 0 : }
306 : }
307 :
308 0 : if( bUndo )
309 0 : EndUndo();
310 0 : }
311 :
312 0 : void SdrEditView::MirrorMarkedObj(const Point& rRef1, const Point& rRef2, bool bCopy)
313 : {
314 0 : const bool bUndo = IsUndoEnabled();
315 :
316 0 : if( bUndo )
317 : {
318 0 : XubString aStr;
319 0 : Point aDif(rRef2-rRef1);
320 0 : if (aDif.X()==0) ImpTakeDescriptionStr(STR_EditMirrorHori,aStr);
321 0 : else if (aDif.Y()==0) ImpTakeDescriptionStr(STR_EditMirrorVert,aStr);
322 0 : else if (Abs(aDif.X())==Abs(aDif.Y())) ImpTakeDescriptionStr(STR_EditMirrorDiag,aStr);
323 0 : else ImpTakeDescriptionStr(STR_EditMirrorFree,aStr);
324 0 : if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy);
325 0 : BegUndo(aStr);
326 : }
327 :
328 0 : if (bCopy)
329 0 : CopyMarkedObj();
330 :
331 0 : const sal_uInt32 nMarkAnz(GetMarkedObjectCount());
332 :
333 0 : if(nMarkAnz)
334 : {
335 0 : std::vector< E3DModifySceneSnapRectUpdater* > aUpdaters;
336 :
337 0 : for(sal_uInt32 nm(0); nm < nMarkAnz; nm++)
338 : {
339 0 : SdrMark* pM = GetSdrMarkByIndex(nm);
340 0 : SdrObject* pO = pM->GetMarkedSdrObj();
341 :
342 0 : if( bUndo )
343 : {
344 : // extra undo actions for changed connector which now may hold its laid out path (SJ)
345 0 : std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pO ) );
346 0 : AddUndoActions( vConnectorUndoActions );
347 :
348 0 : AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO));
349 : }
350 :
351 : // set up a scene updater if object is a 3d object
352 0 : if(dynamic_cast< E3dObject* >(pO))
353 : {
354 0 : aUpdaters.push_back(new E3DModifySceneSnapRectUpdater(pO));
355 : }
356 :
357 0 : pO->Mirror(rRef1,rRef2);
358 : }
359 :
360 : // fire scene updaters
361 0 : while(!aUpdaters.empty())
362 : {
363 0 : delete aUpdaters.back();
364 0 : aUpdaters.pop_back();
365 0 : }
366 : }
367 :
368 0 : if( bUndo )
369 0 : EndUndo();
370 0 : }
371 :
372 0 : void SdrEditView::MirrorMarkedObjHorizontal(sal_Bool bCopy)
373 : {
374 0 : Point aCenter(GetMarkedObjRect().Center());
375 0 : Point aPt2(aCenter);
376 0 : aPt2.Y()++;
377 0 : MirrorMarkedObj(aCenter,aPt2,bCopy);
378 0 : }
379 :
380 0 : void SdrEditView::MirrorMarkedObjVertical(sal_Bool bCopy)
381 : {
382 0 : Point aCenter(GetMarkedObjRect().Center());
383 0 : Point aPt2(aCenter);
384 0 : aPt2.X()++;
385 0 : MirrorMarkedObj(aCenter,aPt2,bCopy);
386 0 : }
387 :
388 0 : long SdrEditView::GetMarkedObjShear() const
389 : {
390 0 : sal_Bool b1st=sal_True;
391 0 : sal_Bool bOk=sal_True;
392 0 : long nWink=0;
393 0 : sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
394 0 : for (sal_uIntPtr nm=0; nm<nMarkAnz && bOk; nm++) {
395 0 : SdrMark* pM=GetSdrMarkByIndex(nm);
396 0 : SdrObject* pO=pM->GetMarkedSdrObj();
397 0 : long nWink2=pO->GetShearAngle();
398 0 : if (b1st) nWink=nWink2;
399 0 : else if (nWink2!=nWink) bOk=sal_False;
400 0 : b1st=sal_False;
401 : }
402 0 : if (nWink>SDRMAXSHEAR) nWink=SDRMAXSHEAR;
403 0 : if (nWink<-SDRMAXSHEAR) nWink=-SDRMAXSHEAR;
404 0 : if (!bOk) nWink=0;
405 0 : return nWink;
406 : }
407 :
408 0 : void SdrEditView::ShearMarkedObj(const Point& rRef, long nWink, bool bVShear, bool bCopy)
409 : {
410 0 : const bool bUndo = IsUndoEnabled();
411 :
412 0 : if( bUndo )
413 : {
414 0 : XubString aStr;
415 0 : ImpTakeDescriptionStr(STR_EditShear,aStr);
416 0 : if (bCopy)
417 0 : aStr+=ImpGetResStr(STR_EditWithCopy);
418 0 : BegUndo(aStr);
419 : }
420 :
421 0 : if (bCopy)
422 0 : CopyMarkedObj();
423 :
424 0 : double nTan=tan(nWink*nPi180);
425 0 : sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
426 0 : for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++)
427 : {
428 0 : SdrMark* pM=GetSdrMarkByIndex(nm);
429 0 : SdrObject* pO=pM->GetMarkedSdrObj();
430 0 : if( bUndo )
431 : {
432 0 : std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pO ) );
433 0 : AddUndoActions( vConnectorUndoActions );
434 0 : AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO));
435 : }
436 0 : pO->Shear(rRef,nWink,nTan,bVShear);
437 : }
438 :
439 0 : if( bUndo )
440 0 : EndUndo();
441 0 : }
442 :
443 0 : void SdrEditView::ImpCrookObj(SdrObject* pO, const Point& rRef, const Point& rRad,
444 : SdrCrookMode eMode, sal_Bool bVertical, sal_Bool bNoContortion, sal_Bool bRotate, const Rectangle& rMarkRect)
445 : {
446 0 : SdrPathObj* pPath=PTR_CAST(SdrPathObj,pO);
447 0 : sal_Bool bDone = sal_False;
448 :
449 0 : if(pPath!=NULL && !bNoContortion)
450 : {
451 0 : XPolyPolygon aXPP(pPath->GetPathPoly());
452 0 : switch (eMode) {
453 0 : case SDRCROOK_ROTATE : CrookRotatePoly (aXPP,rRef,rRad,bVertical); break;
454 0 : case SDRCROOK_SLANT : CrookSlantPoly (aXPP,rRef,rRad,bVertical); break;
455 0 : case SDRCROOK_STRETCH: CrookStretchPoly(aXPP,rRef,rRad,bVertical,rMarkRect); break;
456 : } // switch
457 0 : pPath->SetPathPoly(aXPP.getB2DPolyPolygon());
458 0 : bDone = sal_True;
459 : }
460 :
461 0 : if(!bDone && !pPath && pO->IsPolyObj() && 0L != pO->GetPointCount())
462 : {
463 : // for PolyObj's, but NOT for SdrPathObj's, e.g. the measurement object
464 0 : sal_uInt32 nPtAnz(pO->GetPointCount());
465 0 : XPolygon aXP((sal_uInt16)nPtAnz);
466 : sal_uInt32 nPtNum;
467 :
468 0 : for(nPtNum = 0L; nPtNum < nPtAnz; nPtNum++)
469 : {
470 0 : Point aPt(pO->GetPoint(nPtNum));
471 0 : aXP[(sal_uInt16)nPtNum]=aPt;
472 : }
473 :
474 0 : switch (eMode)
475 : {
476 0 : case SDRCROOK_ROTATE : CrookRotatePoly (aXP,rRef,rRad,bVertical); break;
477 0 : case SDRCROOK_SLANT : CrookSlantPoly (aXP,rRef,rRad,bVertical); break;
478 0 : case SDRCROOK_STRETCH: CrookStretchPoly(aXP,rRef,rRad,bVertical,rMarkRect); break;
479 : }
480 :
481 0 : for(nPtNum = 0L; nPtNum < nPtAnz; nPtNum++)
482 : {
483 : // broadcasting could be optimized here, but for the
484 : // current two points of the measurement object, it's fine
485 0 : pO->SetPoint(aXP[(sal_uInt16)nPtNum],nPtNum);
486 : }
487 :
488 0 : bDone = sal_True;
489 : }
490 :
491 0 : if(!bDone)
492 : {
493 : // for all others or if bNoContortion
494 0 : Point aCtr0(pO->GetSnapRect().Center());
495 0 : Point aCtr1(aCtr0);
496 0 : sal_Bool bRotOk(sal_False);
497 0 : double nSin(0.0), nCos(1.0);
498 0 : double nWink(0.0);
499 :
500 0 : if(0 != rRad.X() && 0 != rRad.Y())
501 : {
502 0 : bRotOk = bRotate;
503 :
504 0 : switch (eMode)
505 : {
506 0 : case SDRCROOK_ROTATE : nWink=CrookRotateXPoint (aCtr1,NULL,NULL,rRef,rRad,nSin,nCos,bVertical); bRotOk=bRotate; break;
507 0 : case SDRCROOK_SLANT : nWink=CrookSlantXPoint (aCtr1,NULL,NULL,rRef,rRad,nSin,nCos,bVertical); break;
508 0 : case SDRCROOK_STRETCH: nWink=CrookStretchXPoint(aCtr1,NULL,NULL,rRef,rRad,nSin,nCos,bVertical,rMarkRect); break;
509 : }
510 : }
511 :
512 0 : aCtr1 -= aCtr0;
513 :
514 0 : if(bRotOk)
515 0 : pO->Rotate(aCtr0, Round(nWink/nPi180), nSin, nCos);
516 :
517 0 : pO->Move(Size(aCtr1.X(),aCtr1.Y()));
518 : }
519 0 : }
520 :
521 0 : void SdrEditView::CrookMarkedObj(const Point& rRef, const Point& rRad, SdrCrookMode eMode,
522 : bool bVertical, bool bNoContortion, bool bCopy)
523 : {
524 0 : Rectangle aMarkRect(GetMarkedObjRect());
525 0 : const bool bUndo = IsUndoEnabled();
526 :
527 0 : bool bRotate=bNoContortion && eMode==SDRCROOK_ROTATE && IsRotateAllowed(sal_False);
528 :
529 0 : if( bUndo )
530 : {
531 0 : XubString aStr;
532 0 : ImpTakeDescriptionStr(bNoContortion?STR_EditCrook:STR_EditCrookContortion,aStr);
533 0 : if (bCopy)
534 0 : aStr+=ImpGetResStr(STR_EditWithCopy);
535 0 : BegUndo(aStr);
536 : }
537 :
538 0 : if (bCopy)
539 0 : CopyMarkedObj();
540 :
541 0 : sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
542 0 : for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++)
543 : {
544 0 : SdrMark* pM=GetSdrMarkByIndex(nm);
545 0 : SdrObject* pO=pM->GetMarkedSdrObj();
546 0 : if( bUndo )
547 0 : AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO));
548 :
549 0 : const SdrObjList* pOL=pO->GetSubList();
550 0 : if (bNoContortion || pOL==NULL) {
551 0 : ImpCrookObj(pO,rRef,rRad,eMode,bVertical,bNoContortion,bRotate,aMarkRect);
552 : } else {
553 0 : SdrObjListIter aIter(*pOL,IM_DEEPNOGROUPS);
554 0 : while (aIter.IsMore()) {
555 0 : SdrObject* pO1=aIter.Next();
556 0 : ImpCrookObj(pO1,rRef,rRad,eMode,bVertical,bNoContortion,bRotate,aMarkRect);
557 0 : }
558 : }
559 : }
560 :
561 0 : if( bUndo )
562 0 : EndUndo();
563 0 : }
564 :
565 0 : void SdrEditView::ImpDistortObj(SdrObject* pO, const Rectangle& rRef, const XPolygon& rDistortedRect, sal_Bool bNoContortion)
566 : {
567 0 : SdrPathObj* pPath = PTR_CAST(SdrPathObj, pO);
568 :
569 0 : if(!bNoContortion && pPath)
570 : {
571 0 : XPolyPolygon aXPP(pPath->GetPathPoly());
572 0 : aXPP.Distort(rRef, rDistortedRect);
573 0 : pPath->SetPathPoly(aXPP.getB2DPolyPolygon());
574 : }
575 0 : else if(pO->IsPolyObj())
576 : {
577 : // e. g. for the measurement object
578 0 : sal_uInt32 nPtAnz(pO->GetPointCount());
579 0 : XPolygon aXP((sal_uInt16)nPtAnz);
580 : sal_uInt32 nPtNum;
581 :
582 0 : for(nPtNum = 0L; nPtNum < nPtAnz; nPtNum++)
583 : {
584 0 : Point aPt(pO->GetPoint(nPtNum));
585 0 : aXP[(sal_uInt16)nPtNum]=aPt;
586 : }
587 :
588 0 : aXP.Distort(rRef, rDistortedRect);
589 :
590 0 : for(nPtNum = 0L; nPtNum < nPtAnz; nPtNum++)
591 : {
592 : // broadcasting could be optimized here, but for the
593 : // current two points of the measurement object it's fine
594 0 : pO->SetPoint(aXP[(sal_uInt16)nPtNum],nPtNum);
595 0 : }
596 : }
597 0 : }
598 :
599 0 : void SdrEditView::DistortMarkedObj(const Rectangle& rRef, const XPolygon& rDistortedRect, bool bNoContortion, bool bCopy)
600 : {
601 0 : const bool bUndo = IsUndoEnabled();
602 :
603 0 : if( bUndo )
604 : {
605 0 : XubString aStr;
606 0 : ImpTakeDescriptionStr(STR_EditDistort,aStr);
607 0 : if (bCopy)
608 0 : aStr+=ImpGetResStr(STR_EditWithCopy);
609 0 : BegUndo(aStr);
610 : }
611 :
612 0 : if (bCopy)
613 0 : CopyMarkedObj();
614 :
615 0 : sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
616 0 : for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++)
617 : {
618 0 : SdrMark* pM=GetSdrMarkByIndex(nm);
619 0 : SdrObject* pO=pM->GetMarkedSdrObj();
620 0 : if( bUndo )
621 0 : AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pO));
622 :
623 0 : Rectangle aRefRect(rRef);
624 0 : XPolygon aRefPoly(rDistortedRect);
625 0 : const SdrObjList* pOL=pO->GetSubList();
626 0 : if (bNoContortion || pOL==NULL) {
627 0 : ImpDistortObj(pO,aRefRect,aRefPoly,bNoContortion);
628 : } else {
629 0 : SdrObjListIter aIter(*pOL,IM_DEEPNOGROUPS);
630 0 : while (aIter.IsMore()) {
631 0 : SdrObject* pO1=aIter.Next();
632 0 : ImpDistortObj(pO1,aRefRect,aRefPoly,bNoContortion);
633 0 : }
634 : }
635 0 : }
636 0 : if( bUndo )
637 0 : EndUndo();
638 0 : }
639 :
640 : ////////////////////////////////////////////////////////////////////////////////////////////////////
641 :
642 0 : void SdrEditView::SetNotPersistAttrToMarked(const SfxItemSet& rAttr, sal_Bool /*bReplaceAll*/)
643 : {
644 : // bReplaceAll has no effect here
645 0 : Rectangle aAllSnapRect(GetMarkedObjRect());
646 0 : const SfxPoolItem *pPoolItem=NULL;
647 0 : if (rAttr.GetItemState(SDRATTR_TRANSFORMREF1X,sal_True,&pPoolItem)==SFX_ITEM_SET) {
648 0 : long n=((const SdrTransformRef1XItem*)pPoolItem)->GetValue();
649 0 : SetRef1(Point(n,GetRef1().Y()));
650 : }
651 0 : if (rAttr.GetItemState(SDRATTR_TRANSFORMREF1Y,sal_True,&pPoolItem)==SFX_ITEM_SET) {
652 0 : long n=((const SdrTransformRef1YItem*)pPoolItem)->GetValue();
653 0 : SetRef1(Point(GetRef1().X(),n));
654 : }
655 0 : if (rAttr.GetItemState(SDRATTR_TRANSFORMREF2X,sal_True,&pPoolItem)==SFX_ITEM_SET) {
656 0 : long n=((const SdrTransformRef2XItem*)pPoolItem)->GetValue();
657 0 : SetRef2(Point(n,GetRef2().Y()));
658 : }
659 0 : if (rAttr.GetItemState(SDRATTR_TRANSFORMREF2Y,sal_True,&pPoolItem)==SFX_ITEM_SET) {
660 0 : long n=((const SdrTransformRef2YItem*)pPoolItem)->GetValue();
661 0 : SetRef2(Point(GetRef2().X(),n));
662 : }
663 0 : long nAllPosX=0; sal_Bool bAllPosX=sal_False;
664 0 : long nAllPosY=0; sal_Bool bAllPosY=sal_False;
665 0 : long nAllWdt=0; sal_Bool bAllWdt=sal_False;
666 0 : long nAllHgt=0; sal_Bool bAllHgt=sal_False;
667 0 : sal_Bool bDoIt=sal_False;
668 0 : if (rAttr.GetItemState(SDRATTR_ALLPOSITIONX,sal_True,&pPoolItem)==SFX_ITEM_SET) {
669 0 : nAllPosX=((const SdrAllPositionXItem*)pPoolItem)->GetValue();
670 0 : bAllPosX=sal_True; bDoIt=sal_True;
671 : }
672 0 : if (rAttr.GetItemState(SDRATTR_ALLPOSITIONY,sal_True,&pPoolItem)==SFX_ITEM_SET) {
673 0 : nAllPosY=((const SdrAllPositionYItem*)pPoolItem)->GetValue();
674 0 : bAllPosY=sal_True; bDoIt=sal_True;
675 : }
676 0 : if (rAttr.GetItemState(SDRATTR_ALLSIZEWIDTH,sal_True,&pPoolItem)==SFX_ITEM_SET) {
677 0 : nAllWdt=((const SdrAllSizeWidthItem*)pPoolItem)->GetValue();
678 0 : bAllWdt=sal_True; bDoIt=sal_True;
679 : }
680 0 : if (rAttr.GetItemState(SDRATTR_ALLSIZEHEIGHT,sal_True,&pPoolItem)==SFX_ITEM_SET) {
681 0 : nAllHgt=((const SdrAllSizeHeightItem*)pPoolItem)->GetValue();
682 0 : bAllHgt=sal_True; bDoIt=sal_True;
683 : }
684 0 : if (bDoIt) {
685 0 : Rectangle aRect(aAllSnapRect); // TODO: change this for PolyPt's and GluePt's!!!
686 0 : if (bAllPosX) aRect.Move(nAllPosX-aRect.Left(),0);
687 0 : if (bAllPosY) aRect.Move(0,nAllPosY-aRect.Top());
688 0 : if (bAllWdt) aRect.Right()=aAllSnapRect.Left()+nAllWdt;
689 0 : if (bAllHgt) aRect.Bottom()=aAllSnapRect.Top()+nAllHgt;
690 0 : SetMarkedObjRect(aRect);
691 : }
692 0 : if (rAttr.GetItemState(SDRATTR_RESIZEXALL,sal_True,&pPoolItem)==SFX_ITEM_SET) {
693 0 : Fraction aXFact=((const SdrResizeXAllItem*)pPoolItem)->GetValue();
694 0 : ResizeMarkedObj(aAllSnapRect.TopLeft(),aXFact,Fraction(1,1));
695 : }
696 0 : if (rAttr.GetItemState(SDRATTR_RESIZEYALL,sal_True,&pPoolItem)==SFX_ITEM_SET) {
697 0 : Fraction aYFact=((const SdrResizeYAllItem*)pPoolItem)->GetValue();
698 0 : ResizeMarkedObj(aAllSnapRect.TopLeft(),Fraction(1,1),aYFact);
699 : }
700 0 : if (rAttr.GetItemState(SDRATTR_ROTATEALL,sal_True,&pPoolItem)==SFX_ITEM_SET) {
701 0 : long nAngle=((const SdrRotateAllItem*)pPoolItem)->GetValue();
702 0 : RotateMarkedObj(aAllSnapRect.Center(),nAngle);
703 : }
704 0 : if (rAttr.GetItemState(SDRATTR_HORZSHEARALL,sal_True,&pPoolItem)==SFX_ITEM_SET) {
705 0 : long nAngle=((const SdrHorzShearAllItem*)pPoolItem)->GetValue();
706 0 : ShearMarkedObj(aAllSnapRect.Center(),nAngle,sal_False);
707 : }
708 0 : if (rAttr.GetItemState(SDRATTR_VERTSHEARALL,sal_True,&pPoolItem)==SFX_ITEM_SET) {
709 0 : long nAngle=((const SdrVertShearAllItem*)pPoolItem)->GetValue();
710 0 : ShearMarkedObj(aAllSnapRect.Center(),nAngle,sal_True);
711 : }
712 :
713 0 : const bool bUndo = IsUndoEnabled();
714 :
715 : // TODO: check if WhichRange is necessary.
716 0 : sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
717 0 : for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++)
718 : {
719 0 : const SdrMark* pM=GetSdrMarkByIndex(nm);
720 0 : SdrObject* pObj=pM->GetMarkedSdrObj();
721 0 : if( bUndo )
722 0 : AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
723 :
724 0 : pObj->ApplyNotPersistAttr(rAttr);
725 : }
726 0 : }
727 :
728 0 : void SdrEditView::MergeNotPersistAttrFromMarked(SfxItemSet& rAttr, sal_Bool /*bOnlyHardAttr*/) const
729 : {
730 : // bOnlyHardAttr has no effect here.
731 : // TODO: Take into account the origin and PvPos.
732 0 : Rectangle aAllSnapRect(GetMarkedObjRect()); // TODO: change this for PolyPt's and GluePt's!!!
733 0 : long nAllSnapPosX=aAllSnapRect.Left();
734 0 : long nAllSnapPosY=aAllSnapRect.Top();
735 0 : long nAllSnapWdt=aAllSnapRect.GetWidth()-1;
736 0 : long nAllSnapHgt=aAllSnapRect.GetHeight()-1;
737 : // TODO: could go into CheckPossibilities
738 0 : bool bMovProtect = false, bMovProtectDC = false;
739 0 : bool bSizProtect = false, bSizProtectDC = false;
740 0 : bool bPrintable = true, bPrintableDC = false;
741 0 : bool bVisible = true, bVisibleDC = false;
742 0 : SdrLayerID nLayerId=0; sal_Bool bLayerDC=sal_False;
743 0 : rtl::OUString aObjName;
744 0 : sal_Bool bObjNameDC=sal_False,bObjNameSet=sal_False;
745 0 : long nSnapPosX=0; sal_Bool bSnapPosXDC=sal_False;
746 0 : long nSnapPosY=0; sal_Bool bSnapPosYDC=sal_False;
747 0 : long nSnapWdt=0; sal_Bool bSnapWdtDC=sal_False;
748 0 : long nSnapHgt=0; sal_Bool bSnapHgtDC=sal_False;
749 0 : long nLogicWdt=0; sal_Bool bLogicWdtDC=sal_False,bLogicWdtDiff=sal_False;
750 0 : long nLogicHgt=0; sal_Bool bLogicHgtDC=sal_False,bLogicHgtDiff=sal_False;
751 0 : long nRotAngle=0; sal_Bool bRotAngleDC=sal_False;
752 0 : long nShrAngle=0; sal_Bool bShrAngleDC=sal_False;
753 0 : Rectangle aSnapRect;
754 0 : Rectangle aLogicRect;
755 0 : sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
756 0 : for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++) {
757 0 : const SdrMark* pM=GetSdrMarkByIndex(nm);
758 0 : const SdrObject* pObj=pM->GetMarkedSdrObj();
759 0 : if (nm==0) {
760 0 : nLayerId=pObj->GetLayer();
761 0 : bMovProtect=pObj->IsMoveProtect();
762 0 : bSizProtect=pObj->IsResizeProtect();
763 0 : bPrintable =pObj->IsPrintable();
764 0 : bVisible = pObj->IsVisible();
765 0 : Rectangle aSnapRect2(pObj->GetSnapRect());
766 0 : Rectangle aLogicRect2(pObj->GetLogicRect());
767 0 : nSnapPosX=aSnapRect2.Left();
768 0 : nSnapPosY=aSnapRect2.Top();
769 0 : nSnapWdt=aSnapRect2.GetWidth()-1;
770 0 : nSnapHgt=aSnapRect2.GetHeight()-1;
771 0 : nLogicWdt=aLogicRect2.GetWidth()-1;
772 0 : nLogicHgt=aLogicRect2.GetHeight()-1;
773 0 : bLogicWdtDiff=nLogicWdt!=nSnapWdt;
774 0 : bLogicHgtDiff=nLogicHgt!=nSnapHgt;
775 0 : nRotAngle=pObj->GetRotateAngle();
776 0 : nShrAngle=pObj->GetShearAngle();
777 : } else {
778 0 : if (!bLayerDC && nLayerId !=pObj->GetLayer()) bLayerDC = true;
779 0 : if (!bMovProtectDC && bMovProtect!=pObj->IsMoveProtect()) bMovProtectDC = true;
780 0 : if (!bSizProtectDC && bSizProtect!=pObj->IsResizeProtect()) bSizProtectDC = true;
781 0 : if (!bPrintableDC && bPrintable !=pObj->IsPrintable()) bPrintableDC = true;
782 0 : if (!bVisibleDC && bVisible !=pObj->IsVisible()) bVisibleDC=true;
783 0 : if (!bRotAngleDC && nRotAngle !=pObj->GetRotateAngle()) bRotAngleDC=sal_True;
784 0 : if (!bShrAngleDC && nShrAngle !=pObj->GetShearAngle()) bShrAngleDC=sal_True;
785 0 : if (!bSnapWdtDC || !bSnapHgtDC || !bSnapPosXDC || !bSnapPosYDC || !bLogicWdtDiff || !bLogicHgtDiff) {
786 0 : aSnapRect=pObj->GetSnapRect();
787 0 : if (nSnapPosX!=aSnapRect.Left()) bSnapPosXDC=sal_True;
788 0 : if (nSnapPosY!=aSnapRect.Top()) bSnapPosYDC=sal_True;
789 0 : if (nSnapWdt!=aSnapRect.GetWidth()-1) bSnapWdtDC=sal_True;
790 0 : if (nSnapHgt!=aSnapRect.GetHeight()-1) bSnapHgtDC=sal_True;
791 : }
792 0 : if (!bLogicWdtDC || !bLogicHgtDC || !bLogicWdtDiff || !bLogicHgtDiff) {
793 0 : aLogicRect=pObj->GetLogicRect();
794 0 : if (nLogicWdt!=aLogicRect.GetWidth()-1) bLogicWdtDC=sal_True;
795 0 : if (nLogicHgt!=aLogicRect.GetHeight()-1) bLogicHgtDC=sal_True;
796 0 : if (!bLogicWdtDiff && aSnapRect.GetWidth()!=aLogicRect.GetWidth()) bLogicWdtDiff=sal_True;
797 0 : if (!bLogicHgtDiff && aSnapRect.GetHeight()!=aLogicRect.GetHeight()) bLogicHgtDiff=sal_True;
798 : }
799 : }
800 0 : if (!bObjNameDC ) {
801 0 : if (!bObjNameSet) {
802 0 : aObjName=pObj->GetName();
803 : } else {
804 0 : if (!aObjName.equals(pObj->GetName()))
805 0 : bObjNameDC = true;
806 : }
807 : }
808 : }
809 :
810 0 : if (bSnapPosXDC || nAllSnapPosX!=nSnapPosX) rAttr.Put(SdrAllPositionXItem(nAllSnapPosX));
811 0 : if (bSnapPosYDC || nAllSnapPosY!=nSnapPosY) rAttr.Put(SdrAllPositionYItem(nAllSnapPosY));
812 0 : if (bSnapWdtDC || nAllSnapWdt !=nSnapWdt ) rAttr.Put(SdrAllSizeWidthItem(nAllSnapWdt));
813 0 : if (bSnapHgtDC || nAllSnapHgt !=nSnapHgt ) rAttr.Put(SdrAllSizeHeightItem(nAllSnapHgt));
814 :
815 : // items for pure transformations
816 0 : rAttr.Put(SdrMoveXItem());
817 0 : rAttr.Put(SdrMoveYItem());
818 0 : rAttr.Put(SdrResizeXOneItem());
819 0 : rAttr.Put(SdrResizeYOneItem());
820 0 : rAttr.Put(SdrRotateOneItem());
821 0 : rAttr.Put(SdrHorzShearOneItem());
822 0 : rAttr.Put(SdrVertShearOneItem());
823 :
824 0 : if (nMarkAnz>1) {
825 0 : rAttr.Put(SdrResizeXAllItem());
826 0 : rAttr.Put(SdrResizeYAllItem());
827 0 : rAttr.Put(SdrRotateAllItem());
828 0 : rAttr.Put(SdrHorzShearAllItem());
829 0 : rAttr.Put(SdrVertShearAllItem());
830 : }
831 :
832 0 : if(eDragMode == SDRDRAG_ROTATE || eDragMode == SDRDRAG_MIRROR)
833 : {
834 0 : rAttr.Put(SdrTransformRef1XItem(GetRef1().X()));
835 0 : rAttr.Put(SdrTransformRef1YItem(GetRef1().Y()));
836 : }
837 :
838 0 : if(eDragMode == SDRDRAG_MIRROR)
839 : {
840 0 : rAttr.Put(SdrTransformRef2XItem(GetRef2().X()));
841 0 : rAttr.Put(SdrTransformRef2YItem(GetRef2().Y()));
842 0 : }
843 0 : }
844 :
845 0 : SfxItemSet SdrEditView::GetAttrFromMarked(sal_Bool bOnlyHardAttr) const
846 : {
847 0 : SfxItemSet aSet(pMod->GetItemPool());
848 0 : MergeAttrFromMarked(aSet,bOnlyHardAttr);
849 : //the EE_FEATURE items should not be set with SetAttrToMarked (see error message there)
850 : //so we do not set them here
851 : // #i32448#
852 : // Do not disable, but clear the items.
853 0 : aSet.ClearItem(EE_FEATURE_TAB);
854 0 : aSet.ClearItem(EE_FEATURE_LINEBR);
855 0 : aSet.ClearItem(EE_FEATURE_NOTCONV);
856 0 : aSet.ClearItem(EE_FEATURE_FIELD);
857 0 : return aSet;
858 : }
859 :
860 0 : void SdrEditView::MergeAttrFromMarked(SfxItemSet& rAttr, sal_Bool bOnlyHardAttr) const
861 : {
862 0 : sal_uInt32 nMarkAnz(GetMarkedObjectCount());
863 :
864 0 : for(sal_uInt32 a(0); a < nMarkAnz; a++)
865 : {
866 : // #80277# merging was done wrong in the prev version
867 0 : const SfxItemSet& rSet = GetMarkedObjectByIndex(a)->GetMergedItemSet();
868 0 : SfxWhichIter aIter(rSet);
869 0 : sal_uInt16 nWhich(aIter.FirstWhich());
870 :
871 0 : while(nWhich)
872 : {
873 0 : if(!bOnlyHardAttr)
874 : {
875 0 : if(SFX_ITEM_DONTCARE == rSet.GetItemState(nWhich, sal_False))
876 0 : rAttr.InvalidateItem(nWhich);
877 : else
878 0 : rAttr.MergeValue(rSet.Get(nWhich), sal_True);
879 : }
880 0 : else if(SFX_ITEM_SET == rSet.GetItemState(nWhich, sal_False))
881 : {
882 0 : const SfxPoolItem& rItem = rSet.Get(nWhich);
883 0 : rAttr.MergeValue(rItem, sal_True);
884 : }
885 :
886 0 : nWhich = aIter.NextWhich();
887 : }
888 0 : }
889 0 : }
890 :
891 0 : void SdrEditView::SetAttrToMarked(const SfxItemSet& rAttr, sal_Bool bReplaceAll)
892 : {
893 0 : if (AreObjectsMarked())
894 : {
895 : #ifdef DBG_UTIL
896 : {
897 : sal_Bool bHasEEFeatureItems=sal_False;
898 : SfxItemIter aIter(rAttr);
899 : const SfxPoolItem* pItem=aIter.FirstItem();
900 : while (!bHasEEFeatureItems && pItem!=NULL) {
901 : if (!IsInvalidItem(pItem)) {
902 : sal_uInt16 nW=pItem->Which();
903 : if (nW>=EE_FEATURE_START && nW<=EE_FEATURE_END) bHasEEFeatureItems=sal_True;
904 : }
905 : pItem=aIter.NextItem();
906 : }
907 : if(bHasEEFeatureItems)
908 : {
909 : String aMessage;
910 : aMessage.AppendAscii("SdrEditView::SetAttrToMarked(): Setting EE_FEATURE items at the SdrView does not make sense! It only leads to overhead and unreadable documents.");
911 : InfoBox(NULL, aMessage).Execute();
912 : }
913 : }
914 : #endif
915 :
916 : // #103836# if the user thets character attributes to the complete shape,
917 : // we want to remove all hard set character attributes with same
918 : // which ids from the text. We do that later but here we remember
919 : // all character attribute which id's that are set.
920 0 : std::vector<sal_uInt16> aCharWhichIds;
921 : {
922 0 : SfxItemIter aIter(rAttr);
923 0 : const SfxPoolItem* pItem=aIter.FirstItem();
924 0 : while( pItem!=NULL )
925 : {
926 0 : if (!IsInvalidItem(pItem))
927 : {
928 0 : sal_uInt16 nWhich = pItem->Which();
929 0 : if (nWhich>=EE_CHAR_START && nWhich<=EE_CHAR_END)
930 0 : aCharWhichIds.push_back( nWhich );
931 : }
932 0 : pItem=aIter.NextItem();
933 0 : }
934 : }
935 :
936 : // To make Undo reconstruct text attributes correctly after Format.Standard
937 0 : sal_Bool bHasEEItems=SearchOutlinerItems(rAttr,bReplaceAll);
938 :
939 : // save additional geometry information when paragraph or character attributes
940 : // are changed and the geometrical shape of the text object might be changed
941 0 : sal_Bool bPossibleGeomChange(sal_False);
942 0 : SfxWhichIter aIter(rAttr);
943 0 : sal_uInt16 nWhich = aIter.FirstWhich();
944 0 : while(!bPossibleGeomChange && nWhich)
945 : {
946 0 : SfxItemState eState = rAttr.GetItemState(nWhich);
947 0 : if(eState == SFX_ITEM_SET)
948 : {
949 0 : if((nWhich >= SDRATTR_TEXT_MINFRAMEHEIGHT && nWhich <= SDRATTR_TEXT_CONTOURFRAME)
950 : || nWhich == SDRATTR_3DOBJ_PERCENT_DIAGONAL
951 : || nWhich == SDRATTR_3DOBJ_BACKSCALE
952 : || nWhich == SDRATTR_3DOBJ_DEPTH
953 : || nWhich == SDRATTR_3DOBJ_END_ANGLE
954 : || nWhich == SDRATTR_3DSCENE_DISTANCE)
955 : {
956 0 : bPossibleGeomChange = sal_True;
957 : }
958 : }
959 0 : nWhich = aIter.NextWhich();
960 : }
961 :
962 0 : const bool bUndo = IsUndoEnabled();
963 0 : if( bUndo )
964 : {
965 0 : XubString aStr;
966 0 : ImpTakeDescriptionStr(STR_EditSetAttributes,aStr);
967 0 : BegUndo(aStr);
968 : }
969 :
970 0 : const sal_uInt32 nMarkAnz(GetMarkedObjectCount());
971 0 : std::vector< E3DModifySceneSnapRectUpdater* > aUpdaters;
972 :
973 : // create ItemSet without SFX_ITEM_DONTCARE. Put()
974 : // uses its second parameter (bInvalidAsDefault) to
975 : // remove all such items to set them to default.
976 0 : SfxItemSet aAttr(*rAttr.GetPool(), rAttr.GetRanges());
977 0 : aAttr.Put(rAttr, sal_True);
978 :
979 : // #i38135#
980 0 : bool bResetAnimationTimer(false);
981 :
982 0 : for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++)
983 : {
984 0 : SdrMark* pM=GetSdrMarkByIndex(nm);
985 0 : SdrObject* pObj = pM->GetMarkedSdrObj();
986 :
987 0 : if( bUndo )
988 : {
989 0 : std::vector< SdrUndoAction* > vConnectorUndoActions;
990 0 : SdrEdgeObj* pEdgeObj = dynamic_cast< SdrEdgeObj* >( pObj );
991 0 : if ( pEdgeObj )
992 0 : bPossibleGeomChange = sal_True;
993 0 : else if( bUndo )
994 0 : vConnectorUndoActions = CreateConnectorUndo( *pObj );
995 :
996 0 : AddUndoActions( vConnectorUndoActions );
997 : }
998 :
999 : // new geometry undo
1000 0 : if(bPossibleGeomChange && bUndo)
1001 : {
1002 : // save position and size of object, too
1003 0 : AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
1004 : }
1005 :
1006 0 : if( bUndo )
1007 : {
1008 : // #i8508#
1009 : // If this is a text object also rescue the OutlinerParaObject since
1010 : // applying attributes to the object may change text layout when
1011 : // multiple portions exist with multiple formats. If a OutlinerParaObject
1012 : // really exists and needs to be rescued is evaluated in the undo
1013 : // implementation itself.
1014 0 : const bool bRescueText = dynamic_cast< SdrTextObj* >(pObj) != 0;
1015 :
1016 : // add attribute undo
1017 0 : AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pObj,sal_False,bHasEEItems || bPossibleGeomChange || bRescueText));
1018 : }
1019 :
1020 : // set up a scene updater if object is a 3d object
1021 0 : if(dynamic_cast< E3dObject* >(pObj))
1022 : {
1023 0 : aUpdaters.push_back(new E3DModifySceneSnapRectUpdater(pObj));
1024 : }
1025 :
1026 : // set attributes at object
1027 0 : pObj->SetMergedItemSetAndBroadcast(aAttr, bReplaceAll);
1028 :
1029 0 : if(pObj->ISA(SdrTextObj))
1030 : {
1031 0 : SdrTextObj* pTextObj = ((SdrTextObj*)pObj);
1032 :
1033 0 : if(!aCharWhichIds.empty())
1034 : {
1035 0 : Rectangle aOldBoundRect = pTextObj->GetLastBoundRect();
1036 :
1037 : // #110094#-14 pTextObj->SendRepaintBroadcast(pTextObj->GetBoundRect());
1038 0 : pTextObj->RemoveOutlinerCharacterAttribs( aCharWhichIds );
1039 :
1040 : // object has changed, should be called from
1041 : // RemoveOutlinerCharacterAttribs. This will change when the text
1042 : // object implementation changes.
1043 0 : pTextObj->SetChanged();
1044 :
1045 0 : pTextObj->BroadcastObjectChange();
1046 0 : pTextObj->SendUserCall(SDRUSERCALL_CHGATTR, aOldBoundRect);
1047 : }
1048 : }
1049 :
1050 : // #i38495#
1051 0 : if(!bResetAnimationTimer)
1052 : {
1053 0 : if(pObj->GetViewContact().isAnimatedInAnyViewObjectContact())
1054 : {
1055 0 : bResetAnimationTimer = true;
1056 : }
1057 : }
1058 : }
1059 :
1060 : // fire scene updaters
1061 0 : while(!aUpdaters.empty())
1062 : {
1063 0 : delete aUpdaters.back();
1064 0 : aUpdaters.pop_back();
1065 : }
1066 :
1067 : // #i38135#
1068 0 : if(bResetAnimationTimer)
1069 : {
1070 0 : SetAnimationTimer(0L);
1071 : }
1072 :
1073 : // better check before what to do:
1074 : // pObj->SetAttr() or SetNotPersistAttr()
1075 : // TODO: missing implementation!
1076 0 : SetNotPersistAttrToMarked(rAttr,bReplaceAll);
1077 :
1078 0 : if( bUndo )
1079 0 : EndUndo();
1080 : }
1081 0 : }
1082 :
1083 0 : SfxStyleSheet* SdrEditView::GetStyleSheetFromMarked() const
1084 : {
1085 0 : SfxStyleSheet* pRet=NULL;
1086 0 : sal_Bool b1st=sal_True;
1087 0 : sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
1088 0 : for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++) {
1089 0 : SdrMark* pM=GetSdrMarkByIndex(nm);
1090 0 : SfxStyleSheet* pSS=pM->GetMarkedSdrObj()->GetStyleSheet();
1091 0 : if (b1st) pRet=pSS;
1092 0 : else if (pRet!=pSS) return NULL; // different stylesheets
1093 0 : b1st=sal_False;
1094 : }
1095 0 : return pRet;
1096 : }
1097 :
1098 0 : void SdrEditView::SetStyleSheetToMarked(SfxStyleSheet* pStyleSheet, sal_Bool bDontRemoveHardAttr)
1099 : {
1100 0 : if (AreObjectsMarked())
1101 : {
1102 0 : const bool bUndo = IsUndoEnabled();
1103 :
1104 0 : if( bUndo )
1105 : {
1106 0 : XubString aStr;
1107 0 : if (pStyleSheet!=NULL)
1108 0 : ImpTakeDescriptionStr(STR_EditSetStylesheet,aStr);
1109 : else
1110 0 : ImpTakeDescriptionStr(STR_EditDelStylesheet,aStr);
1111 0 : BegUndo(aStr);
1112 : }
1113 :
1114 0 : sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
1115 0 : for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++)
1116 : {
1117 0 : SdrMark* pM=GetSdrMarkByIndex(nm);
1118 0 : if( bUndo )
1119 : {
1120 0 : AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pM->GetMarkedSdrObj()));
1121 0 : AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoAttrObject(*pM->GetMarkedSdrObj(),true,true));
1122 : }
1123 0 : pM->GetMarkedSdrObj()->SetStyleSheet(pStyleSheet,bDontRemoveHardAttr);
1124 : }
1125 :
1126 0 : if( bUndo )
1127 0 : EndUndo();
1128 : }
1129 0 : }
1130 :
1131 : ////////////////////////////////////////////////////////////////////////////////////////////////////
1132 :
1133 0 : sal_Bool SdrEditView::GetAttributes(SfxItemSet& rTargetSet, sal_Bool bOnlyHardAttr) const
1134 : {
1135 0 : if(GetMarkedObjectCount())
1136 : {
1137 0 : rTargetSet.Put(GetAttrFromMarked(bOnlyHardAttr), sal_False);
1138 0 : return sal_True;
1139 : }
1140 : else
1141 : {
1142 0 : return SdrMarkView::GetAttributes(rTargetSet, bOnlyHardAttr);
1143 : }
1144 : }
1145 :
1146 0 : sal_Bool SdrEditView::SetAttributes(const SfxItemSet& rSet, sal_Bool bReplaceAll)
1147 : {
1148 0 : if (GetMarkedObjectCount()!=0) {
1149 0 : SetAttrToMarked(rSet,bReplaceAll);
1150 0 : return sal_True;
1151 : } else {
1152 0 : return SdrMarkView::SetAttributes(rSet,bReplaceAll);
1153 : }
1154 : }
1155 :
1156 0 : SfxStyleSheet* SdrEditView::GetStyleSheet() const
1157 : {
1158 0 : if (GetMarkedObjectCount()!=0) {
1159 0 : return GetStyleSheetFromMarked();
1160 : } else {
1161 0 : return SdrMarkView::GetStyleSheet();
1162 : }
1163 : }
1164 :
1165 0 : sal_Bool SdrEditView::SetStyleSheet(SfxStyleSheet* pStyleSheet, sal_Bool bDontRemoveHardAttr)
1166 : {
1167 0 : if (GetMarkedObjectCount()!=0) {
1168 0 : SetStyleSheetToMarked(pStyleSheet,bDontRemoveHardAttr);
1169 0 : return sal_True;
1170 : } else {
1171 0 : return SdrMarkView::SetStyleSheet(pStyleSheet,bDontRemoveHardAttr);
1172 : }
1173 : }
1174 :
1175 : ////////////////////////////////////////////////////////////////////////////////////////////////////
1176 :
1177 0 : SfxItemSet SdrEditView::GetGeoAttrFromMarked() const
1178 : {
1179 0 : SfxItemSet aRetSet(pMod->GetItemPool(), // SID_ATTR_TRANSFORM_... from s:svxids.hrc
1180 : SID_ATTR_TRANSFORM_POS_X,SID_ATTR_TRANSFORM_ANGLE,
1181 : SID_ATTR_TRANSFORM_PROTECT_POS,SID_ATTR_TRANSFORM_AUTOHEIGHT,
1182 : SDRATTR_ECKENRADIUS,SDRATTR_ECKENRADIUS,
1183 0 : 0);
1184 0 : if (AreObjectsMarked()) {
1185 0 : SfxItemSet aMarkAttr(GetAttrFromMarked(sal_False)); // because of AutoGrowHeight and corner radius
1186 0 : Rectangle aRect(GetMarkedObjRect() );
1187 : // restore position to that before calc hack
1188 0 : aRect -= GetGridOffset();
1189 :
1190 0 : if(GetSdrPageView())
1191 : {
1192 0 : GetSdrPageView()->LogicToPagePos(aRect);
1193 : }
1194 :
1195 : // position
1196 0 : aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_POS_X,aRect.Left()));
1197 0 : aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_POS_Y,aRect.Top()));
1198 :
1199 : // size
1200 0 : long nResizeRefX=aRect.Left();
1201 0 : long nResizeRefY=aRect.Top();
1202 0 : if (eDragMode==SDRDRAG_ROTATE) { // use rotation axis as a reference for resizing, too
1203 0 : nResizeRefX=aRef1.X();
1204 0 : nResizeRefY=aRef1.Y();
1205 : }
1206 0 : aRetSet.Put(SfxUInt32Item(SID_ATTR_TRANSFORM_WIDTH,aRect.Right()-aRect.Left()));
1207 0 : aRetSet.Put(SfxUInt32Item(SID_ATTR_TRANSFORM_HEIGHT,aRect.Bottom()-aRect.Top()));
1208 0 : aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_RESIZE_REF_X,nResizeRefX));
1209 0 : aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_RESIZE_REF_Y,nResizeRefY));
1210 :
1211 0 : Point aRotateAxe(aRef1);
1212 :
1213 0 : if(GetSdrPageView())
1214 : {
1215 0 : GetSdrPageView()->LogicToPagePos(aRotateAxe);
1216 : }
1217 :
1218 : // rotation
1219 0 : long nRotateRefX=aRect.Center().X();
1220 0 : long nRotateRefY=aRect.Center().Y();
1221 0 : if (eDragMode==SDRDRAG_ROTATE) {
1222 0 : nRotateRefX=aRotateAxe.X();
1223 0 : nRotateRefY=aRotateAxe.Y();
1224 : }
1225 0 : aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_ANGLE,GetMarkedObjRotate()));
1226 0 : aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_ROT_X,nRotateRefX));
1227 0 : aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_ROT_Y,nRotateRefY));
1228 :
1229 : // shearing
1230 0 : long nShearRefX=aRect.Left();
1231 0 : long nShearRefY=aRect.Bottom();
1232 0 : if (eDragMode==SDRDRAG_ROTATE) { // use rotation axis as a reference for shearing, too
1233 0 : nShearRefX=aRotateAxe.X();
1234 0 : nShearRefY=aRotateAxe.Y();
1235 : }
1236 0 : aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR,GetMarkedObjShear()));
1237 0 : aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_X,nShearRefX));
1238 0 : aRetSet.Put(SfxInt32Item(SID_ATTR_TRANSFORM_SHEAR_Y,nShearRefY));
1239 :
1240 : // check every object whether it is protected
1241 0 : const SdrMarkList& rMarkList=GetMarkedObjectList();
1242 0 : sal_uIntPtr nMarkCount=rMarkList.GetMarkCount();
1243 0 : SdrObject* pObj=rMarkList.GetMark(0)->GetMarkedSdrObj();
1244 0 : bool bPosProt=pObj->IsMoveProtect();
1245 0 : bool bSizProt=pObj->IsResizeProtect();
1246 0 : bool bPosProtDontCare=false;
1247 0 : bool bSizProtDontCare=false;
1248 0 : for (sal_uIntPtr i=1; i<nMarkCount && (!bPosProtDontCare || !bSizProtDontCare); i++) {
1249 0 : pObj=rMarkList.GetMark(i)->GetMarkedSdrObj();
1250 0 : if (bPosProt!=pObj->IsMoveProtect()) bPosProtDontCare=true;
1251 0 : if (bSizProt!=pObj->IsResizeProtect()) bSizProtDontCare=true;
1252 : }
1253 :
1254 : // InvalidateItem sets item to DONT_CARE
1255 0 : if (bPosProtDontCare) {
1256 0 : aRetSet.InvalidateItem(SID_ATTR_TRANSFORM_PROTECT_POS);
1257 : } else {
1258 0 : aRetSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_PROTECT_POS,bPosProt));
1259 : }
1260 0 : if (bSizProtDontCare) {
1261 0 : aRetSet.InvalidateItem(SID_ATTR_TRANSFORM_PROTECT_SIZE);
1262 : } else {
1263 0 : aRetSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_PROTECT_SIZE,bSizProt));
1264 : }
1265 :
1266 0 : SfxItemState eState=aMarkAttr.GetItemState(SDRATTR_TEXT_AUTOGROWWIDTH);
1267 0 : sal_Bool bAutoGrow=((SdrTextAutoGrowWidthItem&)(aMarkAttr.Get(SDRATTR_TEXT_AUTOGROWWIDTH))).GetValue();
1268 0 : if (eState==SFX_ITEM_DONTCARE) {
1269 0 : aRetSet.InvalidateItem(SID_ATTR_TRANSFORM_AUTOWIDTH);
1270 0 : } else if (eState==SFX_ITEM_SET) {
1271 0 : aRetSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_AUTOWIDTH,bAutoGrow));
1272 : }
1273 :
1274 0 : eState=aMarkAttr.GetItemState(SDRATTR_TEXT_AUTOGROWHEIGHT);
1275 0 : bAutoGrow=((SdrTextAutoGrowHeightItem&)(aMarkAttr.Get(SDRATTR_TEXT_AUTOGROWHEIGHT))).GetValue();
1276 0 : if (eState==SFX_ITEM_DONTCARE) {
1277 0 : aRetSet.InvalidateItem(SID_ATTR_TRANSFORM_AUTOHEIGHT);
1278 0 : } else if (eState==SFX_ITEM_SET) {
1279 0 : aRetSet.Put(SfxBoolItem(SID_ATTR_TRANSFORM_AUTOHEIGHT,bAutoGrow));
1280 : }
1281 :
1282 0 : eState=aMarkAttr.GetItemState(SDRATTR_ECKENRADIUS);
1283 0 : long nRadius=((SdrEckenradiusItem&)(aMarkAttr.Get(SDRATTR_ECKENRADIUS))).GetValue();
1284 0 : if (eState==SFX_ITEM_DONTCARE) {
1285 0 : aRetSet.InvalidateItem(SDRATTR_ECKENRADIUS);
1286 0 : } else if (eState==SFX_ITEM_SET) {
1287 0 : aRetSet.Put(SdrEckenradiusItem(nRadius));
1288 0 : }
1289 :
1290 : }
1291 0 : return aRetSet;
1292 : }
1293 :
1294 0 : Point ImpGetPoint(Rectangle aRect, RECT_POINT eRP)
1295 : {
1296 0 : switch(eRP) {
1297 0 : case RP_LT: return aRect.TopLeft();
1298 0 : case RP_MT: return aRect.TopCenter();
1299 0 : case RP_RT: return aRect.TopRight();
1300 0 : case RP_LM: return aRect.LeftCenter();
1301 0 : case RP_MM: return aRect.Center();
1302 0 : case RP_RM: return aRect.RightCenter();
1303 0 : case RP_LB: return aRect.BottomLeft();
1304 0 : case RP_MB: return aRect.BottomCenter();
1305 0 : case RP_RB: return aRect.BottomRight();
1306 : }
1307 0 : return Point(); // Should not happen!
1308 : }
1309 :
1310 0 : void SdrEditView::SetGeoAttrToMarked(const SfxItemSet& rAttr)
1311 : {
1312 0 : Rectangle aRect(GetMarkedObjRect());
1313 :
1314 0 : if(GetSdrPageView())
1315 : {
1316 0 : GetSdrPageView()->LogicToPagePos(aRect);
1317 : }
1318 :
1319 0 : long nOldRotateAngle=GetMarkedObjRotate();
1320 0 : long nOldShearAngle=GetMarkedObjShear();
1321 0 : const SdrMarkList& rMarkList=GetMarkedObjectList();
1322 0 : sal_uIntPtr nMarkCount=rMarkList.GetMarkCount();
1323 0 : SdrObject* pObj=NULL;
1324 :
1325 0 : RECT_POINT eSizePoint=RP_MM;
1326 0 : long nPosDX=0;
1327 0 : long nPosDY=0;
1328 0 : long nSizX=0;
1329 0 : long nSizY=0;
1330 0 : long nRotateAngle=0;
1331 :
1332 0 : sal_Bool bModeIsRotate(eDragMode == SDRDRAG_ROTATE);
1333 0 : long nRotateX(0);
1334 0 : long nRotateY(0);
1335 0 : long nOldRotateX(0);
1336 0 : long nOldRotateY(0);
1337 0 : if(bModeIsRotate)
1338 : {
1339 0 : Point aRotateAxe(aRef1);
1340 :
1341 0 : if(GetSdrPageView())
1342 : {
1343 0 : GetSdrPageView()->LogicToPagePos(aRotateAxe);
1344 : }
1345 :
1346 0 : nRotateX = nOldRotateX = aRotateAxe.X();
1347 0 : nRotateY = nOldRotateY = aRotateAxe.Y();
1348 : }
1349 :
1350 0 : long nShearAngle=0;
1351 0 : long nShearX=0;
1352 0 : long nShearY=0;
1353 0 : sal_Bool bShearVert=sal_False;
1354 :
1355 0 : sal_Bool bChgPos=sal_False;
1356 0 : sal_Bool bChgSiz=sal_False;
1357 0 : sal_Bool bRotate=sal_False;
1358 0 : sal_Bool bShear =sal_False;
1359 :
1360 0 : sal_Bool bSetAttr=sal_False;
1361 0 : SfxItemSet aSetAttr(pMod->GetItemPool());
1362 :
1363 0 : const SfxPoolItem* pPoolItem=NULL;
1364 :
1365 : // position
1366 0 : if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_POS_X,sal_True,&pPoolItem)) {
1367 0 : nPosDX=((const SfxInt32Item*)pPoolItem)->GetValue()-aRect.Left();
1368 0 : bChgPos=sal_True;
1369 : }
1370 0 : if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_POS_Y,sal_True,&pPoolItem)){
1371 0 : nPosDY=((const SfxInt32Item*)pPoolItem)->GetValue()-aRect.Top();
1372 0 : bChgPos=sal_True;
1373 : }
1374 : // size
1375 0 : if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_WIDTH,sal_True,&pPoolItem)) {
1376 0 : nSizX=((const SfxUInt32Item*)pPoolItem)->GetValue();
1377 0 : bChgSiz=sal_True;
1378 : }
1379 0 : if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_HEIGHT,sal_True,&pPoolItem)) {
1380 0 : nSizY=((const SfxUInt32Item*)pPoolItem)->GetValue();
1381 0 : bChgSiz=sal_True;
1382 : }
1383 0 : if (bChgSiz) {
1384 0 : eSizePoint=(RECT_POINT)((const SfxAllEnumItem&)rAttr.Get(SID_ATTR_TRANSFORM_SIZE_POINT)).GetValue();
1385 : }
1386 :
1387 : // rotation
1388 0 : if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_ANGLE,sal_True,&pPoolItem)) {
1389 0 : nRotateAngle=((const SfxInt32Item*)pPoolItem)->GetValue()-nOldRotateAngle;
1390 0 : bRotate = (nRotateAngle != 0);
1391 : }
1392 :
1393 : // position rotation point x
1394 0 : if(bRotate || SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_ROT_X, sal_True ,&pPoolItem))
1395 0 : nRotateX = ((const SfxInt32Item&)rAttr.Get(SID_ATTR_TRANSFORM_ROT_X)).GetValue();
1396 :
1397 : // position rotation point y
1398 0 : if(bRotate || SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_ROT_Y, sal_True ,&pPoolItem))
1399 0 : nRotateY = ((const SfxInt32Item&)rAttr.Get(SID_ATTR_TRANSFORM_ROT_Y)).GetValue();
1400 :
1401 : // shearing
1402 0 : if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_SHEAR,sal_True,&pPoolItem)) {
1403 0 : long nNewShearAngle=((const SfxInt32Item*)pPoolItem)->GetValue();
1404 0 : if (nNewShearAngle>SDRMAXSHEAR) nNewShearAngle=SDRMAXSHEAR;
1405 0 : if (nNewShearAngle<-SDRMAXSHEAR) nNewShearAngle=-SDRMAXSHEAR;
1406 0 : if (nNewShearAngle!=nOldShearAngle) {
1407 0 : bShearVert=((const SfxBoolItem&)rAttr.Get(SID_ATTR_TRANSFORM_SHEAR_VERTICAL)).GetValue();
1408 0 : if (bShearVert) {
1409 0 : nShearAngle=nNewShearAngle;
1410 : } else {
1411 0 : if (nNewShearAngle!=0 && nOldShearAngle!=0) {
1412 : // bug fix
1413 0 : double nOld=tan((double)nOldShearAngle*nPi180);
1414 0 : double nNew=tan((double)nNewShearAngle*nPi180);
1415 0 : nNew-=nOld;
1416 0 : nNew=atan(nNew)/nPi180;
1417 0 : nShearAngle=Round(nNew);
1418 : } else {
1419 0 : nShearAngle=nNewShearAngle-nOldShearAngle;
1420 : }
1421 : }
1422 0 : bShear=nShearAngle!=0;
1423 0 : if (bShear) {
1424 0 : nShearX=((const SfxInt32Item&)rAttr.Get(SID_ATTR_TRANSFORM_SHEAR_X)).GetValue();
1425 0 : nShearY=((const SfxInt32Item&)rAttr.Get(SID_ATTR_TRANSFORM_SHEAR_Y)).GetValue();
1426 : }
1427 : }
1428 : }
1429 :
1430 : // AutoGrow
1431 0 : if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_AUTOWIDTH,sal_True,&pPoolItem)) {
1432 0 : sal_Bool bAutoGrow=((const SfxBoolItem*)pPoolItem)->GetValue();
1433 0 : aSetAttr.Put(SdrTextAutoGrowWidthItem(bAutoGrow));
1434 0 : bSetAttr=sal_True;
1435 : }
1436 :
1437 0 : if (SFX_ITEM_SET==rAttr.GetItemState(SID_ATTR_TRANSFORM_AUTOHEIGHT,sal_True,&pPoolItem)) {
1438 0 : sal_Bool bAutoGrow=((const SfxBoolItem*)pPoolItem)->GetValue();
1439 0 : aSetAttr.Put(SdrTextAutoGrowHeightItem(bAutoGrow));
1440 0 : bSetAttr=sal_True;
1441 : }
1442 :
1443 : // corner radius
1444 0 : if (bEdgeRadiusAllowed && SFX_ITEM_SET==rAttr.GetItemState(SDRATTR_ECKENRADIUS,sal_True,&pPoolItem)) {
1445 0 : long nRadius=((SdrEckenradiusItem*)pPoolItem)->GetValue();
1446 0 : aSetAttr.Put(SdrEckenradiusItem(nRadius));
1447 0 : bSetAttr=sal_True;
1448 : }
1449 :
1450 0 : ForcePossibilities();
1451 :
1452 0 : BegUndo(ImpGetResStr(STR_EditTransform),GetDescriptionOfMarkedObjects());
1453 :
1454 0 : if (bSetAttr) {
1455 0 : SetAttrToMarked(aSetAttr,sal_False);
1456 : }
1457 :
1458 : // change size and height
1459 0 : if (bChgSiz && (bResizeFreeAllowed || bResizePropAllowed)) {
1460 0 : Fraction aWdt(nSizX,aRect.Right()-aRect.Left());
1461 0 : Fraction aHgt(nSizY,aRect.Bottom()-aRect.Top());
1462 0 : Point aRef(ImpGetPoint(aRect,eSizePoint));
1463 :
1464 0 : if(GetSdrPageView())
1465 : {
1466 0 : GetSdrPageView()->PagePosToLogic(aRef);
1467 : }
1468 :
1469 0 : ResizeMarkedObj(aRef,aWdt,aHgt);
1470 : }
1471 :
1472 : // rotate
1473 0 : if (bRotate && (bRotateFreeAllowed || bRotate90Allowed)) {
1474 0 : Point aRef(nRotateX,nRotateY);
1475 :
1476 0 : if(GetSdrPageView())
1477 : {
1478 0 : GetSdrPageView()->PagePosToLogic(aRef);
1479 : }
1480 :
1481 0 : RotateMarkedObj(aRef,nRotateAngle);
1482 : }
1483 :
1484 : // set rotation point position
1485 0 : if(bModeIsRotate && (nRotateX != nOldRotateX || nRotateY != nOldRotateY))
1486 : {
1487 0 : Point aNewRef1(nRotateX, nRotateY);
1488 :
1489 0 : if(GetSdrPageView())
1490 : {
1491 0 : GetSdrPageView()->PagePosToLogic(aNewRef1);
1492 : }
1493 :
1494 0 : SetRef1(aNewRef1);
1495 : }
1496 :
1497 : // shear
1498 0 : if (bShear && bShearAllowed) {
1499 0 : Point aRef(nShearX,nShearY);
1500 :
1501 0 : if(GetSdrPageView())
1502 : {
1503 0 : GetSdrPageView()->PagePosToLogic(aRef);
1504 : }
1505 :
1506 0 : ShearMarkedObj(aRef,nShearAngle,bShearVert);
1507 :
1508 : // #i74358#
1509 : // ShearMarkedObj creates a linear combination of the existing transformation and
1510 : // the new shear to apply. If the object is already transformed (e.g. rotated) the
1511 : // linear combination will not decompose to the same start values again, but to a
1512 : // new combination. Thus it makes no sense to check if the wanted shear is reached
1513 : // or not. Taking out.
1514 : }
1515 :
1516 : // change position
1517 0 : if (bChgPos && bMoveAllowed) {
1518 0 : MoveMarkedObj(Size(nPosDX,nPosDY));
1519 : }
1520 :
1521 : // protect position
1522 0 : if(SFX_ITEM_SET == rAttr.GetItemState(SID_ATTR_TRANSFORM_PROTECT_POS, sal_True, &pPoolItem))
1523 : {
1524 0 : const bool bProtPos(((const SfxBoolItem*)pPoolItem)->GetValue());
1525 0 : bool bChanged(false);
1526 :
1527 0 : for(sal_uInt32 i(0); i < nMarkCount; i++)
1528 : {
1529 0 : pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
1530 :
1531 0 : if(pObj->IsMoveProtect() != bProtPos)
1532 : {
1533 0 : bChanged = true;
1534 0 : pObj->SetMoveProtect(bProtPos);
1535 :
1536 0 : if(bProtPos)
1537 : {
1538 0 : pObj->SetResizeProtect(true);
1539 : }
1540 : }
1541 : }
1542 :
1543 0 : if(bChanged)
1544 : {
1545 0 : bMoveProtect = bProtPos;
1546 :
1547 0 : if(bProtPos)
1548 : {
1549 0 : bResizeProtect = true;
1550 : }
1551 :
1552 : // #i77187# there is no simple method to get the toolbars updated
1553 : // in the application. The App is listening to selection change and i
1554 : // will use it here (even if not true). It's acceptable since changing
1555 : // this model data is pretty rare and only possible using the F4 dialog
1556 0 : MarkListHasChanged();
1557 : }
1558 : }
1559 :
1560 0 : if(!bMoveProtect)
1561 : {
1562 : // protect size
1563 0 : if(SFX_ITEM_SET == rAttr.GetItemState(SID_ATTR_TRANSFORM_PROTECT_SIZE, sal_True, &pPoolItem))
1564 : {
1565 0 : const bool bProtSize(((const SfxBoolItem*)pPoolItem)->GetValue());
1566 0 : bool bChanged(false);
1567 :
1568 0 : for(sal_uInt32 i(0); i < nMarkCount; i++)
1569 : {
1570 0 : pObj = rMarkList.GetMark(i)->GetMarkedSdrObj();
1571 :
1572 0 : if(pObj->IsResizeProtect() != bProtSize)
1573 : {
1574 0 : bChanged = true;
1575 0 : pObj->SetResizeProtect(bProtSize);
1576 : }
1577 : }
1578 :
1579 0 : if(bChanged)
1580 : {
1581 0 : bResizeProtect = bProtSize;
1582 :
1583 : // #i77187# see above
1584 0 : MarkListHasChanged();
1585 : }
1586 : }
1587 : }
1588 :
1589 0 : EndUndo();
1590 0 : }
1591 :
1592 : ////////////////////////////////////////////////////////////////////////////////////////////////////
1593 :
1594 0 : sal_Bool SdrEditView::IsAlignPossible() const
1595 : { // at least two selected objects, at least one of them movable
1596 0 : ForcePossibilities();
1597 0 : sal_uIntPtr nAnz=GetMarkedObjectCount();
1598 0 : if (nAnz==0) return sal_False; // nothing selected!
1599 0 : if (nAnz==1) return bMoveAllowed; // align single object to page
1600 0 : return bOneOrMoreMovable; // otherwise: MarkCount>=2
1601 : }
1602 :
1603 0 : void SdrEditView::AlignMarkedObjects(SdrHorAlign eHor, SdrVertAlign eVert, sal_Bool bBoundRects)
1604 : {
1605 0 : if (eHor==SDRHALIGN_NONE && eVert==SDRVALIGN_NONE)
1606 : return;
1607 :
1608 0 : SortMarkedObjects();
1609 0 : if (GetMarkedObjectCount()<1)
1610 : return;
1611 :
1612 0 : const bool bUndo = IsUndoEnabled();
1613 0 : if( bUndo )
1614 : {
1615 0 : XubString aStr(GetDescriptionOfMarkedObjects());
1616 0 : if (eHor==SDRHALIGN_NONE)
1617 : {
1618 0 : switch (eVert)
1619 : {
1620 0 : case SDRVALIGN_TOP : ImpTakeDescriptionStr(STR_EditAlignVTop ,aStr); break;
1621 0 : case SDRVALIGN_BOTTOM: ImpTakeDescriptionStr(STR_EditAlignVBottom,aStr); break;
1622 0 : case SDRVALIGN_CENTER: ImpTakeDescriptionStr(STR_EditAlignVCenter,aStr); break;
1623 0 : default: break;
1624 : }
1625 : }
1626 0 : else if (eVert==SDRVALIGN_NONE)
1627 : {
1628 0 : switch (eHor)
1629 : {
1630 0 : case SDRHALIGN_LEFT : ImpTakeDescriptionStr(STR_EditAlignHLeft ,aStr); break;
1631 0 : case SDRHALIGN_RIGHT : ImpTakeDescriptionStr(STR_EditAlignHRight ,aStr); break;
1632 0 : case SDRHALIGN_CENTER: ImpTakeDescriptionStr(STR_EditAlignHCenter,aStr); break;
1633 0 : default: break;
1634 : }
1635 : }
1636 0 : else if (eHor==SDRHALIGN_CENTER && eVert==SDRVALIGN_CENTER)
1637 : {
1638 0 : ImpTakeDescriptionStr(STR_EditAlignCenter,aStr);
1639 : }
1640 : else
1641 : {
1642 0 : ImpTakeDescriptionStr(STR_EditAlign,aStr);
1643 : }
1644 0 : BegUndo(aStr);
1645 : }
1646 :
1647 0 : Rectangle aBound;
1648 0 : sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
1649 : sal_uIntPtr nm;
1650 0 : sal_Bool bHasFixed=sal_False;
1651 0 : for (nm=0; nm<nMarkAnz; nm++)
1652 : {
1653 0 : SdrMark* pM=GetSdrMarkByIndex(nm);
1654 0 : SdrObject* pObj=pM->GetMarkedSdrObj();
1655 0 : SdrObjTransformInfoRec aInfo;
1656 0 : pObj->TakeObjInfo(aInfo);
1657 0 : if (!aInfo.bMoveAllowed || pObj->IsMoveProtect())
1658 : {
1659 0 : Rectangle aObjRect(bBoundRects?pObj->GetCurrentBoundRect():pObj->GetSnapRect());
1660 0 : aBound.Union(aObjRect);
1661 0 : bHasFixed=sal_True;
1662 : }
1663 : }
1664 0 : if (!bHasFixed)
1665 : {
1666 0 : if (nMarkAnz==1)
1667 : { // align single object to page
1668 0 : const SdrObject* pObj=GetMarkedObjectByIndex(0L);
1669 0 : const SdrPage* pPage=pObj->GetPage();
1670 0 : const SdrPageGridFrameList* pGFL=pPage->GetGridFrameList(GetSdrPageViewOfMarkedByIndex(0),&(pObj->GetSnapRect()));
1671 0 : const SdrPageGridFrame* pFrame=NULL;
1672 0 : if (pGFL!=NULL && pGFL->GetCount()!=0)
1673 : { // Writer
1674 0 : pFrame=&((*pGFL)[0]);
1675 : }
1676 :
1677 0 : if (pFrame!=NULL)
1678 : { // Writer
1679 0 : aBound=pFrame->GetUserArea();
1680 : }
1681 : else
1682 : {
1683 0 : aBound=Rectangle(pPage->GetLftBorder(),pPage->GetUppBorder(),
1684 0 : pPage->GetWdt()-pPage->GetRgtBorder(),
1685 0 : pPage->GetHgt()-pPage->GetLwrBorder());
1686 : }
1687 : }
1688 : else
1689 : {
1690 0 : if (bBoundRects)
1691 0 : aBound=GetMarkedObjBoundRect();
1692 : else
1693 0 : aBound=GetMarkedObjRect();
1694 : }
1695 : }
1696 0 : Point aCenter(aBound.Center());
1697 0 : for (nm=0; nm<nMarkAnz; nm++)
1698 : {
1699 0 : SdrMark* pM=GetSdrMarkByIndex(nm);
1700 0 : SdrObject* pObj=pM->GetMarkedSdrObj();
1701 0 : SdrObjTransformInfoRec aInfo;
1702 0 : pObj->TakeObjInfo(aInfo);
1703 0 : if (aInfo.bMoveAllowed && !pObj->IsMoveProtect())
1704 : {
1705 0 : long nXMov=0;
1706 0 : long nYMov=0;
1707 0 : Rectangle aObjRect(bBoundRects?pObj->GetCurrentBoundRect():pObj->GetSnapRect());
1708 0 : switch (eVert)
1709 : {
1710 0 : case SDRVALIGN_TOP : nYMov=aBound.Top() -aObjRect.Top() ; break;
1711 0 : case SDRVALIGN_BOTTOM: nYMov=aBound.Bottom()-aObjRect.Bottom() ; break;
1712 0 : case SDRVALIGN_CENTER: nYMov=aCenter.Y() -aObjRect.Center().Y(); break;
1713 0 : default: break;
1714 : }
1715 0 : switch (eHor)
1716 : {
1717 0 : case SDRHALIGN_LEFT : nXMov=aBound.Left() -aObjRect.Left() ; break;
1718 0 : case SDRHALIGN_RIGHT : nXMov=aBound.Right() -aObjRect.Right() ; break;
1719 0 : case SDRHALIGN_CENTER: nXMov=aCenter.X() -aObjRect.Center().X(); break;
1720 0 : default: break;
1721 : }
1722 0 : if (nXMov!=0 || nYMov!=0)
1723 : {
1724 : // SdrEdgeObj needs an extra SdrUndoGeoObj since the
1725 : // connections may need to be saved
1726 0 : if( bUndo )
1727 : {
1728 0 : if( dynamic_cast<SdrEdgeObj*>(pObj) )
1729 : {
1730 0 : AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
1731 : }
1732 :
1733 0 : AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoMoveObject(*pObj,Size(nXMov,nYMov)));
1734 : }
1735 :
1736 0 : pObj->Move(Size(nXMov,nYMov));
1737 : }
1738 : }
1739 : }
1740 :
1741 0 : if( bUndo )
1742 0 : EndUndo();
1743 : }
1744 :
1745 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|