xref: /aoo41x/main/svx/source/svdraw/svdglev.cxx (revision cdf0e10c)
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