xref: /trunk/main/svx/source/svdraw/svdglev.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
30 
31 #include <svx/svdglev.hxx>
32 #include <math.h>
33 
34 #include <svx/svdundo.hxx>
35 #include "svx/svdstr.hrc"   // Namen aus der Resource
36 #include "svx/svdglob.hxx"  // StringCache
37 #include <svx/svdpagv.hxx>
38 #include <svx/svdglue.hxx>
39 #include <svx/svdtrans.hxx>
40 #include <svx/svdobj.hxx>
41 
42 ////////////////////////////////////////////////////////////////////////////////////////////////////
43 
44 void SdrGlueEditView::ImpClearVars()
45 {
46 }
47 
48 SdrGlueEditView::SdrGlueEditView(SdrModel* pModel1, OutputDevice* pOut):
49     SdrPolyEditView(pModel1,pOut)
50 {
51     ImpClearVars();
52 }
53 
54 SdrGlueEditView::~SdrGlueEditView()
55 {
56 }
57 
58 ////////////////////////////////////////////////////////////////////////////////////////////////////
59 
60 void SdrGlueEditView::ImpDoMarkedGluePoints(PGlueDoFunc pDoFunc, sal_Bool bConst, const void* p1, const void* p2, const void* p3, const void* p4, const void* p5)
61 {
62     sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
63     for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++) {
64         SdrMark* pM=GetSdrMarkByIndex(nm);
65         SdrObject* pObj=pM->GetMarkedSdrObj();
66         const SdrUShortCont* pPts=pM->GetMarkedGluePoints();
67         sal_uIntPtr nPtAnz=pPts==NULL ? 0 : pPts->GetCount();
68         if (nPtAnz!=0) {
69             SdrGluePointList* pGPL=NULL;
70             if (bConst) {
71                 const SdrGluePointList* pConstGPL=pObj->GetGluePointList();
72                 pGPL=(SdrGluePointList*)pConstGPL;
73             } else {
74                 pGPL=pObj->ForceGluePointList();
75             }
76             if (pGPL!=NULL)
77             {
78                 if(!bConst && IsUndoEnabled() )
79                     AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
80 
81                 for (sal_uIntPtr nPtNum=0; nPtNum<nPtAnz; nPtNum++)
82                 {
83                     sal_uInt16 nPtId=pPts->GetObject(nPtNum);
84                     sal_uInt16 nGlueIdx=pGPL->FindGluePoint(nPtId);
85                     if (nGlueIdx!=SDRGLUEPOINT_NOTFOUND)
86                     {
87                         SdrGluePoint& rGP=(*pGPL)[nGlueIdx];
88                         (*pDoFunc)(rGP,pObj,p1,p2,p3,p4,p5);
89                     }
90                 }
91                 if (!bConst)
92                 {
93                     pObj->SetChanged();
94                     pObj->BroadcastObjectChange();
95                 }
96             }
97         }
98     }
99     if (!bConst && nMarkAnz!=0) pMod->SetChanged();
100 }
101 
102 ////////////////////////////////////////////////////////////////////////////////////////////////////
103 
104 static void ImpGetEscDir(SdrGluePoint& rGP, const SdrObject* /*pObj*/, const void* pbFirst, const void* pnThisEsc, const void* pnRet, const void*, const void*)
105 {
106     sal_uInt16& nRet=*(sal_uInt16*)pnRet;
107     sal_Bool& bFirst=*(sal_Bool*)pbFirst;
108     if (nRet!=FUZZY) {
109         sal_uInt16 nEsc=rGP.GetEscDir();
110         sal_Bool bOn=(nEsc & *(sal_uInt16*)pnThisEsc)!=0;
111         if (bFirst) { nRet=bOn; bFirst=sal_False; }
112         else if (nRet!=bOn) nRet=FUZZY;
113     }
114 }
115 
116 TRISTATE SdrGlueEditView::IsMarkedGluePointsEscDir(sal_uInt16 nThisEsc) const
117 {
118     ForceUndirtyMrkPnt();
119     sal_Bool bFirst=sal_True;
120     sal_uInt16 nRet=sal_False;
121     ((SdrGlueEditView*)this)->ImpDoMarkedGluePoints(ImpGetEscDir,sal_True,&bFirst,&nThisEsc,&nRet);
122     return (TRISTATE)nRet;
123 }
124 
125 static void ImpSetEscDir(SdrGluePoint& rGP, const SdrObject* /*pObj*/, const void* pnThisEsc, const void* pbOn, const void*, const void*, const void*)
126 {
127     sal_uInt16 nEsc=rGP.GetEscDir();
128     if (*(sal_Bool*)pbOn) nEsc|=*(sal_uInt16*)pnThisEsc;
129     else nEsc&=~*(sal_uInt16*)pnThisEsc;
130     rGP.SetEscDir(nEsc);
131 }
132 
133 void SdrGlueEditView::SetMarkedGluePointsEscDir(sal_uInt16 nThisEsc, sal_Bool bOn)
134 {
135     ForceUndirtyMrkPnt();
136     BegUndo(ImpGetResStr(STR_EditSetGlueEscDir),GetDescriptionOfMarkedGluePoints());
137     ImpDoMarkedGluePoints(ImpSetEscDir,sal_False,&nThisEsc,&bOn);
138     EndUndo();
139 }
140 
141 ////////////////////////////////////////////////////////////////////////////////////////////////////
142 
143 static void ImpGetPercent(SdrGluePoint& rGP, const SdrObject* /*pObj*/, const void* pbFirst, const void* pnRet, const void*, const void*, const void*)
144 {
145     sal_uInt16& nRet=*(sal_uInt16*)pnRet;
146     sal_Bool& bFirst=*(sal_Bool*)pbFirst;
147     if (nRet!=FUZZY) {
148         bool bOn=rGP.IsPercent();
149         if (bFirst) { nRet=bOn; bFirst=sal_False; }
150         else if ((nRet!=0)!=bOn) nRet=FUZZY;
151     }
152 }
153 
154 TRISTATE SdrGlueEditView::IsMarkedGluePointsPercent() const
155 {
156     ForceUndirtyMrkPnt();
157     sal_Bool bFirst=sal_True;
158     sal_uInt16 nRet=sal_True;
159     ((SdrGlueEditView*)this)->ImpDoMarkedGluePoints(ImpGetPercent,sal_True,&bFirst,&nRet);
160     return (TRISTATE)nRet;
161 }
162 
163 static void ImpSetPercent(SdrGluePoint& rGP, const SdrObject* pObj, const void* pbOn, const void*, const void*, const void*, const void*)
164 {
165     Point aPos(rGP.GetAbsolutePos(*pObj));
166     rGP.SetPercent(*(sal_Bool*)pbOn);
167     rGP.SetAbsolutePos(aPos,*pObj);
168 }
169 
170 void SdrGlueEditView::SetMarkedGluePointsPercent(sal_Bool bOn)
171 {
172     ForceUndirtyMrkPnt();
173     BegUndo(ImpGetResStr(STR_EditSetGluePercent),GetDescriptionOfMarkedGluePoints());
174     ImpDoMarkedGluePoints(ImpSetPercent,sal_False,&bOn);
175     EndUndo();
176 }
177 
178 ////////////////////////////////////////////////////////////////////////////////////////////////////
179 
180 static void ImpGetAlign(SdrGluePoint& rGP, const SdrObject* /*pObj*/, const void* pbFirst, const void* pbDontCare, const void* pbVert, const void* pnRet, const void*)
181 {
182     sal_uInt16& nRet=*(sal_uInt16*)pnRet;
183     sal_Bool& bFirst=*(sal_Bool*)pbFirst;
184     sal_Bool& bDontCare=*(sal_Bool*)pbDontCare;
185     sal_Bool bVert=*(sal_Bool*)pbVert;
186     if (!bDontCare) {
187         sal_uInt16 nAlg=0;
188         if (bVert) {
189             nAlg=rGP.GetVertAlign();
190         } else {
191             nAlg=rGP.GetHorzAlign();
192         }
193         if (bFirst) { nRet=nAlg; bFirst=sal_False; }
194         else if (nRet!=nAlg) {
195             if (bVert) {
196                 nRet=SDRVERTALIGN_DONTCARE;
197             } else {
198                 nRet=SDRHORZALIGN_DONTCARE;
199             }
200             bDontCare=sal_True;
201         }
202     }
203 }
204 
205 sal_uInt16 SdrGlueEditView::GetMarkedGluePointsAlign(sal_Bool bVert) const
206 {
207     ForceUndirtyMrkPnt();
208     sal_Bool bFirst=sal_True;
209     sal_Bool bDontCare=sal_False;
210     sal_uInt16 nRet=0;
211     ((SdrGlueEditView*)this)->ImpDoMarkedGluePoints(ImpGetAlign,sal_True,&bFirst,&bDontCare,&bVert,&nRet);
212     return nRet;
213 }
214 
215 static void ImpSetAlign(SdrGluePoint& rGP, const SdrObject* pObj, const void* pbVert, const void* pnAlign, const void*, const void*, const void*)
216 {
217     Point aPos(rGP.GetAbsolutePos(*pObj));
218     if (*(sal_Bool*)pbVert) { // bVert?
219         rGP.SetVertAlign(*(sal_uInt16*)pnAlign);
220     } else {
221         rGP.SetHorzAlign(*(sal_uInt16*)pnAlign);
222     }
223     rGP.SetAbsolutePos(aPos,*pObj);
224 }
225 
226 void SdrGlueEditView::SetMarkedGluePointsAlign(sal_Bool bVert, sal_uInt16 nAlign)
227 {
228     ForceUndirtyMrkPnt();
229     BegUndo(ImpGetResStr(STR_EditSetGlueAlign),GetDescriptionOfMarkedGluePoints());
230     ImpDoMarkedGluePoints(ImpSetAlign,sal_False,&bVert,&nAlign);
231     EndUndo();
232 }
233 
234 ////////////////////////////////////////////////////////////////////////////////////////////////////
235 
236 sal_Bool SdrGlueEditView::IsDeleteMarkedGluePointsPossible() const
237 {
238     return HasMarkedGluePoints();
239 }
240 
241 void SdrGlueEditView::DeleteMarkedGluePoints()
242 {
243     BrkAction();
244     ForceUndirtyMrkPnt();
245     const bool bUndo = IsUndoEnabled();
246     if( bUndo )
247         BegUndo(ImpGetResStr(STR_EditDelete),GetDescriptionOfMarkedGluePoints(),SDRREPFUNC_OBJ_DELETE);
248 
249     sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
250     for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++)
251     {
252         SdrMark* pM=GetSdrMarkByIndex(nm);
253         SdrObject* pObj=pM->GetMarkedSdrObj();
254         const SdrUShortCont* pPts=pM->GetMarkedGluePoints();
255         sal_uIntPtr nPtAnz=pPts==NULL ? 0 : pPts->GetCount();
256         if (nPtAnz!=0)
257         {
258             SdrGluePointList* pGPL=pObj->ForceGluePointList();
259             if (pGPL!=NULL)
260             {
261                 if( bUndo )
262                     AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
263 
264                 for (sal_uIntPtr nPtNum=0; nPtNum<nPtAnz; nPtNum++)
265                 {
266                     sal_uInt16 nPtId=pPts->GetObject(nPtNum);
267                     sal_uInt16 nGlueIdx=pGPL->FindGluePoint(nPtId);
268                     if (nGlueIdx!=SDRGLUEPOINT_NOTFOUND)
269                     {
270                         pGPL->Delete(nGlueIdx);
271                     }
272                 }
273                 pObj->SetChanged();
274                 pObj->BroadcastObjectChange();
275             }
276         }
277     }
278     if( bUndo )
279         EndUndo();
280     UnmarkAllGluePoints();
281     if (nMarkAnz!=0)
282         pMod->SetChanged();
283 }
284 
285 ////////////////////////////////////////////////////////////////////////////////////////////////////
286 
287 void SdrGlueEditView::ImpCopyMarkedGluePoints()
288 {
289     const bool bUndo = IsUndoEnabled();
290 
291     if( bUndo )
292         BegUndo();
293 
294     sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
295     for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++)
296     {
297         SdrMark* pM=GetSdrMarkByIndex(nm);
298         SdrObject* pObj=pM->GetMarkedSdrObj();
299         SdrUShortCont* pPts=pM->GetMarkedGluePoints();
300         SdrGluePointList* pGPL=pObj->ForceGluePointList();
301         sal_uIntPtr nPtAnz=pPts==NULL ? 0 : pPts->GetCount();
302         if (nPtAnz!=0 && pGPL!=NULL)
303         {
304             if( bUndo )
305                 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
306 
307             for (sal_uIntPtr nPtNum=0; nPtNum<nPtAnz; nPtNum++)
308             {
309                 sal_uInt16 nPtId=pPts->GetObject(nPtNum);
310                 sal_uInt16 nGlueIdx=pGPL->FindGluePoint(nPtId);
311                 if (nGlueIdx!=SDRGLUEPOINT_NOTFOUND)
312                 {
313                     SdrGluePoint aNewGP((*pGPL)[nGlueIdx]);  // GluePoint klonen
314                     sal_uInt16 nNewIdx=pGPL->Insert(aNewGP);     // und einfuegen
315                     sal_uInt16 nNewId=(*pGPL)[nNewIdx].GetId();  // Id des neuen GluePoints ermitteln
316                     pPts->Replace(nNewId,nPtNum);            // und diesen markieren (anstelle des alten)
317                 }
318             }
319         }
320     }
321     if( bUndo )
322         EndUndo();
323 
324     if (nMarkAnz!=0)
325         pMod->SetChanged();
326 }
327 
328 ////////////////////////////////////////////////////////////////////////////////////////////////////
329 
330 void SdrGlueEditView::ImpTransformMarkedGluePoints(PGlueTrFunc pTrFunc, const void* p1, const void* p2, const void* p3, const void* p4, const void* p5)
331 {
332     sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
333     for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++) {
334         SdrMark* pM=GetSdrMarkByIndex(nm);
335         SdrObject* pObj=pM->GetMarkedSdrObj();
336         const SdrUShortCont* pPts=pM->GetMarkedGluePoints();
337         sal_uIntPtr nPtAnz=pPts==NULL ? 0 : pPts->GetCount();
338         if (nPtAnz!=0) {
339             SdrGluePointList* pGPL=pObj->ForceGluePointList();
340             if (pGPL!=NULL)
341             {
342                 if( IsUndoEnabled() )
343                     AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
344 
345                 for (sal_uIntPtr nPtNum=0; nPtNum<nPtAnz; nPtNum++) {
346                     sal_uInt16 nPtId=pPts->GetObject(nPtNum);
347                     sal_uInt16 nGlueIdx=pGPL->FindGluePoint(nPtId);
348                     if (nGlueIdx!=SDRGLUEPOINT_NOTFOUND) {
349                         SdrGluePoint& rGP=(*pGPL)[nGlueIdx];
350                         Point aPos(rGP.GetAbsolutePos(*pObj));
351                         (*pTrFunc)(aPos,p1,p2,p3,p4,p5);
352                         rGP.SetAbsolutePos(aPos,*pObj);
353                     }
354                 }
355                 pObj->SetChanged();
356                 pObj->BroadcastObjectChange();
357             }
358         }
359     }
360     if (nMarkAnz!=0) pMod->SetChanged();
361 }
362 
363 ////////////////////////////////////////////////////////////////////////////////////////////////////
364 
365 static void ImpMove(Point& rPt, const void* p1, const void* /*p2*/, const void* /*p3*/, const void* /*p4*/, const void* /*p5*/)
366 {
367     rPt.X()+=((const Size*)p1)->Width();
368     rPt.Y()+=((const Size*)p1)->Height();
369 }
370 
371 void SdrGlueEditView::MoveMarkedGluePoints(const Size& rSiz, bool bCopy)
372 {
373     ForceUndirtyMrkPnt();
374     XubString aStr(ImpGetResStr(STR_EditMove));
375     if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy);
376     BegUndo(aStr,GetDescriptionOfMarkedGluePoints(),SDRREPFUNC_OBJ_MOVE);
377     if (bCopy) ImpCopyMarkedGluePoints();
378     ImpTransformMarkedGluePoints(ImpMove,&rSiz);
379     EndUndo();
380     AdjustMarkHdl();
381 }
382 
383 ////////////////////////////////////////////////////////////////////////////////////////////////////
384 
385 static void ImpResize(Point& rPt, const void* p1, const void* p2, const void* p3, const void* /*p4*/, const void* /*p5*/)
386 {
387     ResizePoint(rPt,*(const Point*)p1,*(const Fraction*)p2,*(const Fraction*)p3);
388 }
389 
390 void SdrGlueEditView::ResizeMarkedGluePoints(const Point& rRef, const Fraction& xFact, const Fraction& yFact, bool bCopy)
391 {
392     ForceUndirtyMrkPnt();
393     XubString aStr(ImpGetResStr(STR_EditResize));
394     if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy);
395     BegUndo(aStr,GetDescriptionOfMarkedGluePoints(),SDRREPFUNC_OBJ_RESIZE);
396     if (bCopy) ImpCopyMarkedGluePoints();
397     ImpTransformMarkedGluePoints(ImpResize,&rRef,&xFact,&yFact);
398     EndUndo();
399     AdjustMarkHdl();
400 }
401 
402 ////////////////////////////////////////////////////////////////////////////////////////////////////
403 
404 static void ImpRotate(Point& rPt, const void* p1, const void* /*p2*/, const void* p3, const void* p4, const void* /*p5*/)
405 {
406     RotatePoint(rPt,*(const Point*)p1,*(const double*)p3,*(const double*)p4);
407 }
408 
409 void SdrGlueEditView::RotateMarkedGluePoints(const Point& rRef, long nWink, bool bCopy)
410 {
411     ForceUndirtyMrkPnt();
412     XubString aStr(ImpGetResStr(STR_EditRotate));
413     if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy);
414     BegUndo(aStr,GetDescriptionOfMarkedGluePoints(),SDRREPFUNC_OBJ_ROTATE);
415     if (bCopy) ImpCopyMarkedGluePoints();
416     double nSin=sin(nWink*nPi180);
417     double nCos=cos(nWink*nPi180);
418     ImpTransformMarkedGluePoints(ImpRotate,&rRef,&nWink,&nSin,&nCos);
419     EndUndo();
420     AdjustMarkHdl();
421 }
422 
423