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