xref: /trunk/main/svx/source/svdraw/svdglev.cxx (revision 60822731f97e392f18f66164e20dcaceb878c33f)
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/svdglev.hxx>
28 #include <math.h>
29 
30 #include <svx/svdundo.hxx>
31 #include "svx/svdstr.hrc" // Namen aus der Ressource
32 #include "svx/svdglob.hxx" // StringCache
33 #include <svx/svdpagv.hxx>
34 #include <svx/svdglue.hxx>
35 #include <svx/svdtrans.hxx>
36 #include <svx/svdobj.hxx>
37 
38 
39 void SdrGlueEditView::ImpClearVars()
40 {
41 }
42 
43 SdrGlueEditView::SdrGlueEditView(SdrModel* pModel1, OutputDevice* pOut):
44     SdrPolyEditView(pModel1,pOut)
45 {
46     ImpClearVars();
47 }
48 
49 SdrGlueEditView::~SdrGlueEditView()
50 {
51 }
52 
53 
54 void SdrGlueEditView::ImpDoMarkedGluePoints(PGlueDoFunc pDoFunc, sal_Bool bConst, const void* p1, const void* p2, const void* p3, const void* p4, const void* p5)
55 {
56     sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
57     for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++) {
58         SdrMark* pM=GetSdrMarkByIndex(nm);
59         SdrObject* pObj=pM->GetMarkedSdrObj();
60         const SdrUShortCont* pPts=pM->GetMarkedGluePoints();
61         sal_uIntPtr nPtAnz=pPts==NULL ? 0 : pPts->GetCount();
62         if (nPtAnz!=0) {
63             SdrGluePointList* pGPL=NULL;
64             if (bConst) {
65                 const SdrGluePointList* pConstGPL=pObj->GetGluePointList();
66                 pGPL=(SdrGluePointList*)pConstGPL;
67             } else {
68                 pGPL=pObj->ForceGluePointList();
69             }
70             if (pGPL!=NULL)
71             {
72                 if(!bConst && IsUndoEnabled() )
73                     AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
74 
75                 for (sal_uIntPtr nPtNum=0; nPtNum<nPtAnz; nPtNum++)
76                 {
77                     sal_uInt16 nPtId=pPts->GetObject(nPtNum);
78                     sal_uInt16 nGlueIdx=pGPL->FindGluePoint(nPtId);
79                     if (nGlueIdx!=SDRGLUEPOINT_NOTFOUND)
80                     {
81                         SdrGluePoint& rGP=(*pGPL)[nGlueIdx];
82                         (*pDoFunc)(rGP,pObj,p1,p2,p3,p4,p5);
83                     }
84                 }
85                 if (!bConst)
86                 {
87                     pObj->SetChanged();
88                     pObj->BroadcastObjectChange();
89                 }
90             }
91         }
92     }
93     if (!bConst && nMarkAnz!=0) pMod->SetChanged();
94 }
95 
96 
97 static void ImpGetEscDir(SdrGluePoint& rGP, const SdrObject* /*pObj*/, const void* pbFirst, const void* pnThisEsc, const void* pnRet, const void*, const void*)
98 {
99     sal_uInt16& nRet=*(sal_uInt16*)pnRet;
100     sal_Bool& bFirst=*(sal_Bool*)pbFirst;
101     if (nRet!=FUZZY) {
102         sal_uInt16 nEsc=rGP.GetEscDir();
103         sal_Bool bOn=(nEsc & *(sal_uInt16*)pnThisEsc)!=0;
104         if (bFirst) { nRet=bOn; bFirst=sal_False; }
105         else if (nRet!=bOn) nRet=FUZZY;
106     }
107 }
108 
109 TRISTATE SdrGlueEditView::IsMarkedGluePointsEscDir(sal_uInt16 nThisEsc) const
110 {
111     ForceUndirtyMrkPnt();
112     sal_Bool bFirst=sal_True;
113     sal_uInt16 nRet=sal_False;
114     ((SdrGlueEditView*)this)->ImpDoMarkedGluePoints(ImpGetEscDir,sal_True,&bFirst,&nThisEsc,&nRet);
115     return (TRISTATE)nRet;
116 }
117 
118 static void ImpSetEscDir(SdrGluePoint& rGP, const SdrObject* /*pObj*/, const void* pnThisEsc, const void* pbOn, const void*, const void*, const void*)
119 {
120     sal_uInt16 nEsc=rGP.GetEscDir();
121     if (*(sal_Bool*)pbOn) nEsc|=*(sal_uInt16*)pnThisEsc;
122     else nEsc&=~*(sal_uInt16*)pnThisEsc;
123     rGP.SetEscDir(nEsc);
124 }
125 
126 void SdrGlueEditView::SetMarkedGluePointsEscDir(sal_uInt16 nThisEsc, sal_Bool bOn)
127 {
128     ForceUndirtyMrkPnt();
129     BegUndo(ImpGetResStr(STR_EditSetGlueEscDir),GetDescriptionOfMarkedGluePoints());
130     ImpDoMarkedGluePoints(ImpSetEscDir,sal_False,&nThisEsc,&bOn);
131     EndUndo();
132 }
133 
134 
135 static void ImpGetPercent(SdrGluePoint& rGP, const SdrObject* /*pObj*/, const void* pbFirst, const void* pnRet, const void*, const void*, const void*)
136 {
137     sal_uInt16& nRet=*(sal_uInt16*)pnRet;
138     sal_Bool& bFirst=*(sal_Bool*)pbFirst;
139     if (nRet!=FUZZY) {
140         bool bOn=rGP.IsPercent();
141         if (bFirst) { nRet=bOn; bFirst=sal_False; }
142         else if ((nRet!=0)!=bOn) nRet=FUZZY;
143     }
144 }
145 
146 TRISTATE SdrGlueEditView::IsMarkedGluePointsPercent() const
147 {
148     ForceUndirtyMrkPnt();
149     sal_Bool bFirst=sal_True;
150     sal_uInt16 nRet=sal_True;
151     ((SdrGlueEditView*)this)->ImpDoMarkedGluePoints(ImpGetPercent,sal_True,&bFirst,&nRet);
152     return (TRISTATE)nRet;
153 }
154 
155 static void ImpSetPercent(SdrGluePoint& rGP, const SdrObject* pObj, const void* pbOn, const void*, const void*, const void*, const void*)
156 {
157     Point aPos(rGP.GetAbsolutePos(*pObj));
158     rGP.SetPercent(*(sal_Bool*)pbOn);
159     rGP.SetAbsolutePos(aPos,*pObj);
160 }
161 
162 void SdrGlueEditView::SetMarkedGluePointsPercent(sal_Bool bOn)
163 {
164     ForceUndirtyMrkPnt();
165     BegUndo(ImpGetResStr(STR_EditSetGluePercent),GetDescriptionOfMarkedGluePoints());
166     ImpDoMarkedGluePoints(ImpSetPercent,sal_False,&bOn);
167     EndUndo();
168 }
169 
170 
171 static void ImpGetAlign(SdrGluePoint& rGP, const SdrObject* /*pObj*/, const void* pbFirst, const void* pbDontCare, const void* pbVert, const void* pnRet, const void*)
172 {
173     sal_uInt16& nRet=*(sal_uInt16*)pnRet;
174     sal_Bool& bFirst=*(sal_Bool*)pbFirst;
175     sal_Bool& bDontCare=*(sal_Bool*)pbDontCare;
176     sal_Bool bVert=*(sal_Bool*)pbVert;
177     if (!bDontCare) {
178         sal_uInt16 nAlg=0;
179         if (bVert) {
180             nAlg=rGP.GetVertAlign();
181         } else {
182             nAlg=rGP.GetHorzAlign();
183         }
184         if (bFirst) { nRet=nAlg; bFirst=sal_False; }
185         else if (nRet!=nAlg) {
186             if (bVert) {
187                 nRet=SDRVERTALIGN_DONTCARE;
188             } else {
189                 nRet=SDRHORZALIGN_DONTCARE;
190             }
191             bDontCare=sal_True;
192         }
193     }
194 }
195 
196 sal_uInt16 SdrGlueEditView::GetMarkedGluePointsAlign(sal_Bool bVert) const
197 {
198     ForceUndirtyMrkPnt();
199     sal_Bool bFirst=sal_True;
200     sal_Bool bDontCare=sal_False;
201     sal_uInt16 nRet=0;
202     ((SdrGlueEditView*)this)->ImpDoMarkedGluePoints(ImpGetAlign,sal_True,&bFirst,&bDontCare,&bVert,&nRet);
203     return nRet;
204 }
205 
206 static void ImpSetAlign(SdrGluePoint& rGP, const SdrObject* pObj, const void* pbVert, const void* pnAlign, const void*, const void*, const void*)
207 {
208     Point aPos(rGP.GetAbsolutePos(*pObj));
209     if (*(sal_Bool*)pbVert) { // bVert?
210         rGP.SetVertAlign(*(sal_uInt16*)pnAlign);
211     } else {
212         rGP.SetHorzAlign(*(sal_uInt16*)pnAlign);
213     }
214     rGP.SetAbsolutePos(aPos,*pObj);
215 }
216 
217 void SdrGlueEditView::SetMarkedGluePointsAlign(sal_Bool bVert, sal_uInt16 nAlign)
218 {
219     ForceUndirtyMrkPnt();
220     BegUndo(ImpGetResStr(STR_EditSetGlueAlign),GetDescriptionOfMarkedGluePoints());
221     ImpDoMarkedGluePoints(ImpSetAlign,sal_False,&bVert,&nAlign);
222     EndUndo();
223 }
224 
225 
226 sal_Bool SdrGlueEditView::IsDeleteMarkedGluePointsPossible() const
227 {
228     return HasMarkedGluePoints();
229 }
230 
231 void SdrGlueEditView::DeleteMarkedGluePoints()
232 {
233     BrkAction();
234     ForceUndirtyMrkPnt();
235     const bool bUndo = IsUndoEnabled();
236     if( bUndo )
237         BegUndo(ImpGetResStr(STR_EditDelete),GetDescriptionOfMarkedGluePoints(),SDRREPFUNC_OBJ_DELETE);
238 
239     sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
240     for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++)
241     {
242         SdrMark* pM=GetSdrMarkByIndex(nm);
243         SdrObject* pObj=pM->GetMarkedSdrObj();
244         const SdrUShortCont* pPts=pM->GetMarkedGluePoints();
245         sal_uIntPtr nPtAnz=pPts==NULL ? 0 : pPts->GetCount();
246         if (nPtAnz!=0)
247         {
248             SdrGluePointList* pGPL=pObj->ForceGluePointList();
249             if (pGPL!=NULL)
250             {
251                 if( bUndo )
252                     AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
253 
254                 for (sal_uIntPtr nPtNum=0; nPtNum<nPtAnz; nPtNum++)
255                 {
256                     sal_uInt16 nPtId=pPts->GetObject(nPtNum);
257                     sal_uInt16 nGlueIdx=pGPL->FindGluePoint(nPtId);
258                     if (nGlueIdx!=SDRGLUEPOINT_NOTFOUND)
259                     {
260                         pGPL->Delete(nGlueIdx);
261                     }
262                 }
263                 pObj->SetChanged();
264                 pObj->BroadcastObjectChange();
265             }
266         }
267     }
268     if( bUndo )
269         EndUndo();
270     UnmarkAllGluePoints();
271     if (nMarkAnz!=0)
272         pMod->SetChanged();
273 }
274 
275 
276 void SdrGlueEditView::ImpCopyMarkedGluePoints()
277 {
278     const bool bUndo = IsUndoEnabled();
279 
280     if( bUndo )
281         BegUndo();
282 
283     sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
284     for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++)
285     {
286         SdrMark* pM=GetSdrMarkByIndex(nm);
287         SdrObject* pObj=pM->GetMarkedSdrObj();
288         SdrUShortCont* pPts=pM->GetMarkedGluePoints();
289         SdrGluePointList* pGPL=pObj->ForceGluePointList();
290         sal_uIntPtr nPtAnz=pPts==NULL ? 0 : pPts->GetCount();
291         if (nPtAnz!=0 && pGPL!=NULL)
292         {
293             if( bUndo )
294                 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
295 
296             for (sal_uIntPtr nPtNum=0; nPtNum<nPtAnz; nPtNum++)
297             {
298                 sal_uInt16 nPtId=pPts->GetObject(nPtNum);
299                 sal_uInt16 nGlueIdx=pGPL->FindGluePoint(nPtId);
300                 if (nGlueIdx!=SDRGLUEPOINT_NOTFOUND)
301                 {
302                     SdrGluePoint aNewGP((*pGPL)[nGlueIdx]); // Clone GluePoint
303                     sal_uInt16 nNewIdx=pGPL->Insert(aNewGP); // and insert
304                     sal_uInt16 nNewId=(*pGPL)[nNewIdx].GetId(); // Id des neuen GluePoints ermitteln
305                     pPts->Replace(nNewId,nPtNum); // und diesen markieren (anstelle des alten)
306                 }
307             }
308         }
309     }
310     if( bUndo )
311         EndUndo();
312 
313     if (nMarkAnz!=0)
314         pMod->SetChanged();
315 }
316 
317 
318 void SdrGlueEditView::ImpTransformMarkedGluePoints(PGlueTrFunc pTrFunc, const void* p1, const void* p2, const void* p3, const void* p4, const void* p5)
319 {
320     sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
321     for (sal_uIntPtr nm=0; nm<nMarkAnz; nm++) {
322         SdrMark* pM=GetSdrMarkByIndex(nm);
323         SdrObject* pObj=pM->GetMarkedSdrObj();
324         const SdrUShortCont* pPts=pM->GetMarkedGluePoints();
325         sal_uIntPtr nPtAnz=pPts==NULL ? 0 : pPts->GetCount();
326         if (nPtAnz!=0) {
327             SdrGluePointList* pGPL=pObj->ForceGluePointList();
328             if (pGPL!=NULL)
329             {
330                 if( IsUndoEnabled() )
331                     AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj));
332 
333                 for (sal_uIntPtr nPtNum=0; nPtNum<nPtAnz; nPtNum++) {
334                     sal_uInt16 nPtId=pPts->GetObject(nPtNum);
335                     sal_uInt16 nGlueIdx=pGPL->FindGluePoint(nPtId);
336                     if (nGlueIdx!=SDRGLUEPOINT_NOTFOUND) {
337                         SdrGluePoint& rGP=(*pGPL)[nGlueIdx];
338                         Point aPos(rGP.GetAbsolutePos(*pObj));
339                         (*pTrFunc)(aPos,p1,p2,p3,p4,p5);
340                         rGP.SetAbsolutePos(aPos,*pObj);
341                     }
342                 }
343                 pObj->SetChanged();
344                 pObj->BroadcastObjectChange();
345             }
346         }
347     }
348     if (nMarkAnz!=0) pMod->SetChanged();
349 }
350 
351 
352 static void ImpMove(Point& rPt, const void* p1, const void* /*p2*/, const void* /*p3*/, const void* /*p4*/, const void* /*p5*/)
353 {
354     rPt.X()+=((const Size*)p1)->Width();
355     rPt.Y()+=((const Size*)p1)->Height();
356 }
357 
358 void SdrGlueEditView::MoveMarkedGluePoints(const Size& rSiz, bool bCopy)
359 {
360     ForceUndirtyMrkPnt();
361     XubString aStr(ImpGetResStr(STR_EditMove));
362     if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy);
363     BegUndo(aStr,GetDescriptionOfMarkedGluePoints(),SDRREPFUNC_OBJ_MOVE);
364     if (bCopy) ImpCopyMarkedGluePoints();
365     ImpTransformMarkedGluePoints(ImpMove,&rSiz);
366     EndUndo();
367     AdjustMarkHdl();
368 }
369 
370 
371 static void ImpResize(Point& rPt, const void* p1, const void* p2, const void* p3, const void* /*p4*/, const void* /*p5*/)
372 {
373     ResizePoint(rPt,*(const Point*)p1,*(const Fraction*)p2,*(const Fraction*)p3);
374 }
375 
376 void SdrGlueEditView::ResizeMarkedGluePoints(const Point& rRef, const Fraction& xFact, const Fraction& yFact, bool bCopy)
377 {
378     ForceUndirtyMrkPnt();
379     XubString aStr(ImpGetResStr(STR_EditResize));
380     if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy);
381     BegUndo(aStr,GetDescriptionOfMarkedGluePoints(),SDRREPFUNC_OBJ_RESIZE);
382     if (bCopy) ImpCopyMarkedGluePoints();
383     ImpTransformMarkedGluePoints(ImpResize,&rRef,&xFact,&yFact);
384     EndUndo();
385     AdjustMarkHdl();
386 }
387 
388 
389 static void ImpRotate(Point& rPt, const void* p1, const void* /*p2*/, const void* p3, const void* p4, const void* /*p5*/)
390 {
391     RotatePoint(rPt,*(const Point*)p1,*(const double*)p3,*(const double*)p4);
392 }
393 
394 void SdrGlueEditView::RotateMarkedGluePoints(const Point& rRef, long nWink, bool bCopy)
395 {
396     ForceUndirtyMrkPnt();
397     XubString aStr(ImpGetResStr(STR_EditRotate));
398     if (bCopy) aStr+=ImpGetResStr(STR_EditWithCopy);
399     BegUndo(aStr,GetDescriptionOfMarkedGluePoints(),SDRREPFUNC_OBJ_ROTATE);
400     if (bCopy) ImpCopyMarkedGluePoints();
401     double nSin=sin(nWink*nPi180);
402     double nCos=cos(nWink*nPi180);
403     ImpTransformMarkedGluePoints(ImpRotate,&rRef,&nWink,&nSin,&nCos);
404     EndUndo();
405     AdjustMarkHdl();
406 }
407 
408 /* vim: set noet sw=4 ts=4: */
409