xref: /AOO41X/main/svx/source/svdraw/svdedtv2.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_svx.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <svx/svdedtv.hxx>
32*cdf0e10cSrcweir #include <editeng/outliner.hxx>
33*cdf0e10cSrcweir #include <svx/svdundo.hxx>
34*cdf0e10cSrcweir #include <svx/svdogrp.hxx>   // fuer's Gruppieren
35*cdf0e10cSrcweir #include <svx/svdovirt.hxx>  // fuer VirtualObject-Bundling (Writer)
36*cdf0e10cSrcweir #include <svx/svdopath.hxx>  // fuer CombineObjects
37*cdf0e10cSrcweir #include <svx/svdpage.hxx>
38*cdf0e10cSrcweir #include <svx/svdpagv.hxx>
39*cdf0e10cSrcweir #include "svx/svditer.hxx"
40*cdf0e10cSrcweir #include <svx/svdograf.hxx>  // fuer Possibilities
41*cdf0e10cSrcweir #include <svx/svdoole2.hxx>  // und Mtf-Import
42*cdf0e10cSrcweir #include "svx/svdstr.hrc"   // Namen aus der Resource
43*cdf0e10cSrcweir #include "svx/svdglob.hxx"  // StringCache
44*cdf0e10cSrcweir #include "svdfmtf.hxx"
45*cdf0e10cSrcweir #include <svx/svdetc.hxx>
46*cdf0e10cSrcweir #include <sfx2/basedlgs.hxx>
47*cdf0e10cSrcweir #include <vcl/msgbox.hxx>
48*cdf0e10cSrcweir #include <editeng/outlobj.hxx>
49*cdf0e10cSrcweir #include <editeng/eeitem.hxx>
50*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygon.hxx>
51*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygontools.hxx>
52*cdf0e10cSrcweir 
53*cdf0e10cSrcweir #include <svx/svxdlg.hxx> //CHINA001
54*cdf0e10cSrcweir #include <svx/dialogs.hrc> //CHINA001
55*cdf0e10cSrcweir 
56*cdf0e10cSrcweir // #i37011#
57*cdf0e10cSrcweir #include <svx/svdoashp.hxx>
58*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygoncutter.hxx>
59*cdf0e10cSrcweir 
60*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
61*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
62*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
63*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
64*cdf0e10cSrcweir //
65*cdf0e10cSrcweir //  @@@@@ @@@@@  @@ @@@@@@  @@ @@ @@ @@@@@ @@   @@
66*cdf0e10cSrcweir //  @@    @@  @@ @@   @@    @@ @@ @@ @@    @@   @@
67*cdf0e10cSrcweir //  @@    @@  @@ @@   @@    @@ @@ @@ @@    @@ @ @@
68*cdf0e10cSrcweir //  @@@@  @@  @@ @@   @@    @@@@@ @@ @@@@  @@@@@@@
69*cdf0e10cSrcweir //  @@    @@  @@ @@   @@     @@@  @@ @@    @@@@@@@
70*cdf0e10cSrcweir //  @@    @@  @@ @@   @@     @@@  @@ @@    @@@ @@@
71*cdf0e10cSrcweir //  @@@@@ @@@@@  @@   @@      @   @@ @@@@@ @@   @@
72*cdf0e10cSrcweir //
73*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
74*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
75*cdf0e10cSrcweir 
76*cdf0e10cSrcweir void SdrEditView::ImpBundleVirtObjOfMarkList()
77*cdf0e10cSrcweir {
78*cdf0e10cSrcweir   // ... fehlende Implementation
79*cdf0e10cSrcweir }
80*cdf0e10cSrcweir 
81*cdf0e10cSrcweir SdrObject* SdrEditView::GetMaxToTopObj(SdrObject* /*pObj*/) const
82*cdf0e10cSrcweir {
83*cdf0e10cSrcweir   return NULL;
84*cdf0e10cSrcweir }
85*cdf0e10cSrcweir 
86*cdf0e10cSrcweir SdrObject* SdrEditView::GetMaxToBtmObj(SdrObject* /*pObj*/) const
87*cdf0e10cSrcweir {
88*cdf0e10cSrcweir   return NULL;
89*cdf0e10cSrcweir }
90*cdf0e10cSrcweir 
91*cdf0e10cSrcweir void SdrEditView::ObjOrderChanged(SdrObject* /*pObj*/, sal_uIntPtr /*nOldPos*/, sal_uIntPtr /*nNewPos*/)
92*cdf0e10cSrcweir {
93*cdf0e10cSrcweir }
94*cdf0e10cSrcweir 
95*cdf0e10cSrcweir void SdrEditView::MovMarkedToTop()
96*cdf0e10cSrcweir {
97*cdf0e10cSrcweir 	sal_uIntPtr nAnz=GetMarkedObjectCount();
98*cdf0e10cSrcweir 	if (nAnz!=0)
99*cdf0e10cSrcweir 	{
100*cdf0e10cSrcweir 		const bool bUndo = IsUndoEnabled();
101*cdf0e10cSrcweir 
102*cdf0e10cSrcweir 		if( bUndo )
103*cdf0e10cSrcweir 			BegUndo(ImpGetResStr(STR_EditMovToTop),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_MOVTOTOP);
104*cdf0e10cSrcweir 
105*cdf0e10cSrcweir 		SortMarkedObjects();
106*cdf0e10cSrcweir 		sal_uIntPtr nm;
107*cdf0e10cSrcweir 		for (nm=0; nm<nAnz; nm++)
108*cdf0e10cSrcweir 		{ // Ordnums muessen alle stimmen!
109*cdf0e10cSrcweir 			GetMarkedObjectByIndex(nm)->GetOrdNum();
110*cdf0e10cSrcweir 		}
111*cdf0e10cSrcweir 		sal_Bool bChg=sal_False;
112*cdf0e10cSrcweir 		SdrObjList* pOL0=NULL;
113*cdf0e10cSrcweir 		sal_uIntPtr nNewPos=0;
114*cdf0e10cSrcweir 		for (nm=nAnz; nm>0;)
115*cdf0e10cSrcweir 		{
116*cdf0e10cSrcweir 			nm--;
117*cdf0e10cSrcweir 			SdrMark* pM=GetSdrMarkByIndex(nm);
118*cdf0e10cSrcweir 			SdrObject* pObj=pM->GetMarkedSdrObj();
119*cdf0e10cSrcweir 			SdrObjList* pOL=pObj->GetObjList();
120*cdf0e10cSrcweir 			if (pOL!=pOL0)
121*cdf0e10cSrcweir 			{
122*cdf0e10cSrcweir 				nNewPos=sal_uIntPtr(pOL->GetObjCount()-1);
123*cdf0e10cSrcweir 				pOL0=pOL;
124*cdf0e10cSrcweir 			}
125*cdf0e10cSrcweir 			sal_uIntPtr nNowPos=pObj->GetOrdNumDirect();
126*cdf0e10cSrcweir 			const Rectangle& rBR=pObj->GetCurrentBoundRect();
127*cdf0e10cSrcweir 			sal_uIntPtr nCmpPos=nNowPos+1;
128*cdf0e10cSrcweir             SdrObject* pMaxObj=GetMaxToTopObj(pObj);
129*cdf0e10cSrcweir             if (pMaxObj!=NULL)
130*cdf0e10cSrcweir 			{
131*cdf0e10cSrcweir                 sal_uIntPtr nMaxPos=pMaxObj->GetOrdNum();
132*cdf0e10cSrcweir                 if (nMaxPos!=0)
133*cdf0e10cSrcweir 					nMaxPos--;
134*cdf0e10cSrcweir                 if (nNewPos>nMaxPos)
135*cdf0e10cSrcweir 					nNewPos=nMaxPos; // diesen nicht ueberholen.
136*cdf0e10cSrcweir                 if (nNewPos<nNowPos)
137*cdf0e10cSrcweir 					nNewPos=nNowPos; // aber dabei auch nicht in die falsche Richtung schieben
138*cdf0e10cSrcweir             }
139*cdf0e10cSrcweir 			sal_Bool bEnd=sal_False;
140*cdf0e10cSrcweir 			while (nCmpPos<nNewPos && !bEnd)
141*cdf0e10cSrcweir 			{
142*cdf0e10cSrcweir 				SdrObject* pCmpObj=pOL->GetObj(nCmpPos);
143*cdf0e10cSrcweir 				if (pCmpObj==NULL)
144*cdf0e10cSrcweir 				{
145*cdf0e10cSrcweir 					DBG_ERROR("MovMarkedToTop(): Vergleichsobjekt nicht gefunden");
146*cdf0e10cSrcweir 					bEnd=sal_True;
147*cdf0e10cSrcweir                 }
148*cdf0e10cSrcweir 				else if (pCmpObj==pMaxObj)
149*cdf0e10cSrcweir 				{
150*cdf0e10cSrcweir                     nNewPos=nCmpPos;
151*cdf0e10cSrcweir                     nNewPos--;
152*cdf0e10cSrcweir                     bEnd=sal_True;
153*cdf0e10cSrcweir 				}
154*cdf0e10cSrcweir 				else if (rBR.IsOver(pCmpObj->GetCurrentBoundRect()))
155*cdf0e10cSrcweir 				{
156*cdf0e10cSrcweir 					nNewPos=nCmpPos;
157*cdf0e10cSrcweir 					bEnd=sal_True;
158*cdf0e10cSrcweir 				}
159*cdf0e10cSrcweir 				else
160*cdf0e10cSrcweir 				{
161*cdf0e10cSrcweir 					nCmpPos++;
162*cdf0e10cSrcweir 				}
163*cdf0e10cSrcweir 			}
164*cdf0e10cSrcweir 			if (nNowPos!=nNewPos)
165*cdf0e10cSrcweir 			{
166*cdf0e10cSrcweir 				bChg=sal_True;
167*cdf0e10cSrcweir 				pOL->SetObjectOrdNum(nNowPos,nNewPos);
168*cdf0e10cSrcweir 				if( bUndo )
169*cdf0e10cSrcweir 					AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj,nNowPos,nNewPos));
170*cdf0e10cSrcweir 				ObjOrderChanged(pObj,nNowPos,nNewPos);
171*cdf0e10cSrcweir 			}
172*cdf0e10cSrcweir 			nNewPos--;
173*cdf0e10cSrcweir 		}
174*cdf0e10cSrcweir 
175*cdf0e10cSrcweir 		if( bUndo )
176*cdf0e10cSrcweir 			EndUndo();
177*cdf0e10cSrcweir 
178*cdf0e10cSrcweir 		if (bChg)
179*cdf0e10cSrcweir 			MarkListHasChanged();
180*cdf0e10cSrcweir 	}
181*cdf0e10cSrcweir }
182*cdf0e10cSrcweir 
183*cdf0e10cSrcweir void SdrEditView::MovMarkedToBtm()
184*cdf0e10cSrcweir {
185*cdf0e10cSrcweir 	sal_uIntPtr nAnz=GetMarkedObjectCount();
186*cdf0e10cSrcweir 	if (nAnz!=0)
187*cdf0e10cSrcweir 	{
188*cdf0e10cSrcweir 		const bool bUndo = IsUndoEnabled();
189*cdf0e10cSrcweir 
190*cdf0e10cSrcweir 		if( bUndo )
191*cdf0e10cSrcweir 			BegUndo(ImpGetResStr(STR_EditMovToBtm),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_MOVTOBTM);
192*cdf0e10cSrcweir 
193*cdf0e10cSrcweir 		SortMarkedObjects();
194*cdf0e10cSrcweir 		sal_uIntPtr nm;
195*cdf0e10cSrcweir 		for (nm=0; nm<nAnz; nm++)
196*cdf0e10cSrcweir 		{ // Ordnums muessen alle stimmen!
197*cdf0e10cSrcweir 			GetMarkedObjectByIndex(nm)->GetOrdNum();
198*cdf0e10cSrcweir 		}
199*cdf0e10cSrcweir 
200*cdf0e10cSrcweir 		sal_Bool bChg=sal_False;
201*cdf0e10cSrcweir 		SdrObjList* pOL0=NULL;
202*cdf0e10cSrcweir 		sal_uIntPtr nNewPos=0;
203*cdf0e10cSrcweir 		for (nm=0; nm<nAnz; nm++)
204*cdf0e10cSrcweir 		{
205*cdf0e10cSrcweir 			SdrMark* pM=GetSdrMarkByIndex(nm);
206*cdf0e10cSrcweir 			SdrObject* pObj=pM->GetMarkedSdrObj();
207*cdf0e10cSrcweir 			SdrObjList* pOL=pObj->GetObjList();
208*cdf0e10cSrcweir 			if (pOL!=pOL0)
209*cdf0e10cSrcweir 			{
210*cdf0e10cSrcweir 				nNewPos=0;
211*cdf0e10cSrcweir 				pOL0=pOL;
212*cdf0e10cSrcweir 			}
213*cdf0e10cSrcweir 			sal_uIntPtr nNowPos=pObj->GetOrdNumDirect();
214*cdf0e10cSrcweir 			const Rectangle& rBR=pObj->GetCurrentBoundRect();
215*cdf0e10cSrcweir 			sal_uIntPtr nCmpPos=nNowPos; if (nCmpPos>0) nCmpPos--;
216*cdf0e10cSrcweir             SdrObject* pMaxObj=GetMaxToBtmObj(pObj);
217*cdf0e10cSrcweir             if (pMaxObj!=NULL)
218*cdf0e10cSrcweir 			{
219*cdf0e10cSrcweir                 sal_uIntPtr nMinPos=pMaxObj->GetOrdNum()+1;
220*cdf0e10cSrcweir                 if (nNewPos<nMinPos)
221*cdf0e10cSrcweir 					nNewPos=nMinPos; // diesen nicht ueberholen.
222*cdf0e10cSrcweir                 if (nNewPos>nNowPos)
223*cdf0e10cSrcweir 					nNewPos=nNowPos; // aber dabei auch nicht in die falsche Richtung schieben
224*cdf0e10cSrcweir             }
225*cdf0e10cSrcweir 			sal_Bool bEnd=sal_False;
226*cdf0e10cSrcweir 			// nNewPos ist an dieser Stelle noch die maximale Position,
227*cdf0e10cSrcweir 			// an der das Obj hinruecken darf, ohne seinen Vorgaenger
228*cdf0e10cSrcweir 			// (Mehrfachselektion) zu ueberholen.
229*cdf0e10cSrcweir 			while (nCmpPos>nNewPos && !bEnd)
230*cdf0e10cSrcweir 			{
231*cdf0e10cSrcweir 				SdrObject* pCmpObj=pOL->GetObj(nCmpPos);
232*cdf0e10cSrcweir 				if (pCmpObj==NULL)
233*cdf0e10cSrcweir 				{
234*cdf0e10cSrcweir 					DBG_ERROR("MovMarkedToBtm(): Vergleichsobjekt nicht gefunden");
235*cdf0e10cSrcweir 					bEnd=sal_True;
236*cdf0e10cSrcweir                 }
237*cdf0e10cSrcweir 				else if (pCmpObj==pMaxObj)
238*cdf0e10cSrcweir 				{
239*cdf0e10cSrcweir                     nNewPos=nCmpPos;
240*cdf0e10cSrcweir                     nNewPos++;
241*cdf0e10cSrcweir                     bEnd=sal_True;
242*cdf0e10cSrcweir 				}
243*cdf0e10cSrcweir 				else if (rBR.IsOver(pCmpObj->GetCurrentBoundRect()))
244*cdf0e10cSrcweir 				{
245*cdf0e10cSrcweir 					nNewPos=nCmpPos;
246*cdf0e10cSrcweir 					bEnd=sal_True;
247*cdf0e10cSrcweir 				}
248*cdf0e10cSrcweir 				else
249*cdf0e10cSrcweir 				{
250*cdf0e10cSrcweir 					nCmpPos--;
251*cdf0e10cSrcweir 				}
252*cdf0e10cSrcweir 			}
253*cdf0e10cSrcweir 			if (nNowPos!=nNewPos)
254*cdf0e10cSrcweir 			{
255*cdf0e10cSrcweir 				bChg=sal_True;
256*cdf0e10cSrcweir 				pOL->SetObjectOrdNum(nNowPos,nNewPos);
257*cdf0e10cSrcweir 				if( bUndo )
258*cdf0e10cSrcweir 					AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj,nNowPos,nNewPos));
259*cdf0e10cSrcweir 				ObjOrderChanged(pObj,nNowPos,nNewPos);
260*cdf0e10cSrcweir 			}
261*cdf0e10cSrcweir 			nNewPos++;
262*cdf0e10cSrcweir 		}
263*cdf0e10cSrcweir 
264*cdf0e10cSrcweir 		if(bUndo)
265*cdf0e10cSrcweir 			EndUndo();
266*cdf0e10cSrcweir 
267*cdf0e10cSrcweir 		if(bChg)
268*cdf0e10cSrcweir 			MarkListHasChanged();
269*cdf0e10cSrcweir 	}
270*cdf0e10cSrcweir }
271*cdf0e10cSrcweir 
272*cdf0e10cSrcweir void SdrEditView::PutMarkedToTop()
273*cdf0e10cSrcweir {
274*cdf0e10cSrcweir 	PutMarkedInFrontOfObj(NULL);
275*cdf0e10cSrcweir }
276*cdf0e10cSrcweir 
277*cdf0e10cSrcweir void SdrEditView::PutMarkedInFrontOfObj(const SdrObject* pRefObj)
278*cdf0e10cSrcweir {
279*cdf0e10cSrcweir 	sal_uIntPtr nAnz=GetMarkedObjectCount();
280*cdf0e10cSrcweir 	if (nAnz!=0)
281*cdf0e10cSrcweir 	{
282*cdf0e10cSrcweir 		const bool bUndo = IsUndoEnabled();
283*cdf0e10cSrcweir 		if( bUndo )
284*cdf0e10cSrcweir 			BegUndo(ImpGetResStr(STR_EditPutToTop),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_PUTTOTOP);
285*cdf0e10cSrcweir 
286*cdf0e10cSrcweir 		SortMarkedObjects();
287*cdf0e10cSrcweir 
288*cdf0e10cSrcweir 		if (pRefObj!=NULL)
289*cdf0e10cSrcweir 		{
290*cdf0e10cSrcweir 			// Damit "Vor das Objekt" auch funktioniert wenn die
291*cdf0e10cSrcweir 			// markierten Objekte bereits vor dem Objekt stehen
292*cdf0e10cSrcweir 			sal_uIntPtr nRefMark=TryToFindMarkedObject(pRefObj);
293*cdf0e10cSrcweir 			SdrMark aRefMark;
294*cdf0e10cSrcweir 			if (nRefMark!=CONTAINER_ENTRY_NOTFOUND)
295*cdf0e10cSrcweir 			{
296*cdf0e10cSrcweir 				aRefMark=*GetSdrMarkByIndex(nRefMark);
297*cdf0e10cSrcweir 				GetMarkedObjectListWriteAccess().DeleteMark(nRefMark);
298*cdf0e10cSrcweir 			}
299*cdf0e10cSrcweir 			PutMarkedToBtm();
300*cdf0e10cSrcweir 			if (nRefMark!=CONTAINER_ENTRY_NOTFOUND)
301*cdf0e10cSrcweir 			{
302*cdf0e10cSrcweir 				GetMarkedObjectListWriteAccess().InsertEntry(aRefMark);
303*cdf0e10cSrcweir 				SortMarkedObjects();
304*cdf0e10cSrcweir 			}
305*cdf0e10cSrcweir 		}
306*cdf0e10cSrcweir 		sal_uIntPtr nm;
307*cdf0e10cSrcweir 		for (nm=0; nm<nAnz; nm++)
308*cdf0e10cSrcweir 		{ // Ordnums muessen alle stimmen!
309*cdf0e10cSrcweir 			GetMarkedObjectByIndex(nm)->GetOrdNum();
310*cdf0e10cSrcweir 		}
311*cdf0e10cSrcweir 		sal_Bool bChg=sal_False;
312*cdf0e10cSrcweir 		SdrObjList* pOL0=NULL;
313*cdf0e10cSrcweir 		sal_uIntPtr nNewPos=0;
314*cdf0e10cSrcweir 		for (nm=nAnz; nm>0;)
315*cdf0e10cSrcweir 		{
316*cdf0e10cSrcweir 			nm--;
317*cdf0e10cSrcweir 			SdrMark* pM=GetSdrMarkByIndex(nm);
318*cdf0e10cSrcweir 			SdrObject* pObj=pM->GetMarkedSdrObj();
319*cdf0e10cSrcweir 			if (pObj!=pRefObj)
320*cdf0e10cSrcweir 			{
321*cdf0e10cSrcweir 				SdrObjList* pOL=pObj->GetObjList();
322*cdf0e10cSrcweir 				if (pOL!=pOL0)
323*cdf0e10cSrcweir 				{
324*cdf0e10cSrcweir 					nNewPos=sal_uIntPtr(pOL->GetObjCount()-1);
325*cdf0e10cSrcweir 					pOL0=pOL;
326*cdf0e10cSrcweir 				}
327*cdf0e10cSrcweir 				sal_uIntPtr nNowPos=pObj->GetOrdNumDirect();
328*cdf0e10cSrcweir                 SdrObject* pMaxObj=GetMaxToTopObj(pObj);
329*cdf0e10cSrcweir                 if (pMaxObj!=NULL)
330*cdf0e10cSrcweir 				{
331*cdf0e10cSrcweir                     sal_uIntPtr nMaxOrd=pMaxObj->GetOrdNum(); // geht leider nicht anders
332*cdf0e10cSrcweir                     if (nMaxOrd>0)
333*cdf0e10cSrcweir 						nMaxOrd--;
334*cdf0e10cSrcweir                     if (nNewPos>nMaxOrd)
335*cdf0e10cSrcweir 						nNewPos=nMaxOrd; // nicht ueberholen.
336*cdf0e10cSrcweir                     if (nNewPos<nNowPos)
337*cdf0e10cSrcweir 						nNewPos=nNowPos; // aber dabei auch nicht in die falsche Richtung schieben
338*cdf0e10cSrcweir                 }
339*cdf0e10cSrcweir 				if (pRefObj!=NULL)
340*cdf0e10cSrcweir 				{
341*cdf0e10cSrcweir 					if (pRefObj->GetObjList()==pObj->GetObjList())
342*cdf0e10cSrcweir 					{
343*cdf0e10cSrcweir 						sal_uIntPtr nMaxOrd=pRefObj->GetOrdNum(); // geht leider nicht anders
344*cdf0e10cSrcweir 						if (nNewPos>nMaxOrd)
345*cdf0e10cSrcweir 							nNewPos=nMaxOrd; // nicht ueberholen.
346*cdf0e10cSrcweir 						if (nNewPos<nNowPos)
347*cdf0e10cSrcweir 							nNewPos=nNowPos; // aber dabei auch nicht in die falsche Richtung schieben
348*cdf0e10cSrcweir 					}
349*cdf0e10cSrcweir 					else
350*cdf0e10cSrcweir 					{
351*cdf0e10cSrcweir 						nNewPos=nNowPos; // andere PageView, also nicht veraendern
352*cdf0e10cSrcweir 					}
353*cdf0e10cSrcweir 				}
354*cdf0e10cSrcweir 				if (nNowPos!=nNewPos)
355*cdf0e10cSrcweir 				{
356*cdf0e10cSrcweir 					bChg=sal_True;
357*cdf0e10cSrcweir 					pOL->SetObjectOrdNum(nNowPos,nNewPos);
358*cdf0e10cSrcweir 					if( bUndo )
359*cdf0e10cSrcweir 						AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj,nNowPos,nNewPos));
360*cdf0e10cSrcweir 					ObjOrderChanged(pObj,nNowPos,nNewPos);
361*cdf0e10cSrcweir 				}
362*cdf0e10cSrcweir 				nNewPos--;
363*cdf0e10cSrcweir 			} // if (pObj!=pRefObj)
364*cdf0e10cSrcweir 		} // for-Schleife ueber alle Markierten Objekte
365*cdf0e10cSrcweir 
366*cdf0e10cSrcweir 		if( bUndo )
367*cdf0e10cSrcweir 			EndUndo();
368*cdf0e10cSrcweir 
369*cdf0e10cSrcweir 		if(bChg)
370*cdf0e10cSrcweir 			MarkListHasChanged();
371*cdf0e10cSrcweir 	}
372*cdf0e10cSrcweir }
373*cdf0e10cSrcweir 
374*cdf0e10cSrcweir void SdrEditView::PutMarkedToBtm()
375*cdf0e10cSrcweir {
376*cdf0e10cSrcweir 	PutMarkedBehindObj(NULL);
377*cdf0e10cSrcweir }
378*cdf0e10cSrcweir 
379*cdf0e10cSrcweir void SdrEditView::PutMarkedBehindObj(const SdrObject* pRefObj)
380*cdf0e10cSrcweir {
381*cdf0e10cSrcweir 	sal_uIntPtr nAnz=GetMarkedObjectCount();
382*cdf0e10cSrcweir 	if (nAnz!=0)
383*cdf0e10cSrcweir 	{
384*cdf0e10cSrcweir 		const bool bUndo = IsUndoEnabled();
385*cdf0e10cSrcweir 
386*cdf0e10cSrcweir 		if( bUndo )
387*cdf0e10cSrcweir 			BegUndo(ImpGetResStr(STR_EditPutToBtm),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_PUTTOBTM);
388*cdf0e10cSrcweir 
389*cdf0e10cSrcweir 		SortMarkedObjects();
390*cdf0e10cSrcweir 		if (pRefObj!=NULL)
391*cdf0e10cSrcweir 		{
392*cdf0e10cSrcweir 			// Damit "Hinter das Objekt" auch funktioniert wenn die
393*cdf0e10cSrcweir 			// markierten Objekte bereits hinter dem Objekt stehen
394*cdf0e10cSrcweir 			sal_uIntPtr nRefMark=TryToFindMarkedObject(pRefObj);
395*cdf0e10cSrcweir 			SdrMark aRefMark;
396*cdf0e10cSrcweir 			if (nRefMark!=CONTAINER_ENTRY_NOTFOUND)
397*cdf0e10cSrcweir 			{
398*cdf0e10cSrcweir 				aRefMark=*GetSdrMarkByIndex(nRefMark);
399*cdf0e10cSrcweir 				GetMarkedObjectListWriteAccess().DeleteMark(nRefMark);
400*cdf0e10cSrcweir 			}
401*cdf0e10cSrcweir 			PutMarkedToTop();
402*cdf0e10cSrcweir 			if (nRefMark!=CONTAINER_ENTRY_NOTFOUND)
403*cdf0e10cSrcweir 			{
404*cdf0e10cSrcweir 				GetMarkedObjectListWriteAccess().InsertEntry(aRefMark);
405*cdf0e10cSrcweir 				SortMarkedObjects();
406*cdf0e10cSrcweir 			}
407*cdf0e10cSrcweir 		}
408*cdf0e10cSrcweir 		sal_uIntPtr nm;
409*cdf0e10cSrcweir 		for (nm=0; nm<nAnz; nm++) { // Ordnums muessen alle stimmen!
410*cdf0e10cSrcweir 			GetMarkedObjectByIndex(nm)->GetOrdNum();
411*cdf0e10cSrcweir 		}
412*cdf0e10cSrcweir 		sal_Bool bChg=sal_False;
413*cdf0e10cSrcweir 		SdrObjList* pOL0=NULL;
414*cdf0e10cSrcweir 		sal_uIntPtr nNewPos=0;
415*cdf0e10cSrcweir 		for (nm=0; nm<nAnz; nm++) {
416*cdf0e10cSrcweir 			SdrMark* pM=GetSdrMarkByIndex(nm);
417*cdf0e10cSrcweir 			SdrObject* pObj=pM->GetMarkedSdrObj();
418*cdf0e10cSrcweir 			if (pObj!=pRefObj) {
419*cdf0e10cSrcweir 				SdrObjList* pOL=pObj->GetObjList();
420*cdf0e10cSrcweir 				if (pOL!=pOL0) {
421*cdf0e10cSrcweir 					nNewPos=0;
422*cdf0e10cSrcweir 					pOL0=pOL;
423*cdf0e10cSrcweir 				}
424*cdf0e10cSrcweir 				sal_uIntPtr nNowPos=pObj->GetOrdNumDirect();
425*cdf0e10cSrcweir                 SdrObject* pMinObj=GetMaxToBtmObj(pObj);
426*cdf0e10cSrcweir                 if (pMinObj!=NULL) {
427*cdf0e10cSrcweir                     sal_uIntPtr nMinOrd=pMinObj->GetOrdNum()+1; // geht leider nicht anders
428*cdf0e10cSrcweir                     if (nNewPos<nMinOrd) nNewPos=nMinOrd; // nicht ueberholen.
429*cdf0e10cSrcweir                     if (nNewPos>nNowPos) nNewPos=nNowPos; // aber dabei auch nicht in die falsche Richtung schieben
430*cdf0e10cSrcweir                 }
431*cdf0e10cSrcweir 				if (pRefObj!=NULL) {
432*cdf0e10cSrcweir 					if (pRefObj->GetObjList()==pObj->GetObjList()) {
433*cdf0e10cSrcweir 						sal_uIntPtr nMinOrd=pRefObj->GetOrdNum(); // geht leider nicht anders
434*cdf0e10cSrcweir 						if (nNewPos<nMinOrd) nNewPos=nMinOrd; // nicht ueberholen.
435*cdf0e10cSrcweir 						if (nNewPos>nNowPos) nNewPos=nNowPos; // aber dabei auch nicht in die falsche Richtung schieben
436*cdf0e10cSrcweir 					} else {
437*cdf0e10cSrcweir 						nNewPos=nNowPos; // andere PageView, also nicht veraendern
438*cdf0e10cSrcweir 					}
439*cdf0e10cSrcweir 				}
440*cdf0e10cSrcweir 				if (nNowPos!=nNewPos) {
441*cdf0e10cSrcweir 					bChg=sal_True;
442*cdf0e10cSrcweir 					pOL->SetObjectOrdNum(nNowPos,nNewPos);
443*cdf0e10cSrcweir 					if( bUndo )
444*cdf0e10cSrcweir 						AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj,nNowPos,nNewPos));
445*cdf0e10cSrcweir 					ObjOrderChanged(pObj,nNowPos,nNewPos);
446*cdf0e10cSrcweir 				}
447*cdf0e10cSrcweir 				nNewPos++;
448*cdf0e10cSrcweir 			} // if (pObj!=pRefObj)
449*cdf0e10cSrcweir 		} // for-Schleife ueber alle markierten Objekte
450*cdf0e10cSrcweir 
451*cdf0e10cSrcweir 		if(bUndo)
452*cdf0e10cSrcweir 			EndUndo();
453*cdf0e10cSrcweir 
454*cdf0e10cSrcweir 		if(bChg)
455*cdf0e10cSrcweir 			MarkListHasChanged();
456*cdf0e10cSrcweir 	}
457*cdf0e10cSrcweir }
458*cdf0e10cSrcweir 
459*cdf0e10cSrcweir void SdrEditView::ReverseOrderOfMarked()
460*cdf0e10cSrcweir {
461*cdf0e10cSrcweir 	SortMarkedObjects();
462*cdf0e10cSrcweir 	sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
463*cdf0e10cSrcweir 	if (nMarkAnz>0)
464*cdf0e10cSrcweir 	{
465*cdf0e10cSrcweir 		//sal_Bool bNeedBundle=sal_False;
466*cdf0e10cSrcweir 		sal_Bool bChg=sal_False;
467*cdf0e10cSrcweir 
468*cdf0e10cSrcweir 		bool bUndo = IsUndoEnabled();
469*cdf0e10cSrcweir 		if( bUndo )
470*cdf0e10cSrcweir 			BegUndo(ImpGetResStr(STR_EditRevOrder),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_REVORDER);
471*cdf0e10cSrcweir 
472*cdf0e10cSrcweir 		sal_uIntPtr a=0;
473*cdf0e10cSrcweir 		do {
474*cdf0e10cSrcweir 			// Markierung ueber mehrere PageViews berueksichtigen
475*cdf0e10cSrcweir 			sal_uIntPtr b=a+1;
476*cdf0e10cSrcweir 			while (b<nMarkAnz && GetSdrPageViewOfMarkedByIndex(b) == GetSdrPageViewOfMarkedByIndex(a)) b++;
477*cdf0e10cSrcweir 			b--;
478*cdf0e10cSrcweir 			SdrObjList* pOL=GetSdrPageViewOfMarkedByIndex(a)->GetObjList();
479*cdf0e10cSrcweir 			sal_uIntPtr c=b;
480*cdf0e10cSrcweir 			if (a<c) { // Sicherstellen, dass die OrdNums nicht Dirty sind
481*cdf0e10cSrcweir 				GetMarkedObjectByIndex(a)->GetOrdNum();
482*cdf0e10cSrcweir 			}
483*cdf0e10cSrcweir 			while (a<c) {
484*cdf0e10cSrcweir 				SdrObject* pObj1=GetMarkedObjectByIndex(a);
485*cdf0e10cSrcweir 				SdrObject* pObj2=GetMarkedObjectByIndex(c);
486*cdf0e10cSrcweir 				sal_uIntPtr nOrd1=pObj1->GetOrdNumDirect();
487*cdf0e10cSrcweir 				sal_uIntPtr nOrd2=pObj2->GetOrdNumDirect();
488*cdf0e10cSrcweir 				if( bUndo )
489*cdf0e10cSrcweir 				{
490*cdf0e10cSrcweir 					AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj1,nOrd1,nOrd2));
491*cdf0e10cSrcweir 					AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj2,nOrd2-1,nOrd1));
492*cdf0e10cSrcweir 				}
493*cdf0e10cSrcweir 				pOL->SetObjectOrdNum(nOrd1,nOrd2);
494*cdf0e10cSrcweir 				// Obj 2 ist um eine Position nach vorn gerutscht, deshalb nun nOrd2-1
495*cdf0e10cSrcweir 				pOL->SetObjectOrdNum(nOrd2-1,nOrd1);
496*cdf0e10cSrcweir 				// Verwendung von Replace statt SetOrdNum wg. Performance (Neuberechnung der Ordnums)
497*cdf0e10cSrcweir 				a++; c--;
498*cdf0e10cSrcweir 				bChg=sal_True;
499*cdf0e10cSrcweir 			}
500*cdf0e10cSrcweir 			a=b+1;
501*cdf0e10cSrcweir 		} while (a<nMarkAnz);
502*cdf0e10cSrcweir 
503*cdf0e10cSrcweir 		if(bUndo)
504*cdf0e10cSrcweir 			EndUndo();
505*cdf0e10cSrcweir 
506*cdf0e10cSrcweir 		if(bChg)
507*cdf0e10cSrcweir 			MarkListHasChanged();
508*cdf0e10cSrcweir 	}
509*cdf0e10cSrcweir }
510*cdf0e10cSrcweir 
511*cdf0e10cSrcweir void SdrEditView::ImpCheckToTopBtmPossible()
512*cdf0e10cSrcweir {
513*cdf0e10cSrcweir 	sal_uIntPtr nAnz=GetMarkedObjectCount();
514*cdf0e10cSrcweir 	if (nAnz==0)
515*cdf0e10cSrcweir 		return;
516*cdf0e10cSrcweir 	if (nAnz==1)
517*cdf0e10cSrcweir 	{ // Sonderbehandlung fuer Einzelmarkierung
518*cdf0e10cSrcweir 		SdrObject* pObj=GetMarkedObjectByIndex(0);
519*cdf0e10cSrcweir 		SdrObjList* pOL=pObj->GetObjList();
520*cdf0e10cSrcweir 		sal_uIntPtr nMax=pOL->GetObjCount();
521*cdf0e10cSrcweir 		sal_uIntPtr nMin=0;
522*cdf0e10cSrcweir 		sal_uIntPtr nObjNum=pObj->GetOrdNum();
523*cdf0e10cSrcweir 		SdrObject* pRestrict=GetMaxToTopObj(pObj);
524*cdf0e10cSrcweir 		if (pRestrict!=NULL) {
525*cdf0e10cSrcweir 			sal_uIntPtr nRestrict=pRestrict->GetOrdNum();
526*cdf0e10cSrcweir 			if (nRestrict<nMax) nMax=nRestrict;
527*cdf0e10cSrcweir 		}
528*cdf0e10cSrcweir 		pRestrict=GetMaxToBtmObj(pObj);
529*cdf0e10cSrcweir 		if (pRestrict!=NULL) {
530*cdf0e10cSrcweir 			sal_uIntPtr nRestrict=pRestrict->GetOrdNum();
531*cdf0e10cSrcweir 			if (nRestrict>nMin) nMin=nRestrict;
532*cdf0e10cSrcweir 		}
533*cdf0e10cSrcweir 		bToTopPossible=nObjNum<sal_uIntPtr(nMax-1);
534*cdf0e10cSrcweir 		bToBtmPossible=nObjNum>nMin;
535*cdf0e10cSrcweir 	} else { // Mehrfachselektion
536*cdf0e10cSrcweir 		sal_uIntPtr nm=0;
537*cdf0e10cSrcweir 		SdrObjList* pOL0=NULL;
538*cdf0e10cSrcweir 		long nPos0=-1;
539*cdf0e10cSrcweir 		while (!bToBtmPossible && nm<nAnz) { // 'nach hinten' checken
540*cdf0e10cSrcweir 			SdrObject* pObj=GetMarkedObjectByIndex(nm);
541*cdf0e10cSrcweir 			SdrObjList* pOL=pObj->GetObjList();
542*cdf0e10cSrcweir 			if (pOL!=pOL0) {
543*cdf0e10cSrcweir 				nPos0=-1;
544*cdf0e10cSrcweir 				pOL0=pOL;
545*cdf0e10cSrcweir 			}
546*cdf0e10cSrcweir 			sal_uIntPtr nPos=pObj->GetOrdNum();
547*cdf0e10cSrcweir 			bToBtmPossible=nPos>sal_uIntPtr(nPos0+1);
548*cdf0e10cSrcweir 			nPos0=long(nPos);
549*cdf0e10cSrcweir 			nm++;
550*cdf0e10cSrcweir 		}
551*cdf0e10cSrcweir 		nm=nAnz;
552*cdf0e10cSrcweir 		pOL0=NULL;
553*cdf0e10cSrcweir 		nPos0=0x7FFFFFFF;
554*cdf0e10cSrcweir 		while (!bToTopPossible && nm>0) { // 'nach vorn' checken
555*cdf0e10cSrcweir 			nm--;
556*cdf0e10cSrcweir 			SdrObject* pObj=GetMarkedObjectByIndex(nm);
557*cdf0e10cSrcweir 			SdrObjList* pOL=pObj->GetObjList();
558*cdf0e10cSrcweir 			if (pOL!=pOL0) {
559*cdf0e10cSrcweir 				nPos0=pOL->GetObjCount();
560*cdf0e10cSrcweir 				pOL0=pOL;
561*cdf0e10cSrcweir 			}
562*cdf0e10cSrcweir 			sal_uIntPtr nPos=pObj->GetOrdNum();
563*cdf0e10cSrcweir 			bToTopPossible=nPos+1<sal_uIntPtr(nPos0);
564*cdf0e10cSrcweir 			nPos0=nPos;
565*cdf0e10cSrcweir 		}
566*cdf0e10cSrcweir 	}
567*cdf0e10cSrcweir }
568*cdf0e10cSrcweir 
569*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
570*cdf0e10cSrcweir //
571*cdf0e10cSrcweir //   @@@@    @@@@   @@   @@  @@@@@   @@  @@  @@  @@@@@
572*cdf0e10cSrcweir //  @@  @@  @@  @@  @@@ @@@  @@  @@  @@  @@@ @@  @@
573*cdf0e10cSrcweir //  @@      @@  @@  @@@@@@@  @@  @@  @@  @@@@@@  @@
574*cdf0e10cSrcweir //  @@      @@  @@  @@@@@@@  @@@@@   @@  @@@@@@  @@@@
575*cdf0e10cSrcweir //  @@      @@  @@  @@ @ @@  @@  @@  @@  @@ @@@  @@
576*cdf0e10cSrcweir //  @@  @@  @@  @@  @@   @@  @@  @@  @@  @@  @@  @@
577*cdf0e10cSrcweir //   @@@@    @@@@   @@   @@  @@@@@   @@  @@  @@  @@@@@
578*cdf0e10cSrcweir //
579*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
580*cdf0e10cSrcweir 
581*cdf0e10cSrcweir void SdrEditView::ImpCopyAttributes(const SdrObject* pSource, SdrObject* pDest) const
582*cdf0e10cSrcweir {
583*cdf0e10cSrcweir 	if (pSource!=NULL) {
584*cdf0e10cSrcweir 		SdrObjList* pOL=pSource->GetSubList();
585*cdf0e10cSrcweir 		if (pOL!=NULL && !pSource->Is3DObj()) { // erstes Nichtgruppenobjekt aus der Gruppe holen
586*cdf0e10cSrcweir 			SdrObjListIter aIter(*pOL,IM_DEEPNOGROUPS);
587*cdf0e10cSrcweir 			pSource=aIter.Next();
588*cdf0e10cSrcweir 		}
589*cdf0e10cSrcweir 	}
590*cdf0e10cSrcweir 
591*cdf0e10cSrcweir 	if(pSource && pDest)
592*cdf0e10cSrcweir 	{
593*cdf0e10cSrcweir 		SfxItemSet aSet(pMod->GetItemPool(),
594*cdf0e10cSrcweir 			SDRATTR_START,				SDRATTR_NOTPERSIST_FIRST-1,
595*cdf0e10cSrcweir 			SDRATTR_NOTPERSIST_LAST+1,	SDRATTR_END,
596*cdf0e10cSrcweir 			EE_ITEMS_START,				EE_ITEMS_END,
597*cdf0e10cSrcweir 			0, 0); // #52757#, #52762#
598*cdf0e10cSrcweir 
599*cdf0e10cSrcweir 		aSet.Put(pSource->GetMergedItemSet());
600*cdf0e10cSrcweir 
601*cdf0e10cSrcweir 		pDest->ClearMergedItem();
602*cdf0e10cSrcweir 		pDest->SetMergedItemSet(aSet);
603*cdf0e10cSrcweir 
604*cdf0e10cSrcweir 		pDest->NbcSetLayer(pSource->GetLayer());
605*cdf0e10cSrcweir 		pDest->NbcSetStyleSheet(pSource->GetStyleSheet(), sal_True);
606*cdf0e10cSrcweir 	}
607*cdf0e10cSrcweir }
608*cdf0e10cSrcweir 
609*cdf0e10cSrcweir sal_Bool SdrEditView::ImpCanConvertForCombine1(const SdrObject* pObj) const
610*cdf0e10cSrcweir {
611*cdf0e10cSrcweir 	// #69711 : new condition IsLine() to be able to combine simple Lines
612*cdf0e10cSrcweir 	sal_Bool bIsLine(sal_False);
613*cdf0e10cSrcweir 
614*cdf0e10cSrcweir 	const SdrPathObj* pPath = PTR_CAST(SdrPathObj,pObj);
615*cdf0e10cSrcweir 
616*cdf0e10cSrcweir 	if(pPath)
617*cdf0e10cSrcweir 	{
618*cdf0e10cSrcweir 		bIsLine = pPath->IsLine();
619*cdf0e10cSrcweir 	}
620*cdf0e10cSrcweir 
621*cdf0e10cSrcweir 	SdrObjTransformInfoRec aInfo;
622*cdf0e10cSrcweir 	pObj->TakeObjInfo(aInfo);
623*cdf0e10cSrcweir 
624*cdf0e10cSrcweir 	return (aInfo.bCanConvToPath || aInfo.bCanConvToPoly || bIsLine);
625*cdf0e10cSrcweir }
626*cdf0e10cSrcweir 
627*cdf0e10cSrcweir sal_Bool SdrEditView::ImpCanConvertForCombine(const SdrObject* pObj) const
628*cdf0e10cSrcweir {
629*cdf0e10cSrcweir 	SdrObjList* pOL = pObj->GetSubList();
630*cdf0e10cSrcweir 
631*cdf0e10cSrcweir 	if(pOL && !pObj->Is3DObj())
632*cdf0e10cSrcweir 	{
633*cdf0e10cSrcweir 		SdrObjListIter aIter(*pOL, IM_DEEPNOGROUPS);
634*cdf0e10cSrcweir 
635*cdf0e10cSrcweir 		while(aIter.IsMore())
636*cdf0e10cSrcweir 		{
637*cdf0e10cSrcweir 			SdrObject* pObj1 = aIter.Next();
638*cdf0e10cSrcweir 
639*cdf0e10cSrcweir 			// Es muessen alle Member einer Gruppe konvertierbar sein
640*cdf0e10cSrcweir 			if(!ImpCanConvertForCombine1(pObj1))
641*cdf0e10cSrcweir 			{
642*cdf0e10cSrcweir 				return sal_False;
643*cdf0e10cSrcweir 			}
644*cdf0e10cSrcweir 		}
645*cdf0e10cSrcweir 	}
646*cdf0e10cSrcweir 	else
647*cdf0e10cSrcweir 	{
648*cdf0e10cSrcweir 		if(!ImpCanConvertForCombine1(pObj))
649*cdf0e10cSrcweir 		{
650*cdf0e10cSrcweir 			return sal_False;
651*cdf0e10cSrcweir 		}
652*cdf0e10cSrcweir 	}
653*cdf0e10cSrcweir 
654*cdf0e10cSrcweir 	return sal_True;
655*cdf0e10cSrcweir }
656*cdf0e10cSrcweir 
657*cdf0e10cSrcweir basegfx::B2DPolyPolygon SdrEditView::ImpGetPolyPolygon1(const SdrObject* pObj, sal_Bool bCombine) const
658*cdf0e10cSrcweir {
659*cdf0e10cSrcweir 	basegfx::B2DPolyPolygon aRetval;
660*cdf0e10cSrcweir 	SdrPathObj* pPath = PTR_CAST(SdrPathObj, pObj);
661*cdf0e10cSrcweir 
662*cdf0e10cSrcweir 	if(bCombine && pPath && !pObj->GetOutlinerParaObject())
663*cdf0e10cSrcweir 	{
664*cdf0e10cSrcweir 		aRetval = pPath->GetPathPoly();
665*cdf0e10cSrcweir 	}
666*cdf0e10cSrcweir 	else
667*cdf0e10cSrcweir 	{
668*cdf0e10cSrcweir 		SdrObject* pConvObj = pObj->ConvertToPolyObj(bCombine, sal_False);
669*cdf0e10cSrcweir 
670*cdf0e10cSrcweir 		if(pConvObj)
671*cdf0e10cSrcweir 		{
672*cdf0e10cSrcweir 			SdrObjList* pOL = pConvObj->GetSubList();
673*cdf0e10cSrcweir 
674*cdf0e10cSrcweir 			if(pOL)
675*cdf0e10cSrcweir 			{
676*cdf0e10cSrcweir 				SdrObjListIter aIter(*pOL, IM_DEEPNOGROUPS);
677*cdf0e10cSrcweir 
678*cdf0e10cSrcweir 				while(aIter.IsMore())
679*cdf0e10cSrcweir 				{
680*cdf0e10cSrcweir 					SdrObject* pObj1 = aIter.Next();
681*cdf0e10cSrcweir 					pPath = PTR_CAST(SdrPathObj, pObj1);
682*cdf0e10cSrcweir 
683*cdf0e10cSrcweir 					if(pPath)
684*cdf0e10cSrcweir 					{
685*cdf0e10cSrcweir 						aRetval.append(pPath->GetPathPoly());
686*cdf0e10cSrcweir 					}
687*cdf0e10cSrcweir 				}
688*cdf0e10cSrcweir 			}
689*cdf0e10cSrcweir 			else
690*cdf0e10cSrcweir 			{
691*cdf0e10cSrcweir 				pPath = PTR_CAST(SdrPathObj, pConvObj);
692*cdf0e10cSrcweir 
693*cdf0e10cSrcweir 				if(pPath)
694*cdf0e10cSrcweir 				{
695*cdf0e10cSrcweir 					aRetval = pPath->GetPathPoly();
696*cdf0e10cSrcweir 				}
697*cdf0e10cSrcweir 			}
698*cdf0e10cSrcweir 
699*cdf0e10cSrcweir 			SdrObject::Free( pConvObj );
700*cdf0e10cSrcweir 		}
701*cdf0e10cSrcweir 	}
702*cdf0e10cSrcweir 
703*cdf0e10cSrcweir 	return aRetval;
704*cdf0e10cSrcweir }
705*cdf0e10cSrcweir 
706*cdf0e10cSrcweir basegfx::B2DPolyPolygon SdrEditView::ImpGetPolyPolygon(const SdrObject* pObj, sal_Bool bCombine) const
707*cdf0e10cSrcweir {
708*cdf0e10cSrcweir 	SdrObjList* pOL = pObj->GetSubList();
709*cdf0e10cSrcweir 
710*cdf0e10cSrcweir 	if(pOL && !pObj->Is3DObj())
711*cdf0e10cSrcweir 	{
712*cdf0e10cSrcweir 		basegfx::B2DPolyPolygon aRetval;
713*cdf0e10cSrcweir 		SdrObjListIter aIter(*pOL, IM_DEEPNOGROUPS);
714*cdf0e10cSrcweir 
715*cdf0e10cSrcweir 		while(aIter.IsMore())
716*cdf0e10cSrcweir 		{
717*cdf0e10cSrcweir 			SdrObject* pObj1 = aIter.Next();
718*cdf0e10cSrcweir 			aRetval.append(ImpGetPolyPolygon1(pObj1, bCombine));
719*cdf0e10cSrcweir 		}
720*cdf0e10cSrcweir 
721*cdf0e10cSrcweir 		return aRetval;
722*cdf0e10cSrcweir 	}
723*cdf0e10cSrcweir 	else
724*cdf0e10cSrcweir 	{
725*cdf0e10cSrcweir 		return ImpGetPolyPolygon1(pObj, bCombine);
726*cdf0e10cSrcweir 	}
727*cdf0e10cSrcweir }
728*cdf0e10cSrcweir 
729*cdf0e10cSrcweir basegfx::B2DPolygon SdrEditView::ImpCombineToSinglePolygon(const basegfx::B2DPolyPolygon& rPolyPolygon) const
730*cdf0e10cSrcweir {
731*cdf0e10cSrcweir 	const sal_uInt32 nPolyCount(rPolyPolygon.count());
732*cdf0e10cSrcweir 
733*cdf0e10cSrcweir 	if(0L == nPolyCount)
734*cdf0e10cSrcweir 	{
735*cdf0e10cSrcweir 		return basegfx::B2DPolygon();
736*cdf0e10cSrcweir 	}
737*cdf0e10cSrcweir 	else if(1L == nPolyCount)
738*cdf0e10cSrcweir 	{
739*cdf0e10cSrcweir 		return rPolyPolygon.getB2DPolygon(0L);
740*cdf0e10cSrcweir 	}
741*cdf0e10cSrcweir 	else
742*cdf0e10cSrcweir 	{
743*cdf0e10cSrcweir 		basegfx::B2DPolygon aRetval(rPolyPolygon.getB2DPolygon(0L));
744*cdf0e10cSrcweir 
745*cdf0e10cSrcweir 		for(sal_uInt32 a(1L); a < nPolyCount; a++)
746*cdf0e10cSrcweir 		{
747*cdf0e10cSrcweir 			basegfx::B2DPolygon aCandidate(rPolyPolygon.getB2DPolygon(a));
748*cdf0e10cSrcweir 
749*cdf0e10cSrcweir 			if(aRetval.count())
750*cdf0e10cSrcweir 			{
751*cdf0e10cSrcweir 				if(aCandidate.count())
752*cdf0e10cSrcweir 				{
753*cdf0e10cSrcweir 					const basegfx::B2DPoint aCA(aCandidate.getB2DPoint(0L));
754*cdf0e10cSrcweir 					const basegfx::B2DPoint aCB(aCandidate.getB2DPoint(aCandidate.count() - 1L));
755*cdf0e10cSrcweir 					const basegfx::B2DPoint aRA(aRetval.getB2DPoint(0L));
756*cdf0e10cSrcweir 					const basegfx::B2DPoint aRB(aRetval.getB2DPoint(aRetval.count() - 1L));
757*cdf0e10cSrcweir 
758*cdf0e10cSrcweir 					const double fRACA(basegfx::B2DVector(aCA - aRA).getLength());
759*cdf0e10cSrcweir 					const double fRACB(basegfx::B2DVector(aCB - aRA).getLength());
760*cdf0e10cSrcweir 					const double fRBCA(basegfx::B2DVector(aCA - aRB).getLength());
761*cdf0e10cSrcweir 					const double fRBCB(basegfx::B2DVector(aCB - aRB).getLength());
762*cdf0e10cSrcweir 
763*cdf0e10cSrcweir 					const double fSmallestRA(fRACA < fRACB ? fRACA : fRACB);
764*cdf0e10cSrcweir 					const double fSmallestRB(fRBCA < fRBCB ? fRBCA : fRBCB);
765*cdf0e10cSrcweir 
766*cdf0e10cSrcweir 					if(fSmallestRA < fSmallestRB)
767*cdf0e10cSrcweir 					{
768*cdf0e10cSrcweir 						// flip result
769*cdf0e10cSrcweir 						aRetval.flip();
770*cdf0e10cSrcweir 					}
771*cdf0e10cSrcweir 
772*cdf0e10cSrcweir 					const double fSmallestCA(fRACA < fRBCA ? fRACA : fRBCA);
773*cdf0e10cSrcweir 					const double fSmallestCB(fRACB < fRBCB ? fRACB : fRBCB);
774*cdf0e10cSrcweir 
775*cdf0e10cSrcweir 					if(fSmallestCB < fSmallestCA)
776*cdf0e10cSrcweir 					{
777*cdf0e10cSrcweir 						// flip candidate
778*cdf0e10cSrcweir 						aCandidate.flip();
779*cdf0e10cSrcweir 					}
780*cdf0e10cSrcweir 
781*cdf0e10cSrcweir 					// append candidate to retval
782*cdf0e10cSrcweir 					aRetval.append(aCandidate);
783*cdf0e10cSrcweir 				}
784*cdf0e10cSrcweir 			}
785*cdf0e10cSrcweir 			else
786*cdf0e10cSrcweir 			{
787*cdf0e10cSrcweir 				aRetval = aCandidate;
788*cdf0e10cSrcweir 			}
789*cdf0e10cSrcweir 		}
790*cdf0e10cSrcweir 
791*cdf0e10cSrcweir 		return aRetval;
792*cdf0e10cSrcweir 	}
793*cdf0e10cSrcweir }
794*cdf0e10cSrcweir 
795*cdf0e10cSrcweir // for distribution dialog function
796*cdf0e10cSrcweir struct ImpDistributeEntry
797*cdf0e10cSrcweir {
798*cdf0e10cSrcweir 	SdrObject*					mpObj;
799*cdf0e10cSrcweir 	sal_Int32						mnPos;
800*cdf0e10cSrcweir 	sal_Int32						mnLength;
801*cdf0e10cSrcweir };
802*cdf0e10cSrcweir 
803*cdf0e10cSrcweir DECLARE_LIST(ImpDistributeEntryList, ImpDistributeEntry*)
804*cdf0e10cSrcweir 
805*cdf0e10cSrcweir void SdrEditView::DistributeMarkedObjects()
806*cdf0e10cSrcweir {
807*cdf0e10cSrcweir 	sal_uInt32 nMark(GetMarkedObjectCount());
808*cdf0e10cSrcweir 
809*cdf0e10cSrcweir 	if(nMark > 2)
810*cdf0e10cSrcweir 	{
811*cdf0e10cSrcweir 		SfxItemSet aNewAttr(pMod->GetItemPool());
812*cdf0e10cSrcweir 		//CHINA001 SvxDistributeDialog* pDlg = new SvxDistributeDialog(NULL, aNewAttr);
813*cdf0e10cSrcweir 		SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
814*cdf0e10cSrcweir 		if(pFact)
815*cdf0e10cSrcweir 		{
816*cdf0e10cSrcweir 			AbstractSvxDistributeDialog *pDlg = pFact->CreateSvxDistributeDialog(NULL, aNewAttr);
817*cdf0e10cSrcweir 			DBG_ASSERT(pDlg, "Dialogdiet fail!");//CHINA001
818*cdf0e10cSrcweir 
819*cdf0e10cSrcweir 			sal_uInt16 nResult = pDlg->Execute();
820*cdf0e10cSrcweir 
821*cdf0e10cSrcweir 			if(nResult == RET_OK)
822*cdf0e10cSrcweir 			{
823*cdf0e10cSrcweir 				SvxDistributeHorizontal eHor = pDlg->GetDistributeHor();
824*cdf0e10cSrcweir 				SvxDistributeVertical eVer = pDlg->GetDistributeVer();
825*cdf0e10cSrcweir 				ImpDistributeEntryList aEntryList;
826*cdf0e10cSrcweir 				sal_uInt32 a, nInsPos, nFullLength;
827*cdf0e10cSrcweir 
828*cdf0e10cSrcweir 				const bool bUndo = IsUndoEnabled();
829*cdf0e10cSrcweir 				if( bUndo )
830*cdf0e10cSrcweir 					BegUndo();
831*cdf0e10cSrcweir 
832*cdf0e10cSrcweir 				if(eHor != SvxDistributeHorizontalNone)
833*cdf0e10cSrcweir 				{
834*cdf0e10cSrcweir 					// build sorted entry list
835*cdf0e10cSrcweir 					nFullLength = 0L;
836*cdf0e10cSrcweir 
837*cdf0e10cSrcweir 					for(a=0;a<nMark;a++)
838*cdf0e10cSrcweir 					{
839*cdf0e10cSrcweir 						SdrMark* pMark = GetSdrMarkByIndex(a);
840*cdf0e10cSrcweir 						ImpDistributeEntry* pNew = new ImpDistributeEntry;
841*cdf0e10cSrcweir 
842*cdf0e10cSrcweir 						pNew->mpObj = pMark->GetMarkedSdrObj();
843*cdf0e10cSrcweir 						nInsPos = 0;
844*cdf0e10cSrcweir 
845*cdf0e10cSrcweir 						switch(eHor)
846*cdf0e10cSrcweir 						{
847*cdf0e10cSrcweir 							case SvxDistributeHorizontalLeft:
848*cdf0e10cSrcweir 							{
849*cdf0e10cSrcweir 								pNew->mnPos = pNew->mpObj->GetSnapRect().Left();
850*cdf0e10cSrcweir 								break;
851*cdf0e10cSrcweir 							}
852*cdf0e10cSrcweir 							case SvxDistributeHorizontalCenter:
853*cdf0e10cSrcweir 							{
854*cdf0e10cSrcweir 								pNew->mnPos = (pNew->mpObj->GetSnapRect().Right() + pNew->mpObj->GetSnapRect().Left()) / 2;
855*cdf0e10cSrcweir 								break;
856*cdf0e10cSrcweir 							}
857*cdf0e10cSrcweir 							case SvxDistributeHorizontalDistance:
858*cdf0e10cSrcweir 							{
859*cdf0e10cSrcweir 								pNew->mnLength = pNew->mpObj->GetSnapRect().GetWidth() + 1;
860*cdf0e10cSrcweir 								nFullLength += pNew->mnLength;
861*cdf0e10cSrcweir 								pNew->mnPos = (pNew->mpObj->GetSnapRect().Right() + pNew->mpObj->GetSnapRect().Left()) / 2;
862*cdf0e10cSrcweir 								break;
863*cdf0e10cSrcweir 							}
864*cdf0e10cSrcweir 							case SvxDistributeHorizontalRight:
865*cdf0e10cSrcweir 							{
866*cdf0e10cSrcweir 								pNew->mnPos = pNew->mpObj->GetSnapRect().Right();
867*cdf0e10cSrcweir 								break;
868*cdf0e10cSrcweir 							}
869*cdf0e10cSrcweir 							default: break;
870*cdf0e10cSrcweir 						}
871*cdf0e10cSrcweir 
872*cdf0e10cSrcweir 						while(nInsPos < aEntryList.Count() && aEntryList.GetObject(nInsPos)->mnPos < pNew->mnPos)
873*cdf0e10cSrcweir 							nInsPos++;
874*cdf0e10cSrcweir 
875*cdf0e10cSrcweir 						aEntryList.Insert(pNew, nInsPos);
876*cdf0e10cSrcweir 					}
877*cdf0e10cSrcweir 
878*cdf0e10cSrcweir 					if(eHor == SvxDistributeHorizontalDistance)
879*cdf0e10cSrcweir 					{
880*cdf0e10cSrcweir 						// calc room in-between
881*cdf0e10cSrcweir 						sal_Int32 nWidth = GetAllMarkedBoundRect().GetWidth() + 1;
882*cdf0e10cSrcweir 						double fStepWidth = ((double)nWidth - (double)nFullLength) / (double)(aEntryList.Count() - 1);
883*cdf0e10cSrcweir 						double fStepStart = (double)aEntryList.GetObject(0)->mnPos;
884*cdf0e10cSrcweir 						fStepStart += fStepWidth + (double)((aEntryList.GetObject(0)->mnLength + aEntryList.GetObject(1)->mnLength) / 2);
885*cdf0e10cSrcweir 
886*cdf0e10cSrcweir 						// move entries 1..n-1
887*cdf0e10cSrcweir 						for(a=1;a<aEntryList.Count()-1;a++)
888*cdf0e10cSrcweir 						{
889*cdf0e10cSrcweir 							ImpDistributeEntry* pCurr = aEntryList.GetObject(a);
890*cdf0e10cSrcweir 							ImpDistributeEntry* pNext = aEntryList.GetObject(a+1);
891*cdf0e10cSrcweir 							sal_Int32 nDelta = (sal_Int32)(fStepStart + 0.5) - pCurr->mnPos;
892*cdf0e10cSrcweir 							if( bUndo )
893*cdf0e10cSrcweir 								AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pCurr->mpObj));
894*cdf0e10cSrcweir 							pCurr->mpObj->Move(Size(nDelta, 0));
895*cdf0e10cSrcweir 							fStepStart += fStepWidth + (double)((pCurr->mnLength + pNext->mnLength) / 2);
896*cdf0e10cSrcweir 						}
897*cdf0e10cSrcweir 					}
898*cdf0e10cSrcweir 					else
899*cdf0e10cSrcweir 					{
900*cdf0e10cSrcweir 						// calc distances
901*cdf0e10cSrcweir 						sal_Int32 nWidth = aEntryList.GetObject(aEntryList.Count() - 1)->mnPos - aEntryList.GetObject(0)->mnPos;
902*cdf0e10cSrcweir 						double fStepWidth = (double)nWidth / (double)(aEntryList.Count() - 1);
903*cdf0e10cSrcweir 						double fStepStart = (double)aEntryList.GetObject(0)->mnPos;
904*cdf0e10cSrcweir 						fStepStart += fStepWidth;
905*cdf0e10cSrcweir 
906*cdf0e10cSrcweir 						// move entries 1..n-1
907*cdf0e10cSrcweir 						for(a=1;a<aEntryList.Count()-1;a++)
908*cdf0e10cSrcweir 						{
909*cdf0e10cSrcweir 							ImpDistributeEntry* pCurr = aEntryList.GetObject(a);
910*cdf0e10cSrcweir 							sal_Int32 nDelta = (sal_Int32)(fStepStart + 0.5) - pCurr->mnPos;
911*cdf0e10cSrcweir 							if( bUndo )
912*cdf0e10cSrcweir 								AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pCurr->mpObj));
913*cdf0e10cSrcweir 							pCurr->mpObj->Move(Size(nDelta, 0));
914*cdf0e10cSrcweir 							fStepStart += fStepWidth;
915*cdf0e10cSrcweir 						}
916*cdf0e10cSrcweir 					}
917*cdf0e10cSrcweir 
918*cdf0e10cSrcweir 					// clear list
919*cdf0e10cSrcweir 					while(aEntryList.Count())
920*cdf0e10cSrcweir 						delete aEntryList.Remove((sal_uIntPtr)0L);
921*cdf0e10cSrcweir 				}
922*cdf0e10cSrcweir 
923*cdf0e10cSrcweir 				if(eVer != SvxDistributeVerticalNone)
924*cdf0e10cSrcweir 				{
925*cdf0e10cSrcweir 					// build sorted entry list
926*cdf0e10cSrcweir 					nFullLength = 0L;
927*cdf0e10cSrcweir 
928*cdf0e10cSrcweir 					for(a=0;a<nMark;a++)
929*cdf0e10cSrcweir 					{
930*cdf0e10cSrcweir 						SdrMark* pMark = GetSdrMarkByIndex(a);
931*cdf0e10cSrcweir 						ImpDistributeEntry* pNew = new ImpDistributeEntry;
932*cdf0e10cSrcweir 
933*cdf0e10cSrcweir 						pNew->mpObj = pMark->GetMarkedSdrObj();
934*cdf0e10cSrcweir 						nInsPos = 0;
935*cdf0e10cSrcweir 
936*cdf0e10cSrcweir 						switch(eVer)
937*cdf0e10cSrcweir 						{
938*cdf0e10cSrcweir 							case SvxDistributeVerticalTop:
939*cdf0e10cSrcweir 							{
940*cdf0e10cSrcweir 								pNew->mnPos = pNew->mpObj->GetSnapRect().Top();
941*cdf0e10cSrcweir 								break;
942*cdf0e10cSrcweir 							}
943*cdf0e10cSrcweir 							case SvxDistributeVerticalCenter:
944*cdf0e10cSrcweir 							{
945*cdf0e10cSrcweir 								pNew->mnPos = (pNew->mpObj->GetSnapRect().Bottom() + pNew->mpObj->GetSnapRect().Top()) / 2;
946*cdf0e10cSrcweir 								break;
947*cdf0e10cSrcweir 							}
948*cdf0e10cSrcweir 							case SvxDistributeVerticalDistance:
949*cdf0e10cSrcweir 							{
950*cdf0e10cSrcweir 								pNew->mnLength = pNew->mpObj->GetSnapRect().GetHeight() + 1;
951*cdf0e10cSrcweir 								nFullLength += pNew->mnLength;
952*cdf0e10cSrcweir 								pNew->mnPos = (pNew->mpObj->GetSnapRect().Bottom() + pNew->mpObj->GetSnapRect().Top()) / 2;
953*cdf0e10cSrcweir 								break;
954*cdf0e10cSrcweir 							}
955*cdf0e10cSrcweir 							case SvxDistributeVerticalBottom:
956*cdf0e10cSrcweir 							{
957*cdf0e10cSrcweir 								pNew->mnPos = pNew->mpObj->GetSnapRect().Bottom();
958*cdf0e10cSrcweir 								break;
959*cdf0e10cSrcweir 							}
960*cdf0e10cSrcweir 							default: break;
961*cdf0e10cSrcweir 						}
962*cdf0e10cSrcweir 
963*cdf0e10cSrcweir 						while(nInsPos < aEntryList.Count() && aEntryList.GetObject(nInsPos)->mnPos < pNew->mnPos)
964*cdf0e10cSrcweir 							nInsPos++;
965*cdf0e10cSrcweir 
966*cdf0e10cSrcweir 						aEntryList.Insert(pNew, nInsPos);
967*cdf0e10cSrcweir 					}
968*cdf0e10cSrcweir 
969*cdf0e10cSrcweir 					if(eVer == SvxDistributeVerticalDistance)
970*cdf0e10cSrcweir 					{
971*cdf0e10cSrcweir 						// calc room in-between
972*cdf0e10cSrcweir 						sal_Int32 nHeight = GetAllMarkedBoundRect().GetHeight() + 1;
973*cdf0e10cSrcweir 						double fStepWidth = ((double)nHeight - (double)nFullLength) / (double)(aEntryList.Count() - 1);
974*cdf0e10cSrcweir 						double fStepStart = (double)aEntryList.GetObject(0)->mnPos;
975*cdf0e10cSrcweir 						fStepStart += fStepWidth + (double)((aEntryList.GetObject(0)->mnLength + aEntryList.GetObject(1)->mnLength) / 2);
976*cdf0e10cSrcweir 
977*cdf0e10cSrcweir 						// move entries 1..n-1
978*cdf0e10cSrcweir 						for(a=1;a<aEntryList.Count()-1;a++)
979*cdf0e10cSrcweir 						{
980*cdf0e10cSrcweir 							ImpDistributeEntry* pCurr = aEntryList.GetObject(a);
981*cdf0e10cSrcweir 							ImpDistributeEntry* pNext = aEntryList.GetObject(a+1);
982*cdf0e10cSrcweir 							sal_Int32 nDelta = (sal_Int32)(fStepStart + 0.5) - pCurr->mnPos;
983*cdf0e10cSrcweir 							if( bUndo )
984*cdf0e10cSrcweir 								AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pCurr->mpObj));
985*cdf0e10cSrcweir 							pCurr->mpObj->Move(Size(0, nDelta));
986*cdf0e10cSrcweir 							fStepStart += fStepWidth + (double)((pCurr->mnLength + pNext->mnLength) / 2);
987*cdf0e10cSrcweir 						}
988*cdf0e10cSrcweir 					}
989*cdf0e10cSrcweir 					else
990*cdf0e10cSrcweir 					{
991*cdf0e10cSrcweir 						// calc distances
992*cdf0e10cSrcweir 						sal_Int32 nHeight = aEntryList.GetObject(aEntryList.Count() - 1)->mnPos - aEntryList.GetObject(0)->mnPos;
993*cdf0e10cSrcweir 						double fStepWidth = (double)nHeight / (double)(aEntryList.Count() - 1);
994*cdf0e10cSrcweir 						double fStepStart = (double)aEntryList.GetObject(0)->mnPos;
995*cdf0e10cSrcweir 						fStepStart += fStepWidth;
996*cdf0e10cSrcweir 
997*cdf0e10cSrcweir 						// move entries 1..n-1
998*cdf0e10cSrcweir 						for(a=1;a<aEntryList.Count()-1;a++)
999*cdf0e10cSrcweir 						{
1000*cdf0e10cSrcweir 							ImpDistributeEntry* pCurr = aEntryList.GetObject(a);
1001*cdf0e10cSrcweir 							sal_Int32 nDelta = (sal_Int32)(fStepStart + 0.5) - pCurr->mnPos;
1002*cdf0e10cSrcweir 							if( bUndo )
1003*cdf0e10cSrcweir 								AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pCurr->mpObj));
1004*cdf0e10cSrcweir 							pCurr->mpObj->Move(Size(0, nDelta));
1005*cdf0e10cSrcweir 							fStepStart += fStepWidth;
1006*cdf0e10cSrcweir 						}
1007*cdf0e10cSrcweir 					}
1008*cdf0e10cSrcweir 
1009*cdf0e10cSrcweir 					// clear list
1010*cdf0e10cSrcweir 					while(aEntryList.Count())
1011*cdf0e10cSrcweir 						delete aEntryList.Remove((sal_uIntPtr)0L);
1012*cdf0e10cSrcweir 				}
1013*cdf0e10cSrcweir 
1014*cdf0e10cSrcweir 				// UNDO-Comment and end of UNDO
1015*cdf0e10cSrcweir 				SetUndoComment(ImpGetResStr(STR_DistributeMarkedObjects));
1016*cdf0e10cSrcweir 
1017*cdf0e10cSrcweir 				if( bUndo )
1018*cdf0e10cSrcweir 					EndUndo();
1019*cdf0e10cSrcweir 			}
1020*cdf0e10cSrcweir 
1021*cdf0e10cSrcweir 			delete(pDlg);
1022*cdf0e10cSrcweir 		}
1023*cdf0e10cSrcweir 	}
1024*cdf0e10cSrcweir }
1025*cdf0e10cSrcweir 
1026*cdf0e10cSrcweir void SdrEditView::MergeMarkedObjects(SdrMergeMode eMode)
1027*cdf0e10cSrcweir {
1028*cdf0e10cSrcweir 	// #i73441# check content
1029*cdf0e10cSrcweir 	if(AreObjectsMarked())
1030*cdf0e10cSrcweir 	{
1031*cdf0e10cSrcweir 		SdrMarkList aRemove;
1032*cdf0e10cSrcweir 		SortMarkedObjects();
1033*cdf0e10cSrcweir 
1034*cdf0e10cSrcweir 		const bool bUndo = IsUndoEnabled();
1035*cdf0e10cSrcweir 
1036*cdf0e10cSrcweir 		if( bUndo )
1037*cdf0e10cSrcweir 			BegUndo();
1038*cdf0e10cSrcweir 
1039*cdf0e10cSrcweir 		sal_uInt32 nInsPos=0xFFFFFFFF;
1040*cdf0e10cSrcweir 		const SdrObject* pAttrObj = NULL;
1041*cdf0e10cSrcweir 		basegfx::B2DPolyPolygon aMergePolyPolygonA;
1042*cdf0e10cSrcweir 		basegfx::B2DPolyPolygon aMergePolyPolygonB;
1043*cdf0e10cSrcweir 
1044*cdf0e10cSrcweir 		SdrObjList* pInsOL = NULL;
1045*cdf0e10cSrcweir 		SdrPageView* pInsPV = NULL;
1046*cdf0e10cSrcweir 		sal_Bool bFirstObjectComplete(sal_False);
1047*cdf0e10cSrcweir 
1048*cdf0e10cSrcweir 		// make sure selected objects are contour objects
1049*cdf0e10cSrcweir 		// since now basegfx::tools::adaptiveSubdivide() is used, it is no longer
1050*cdf0e10cSrcweir 		// necessary to use ConvertMarkedToPolyObj which will subdivide curves using the old
1051*cdf0e10cSrcweir 		// mechanisms. In a next step the polygon clipper will even be able to clip curves...
1052*cdf0e10cSrcweir 		// ConvertMarkedToPolyObj(sal_True);
1053*cdf0e10cSrcweir 		ConvertMarkedToPathObj(sal_True);
1054*cdf0e10cSrcweir 		OSL_ENSURE(AreObjectsMarked(), "no more objects selected after preparations (!)");
1055*cdf0e10cSrcweir 
1056*cdf0e10cSrcweir 		for(sal_uInt32 a=0;a<GetMarkedObjectCount();a++)
1057*cdf0e10cSrcweir 		{
1058*cdf0e10cSrcweir 			SdrMark* pM = GetSdrMarkByIndex(a);
1059*cdf0e10cSrcweir 			SdrObject* pObj = pM->GetMarkedSdrObj();
1060*cdf0e10cSrcweir 
1061*cdf0e10cSrcweir 			if(ImpCanConvertForCombine(pObj))
1062*cdf0e10cSrcweir 			{
1063*cdf0e10cSrcweir 				if(!pAttrObj)
1064*cdf0e10cSrcweir 					pAttrObj = pObj;
1065*cdf0e10cSrcweir 
1066*cdf0e10cSrcweir 				nInsPos = pObj->GetOrdNum() + 1;
1067*cdf0e10cSrcweir 				pInsPV = pM->GetPageView();
1068*cdf0e10cSrcweir 				pInsOL = pObj->GetObjList();
1069*cdf0e10cSrcweir 
1070*cdf0e10cSrcweir 				// #i76891# use single iter from SJ here whcih works on SdrObjects and takes
1071*cdf0e10cSrcweir 				// groups into account by itself
1072*cdf0e10cSrcweir 				SdrObjListIter aIter(*pObj, IM_DEEPWITHGROUPS);
1073*cdf0e10cSrcweir 
1074*cdf0e10cSrcweir 				while(aIter.IsMore())
1075*cdf0e10cSrcweir 				{
1076*cdf0e10cSrcweir 					SdrObject* pCandidate = aIter.Next();
1077*cdf0e10cSrcweir 					SdrPathObj* pPathObj = PTR_CAST(SdrPathObj, pCandidate);
1078*cdf0e10cSrcweir 					if(pPathObj)
1079*cdf0e10cSrcweir 					{
1080*cdf0e10cSrcweir 						basegfx::B2DPolyPolygon aTmpPoly(pPathObj->GetPathPoly());
1081*cdf0e10cSrcweir 
1082*cdf0e10cSrcweir 						// #i76891# unfortunately ConvertMarkedToPathObj has converted all
1083*cdf0e10cSrcweir 						// involved polygon data to curve segments, even if not necessary.
1084*cdf0e10cSrcweir 						// It is better to try to reduce to more simple polygons.
1085*cdf0e10cSrcweir 						aTmpPoly = basegfx::tools::simplifyCurveSegments(aTmpPoly);
1086*cdf0e10cSrcweir 
1087*cdf0e10cSrcweir 						// for each part polygon as preparation, remove self-intersections
1088*cdf0e10cSrcweir 						// correct orientations and get rid of evtl. neutral polygons.
1089*cdf0e10cSrcweir 	                    aTmpPoly = basegfx::tools::prepareForPolygonOperation(aTmpPoly);
1090*cdf0e10cSrcweir 
1091*cdf0e10cSrcweir 						if(!bFirstObjectComplete)
1092*cdf0e10cSrcweir 						{
1093*cdf0e10cSrcweir                             // #i111987# Also need to collect ORed source shape when more than
1094*cdf0e10cSrcweir                             // a single polygon is involved
1095*cdf0e10cSrcweir                             if(aMergePolyPolygonA.count())
1096*cdf0e10cSrcweir                             {
1097*cdf0e10cSrcweir                                 aMergePolyPolygonA = basegfx::tools::solvePolygonOperationOr(aMergePolyPolygonA, aTmpPoly);
1098*cdf0e10cSrcweir                             }
1099*cdf0e10cSrcweir                             else
1100*cdf0e10cSrcweir                             {
1101*cdf0e10cSrcweir     							aMergePolyPolygonA = aTmpPoly;
1102*cdf0e10cSrcweir                             }
1103*cdf0e10cSrcweir 						}
1104*cdf0e10cSrcweir 						else
1105*cdf0e10cSrcweir 						{
1106*cdf0e10cSrcweir                             if(aMergePolyPolygonB.count())
1107*cdf0e10cSrcweir                             {
1108*cdf0e10cSrcweir                                 // to topologically correctly collect the 2nd polygon
1109*cdf0e10cSrcweir                                 // group it is necessary to OR the parts (each is seen as
1110*cdf0e10cSrcweir                                 // XOR-FillRule polygon and they are drawn over each-other)
1111*cdf0e10cSrcweir                                 aMergePolyPolygonB = basegfx::tools::solvePolygonOperationOr(aMergePolyPolygonB, aTmpPoly);
1112*cdf0e10cSrcweir                             }
1113*cdf0e10cSrcweir                             else
1114*cdf0e10cSrcweir                             {
1115*cdf0e10cSrcweir     							aMergePolyPolygonB = aTmpPoly;
1116*cdf0e10cSrcweir                             }
1117*cdf0e10cSrcweir 						}
1118*cdf0e10cSrcweir 					}
1119*cdf0e10cSrcweir 				}
1120*cdf0e10cSrcweir 
1121*cdf0e10cSrcweir 				// was there something added to the first poly?
1122*cdf0e10cSrcweir 				if(!bFirstObjectComplete && aMergePolyPolygonA.count())
1123*cdf0e10cSrcweir 				{
1124*cdf0e10cSrcweir 					bFirstObjectComplete = sal_True;
1125*cdf0e10cSrcweir 				}
1126*cdf0e10cSrcweir 
1127*cdf0e10cSrcweir 				// move object to temporary delete list
1128*cdf0e10cSrcweir 				aRemove.InsertEntry(SdrMark(pObj, pM->GetPageView()));
1129*cdf0e10cSrcweir 			}
1130*cdf0e10cSrcweir 		}
1131*cdf0e10cSrcweir 
1132*cdf0e10cSrcweir 		switch(eMode)
1133*cdf0e10cSrcweir 		{
1134*cdf0e10cSrcweir 			case SDR_MERGE_MERGE:
1135*cdf0e10cSrcweir 			{
1136*cdf0e10cSrcweir 				// merge all contained parts (OR)
1137*cdf0e10cSrcweir                 static bool bTestXOR(false);
1138*cdf0e10cSrcweir                 if(bTestXOR)
1139*cdf0e10cSrcweir                 {
1140*cdf0e10cSrcweir                     aMergePolyPolygonA = basegfx::tools::solvePolygonOperationXor(aMergePolyPolygonA, aMergePolyPolygonB);
1141*cdf0e10cSrcweir                 }
1142*cdf0e10cSrcweir                 else
1143*cdf0e10cSrcweir                 {
1144*cdf0e10cSrcweir                     aMergePolyPolygonA = basegfx::tools::solvePolygonOperationOr(aMergePolyPolygonA, aMergePolyPolygonB);
1145*cdf0e10cSrcweir                 }
1146*cdf0e10cSrcweir 				break;
1147*cdf0e10cSrcweir 			}
1148*cdf0e10cSrcweir 			case SDR_MERGE_SUBSTRACT:
1149*cdf0e10cSrcweir 			{
1150*cdf0e10cSrcweir 				// Substract B from A
1151*cdf0e10cSrcweir                 aMergePolyPolygonA = basegfx::tools::solvePolygonOperationDiff(aMergePolyPolygonA, aMergePolyPolygonB);
1152*cdf0e10cSrcweir 				break;
1153*cdf0e10cSrcweir 			}
1154*cdf0e10cSrcweir 			case SDR_MERGE_INTERSECT:
1155*cdf0e10cSrcweir 			{
1156*cdf0e10cSrcweir 				// AND B and A
1157*cdf0e10cSrcweir                 aMergePolyPolygonA = basegfx::tools::solvePolygonOperationAnd(aMergePolyPolygonA, aMergePolyPolygonB);
1158*cdf0e10cSrcweir 				break;
1159*cdf0e10cSrcweir 			}
1160*cdf0e10cSrcweir 		}
1161*cdf0e10cSrcweir 
1162*cdf0e10cSrcweir 		// #i73441# check insert list before taking actions
1163*cdf0e10cSrcweir 		if(pInsOL)
1164*cdf0e10cSrcweir 		{
1165*cdf0e10cSrcweir 			SdrPathObj* pPath = new SdrPathObj(OBJ_PATHFILL, aMergePolyPolygonA);
1166*cdf0e10cSrcweir 			ImpCopyAttributes(pAttrObj, pPath);
1167*cdf0e10cSrcweir 			SdrInsertReason aReason(SDRREASON_VIEWCALL, pAttrObj);
1168*cdf0e10cSrcweir 			pInsOL->InsertObject(pPath, nInsPos, &aReason);
1169*cdf0e10cSrcweir 			if( bUndo )
1170*cdf0e10cSrcweir 				AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pPath));
1171*cdf0e10cSrcweir 			MarkObj(pPath, pInsPV, sal_False, sal_True);
1172*cdf0e10cSrcweir 		}
1173*cdf0e10cSrcweir 
1174*cdf0e10cSrcweir 		aRemove.ForceSort();
1175*cdf0e10cSrcweir 		switch(eMode)
1176*cdf0e10cSrcweir 		{
1177*cdf0e10cSrcweir 			case SDR_MERGE_MERGE:
1178*cdf0e10cSrcweir 			{
1179*cdf0e10cSrcweir 				SetUndoComment(
1180*cdf0e10cSrcweir 					ImpGetResStr(STR_EditMergeMergePoly),
1181*cdf0e10cSrcweir 					aRemove.GetMarkDescription());
1182*cdf0e10cSrcweir 				break;
1183*cdf0e10cSrcweir 			}
1184*cdf0e10cSrcweir 			case SDR_MERGE_SUBSTRACT:
1185*cdf0e10cSrcweir 			{
1186*cdf0e10cSrcweir 				SetUndoComment(
1187*cdf0e10cSrcweir 					ImpGetResStr(STR_EditMergeSubstractPoly),
1188*cdf0e10cSrcweir 					aRemove.GetMarkDescription());
1189*cdf0e10cSrcweir 				break;
1190*cdf0e10cSrcweir 			}
1191*cdf0e10cSrcweir 			case SDR_MERGE_INTERSECT:
1192*cdf0e10cSrcweir 			{
1193*cdf0e10cSrcweir 				SetUndoComment(
1194*cdf0e10cSrcweir 					ImpGetResStr(STR_EditMergeIntersectPoly),
1195*cdf0e10cSrcweir 					aRemove.GetMarkDescription());
1196*cdf0e10cSrcweir 				break;
1197*cdf0e10cSrcweir 			}
1198*cdf0e10cSrcweir 		}
1199*cdf0e10cSrcweir 		DeleteMarkedList(aRemove);
1200*cdf0e10cSrcweir 
1201*cdf0e10cSrcweir 		if( bUndo )
1202*cdf0e10cSrcweir 			EndUndo();
1203*cdf0e10cSrcweir 	}
1204*cdf0e10cSrcweir }
1205*cdf0e10cSrcweir 
1206*cdf0e10cSrcweir void SdrEditView::CombineMarkedObjects(sal_Bool bNoPolyPoly)
1207*cdf0e10cSrcweir {
1208*cdf0e10cSrcweir 	// #105899# Start of Combine-Undo put to front, else ConvertMarkedToPolyObj would
1209*cdf0e10cSrcweir 	// create a 2nd Undo-action and Undo-Comment.
1210*cdf0e10cSrcweir 
1211*cdf0e10cSrcweir 	bool bUndo = IsUndoEnabled();
1212*cdf0e10cSrcweir 
1213*cdf0e10cSrcweir 	// Undo-String will be set later
1214*cdf0e10cSrcweir 	if( bUndo )
1215*cdf0e10cSrcweir 		BegUndo(String(), String(), bNoPolyPoly ? SDRREPFUNC_OBJ_COMBINE_ONEPOLY : SDRREPFUNC_OBJ_COMBINE_POLYPOLY);
1216*cdf0e10cSrcweir 
1217*cdf0e10cSrcweir 	// #105899# First, guarantee that all objects are converted to polyobjects,
1218*cdf0e10cSrcweir 	// especially for SdrGrafObj with bitmap filling this is necessary to not
1219*cdf0e10cSrcweir 	// loose the bitmap filling.
1220*cdf0e10cSrcweir 
1221*cdf0e10cSrcweir 	// #i12392#
1222*cdf0e10cSrcweir 	// ConvertMarkedToPolyObj was too strong here, it will loose quality and
1223*cdf0e10cSrcweir 	// information when curve objects are combined. This can be replaced by
1224*cdf0e10cSrcweir 	// using ConvertMarkedToPathObj without changing the previous fix.
1225*cdf0e10cSrcweir 
1226*cdf0e10cSrcweir 	// #i21250#
1227*cdf0e10cSrcweir 	// Instead of simply passing sal_True as LineToArea, use bNoPolyPoly as info
1228*cdf0e10cSrcweir 	// if this command is a 'Combine' or a 'Connect' command. On Connect it's sal_True.
1229*cdf0e10cSrcweir 	// To not concert line segments with a set line width to polygons in that case,
1230*cdf0e10cSrcweir 	// use this info. Do not convert LineToArea on Connect commands.
1231*cdf0e10cSrcweir 	// ConvertMarkedToPathObj(!bNoPolyPoly);
1232*cdf0e10cSrcweir 
1233*cdf0e10cSrcweir 	// #114310#
1234*cdf0e10cSrcweir 	// This is used for Combine and Connect. In no case it is necessary to force
1235*cdf0e10cSrcweir 	// the content to curve, but it is also not good to force to polygons. Thus,
1236*cdf0e10cSrcweir 	// curve is the less information loosing one. Remember: This place is not
1237*cdf0e10cSrcweir 	// used for merge.
1238*cdf0e10cSrcweir 	// LineToArea is never necessary, both commands are able to take over the
1239*cdf0e10cSrcweir 	// set line style and to display it correctly. Thus, i will use a
1240*cdf0e10cSrcweir 	// ConvertMarkedToPathObj with a sal_False in any case. Only drawback is that
1241*cdf0e10cSrcweir 	// simple polygons will be changed to curves, but with no information loss.
1242*cdf0e10cSrcweir 	ConvertMarkedToPathObj(sal_False /* bLineToArea */);
1243*cdf0e10cSrcweir 
1244*cdf0e10cSrcweir 	// continue as before
1245*cdf0e10cSrcweir 	basegfx::B2DPolyPolygon aPolyPolygon;
1246*cdf0e10cSrcweir 	SdrObjList* pAktOL = 0L;
1247*cdf0e10cSrcweir 	SdrMarkList aRemoveMerker;
1248*cdf0e10cSrcweir 
1249*cdf0e10cSrcweir 	SortMarkedObjects();
1250*cdf0e10cSrcweir 	sal_uInt32 nInsPos(0xFFFFFFFF);
1251*cdf0e10cSrcweir 	SdrObjList* pInsOL = 0L;
1252*cdf0e10cSrcweir 	SdrPageView* pInsPV = 0L;
1253*cdf0e10cSrcweir 	const sal_uInt32 nAnz(GetMarkedObjectCount());
1254*cdf0e10cSrcweir 	const SdrObject* pAttrObj = 0L;
1255*cdf0e10cSrcweir 
1256*cdf0e10cSrcweir 	for(sal_uInt32 a(nAnz); a > 0L; )
1257*cdf0e10cSrcweir 	{
1258*cdf0e10cSrcweir 		a--;
1259*cdf0e10cSrcweir 		SdrMark* pM = GetSdrMarkByIndex(a);
1260*cdf0e10cSrcweir 		SdrObject* pObj = pM->GetMarkedSdrObj();
1261*cdf0e10cSrcweir 		SdrObjList* pThisOL = pObj->GetObjList();
1262*cdf0e10cSrcweir 
1263*cdf0e10cSrcweir 		if(pAktOL != pThisOL)
1264*cdf0e10cSrcweir 		{
1265*cdf0e10cSrcweir 			pAktOL = pThisOL;
1266*cdf0e10cSrcweir 		}
1267*cdf0e10cSrcweir 
1268*cdf0e10cSrcweir 		if(ImpCanConvertForCombine(pObj))
1269*cdf0e10cSrcweir 		{
1270*cdf0e10cSrcweir 			// Obj merken fuer Attribute kopieren
1271*cdf0e10cSrcweir 			pAttrObj = pObj;
1272*cdf0e10cSrcweir 
1273*cdf0e10cSrcweir 			// unfortunately ConvertMarkedToPathObj has converted all
1274*cdf0e10cSrcweir 			// involved polygon data to curve segments, even if not necessary.
1275*cdf0e10cSrcweir 			// It is better to try to reduce to more simple polygons.
1276*cdf0e10cSrcweir 			basegfx::B2DPolyPolygon aTmpPoly(basegfx::tools::simplifyCurveSegments(ImpGetPolyPolygon(pObj, sal_True)));
1277*cdf0e10cSrcweir 			aPolyPolygon.insert(0L, aTmpPoly);
1278*cdf0e10cSrcweir 
1279*cdf0e10cSrcweir 			if(!pInsOL)
1280*cdf0e10cSrcweir 			{
1281*cdf0e10cSrcweir 				nInsPos = pObj->GetOrdNum() + 1L;
1282*cdf0e10cSrcweir 				pInsPV = pM->GetPageView();
1283*cdf0e10cSrcweir 				pInsOL = pObj->GetObjList();
1284*cdf0e10cSrcweir 			}
1285*cdf0e10cSrcweir 
1286*cdf0e10cSrcweir 			aRemoveMerker.InsertEntry(SdrMark(pObj, pM->GetPageView()));
1287*cdf0e10cSrcweir 		}
1288*cdf0e10cSrcweir 	}
1289*cdf0e10cSrcweir 
1290*cdf0e10cSrcweir 	if(bNoPolyPoly)
1291*cdf0e10cSrcweir 	{
1292*cdf0e10cSrcweir 		basegfx::B2DPolygon aCombinedPolygon(ImpCombineToSinglePolygon(aPolyPolygon));
1293*cdf0e10cSrcweir 		aPolyPolygon.clear();
1294*cdf0e10cSrcweir 		aPolyPolygon.append(aCombinedPolygon);
1295*cdf0e10cSrcweir 	}
1296*cdf0e10cSrcweir 
1297*cdf0e10cSrcweir 	const sal_uInt32 nPolyCount(aPolyPolygon.count());
1298*cdf0e10cSrcweir 
1299*cdf0e10cSrcweir 	if(nPolyCount)
1300*cdf0e10cSrcweir 	{
1301*cdf0e10cSrcweir 		SdrObjKind eKind = OBJ_PATHFILL;
1302*cdf0e10cSrcweir 
1303*cdf0e10cSrcweir 		if(nPolyCount > 1L)
1304*cdf0e10cSrcweir 		{
1305*cdf0e10cSrcweir 			aPolyPolygon.setClosed(true);
1306*cdf0e10cSrcweir 		}
1307*cdf0e10cSrcweir 		else
1308*cdf0e10cSrcweir 		{
1309*cdf0e10cSrcweir 			// auf Polyline Checken
1310*cdf0e10cSrcweir 			const basegfx::B2DPolygon aPolygon(aPolyPolygon.getB2DPolygon(0L));
1311*cdf0e10cSrcweir 			const sal_uInt32 nPointCount(aPolygon.count());
1312*cdf0e10cSrcweir 
1313*cdf0e10cSrcweir 			if(nPointCount <= 2L)
1314*cdf0e10cSrcweir 			{
1315*cdf0e10cSrcweir 				eKind = OBJ_PATHLINE;
1316*cdf0e10cSrcweir 			}
1317*cdf0e10cSrcweir 			else
1318*cdf0e10cSrcweir 			{
1319*cdf0e10cSrcweir 				if(!aPolygon.isClosed())
1320*cdf0e10cSrcweir 				{
1321*cdf0e10cSrcweir 					const basegfx::B2DPoint aPointA(aPolygon.getB2DPoint(0L));
1322*cdf0e10cSrcweir 					const basegfx::B2DPoint aPointB(aPolygon.getB2DPoint(nPointCount - 1L));
1323*cdf0e10cSrcweir 					const double fDistance(basegfx::B2DVector(aPointB - aPointA).getLength());
1324*cdf0e10cSrcweir 					const double fJoinTolerance(10.0);
1325*cdf0e10cSrcweir 
1326*cdf0e10cSrcweir 					if(fDistance < fJoinTolerance)
1327*cdf0e10cSrcweir 					{
1328*cdf0e10cSrcweir 						aPolyPolygon.setClosed(true);
1329*cdf0e10cSrcweir 					}
1330*cdf0e10cSrcweir 					else
1331*cdf0e10cSrcweir 					{
1332*cdf0e10cSrcweir 						eKind = OBJ_PATHLINE;
1333*cdf0e10cSrcweir 					}
1334*cdf0e10cSrcweir 				}
1335*cdf0e10cSrcweir 			}
1336*cdf0e10cSrcweir 		}
1337*cdf0e10cSrcweir 
1338*cdf0e10cSrcweir 		SdrPathObj* pPath = new SdrPathObj(eKind,aPolyPolygon);
1339*cdf0e10cSrcweir 
1340*cdf0e10cSrcweir 		// Attribute des untersten Objekts
1341*cdf0e10cSrcweir 		ImpCopyAttributes(pAttrObj, pPath);
1342*cdf0e10cSrcweir 
1343*cdf0e10cSrcweir 		// #100408# If LineStyle of pAttrObj is XLINE_NONE force to XLINE_SOLID to make visible.
1344*cdf0e10cSrcweir 		const XLineStyle eLineStyle = ((const XLineStyleItem&)pAttrObj->GetMergedItem(XATTR_LINESTYLE)).GetValue();
1345*cdf0e10cSrcweir 		const XFillStyle eFillStyle = ((const XFillStyleItem&)pAttrObj->GetMergedItem(XATTR_FILLSTYLE)).GetValue();
1346*cdf0e10cSrcweir 
1347*cdf0e10cSrcweir 		// #110635#
1348*cdf0e10cSrcweir 		// Take fill style/closed state of pAttrObj in account when deciding to change the line style
1349*cdf0e10cSrcweir 		sal_Bool bIsClosedPathObj(pAttrObj->ISA(SdrPathObj) && ((SdrPathObj*)pAttrObj)->IsClosed());
1350*cdf0e10cSrcweir 
1351*cdf0e10cSrcweir 		if(XLINE_NONE == eLineStyle && (XFILL_NONE == eFillStyle || !bIsClosedPathObj))
1352*cdf0e10cSrcweir 		{
1353*cdf0e10cSrcweir 			pPath->SetMergedItem(XLineStyleItem(XLINE_SOLID));
1354*cdf0e10cSrcweir 		}
1355*cdf0e10cSrcweir 
1356*cdf0e10cSrcweir 		SdrInsertReason aReason(SDRREASON_VIEWCALL,pAttrObj);
1357*cdf0e10cSrcweir 		pInsOL->InsertObject(pPath,nInsPos,&aReason);
1358*cdf0e10cSrcweir 		if( bUndo )
1359*cdf0e10cSrcweir 			AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pPath));
1360*cdf0e10cSrcweir 
1361*cdf0e10cSrcweir 		// #111111#
1362*cdf0e10cSrcweir 		// Here was a severe error: Without UnmarkAllObj, the new object was marked
1363*cdf0e10cSrcweir 		// additionally to the two ones which are deleted below. As long as those are
1364*cdf0e10cSrcweir 		// in the UNDO there is no problem, but as soon as they get deleted, the
1365*cdf0e10cSrcweir 		// MarkList will contain deleted objects -> GPF.
1366*cdf0e10cSrcweir 		UnmarkAllObj(pInsPV);
1367*cdf0e10cSrcweir 		MarkObj(pPath, pInsPV, sal_False, sal_True);
1368*cdf0e10cSrcweir 	}
1369*cdf0e10cSrcweir 
1370*cdf0e10cSrcweir 	// UndoComment aus den tatsaechlich verwendeten Objekten zusammenbauen
1371*cdf0e10cSrcweir 	aRemoveMerker.ForceSort(); // wichtig fuer Remove (s.u.)
1372*cdf0e10cSrcweir 	if( bUndo )
1373*cdf0e10cSrcweir 		SetUndoComment(ImpGetResStr(bNoPolyPoly?STR_EditCombine_OnePoly:STR_EditCombine_PolyPoly),aRemoveMerker.GetMarkDescription());
1374*cdf0e10cSrcweir 
1375*cdf0e10cSrcweir 	// die tatsaechlich verwendeten Objekten aus der Liste entfernen
1376*cdf0e10cSrcweir 	DeleteMarkedList(aRemoveMerker);
1377*cdf0e10cSrcweir 	if( bUndo )
1378*cdf0e10cSrcweir 		EndUndo();
1379*cdf0e10cSrcweir }
1380*cdf0e10cSrcweir 
1381*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
1382*cdf0e10cSrcweir //
1383*cdf0e10cSrcweir //  @@@@@   @@   @@@@   @@   @@   @@@@   @@  @@  @@@@@@  @@     @@@@@
1384*cdf0e10cSrcweir //  @@  @@  @@  @@  @@  @@@ @@@  @@  @@  @@@ @@    @@    @@     @@
1385*cdf0e10cSrcweir //  @@  @@  @@  @@      @@@@@@@  @@  @@  @@@@@@    @@    @@     @@
1386*cdf0e10cSrcweir //  @@  @@  @@   @@@@   @@@@@@@  @@@@@@  @@@@@@    @@    @@     @@@@
1387*cdf0e10cSrcweir //  @@  @@  @@      @@  @@ @ @@  @@  @@  @@ @@@    @@    @@     @@
1388*cdf0e10cSrcweir //  @@  @@  @@  @@  @@  @@   @@  @@  @@  @@  @@    @@    @@     @@
1389*cdf0e10cSrcweir //  @@@@@   @@   @@@@   @@   @@  @@  @@  @@  @@    @@    @@@@@  @@@@@
1390*cdf0e10cSrcweir //
1391*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
1392*cdf0e10cSrcweir 
1393*cdf0e10cSrcweir sal_Bool SdrEditView::ImpCanDismantle(const basegfx::B2DPolyPolygon& rPpolyPolygon, sal_Bool bMakeLines) const
1394*cdf0e10cSrcweir {
1395*cdf0e10cSrcweir 	sal_Bool bCan(sal_False);
1396*cdf0e10cSrcweir 	const sal_uInt32 nPolygonCount(rPpolyPolygon.count());
1397*cdf0e10cSrcweir 
1398*cdf0e10cSrcweir 	if(nPolygonCount >= 2L)
1399*cdf0e10cSrcweir 	{
1400*cdf0e10cSrcweir 		// #i69172# dismantle makes sense with 2 or more polygons in a polyPolygon
1401*cdf0e10cSrcweir 		bCan = sal_True;
1402*cdf0e10cSrcweir 	}
1403*cdf0e10cSrcweir 	else if(bMakeLines && 1L == nPolygonCount)
1404*cdf0e10cSrcweir 	{
1405*cdf0e10cSrcweir 		// #i69172# ..or with at least 2 edges (curves or lines)
1406*cdf0e10cSrcweir 		const basegfx::B2DPolygon aPolygon(rPpolyPolygon.getB2DPolygon(0L));
1407*cdf0e10cSrcweir 		const sal_uInt32 nPointCount(aPolygon.count());
1408*cdf0e10cSrcweir 
1409*cdf0e10cSrcweir 		if(nPointCount > 2L)
1410*cdf0e10cSrcweir 		{
1411*cdf0e10cSrcweir 			bCan = sal_True;
1412*cdf0e10cSrcweir 		}
1413*cdf0e10cSrcweir 	}
1414*cdf0e10cSrcweir 
1415*cdf0e10cSrcweir 	return bCan;
1416*cdf0e10cSrcweir }
1417*cdf0e10cSrcweir 
1418*cdf0e10cSrcweir sal_Bool SdrEditView::ImpCanDismantle(const SdrObject* pObj, sal_Bool bMakeLines) const
1419*cdf0e10cSrcweir {
1420*cdf0e10cSrcweir 	sal_Bool bOtherObjs(sal_False);    // sal_True=andere Objekte ausser PathObj's vorhanden
1421*cdf0e10cSrcweir 	sal_Bool bMin1PolyPoly(sal_False); // sal_True=mind. 1 PolyPolygon mit mehr als ein Polygon vorhanden
1422*cdf0e10cSrcweir 	SdrObjList* pOL = pObj->GetSubList();
1423*cdf0e10cSrcweir 
1424*cdf0e10cSrcweir 	if(pOL)
1425*cdf0e10cSrcweir 	{
1426*cdf0e10cSrcweir 		// Aha, Gruppenobjekt. Also alle Member ansehen.
1427*cdf0e10cSrcweir 		// Alle muessen PathObjs sein !
1428*cdf0e10cSrcweir 		SdrObjListIter aIter(*pOL, IM_DEEPNOGROUPS);
1429*cdf0e10cSrcweir 
1430*cdf0e10cSrcweir 		while(aIter.IsMore() && !bOtherObjs)
1431*cdf0e10cSrcweir 		{
1432*cdf0e10cSrcweir 			const SdrObject* pObj1 = aIter.Next();
1433*cdf0e10cSrcweir 			const SdrPathObj* pPath = PTR_CAST(SdrPathObj, pObj1);
1434*cdf0e10cSrcweir 
1435*cdf0e10cSrcweir 			if(pPath)
1436*cdf0e10cSrcweir 			{
1437*cdf0e10cSrcweir 				if(ImpCanDismantle(pPath->GetPathPoly(), bMakeLines))
1438*cdf0e10cSrcweir 				{
1439*cdf0e10cSrcweir 					bMin1PolyPoly = sal_True;
1440*cdf0e10cSrcweir 				}
1441*cdf0e10cSrcweir 
1442*cdf0e10cSrcweir 				SdrObjTransformInfoRec aInfo;
1443*cdf0e10cSrcweir 				pObj1->TakeObjInfo(aInfo);
1444*cdf0e10cSrcweir 
1445*cdf0e10cSrcweir 				if(!aInfo.bCanConvToPath)
1446*cdf0e10cSrcweir 				{
1447*cdf0e10cSrcweir 					// Passiert z.B. im Falle Fontwork (Joe, 28-11-95)
1448*cdf0e10cSrcweir 					bOtherObjs = sal_True;
1449*cdf0e10cSrcweir 				}
1450*cdf0e10cSrcweir 			}
1451*cdf0e10cSrcweir 			else
1452*cdf0e10cSrcweir 			{
1453*cdf0e10cSrcweir 				bOtherObjs = sal_True;
1454*cdf0e10cSrcweir 			}
1455*cdf0e10cSrcweir 		}
1456*cdf0e10cSrcweir 	}
1457*cdf0e10cSrcweir 	else
1458*cdf0e10cSrcweir 	{
1459*cdf0e10cSrcweir 		const SdrPathObj* pPath = PTR_CAST(SdrPathObj, pObj);
1460*cdf0e10cSrcweir 		const SdrObjCustomShape* pCustomShape = PTR_CAST(SdrObjCustomShape, pObj);
1461*cdf0e10cSrcweir 
1462*cdf0e10cSrcweir 		// #i37011#
1463*cdf0e10cSrcweir 		if(pPath)
1464*cdf0e10cSrcweir 		{
1465*cdf0e10cSrcweir 			if(ImpCanDismantle(pPath->GetPathPoly(),bMakeLines))
1466*cdf0e10cSrcweir 			{
1467*cdf0e10cSrcweir 				bMin1PolyPoly = sal_True;
1468*cdf0e10cSrcweir 			}
1469*cdf0e10cSrcweir 
1470*cdf0e10cSrcweir 			SdrObjTransformInfoRec aInfo;
1471*cdf0e10cSrcweir 			pObj->TakeObjInfo(aInfo);
1472*cdf0e10cSrcweir 
1473*cdf0e10cSrcweir 			// #69711 : new condition IsLine() to be able to break simple Lines
1474*cdf0e10cSrcweir 			if(!(aInfo.bCanConvToPath || aInfo.bCanConvToPoly) && !pPath->IsLine())
1475*cdf0e10cSrcweir 			{
1476*cdf0e10cSrcweir 				// Passiert z.B. im Falle Fontwork (Joe, 28-11-95)
1477*cdf0e10cSrcweir 				bOtherObjs = sal_True;
1478*cdf0e10cSrcweir 			}
1479*cdf0e10cSrcweir 		}
1480*cdf0e10cSrcweir 		else if(pCustomShape)
1481*cdf0e10cSrcweir 		{
1482*cdf0e10cSrcweir 			if(bMakeLines)
1483*cdf0e10cSrcweir 			{
1484*cdf0e10cSrcweir 				// allow break command
1485*cdf0e10cSrcweir 				bMin1PolyPoly = sal_True;
1486*cdf0e10cSrcweir 			}
1487*cdf0e10cSrcweir 		}
1488*cdf0e10cSrcweir 		else
1489*cdf0e10cSrcweir 		{
1490*cdf0e10cSrcweir 			bOtherObjs = sal_True;
1491*cdf0e10cSrcweir 		}
1492*cdf0e10cSrcweir 	}
1493*cdf0e10cSrcweir 	return bMin1PolyPoly && !bOtherObjs;
1494*cdf0e10cSrcweir }
1495*cdf0e10cSrcweir 
1496*cdf0e10cSrcweir void SdrEditView::ImpDismantleOneObject(const SdrObject* pObj, SdrObjList& rOL, sal_uIntPtr& rPos, SdrPageView* pPV, sal_Bool bMakeLines)
1497*cdf0e10cSrcweir {
1498*cdf0e10cSrcweir 	const SdrPathObj* pSrcPath = PTR_CAST(SdrPathObj, pObj);
1499*cdf0e10cSrcweir 	const SdrObjCustomShape* pCustomShape = PTR_CAST(SdrObjCustomShape, pObj);
1500*cdf0e10cSrcweir 
1501*cdf0e10cSrcweir 	const bool bUndo = IsUndoEnabled();
1502*cdf0e10cSrcweir 
1503*cdf0e10cSrcweir 	if(pSrcPath)
1504*cdf0e10cSrcweir 	{
1505*cdf0e10cSrcweir 		// #i74631# redesigned due to XpolyPolygon removal and explicit constructors
1506*cdf0e10cSrcweir 		SdrObject* pLast = 0; // fuer die Zuweisung des OutlinerParaObject
1507*cdf0e10cSrcweir 		const basegfx::B2DPolyPolygon& rPolyPolygon(pSrcPath->GetPathPoly());
1508*cdf0e10cSrcweir 		const sal_uInt32 nPolyCount(rPolyPolygon.count());
1509*cdf0e10cSrcweir 
1510*cdf0e10cSrcweir 		for(sal_uInt32 a(0); a < nPolyCount; a++)
1511*cdf0e10cSrcweir 		{
1512*cdf0e10cSrcweir 			const basegfx::B2DPolygon& rCandidate(rPolyPolygon.getB2DPolygon(a));
1513*cdf0e10cSrcweir 			const sal_uInt32 nPointCount(rCandidate.count());
1514*cdf0e10cSrcweir 
1515*cdf0e10cSrcweir 			if(!bMakeLines || nPointCount < 2)
1516*cdf0e10cSrcweir 			{
1517*cdf0e10cSrcweir 				SdrPathObj* pPath = new SdrPathObj((SdrObjKind)pSrcPath->GetObjIdentifier(), basegfx::B2DPolyPolygon(rCandidate));
1518*cdf0e10cSrcweir 				ImpCopyAttributes(pSrcPath, pPath);
1519*cdf0e10cSrcweir 				pLast = pPath;
1520*cdf0e10cSrcweir 				SdrInsertReason aReason(SDRREASON_VIEWCALL, pSrcPath);
1521*cdf0e10cSrcweir 				rOL.InsertObject(pPath, rPos, &aReason);
1522*cdf0e10cSrcweir 				if( bUndo )
1523*cdf0e10cSrcweir 					AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pPath, sal_True));
1524*cdf0e10cSrcweir 				MarkObj(pPath, pPV, sal_False, sal_True);
1525*cdf0e10cSrcweir 				rPos++;
1526*cdf0e10cSrcweir 			}
1527*cdf0e10cSrcweir 			else
1528*cdf0e10cSrcweir 			{
1529*cdf0e10cSrcweir 				const sal_uInt32 nLoopCount(rCandidate.isClosed() ? nPointCount : nPointCount - 1);
1530*cdf0e10cSrcweir 
1531*cdf0e10cSrcweir 				for(sal_uInt32 b(0); b < nLoopCount; b++)
1532*cdf0e10cSrcweir 				{
1533*cdf0e10cSrcweir 					SdrObjKind eKind(OBJ_PLIN);
1534*cdf0e10cSrcweir 					basegfx::B2DPolygon aNewPolygon;
1535*cdf0e10cSrcweir 					const sal_uInt32 nNextIndex((b + 1) % nPointCount);
1536*cdf0e10cSrcweir 
1537*cdf0e10cSrcweir 					aNewPolygon.append(rCandidate.getB2DPoint(b));
1538*cdf0e10cSrcweir 
1539*cdf0e10cSrcweir 					if(rCandidate.areControlPointsUsed())
1540*cdf0e10cSrcweir 					{
1541*cdf0e10cSrcweir 						aNewPolygon.appendBezierSegment(
1542*cdf0e10cSrcweir 							rCandidate.getNextControlPoint(b),
1543*cdf0e10cSrcweir 							rCandidate.getPrevControlPoint(nNextIndex),
1544*cdf0e10cSrcweir 							rCandidate.getB2DPoint(nNextIndex));
1545*cdf0e10cSrcweir 						eKind = OBJ_PATHLINE;
1546*cdf0e10cSrcweir 					}
1547*cdf0e10cSrcweir 					else
1548*cdf0e10cSrcweir 					{
1549*cdf0e10cSrcweir 						aNewPolygon.append(rCandidate.getB2DPoint(nNextIndex));
1550*cdf0e10cSrcweir 					}
1551*cdf0e10cSrcweir 
1552*cdf0e10cSrcweir 					SdrPathObj* pPath = new SdrPathObj(eKind, basegfx::B2DPolyPolygon(aNewPolygon));
1553*cdf0e10cSrcweir 					ImpCopyAttributes(pSrcPath, pPath);
1554*cdf0e10cSrcweir 					pLast = pPath;
1555*cdf0e10cSrcweir 					SdrInsertReason aReason(SDRREASON_VIEWCALL, pSrcPath);
1556*cdf0e10cSrcweir 					rOL.InsertObject(pPath, rPos, &aReason);
1557*cdf0e10cSrcweir 					if( bUndo )
1558*cdf0e10cSrcweir 						AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pPath, sal_True));
1559*cdf0e10cSrcweir 					MarkObj(pPath, pPV, sal_False, sal_True);
1560*cdf0e10cSrcweir 					rPos++;
1561*cdf0e10cSrcweir 				}
1562*cdf0e10cSrcweir 			}
1563*cdf0e10cSrcweir 		}
1564*cdf0e10cSrcweir 
1565*cdf0e10cSrcweir 		if(pLast && pSrcPath->GetOutlinerParaObject())
1566*cdf0e10cSrcweir 		{
1567*cdf0e10cSrcweir 			pLast->SetOutlinerParaObject(new OutlinerParaObject(*pSrcPath->GetOutlinerParaObject()));
1568*cdf0e10cSrcweir 		}
1569*cdf0e10cSrcweir 	}
1570*cdf0e10cSrcweir 	else if(pCustomShape)
1571*cdf0e10cSrcweir 	{
1572*cdf0e10cSrcweir 		if(bMakeLines)
1573*cdf0e10cSrcweir 		{
1574*cdf0e10cSrcweir 			// break up custom shape
1575*cdf0e10cSrcweir 			const SdrObject* pReplacement = pCustomShape->GetSdrObjectFromCustomShape();
1576*cdf0e10cSrcweir 
1577*cdf0e10cSrcweir 			if(pReplacement)
1578*cdf0e10cSrcweir 			{
1579*cdf0e10cSrcweir 				SdrObject* pCandidate = pReplacement->Clone();
1580*cdf0e10cSrcweir 				DBG_ASSERT(pCandidate, "SdrEditView::ImpDismantleOneObject: Could not clone SdrObject (!)");
1581*cdf0e10cSrcweir 				pCandidate->SetModel(pCustomShape->GetModel());
1582*cdf0e10cSrcweir 
1583*cdf0e10cSrcweir 				if(((SdrShadowItem&)pCustomShape->GetMergedItem(SDRATTR_SHADOW)).GetValue())
1584*cdf0e10cSrcweir 				{
1585*cdf0e10cSrcweir 					if(pReplacement->ISA(SdrObjGroup))
1586*cdf0e10cSrcweir 					{
1587*cdf0e10cSrcweir 						pCandidate->SetMergedItem(SdrShadowItem(sal_True));
1588*cdf0e10cSrcweir 					}
1589*cdf0e10cSrcweir 				}
1590*cdf0e10cSrcweir 
1591*cdf0e10cSrcweir 				SdrInsertReason aReason(SDRREASON_VIEWCALL, pCustomShape);
1592*cdf0e10cSrcweir 				rOL.InsertObject(pCandidate, rPos, &aReason);
1593*cdf0e10cSrcweir 				if( bUndo )
1594*cdf0e10cSrcweir 					AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pCandidate, true));
1595*cdf0e10cSrcweir 				MarkObj(pCandidate, pPV, sal_False, sal_True);
1596*cdf0e10cSrcweir 
1597*cdf0e10cSrcweir 				if(pCustomShape->HasText() && !pCustomShape->IsTextPath())
1598*cdf0e10cSrcweir 				{
1599*cdf0e10cSrcweir 					// #i37011# also create a text object and add at rPos + 1
1600*cdf0e10cSrcweir 					SdrTextObj* pTextObj = (SdrTextObj*)SdrObjFactory::MakeNewObject(
1601*cdf0e10cSrcweir 						pCustomShape->GetObjInventor(), OBJ_TEXT, 0L, pCustomShape->GetModel());
1602*cdf0e10cSrcweir 
1603*cdf0e10cSrcweir 					// Copy text content
1604*cdf0e10cSrcweir 					OutlinerParaObject* pParaObj = pCustomShape->GetOutlinerParaObject();
1605*cdf0e10cSrcweir 					if(pParaObj)
1606*cdf0e10cSrcweir 					{
1607*cdf0e10cSrcweir 						pTextObj->NbcSetOutlinerParaObject(new OutlinerParaObject(*pParaObj));
1608*cdf0e10cSrcweir 					}
1609*cdf0e10cSrcweir 
1610*cdf0e10cSrcweir 					// copy all attributes
1611*cdf0e10cSrcweir 					SfxItemSet aTargetItemSet(pCustomShape->GetMergedItemSet());
1612*cdf0e10cSrcweir 
1613*cdf0e10cSrcweir 					// clear fill and line style
1614*cdf0e10cSrcweir 					aTargetItemSet.Put(XLineStyleItem(XLINE_NONE));
1615*cdf0e10cSrcweir 					aTargetItemSet.Put(XFillStyleItem(XFILL_NONE));
1616*cdf0e10cSrcweir 
1617*cdf0e10cSrcweir 					// get the text bounds and set at text object
1618*cdf0e10cSrcweir 					Rectangle aTextBounds = pCustomShape->GetSnapRect();
1619*cdf0e10cSrcweir 					if(pCustomShape->GetTextBounds(aTextBounds))
1620*cdf0e10cSrcweir 					{
1621*cdf0e10cSrcweir 						pTextObj->SetSnapRect(aTextBounds);
1622*cdf0e10cSrcweir 					}
1623*cdf0e10cSrcweir 
1624*cdf0e10cSrcweir 					// if rotated, copy GeoStat, too.
1625*cdf0e10cSrcweir 					const GeoStat& rSourceGeo = pCustomShape->GetGeoStat();
1626*cdf0e10cSrcweir 					if(rSourceGeo.nDrehWink)
1627*cdf0e10cSrcweir 					{
1628*cdf0e10cSrcweir 						pTextObj->NbcRotate(
1629*cdf0e10cSrcweir 							pCustomShape->GetSnapRect().Center(), rSourceGeo.nDrehWink,
1630*cdf0e10cSrcweir 							rSourceGeo.nSin, rSourceGeo.nCos);
1631*cdf0e10cSrcweir 					}
1632*cdf0e10cSrcweir 
1633*cdf0e10cSrcweir 					// set modified ItemSet at text object
1634*cdf0e10cSrcweir 					pTextObj->SetMergedItemSet(aTargetItemSet);
1635*cdf0e10cSrcweir 
1636*cdf0e10cSrcweir 					// insert object
1637*cdf0e10cSrcweir 					rOL.InsertObject(pTextObj, rPos + 1, &aReason);
1638*cdf0e10cSrcweir 					if( bUndo )
1639*cdf0e10cSrcweir 						AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pTextObj, true));
1640*cdf0e10cSrcweir 					MarkObj(pTextObj, pPV, sal_False, sal_True);
1641*cdf0e10cSrcweir 				}
1642*cdf0e10cSrcweir 			}
1643*cdf0e10cSrcweir 		}
1644*cdf0e10cSrcweir 	}
1645*cdf0e10cSrcweir }
1646*cdf0e10cSrcweir 
1647*cdf0e10cSrcweir void SdrEditView::DismantleMarkedObjects(sal_Bool bMakeLines)
1648*cdf0e10cSrcweir {
1649*cdf0e10cSrcweir 	//sal_uInt32 nCnt(0);
1650*cdf0e10cSrcweir 	// Temporaere Marklist
1651*cdf0e10cSrcweir 	SdrMarkList aRemoveMerker;
1652*cdf0e10cSrcweir 
1653*cdf0e10cSrcweir 	SortMarkedObjects();
1654*cdf0e10cSrcweir 
1655*cdf0e10cSrcweir 	const bool bUndo = IsUndoEnabled();
1656*cdf0e10cSrcweir 
1657*cdf0e10cSrcweir 	if( bUndo )
1658*cdf0e10cSrcweir 	{
1659*cdf0e10cSrcweir 		// Der Comment wird spaeter zusammengebaut
1660*cdf0e10cSrcweir 		BegUndo(String(), String(),
1661*cdf0e10cSrcweir 			bMakeLines ? SDRREPFUNC_OBJ_DISMANTLE_LINES : SDRREPFUNC_OBJ_DISMANTLE_POLYS);
1662*cdf0e10cSrcweir 	}
1663*cdf0e10cSrcweir 
1664*cdf0e10cSrcweir 	sal_uIntPtr nm;
1665*cdf0e10cSrcweir 	sal_uIntPtr nAnz=GetMarkedObjectCount();
1666*cdf0e10cSrcweir 	SdrObjList* pOL0=NULL;
1667*cdf0e10cSrcweir 	for (nm=nAnz; nm>0;) {
1668*cdf0e10cSrcweir 		nm--;
1669*cdf0e10cSrcweir 		SdrMark* pM=GetSdrMarkByIndex(nm);
1670*cdf0e10cSrcweir 		SdrObject* pObj=pM->GetMarkedSdrObj();
1671*cdf0e10cSrcweir 		SdrPageView* pPV=pM->GetPageView();
1672*cdf0e10cSrcweir 		SdrObjList* pOL=pObj->GetObjList();
1673*cdf0e10cSrcweir 		if (pOL!=pOL0) { pOL0=pOL; pObj->GetOrdNum(); } // sicherstellen, dass OrdNums stimmen!
1674*cdf0e10cSrcweir 		if (ImpCanDismantle(pObj,bMakeLines)) {
1675*cdf0e10cSrcweir 			aRemoveMerker.InsertEntry(SdrMark(pObj,pM->GetPageView()));
1676*cdf0e10cSrcweir 			sal_uIntPtr nPos0=pObj->GetOrdNumDirect();
1677*cdf0e10cSrcweir 			sal_uIntPtr nPos=nPos0+1;
1678*cdf0e10cSrcweir 			SdrObjList* pSubList=pObj->GetSubList();
1679*cdf0e10cSrcweir 			if (pSubList!=NULL && !pObj->Is3DObj()) {
1680*cdf0e10cSrcweir 				SdrObjListIter aIter(*pSubList,IM_DEEPNOGROUPS);
1681*cdf0e10cSrcweir 				while (aIter.IsMore()) {
1682*cdf0e10cSrcweir 					const SdrObject* pObj1=aIter.Next();
1683*cdf0e10cSrcweir 					ImpDismantleOneObject(pObj1,*pOL,nPos,pPV,bMakeLines);
1684*cdf0e10cSrcweir 				}
1685*cdf0e10cSrcweir 			} else {
1686*cdf0e10cSrcweir 				ImpDismantleOneObject(pObj,*pOL,nPos,pPV,bMakeLines);
1687*cdf0e10cSrcweir 			}
1688*cdf0e10cSrcweir 			if( bUndo )
1689*cdf0e10cSrcweir 				AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj,sal_True));
1690*cdf0e10cSrcweir 			pOL->RemoveObject(nPos0);
1691*cdf0e10cSrcweir 
1692*cdf0e10cSrcweir 			if( !bUndo )
1693*cdf0e10cSrcweir 				SdrObject::Free(pObj);
1694*cdf0e10cSrcweir 		}
1695*cdf0e10cSrcweir 	}
1696*cdf0e10cSrcweir 
1697*cdf0e10cSrcweir 	if( bUndo )
1698*cdf0e10cSrcweir 	{
1699*cdf0e10cSrcweir 		// UndoComment aus den tatsaechlich verwendeten Objekten zusammenbauen
1700*cdf0e10cSrcweir 		SetUndoComment(ImpGetResStr(bMakeLines?STR_EditDismantle_Lines:STR_EditDismantle_Polys),aRemoveMerker.GetMarkDescription());
1701*cdf0e10cSrcweir 		// die tatsaechlich verwendeten Objekten aus der Liste entfernen
1702*cdf0e10cSrcweir 		EndUndo();
1703*cdf0e10cSrcweir 	}
1704*cdf0e10cSrcweir }
1705*cdf0e10cSrcweir 
1706*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
1707*cdf0e10cSrcweir //
1708*cdf0e10cSrcweir //   #### ####   ###  #   # ####
1709*cdf0e10cSrcweir //  #     #   # #   # #   # #   #
1710*cdf0e10cSrcweir //  #  ## ####  #   # #   # ####
1711*cdf0e10cSrcweir //  #   # #   # #   # #   # #
1712*cdf0e10cSrcweir //   #### #   #  ###   ###  #
1713*cdf0e10cSrcweir //
1714*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
1715*cdf0e10cSrcweir 
1716*cdf0e10cSrcweir void SdrEditView::GroupMarked(const SdrObject* pUserGrp)
1717*cdf0e10cSrcweir {
1718*cdf0e10cSrcweir 	if (AreObjectsMarked())
1719*cdf0e10cSrcweir 	{
1720*cdf0e10cSrcweir 		SortMarkedObjects();
1721*cdf0e10cSrcweir 
1722*cdf0e10cSrcweir 		const bool bUndo = IsUndoEnabled();
1723*cdf0e10cSrcweir 		if( bUndo )
1724*cdf0e10cSrcweir 		{
1725*cdf0e10cSrcweir 			BegUndo(ImpGetResStr(STR_EditGroup),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_GROUP);
1726*cdf0e10cSrcweir 
1727*cdf0e10cSrcweir 			const sal_uIntPtr nAnz = GetMarkedObjectCount();
1728*cdf0e10cSrcweir 			for(sal_uIntPtr nm = nAnz; nm>0; )
1729*cdf0e10cSrcweir 			{
1730*cdf0e10cSrcweir 				// UndoActions fuer alle betroffenen Objekte anlegen
1731*cdf0e10cSrcweir 				nm--;
1732*cdf0e10cSrcweir 				SdrMark* pM=GetSdrMarkByIndex(nm);
1733*cdf0e10cSrcweir 				SdrObject* pObj = pM->GetMarkedSdrObj();
1734*cdf0e10cSrcweir 					std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pObj ) );
1735*cdf0e10cSrcweir 					AddUndoActions( vConnectorUndoActions );
1736*cdf0e10cSrcweir 					AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoRemoveObject( *pObj ));
1737*cdf0e10cSrcweir 			}
1738*cdf0e10cSrcweir 		}
1739*cdf0e10cSrcweir 
1740*cdf0e10cSrcweir 		SdrMarkList aNewMark;
1741*cdf0e10cSrcweir 		SdrPageView* pPV = GetSdrPageView();
1742*cdf0e10cSrcweir 
1743*cdf0e10cSrcweir 		if(pPV)
1744*cdf0e10cSrcweir 		{
1745*cdf0e10cSrcweir 			SdrObjList* pAktLst=pPV->GetObjList();
1746*cdf0e10cSrcweir 			SdrObjList* pSrcLst=pAktLst;
1747*cdf0e10cSrcweir 			SdrObjList* pSrcLst0=pSrcLst;
1748*cdf0e10cSrcweir 			SdrPage*    pPage=pPV->GetPage();
1749*cdf0e10cSrcweir 			// sicherstellen, dass die OrdNums stimmen
1750*cdf0e10cSrcweir 			if (pSrcLst->IsObjOrdNumsDirty())
1751*cdf0e10cSrcweir 				pSrcLst->RecalcObjOrdNums();
1752*cdf0e10cSrcweir 			SdrObject*  pGrp=NULL;
1753*cdf0e10cSrcweir 			SdrObject*  pRefObj=NULL; // Referenz fuer InsertReason (-> rumankern im Writer)
1754*cdf0e10cSrcweir 			SdrObject*  pRefObj1=NULL; // Referenz fuer InsertReason (-> rumankern im Writer)
1755*cdf0e10cSrcweir 			SdrObjList* pDstLst=NULL;
1756*cdf0e10cSrcweir 			// Falls alle markierten Objekte aus Fremden Obj-Listen
1757*cdf0e10cSrcweir 			// kommen, kommt das Gruppenobjekt an das Ende der Liste.
1758*cdf0e10cSrcweir 			sal_uIntPtr       nInsPos=pSrcLst->GetObjCount();
1759*cdf0e10cSrcweir 			sal_Bool    bNeedInsPos=sal_True;
1760*cdf0e10cSrcweir 			for (sal_uIntPtr nm=GetMarkedObjectCount(); nm>0;)
1761*cdf0e10cSrcweir 			{
1762*cdf0e10cSrcweir 				nm--;
1763*cdf0e10cSrcweir 				SdrMark* pM=GetSdrMarkByIndex(nm);
1764*cdf0e10cSrcweir 				if (pM->GetPageView()==pPV)
1765*cdf0e10cSrcweir 				{
1766*cdf0e10cSrcweir 					if (pGrp==NULL)
1767*cdf0e10cSrcweir 					{
1768*cdf0e10cSrcweir 						if (pUserGrp!=NULL)
1769*cdf0e10cSrcweir 							pGrp=pUserGrp->Clone();
1770*cdf0e10cSrcweir 						if (pGrp==NULL)
1771*cdf0e10cSrcweir 							pGrp=new SdrObjGroup;
1772*cdf0e10cSrcweir 						pDstLst=pGrp->GetSubList();
1773*cdf0e10cSrcweir 						DBG_ASSERT(pDstLst!=NULL,"Angebliches Gruppenobjekt liefert keine Objektliste");
1774*cdf0e10cSrcweir 					}
1775*cdf0e10cSrcweir 					SdrObject* pObj=pM->GetMarkedSdrObj();
1776*cdf0e10cSrcweir 					pSrcLst=pObj->GetObjList();
1777*cdf0e10cSrcweir 					if (pSrcLst!=pSrcLst0)
1778*cdf0e10cSrcweir 					{
1779*cdf0e10cSrcweir 						if (pSrcLst->IsObjOrdNumsDirty())
1780*cdf0e10cSrcweir 							pSrcLst->RecalcObjOrdNums();
1781*cdf0e10cSrcweir 					}
1782*cdf0e10cSrcweir 					sal_Bool bForeignList=pSrcLst!=pAktLst;
1783*cdf0e10cSrcweir 					sal_Bool bGrouped=pSrcLst!=pPage;
1784*cdf0e10cSrcweir 					if (!bForeignList && bNeedInsPos)
1785*cdf0e10cSrcweir 					{
1786*cdf0e10cSrcweir 						nInsPos=pObj->GetOrdNum(); // ua, damit sind alle ObjOrdNum der Page gesetzt
1787*cdf0e10cSrcweir 						nInsPos++;
1788*cdf0e10cSrcweir 						bNeedInsPos=sal_False;
1789*cdf0e10cSrcweir 					}
1790*cdf0e10cSrcweir 					pSrcLst->RemoveObject(pObj->GetOrdNumDirect());
1791*cdf0e10cSrcweir 					if (!bForeignList)
1792*cdf0e10cSrcweir 						nInsPos--; // InsertPos korregieren
1793*cdf0e10cSrcweir 					SdrInsertReason aReason(SDRREASON_VIEWCALL);
1794*cdf0e10cSrcweir 					pDstLst->InsertObject(pObj,0,&aReason);
1795*cdf0e10cSrcweir 					GetMarkedObjectListWriteAccess().DeleteMark(nm);
1796*cdf0e10cSrcweir 					if (pRefObj1==NULL)
1797*cdf0e10cSrcweir 						pRefObj1=pObj; // Das oberste sichtbare Objekt
1798*cdf0e10cSrcweir 					if (!bGrouped)
1799*cdf0e10cSrcweir 					{
1800*cdf0e10cSrcweir 						if (pRefObj==NULL)
1801*cdf0e10cSrcweir 							pRefObj=pObj; // Das oberste sichtbare nicht gruppierte Objekt
1802*cdf0e10cSrcweir 					}
1803*cdf0e10cSrcweir 					pSrcLst0=pSrcLst;
1804*cdf0e10cSrcweir 				}
1805*cdf0e10cSrcweir 			}
1806*cdf0e10cSrcweir 			if (pRefObj==NULL)
1807*cdf0e10cSrcweir 				pRefObj=pRefObj1;
1808*cdf0e10cSrcweir 			if (pGrp!=NULL)
1809*cdf0e10cSrcweir 			{
1810*cdf0e10cSrcweir 				aNewMark.InsertEntry(SdrMark(pGrp,pPV));
1811*cdf0e10cSrcweir 				sal_uIntPtr nAnz=pDstLst->GetObjCount();
1812*cdf0e10cSrcweir 				SdrInsertReason aReason(SDRREASON_VIEWCALL,pRefObj);
1813*cdf0e10cSrcweir 				pAktLst->InsertObject(pGrp,nInsPos,&aReason);
1814*cdf0e10cSrcweir 				if( bUndo )
1815*cdf0e10cSrcweir 				{
1816*cdf0e10cSrcweir 					AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pGrp,true)); // Kein Recalc!
1817*cdf0e10cSrcweir 					for (sal_uIntPtr no=0; no<nAnz; no++)
1818*cdf0e10cSrcweir 					{
1819*cdf0e10cSrcweir 						AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoInsertObject(*pDstLst->GetObj(no)));
1820*cdf0e10cSrcweir 					}
1821*cdf0e10cSrcweir 				}
1822*cdf0e10cSrcweir 			}
1823*cdf0e10cSrcweir 		}
1824*cdf0e10cSrcweir 		GetMarkedObjectListWriteAccess().Merge(aNewMark);
1825*cdf0e10cSrcweir 		MarkListHasChanged();
1826*cdf0e10cSrcweir 
1827*cdf0e10cSrcweir 		if( bUndo )
1828*cdf0e10cSrcweir 			EndUndo();
1829*cdf0e10cSrcweir 	}
1830*cdf0e10cSrcweir }
1831*cdf0e10cSrcweir 
1832*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
1833*cdf0e10cSrcweir //
1834*cdf0e10cSrcweir //  #   # #   #  #### ####   ###  #   # ####
1835*cdf0e10cSrcweir //  #   # ##  # #     #   # #   # #   # #   #
1836*cdf0e10cSrcweir //  #   # # # # #  ## ####  #   # #   # ####
1837*cdf0e10cSrcweir //  #   # #  ## #   # #   # #   # #   # #
1838*cdf0e10cSrcweir //   ###  #   #  #### #   #  ###   ###  #
1839*cdf0e10cSrcweir //
1840*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
1841*cdf0e10cSrcweir 
1842*cdf0e10cSrcweir void SdrEditView::UnGroupMarked()
1843*cdf0e10cSrcweir {
1844*cdf0e10cSrcweir 	SdrMarkList aNewMark;
1845*cdf0e10cSrcweir 
1846*cdf0e10cSrcweir 	const bool bUndo = IsUndoEnabled();
1847*cdf0e10cSrcweir 	if( bUndo )
1848*cdf0e10cSrcweir 		BegUndo(String(), String(), SDRREPFUNC_OBJ_UNGROUP);
1849*cdf0e10cSrcweir 
1850*cdf0e10cSrcweir 	sal_uIntPtr nCount=0;
1851*cdf0e10cSrcweir 	XubString aName1;
1852*cdf0e10cSrcweir 	XubString aName;
1853*cdf0e10cSrcweir 	sal_Bool bNameOk=sal_False;
1854*cdf0e10cSrcweir 	for (sal_uIntPtr nm=GetMarkedObjectCount(); nm>0;) {
1855*cdf0e10cSrcweir 		nm--;
1856*cdf0e10cSrcweir 		SdrMark* pM=GetSdrMarkByIndex(nm);
1857*cdf0e10cSrcweir 		SdrObject* pGrp=pM->GetMarkedSdrObj();
1858*cdf0e10cSrcweir 		SdrObjList* pSrcLst=pGrp->GetSubList();
1859*cdf0e10cSrcweir 		if (pSrcLst!=NULL) {
1860*cdf0e10cSrcweir 			nCount++;
1861*cdf0e10cSrcweir 			if (nCount==1) {
1862*cdf0e10cSrcweir 				pGrp->TakeObjNameSingul(aName);  // Bezeichnung der Gruppe holen
1863*cdf0e10cSrcweir 				pGrp->TakeObjNamePlural(aName1); // Bezeichnung der Gruppe holen
1864*cdf0e10cSrcweir 				bNameOk=sal_True;
1865*cdf0e10cSrcweir 			} else {
1866*cdf0e10cSrcweir 				if (nCount==2) aName=aName1; // Pluralname setzen
1867*cdf0e10cSrcweir 				if (bNameOk) {
1868*cdf0e10cSrcweir 					XubString aStr;
1869*cdf0e10cSrcweir 					pGrp->TakeObjNamePlural(aStr); // Bezeichnung der Gruppe holen
1870*cdf0e10cSrcweir 
1871*cdf0e10cSrcweir 					if(!aStr.Equals(aName))
1872*cdf0e10cSrcweir 						bNameOk = sal_False;
1873*cdf0e10cSrcweir 				}
1874*cdf0e10cSrcweir 			}
1875*cdf0e10cSrcweir 			sal_uIntPtr nDstCnt=pGrp->GetOrdNum();
1876*cdf0e10cSrcweir 			SdrObjList* pDstLst=pM->GetPageView()->GetObjList();
1877*cdf0e10cSrcweir 
1878*cdf0e10cSrcweir 			// FIRST move contained objects to parent of group, so that
1879*cdf0e10cSrcweir 			// the contained objects are NOT migrated to the UNDO-ItemPool
1880*cdf0e10cSrcweir 			// when AddUndo(new SdrUndoDelObj(*pGrp)) is called.
1881*cdf0e10cSrcweir 			sal_uIntPtr nAnz=pSrcLst->GetObjCount();
1882*cdf0e10cSrcweir 			sal_uIntPtr no;
1883*cdf0e10cSrcweir 
1884*cdf0e10cSrcweir 			if( bUndo )
1885*cdf0e10cSrcweir 			{
1886*cdf0e10cSrcweir 				for (no=nAnz; no>0;)
1887*cdf0e10cSrcweir 				{
1888*cdf0e10cSrcweir 					no--;
1889*cdf0e10cSrcweir 					SdrObject* pObj=pSrcLst->GetObj(no);
1890*cdf0e10cSrcweir 					AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoRemoveObject(*pObj));
1891*cdf0e10cSrcweir 				}
1892*cdf0e10cSrcweir 			}
1893*cdf0e10cSrcweir 			for (no=0; no<nAnz; no++)
1894*cdf0e10cSrcweir 			{
1895*cdf0e10cSrcweir 				SdrObject* pObj=pSrcLst->RemoveObject(0);
1896*cdf0e10cSrcweir 				SdrInsertReason aReason(SDRREASON_VIEWCALL,pGrp);
1897*cdf0e10cSrcweir 				pDstLst->InsertObject(pObj,nDstCnt,&aReason);
1898*cdf0e10cSrcweir 				if( bUndo )
1899*cdf0e10cSrcweir 					AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoInsertObject(*pObj,true));
1900*cdf0e10cSrcweir 				nDstCnt++;
1901*cdf0e10cSrcweir 				// Kein SortCheck beim einfuegen in die MarkList, denn das
1902*cdf0e10cSrcweir 				// wuerde wg. pObj->GetOrdNum() jedesmal ein RecalcOrdNums()
1903*cdf0e10cSrcweir 				// provozieren:
1904*cdf0e10cSrcweir 				aNewMark.InsertEntry(SdrMark(pObj,pM->GetPageView()),sal_False);
1905*cdf0e10cSrcweir 			}
1906*cdf0e10cSrcweir 
1907*cdf0e10cSrcweir 			if( bUndo )
1908*cdf0e10cSrcweir 			{
1909*cdf0e10cSrcweir 				// Now it is safe to add the delete-UNDO which trigers the
1910*cdf0e10cSrcweir 				// MigrateItemPool now only for itself, not for the subobjects.
1911*cdf0e10cSrcweir 				// nDstCnt is right, because previous inserts move group
1912*cdf0e10cSrcweir 				// object deeper and increase nDstCnt.
1913*cdf0e10cSrcweir 				AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pGrp));
1914*cdf0e10cSrcweir 			}
1915*cdf0e10cSrcweir 			pDstLst->RemoveObject(nDstCnt);
1916*cdf0e10cSrcweir 
1917*cdf0e10cSrcweir 			if( !bUndo )
1918*cdf0e10cSrcweir 				SdrObject::Free(pGrp);
1919*cdf0e10cSrcweir 
1920*cdf0e10cSrcweir 			GetMarkedObjectListWriteAccess().DeleteMark(nm);
1921*cdf0e10cSrcweir 		}
1922*cdf0e10cSrcweir 	}
1923*cdf0e10cSrcweir 	if (nCount!=0)
1924*cdf0e10cSrcweir 	{
1925*cdf0e10cSrcweir 		if (!bNameOk)
1926*cdf0e10cSrcweir 			aName=ImpGetResStr(STR_ObjNamePluralGRUP); // Oberbegriff Gruppenobjekte verwenden, wenn verschiedene Objekte.
1927*cdf0e10cSrcweir 		SetUndoComment(ImpGetResStr(STR_EditUngroup),aName);
1928*cdf0e10cSrcweir 	}
1929*cdf0e10cSrcweir 
1930*cdf0e10cSrcweir 	if( bUndo )
1931*cdf0e10cSrcweir 		EndUndo();
1932*cdf0e10cSrcweir 
1933*cdf0e10cSrcweir 	if (nCount!=0)
1934*cdf0e10cSrcweir 	{
1935*cdf0e10cSrcweir 		GetMarkedObjectListWriteAccess().Merge(aNewMark,sal_True); // Durch das obige Einsortieren ist aNewMark genau verkehrtherum
1936*cdf0e10cSrcweir 		MarkListHasChanged();
1937*cdf0e10cSrcweir 	}
1938*cdf0e10cSrcweir }
1939*cdf0e10cSrcweir 
1940*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
1941*cdf0e10cSrcweir //
1942*cdf0e10cSrcweir //   ###   ###  #   # #   # ##### ####  #####   #####  ###    ####   ###  #  #   #
1943*cdf0e10cSrcweir //  #   # #   # ##  # #   # #     #   #   #       #   #   #   #   # #   # #   # #
1944*cdf0e10cSrcweir //  #     #   # # # # #   # ####  ####    #       #   #   #   ####  #   # #    #
1945*cdf0e10cSrcweir //  #   # #   # #  ##  # #  #     #   #   #       #   #   #   #     #   # #    #
1946*cdf0e10cSrcweir //   ###   ###  #   #   #   ##### #   #   #       #    ###    #      ###  #### #
1947*cdf0e10cSrcweir //
1948*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
1949*cdf0e10cSrcweir 
1950*cdf0e10cSrcweir SdrObject* SdrEditView::ImpConvertOneObj(SdrObject* pObj, sal_Bool bPath, sal_Bool bLineToArea)
1951*cdf0e10cSrcweir {
1952*cdf0e10cSrcweir 	SdrObject* pNewObj = pObj->ConvertToPolyObj(bPath, bLineToArea);
1953*cdf0e10cSrcweir 	if (pNewObj!=NULL)
1954*cdf0e10cSrcweir 	{
1955*cdf0e10cSrcweir 		SdrObjList* pOL=pObj->GetObjList();
1956*cdf0e10cSrcweir 		DBG_ASSERT(pOL!=NULL,"ConvertTo: Obj liefert keine ObjList");
1957*cdf0e10cSrcweir 		if (pOL!=NULL)
1958*cdf0e10cSrcweir 		{
1959*cdf0e10cSrcweir 			const bool bUndo = IsUndoEnabled();
1960*cdf0e10cSrcweir 			if( bUndo )
1961*cdf0e10cSrcweir 				AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoReplaceObject(*pObj,*pNewObj));
1962*cdf0e10cSrcweir 
1963*cdf0e10cSrcweir 			pOL->ReplaceObject(pNewObj,pObj->GetOrdNum());
1964*cdf0e10cSrcweir 
1965*cdf0e10cSrcweir 			if( !bUndo )
1966*cdf0e10cSrcweir 				SdrObject::Free(pObj);
1967*cdf0e10cSrcweir 		}
1968*cdf0e10cSrcweir 	}
1969*cdf0e10cSrcweir 	return pNewObj;
1970*cdf0e10cSrcweir }
1971*cdf0e10cSrcweir 
1972*cdf0e10cSrcweir void SdrEditView::ImpConvertTo(sal_Bool bPath, sal_Bool bLineToArea)
1973*cdf0e10cSrcweir {
1974*cdf0e10cSrcweir 	sal_Bool bMrkChg=sal_False;
1975*cdf0e10cSrcweir 	sal_Bool bModChg=sal_False;
1976*cdf0e10cSrcweir 	if (AreObjectsMarked()) {
1977*cdf0e10cSrcweir 		sal_uIntPtr nMarkAnz=GetMarkedObjectCount();
1978*cdf0e10cSrcweir 		sal_uInt16 nDscrID=0;
1979*cdf0e10cSrcweir 		if(bLineToArea)
1980*cdf0e10cSrcweir 		{
1981*cdf0e10cSrcweir 			if(nMarkAnz == 1)
1982*cdf0e10cSrcweir 				nDscrID = STR_EditConvToContour;
1983*cdf0e10cSrcweir 			else
1984*cdf0e10cSrcweir 				nDscrID = STR_EditConvToContours;
1985*cdf0e10cSrcweir 
1986*cdf0e10cSrcweir 			BegUndo(ImpGetResStr(nDscrID), GetDescriptionOfMarkedObjects());
1987*cdf0e10cSrcweir 		}
1988*cdf0e10cSrcweir 		else
1989*cdf0e10cSrcweir 		{
1990*cdf0e10cSrcweir 			if (bPath) {
1991*cdf0e10cSrcweir 				if (nMarkAnz==1) nDscrID=STR_EditConvToCurve;
1992*cdf0e10cSrcweir 				else nDscrID=STR_EditConvToCurves;
1993*cdf0e10cSrcweir 				BegUndo(ImpGetResStr(nDscrID),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_CONVERTTOPATH);
1994*cdf0e10cSrcweir 			} else {
1995*cdf0e10cSrcweir 				if (nMarkAnz==1) nDscrID=STR_EditConvToPoly;
1996*cdf0e10cSrcweir 				else nDscrID=STR_EditConvToPolys;
1997*cdf0e10cSrcweir 				BegUndo(ImpGetResStr(nDscrID),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_CONVERTTOPOLY);
1998*cdf0e10cSrcweir 			}
1999*cdf0e10cSrcweir 		}
2000*cdf0e10cSrcweir 		for (sal_uIntPtr nm=nMarkAnz; nm>0;) {
2001*cdf0e10cSrcweir 			nm--;
2002*cdf0e10cSrcweir 			SdrMark* pM=GetSdrMarkByIndex(nm);
2003*cdf0e10cSrcweir 			SdrObject* pObj=pM->GetMarkedSdrObj();
2004*cdf0e10cSrcweir 			SdrPageView* pPV=pM->GetPageView();
2005*cdf0e10cSrcweir 			if (pObj->IsGroupObject() && !pObj->Is3DObj()) {
2006*cdf0e10cSrcweir 				SdrObject* pGrp=pObj;
2007*cdf0e10cSrcweir 				SdrObjListIter aIter(*pGrp,IM_DEEPNOGROUPS);
2008*cdf0e10cSrcweir 				while (aIter.IsMore()) {
2009*cdf0e10cSrcweir 					pObj=aIter.Next();
2010*cdf0e10cSrcweir 					if (ImpConvertOneObj(pObj,bPath,bLineToArea)) bModChg=sal_True;
2011*cdf0e10cSrcweir 				}
2012*cdf0e10cSrcweir 			} else {
2013*cdf0e10cSrcweir 				SdrObject* pNewObj=ImpConvertOneObj(pObj,bPath,bLineToArea);
2014*cdf0e10cSrcweir 				if (pNewObj!=NULL) {
2015*cdf0e10cSrcweir 					bModChg=sal_True;
2016*cdf0e10cSrcweir 					bMrkChg=sal_True;
2017*cdf0e10cSrcweir 					GetMarkedObjectListWriteAccess().ReplaceMark(SdrMark(pNewObj,pPV),nm);
2018*cdf0e10cSrcweir 				}
2019*cdf0e10cSrcweir 			}
2020*cdf0e10cSrcweir 		}
2021*cdf0e10cSrcweir 		EndUndo();
2022*cdf0e10cSrcweir 		if (bMrkChg) AdjustMarkHdl();
2023*cdf0e10cSrcweir 		if (bMrkChg) MarkListHasChanged();
2024*cdf0e10cSrcweir 	}
2025*cdf0e10cSrcweir }
2026*cdf0e10cSrcweir 
2027*cdf0e10cSrcweir void SdrEditView::ConvertMarkedToPathObj(sal_Bool bLineToArea)
2028*cdf0e10cSrcweir {
2029*cdf0e10cSrcweir 	ImpConvertTo(sal_True, bLineToArea);
2030*cdf0e10cSrcweir }
2031*cdf0e10cSrcweir 
2032*cdf0e10cSrcweir void SdrEditView::ConvertMarkedToPolyObj(sal_Bool bLineToArea)
2033*cdf0e10cSrcweir {
2034*cdf0e10cSrcweir 	ImpConvertTo(sal_False, bLineToArea);
2035*cdf0e10cSrcweir }
2036*cdf0e10cSrcweir 
2037*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
2038*cdf0e10cSrcweir //
2039*cdf0e10cSrcweir //  #   # ##### #####  ###  ##### # #    #####      # #   # ####   ###  ####  #####
2040*cdf0e10cSrcweir //  ## ## #       #   #   # #     # #    #          # ## ## #   # #   # #   #   #
2041*cdf0e10cSrcweir //  # # # ####    #   ##### ###   # #    ####  ###  # # # # ####  #   # ####    #
2042*cdf0e10cSrcweir //  #   # #       #   #   # #     # #    #          # #   # #     #   # #   #   #
2043*cdf0e10cSrcweir //  #   # #####   #   #   # #     # #### #####      # #   # #      ###  #   #   #
2044*cdf0e10cSrcweir //
2045*cdf0e10cSrcweir ////////////////////////////////////////////////////////////////////////////////////////////////////
2046*cdf0e10cSrcweir 
2047*cdf0e10cSrcweir void SdrEditView::DoImportMarkedMtf(SvdProgressInfo *pProgrInfo)
2048*cdf0e10cSrcweir {
2049*cdf0e10cSrcweir 	const bool bUndo = IsUndoEnabled();
2050*cdf0e10cSrcweir 
2051*cdf0e10cSrcweir 	if( bUndo )
2052*cdf0e10cSrcweir 		BegUndo(String(), String(), SDRREPFUNC_OBJ_IMPORTMTF);
2053*cdf0e10cSrcweir 
2054*cdf0e10cSrcweir 	SortMarkedObjects();
2055*cdf0e10cSrcweir 	SdrMarkList aForTheDescription;
2056*cdf0e10cSrcweir 	SdrMarkList aNewMarked;
2057*cdf0e10cSrcweir 	sal_uIntPtr nAnz=GetMarkedObjectCount();
2058*cdf0e10cSrcweir 
2059*cdf0e10cSrcweir 	for (sal_uIntPtr nm=nAnz; nm>0;)
2060*cdf0e10cSrcweir 	{ // Undo Objekte fuer alle neuen Objekte erzeugen
2061*cdf0e10cSrcweir 		// zwischen den Metafiles auf Abbruch testen
2062*cdf0e10cSrcweir 		if( pProgrInfo != NULL )
2063*cdf0e10cSrcweir 		{
2064*cdf0e10cSrcweir 			pProgrInfo->SetNextObject();
2065*cdf0e10cSrcweir 			if(!pProgrInfo->ReportActions(0))
2066*cdf0e10cSrcweir 				break;
2067*cdf0e10cSrcweir 		}
2068*cdf0e10cSrcweir 
2069*cdf0e10cSrcweir 		nm--;
2070*cdf0e10cSrcweir 		SdrMark*     pM=GetSdrMarkByIndex(nm);
2071*cdf0e10cSrcweir 		SdrObject*   pObj=pM->GetMarkedSdrObj();
2072*cdf0e10cSrcweir 		SdrPageView* pPV=pM->GetPageView();
2073*cdf0e10cSrcweir 		SdrObjList*  pOL=pObj->GetObjList();
2074*cdf0e10cSrcweir 		sal_uIntPtr        nInsPos=pObj->GetOrdNum()+1;
2075*cdf0e10cSrcweir 		SdrGrafObj*  pGraf=PTR_CAST(SdrGrafObj,pObj);
2076*cdf0e10cSrcweir 		SdrOle2Obj*  pOle2=PTR_CAST(SdrOle2Obj,pObj);
2077*cdf0e10cSrcweir 		sal_uIntPtr        nInsAnz=0;
2078*cdf0e10cSrcweir 		if (pGraf!=NULL && pGraf->HasGDIMetaFile())
2079*cdf0e10cSrcweir 		{
2080*cdf0e10cSrcweir 			ImpSdrGDIMetaFileImport aFilter(*pMod);
2081*cdf0e10cSrcweir 			aFilter.SetScaleRect(pGraf->GetSnapRect());
2082*cdf0e10cSrcweir 			aFilter.SetLayer(pObj->GetLayer());
2083*cdf0e10cSrcweir 			nInsAnz=aFilter.DoImport(pGraf->GetTransformedGraphic().GetGDIMetaFile(),*pOL,nInsPos,pProgrInfo);
2084*cdf0e10cSrcweir 		}
2085*cdf0e10cSrcweir         if ( pOle2!=NULL && pOle2->GetGraphic() )
2086*cdf0e10cSrcweir 		{
2087*cdf0e10cSrcweir             //const GDIMetaFile* pMtf=pOle2->GetGDIMetaFile();
2088*cdf0e10cSrcweir 			ImpSdrGDIMetaFileImport aFilter(*pMod);
2089*cdf0e10cSrcweir 			aFilter.SetScaleRect(pOle2->GetLogicRect());
2090*cdf0e10cSrcweir 			aFilter.SetLayer(pObj->GetLayer());
2091*cdf0e10cSrcweir             nInsAnz=aFilter.DoImport(pOle2->GetGraphic()->GetGDIMetaFile(),*pOL,nInsPos,pProgrInfo);
2092*cdf0e10cSrcweir 		}
2093*cdf0e10cSrcweir 		if (nInsAnz!=0)
2094*cdf0e10cSrcweir 		{
2095*cdf0e10cSrcweir 			sal_uIntPtr nObj=nInsPos;
2096*cdf0e10cSrcweir 			for (sal_uIntPtr i=0; i<nInsAnz; i++)
2097*cdf0e10cSrcweir 			{
2098*cdf0e10cSrcweir 				if( bUndo )
2099*cdf0e10cSrcweir 					AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pOL->GetObj(nObj)));
2100*cdf0e10cSrcweir 
2101*cdf0e10cSrcweir 				// Neue MarkList pflegen
2102*cdf0e10cSrcweir 				SdrMark aNewMark(pOL->GetObj(nObj), pPV);
2103*cdf0e10cSrcweir 				aNewMarked.InsertEntry(aNewMark);
2104*cdf0e10cSrcweir 
2105*cdf0e10cSrcweir 				nObj++;
2106*cdf0e10cSrcweir 			}
2107*cdf0e10cSrcweir 			aForTheDescription.InsertEntry(*pM);
2108*cdf0e10cSrcweir 
2109*cdf0e10cSrcweir 			if( bUndo )
2110*cdf0e10cSrcweir 				AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj));
2111*cdf0e10cSrcweir 
2112*cdf0e10cSrcweir 			// Objekt aus selektion loesen und loeschen
2113*cdf0e10cSrcweir 			GetMarkedObjectListWriteAccess().DeleteMark(TryToFindMarkedObject(pObj));
2114*cdf0e10cSrcweir 			pOL->RemoveObject(nInsPos-1);
2115*cdf0e10cSrcweir 
2116*cdf0e10cSrcweir 			if( !bUndo )
2117*cdf0e10cSrcweir 				SdrObject::Free(pObj);
2118*cdf0e10cSrcweir 		}
2119*cdf0e10cSrcweir 	}
2120*cdf0e10cSrcweir 
2121*cdf0e10cSrcweir 	// MarkObj... fehlt... jetzt nicht mehr (AW)
2122*cdf0e10cSrcweir 	if(aNewMarked.GetMarkCount())
2123*cdf0e10cSrcweir 	{
2124*cdf0e10cSrcweir 		// Neue Selektion bilden
2125*cdf0e10cSrcweir 		for(sal_uIntPtr a(0); a < aNewMarked.GetMarkCount(); a++)
2126*cdf0e10cSrcweir 		{
2127*cdf0e10cSrcweir 			GetMarkedObjectListWriteAccess().InsertEntry(*aNewMarked.GetMark(a));
2128*cdf0e10cSrcweir 		}
2129*cdf0e10cSrcweir 
2130*cdf0e10cSrcweir 		SortMarkedObjects();
2131*cdf0e10cSrcweir 	}
2132*cdf0e10cSrcweir 
2133*cdf0e10cSrcweir 	if( bUndo )
2134*cdf0e10cSrcweir 	{
2135*cdf0e10cSrcweir 		SetUndoComment(ImpGetResStr(STR_EditImportMtf),aForTheDescription.GetMarkDescription());
2136*cdf0e10cSrcweir 		EndUndo();
2137*cdf0e10cSrcweir 	}
2138*cdf0e10cSrcweir }
2139*cdf0e10cSrcweir 
2140