LCOV - code coverage report
Current view: top level - svx/source/svdraw - svdedtv2.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 412 1110 37.1 %
Date: 2014-04-11 Functions: 21 33 63.6 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10