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