merge the formfield patch from ooo-build
[ooovba.git] / svx / source / svdraw / svdedtv2.cxx
blob89122decf4dc9a62492a6026ed3bf6eda5ae3335
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: svdedtv2.cxx,v $
10 * $Revision: 1.33.146.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 #include <svx/svdedtv.hxx>
35 #include <svx/outliner.hxx>
36 #include <svx/svdundo.hxx>
37 #include <svx/svdogrp.hxx> // fuer's Gruppieren
38 #include <svx/svdovirt.hxx> // fuer VirtualObject-Bundling (Writer)
39 #include <svx/svdopath.hxx> // fuer CombineObjects
40 #include <svx/svdpage.hxx>
41 #include <svx/svdpagv.hxx>
42 #include "svditer.hxx"
43 #include <svx/svdograf.hxx> // fuer Possibilities
44 #include <svx/svdoole2.hxx> // und Mtf-Import
45 #include "svdstr.hrc" // Namen aus der Resource
46 #include "svdglob.hxx" // StringCache
47 #include "svdfmtf.hxx"
48 #include <svx/svdetc.hxx>
49 #include <sfx2/basedlgs.hxx>
50 #include <vcl/msgbox.hxx>
51 #include <svx/outlobj.hxx>
52 #include <svx/eeitem.hxx>
53 #include <basegfx/polygon/b2dpolypolygon.hxx>
54 #include <basegfx/polygon/b2dpolypolygontools.hxx>
56 #include <svx/svxdlg.hxx> //CHINA001
57 #include <svx/dialogs.hrc> //CHINA001
59 // #i37011#
60 #include <svx/svdoashp.hxx>
61 #include <basegfx/polygon/b2dpolypolygoncutter.hxx>
63 ////////////////////////////////////////////////////////////////////////////////////////////////////
64 ////////////////////////////////////////////////////////////////////////////////////////////////////
65 ////////////////////////////////////////////////////////////////////////////////////////////////////
66 ////////////////////////////////////////////////////////////////////////////////////////////////////
68 // @@@@@ @@@@@ @@ @@@@@@ @@ @@ @@ @@@@@ @@ @@
69 // @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
70 // @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @ @@
71 // @@@@ @@ @@ @@ @@ @@@@@ @@ @@@@ @@@@@@@
72 // @@ @@ @@ @@ @@ @@@ @@ @@ @@@@@@@
73 // @@ @@ @@ @@ @@ @@@ @@ @@ @@@ @@@
74 // @@@@@ @@@@@ @@ @@ @ @@ @@@@@ @@ @@
76 ////////////////////////////////////////////////////////////////////////////////////////////////////
77 ////////////////////////////////////////////////////////////////////////////////////////////////////
79 void SdrEditView::ImpBundleVirtObjOfMarkList()
81 // ... fehlende Implementation
84 SdrObject* SdrEditView::GetMaxToTopObj(SdrObject* /*pObj*/) const
86 return NULL;
89 SdrObject* SdrEditView::GetMaxToBtmObj(SdrObject* /*pObj*/) const
91 return NULL;
94 void SdrEditView::ObjOrderChanged(SdrObject* /*pObj*/, ULONG /*nOldPos*/, ULONG /*nNewPos*/)
98 void SdrEditView::MovMarkedToTop()
100 ULONG nAnz=GetMarkedObjectCount();
101 if (nAnz!=0)
103 const bool bUndo = IsUndoEnabled();
105 if( bUndo )
106 BegUndo(ImpGetResStr(STR_EditMovToTop),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_MOVTOTOP);
108 SortMarkedObjects();
109 ULONG nm;
110 for (nm=0; nm<nAnz; nm++)
111 { // Ordnums muessen alle stimmen!
112 GetMarkedObjectByIndex(nm)->GetOrdNum();
114 BOOL bChg=FALSE;
115 SdrObjList* pOL0=NULL;
116 ULONG nNewPos=0;
117 for (nm=nAnz; nm>0;)
119 nm--;
120 SdrMark* pM=GetSdrMarkByIndex(nm);
121 SdrObject* pObj=pM->GetMarkedSdrObj();
122 SdrObjList* pOL=pObj->GetObjList();
123 if (pOL!=pOL0)
125 nNewPos=ULONG(pOL->GetObjCount()-1);
126 pOL0=pOL;
128 ULONG nNowPos=pObj->GetOrdNumDirect();
129 const Rectangle& rBR=pObj->GetCurrentBoundRect();
130 ULONG nCmpPos=nNowPos+1;
131 SdrObject* pMaxObj=GetMaxToTopObj(pObj);
132 if (pMaxObj!=NULL)
134 ULONG nMaxPos=pMaxObj->GetOrdNum();
135 if (nMaxPos!=0)
136 nMaxPos--;
137 if (nNewPos>nMaxPos)
138 nNewPos=nMaxPos; // diesen nicht ueberholen.
139 if (nNewPos<nNowPos)
140 nNewPos=nNowPos; // aber dabei auch nicht in die falsche Richtung schieben
142 BOOL bEnd=FALSE;
143 while (nCmpPos<nNewPos && !bEnd)
145 SdrObject* pCmpObj=pOL->GetObj(nCmpPos);
146 if (pCmpObj==NULL)
148 DBG_ERROR("MovMarkedToTop(): Vergleichsobjekt nicht gefunden");
149 bEnd=TRUE;
151 else if (pCmpObj==pMaxObj)
153 nNewPos=nCmpPos;
154 nNewPos--;
155 bEnd=TRUE;
157 else if (rBR.IsOver(pCmpObj->GetCurrentBoundRect()))
159 nNewPos=nCmpPos;
160 bEnd=TRUE;
162 else
164 nCmpPos++;
167 if (nNowPos!=nNewPos)
169 bChg=TRUE;
170 pOL->SetObjectOrdNum(nNowPos,nNewPos);
171 if( bUndo )
172 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj,nNowPos,nNewPos));
173 ObjOrderChanged(pObj,nNowPos,nNewPos);
175 nNewPos--;
178 if( bUndo )
179 EndUndo();
181 if (bChg)
182 MarkListHasChanged();
186 void SdrEditView::MovMarkedToBtm()
188 ULONG nAnz=GetMarkedObjectCount();
189 if (nAnz!=0)
191 const bool bUndo = IsUndoEnabled();
193 if( bUndo )
194 BegUndo(ImpGetResStr(STR_EditMovToBtm),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_MOVTOBTM);
196 SortMarkedObjects();
197 ULONG nm;
198 for (nm=0; nm<nAnz; nm++)
199 { // Ordnums muessen alle stimmen!
200 GetMarkedObjectByIndex(nm)->GetOrdNum();
203 BOOL bChg=FALSE;
204 SdrObjList* pOL0=NULL;
205 ULONG nNewPos=0;
206 for (nm=0; nm<nAnz; nm++)
208 SdrMark* pM=GetSdrMarkByIndex(nm);
209 SdrObject* pObj=pM->GetMarkedSdrObj();
210 SdrObjList* pOL=pObj->GetObjList();
211 if (pOL!=pOL0)
213 nNewPos=0;
214 pOL0=pOL;
216 ULONG nNowPos=pObj->GetOrdNumDirect();
217 const Rectangle& rBR=pObj->GetCurrentBoundRect();
218 ULONG nCmpPos=nNowPos; if (nCmpPos>0) nCmpPos--;
219 SdrObject* pMaxObj=GetMaxToBtmObj(pObj);
220 if (pMaxObj!=NULL)
222 ULONG nMinPos=pMaxObj->GetOrdNum()+1;
223 if (nNewPos<nMinPos)
224 nNewPos=nMinPos; // diesen nicht ueberholen.
225 if (nNewPos>nNowPos)
226 nNewPos=nNowPos; // aber dabei auch nicht in die falsche Richtung schieben
228 BOOL bEnd=FALSE;
229 // nNewPos ist an dieser Stelle noch die maximale Position,
230 // an der das Obj hinruecken darf, ohne seinen Vorgaenger
231 // (Mehrfachselektion) zu ueberholen.
232 while (nCmpPos>nNewPos && !bEnd)
234 SdrObject* pCmpObj=pOL->GetObj(nCmpPos);
235 if (pCmpObj==NULL)
237 DBG_ERROR("MovMarkedToBtm(): Vergleichsobjekt nicht gefunden");
238 bEnd=TRUE;
240 else if (pCmpObj==pMaxObj)
242 nNewPos=nCmpPos;
243 nNewPos++;
244 bEnd=TRUE;
246 else if (rBR.IsOver(pCmpObj->GetCurrentBoundRect()))
248 nNewPos=nCmpPos;
249 bEnd=TRUE;
251 else
253 nCmpPos--;
256 if (nNowPos!=nNewPos)
258 bChg=TRUE;
259 pOL->SetObjectOrdNum(nNowPos,nNewPos);
260 if( bUndo )
261 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj,nNowPos,nNewPos));
262 ObjOrderChanged(pObj,nNowPos,nNewPos);
264 nNewPos++;
267 if(bUndo)
268 EndUndo();
270 if(bChg)
271 MarkListHasChanged();
275 void SdrEditView::PutMarkedToTop()
277 PutMarkedInFrontOfObj(NULL);
280 void SdrEditView::PutMarkedInFrontOfObj(const SdrObject* pRefObj)
282 ULONG nAnz=GetMarkedObjectCount();
283 if (nAnz!=0)
285 const bool bUndo = IsUndoEnabled();
286 if( bUndo )
287 BegUndo(ImpGetResStr(STR_EditPutToTop),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_PUTTOTOP);
289 SortMarkedObjects();
291 if (pRefObj!=NULL)
293 // Damit "Vor das Objekt" auch funktioniert wenn die
294 // markierten Objekte bereits vor dem Objekt stehen
295 ULONG nRefMark=TryToFindMarkedObject(pRefObj);
296 SdrMark aRefMark;
297 if (nRefMark!=CONTAINER_ENTRY_NOTFOUND)
299 aRefMark=*GetSdrMarkByIndex(nRefMark);
300 GetMarkedObjectListWriteAccess().DeleteMark(nRefMark);
302 PutMarkedToBtm();
303 if (nRefMark!=CONTAINER_ENTRY_NOTFOUND)
305 GetMarkedObjectListWriteAccess().InsertEntry(aRefMark);
306 SortMarkedObjects();
309 ULONG nm;
310 for (nm=0; nm<nAnz; nm++)
311 { // Ordnums muessen alle stimmen!
312 GetMarkedObjectByIndex(nm)->GetOrdNum();
314 BOOL bChg=FALSE;
315 SdrObjList* pOL0=NULL;
316 ULONG nNewPos=0;
317 for (nm=nAnz; nm>0;)
319 nm--;
320 SdrMark* pM=GetSdrMarkByIndex(nm);
321 SdrObject* pObj=pM->GetMarkedSdrObj();
322 if (pObj!=pRefObj)
324 SdrObjList* pOL=pObj->GetObjList();
325 if (pOL!=pOL0)
327 nNewPos=ULONG(pOL->GetObjCount()-1);
328 pOL0=pOL;
330 ULONG nNowPos=pObj->GetOrdNumDirect();
331 SdrObject* pMaxObj=GetMaxToTopObj(pObj);
332 if (pMaxObj!=NULL)
334 ULONG nMaxOrd=pMaxObj->GetOrdNum(); // geht leider nicht anders
335 if (nMaxOrd>0)
336 nMaxOrd--;
337 if (nNewPos>nMaxOrd)
338 nNewPos=nMaxOrd; // nicht ueberholen.
339 if (nNewPos<nNowPos)
340 nNewPos=nNowPos; // aber dabei auch nicht in die falsche Richtung schieben
342 if (pRefObj!=NULL)
344 if (pRefObj->GetObjList()==pObj->GetObjList())
346 ULONG nMaxOrd=pRefObj->GetOrdNum(); // geht leider nicht anders
347 if (nNewPos>nMaxOrd)
348 nNewPos=nMaxOrd; // nicht ueberholen.
349 if (nNewPos<nNowPos)
350 nNewPos=nNowPos; // aber dabei auch nicht in die falsche Richtung schieben
352 else
354 nNewPos=nNowPos; // andere PageView, also nicht veraendern
357 if (nNowPos!=nNewPos)
359 bChg=TRUE;
360 pOL->SetObjectOrdNum(nNowPos,nNewPos);
361 if( bUndo )
362 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj,nNowPos,nNewPos));
363 ObjOrderChanged(pObj,nNowPos,nNewPos);
365 nNewPos--;
366 } // if (pObj!=pRefObj)
367 } // for-Schleife ueber alle Markierten Objekte
369 if( bUndo )
370 EndUndo();
372 if(bChg)
373 MarkListHasChanged();
377 void SdrEditView::PutMarkedToBtm()
379 PutMarkedBehindObj(NULL);
382 void SdrEditView::PutMarkedBehindObj(const SdrObject* pRefObj)
384 ULONG nAnz=GetMarkedObjectCount();
385 if (nAnz!=0)
387 const bool bUndo = IsUndoEnabled();
389 if( bUndo )
390 BegUndo(ImpGetResStr(STR_EditPutToBtm),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_PUTTOBTM);
392 SortMarkedObjects();
393 if (pRefObj!=NULL)
395 // Damit "Hinter das Objekt" auch funktioniert wenn die
396 // markierten Objekte bereits hinter dem Objekt stehen
397 ULONG nRefMark=TryToFindMarkedObject(pRefObj);
398 SdrMark aRefMark;
399 if (nRefMark!=CONTAINER_ENTRY_NOTFOUND)
401 aRefMark=*GetSdrMarkByIndex(nRefMark);
402 GetMarkedObjectListWriteAccess().DeleteMark(nRefMark);
404 PutMarkedToTop();
405 if (nRefMark!=CONTAINER_ENTRY_NOTFOUND)
407 GetMarkedObjectListWriteAccess().InsertEntry(aRefMark);
408 SortMarkedObjects();
411 ULONG nm;
412 for (nm=0; nm<nAnz; nm++) { // Ordnums muessen alle stimmen!
413 GetMarkedObjectByIndex(nm)->GetOrdNum();
415 BOOL bChg=FALSE;
416 SdrObjList* pOL0=NULL;
417 ULONG nNewPos=0;
418 for (nm=0; nm<nAnz; nm++) {
419 SdrMark* pM=GetSdrMarkByIndex(nm);
420 SdrObject* pObj=pM->GetMarkedSdrObj();
421 if (pObj!=pRefObj) {
422 SdrObjList* pOL=pObj->GetObjList();
423 if (pOL!=pOL0) {
424 nNewPos=0;
425 pOL0=pOL;
427 ULONG nNowPos=pObj->GetOrdNumDirect();
428 SdrObject* pMinObj=GetMaxToBtmObj(pObj);
429 if (pMinObj!=NULL) {
430 ULONG nMinOrd=pMinObj->GetOrdNum()+1; // geht leider nicht anders
431 if (nNewPos<nMinOrd) nNewPos=nMinOrd; // nicht ueberholen.
432 if (nNewPos>nNowPos) nNewPos=nNowPos; // aber dabei auch nicht in die falsche Richtung schieben
434 if (pRefObj!=NULL) {
435 if (pRefObj->GetObjList()==pObj->GetObjList()) {
436 ULONG nMinOrd=pRefObj->GetOrdNum(); // geht leider nicht anders
437 if (nNewPos<nMinOrd) nNewPos=nMinOrd; // nicht ueberholen.
438 if (nNewPos>nNowPos) nNewPos=nNowPos; // aber dabei auch nicht in die falsche Richtung schieben
439 } else {
440 nNewPos=nNowPos; // andere PageView, also nicht veraendern
443 if (nNowPos!=nNewPos) {
444 bChg=TRUE;
445 pOL->SetObjectOrdNum(nNowPos,nNewPos);
446 if( bUndo )
447 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj,nNowPos,nNewPos));
448 ObjOrderChanged(pObj,nNowPos,nNewPos);
450 nNewPos++;
451 } // if (pObj!=pRefObj)
452 } // for-Schleife ueber alle markierten Objekte
454 if(bUndo)
455 EndUndo();
457 if(bChg)
458 MarkListHasChanged();
462 void SdrEditView::ReverseOrderOfMarked()
464 SortMarkedObjects();
465 ULONG nMarkAnz=GetMarkedObjectCount();
466 if (nMarkAnz>0)
468 //BOOL bNeedBundle=FALSE;
469 BOOL bChg=FALSE;
471 bool bUndo = IsUndoEnabled();
472 if( bUndo )
473 BegUndo(ImpGetResStr(STR_EditRevOrder),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_REVORDER);
475 ULONG a=0;
476 do {
477 // Markierung ueber mehrere PageViews berueksichtigen
478 ULONG b=a+1;
479 while (b<nMarkAnz && GetSdrPageViewOfMarkedByIndex(b) == GetSdrPageViewOfMarkedByIndex(a)) b++;
480 b--;
481 SdrObjList* pOL=GetSdrPageViewOfMarkedByIndex(a)->GetObjList();
482 ULONG c=b;
483 if (a<c) { // Sicherstellen, dass die OrdNums nicht Dirty sind
484 GetMarkedObjectByIndex(a)->GetOrdNum();
486 while (a<c) {
487 SdrObject* pObj1=GetMarkedObjectByIndex(a);
488 SdrObject* pObj2=GetMarkedObjectByIndex(c);
489 ULONG nOrd1=pObj1->GetOrdNumDirect();
490 ULONG nOrd2=pObj2->GetOrdNumDirect();
491 if( bUndo )
493 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj1,nOrd1,nOrd2));
494 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj2,nOrd2-1,nOrd1));
496 pOL->SetObjectOrdNum(nOrd1,nOrd2);
497 // Obj 2 ist um eine Position nach vorn gerutscht, deshalb nun nOrd2-1
498 pOL->SetObjectOrdNum(nOrd2-1,nOrd1);
499 // Verwendung von Replace statt SetOrdNum wg. Performance (Neuberechnung der Ordnums)
500 a++; c--;
501 bChg=TRUE;
503 a=b+1;
504 } while (a<nMarkAnz);
506 if(bUndo)
507 EndUndo();
509 if(bChg)
510 MarkListHasChanged();
514 void SdrEditView::ImpCheckToTopBtmPossible()
516 ULONG nAnz=GetMarkedObjectCount();
517 if (nAnz==0)
518 return;
519 if (nAnz==1)
520 { // Sonderbehandlung fuer Einzelmarkierung
521 SdrObject* pObj=GetMarkedObjectByIndex(0);
522 SdrObjList* pOL=pObj->GetObjList();
523 ULONG nMax=pOL->GetObjCount();
524 ULONG nMin=0;
525 ULONG nObjNum=pObj->GetOrdNum();
526 SdrObject* pRestrict=GetMaxToTopObj(pObj);
527 if (pRestrict!=NULL) {
528 ULONG nRestrict=pRestrict->GetOrdNum();
529 if (nRestrict<nMax) nMax=nRestrict;
531 pRestrict=GetMaxToBtmObj(pObj);
532 if (pRestrict!=NULL) {
533 ULONG nRestrict=pRestrict->GetOrdNum();
534 if (nRestrict>nMin) nMin=nRestrict;
536 bToTopPossible=nObjNum<ULONG(nMax-1);
537 bToBtmPossible=nObjNum>nMin;
538 } else { // Mehrfachselektion
539 ULONG nm=0;
540 SdrObjList* pOL0=NULL;
541 long nPos0=-1;
542 while (!bToBtmPossible && nm<nAnz) { // 'nach hinten' checken
543 SdrObject* pObj=GetMarkedObjectByIndex(nm);
544 SdrObjList* pOL=pObj->GetObjList();
545 if (pOL!=pOL0) {
546 nPos0=-1;
547 pOL0=pOL;
549 ULONG nPos=pObj->GetOrdNum();
550 bToBtmPossible=nPos>ULONG(nPos0+1);
551 nPos0=long(nPos);
552 nm++;
554 nm=nAnz;
555 pOL0=NULL;
556 nPos0=0x7FFFFFFF;
557 while (!bToTopPossible && nm>0) { // 'nach vorn' checken
558 nm--;
559 SdrObject* pObj=GetMarkedObjectByIndex(nm);
560 SdrObjList* pOL=pObj->GetObjList();
561 if (pOL!=pOL0) {
562 nPos0=pOL->GetObjCount();
563 pOL0=pOL;
565 ULONG nPos=pObj->GetOrdNum();
566 bToTopPossible=nPos+1<ULONG(nPos0);
567 nPos0=nPos;
572 ////////////////////////////////////////////////////////////////////////////////////////////////////
574 // @@@@ @@@@ @@ @@ @@@@@ @@ @@ @@ @@@@@
575 // @@ @@ @@ @@ @@@ @@@ @@ @@ @@ @@@ @@ @@
576 // @@ @@ @@ @@@@@@@ @@ @@ @@ @@@@@@ @@
577 // @@ @@ @@ @@@@@@@ @@@@@ @@ @@@@@@ @@@@
578 // @@ @@ @@ @@ @ @@ @@ @@ @@ @@ @@@ @@
579 // @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
580 // @@@@ @@@@ @@ @@ @@@@@ @@ @@ @@ @@@@@
582 ////////////////////////////////////////////////////////////////////////////////////////////////////
584 void SdrEditView::ImpCopyAttributes(const SdrObject* pSource, SdrObject* pDest) const
586 if (pSource!=NULL) {
587 SdrObjList* pOL=pSource->GetSubList();
588 if (pOL!=NULL && !pSource->Is3DObj()) { // erstes Nichtgruppenobjekt aus der Gruppe holen
589 SdrObjListIter aIter(*pOL,IM_DEEPNOGROUPS);
590 pSource=aIter.Next();
594 if(pSource && pDest)
596 SfxItemSet aSet(pMod->GetItemPool(),
597 SDRATTR_START, SDRATTR_NOTPERSIST_FIRST-1,
598 SDRATTR_NOTPERSIST_LAST+1, SDRATTR_END,
599 EE_ITEMS_START, EE_ITEMS_END,
600 0, 0); // #52757#, #52762#
602 aSet.Put(pSource->GetMergedItemSet());
604 pDest->ClearMergedItem();
605 pDest->SetMergedItemSet(aSet);
607 pDest->NbcSetLayer(pSource->GetLayer());
608 pDest->NbcSetStyleSheet(pSource->GetStyleSheet(), sal_True);
612 sal_Bool SdrEditView::ImpCanConvertForCombine1(const SdrObject* pObj) const
614 // #69711 : new condition IsLine() to be able to combine simple Lines
615 sal_Bool bIsLine(sal_False);
617 const SdrPathObj* pPath = PTR_CAST(SdrPathObj,pObj);
619 if(pPath)
621 bIsLine = pPath->IsLine();
624 SdrObjTransformInfoRec aInfo;
625 pObj->TakeObjInfo(aInfo);
627 return (aInfo.bCanConvToPath || aInfo.bCanConvToPoly || bIsLine);
630 sal_Bool SdrEditView::ImpCanConvertForCombine(const SdrObject* pObj) const
632 SdrObjList* pOL = pObj->GetSubList();
634 if(pOL && !pObj->Is3DObj())
636 SdrObjListIter aIter(*pOL, IM_DEEPNOGROUPS);
638 while(aIter.IsMore())
640 SdrObject* pObj1 = aIter.Next();
642 // Es muessen alle Member einer Gruppe konvertierbar sein
643 if(!ImpCanConvertForCombine1(pObj1))
645 return sal_False;
649 else
651 if(!ImpCanConvertForCombine1(pObj))
653 return sal_False;
657 return sal_True;
660 basegfx::B2DPolyPolygon SdrEditView::ImpGetPolyPolygon1(const SdrObject* pObj, sal_Bool bCombine) const
662 basegfx::B2DPolyPolygon aRetval;
663 SdrPathObj* pPath = PTR_CAST(SdrPathObj, pObj);
665 if(bCombine && pPath && !pObj->GetOutlinerParaObject())
667 aRetval = pPath->GetPathPoly();
669 else
671 SdrObject* pConvObj = pObj->ConvertToPolyObj(bCombine, sal_False);
673 if(pConvObj)
675 SdrObjList* pOL = pConvObj->GetSubList();
677 if(pOL)
679 SdrObjListIter aIter(*pOL, IM_DEEPNOGROUPS);
681 while(aIter.IsMore())
683 SdrObject* pObj1 = aIter.Next();
684 pPath = PTR_CAST(SdrPathObj, pObj1);
686 if(pPath)
688 aRetval.append(pPath->GetPathPoly());
692 else
694 pPath = PTR_CAST(SdrPathObj, pConvObj);
696 if(pPath)
698 aRetval = pPath->GetPathPoly();
702 SdrObject::Free( pConvObj );
706 return aRetval;
709 basegfx::B2DPolyPolygon SdrEditView::ImpGetPolyPolygon(const SdrObject* pObj, sal_Bool bCombine) const
711 SdrObjList* pOL = pObj->GetSubList();
713 if(pOL && !pObj->Is3DObj())
715 basegfx::B2DPolyPolygon aRetval;
716 SdrObjListIter aIter(*pOL, IM_DEEPNOGROUPS);
718 while(aIter.IsMore())
720 SdrObject* pObj1 = aIter.Next();
721 aRetval.append(ImpGetPolyPolygon1(pObj1, bCombine));
724 return aRetval;
726 else
728 return ImpGetPolyPolygon1(pObj, bCombine);
732 basegfx::B2DPolygon SdrEditView::ImpCombineToSinglePolygon(const basegfx::B2DPolyPolygon& rPolyPolygon) const
734 const sal_uInt32 nPolyCount(rPolyPolygon.count());
736 if(0L == nPolyCount)
738 return basegfx::B2DPolygon();
740 else if(1L == nPolyCount)
742 return rPolyPolygon.getB2DPolygon(0L);
744 else
746 basegfx::B2DPolygon aRetval(rPolyPolygon.getB2DPolygon(0L));
748 for(sal_uInt32 a(1L); a < nPolyCount; a++)
750 basegfx::B2DPolygon aCandidate(rPolyPolygon.getB2DPolygon(a));
752 if(aRetval.count())
754 if(aCandidate.count())
756 const basegfx::B2DPoint aCA(aCandidate.getB2DPoint(0L));
757 const basegfx::B2DPoint aCB(aCandidate.getB2DPoint(aCandidate.count() - 1L));
758 const basegfx::B2DPoint aRA(aRetval.getB2DPoint(0L));
759 const basegfx::B2DPoint aRB(aRetval.getB2DPoint(aRetval.count() - 1L));
761 const double fRACA(basegfx::B2DVector(aCA - aRA).getLength());
762 const double fRACB(basegfx::B2DVector(aCB - aRA).getLength());
763 const double fRBCA(basegfx::B2DVector(aCA - aRB).getLength());
764 const double fRBCB(basegfx::B2DVector(aCB - aRB).getLength());
766 const double fSmallestRA(fRACA < fRACB ? fRACA : fRACB);
767 const double fSmallestRB(fRBCA < fRBCB ? fRBCA : fRBCB);
769 if(fSmallestRA < fSmallestRB)
771 // flip result
772 aRetval.flip();
775 const double fSmallestCA(fRACA < fRBCA ? fRACA : fRBCA);
776 const double fSmallestCB(fRACB < fRBCB ? fRACB : fRBCB);
778 if(fSmallestCB < fSmallestCA)
780 // flip candidate
781 aCandidate.flip();
784 // append candidate to retval
785 aRetval.append(aCandidate);
788 else
790 aRetval = aCandidate;
794 return aRetval;
798 // for distribution dialog function
799 struct ImpDistributeEntry
801 SdrObject* mpObj;
802 INT32 mnPos;
803 INT32 mnLength;
806 DECLARE_LIST(ImpDistributeEntryList, ImpDistributeEntry*)
808 void SdrEditView::DistributeMarkedObjects()
810 UINT32 nMark(GetMarkedObjectCount());
812 if(nMark > 2)
814 SfxItemSet aNewAttr(pMod->GetItemPool());
815 //CHINA001 SvxDistributeDialog* pDlg = new SvxDistributeDialog(NULL, aNewAttr);
816 SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
817 if(pFact)
819 AbstractSvxDistributeDialog *pDlg = pFact->CreateSvxDistributeDialog(NULL, aNewAttr, RID_SVXPAGE_DISTRIBUTE);
820 DBG_ASSERT(pDlg, "Dialogdiet fail!");//CHINA001
822 UINT16 nResult = pDlg->Execute();
824 if(nResult == RET_OK)
826 SvxDistributeHorizontal eHor = pDlg->GetDistributeHor();
827 SvxDistributeVertical eVer = pDlg->GetDistributeVer();
828 ImpDistributeEntryList aEntryList;
829 UINT32 a, nInsPos, nFullLength;
831 const bool bUndo = IsUndoEnabled();
832 if( bUndo )
833 BegUndo();
835 if(eHor != SvxDistributeHorizontalNone)
837 // build sorted entry list
838 nFullLength = 0L;
840 for(a=0;a<nMark;a++)
842 SdrMark* pMark = GetSdrMarkByIndex(a);
843 ImpDistributeEntry* pNew = new ImpDistributeEntry;
845 pNew->mpObj = pMark->GetMarkedSdrObj();
846 nInsPos = 0;
848 switch(eHor)
850 case SvxDistributeHorizontalLeft:
852 pNew->mnPos = pNew->mpObj->GetSnapRect().Left();
853 break;
855 case SvxDistributeHorizontalCenter:
857 pNew->mnPos = (pNew->mpObj->GetSnapRect().Right() + pNew->mpObj->GetSnapRect().Left()) / 2;
858 break;
860 case SvxDistributeHorizontalDistance:
862 pNew->mnLength = pNew->mpObj->GetSnapRect().GetWidth() + 1;
863 nFullLength += pNew->mnLength;
864 pNew->mnPos = (pNew->mpObj->GetSnapRect().Right() + pNew->mpObj->GetSnapRect().Left()) / 2;
865 break;
867 case SvxDistributeHorizontalRight:
869 pNew->mnPos = pNew->mpObj->GetSnapRect().Right();
870 break;
872 default: break;
875 while(nInsPos < aEntryList.Count() && aEntryList.GetObject(nInsPos)->mnPos < pNew->mnPos)
876 nInsPos++;
878 aEntryList.Insert(pNew, nInsPos);
881 if(eHor == SvxDistributeHorizontalDistance)
883 // calc room in-between
884 INT32 nWidth = GetAllMarkedBoundRect().GetWidth() + 1;
885 double fStepWidth = ((double)nWidth - (double)nFullLength) / (double)(aEntryList.Count() - 1);
886 double fStepStart = (double)aEntryList.GetObject(0)->mnPos;
887 fStepStart += fStepWidth + (double)((aEntryList.GetObject(0)->mnLength + aEntryList.GetObject(1)->mnLength) / 2);
889 // move entries 1..n-1
890 for(a=1;a<aEntryList.Count()-1;a++)
892 ImpDistributeEntry* pCurr = aEntryList.GetObject(a);
893 ImpDistributeEntry* pNext = aEntryList.GetObject(a+1);
894 INT32 nDelta = (INT32)(fStepStart + 0.5) - pCurr->mnPos;
895 if( bUndo )
896 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pCurr->mpObj));
897 pCurr->mpObj->Move(Size(nDelta, 0));
898 fStepStart += fStepWidth + (double)((pCurr->mnLength + pNext->mnLength) / 2);
901 else
903 // calc distances
904 INT32 nWidth = aEntryList.GetObject(aEntryList.Count() - 1)->mnPos - aEntryList.GetObject(0)->mnPos;
905 double fStepWidth = (double)nWidth / (double)(aEntryList.Count() - 1);
906 double fStepStart = (double)aEntryList.GetObject(0)->mnPos;
907 fStepStart += fStepWidth;
909 // move entries 1..n-1
910 for(a=1;a<aEntryList.Count()-1;a++)
912 ImpDistributeEntry* pCurr = aEntryList.GetObject(a);
913 INT32 nDelta = (INT32)(fStepStart + 0.5) - pCurr->mnPos;
914 if( bUndo )
915 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pCurr->mpObj));
916 pCurr->mpObj->Move(Size(nDelta, 0));
917 fStepStart += fStepWidth;
921 // clear list
922 while(aEntryList.Count())
923 delete aEntryList.Remove((ULONG)0L);
926 if(eVer != SvxDistributeVerticalNone)
928 // build sorted entry list
929 nFullLength = 0L;
931 for(a=0;a<nMark;a++)
933 SdrMark* pMark = GetSdrMarkByIndex(a);
934 ImpDistributeEntry* pNew = new ImpDistributeEntry;
936 pNew->mpObj = pMark->GetMarkedSdrObj();
937 nInsPos = 0;
939 switch(eVer)
941 case SvxDistributeVerticalTop:
943 pNew->mnPos = pNew->mpObj->GetSnapRect().Top();
944 break;
946 case SvxDistributeVerticalCenter:
948 pNew->mnPos = (pNew->mpObj->GetSnapRect().Bottom() + pNew->mpObj->GetSnapRect().Top()) / 2;
949 break;
951 case SvxDistributeVerticalDistance:
953 pNew->mnLength = pNew->mpObj->GetSnapRect().GetHeight() + 1;
954 nFullLength += pNew->mnLength;
955 pNew->mnPos = (pNew->mpObj->GetSnapRect().Bottom() + pNew->mpObj->GetSnapRect().Top()) / 2;
956 break;
958 case SvxDistributeVerticalBottom:
960 pNew->mnPos = pNew->mpObj->GetSnapRect().Bottom();
961 break;
963 default: break;
966 while(nInsPos < aEntryList.Count() && aEntryList.GetObject(nInsPos)->mnPos < pNew->mnPos)
967 nInsPos++;
969 aEntryList.Insert(pNew, nInsPos);
972 if(eVer == SvxDistributeVerticalDistance)
974 // calc room in-between
975 INT32 nHeight = GetAllMarkedBoundRect().GetHeight() + 1;
976 double fStepWidth = ((double)nHeight - (double)nFullLength) / (double)(aEntryList.Count() - 1);
977 double fStepStart = (double)aEntryList.GetObject(0)->mnPos;
978 fStepStart += fStepWidth + (double)((aEntryList.GetObject(0)->mnLength + aEntryList.GetObject(1)->mnLength) / 2);
980 // move entries 1..n-1
981 for(a=1;a<aEntryList.Count()-1;a++)
983 ImpDistributeEntry* pCurr = aEntryList.GetObject(a);
984 ImpDistributeEntry* pNext = aEntryList.GetObject(a+1);
985 INT32 nDelta = (INT32)(fStepStart + 0.5) - pCurr->mnPos;
986 if( bUndo )
987 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pCurr->mpObj));
988 pCurr->mpObj->Move(Size(0, nDelta));
989 fStepStart += fStepWidth + (double)((pCurr->mnLength + pNext->mnLength) / 2);
992 else
994 // calc distances
995 INT32 nHeight = aEntryList.GetObject(aEntryList.Count() - 1)->mnPos - aEntryList.GetObject(0)->mnPos;
996 double fStepWidth = (double)nHeight / (double)(aEntryList.Count() - 1);
997 double fStepStart = (double)aEntryList.GetObject(0)->mnPos;
998 fStepStart += fStepWidth;
1000 // move entries 1..n-1
1001 for(a=1;a<aEntryList.Count()-1;a++)
1003 ImpDistributeEntry* pCurr = aEntryList.GetObject(a);
1004 INT32 nDelta = (INT32)(fStepStart + 0.5) - pCurr->mnPos;
1005 if( bUndo )
1006 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pCurr->mpObj));
1007 pCurr->mpObj->Move(Size(0, nDelta));
1008 fStepStart += fStepWidth;
1012 // clear list
1013 while(aEntryList.Count())
1014 delete aEntryList.Remove((ULONG)0L);
1017 // UNDO-Comment and end of UNDO
1018 SetUndoComment(ImpGetResStr(STR_DistributeMarkedObjects));
1020 if( bUndo )
1021 EndUndo();
1024 delete(pDlg);
1029 void SdrEditView::MergeMarkedObjects(SdrMergeMode eMode)
1031 // #i73441# check content
1032 if(AreObjectsMarked())
1034 SdrMarkList aRemove;
1035 SortMarkedObjects();
1037 const bool bUndo = IsUndoEnabled();
1039 if( bUndo )
1040 BegUndo();
1042 UINT32 nInsPos=0xFFFFFFFF;
1043 const SdrObject* pAttrObj = NULL;
1044 basegfx::B2DPolyPolygon aMergePolyPolygonA;
1045 basegfx::B2DPolyPolygon aMergePolyPolygonB;
1047 SdrObjList* pInsOL = NULL;
1048 SdrPageView* pInsPV = NULL;
1049 BOOL bFirstObjectComplete(FALSE);
1051 // make sure selected objects are contour objects
1052 // since now basegfx::tools::adaptiveSubdivide() is used, it is no longer
1053 // necessary to use ConvertMarkedToPolyObj which will subdivide curves using the old
1054 // mechanisms. In a next step the polygon clipper will even be able to clip curves...
1055 // ConvertMarkedToPolyObj(TRUE);
1056 ConvertMarkedToPathObj(sal_True);
1057 OSL_ENSURE(AreObjectsMarked(), "no more objects selected after preparations (!)");
1059 for(UINT32 a=0;a<GetMarkedObjectCount();a++)
1061 SdrMark* pM = GetSdrMarkByIndex(a);
1062 SdrObject* pObj = pM->GetMarkedSdrObj();
1064 if(ImpCanConvertForCombine(pObj))
1066 if(!pAttrObj)
1067 pAttrObj = pObj;
1069 nInsPos = pObj->GetOrdNum() + 1;
1070 pInsPV = pM->GetPageView();
1071 pInsOL = pObj->GetObjList();
1073 // #i76891# use single iter from SJ here whcih works on SdrObjects and takes
1074 // groups into account by itself
1075 SdrObjListIter aIter(*pObj, IM_DEEPWITHGROUPS);
1077 while(aIter.IsMore())
1079 SdrObject* pCandidate = aIter.Next();
1080 SdrPathObj* pPathObj = PTR_CAST(SdrPathObj, pCandidate);
1081 if(pPathObj)
1083 basegfx::B2DPolyPolygon aTmpPoly(pPathObj->GetPathPoly());
1085 // #i76891# unfortunately ConvertMarkedToPathObj has converted all
1086 // involved polygon data to curve segments, even if not necessary.
1087 // It is better to try to reduce to more simple polygons.
1088 aTmpPoly = basegfx::tools::simplifyCurveSegments(aTmpPoly);
1090 // for each part polygon as preparation, remove self-intersections
1091 // correct orientations and get rid of evtl. neutral polygons.
1092 aTmpPoly = basegfx::tools::prepareForPolygonOperation(aTmpPoly);
1094 if(!bFirstObjectComplete)
1096 aMergePolyPolygonA = aTmpPoly;
1098 else
1100 if(aMergePolyPolygonB.count())
1102 // to topologically correctly collect the 2nd polygon
1103 // group it is necessary to OR the parts (each is seen as
1104 // XOR-FillRule polygon and they are drawn over each-other)
1105 aMergePolyPolygonB = basegfx::tools::solvePolygonOperationOr(aMergePolyPolygonB, aTmpPoly);
1107 else
1109 aMergePolyPolygonB = aTmpPoly;
1115 // was there something added to the first poly?
1116 if(!bFirstObjectComplete && aMergePolyPolygonA.count())
1118 bFirstObjectComplete = TRUE;
1121 // move object to temporary delete list
1122 aRemove.InsertEntry(SdrMark(pObj, pM->GetPageView()));
1126 switch(eMode)
1128 case SDR_MERGE_MERGE:
1130 // merge all contained parts (OR)
1131 static bool bTestXOR(false);
1132 if(bTestXOR)
1134 aMergePolyPolygonA = basegfx::tools::solvePolygonOperationXor(aMergePolyPolygonA, aMergePolyPolygonB);
1136 else
1138 aMergePolyPolygonA = basegfx::tools::solvePolygonOperationOr(aMergePolyPolygonA, aMergePolyPolygonB);
1140 break;
1142 case SDR_MERGE_SUBSTRACT:
1144 // Substract B from A
1145 aMergePolyPolygonA = basegfx::tools::solvePolygonOperationDiff(aMergePolyPolygonA, aMergePolyPolygonB);
1146 break;
1148 case SDR_MERGE_INTERSECT:
1150 // AND B and A
1151 aMergePolyPolygonA = basegfx::tools::solvePolygonOperationAnd(aMergePolyPolygonA, aMergePolyPolygonB);
1152 break;
1156 // #i73441# check insert list before taking actions
1157 if(pInsOL)
1159 SdrPathObj* pPath = new SdrPathObj(OBJ_PATHFILL, aMergePolyPolygonA);
1160 ImpCopyAttributes(pAttrObj, pPath);
1161 SdrInsertReason aReason(SDRREASON_VIEWCALL, pAttrObj);
1162 pInsOL->InsertObject(pPath, nInsPos, &aReason);
1163 if( bUndo )
1164 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pPath));
1165 MarkObj(pPath, pInsPV, FALSE, TRUE);
1168 aRemove.ForceSort();
1169 switch(eMode)
1171 case SDR_MERGE_MERGE:
1173 SetUndoComment(
1174 ImpGetResStr(STR_EditMergeMergePoly),
1175 aRemove.GetMarkDescription());
1176 break;
1178 case SDR_MERGE_SUBSTRACT:
1180 SetUndoComment(
1181 ImpGetResStr(STR_EditMergeSubstractPoly),
1182 aRemove.GetMarkDescription());
1183 break;
1185 case SDR_MERGE_INTERSECT:
1187 SetUndoComment(
1188 ImpGetResStr(STR_EditMergeIntersectPoly),
1189 aRemove.GetMarkDescription());
1190 break;
1193 DeleteMarkedList(aRemove);
1195 if( bUndo )
1196 EndUndo();
1200 void SdrEditView::CombineMarkedObjects(sal_Bool bNoPolyPoly)
1202 // #105899# Start of Combine-Undo put to front, else ConvertMarkedToPolyObj would
1203 // create a 2nd Undo-action and Undo-Comment.
1205 bool bUndo = IsUndoEnabled();
1207 // Undo-String will be set later
1208 if( bUndo )
1209 BegUndo(String(), String(), bNoPolyPoly ? SDRREPFUNC_OBJ_COMBINE_ONEPOLY : SDRREPFUNC_OBJ_COMBINE_POLYPOLY);
1211 // #105899# First, guarantee that all objects are converted to polyobjects,
1212 // especially for SdrGrafObj with bitmap filling this is necessary to not
1213 // loose the bitmap filling.
1215 // #i12392#
1216 // ConvertMarkedToPolyObj was too strong here, it will loose quality and
1217 // information when curve objects are combined. This can be replaced by
1218 // using ConvertMarkedToPathObj without changing the previous fix.
1220 // #i21250#
1221 // Instead of simply passing sal_True as LineToArea, use bNoPolyPoly as info
1222 // if this command is a 'Combine' or a 'Connect' command. On Connect it's sal_True.
1223 // To not concert line segments with a set line width to polygons in that case,
1224 // use this info. Do not convert LineToArea on Connect commands.
1225 // ConvertMarkedToPathObj(!bNoPolyPoly);
1227 // #114310#
1228 // This is used for Combine and Connect. In no case it is necessary to force
1229 // the content to curve, but it is also not good to force to polygons. Thus,
1230 // curve is the less information loosing one. Remember: This place is not
1231 // used for merge.
1232 // LineToArea is never necessary, both commands are able to take over the
1233 // set line style and to display it correctly. Thus, i will use a
1234 // ConvertMarkedToPathObj with a sal_False in any case. Only drawback is that
1235 // simple polygons will be changed to curves, but with no information loss.
1236 ConvertMarkedToPathObj(sal_False /* bLineToArea */);
1238 // continue as before
1239 basegfx::B2DPolyPolygon aPolyPolygon;
1240 SdrObjList* pAktOL = 0L;
1241 SdrMarkList aRemoveMerker;
1243 SortMarkedObjects();
1244 sal_uInt32 nInsPos(0xFFFFFFFF);
1245 SdrObjList* pInsOL = 0L;
1246 SdrPageView* pInsPV = 0L;
1247 const sal_uInt32 nAnz(GetMarkedObjectCount());
1248 const SdrObject* pAttrObj = 0L;
1250 for(sal_uInt32 a(nAnz); a > 0L; )
1252 a--;
1253 SdrMark* pM = GetSdrMarkByIndex(a);
1254 SdrObject* pObj = pM->GetMarkedSdrObj();
1255 SdrObjList* pThisOL = pObj->GetObjList();
1257 if(pAktOL != pThisOL)
1259 pAktOL = pThisOL;
1262 if(ImpCanConvertForCombine(pObj))
1264 // Obj merken fuer Attribute kopieren
1265 pAttrObj = pObj;
1267 // unfortunately ConvertMarkedToPathObj has converted all
1268 // involved polygon data to curve segments, even if not necessary.
1269 // It is better to try to reduce to more simple polygons.
1270 basegfx::B2DPolyPolygon aTmpPoly(basegfx::tools::simplifyCurveSegments(ImpGetPolyPolygon(pObj, sal_True)));
1271 aPolyPolygon.insert(0L, aTmpPoly);
1273 if(!pInsOL)
1275 nInsPos = pObj->GetOrdNum() + 1L;
1276 pInsPV = pM->GetPageView();
1277 pInsOL = pObj->GetObjList();
1280 aRemoveMerker.InsertEntry(SdrMark(pObj, pM->GetPageView()));
1284 if(bNoPolyPoly)
1286 basegfx::B2DPolygon aCombinedPolygon(ImpCombineToSinglePolygon(aPolyPolygon));
1287 aPolyPolygon.clear();
1288 aPolyPolygon.append(aCombinedPolygon);
1291 const sal_uInt32 nPolyCount(aPolyPolygon.count());
1293 if(nPolyCount)
1295 SdrObjKind eKind = OBJ_PATHFILL;
1297 if(nPolyCount > 1L)
1299 aPolyPolygon.setClosed(true);
1301 else
1303 // auf Polyline Checken
1304 const basegfx::B2DPolygon aPolygon(aPolyPolygon.getB2DPolygon(0L));
1305 const sal_uInt32 nPointCount(aPolygon.count());
1307 if(nPointCount <= 2L)
1309 eKind = OBJ_PATHLINE;
1311 else
1313 if(!aPolygon.isClosed())
1315 const basegfx::B2DPoint aPointA(aPolygon.getB2DPoint(0L));
1316 const basegfx::B2DPoint aPointB(aPolygon.getB2DPoint(nPointCount - 1L));
1317 const double fDistance(basegfx::B2DVector(aPointB - aPointA).getLength());
1318 const double fJoinTolerance(10.0);
1320 if(fDistance < fJoinTolerance)
1322 aPolyPolygon.setClosed(true);
1324 else
1326 eKind = OBJ_PATHLINE;
1332 SdrPathObj* pPath = new SdrPathObj(eKind,aPolyPolygon);
1334 // Attribute des untersten Objekts
1335 ImpCopyAttributes(pAttrObj, pPath);
1337 // #100408# If LineStyle of pAttrObj is XLINE_NONE force to XLINE_SOLID to make visible.
1338 const XLineStyle eLineStyle = ((const XLineStyleItem&)pAttrObj->GetMergedItem(XATTR_LINESTYLE)).GetValue();
1339 const XFillStyle eFillStyle = ((const XFillStyleItem&)pAttrObj->GetMergedItem(XATTR_FILLSTYLE)).GetValue();
1341 // #110635#
1342 // Take fill style/closed state of pAttrObj in account when deciding to change the line style
1343 sal_Bool bIsClosedPathObj(pAttrObj->ISA(SdrPathObj) && ((SdrPathObj*)pAttrObj)->IsClosed());
1345 if(XLINE_NONE == eLineStyle && (XFILL_NONE == eFillStyle || !bIsClosedPathObj))
1347 pPath->SetMergedItem(XLineStyleItem(XLINE_SOLID));
1350 SdrInsertReason aReason(SDRREASON_VIEWCALL,pAttrObj);
1351 pInsOL->InsertObject(pPath,nInsPos,&aReason);
1352 if( bUndo )
1353 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pPath));
1355 // #111111#
1356 // Here was a severe error: Without UnmarkAllObj, the new object was marked
1357 // additionally to the two ones which are deleted below. As long as those are
1358 // in the UNDO there is no problem, but as soon as they get deleted, the
1359 // MarkList will contain deleted objects -> GPF.
1360 UnmarkAllObj(pInsPV);
1361 MarkObj(pPath, pInsPV, FALSE, TRUE);
1364 // UndoComment aus den tatsaechlich verwendeten Objekten zusammenbauen
1365 aRemoveMerker.ForceSort(); // wichtig fuer Remove (s.u.)
1366 if( bUndo )
1367 SetUndoComment(ImpGetResStr(bNoPolyPoly?STR_EditCombine_OnePoly:STR_EditCombine_PolyPoly),aRemoveMerker.GetMarkDescription());
1369 // die tatsaechlich verwendeten Objekten aus der Liste entfernen
1370 DeleteMarkedList(aRemoveMerker);
1371 if( bUndo )
1372 EndUndo();
1375 ////////////////////////////////////////////////////////////////////////////////////////////////////
1377 // @@@@@ @@ @@@@ @@ @@ @@@@ @@ @@ @@@@@@ @@ @@@@@
1378 // @@ @@ @@ @@ @@ @@@ @@@ @@ @@ @@@ @@ @@ @@ @@
1379 // @@ @@ @@ @@ @@@@@@@ @@ @@ @@@@@@ @@ @@ @@
1380 // @@ @@ @@ @@@@ @@@@@@@ @@@@@@ @@@@@@ @@ @@ @@@@
1381 // @@ @@ @@ @@ @@ @ @@ @@ @@ @@ @@@ @@ @@ @@
1382 // @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
1383 // @@@@@ @@ @@@@ @@ @@ @@ @@ @@ @@ @@ @@@@@ @@@@@
1385 ////////////////////////////////////////////////////////////////////////////////////////////////////
1387 sal_Bool SdrEditView::ImpCanDismantle(const basegfx::B2DPolyPolygon& rPpolyPolygon, sal_Bool bMakeLines) const
1389 sal_Bool bCan(sal_False);
1390 const sal_uInt32 nPolygonCount(rPpolyPolygon.count());
1392 if(nPolygonCount >= 2L)
1394 // #i69172# dismantle makes sense with 2 or more polygons in a polyPolygon
1395 bCan = sal_True;
1397 else if(bMakeLines && 1L == nPolygonCount)
1399 // #i69172# ..or with at least 2 edges (curves or lines)
1400 const basegfx::B2DPolygon aPolygon(rPpolyPolygon.getB2DPolygon(0L));
1401 const sal_uInt32 nPointCount(aPolygon.count());
1403 if(nPointCount > 2L)
1405 bCan = sal_True;
1409 return bCan;
1412 sal_Bool SdrEditView::ImpCanDismantle(const SdrObject* pObj, sal_Bool bMakeLines) const
1414 sal_Bool bOtherObjs(sal_False); // TRUE=andere Objekte ausser PathObj's vorhanden
1415 sal_Bool bMin1PolyPoly(sal_False); // TRUE=mind. 1 PolyPolygon mit mehr als ein Polygon vorhanden
1416 SdrObjList* pOL = pObj->GetSubList();
1418 if(pOL)
1420 // Aha, Gruppenobjekt. Also alle Member ansehen.
1421 // Alle muessen PathObjs sein !
1422 SdrObjListIter aIter(*pOL, IM_DEEPNOGROUPS);
1424 while(aIter.IsMore() && !bOtherObjs)
1426 const SdrObject* pObj1 = aIter.Next();
1427 const SdrPathObj* pPath = PTR_CAST(SdrPathObj, pObj1);
1429 if(pPath)
1431 if(ImpCanDismantle(pPath->GetPathPoly(), bMakeLines))
1433 bMin1PolyPoly = sal_True;
1436 SdrObjTransformInfoRec aInfo;
1437 pObj1->TakeObjInfo(aInfo);
1439 if(!aInfo.bCanConvToPath)
1441 // Passiert z.B. im Falle Fontwork (Joe, 28-11-95)
1442 bOtherObjs = sal_True;
1445 else
1447 bOtherObjs = sal_True;
1451 else
1453 const SdrPathObj* pPath = PTR_CAST(SdrPathObj, pObj);
1454 const SdrObjCustomShape* pCustomShape = PTR_CAST(SdrObjCustomShape, pObj);
1456 // #i37011#
1457 if(pPath)
1459 if(ImpCanDismantle(pPath->GetPathPoly(),bMakeLines))
1461 bMin1PolyPoly = sal_True;
1464 SdrObjTransformInfoRec aInfo;
1465 pObj->TakeObjInfo(aInfo);
1467 // #69711 : new condition IsLine() to be able to break simple Lines
1468 if(!(aInfo.bCanConvToPath || aInfo.bCanConvToPoly) && !pPath->IsLine())
1470 // Passiert z.B. im Falle Fontwork (Joe, 28-11-95)
1471 bOtherObjs = sal_True;
1474 else if(pCustomShape)
1476 if(bMakeLines)
1478 // allow break command
1479 bMin1PolyPoly = sal_True;
1482 else
1484 bOtherObjs = sal_True;
1487 return bMin1PolyPoly && !bOtherObjs;
1490 void SdrEditView::ImpDismantleOneObject(const SdrObject* pObj, SdrObjList& rOL, ULONG& rPos, SdrPageView* pPV, BOOL bMakeLines)
1492 const SdrPathObj* pSrcPath = PTR_CAST(SdrPathObj, pObj);
1493 const SdrObjCustomShape* pCustomShape = PTR_CAST(SdrObjCustomShape, pObj);
1495 const bool bUndo = IsUndoEnabled();
1497 if(pSrcPath)
1499 // #i74631# redesigned due to XpolyPolygon removal and explicit constructors
1500 SdrObject* pLast = 0; // fuer die Zuweisung des OutlinerParaObject
1501 const basegfx::B2DPolyPolygon& rPolyPolygon(pSrcPath->GetPathPoly());
1502 const sal_uInt32 nPolyCount(rPolyPolygon.count());
1504 for(sal_uInt32 a(0); a < nPolyCount; a++)
1506 const basegfx::B2DPolygon& rCandidate(rPolyPolygon.getB2DPolygon(a));
1507 const sal_uInt32 nPointCount(rCandidate.count());
1509 if(!bMakeLines || nPointCount < 2)
1511 SdrPathObj* pPath = new SdrPathObj((SdrObjKind)pSrcPath->GetObjIdentifier(), basegfx::B2DPolyPolygon(rCandidate));
1512 ImpCopyAttributes(pSrcPath, pPath);
1513 pLast = pPath;
1514 SdrInsertReason aReason(SDRREASON_VIEWCALL, pSrcPath);
1515 rOL.InsertObject(pPath, rPos, &aReason);
1516 if( bUndo )
1517 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pPath, TRUE));
1518 MarkObj(pPath, pPV, FALSE, TRUE);
1519 rPos++;
1521 else
1523 const sal_uInt32 nLoopCount(rCandidate.isClosed() ? nPointCount : nPointCount - 1);
1525 for(sal_uInt32 b(0); b < nLoopCount; b++)
1527 SdrObjKind eKind(OBJ_PLIN);
1528 basegfx::B2DPolygon aNewPolygon;
1529 const sal_uInt32 nNextIndex((b + 1) % nPointCount);
1531 aNewPolygon.append(rCandidate.getB2DPoint(b));
1533 if(rCandidate.areControlPointsUsed())
1535 aNewPolygon.appendBezierSegment(
1536 rCandidate.getNextControlPoint(b),
1537 rCandidate.getPrevControlPoint(nNextIndex),
1538 rCandidate.getB2DPoint(nNextIndex));
1539 eKind = OBJ_PATHLINE;
1541 else
1543 aNewPolygon.append(rCandidate.getB2DPoint(nNextIndex));
1546 SdrPathObj* pPath = new SdrPathObj(eKind, basegfx::B2DPolyPolygon(aNewPolygon));
1547 ImpCopyAttributes(pSrcPath, pPath);
1548 pLast = pPath;
1549 SdrInsertReason aReason(SDRREASON_VIEWCALL, pSrcPath);
1550 rOL.InsertObject(pPath, rPos, &aReason);
1551 if( bUndo )
1552 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pPath, TRUE));
1553 MarkObj(pPath, pPV, FALSE, TRUE);
1554 rPos++;
1559 if(pLast && pSrcPath->GetOutlinerParaObject())
1561 pLast->SetOutlinerParaObject(new OutlinerParaObject(*pSrcPath->GetOutlinerParaObject()));
1564 else if(pCustomShape)
1566 if(bMakeLines)
1568 // break up custom shape
1569 const SdrObject* pReplacement = pCustomShape->GetSdrObjectFromCustomShape();
1571 if(pReplacement)
1573 SdrObject* pCandidate = pReplacement->Clone();
1574 DBG_ASSERT(pCandidate, "SdrEditView::ImpDismantleOneObject: Could not clone SdrObject (!)");
1575 pCandidate->SetModel(pCustomShape->GetModel());
1577 if(((SdrShadowItem&)pCustomShape->GetMergedItem(SDRATTR_SHADOW)).GetValue())
1579 if(pReplacement->ISA(SdrObjGroup))
1581 pCandidate->SetMergedItem(SdrShadowItem(sal_True));
1585 SdrInsertReason aReason(SDRREASON_VIEWCALL, pCustomShape);
1586 rOL.InsertObject(pCandidate, rPos, &aReason);
1587 if( bUndo )
1588 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pCandidate, true));
1589 MarkObj(pCandidate, pPV, FALSE, TRUE);
1591 if(pCustomShape->HasText() && !pCustomShape->IsTextPath())
1593 // #i37011# also create a text object and add at rPos + 1
1594 SdrTextObj* pTextObj = (SdrTextObj*)SdrObjFactory::MakeNewObject(
1595 pCustomShape->GetObjInventor(), OBJ_TEXT, 0L, pCustomShape->GetModel());
1597 // Copy text content
1598 OutlinerParaObject* pParaObj = pCustomShape->GetOutlinerParaObject();
1599 if(pParaObj)
1601 pTextObj->NbcSetOutlinerParaObject(new OutlinerParaObject(*pParaObj));
1604 // copy all attributes
1605 SfxItemSet aTargetItemSet(pCustomShape->GetMergedItemSet());
1607 // clear fill and line style
1608 aTargetItemSet.Put(XLineStyleItem(XLINE_NONE));
1609 aTargetItemSet.Put(XFillStyleItem(XFILL_NONE));
1611 // get the text bounds and set at text object
1612 Rectangle aTextBounds = pCustomShape->GetSnapRect();
1613 if(pCustomShape->GetTextBounds(aTextBounds))
1615 pTextObj->SetSnapRect(aTextBounds);
1618 // if rotated, copy GeoStat, too.
1619 const GeoStat& rSourceGeo = pCustomShape->GetGeoStat();
1620 if(rSourceGeo.nDrehWink)
1622 pTextObj->NbcRotate(
1623 pCustomShape->GetSnapRect().Center(), rSourceGeo.nDrehWink,
1624 rSourceGeo.nSin, rSourceGeo.nCos);
1627 // set modified ItemSet at text object
1628 pTextObj->SetMergedItemSet(aTargetItemSet);
1630 // insert object
1631 rOL.InsertObject(pTextObj, rPos + 1, &aReason);
1632 if( bUndo )
1633 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pTextObj, true));
1634 MarkObj(pTextObj, pPV, FALSE, TRUE);
1641 void SdrEditView::DismantleMarkedObjects(BOOL bMakeLines)
1643 //UINT32 nCnt(0);
1644 // Temporaere Marklist
1645 SdrMarkList aRemoveMerker;
1647 SortMarkedObjects();
1649 const bool bUndo = IsUndoEnabled();
1651 if( bUndo )
1653 // Der Comment wird spaeter zusammengebaut
1654 BegUndo(String(), String(),
1655 bMakeLines ? SDRREPFUNC_OBJ_DISMANTLE_LINES : SDRREPFUNC_OBJ_DISMANTLE_POLYS);
1658 ULONG nm;
1659 ULONG nAnz=GetMarkedObjectCount();
1660 SdrObjList* pOL0=NULL;
1661 for (nm=nAnz; nm>0;) {
1662 nm--;
1663 SdrMark* pM=GetSdrMarkByIndex(nm);
1664 SdrObject* pObj=pM->GetMarkedSdrObj();
1665 SdrPageView* pPV=pM->GetPageView();
1666 SdrObjList* pOL=pObj->GetObjList();
1667 if (pOL!=pOL0) { pOL0=pOL; pObj->GetOrdNum(); } // sicherstellen, dass OrdNums stimmen!
1668 if (ImpCanDismantle(pObj,bMakeLines)) {
1669 aRemoveMerker.InsertEntry(SdrMark(pObj,pM->GetPageView()));
1670 ULONG nPos0=pObj->GetOrdNumDirect();
1671 ULONG nPos=nPos0+1;
1672 SdrObjList* pSubList=pObj->GetSubList();
1673 if (pSubList!=NULL && !pObj->Is3DObj()) {
1674 SdrObjListIter aIter(*pSubList,IM_DEEPNOGROUPS);
1675 while (aIter.IsMore()) {
1676 const SdrObject* pObj1=aIter.Next();
1677 ImpDismantleOneObject(pObj1,*pOL,nPos,pPV,bMakeLines);
1679 } else {
1680 ImpDismantleOneObject(pObj,*pOL,nPos,pPV,bMakeLines);
1682 if( bUndo )
1683 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj,TRUE));
1684 pOL->RemoveObject(nPos0);
1686 if( !bUndo )
1687 SdrObject::Free(pObj);
1691 if( bUndo )
1693 // UndoComment aus den tatsaechlich verwendeten Objekten zusammenbauen
1694 SetUndoComment(ImpGetResStr(bMakeLines?STR_EditDismantle_Lines:STR_EditDismantle_Polys),aRemoveMerker.GetMarkDescription());
1695 // die tatsaechlich verwendeten Objekten aus der Liste entfernen
1696 EndUndo();
1700 ////////////////////////////////////////////////////////////////////////////////////////////////////
1702 // #### #### ### # # ####
1703 // # # # # # # # # #
1704 // # ## #### # # # # ####
1705 // # # # # # # # # #
1706 // #### # # ### ### #
1708 ////////////////////////////////////////////////////////////////////////////////////////////////////
1710 void SdrEditView::GroupMarked(const SdrObject* pUserGrp)
1712 if (AreObjectsMarked())
1714 SortMarkedObjects();
1716 const bool bUndo = IsUndoEnabled();
1717 if( bUndo )
1719 BegUndo(ImpGetResStr(STR_EditGroup),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_GROUP);
1721 const ULONG nAnz = GetMarkedObjectCount();
1722 for(ULONG nm = nAnz; nm>0; )
1724 // UndoActions fuer alle betroffenen Objekte anlegen
1725 nm--;
1726 SdrMark* pM=GetSdrMarkByIndex(nm);
1727 SdrObject* pObj = pM->GetMarkedSdrObj();
1728 std::vector< SdrUndoAction* > vConnectorUndoActions( CreateConnectorUndo( *pObj ) );
1729 AddUndoActions( vConnectorUndoActions );
1730 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoRemoveObject( *pObj ));
1734 SdrMarkList aNewMark;
1735 SdrPageView* pPV = GetSdrPageView();
1737 if(pPV)
1739 SdrObjList* pAktLst=pPV->GetObjList();
1740 SdrObjList* pSrcLst=pAktLst;
1741 SdrObjList* pSrcLst0=pSrcLst;
1742 SdrPage* pPage=pPV->GetPage();
1743 // sicherstellen, dass die OrdNums stimmen
1744 if (pSrcLst->IsObjOrdNumsDirty())
1745 pSrcLst->RecalcObjOrdNums();
1746 SdrObject* pGrp=NULL;
1747 SdrObject* pRefObj=NULL; // Referenz fuer InsertReason (-> rumankern im Writer)
1748 SdrObject* pRefObj1=NULL; // Referenz fuer InsertReason (-> rumankern im Writer)
1749 SdrObjList* pDstLst=NULL;
1750 // Falls alle markierten Objekte aus Fremden Obj-Listen
1751 // kommen, kommt das Gruppenobjekt an das Ende der Liste.
1752 ULONG nInsPos=pSrcLst->GetObjCount();
1753 BOOL bNeedInsPos=TRUE;
1754 for (ULONG nm=GetMarkedObjectCount(); nm>0;)
1756 nm--;
1757 SdrMark* pM=GetSdrMarkByIndex(nm);
1758 if (pM->GetPageView()==pPV)
1760 if (pGrp==NULL)
1762 if (pUserGrp!=NULL)
1763 pGrp=pUserGrp->Clone();
1764 if (pGrp==NULL)
1765 pGrp=new SdrObjGroup;
1766 pDstLst=pGrp->GetSubList();
1767 DBG_ASSERT(pDstLst!=NULL,"Angebliches Gruppenobjekt liefert keine Objektliste");
1769 SdrObject* pObj=pM->GetMarkedSdrObj();
1770 pSrcLst=pObj->GetObjList();
1771 if (pSrcLst!=pSrcLst0)
1773 if (pSrcLst->IsObjOrdNumsDirty())
1774 pSrcLst->RecalcObjOrdNums();
1776 BOOL bForeignList=pSrcLst!=pAktLst;
1777 BOOL bGrouped=pSrcLst!=pPage;
1778 if (!bForeignList && bNeedInsPos)
1780 nInsPos=pObj->GetOrdNum(); // ua, damit sind alle ObjOrdNum der Page gesetzt
1781 nInsPos++;
1782 bNeedInsPos=FALSE;
1784 pSrcLst->RemoveObject(pObj->GetOrdNumDirect());
1785 if (!bForeignList)
1786 nInsPos--; // InsertPos korregieren
1787 SdrInsertReason aReason(SDRREASON_VIEWCALL);
1788 pDstLst->InsertObject(pObj,0,&aReason);
1789 GetMarkedObjectListWriteAccess().DeleteMark(nm);
1790 if (pRefObj1==NULL)
1791 pRefObj1=pObj; // Das oberste sichtbare Objekt
1792 if (!bGrouped)
1794 if (pRefObj==NULL)
1795 pRefObj=pObj; // Das oberste sichtbare nicht gruppierte Objekt
1797 pSrcLst0=pSrcLst;
1800 if (pRefObj==NULL)
1801 pRefObj=pRefObj1;
1802 if (pGrp!=NULL)
1804 aNewMark.InsertEntry(SdrMark(pGrp,pPV));
1805 ULONG nAnz=pDstLst->GetObjCount();
1806 SdrInsertReason aReason(SDRREASON_VIEWCALL,pRefObj);
1807 pAktLst->InsertObject(pGrp,nInsPos,&aReason);
1808 if( bUndo )
1810 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pGrp,true)); // Kein Recalc!
1811 for (ULONG no=0; no<nAnz; no++)
1813 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoInsertObject(*pDstLst->GetObj(no)));
1818 GetMarkedObjectListWriteAccess().Merge(aNewMark);
1819 MarkListHasChanged();
1821 if( bUndo )
1822 EndUndo();
1826 ////////////////////////////////////////////////////////////////////////////////////////////////////
1828 // # # # # #### #### ### # # ####
1829 // # # ## # # # # # # # # # #
1830 // # # # # # # ## #### # # # # ####
1831 // # # # ## # # # # # # # # #
1832 // ### # # #### # # ### ### #
1834 ////////////////////////////////////////////////////////////////////////////////////////////////////
1836 void SdrEditView::UnGroupMarked()
1838 SdrMarkList aNewMark;
1840 const bool bUndo = IsUndoEnabled();
1841 if( bUndo )
1842 BegUndo(String(), String(), SDRREPFUNC_OBJ_UNGROUP);
1844 ULONG nCount=0;
1845 XubString aName1;
1846 XubString aName;
1847 BOOL bNameOk=FALSE;
1848 for (ULONG nm=GetMarkedObjectCount(); nm>0;) {
1849 nm--;
1850 SdrMark* pM=GetSdrMarkByIndex(nm);
1851 SdrObject* pGrp=pM->GetMarkedSdrObj();
1852 SdrObjList* pSrcLst=pGrp->GetSubList();
1853 if (pSrcLst!=NULL) {
1854 nCount++;
1855 if (nCount==1) {
1856 pGrp->TakeObjNameSingul(aName); // Bezeichnung der Gruppe holen
1857 pGrp->TakeObjNamePlural(aName1); // Bezeichnung der Gruppe holen
1858 bNameOk=TRUE;
1859 } else {
1860 if (nCount==2) aName=aName1; // Pluralname setzen
1861 if (bNameOk) {
1862 XubString aStr;
1863 pGrp->TakeObjNamePlural(aStr); // Bezeichnung der Gruppe holen
1865 if(!aStr.Equals(aName))
1866 bNameOk = FALSE;
1869 ULONG nDstCnt=pGrp->GetOrdNum();
1870 SdrObjList* pDstLst=pM->GetPageView()->GetObjList();
1872 // FIRST move contained objects to parent of group, so that
1873 // the contained objects are NOT migrated to the UNDO-ItemPool
1874 // when AddUndo(new SdrUndoDelObj(*pGrp)) is called.
1875 ULONG nAnz=pSrcLst->GetObjCount();
1876 ULONG no;
1878 if( bUndo )
1880 for (no=nAnz; no>0;)
1882 no--;
1883 SdrObject* pObj=pSrcLst->GetObj(no);
1884 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoRemoveObject(*pObj));
1887 for (no=0; no<nAnz; no++)
1889 SdrObject* pObj=pSrcLst->RemoveObject(0);
1890 SdrInsertReason aReason(SDRREASON_VIEWCALL,pGrp);
1891 pDstLst->InsertObject(pObj,nDstCnt,&aReason);
1892 if( bUndo )
1893 AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoInsertObject(*pObj,true));
1894 nDstCnt++;
1895 // Kein SortCheck beim einfuegen in die MarkList, denn das
1896 // wuerde wg. pObj->GetOrdNum() jedesmal ein RecalcOrdNums()
1897 // provozieren:
1898 aNewMark.InsertEntry(SdrMark(pObj,pM->GetPageView()),FALSE);
1901 if( bUndo )
1903 // Now it is safe to add the delete-UNDO which trigers the
1904 // MigrateItemPool now only for itself, not for the subobjects.
1905 // nDstCnt is right, because previous inserts move group
1906 // object deeper and increase nDstCnt.
1907 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pGrp));
1909 pDstLst->RemoveObject(nDstCnt);
1911 if( !bUndo )
1912 SdrObject::Free(pGrp);
1914 GetMarkedObjectListWriteAccess().DeleteMark(nm);
1917 if (nCount!=0)
1919 if (!bNameOk)
1920 aName=ImpGetResStr(STR_ObjNamePluralGRUP); // Oberbegriff Gruppenobjekte verwenden, wenn verschiedene Objekte.
1921 SetUndoComment(ImpGetResStr(STR_EditUngroup),aName);
1924 if( bUndo )
1925 EndUndo();
1927 if (nCount!=0)
1929 GetMarkedObjectListWriteAccess().Merge(aNewMark,TRUE); // Durch das obige Einsortieren ist aNewMark genau verkehrtherum
1930 MarkListHasChanged();
1934 ////////////////////////////////////////////////////////////////////////////////////////////////////
1936 // ### ### # # # # ##### #### ##### ##### ### #### ### # # #
1937 // # # # # ## # # # # # # # # # # # # # # # # #
1938 // # # # # # # # # #### #### # # # # #### # # # #
1939 // # # # # # ## # # # # # # # # # # # # # #
1940 // ### ### # # # ##### # # # # ### # ### #### #
1942 ////////////////////////////////////////////////////////////////////////////////////////////////////
1944 SdrObject* SdrEditView::ImpConvertOneObj(SdrObject* pObj, BOOL bPath, BOOL bLineToArea)
1946 SdrObject* pNewObj = pObj->ConvertToPolyObj(bPath, bLineToArea);
1947 if (pNewObj!=NULL)
1949 SdrObjList* pOL=pObj->GetObjList();
1950 DBG_ASSERT(pOL!=NULL,"ConvertTo: Obj liefert keine ObjList");
1951 if (pOL!=NULL)
1953 const bool bUndo = IsUndoEnabled();
1954 if( bUndo )
1955 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoReplaceObject(*pObj,*pNewObj));
1957 pOL->ReplaceObject(pNewObj,pObj->GetOrdNum());
1959 if( !bUndo )
1960 SdrObject::Free(pObj);
1963 return pNewObj;
1966 void SdrEditView::ImpConvertTo(BOOL bPath, BOOL bLineToArea)
1968 BOOL bMrkChg=FALSE;
1969 BOOL bModChg=FALSE;
1970 if (AreObjectsMarked()) {
1971 ULONG nMarkAnz=GetMarkedObjectCount();
1972 USHORT nDscrID=0;
1973 if(bLineToArea)
1975 if(nMarkAnz == 1)
1976 nDscrID = STR_EditConvToContour;
1977 else
1978 nDscrID = STR_EditConvToContours;
1980 BegUndo(ImpGetResStr(nDscrID), GetDescriptionOfMarkedObjects());
1982 else
1984 if (bPath) {
1985 if (nMarkAnz==1) nDscrID=STR_EditConvToCurve;
1986 else nDscrID=STR_EditConvToCurves;
1987 BegUndo(ImpGetResStr(nDscrID),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_CONVERTTOPATH);
1988 } else {
1989 if (nMarkAnz==1) nDscrID=STR_EditConvToPoly;
1990 else nDscrID=STR_EditConvToPolys;
1991 BegUndo(ImpGetResStr(nDscrID),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_CONVERTTOPOLY);
1994 for (ULONG nm=nMarkAnz; nm>0;) {
1995 nm--;
1996 SdrMark* pM=GetSdrMarkByIndex(nm);
1997 SdrObject* pObj=pM->GetMarkedSdrObj();
1998 SdrPageView* pPV=pM->GetPageView();
1999 if (pObj->IsGroupObject() && !pObj->Is3DObj()) {
2000 SdrObject* pGrp=pObj;
2001 SdrObjListIter aIter(*pGrp,IM_DEEPNOGROUPS);
2002 while (aIter.IsMore()) {
2003 pObj=aIter.Next();
2004 if (ImpConvertOneObj(pObj,bPath,bLineToArea)) bModChg=TRUE;
2006 } else {
2007 SdrObject* pNewObj=ImpConvertOneObj(pObj,bPath,bLineToArea);
2008 if (pNewObj!=NULL) {
2009 bModChg=TRUE;
2010 bMrkChg=TRUE;
2011 GetMarkedObjectListWriteAccess().ReplaceMark(SdrMark(pNewObj,pPV),nm);
2015 EndUndo();
2016 if (bMrkChg) AdjustMarkHdl();
2017 if (bMrkChg) MarkListHasChanged();
2021 void SdrEditView::ConvertMarkedToPathObj(BOOL bLineToArea)
2023 ImpConvertTo(TRUE, bLineToArea);
2026 void SdrEditView::ConvertMarkedToPolyObj(BOOL bLineToArea)
2028 ImpConvertTo(FALSE, bLineToArea);
2031 ////////////////////////////////////////////////////////////////////////////////////////////////////
2033 // # # ##### ##### ### ##### # # ##### # # # #### ### #### #####
2034 // ## ## # # # # # # # # # ## ## # # # # # # #
2035 // # # # #### # ##### ### # # #### ### # # # # #### # # #### #
2036 // # # # # # # # # # # # # # # # # # # #
2037 // # # ##### # # # # # #### ##### # # # # ### # # #
2039 ////////////////////////////////////////////////////////////////////////////////////////////////////
2041 void SdrEditView::DoImportMarkedMtf(SvdProgressInfo *pProgrInfo)
2043 const bool bUndo = IsUndoEnabled();
2045 if( bUndo )
2046 BegUndo(String(), String(), SDRREPFUNC_OBJ_IMPORTMTF);
2048 SortMarkedObjects();
2049 SdrMarkList aForTheDescription;
2050 SdrMarkList aNewMarked;
2051 ULONG nAnz=GetMarkedObjectCount();
2053 for (ULONG nm=nAnz; nm>0;)
2054 { // Undo Objekte fuer alle neuen Objekte erzeugen
2055 // zwischen den Metafiles auf Abbruch testen
2056 if( pProgrInfo != NULL )
2058 pProgrInfo->SetNextObject();
2059 if(!pProgrInfo->ReportActions(0))
2060 break;
2063 nm--;
2064 SdrMark* pM=GetSdrMarkByIndex(nm);
2065 SdrObject* pObj=pM->GetMarkedSdrObj();
2066 SdrPageView* pPV=pM->GetPageView();
2067 SdrObjList* pOL=pObj->GetObjList();
2068 ULONG nInsPos=pObj->GetOrdNum()+1;
2069 SdrGrafObj* pGraf=PTR_CAST(SdrGrafObj,pObj);
2070 SdrOle2Obj* pOle2=PTR_CAST(SdrOle2Obj,pObj);
2071 ULONG nInsAnz=0;
2072 if (pGraf!=NULL && pGraf->HasGDIMetaFile())
2074 ImpSdrGDIMetaFileImport aFilter(*pMod);
2075 aFilter.SetScaleRect(pGraf->GetSnapRect());
2076 aFilter.SetLayer(pObj->GetLayer());
2077 nInsAnz=aFilter.DoImport(pGraf->GetTransformedGraphic().GetGDIMetaFile(),*pOL,nInsPos,pProgrInfo);
2079 if ( pOle2!=NULL && pOle2->GetGraphic() )
2081 //const GDIMetaFile* pMtf=pOle2->GetGDIMetaFile();
2082 ImpSdrGDIMetaFileImport aFilter(*pMod);
2083 aFilter.SetScaleRect(pOle2->GetLogicRect());
2084 aFilter.SetLayer(pObj->GetLayer());
2085 nInsAnz=aFilter.DoImport(pOle2->GetGraphic()->GetGDIMetaFile(),*pOL,nInsPos,pProgrInfo);
2087 if (nInsAnz!=0)
2089 ULONG nObj=nInsPos;
2090 for (ULONG i=0; i<nInsAnz; i++)
2092 if( bUndo )
2093 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pOL->GetObj(nObj)));
2095 // Neue MarkList pflegen
2096 SdrMark aNewMark(pOL->GetObj(nObj), pPV);
2097 aNewMarked.InsertEntry(aNewMark);
2099 nObj++;
2101 aForTheDescription.InsertEntry(*pM);
2103 if( bUndo )
2104 AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj));
2106 // Objekt aus selektion loesen und loeschen
2107 GetMarkedObjectListWriteAccess().DeleteMark(TryToFindMarkedObject(pObj));
2108 pOL->RemoveObject(nInsPos-1);
2110 if( !bUndo )
2111 SdrObject::Free(pObj);
2115 // MarkObj... fehlt... jetzt nicht mehr (AW)
2116 if(aNewMarked.GetMarkCount())
2118 // Neue Selektion bilden
2119 for(ULONG a(0); a < aNewMarked.GetMarkCount(); a++)
2121 GetMarkedObjectListWriteAccess().InsertEntry(*aNewMarked.GetMark(a));
2124 SortMarkedObjects();
2127 if( bUndo )
2129 SetUndoComment(ImpGetResStr(STR_EditImportMtf),aForTheDescription.GetMarkDescription());
2130 EndUndo();