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

Generated by: LCOV version 1.10