xref: /AOO41X/main/svx/source/svdraw/svdedtv1.cxx (revision cbe4a5e32dd06077057875dd5ecd4d8f1991662a)
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