Files
libreoffice/svx/source/svdraw/svdedtv2.cxx
Rüdiger Timm ee0c863464 INTEGRATION: CWS aw035 (1.22.44); FILE MERGED
2006/07/12 15:29:53 aw 1.22.44.1: #126320# SdrMark::GetObj() -> SdrMark::GetSdrObjectFromSdrMark() for unique identification
2006-07-25 11:55:34 +00:00

1984 lines
80 KiB
C++

/*************************************************************************
*
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: svdedtv2.cxx,v $
*
* $Revision: 1.23 $
*
* last change: $Author: rt $ $Date: 2006-07-25 12:55:34 $
*
* The Contents of this file are made available subject to
* the terms of GNU Lesser General Public License Version 2.1.
*
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2005 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
************************************************************************/
#include "svdedtv.hxx"
#include "outliner.hxx"
#include "svdundo.hxx"
#include "svdogrp.hxx" // fuer's Gruppieren
#include "svdovirt.hxx" // fuer VirtualObject-Bundling (Writer)
#include "svdopath.hxx" // fuer CombineObjects
#include "svdpage.hxx"
#include "svdpagv.hxx"
#include "svditer.hxx"
#include "svdograf.hxx" // fuer Possibilities
#include "svdoole2.hxx" // und Mtf-Import
#include "svdstr.hrc" // Namen aus der Resource
#include "svdglob.hxx" // StringCache
#include "svdfmtf.hxx"
#include "svdetc.hxx"
#ifndef _BASEDLGS_HXX
#include <sfx2/basedlgs.hxx>
#endif
//CHINA001 #include "dstribut.hxx"
#ifndef _SV_MSGBOX_HXX //autogen
#include <vcl/msgbox.hxx>
#endif
#ifndef _OUTLOBJ_HXX //autogen
#include <outlobj.hxx>
#endif
#ifndef _EEITEM_HXX
#include "eeitem.hxx"
#endif
#ifndef _POLY3D_HXX
#include "poly3d.hxx"
#endif
#ifndef _BGFX_POLYGON_B2DPOLYPOLYGON_HXX
#include <basegfx/polygon/b2dpolypolygon.hxx>
#endif
#ifndef _BGFX_POLYPOLYGON_B2DPOLYGONTOOLS_HXX
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#endif
#include "svxdlg.hxx" //CHINA001
#include <dialogs.hrc> //CHINA001
// #i37011#
#ifndef _SVDOASHP_HXX
#include "svdoashp.hxx"
#endif
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// @@@@@ @@@@@ @@ @@@@@@ @@ @@ @@ @@@@@ @@ @@
// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @ @@
// @@@@ @@ @@ @@ @@ @@@@@ @@ @@@@ @@@@@@@
// @@ @@ @@ @@ @@ @@@ @@ @@ @@@@@@@
// @@ @@ @@ @@ @@ @@@ @@ @@ @@@ @@@
// @@@@@ @@@@@ @@ @@ @ @@ @@@@@ @@ @@
//
////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////
void SdrEditView::ImpBundleVirtObjOfMarkList()
{
// ... fehlende Implementation
}
SdrObject* SdrEditView::GetMaxToTopObj(SdrObject* /*pObj*/) const
{
return NULL;
}
SdrObject* SdrEditView::GetMaxToBtmObj(SdrObject* /*pObj*/) const
{
return NULL;
}
void SdrEditView::ObjOrderChanged(SdrObject* /*pObj*/, ULONG /*nOldPos*/, ULONG /*nNewPos*/)
{
}
void SdrEditView::MovMarkedToTop()
{
ULONG nAnz=GetMarkedObjectCount();
if (nAnz!=0) {
BegUndo(ImpGetResStr(STR_EditMovToTop),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_MOVTOTOP);
SortMarkedObjects();
ULONG nm;
for (nm=0; nm<nAnz; nm++) { // Ordnums muessen alle stimmen!
GetMarkedObjectByIndex(nm)->GetOrdNum();
}
// --> OD 2004-08-24 #110810#
// BOOL bNeedBundle=FALSE;
// <--
BOOL bChg=FALSE;
SdrObjList* pOL0=NULL;
ULONG nNewPos=0;
for (nm=nAnz; nm>0;) {
nm--;
SdrMark* pM=GetSdrMarkByIndex(nm);
SdrObject* pObj=pM->GetMarkedSdrObj();
SdrObjList* pOL=pObj->GetObjList();
if (pOL!=pOL0) {
nNewPos=ULONG(pOL->GetObjCount()-1);
pOL0=pOL;
}
ULONG nNowPos=pObj->GetOrdNumDirect();
const Rectangle& rBR=pObj->GetCurrentBoundRect();
ULONG nCmpPos=nNowPos+1;
SdrObject* pMaxObj=GetMaxToTopObj(pObj);
if (pMaxObj!=NULL) {
ULONG nMaxPos=pMaxObj->GetOrdNum();
if (nMaxPos!=0) nMaxPos--;
if (nNewPos>nMaxPos) nNewPos=nMaxPos; // diesen nicht ueberholen.
if (nNewPos<nNowPos) nNewPos=nNowPos; // aber dabei auch nicht in die falsche Richtung schieben
}
BOOL bEnd=FALSE;
while (nCmpPos<nNewPos && !bEnd) {
SdrObject* pCmpObj=pOL->GetObj(nCmpPos);
if (pCmpObj==NULL) {
DBG_ERROR("MovMarkedToTop(): Vergleichsobjekt nicht gefunden");
bEnd=TRUE;
} else if (pCmpObj==pMaxObj) {
nNewPos=nCmpPos;
nNewPos--;
bEnd=TRUE;
} else if (rBR.IsOver(pCmpObj->GetCurrentBoundRect())) {
nNewPos=nCmpPos;
bEnd=TRUE;
} else nCmpPos++;
}
if (nNowPos!=nNewPos) {
// --> OD 2004-08-24 #110810#
// if (bBundleVirtObj) {
// SdrVirtObj* pV0=PTR_CAST(SdrVirtObj,pObj);
// if (pV0!=NULL) bNeedBundle=TRUE;
// do { // nicht zwischen virtuelle Objekte draengeln
// SdrObject* pV1Tmp=pOL->GetObj(nNewPos);
// SdrObject* pV2Tmp=pOL->GetObj(nNewPos+1);
// SdrVirtObj* pV1=PTR_CAST(SdrVirtObj,pV1Tmp);
// SdrVirtObj* pV2=PTR_CAST(SdrVirtObj,pV2Tmp);
// // Zwischen VirtObj mit gleichem Master wie ich darf ich schon
// if (pV0!=NULL && pV1!=NULL && &pV0->GetReferencedObj()==&pV1->GetReferencedObj()) break;
// // Zwischen andere nicht
// if (pV1==NULL || pV2==NULL || &pV1->GetReferencedObj()!=&pV2->GetReferencedObj()) break;
// nNewPos++;
// } while (TRUE);
// }
// <--
bChg=TRUE;
pOL->SetObjectOrdNum(nNowPos,nNewPos);
AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj,nNowPos,nNewPos));
ObjOrderChanged(pObj,nNowPos,nNewPos);
}
nNewPos--;
}
// --> OD 2004-08-24 #110810#
// if (bNeedBundle) ImpBundleVirtObjOfMarkList();
// <--
EndUndo();
if (bChg) MarkListHasChanged();
}
}
void SdrEditView::MovMarkedToBtm()
{
ULONG nAnz=GetMarkedObjectCount();
if (nAnz!=0) {
BegUndo(ImpGetResStr(STR_EditMovToBtm),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_MOVTOBTM);
SortMarkedObjects();
ULONG nm;
for (nm=0; nm<nAnz; nm++) { // Ordnums muessen alle stimmen!
GetMarkedObjectByIndex(nm)->GetOrdNum();
}
// --> OD 2004-08-24 #110810#
// BOOL bNeedBundle=FALSE;
// <--
BOOL bChg=FALSE;
SdrObjList* pOL0=NULL;
ULONG nNewPos=0;
for (nm=0; nm<nAnz; nm++) {
SdrMark* pM=GetSdrMarkByIndex(nm);
SdrObject* pObj=pM->GetMarkedSdrObj();
SdrObjList* pOL=pObj->GetObjList();
if (pOL!=pOL0) {
nNewPos=0;
pOL0=pOL;
}
ULONG nNowPos=pObj->GetOrdNumDirect();
const Rectangle& rBR=pObj->GetCurrentBoundRect();
ULONG nCmpPos=nNowPos; if (nCmpPos>0) nCmpPos--;
SdrObject* pMaxObj=GetMaxToBtmObj(pObj);
if (pMaxObj!=NULL) {
ULONG nMinPos=pMaxObj->GetOrdNum()+1;
if (nNewPos<nMinPos) nNewPos=nMinPos; // diesen nicht ueberholen.
if (nNewPos>nNowPos) nNewPos=nNowPos; // aber dabei auch nicht in die falsche Richtung schieben
}
BOOL bEnd=FALSE;
// nNewPos ist an dieser Stelle noch die maximale Position,
// an der das Obj hinruecken darf, ohne seinen Vorgaenger
// (Mehrfachselektion) zu ueberholen.
while (nCmpPos>nNewPos && !bEnd) {
SdrObject* pCmpObj=pOL->GetObj(nCmpPos);
if (pCmpObj==NULL) {
DBG_ERROR("MovMarkedToBtm(): Vergleichsobjekt nicht gefunden");
bEnd=TRUE;
} else if (pCmpObj==pMaxObj) {
nNewPos=nCmpPos;
nNewPos++;
bEnd=TRUE;
} else if (rBR.IsOver(pCmpObj->GetCurrentBoundRect())) {
nNewPos=nCmpPos;
bEnd=TRUE;
} else nCmpPos--;
}
if (nNowPos!=nNewPos) {
// --> OD 2004-08-24 #110810#
// if (bBundleVirtObj) {
// SdrVirtObj* pV0=PTR_CAST(SdrVirtObj,pObj);
// if (pV0!=NULL) bNeedBundle=TRUE;
// do { // nicht zwischen virtuelle Objekte draengeln
// if (nNewPos==0) break;
// SdrObject* pV1Tmp=pOL->GetObj(nNewPos);
// SdrObject* pV2Tmp=pOL->GetObj(ULONG(nNewPos-1));
// SdrVirtObj* pV1=PTR_CAST(SdrVirtObj,pV1Tmp);
// SdrVirtObj* pV2=PTR_CAST(SdrVirtObj,pV2Tmp);
// // Zwischen VirtObj mit gleichem Master wie ich darf ich schon
// if (pV0!=NULL && pV1!=NULL && &pV0->GetReferencedObj()==&pV1->GetReferencedObj()) break;
// // Zwischen andere nicht
// if (pV1==NULL || pV2==NULL || &pV1->GetReferencedObj()!=&pV2->GetReferencedObj()) break;
// nNewPos--;
// } while (TRUE);
// }
// <--
bChg=TRUE;
pOL->SetObjectOrdNum(nNowPos,nNewPos);
AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj,nNowPos,nNewPos));
ObjOrderChanged(pObj,nNowPos,nNewPos);
}
nNewPos++;
}
// --> OD 2004-08-24 #110810#
// if (bNeedBundle) ImpBundleVirtObjOfMarkList();
// <--
EndUndo();
if (bChg) MarkListHasChanged();
}
}
void SdrEditView::PutMarkedToTop()
{
PutMarkedInFrontOfObj(NULL);
}
void SdrEditView::PutMarkedInFrontOfObj(const SdrObject* pRefObj)
{
ULONG nAnz=GetMarkedObjectCount();
if (nAnz!=0) {
BegUndo(ImpGetResStr(STR_EditPutToTop),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_PUTTOTOP);
SortMarkedObjects();
if (pRefObj!=NULL) {
// Damit "Vor das Objekt" auch funktioniert wenn die
// markierten Objekte bereits vor dem Objekt stehen
ULONG nRefMark=TryToFindMarkedObject(pRefObj);
SdrMark aRefMark;
if (nRefMark!=CONTAINER_ENTRY_NOTFOUND)
{
aRefMark=*GetSdrMarkByIndex(nRefMark);
GetMarkedObjectListWriteAccess().DeleteMark(nRefMark);
}
PutMarkedToBtm();
if (nRefMark!=CONTAINER_ENTRY_NOTFOUND)
{
GetMarkedObjectListWriteAccess().InsertEntry(aRefMark);
SortMarkedObjects();
}
}
ULONG nm;
for (nm=0; nm<nAnz; nm++) { // Ordnums muessen alle stimmen!
GetMarkedObjectByIndex(nm)->GetOrdNum();
}
// --> OD 2004-08-24 #110810#
// BOOL bNeedBundle=FALSE;
// <--
BOOL bChg=FALSE;
SdrObjList* pOL0=NULL;
ULONG nNewPos=0;
for (nm=nAnz; nm>0;) {
nm--;
SdrMark* pM=GetSdrMarkByIndex(nm);
SdrObject* pObj=pM->GetMarkedSdrObj();
if (pObj!=pRefObj) {
SdrObjList* pOL=pObj->GetObjList();
if (pOL!=pOL0) {
nNewPos=ULONG(pOL->GetObjCount()-1);
pOL0=pOL;
}
ULONG nNowPos=pObj->GetOrdNumDirect();
SdrObject* pMaxObj=GetMaxToTopObj(pObj);
if (pMaxObj!=NULL) {
ULONG nMaxOrd=pMaxObj->GetOrdNum(); // geht leider nicht anders
if (nMaxOrd>0) nMaxOrd--;
if (nNewPos>nMaxOrd) nNewPos=nMaxOrd; // nicht ueberholen.
if (nNewPos<nNowPos) nNewPos=nNowPos; // aber dabei auch nicht in die falsche Richtung schieben
}
if (pRefObj!=NULL) {
if (pRefObj->GetObjList()==pObj->GetObjList()) {
ULONG nMaxOrd=pRefObj->GetOrdNum(); // geht leider nicht anders
if (nNewPos>nMaxOrd) nNewPos=nMaxOrd; // nicht ueberholen.
if (nNewPos<nNowPos) nNewPos=nNowPos; // aber dabei auch nicht in die falsche Richtung schieben
} else {
nNewPos=nNowPos; // andere PageView, also nicht veraendern
}
}
if (nNowPos!=nNewPos) {
// --> OD 2004-08-24 #110810#
// if (bBundleVirtObj && HAS_BASE(SdrVirtObj,pObj)) bNeedBundle=TRUE;
// <--
bChg=TRUE;
pOL->SetObjectOrdNum(nNowPos,nNewPos);
AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj,nNowPos,nNewPos));
ObjOrderChanged(pObj,nNowPos,nNewPos);
}
nNewPos--;
} // if (pObj!=pRefObj)
} // for-Schleife ueber alle Markierten Objekte
// --> OD 2004-08-24 #110810#
// if (bNeedBundle) ImpBundleVirtObjOfMarkList();
// <--
EndUndo();
if (bChg) MarkListHasChanged();
}
}
void SdrEditView::PutMarkedToBtm()
{
PutMarkedBehindObj(NULL);
}
void SdrEditView::PutMarkedBehindObj(const SdrObject* pRefObj)
{
ULONG nAnz=GetMarkedObjectCount();
if (nAnz!=0) {
BegUndo(ImpGetResStr(STR_EditPutToBtm),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_PUTTOBTM);
SortMarkedObjects();
if (pRefObj!=NULL) {
// Damit "Hinter das Objekt" auch funktioniert wenn die
// markierten Objekte bereits hinter dem Objekt stehen
ULONG nRefMark=TryToFindMarkedObject(pRefObj);
SdrMark aRefMark;
if (nRefMark!=CONTAINER_ENTRY_NOTFOUND)
{
aRefMark=*GetSdrMarkByIndex(nRefMark);
GetMarkedObjectListWriteAccess().DeleteMark(nRefMark);
}
PutMarkedToTop();
if (nRefMark!=CONTAINER_ENTRY_NOTFOUND)
{
GetMarkedObjectListWriteAccess().InsertEntry(aRefMark);
SortMarkedObjects();
}
}
ULONG nm;
for (nm=0; nm<nAnz; nm++) { // Ordnums muessen alle stimmen!
GetMarkedObjectByIndex(nm)->GetOrdNum();
}
// --> OD 2004-08-24 #110810#
// BOOL bNeedBundle=FALSE;
// <--
BOOL bChg=FALSE;
SdrObjList* pOL0=NULL;
ULONG nNewPos=0;
for (nm=0; nm<nAnz; nm++) {
SdrMark* pM=GetSdrMarkByIndex(nm);
SdrObject* pObj=pM->GetMarkedSdrObj();
if (pObj!=pRefObj) {
SdrObjList* pOL=pObj->GetObjList();
if (pOL!=pOL0) {
nNewPos=0;
pOL0=pOL;
}
ULONG nNowPos=pObj->GetOrdNumDirect();
SdrObject* pMinObj=GetMaxToBtmObj(pObj);
if (pMinObj!=NULL) {
ULONG nMinOrd=pMinObj->GetOrdNum()+1; // geht leider nicht anders
if (nNewPos<nMinOrd) nNewPos=nMinOrd; // nicht ueberholen.
if (nNewPos>nNowPos) nNewPos=nNowPos; // aber dabei auch nicht in die falsche Richtung schieben
}
if (pRefObj!=NULL) {
if (pRefObj->GetObjList()==pObj->GetObjList()) {
ULONG nMinOrd=pRefObj->GetOrdNum(); // geht leider nicht anders
if (nNewPos<nMinOrd) nNewPos=nMinOrd; // nicht ueberholen.
if (nNewPos>nNowPos) nNewPos=nNowPos; // aber dabei auch nicht in die falsche Richtung schieben
} else {
nNewPos=nNowPos; // andere PageView, also nicht veraendern
}
}
if (nNowPos!=nNewPos) {
// --> OD 2004-08-24 #110810#
// if (bBundleVirtObj && !bNeedBundle && HAS_BASE(SdrVirtObj,pObj)) bNeedBundle=TRUE;
// <--
bChg=TRUE;
pOL->SetObjectOrdNum(nNowPos,nNewPos);
AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj,nNowPos,nNewPos));
ObjOrderChanged(pObj,nNowPos,nNewPos);
}
nNewPos++;
} // if (pObj!=pRefObj)
} // for-Schleife ueber alle markierten Objekte
// --> OD 2004-08-24 #110810#
// if (bNeedBundle) ImpBundleVirtObjOfMarkList();
// <--
EndUndo();
if (bChg) MarkListHasChanged();
}
}
void SdrEditView::ReverseOrderOfMarked()
{
SortMarkedObjects();
ULONG nMarkAnz=GetMarkedObjectCount();
if (nMarkAnz>0) {
//BOOL bNeedBundle=FALSE;
BOOL bChg=FALSE;
BegUndo(ImpGetResStr(STR_EditRevOrder),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_REVORDER);
ULONG a=0;
do {
// Markierung ueber mehrere PageViews berueksichtigen
ULONG b=a+1;
while (b<nMarkAnz && GetSdrPageViewOfMarkedByIndex(b) == GetSdrPageViewOfMarkedByIndex(a)) b++;
b--;
SdrObjList* pOL=GetSdrPageViewOfMarkedByIndex(a)->GetObjList();
ULONG c=b;
if (a<c) { // Sicherstellen, dass die OrdNums nicht Dirty sind
GetMarkedObjectByIndex(a)->GetOrdNum();
}
while (a<c) {
SdrObject* pObj1=GetMarkedObjectByIndex(a);
SdrObject* pObj2=GetMarkedObjectByIndex(c);
ULONG nOrd1=pObj1->GetOrdNumDirect();
ULONG nOrd2=pObj2->GetOrdNumDirect();
AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj1,nOrd1,nOrd2));
AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoObjectOrdNum(*pObj2,nOrd2-1,nOrd1));
pOL->SetObjectOrdNum(nOrd1,nOrd2);
// Obj 2 ist um eine Position nach vorn gerutscht, deshalb nun nOrd2-1
pOL->SetObjectOrdNum(nOrd2-1,nOrd1);
// Verwendung von Replace statt SetOrdNum wg. Performance (Neuberechnung der Ordnums)
a++; c--;
bChg=TRUE;
// --> OD 2004-08-24 #110810#
// if (bBundleVirtObj && !bNeedBundle &&
// (HAS_BASE(SdrVirtObj,pObj1) || HAS_BASE(SdrVirtObj,pObj2))) bNeedBundle=TRUE;
// <--
}
a=b+1;
} while (a<nMarkAnz);
// --> OD 2004-08-24 #110810#
// if (bNeedBundle) ImpBundleVirtObjOfMarkList();
// <--
EndUndo();
if (bChg) MarkListHasChanged();
}
}
void SdrEditView::ImpCheckToTopBtmPossible()
{
ULONG nAnz=GetMarkedObjectCount();
if (nAnz==0) return;
if (nAnz==1) { // Sonderbehandlung fuer Einzelmarkierung
SdrObject* pObj=GetMarkedObjectByIndex(0);
SdrObjList* pOL=pObj->GetObjList();
ULONG nMax=pOL->GetObjCount();
ULONG nMin=0;
ULONG nObjNum=pObj->GetOrdNum();
SdrObject* pRestrict=GetMaxToTopObj(pObj);
if (pRestrict!=NULL) {
ULONG nRestrict=pRestrict->GetOrdNum();
if (nRestrict<nMax) nMax=nRestrict;
}
pRestrict=GetMaxToBtmObj(pObj);
if (pRestrict!=NULL) {
ULONG nRestrict=pRestrict->GetOrdNum();
if (nRestrict>nMin) nMin=nRestrict;
}
bToTopPossible=nObjNum<ULONG(nMax-1);
bToBtmPossible=nObjNum>nMin;
} else { // Mehrfachselektion
ULONG nm=0;
SdrObjList* pOL0=NULL;
long nPos0=-1;
while (!bToBtmPossible && nm<nAnz) { // 'nach hinten' checken
SdrObject* pObj=GetMarkedObjectByIndex(nm);
SdrObjList* pOL=pObj->GetObjList();
if (pOL!=pOL0) {
nPos0=-1;
pOL0=pOL;
}
ULONG nPos=pObj->GetOrdNum();
bToBtmPossible=nPos>ULONG(nPos0+1);
nPos0=long(nPos);
nm++;
}
nm=nAnz;
pOL0=NULL;
nPos0=0x7FFFFFFF;
while (!bToTopPossible && nm>0) { // 'nach vorn' checken
nm--;
SdrObject* pObj=GetMarkedObjectByIndex(nm);
SdrObjList* pOL=pObj->GetObjList();
if (pOL!=pOL0) {
nPos0=pOL->GetObjCount();
pOL0=pOL;
}
ULONG nPos=pObj->GetOrdNum();
bToTopPossible=nPos+1<ULONG(nPos0);
nPos0=nPos;
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// @@@@ @@@@ @@ @@ @@@@@ @@ @@ @@ @@@@@
// @@ @@ @@ @@ @@@ @@@ @@ @@ @@ @@@ @@ @@
// @@ @@ @@ @@@@@@@ @@ @@ @@ @@@@@@ @@
// @@ @@ @@ @@@@@@@ @@@@@ @@ @@@@@@ @@@@
// @@ @@ @@ @@ @ @@ @@ @@ @@ @@ @@@ @@
// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
// @@@@ @@@@ @@ @@ @@@@@ @@ @@ @@ @@@@@
//
////////////////////////////////////////////////////////////////////////////////////////////////////
void SdrEditView::ImpCopyAttributes(const SdrObject* pSource, SdrObject* pDest) const
{
if (pSource!=NULL) {
SdrObjList* pOL=pSource->GetSubList();
if (pOL!=NULL && !pSource->Is3DObj()) { // erstes Nichtgruppenobjekt aus der Gruppe holen
SdrObjListIter aIter(*pOL,IM_DEEPNOGROUPS);
pSource=aIter.Next();
}
}
if(pSource && pDest)
{
SfxItemSet aSet(pMod->GetItemPool(),
SDRATTR_START, SDRATTR_NOTPERSIST_FIRST-1,
SDRATTR_NOTPERSIST_LAST+1, SDRATTR_END,
EE_ITEMS_START, EE_ITEMS_END,
0, 0); // #52757#, #52762#
aSet.Put(pSource->GetMergedItemSet());
pDest->ClearMergedItem();
pDest->SetMergedItemSet(aSet);
pDest->NbcSetLayer(pSource->GetLayer());
pDest->NbcSetStyleSheet(pSource->GetStyleSheet(), sal_True);
}
}
BOOL SdrEditView::ImpCanConvertForCombine1(const SdrObject* pObj) const
{
// #69711 : new condition IsLine() to be able to combine simple Lines
BOOL bIsLine = FALSE;
const SdrPathObj* pPath=PTR_CAST(SdrPathObj,pObj);
if (pPath!=NULL)
bIsLine = pPath->IsLine();
SdrObjTransformInfoRec aInfo;
pObj->TakeObjInfo(aInfo);
return ( aInfo.bCanConvToPath || aInfo.bCanConvToPoly || bIsLine );
}
BOOL SdrEditView::ImpCanConvertForCombine(const SdrObject* pObj) const
{
SdrObjList* pOL=pObj->GetSubList();
if (pOL!=NULL && !pObj->Is3DObj()) {
SdrObjListIter aIter(*pOL,IM_DEEPNOGROUPS);
while (aIter.IsMore()) {
SdrObject* pObj1=aIter.Next();
// Es muessen alle Member einer Gruppe konvertierbar sein
if (!ImpCanConvertForCombine1(pObj1)) return FALSE;
}
} else {
if (!ImpCanConvertForCombine1(pObj)) return FALSE;
}
return TRUE;
}
XPolyPolygon SdrEditView::ImpGetXPolyPoly1(const SdrObject* pObj, BOOL bCombine) const
{
XPolyPolygon aRet;
SdrPathObj* pPath=PTR_CAST(SdrPathObj,pObj);
if (bCombine && pPath!=NULL && pObj->GetOutlinerParaObject()==NULL) {
aRet=pPath->GetPathPoly();
} else {
SdrObject* pConvObj=pObj->ConvertToPolyObj(bCombine, FALSE);
if (pConvObj!=NULL) {
SdrObjList* pOL=pConvObj->GetSubList();
if (pOL!=NULL) {
SdrObjListIter aIter(*pOL,IM_DEEPNOGROUPS);
while (aIter.IsMore() && !bCombineError) {
SdrObject* pObj1=aIter.Next();
pPath=PTR_CAST(SdrPathObj,pObj1);
if (pPath!=NULL) {
if ((ULONG)aRet.Count()+(ULONG)pPath->GetPathPoly().Count()<=0xFFFF) {
aRet.Insert(pPath->GetPathPoly());
} else {
((SdrEditView*)this)->bCombineError=TRUE;
}
}
}
} else {
pPath=PTR_CAST(SdrPathObj,pConvObj);
if (pPath!=NULL) {
aRet=pPath->GetPathPoly();
}
}
delete pConvObj;
}
}
return aRet;
}
XPolyPolygon SdrEditView::ImpGetXPolyPoly(const SdrObject* pObj, BOOL bCombine) const
{
XPolyPolygon aRet;
SdrObjList* pOL=pObj->GetSubList();
if (pOL!=NULL && !pObj->Is3DObj()) {
SdrObjListIter aIter(*pOL,IM_DEEPNOGROUPS);
while (aIter.IsMore() && !bCombineError) {
SdrObject* pObj1=aIter.Next();
XPolyPolygon aXPP(ImpGetXPolyPoly1(pObj1, bCombine));
if ((ULONG)aRet.Count()+(ULONG)aXPP.Count()<=0xFFFF) {
aRet.Insert(aXPP);
} else {
((SdrEditView*)this)->bCombineError=TRUE;
}
}
} else {
aRet=ImpGetXPolyPoly1(pObj, bCombine);
}
return aRet;
}
void SdrEditView::ImpCombineToSinglePoly(XPolyPolygon& rXPP, long nJoinTol) const
{
USHORT nPolyCount=rXPP.Count();
if (nPolyCount>=2) {
XPolygon aXP(rXPP[0]);
if (aXP.GetPointCount()!=0) {
aXP.SetFlags(0,XPOLY_NORMAL);
aXP.SetFlags(USHORT(aXP.GetPointCount()-1),XPOLY_NORMAL);
}
for (USHORT i=1; i<nPolyCount && !bCombineError; i++) {
USHORT nDstPointCount=aXP.GetPointCount();
const XPolygon rSrcPoly=rXPP[i];
USHORT nSrcPointCount=rSrcPoly.GetPointCount();
if ((ULONG)nSrcPointCount+(ULONG)nDstPointCount>XPOLY_MAXPOINTS) {
((SdrEditView*)this)->bCombineError=TRUE;
} else {
if (nDstPointCount==0 || nSrcPointCount==0) {
aXP.Insert(nDstPointCount,rSrcPoly);
} else {
Point aDstPt0(aXP[0]);
Point aDstPt1(aXP[USHORT(nDstPointCount-1)]);
Point aSrcPt0(rSrcPoly[0]);
Point aSrcPt1(rSrcPoly[USHORT(nSrcPointCount-1)]);
long n00=Abs(aSrcPt0.X()-aDstPt0.X())+Abs(aSrcPt0.Y()-aDstPt0.Y());
long n10=Abs(aSrcPt1.X()-aDstPt0.X())+Abs(aSrcPt1.Y()-aDstPt0.Y());
long n01=Abs(aSrcPt0.X()-aDstPt1.X())+Abs(aSrcPt0.Y()-aDstPt1.Y());
long n11=Abs(aSrcPt1.X()-aDstPt1.X())+Abs(aSrcPt1.Y()-aDstPt1.Y());
BOOL bAppend=(n01<=n00 && n01<=n10) || (n11<=n00 && n11<=n10);
BOOL bRevers=bAppend ? n11<n01 : n00<n10;
USHORT nDstPos=bAppend ? nDstPointCount : 0;
BOOL b1st=TRUE;
if (bRevers) {
for (USHORT nSrcPos=nSrcPointCount; nSrcPos>0;) {
nSrcPos--;
BOOL bNoIns=FALSE;
if (b1st) bNoIns=(bAppend ? n11 : n00) <=nJoinTol;
if (!bNoIns) {
aXP.Insert(nDstPos,rSrcPoly[nSrcPos],rSrcPoly.GetFlags(nSrcPos));
if (bAppend) nDstPos++;
}
b1st=FALSE;
}
} else {
for (USHORT nSrcPos=0; nSrcPos<nSrcPointCount; nSrcPos++) {
BOOL bNoIns=FALSE;
if (b1st) bNoIns=(bAppend ? n01 : n10) <=nJoinTol;
if (!bNoIns) {
aXP.Insert(nDstPos,rSrcPoly[nSrcPos],rSrcPoly.GetFlags(nSrcPos));
if (bAppend) nDstPos++;
}
b1st=FALSE;
}
}
}
if (aXP.GetPointCount()!=0) {
aXP.SetFlags(0,XPOLY_NORMAL);
aXP.SetFlags(USHORT(aXP.GetPointCount()-1),XPOLY_NORMAL);
}
}
}
if (!bCombineError) {
rXPP.Clear();
rXPP.Insert(aXP,0);
}
}
}
// for distribution dialog function
struct ImpDistributeEntry
{
SdrObject* mpObj;
INT32 mnPos;
INT32 mnLength;
};
DECLARE_LIST(ImpDistributeEntryList, ImpDistributeEntry*)
void SdrEditView::DistributeMarkedObjects()
{
#ifndef SVX_LIGHT
UINT32 nMark(GetMarkedObjectCount());
if(nMark > 2)
{
SfxItemSet aNewAttr(pMod->GetItemPool());
//CHINA001 SvxDistributeDialog* pDlg = new SvxDistributeDialog(NULL, aNewAttr);
SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
if(pFact)
{
AbstractSvxDistributeDialog *pDlg = pFact->CreateSvxDistributeDialog(NULL, aNewAttr, ResId(RID_SVXPAGE_DISTRIBUTE));
DBG_ASSERT(pDlg, "Dialogdiet fail!");//CHINA001
UINT16 nResult = pDlg->Execute();
if(nResult == RET_OK)
{
SvxDistributeHorizontal eHor = pDlg->GetDistributeHor();
SvxDistributeVertical eVer = pDlg->GetDistributeVer();
ImpDistributeEntryList aEntryList;
UINT32 a, nInsPos, nFullLength;
BegUndo();
if(eHor != SvxDistributeHorizontalNone)
{
// build sorted entry list
nFullLength = 0L;
for(a=0;a<nMark;a++)
{
SdrMark* pMark = GetSdrMarkByIndex(a);
ImpDistributeEntry* pNew = new ImpDistributeEntry;
pNew->mpObj = pMark->GetMarkedSdrObj();
nInsPos = 0;
switch(eHor)
{
case SvxDistributeHorizontalLeft:
{
pNew->mnPos = pNew->mpObj->GetSnapRect().Left();
break;
}
case SvxDistributeHorizontalCenter:
{
pNew->mnPos = (pNew->mpObj->GetSnapRect().Right() + pNew->mpObj->GetSnapRect().Left()) / 2;
break;
}
case SvxDistributeHorizontalDistance:
{
pNew->mnLength = pNew->mpObj->GetSnapRect().GetWidth() + 1;
nFullLength += pNew->mnLength;
pNew->mnPos = (pNew->mpObj->GetSnapRect().Right() + pNew->mpObj->GetSnapRect().Left()) / 2;
break;
}
case SvxDistributeHorizontalRight:
{
pNew->mnPos = pNew->mpObj->GetSnapRect().Right();
break;
}
default: break;
}
while(nInsPos < aEntryList.Count() && aEntryList.GetObject(nInsPos)->mnPos < pNew->mnPos)
nInsPos++;
aEntryList.Insert(pNew, nInsPos);
}
if(eHor == SvxDistributeHorizontalDistance)
{
// calc room in-between
INT32 nWidth = GetAllMarkedBoundRect().GetWidth() + 1;
double fStepWidth = ((double)nWidth - (double)nFullLength) / (double)(aEntryList.Count() - 1);
double fStepStart = (double)aEntryList.GetObject(0)->mnPos;
fStepStart += fStepWidth + (double)((aEntryList.GetObject(0)->mnLength + aEntryList.GetObject(1)->mnLength) / 2);
// move entries 1..n-1
for(a=1;a<aEntryList.Count()-1;a++)
{
ImpDistributeEntry* pCurr = aEntryList.GetObject(a);
ImpDistributeEntry* pNext = aEntryList.GetObject(a+1);
INT32 nDelta = (INT32)(fStepStart + 0.5) - pCurr->mnPos;
AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pCurr->mpObj));
pCurr->mpObj->Move(Size(nDelta, 0));
fStepStart += fStepWidth + (double)((pCurr->mnLength + pNext->mnLength) / 2);
}
}
else
{
// calc distances
INT32 nWidth = aEntryList.GetObject(aEntryList.Count() - 1)->mnPos - aEntryList.GetObject(0)->mnPos;
double fStepWidth = (double)nWidth / (double)(aEntryList.Count() - 1);
double fStepStart = (double)aEntryList.GetObject(0)->mnPos;
fStepStart += fStepWidth;
// move entries 1..n-1
for(a=1;a<aEntryList.Count()-1;a++)
{
ImpDistributeEntry* pCurr = aEntryList.GetObject(a);
INT32 nDelta = (INT32)(fStepStart + 0.5) - pCurr->mnPos;
AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pCurr->mpObj));
pCurr->mpObj->Move(Size(nDelta, 0));
fStepStart += fStepWidth;
}
}
// clear list
while(aEntryList.Count())
delete aEntryList.Remove((ULONG)0L);
}
if(eVer != SvxDistributeVerticalNone)
{
// build sorted entry list
nFullLength = 0L;
for(a=0;a<nMark;a++)
{
SdrMark* pMark = GetSdrMarkByIndex(a);
ImpDistributeEntry* pNew = new ImpDistributeEntry;
pNew->mpObj = pMark->GetMarkedSdrObj();
nInsPos = 0;
switch(eVer)
{
case SvxDistributeVerticalTop:
{
pNew->mnPos = pNew->mpObj->GetSnapRect().Top();
break;
}
case SvxDistributeVerticalCenter:
{
pNew->mnPos = (pNew->mpObj->GetSnapRect().Bottom() + pNew->mpObj->GetSnapRect().Top()) / 2;
break;
}
case SvxDistributeVerticalDistance:
{
pNew->mnLength = pNew->mpObj->GetSnapRect().GetHeight() + 1;
nFullLength += pNew->mnLength;
pNew->mnPos = (pNew->mpObj->GetSnapRect().Bottom() + pNew->mpObj->GetSnapRect().Top()) / 2;
break;
}
case SvxDistributeVerticalBottom:
{
pNew->mnPos = pNew->mpObj->GetSnapRect().Bottom();
break;
}
default: break;
}
while(nInsPos < aEntryList.Count() && aEntryList.GetObject(nInsPos)->mnPos < pNew->mnPos)
nInsPos++;
aEntryList.Insert(pNew, nInsPos);
}
if(eVer == SvxDistributeVerticalDistance)
{
// calc room in-between
INT32 nHeight = GetAllMarkedBoundRect().GetHeight() + 1;
double fStepWidth = ((double)nHeight - (double)nFullLength) / (double)(aEntryList.Count() - 1);
double fStepStart = (double)aEntryList.GetObject(0)->mnPos;
fStepStart += fStepWidth + (double)((aEntryList.GetObject(0)->mnLength + aEntryList.GetObject(1)->mnLength) / 2);
// move entries 1..n-1
for(a=1;a<aEntryList.Count()-1;a++)
{
ImpDistributeEntry* pCurr = aEntryList.GetObject(a);
ImpDistributeEntry* pNext = aEntryList.GetObject(a+1);
INT32 nDelta = (INT32)(fStepStart + 0.5) - pCurr->mnPos;
AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pCurr->mpObj));
pCurr->mpObj->Move(Size(0, nDelta));
fStepStart += fStepWidth + (double)((pCurr->mnLength + pNext->mnLength) / 2);
}
}
else
{
// calc distances
INT32 nHeight = aEntryList.GetObject(aEntryList.Count() - 1)->mnPos - aEntryList.GetObject(0)->mnPos;
double fStepWidth = (double)nHeight / (double)(aEntryList.Count() - 1);
double fStepStart = (double)aEntryList.GetObject(0)->mnPos;
fStepStart += fStepWidth;
// move entries 1..n-1
for(a=1;a<aEntryList.Count()-1;a++)
{
ImpDistributeEntry* pCurr = aEntryList.GetObject(a);
INT32 nDelta = (INT32)(fStepStart + 0.5) - pCurr->mnPos;
AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pCurr->mpObj));
pCurr->mpObj->Move(Size(0, nDelta));
fStepStart += fStepWidth;
}
}
// clear list
while(aEntryList.Count())
delete aEntryList.Remove((ULONG)0L);
}
// UNDO-Comment and end of UNDO
SetUndoComment(ImpGetResStr(STR_DistributeMarkedObjects));
EndUndo();
}
delete(pDlg);
}
}
#endif
}
void SdrEditView::MergeMarkedObjects(SdrMergeMode eMode)
{
SdrMarkList aRemove;
SortMarkedObjects();
BegUndo();
UINT32 nInsPos=0xFFFFFFFF;
//UINT32 nAnz=GetMarkedObjectCount();
const SdrObject* pAttrObj = NULL;
//PolyPolygon3D aMergePolyPolygonA;
//PolyPolygon3D aMergePolyPolygonB;
::basegfx::B2DPolyPolygon aMergePolyPolygonA;
::basegfx::B2DPolyPolygon aMergePolyPolygonB;
SdrObjList* pInsOL = NULL;
SdrPageView* pInsPV = NULL;
BOOL bFirstObjectComplete(FALSE);
// make sure selected objects are contour objects
// since now ::basegfx::tools::adaptiveSubdivide() is used, it is no longer
// necessary to use ConvertMarkedToPolyObj which will subdivide curves using the old
// mechanisms. In a next step the polygon clipper will even be able to clip curves...
// ConvertMarkedToPolyObj(TRUE);
ConvertMarkedToPathObj(sal_True);
for(UINT32 a=0;a<GetMarkedObjectCount();a++)
{
SdrMark* pM = GetSdrMarkByIndex(a);
SdrObject* pObj = pM->GetMarkedSdrObj();
if(ImpCanConvertForCombine(pObj))
{
if(!pAttrObj)
pAttrObj = pObj;
nInsPos = pObj->GetOrdNum() + 1;
pInsPV = pM->GetPageView();
pInsOL = pObj->GetObjList();
// get the polygons; do NOT use ImpGetXPolyPoly here - it does fetch all
// the polygons, but they are all put in one single XPolyPolygon so that
// no SetDirections() on single objects can be made. This would lead to
// wrong results.
SdrObjList* pObjectList = pObj->GetSubList();
//Vector3D aCommonNormal(0.0, 0.0, 1.0);
if(pObjectList)
{
SdrObjListIter aIter(*pObjectList, IM_DEEPWITHGROUPS);
while(aIter.IsMore())
{
SdrObject* pCandidate = aIter.Next();
SdrPathObj* pPathObj = PTR_CAST(SdrPathObj, pCandidate);
if(pPathObj)
{
//PolyPolygon3D aTmpPoly3D(pPathObj->GetPathPoly());
//aTmpPoly3D.SetDirections(aCommonNormal);
::basegfx::B2DPolyPolygon aTmpPoly(pPathObj->GetPathPoly().getB2DPolyPolygon());
if(aTmpPoly.areControlPointsUsed())
{
aTmpPoly = ::basegfx::tools::adaptiveSubdivideByAngle(aTmpPoly);
}
// #i37009#
aTmpPoly = ::basegfx::tools::correctOrientations(aTmpPoly);
if(!bFirstObjectComplete)
{
//aMergePolyPolygonA.Insert(aTmpPoly3D);
aMergePolyPolygonA.append(aTmpPoly);
}
else
{
//aMergePolyPolygonB.Insert(aTmpPoly3D);
aMergePolyPolygonB.append(aTmpPoly);
}
}
}
}
else
{
SdrPathObj* pPathObj = PTR_CAST(SdrPathObj, pObj);
if(pPathObj)
{
//PolyPolygon3D aTmpPoly3D(pPathObj->GetPathPoly());
//aTmpPoly3D.SetDirections(aCommonNormal);
::basegfx::B2DPolyPolygon aTmpPoly(pPathObj->GetPathPoly().getB2DPolyPolygon());
if(aTmpPoly.areControlPointsUsed())
{
aTmpPoly = ::basegfx::tools::adaptiveSubdivideByAngle(aTmpPoly);
}
// #i37009#
aTmpPoly = ::basegfx::tools::correctOrientations(aTmpPoly);
if(!bFirstObjectComplete)
{
//aMergePolyPolygonA.Insert(aTmpPoly3D);
aMergePolyPolygonA.append(aTmpPoly);
}
else
{
//aMergePolyPolygonB.Insert(aTmpPoly3D);
aMergePolyPolygonB.append(aTmpPoly);
}
}
}
// was there something added to the first poly?
//if(!bFirstObjectComplete && aMergePolyPolygonA.Count())
if(!bFirstObjectComplete && aMergePolyPolygonA.count())
{
bFirstObjectComplete = TRUE;
}
// move object to temporary delete list
aRemove.InsertEntry(SdrMark(pObj, pM->GetPageView()));
}
}
switch(eMode)
{
case SDR_MERGE_MERGE:
{
// simple merge all contained parts (OR)
//aMergePolyPolygonA.Insert(aMergePolyPolygonB);
//aMergePolyPolygonA.Merge(FALSE);
aMergePolyPolygonA.append(aMergePolyPolygonB);
//BFS08 ::basegfx::tools::removeIntersections(aMergePolyPolygonA, sal_False);
aMergePolyPolygonA = ::basegfx::tools::removeAllIntersections(aMergePolyPolygonA);
aMergePolyPolygonA = ::basegfx::tools::removeNeutralPolygons(aMergePolyPolygonA, sal_True);
break;
}
case SDR_MERGE_SUBSTRACT:
{
// take selected poly 2..n (is in Polygon B), merge them, flipdirections
// and merge with poly 1
//aMergePolyPolygonA.Merge(FALSE);
//aMergePolyPolygonB.Merge(FALSE);
//aMergePolyPolygonB.FlipDirections();
//aMergePolyPolygonA.Insert(aMergePolyPolygonB);
//aMergePolyPolygonA.Merge(FALSE);
//BFS08 ::basegfx::tools::removeIntersections(aMergePolyPolygonA, sal_False);
aMergePolyPolygonA = ::basegfx::tools::removeAllIntersections(aMergePolyPolygonA);
aMergePolyPolygonA = ::basegfx::tools::removeNeutralPolygons(aMergePolyPolygonA, sal_True);
//BFS08 ::basegfx::tools::removeIntersections(aMergePolyPolygonB, sal_False);
aMergePolyPolygonB = ::basegfx::tools::removeAllIntersections(aMergePolyPolygonB);
aMergePolyPolygonB = ::basegfx::tools::removeNeutralPolygons(aMergePolyPolygonB, sal_True);
aMergePolyPolygonB.flip();
aMergePolyPolygonA.append(aMergePolyPolygonB);
//BFS08 ::basegfx::tools::removeIntersections(aMergePolyPolygonA, sal_False);
aMergePolyPolygonA = ::basegfx::tools::removeAllIntersections(aMergePolyPolygonA);
aMergePolyPolygonA = ::basegfx::tools::removeNeutralPolygons(aMergePolyPolygonA, sal_True);
// #72995# one more call to resolve self intersections which
// may have been built by substracting (see bug)
//aMergePolyPolygonA.Merge(FALSE);
//BFS08 ::basegfx::tools::removeIntersections(aMergePolyPolygonA, sal_False);
aMergePolyPolygonA = ::basegfx::tools::removeAllIntersections(aMergePolyPolygonA);
aMergePolyPolygonA = ::basegfx::tools::removeNeutralPolygons(aMergePolyPolygonA, sal_True);
break;
}
case SDR_MERGE_INTERSECT:
{
// cut poly 1 against polys 2..n (AND)
//aMergePolyPolygonA.Merge(FALSE);
//aMergePolyPolygonB.Merge(FALSE);
//aMergePolyPolygonA.Insert(aMergePolyPolygonB);
//aMergePolyPolygonA.Merge(FALSE, TRUE);
//BFS08 ::basegfx::tools::removeIntersections(aMergePolyPolygonA, sal_False);
aMergePolyPolygonA = ::basegfx::tools::removeAllIntersections(aMergePolyPolygonA);
aMergePolyPolygonA = ::basegfx::tools::removeNeutralPolygons(aMergePolyPolygonA, sal_True);
//BFS08 ::basegfx::tools::removeIntersections(aMergePolyPolygonB, sal_False);
aMergePolyPolygonB = ::basegfx::tools::removeAllIntersections(aMergePolyPolygonB);
aMergePolyPolygonB = ::basegfx::tools::removeNeutralPolygons(aMergePolyPolygonB, sal_True);
aMergePolyPolygonA.append(aMergePolyPolygonB);
//BFS08 ::basegfx::tools::removeIntersections(aMergePolyPolygonA, sal_False, sal_True);
aMergePolyPolygonA = ::basegfx::tools::removeAllIntersections(aMergePolyPolygonA);
aMergePolyPolygonA = ::basegfx::tools::removeNeutralPolygons(aMergePolyPolygonA, sal_False);
break;
}
}
// XPolyPolygon aXPP = aMergePolyPolygonA.GetXPolyPolygon();
XPolyPolygon aXPP(aMergePolyPolygonA);
SdrPathObj* pPath = new SdrPathObj(OBJ_PATHFILL, aXPP);
ImpCopyAttributes(pAttrObj, pPath);
SdrInsertReason aReason(SDRREASON_VIEWCALL, pAttrObj);
pInsOL->InsertObject(pPath, nInsPos, &aReason);
AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pPath));
MarkObj(pPath, pInsPV, FALSE, TRUE);
aRemove.ForceSort();
switch(eMode)
{
case SDR_MERGE_MERGE:
{
SetUndoComment(
ImpGetResStr(STR_EditMergeMergePoly),
aRemove.GetMarkDescription());
break;
}
case SDR_MERGE_SUBSTRACT:
{
SetUndoComment(
ImpGetResStr(STR_EditMergeSubstractPoly),
aRemove.GetMarkDescription());
break;
}
case SDR_MERGE_INTERSECT:
{
SetUndoComment(
ImpGetResStr(STR_EditMergeIntersectPoly),
aRemove.GetMarkDescription());
break;
}
}
DeleteMarkedList(aRemove);
EndUndo();
}
BOOL SdrEditView::CombineMarkedObjects(BOOL bNoPolyPoly)
{
// #105899# Start of Combine-Undo put to front, else ConvertMarkedToPolyObj would
// create a 2nd Undo-action and Undo-Comment.
// Undo-String will be set later
BegUndo(String(), String(),
bNoPolyPoly ? SDRREPFUNC_OBJ_COMBINE_ONEPOLY : SDRREPFUNC_OBJ_COMBINE_POLYPOLY);
// #105899# First, guarantee that all objects are converted to polyobjects,
// especially for SdrGrafObj with bitmap filling this is necessary to not
// loose the bitmap filling.
// #i12392#
// ConvertMarkedToPolyObj was too strong here, it will loose quality and
// information when curve objects are combined. This can be replaced by
// using ConvertMarkedToPathObj without changing the previous fix.
// #i21250#
// Instead of simply passing sal_True as LineToArea, use bNoPolyPoly as info
// if this command is a 'Combine' or a 'Connect' command. On Connect it's sal_True.
// To not concert line segments with a set line width to polygons in that case,
// use this info. Do not convert LineToArea on Connect commands.
// ConvertMarkedToPathObj(!bNoPolyPoly);
// #114310#
// This is used for Combine and Connect. In no case it is necessary to force
// the content to curve, but it is also not good to force to polygons. Thus,
// curve is the less information loosing one. Remember: This place is not
// used for merge.
// LineToArea is never necessary, both commands are able to take over the
// set line style and to display it correctly. Thus, i will use a
// ConvertMarkedToPathObj with a sal_False in any case. Only drawback is that
// simple polygons will be changed to curves, but with no information loss.
ConvertMarkedToPathObj(sal_False /* bLineToArea */);
// continue as before
bCombineError = FALSE;
XPolyPolygon aXPP;
SdrObjList* pAktOL = NULL;
// Temporaere Marklist
SdrMarkList aRemoveMerker;
SortMarkedObjects();
ULONG nInsPos=0xFFFFFFFF;
SdrObjList* pInsOL=NULL;
SdrPageView* pInsPV=NULL;
ULONG nAktPointCount=0; // Gesamtpunkteanzahl aller Teilpolygone des PolyPolygons
ULONG nm;
ULONG nAnz=GetMarkedObjectCount();
const SdrObject* pAttrObj=NULL;
for (nm=nAnz; nm>0 && !bCombineError;) {
nm--;
SdrMark* pM=GetSdrMarkByIndex(nm);
SdrObject* pObj=pM->GetMarkedSdrObj();
SdrObjList* pThisOL=pObj->GetObjList();
if (pAktOL!=pThisOL) {
pAktOL=pThisOL;
}
if (ImpCanConvertForCombine(pObj)) {
pAttrObj=pObj; // Obj merken fuer Attribute kopieren
XPolyPolygon aTmpXPP(ImpGetXPolyPoly(pObj, TRUE));
ULONG nAktPolyCount=aXPP.Count();
ULONG nTmpPolyCount=aTmpXPP.Count();
ULONG nTmpPointCount=0;
for (ULONG nTmpPolyNum=0; nTmpPolyNum<nTmpPolyCount; nTmpPolyNum++) {
nTmpPointCount+=aTmpXPP[(USHORT)nTmpPolyNum].GetPointCount();
}
if (nAktPolyCount+nTmpPolyCount<=0xFFFF && nAktPointCount+nTmpPointCount<=XPOLY_MAXPOINTS) {
aXPP.Insert(aTmpXPP,0);
nAktPointCount+=nTmpPointCount;
} else {
bCombineError=TRUE;
}
if (pInsOL==NULL) {
nInsPos=pObj->GetOrdNum()+1;
pInsPV=pM->GetPageView();
pInsOL=pObj->GetObjList();
}
aRemoveMerker.InsertEntry(SdrMark(pObj,pM->GetPageView()));
}
}
long nJoinTol=10;
if (bNoPolyPoly && !bCombineError) ImpCombineToSinglePoly(aXPP,nJoinTol);
USHORT nPolyCount=aXPP.Count();
if (nPolyCount!=0 && !bCombineError) {
SdrObjKind eKind=OBJ_PATHFILL;
if (nPolyCount>1) {
// Polygone ggf. schliessen (Polylines,...)
for (USHORT i=0; i<nPolyCount; i++) {
const XPolygon& rXP=aXPP.GetObject(i);
USHORT nPointCount=rXP.GetPointCount();
USHORT nMaxPoint=USHORT(nPointCount-1);
if (nPointCount>0 && rXP[0]!=rXP[nMaxPoint]) { // nicht geschlossen?
// XPolygon um einen Punkt erweitern (zum schliessen)
aXPP[i][nPointCount]=aXPP[i][0];
}
}
} else { // auf Polyline Checken
const XPolygon& rXP=aXPP.GetObject(0);
USHORT nPointCount=rXP.GetPointCount();
USHORT nMaxPoint=USHORT(nPointCount-1);
if (nPointCount<=2) eKind=OBJ_PATHLINE;
else {
const Point& rPt0=rXP[0];
const Point& rPt1=rXP[nMaxPoint];
if (rPt0!=rPt1) { // nicht geschlossen?
long nDist=Abs(rPt0.X()-rPt1.X())+Abs(rPt0.Y()-rPt1.Y());
if (nDist<=nJoinTol) {
long x=(rPt0.X()+rPt1.X()+1)/2;
long y=(rPt0.Y()+rPt1.Y()+1)/2;
Point aMitte(x,y);
aXPP[0][0]=aMitte;
aXPP[0][nMaxPoint]=aMitte;
} else {
eKind=OBJ_PATHLINE;
}
}
}
}
SdrPathObj* pPath=new SdrPathObj(eKind,aXPP);
// Attribute des untersten Objekts
ImpCopyAttributes(pAttrObj,pPath);
// #100408# If LineStyle of pAttrObj is XLINE_NONE force to XLINE_SOLID to make visible.
const XLineStyle eLineStyle = ((const XLineStyleItem&)pAttrObj->GetMergedItem(XATTR_LINESTYLE)).GetValue();
const XFillStyle eFillStyle = ((const XFillStyleItem&)pAttrObj->GetMergedItem(XATTR_FILLSTYLE)).GetValue();
// #110635#
// Take fill style/closed state of pAttrObj in account when deciding to change the line style
sal_Bool bIsClosedPathObj(pAttrObj->ISA(SdrPathObj) && ((SdrPathObj*)pAttrObj)->IsClosed());
if(XLINE_NONE == eLineStyle && (XFILL_NONE == eFillStyle || !bIsClosedPathObj))
{
pPath->SetMergedItem(XLineStyleItem(XLINE_SOLID));
}
SdrInsertReason aReason(SDRREASON_VIEWCALL,pAttrObj);
pInsOL->InsertObject(pPath,nInsPos,&aReason);
AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pPath));
// #111111#
// Here was a severe error: Without UnmarkAllObj, the new object was marked
// additionally to the two ones which are deleted below. As long as those are
// in the UNDO there is no problem, but as soon as they get deleted, the
// MarkList will contain deleted objects -> GPF.
UnmarkAllObj(pInsPV);
MarkObj(pPath, pInsPV, FALSE, TRUE);
}
if (!bCombineError) {
// UndoComment aus den tatsaechlich verwendeten Objekten zusammenbauen
aRemoveMerker.ForceSort(); // wichtig fuer Remove (s.u.)
SetUndoComment(ImpGetResStr(bNoPolyPoly?STR_EditCombine_OnePoly:STR_EditCombine_PolyPoly),aRemoveMerker.GetMarkDescription());
// die tatsaechlich verwendeten Objekten aus der Liste entfernen
DeleteMarkedList(aRemoveMerker);
}
EndUndo();
return !bCombineError;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// @@@@@ @@ @@@@ @@ @@ @@@@ @@ @@ @@@@@@ @@ @@@@@
// @@ @@ @@ @@ @@ @@@ @@@ @@ @@ @@@ @@ @@ @@ @@
// @@ @@ @@ @@ @@@@@@@ @@ @@ @@@@@@ @@ @@ @@
// @@ @@ @@ @@@@ @@@@@@@ @@@@@@ @@@@@@ @@ @@ @@@@
// @@ @@ @@ @@ @@ @ @@ @@ @@ @@ @@@ @@ @@ @@
// @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@
// @@@@@ @@ @@@@ @@ @@ @@ @@ @@ @@ @@ @@@@@ @@@@@
//
////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL SdrEditView::ImpCanDismantle(const XPolyPolygon& rXPP, BOOL bMakeLines) const
{
BOOL bCan=FALSE;
USHORT nPolyAnz=rXPP.Count();
// Dismantle macht erst Sinn ab 2 Polygone im PolyPolygon
if (nPolyAnz>=2) bCan=TRUE;
else if (bMakeLines && nPolyAnz==1) { // oder ab 2 Linien bzw. 2 Segmenten im Polygon
const XPolygon& rXP=rXPP[0];
USHORT nPointAnz=rXP.GetPointCount();
if (nPointAnz>4) bCan=TRUE;
else if (nPointAnz>2) { // sonst ist es nur eine Linie
if (!rXP.IsControl(1)) bCan=TRUE; // sonst ist es nun ein Beziersegment
}
}
return bCan;
}
BOOL SdrEditView::ImpCanDismantle(const SdrObject* pObj, BOOL bMakeLines) const
{
BOOL bOtherObjs=FALSE; // TRUE=andere Objekte ausser PathObj's vorhanden
BOOL bMin1PolyPoly=FALSE; // TRUE=mind. 1 PolyPolygon mit mehr als ein Polygon vorhanden
SdrObjList* pOL=pObj->GetSubList();
if (pOL!=NULL) {
// Aha, Gruppenobjekt. Also alle Member ansehen.
// Alle muessen PathObjs sein !
SdrObjListIter aIter(*pOL,IM_DEEPNOGROUPS);
while (aIter.IsMore() && !bOtherObjs) {
const SdrObject* pObj1=aIter.Next();
const SdrPathObj* pPath=PTR_CAST(SdrPathObj,pObj1);
if (pPath!=NULL) {
if (ImpCanDismantle(pPath->GetPathPoly(),bMakeLines)) bMin1PolyPoly=TRUE;
SdrObjTransformInfoRec aInfo;
pObj1->TakeObjInfo(aInfo);
if (!aInfo.bCanConvToPath) bOtherObjs=TRUE; // Passiert z.B. im Falle Fontwork (Joe, 28-11-95)
} else {
bOtherObjs=TRUE;
}
}
}
else
{
const SdrPathObj* pPath = PTR_CAST(SdrPathObj, pObj);
const SdrObjCustomShape* pCustomShape = PTR_CAST(SdrObjCustomShape, pObj);
// #i37011#
if(pPath)
{
if (ImpCanDismantle(pPath->GetPathPoly(),bMakeLines)) bMin1PolyPoly=TRUE;
SdrObjTransformInfoRec aInfo;
pObj->TakeObjInfo(aInfo);
// #69711 : new condition IsLine() to be able to break simple Lines
if (!(aInfo.bCanConvToPath || aInfo.bCanConvToPoly) && !pPath->IsLine() ) bOtherObjs=TRUE; // Passiert z.B. im Falle Fontwork (Joe, 28-11-95)
}
else if(pCustomShape)
{
if(bMakeLines)
{
// allow break command
bMin1PolyPoly = TRUE;
}
}
else
{
bOtherObjs = TRUE;
}
}
return bMin1PolyPoly && !bOtherObjs;
}
void SdrEditView::ImpDismantleOneObject(const SdrObject* pObj, SdrObjList& rOL, ULONG& rPos, SdrPageView* pPV, BOOL bMakeLines)
{
const SdrPathObj* pSrcPath = PTR_CAST(SdrPathObj, pObj);
const SdrObjCustomShape* pCustomShape = PTR_CAST(SdrObjCustomShape, pObj);
// #i37011#
if(pSrcPath)
{
SdrObject* pLast=NULL; // // fuer die Zuweisung des OutlinerParaObject
const XPolyPolygon& rXPP=pSrcPath->GetPathPoly();
USHORT nPolyAnz=rXPP.Count();
for (USHORT i=0; i<nPolyAnz; i++) {
const XPolygon& rAktXP=rXPP.GetObject(i);
const XPolygon* pXP=&rAktXP;
XPolygon aTmpPoly;
USHORT nPointAnz=rAktXP.GetPointCount();
if (nPointAnz<2) bMakeLines=FALSE;
for (USHORT nPoint=0; nPoint<nPointAnz; nPoint++) {
SdrObjKind eKind=OBJ_PATHFILL;
if (bMakeLines) {
eKind=OBJ_PLIN;
pXP=&aTmpPoly;
aTmpPoly.SetSize(2);
aTmpPoly[0]=rAktXP[nPoint];
aTmpPoly.SetFlags(0,XPOLY_NORMAL);
aTmpPoly[1]=rAktXP[nPoint+1];
aTmpPoly.SetFlags(1,rAktXP.GetFlags(nPoint+1));
if (aTmpPoly.IsControl(1) && nPoint+3<nPointAnz) { // Aha, Beziersegment
aTmpPoly[2]=rAktXP[nPoint+2];
aTmpPoly.SetFlags(2,rAktXP.GetFlags(nPoint+2));
aTmpPoly[3]=rAktXP[nPoint+3];
aTmpPoly.SetFlags(3,rAktXP.GetFlags(nPoint+3));
nPoint+=2;
eKind=OBJ_PATHLINE;
}
aTmpPoly.SetFlags(USHORT(aTmpPoly.GetPointCount()-1),XPOLY_NORMAL);
if (nPoint>=USHORT(nPointAnz-2)) nPoint=nPointAnz;
} else {
nPoint=nPointAnz;
eKind=SdrObjKind(pSrcPath->GetObjIdentifier());
}
SdrPathObj* pPath=new SdrPathObj(eKind,XPolyPolygon(*pXP));
ImpCopyAttributes(pSrcPath,pPath);
pLast=pPath;
SdrInsertReason aReason(SDRREASON_VIEWCALL,pSrcPath);
rOL.InsertObject(pPath,rPos,&aReason);
AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pPath,TRUE));
MarkObj(pPath,pPV,FALSE,TRUE);
rPos++;
}
}
if (pLast!=NULL && pSrcPath->GetOutlinerParaObject()!=NULL)
pLast->SetOutlinerParaObject(pSrcPath->GetOutlinerParaObject()->Clone());
}
else if(pCustomShape)
{
if(bMakeLines)
{
// break up custom shape
const SdrObject* pReplacement = pCustomShape->GetSdrObjectFromCustomShape();
if(pReplacement)
{
SdrObject* pCandidate = pReplacement->Clone();
DBG_ASSERT(pCandidate, "SdrEditView::ImpDismantleOneObject: Could not clone SdrObject (!)");
pCandidate->SetModel(pCustomShape->GetModel());
if(((SdrShadowItem&)pCustomShape->GetMergedItem(SDRATTR_SHADOW)).GetValue())
{
if(pReplacement->ISA(SdrObjGroup))
{
pCandidate->SetMergedItem(SdrShadowItem(sal_True));
}
}
SdrInsertReason aReason(SDRREASON_VIEWCALL, pCustomShape);
rOL.InsertObject(pCandidate, rPos, &aReason);
AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pCandidate, true));
MarkObj(pCandidate, pPV, FALSE, TRUE);
if(pCustomShape->HasText() && !pCustomShape->IsTextPath())
{
// #i37011# also create a text object and add at rPos + 1
SdrTextObj* pTextObj = (SdrTextObj*)SdrObjFactory::MakeNewObject(
pCustomShape->GetObjInventor(), OBJ_TEXT, 0L, pCustomShape->GetModel());
// Copy text content
OutlinerParaObject* pParaObj = pCustomShape->GetOutlinerParaObject();
if(pParaObj)
{
pTextObj->NbcSetOutlinerParaObject(pParaObj->Clone());
}
// copy all attributes
SfxItemSet aTargetItemSet(pCustomShape->GetMergedItemSet());
// clear fill and line style
aTargetItemSet.Put(XLineStyleItem(XLINE_NONE));
aTargetItemSet.Put(XFillStyleItem(XFILL_NONE));
// get the text bounds and set at text object
Rectangle aTextBounds = pCustomShape->GetSnapRect();
if(pCustomShape->GetTextBounds(aTextBounds))
{
pTextObj->SetSnapRect(aTextBounds);
}
// if rotated, copy GeoStat, too.
const GeoStat& rSourceGeo = pCustomShape->GetGeoStat();
if(rSourceGeo.nDrehWink)
{
pTextObj->NbcRotate(
pCustomShape->GetSnapRect().Center(), rSourceGeo.nDrehWink,
rSourceGeo.nSin, rSourceGeo.nCos);
}
// set modified ItemSet at text object
pTextObj->SetMergedItemSet(aTargetItemSet);
// insert object
rOL.InsertObject(pTextObj, rPos + 1, &aReason);
AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pTextObj, true));
MarkObj(pTextObj, pPV, FALSE, TRUE);
}
}
}
}
}
void SdrEditView::DismantleMarkedObjects(BOOL bMakeLines)
{
//UINT32 nCnt(0);
// Temporaere Marklist
SdrMarkList aRemoveMerker;
SortMarkedObjects();
// Der Comment wird spaeter zusammengebaut
BegUndo(String(), String(),
bMakeLines ? SDRREPFUNC_OBJ_DISMANTLE_LINES : SDRREPFUNC_OBJ_DISMANTLE_POLYS);
ULONG nm;
ULONG nAnz=GetMarkedObjectCount();
SdrObjList* pOL0=NULL;
for (nm=nAnz; nm>0;) {
nm--;
SdrMark* pM=GetSdrMarkByIndex(nm);
SdrObject* pObj=pM->GetMarkedSdrObj();
SdrPageView* pPV=pM->GetPageView();
SdrObjList* pOL=pObj->GetObjList();
if (pOL!=pOL0) { pOL0=pOL; pObj->GetOrdNum(); } // sicherstellen, dass OrdNums stimmen!
if (ImpCanDismantle(pObj,bMakeLines)) {
aRemoveMerker.InsertEntry(SdrMark(pObj,pM->GetPageView()));
ULONG nPos0=pObj->GetOrdNumDirect();
ULONG nPos=nPos0+1;
SdrObjList* pSubList=pObj->GetSubList();
if (pSubList!=NULL && !pObj->Is3DObj()) {
SdrObjListIter aIter(*pSubList,IM_DEEPNOGROUPS);
while (aIter.IsMore()) {
const SdrObject* pObj1=aIter.Next();
ImpDismantleOneObject(pObj1,*pOL,nPos,pPV,bMakeLines);
}
} else {
ImpDismantleOneObject(pObj,*pOL,nPos,pPV,bMakeLines);
}
AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj,TRUE));
pOL->RemoveObject(nPos0);
}
}
// UndoComment aus den tatsaechlich verwendeten Objekten zusammenbauen
SetUndoComment(ImpGetResStr(bMakeLines?STR_EditDismantle_Lines:STR_EditDismantle_Polys),aRemoveMerker.GetMarkDescription());
// die tatsaechlich verwendeten Objekten aus der Liste entfernen
EndUndo();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// #### #### ### # # ####
// # # # # # # # # #
// # ## #### # # # # ####
// # # # # # # # # #
// #### # # ### ### #
//
////////////////////////////////////////////////////////////////////////////////////////////////////
void SdrEditView::GroupMarked(const SdrObject* pUserGrp)
{
if (AreObjectsMarked()) {
BegUndo(ImpGetResStr(STR_EditGroup),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_GROUP);
SortMarkedObjects();
ULONG nAnz=GetMarkedObjectCount();
for (ULONG nm=nAnz; nm>0;) { // UndoActions fuer alle betroffenen Objekte anlegen
nm--;
SdrMark* pM=GetSdrMarkByIndex(nm);
AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoRemoveObject(*pM->GetMarkedSdrObj()));
}
SdrMarkList aNewMark;
for (USHORT nv=0; nv<GetPageViewCount(); nv++) {
SdrPageView* pPV=GetPageViewPvNum(nv);
SdrObjList* pAktLst=pPV->GetObjList();
SdrObjList* pSrcLst=pAktLst;
SdrObjList* pSrcLst0=pSrcLst;
SdrPage* pPage=pPV->GetPage();
// sicherstellen, dass die OrdNums stimmen
if (pSrcLst->IsObjOrdNumsDirty()) pSrcLst->RecalcObjOrdNums();
SdrObject* pGrp=NULL;
SdrObject* pRefObj=NULL; // Referenz fuer InsertReason (-> rumankern im Writer)
SdrObject* pRefObj1=NULL; // Referenz fuer InsertReason (-> rumankern im Writer)
SdrObjList* pDstLst=NULL;
// Falls alle markierten Objekte aus Fremden Obj-Listen
// kommen, kommt das Gruppenobjekt an das Ende der Liste.
ULONG nInsPos=pSrcLst->GetObjCount();
BOOL bNeedInsPos=TRUE;
for (ULONG nm=GetMarkedObjectCount(); nm>0;) {
nm--;
SdrMark* pM=GetSdrMarkByIndex(nm);
if (pM->GetPageView()==pPV) {
if (pGrp==NULL) {
if (pUserGrp!=NULL) pGrp=pUserGrp->Clone();
if (pGrp==NULL) pGrp=new SdrObjGroup;
pDstLst=pGrp->GetSubList();
DBG_ASSERT(pDstLst!=NULL,"Angebliches Gruppenobjekt liefert keine Objektliste");
}
SdrObject* pObj=pM->GetMarkedSdrObj();
pSrcLst=pObj->GetObjList();
if (pSrcLst!=pSrcLst0) {
if (pSrcLst->IsObjOrdNumsDirty()) pSrcLst->RecalcObjOrdNums();
}
BOOL bForeignList=pSrcLst!=pAktLst;
BOOL bGrouped=pSrcLst!=pPage;
if (!bForeignList && bNeedInsPos) {
nInsPos=pObj->GetOrdNum(); // ua, damit sind alle ObjOrdNum der Page gesetzt
nInsPos++;
bNeedInsPos=FALSE;
}
pSrcLst->RemoveObject(pObj->GetOrdNumDirect());
if (!bForeignList) nInsPos--; // InsertPos korregieren
SdrInsertReason aReason(SDRREASON_VIEWCALL);
pDstLst->InsertObject(pObj,0,&aReason);
GetMarkedObjectListWriteAccess().DeleteMark(nm);
if (pRefObj1==NULL) pRefObj1=pObj; // Das oberste sichtbare Objekt
if (!bGrouped) {
if (pRefObj==NULL) pRefObj=pObj; // Das oberste sichtbare nicht gruppierte Objekt
}
pSrcLst0=pSrcLst;
}
}
if (pRefObj==NULL) pRefObj=pRefObj1;
if (pGrp!=NULL) {
aNewMark.InsertEntry(SdrMark(pGrp,pPV));
ULONG nAnz2=pDstLst->GetObjCount();
SdrInsertReason aReason(SDRREASON_VIEWCALL,pRefObj);
pAktLst->InsertObject(pGrp,nInsPos,&aReason);
AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pGrp,true)); // Kein Recalc!
for (ULONG no=0; no<nAnz2; no++) {
AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoInsertObject(*pDstLst->GetObj(no)));
}
}
}
GetMarkedObjectListWriteAccess().Merge(aNewMark);
MarkListHasChanged();
EndUndo();
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// # # # # #### #### ### # # ####
// # # ## # # # # # # # # # #
// # # # # # # ## #### # # # # ####
// # # # ## # # # # # # # # #
// ### # # #### # # ### ### #
//
////////////////////////////////////////////////////////////////////////////////////////////////////
void SdrEditView::UnGroupMarked()
{
SdrMarkList aNewMark;
BegUndo(String(), String(), SDRREPFUNC_OBJ_UNGROUP);
ULONG nCount=0;
XubString aName1;
XubString aName;
BOOL bNameOk=FALSE;
for (ULONG nm=GetMarkedObjectCount(); nm>0;) {
nm--;
SdrMark* pM=GetSdrMarkByIndex(nm);
SdrObject* pGrp=pM->GetMarkedSdrObj();
SdrObjList* pSrcLst=pGrp->GetSubList();
if (pSrcLst!=NULL) {
nCount++;
if (nCount==1) {
pGrp->TakeObjNameSingul(aName); // Bezeichnung der Gruppe holen
pGrp->TakeObjNamePlural(aName1); // Bezeichnung der Gruppe holen
bNameOk=TRUE;
} else {
if (nCount==2) aName=aName1; // Pluralname setzen
if (bNameOk) {
XubString aStr;
pGrp->TakeObjNamePlural(aStr); // Bezeichnung der Gruppe holen
if(!aStr.Equals(aName))
bNameOk = FALSE;
}
}
ULONG nDstCnt=pGrp->GetOrdNum();
SdrObjList* pDstLst=pM->GetPageView()->GetObjList();
// FIRST move contained objects to parent of group, so that
// the contained objects are NOT migrated to the UNDO-ItemPool
// when AddUndo(new SdrUndoDelObj(*pGrp)) is called.
ULONG nAnz=pSrcLst->GetObjCount();
ULONG no;
for (no=nAnz; no>0;) {
no--;
SdrObject* pObj=pSrcLst->GetObj(no);
AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoRemoveObject(*pObj));
}
for (no=0; no<nAnz; no++) {
SdrObject* pObj=pSrcLst->RemoveObject(0);
SdrInsertReason aReason(SDRREASON_VIEWCALL,pGrp);
pDstLst->InsertObject(pObj,nDstCnt,&aReason);
AddUndo( GetModel()->GetSdrUndoFactory().CreateUndoInsertObject(*pObj,true));
nDstCnt++;
// Kein SortCheck beim einfuegen in die MarkList, denn das
// wuerde wg. pObj->GetOrdNum() jedesmal ein RecalcOrdNums()
// provozieren:
aNewMark.InsertEntry(SdrMark(pObj,pM->GetPageView()),FALSE);
}
// Now it is safe to add the delete-UNDO which trigers the
// MigrateItemPool now only for itself, not for the subobjects.
// nDstCnt is right, because previous inserts move group
// object deeper and increase nDstCnt.
AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pGrp));
pDstLst->RemoveObject(nDstCnt);
GetMarkedObjectListWriteAccess().DeleteMark(nm);
}
}
if (nCount!=0)
{
if (!bNameOk) aName=ImpGetResStr(STR_ObjNamePluralGRUP); // Oberbegriff Gruppenobjekte verwenden, wenn verschiedene Objekte.
SetUndoComment(ImpGetResStr(STR_EditUngroup),aName);
}
EndUndo();
if (nCount!=0)
{
GetMarkedObjectListWriteAccess().Merge(aNewMark,TRUE); // Durch das obige Einsortieren ist aNewMark genau verkehrtherum
MarkListHasChanged();
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// ### ### # # # # ##### #### ##### ##### ### #### ### # # #
// # # # # ## # # # # # # # # # # # # # # # # #
// # # # # # # # # #### #### # # # # #### # # # #
// # # # # # ## # # # # # # # # # # # # # #
// ### ### # # # ##### # # # # ### # ### #### #
//
////////////////////////////////////////////////////////////////////////////////////////////////////
SdrObject* SdrEditView::ImpConvertOneObj(SdrObject* pObj, BOOL bPath, BOOL bLineToArea)
{
SdrObject* pNewObj = pObj->ConvertToPolyObj(bPath, bLineToArea);
if (pNewObj!=NULL) {
SdrObjList* pOL=pObj->GetObjList();
DBG_ASSERT(pOL!=NULL,"ConvertTo: Obj liefert keine ObjList");
if (pOL!=NULL) {
AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoReplaceObject(*pObj,*pNewObj));
pOL->ReplaceObject(pNewObj,pObj->GetOrdNum());
}
}
return pNewObj;
}
void SdrEditView::ImpConvertTo(BOOL bPath, BOOL bLineToArea)
{
BOOL bMrkChg=FALSE;
BOOL bModChg=FALSE;
if (AreObjectsMarked()) {
ULONG nMarkAnz=GetMarkedObjectCount();
USHORT nDscrID=0;
if(bLineToArea)
{
if(nMarkAnz == 1)
nDscrID = STR_EditConvToContour;
else
nDscrID = STR_EditConvToContours;
BegUndo(ImpGetResStr(nDscrID), GetDescriptionOfMarkedObjects());
}
else
{
if (bPath) {
if (nMarkAnz==1) nDscrID=STR_EditConvToCurve;
else nDscrID=STR_EditConvToCurves;
BegUndo(ImpGetResStr(nDscrID),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_CONVERTTOPATH);
} else {
if (nMarkAnz==1) nDscrID=STR_EditConvToPoly;
else nDscrID=STR_EditConvToPolys;
BegUndo(ImpGetResStr(nDscrID),GetDescriptionOfMarkedObjects(),SDRREPFUNC_OBJ_CONVERTTOPOLY);
}
}
for (ULONG nm=nMarkAnz; nm>0;) {
nm--;
SdrMark* pM=GetSdrMarkByIndex(nm);
SdrObject* pObj=pM->GetMarkedSdrObj();
SdrPageView* pPV=pM->GetPageView();
if (pObj->IsGroupObject() && !pObj->Is3DObj()) {
SdrObject* pGrp=pObj;
SdrObjListIter aIter(*pGrp,IM_DEEPNOGROUPS);
while (aIter.IsMore()) {
pObj=aIter.Next();
if (ImpConvertOneObj(pObj,bPath,bLineToArea)) bModChg=TRUE;
}
} else {
SdrObject* pNewObj=ImpConvertOneObj(pObj,bPath,bLineToArea);
if (pNewObj!=NULL) {
bModChg=TRUE;
bMrkChg=TRUE;
GetMarkedObjectListWriteAccess().ReplaceMark(SdrMark(pNewObj,pPV),nm);
}
}
}
EndUndo();
if (bMrkChg) AdjustMarkHdl();
if (bMrkChg) MarkListHasChanged();
}
}
void SdrEditView::ConvertMarkedToPathObj(BOOL bLineToArea)
{
ImpConvertTo(TRUE, bLineToArea);
}
void SdrEditView::ConvertMarkedToPolyObj(BOOL bLineToArea)
{
ImpConvertTo(FALSE, bLineToArea);
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// # # ##### ##### ### ##### # # ##### # # # #### ### #### #####
// ## ## # # # # # # # # # ## ## # # # # # # #
// # # # #### # ##### ### # # #### ### # # # # #### # # #### #
// # # # # # # # # # # # # # # # # # # #
// # # ##### # # # # # #### ##### # # # # ### # # #
//
////////////////////////////////////////////////////////////////////////////////////////////////////
void SdrEditView::DoImportMarkedMtf(SvdProgressInfo *pProgrInfo)
{
BegUndo(String(), String(), SDRREPFUNC_OBJ_IMPORTMTF);
SortMarkedObjects();
SdrMarkList aForTheDescription;
SdrMarkList aNewMarked;
ULONG nAnz=GetMarkedObjectCount();
for (ULONG nm=nAnz; nm>0;)
{ // Undo Objekte fuer alle neuen Objekte erzeugen
// zwischen den Metafiles auf Abbruch testen
if( pProgrInfo != NULL )
{
pProgrInfo->SetNextObject();
if(!pProgrInfo->ReportActions(0))
break;
}
nm--;
SdrMark* pM=GetSdrMarkByIndex(nm);
SdrObject* pObj=pM->GetMarkedSdrObj();
SdrPageView* pPV=pM->GetPageView();
SdrObjList* pOL=pObj->GetObjList();
ULONG nInsPos=pObj->GetOrdNum()+1;
SdrGrafObj* pGraf=PTR_CAST(SdrGrafObj,pObj);
SdrOle2Obj* pOle2=PTR_CAST(SdrOle2Obj,pObj);
ULONG nInsAnz=0;
if (pGraf!=NULL && pGraf->HasGDIMetaFile())
{
ImpSdrGDIMetaFileImport aFilter(*pMod);
aFilter.SetScaleRect(pGraf->GetSnapRect());
aFilter.SetLayer(pObj->GetLayer());
nInsAnz=aFilter.DoImport(pGraf->GetTransformedGraphic().GetGDIMetaFile(),*pOL,nInsPos,pProgrInfo);
}
if ( pOle2!=NULL && pOle2->GetGraphic() )
{
//const GDIMetaFile* pMtf=pOle2->GetGDIMetaFile();
ImpSdrGDIMetaFileImport aFilter(*pMod);
aFilter.SetScaleRect(pOle2->GetLogicRect());
aFilter.SetLayer(pObj->GetLayer());
nInsAnz=aFilter.DoImport(pOle2->GetGraphic()->GetGDIMetaFile(),*pOL,nInsPos,pProgrInfo);
}
if (nInsAnz!=0) {
ULONG nObj=nInsPos;
for (ULONG i=0; i<nInsAnz; i++) {
AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoNewObject(*pOL->GetObj(nObj)));
// Neue MarkList pflegen
SdrMark aNewMark(pOL->GetObj(nObj), pPV);
aNewMarked.InsertEntry(aNewMark);
nObj++;
}
aForTheDescription.InsertEntry(*pM);
AddUndo(GetModel()->GetSdrUndoFactory().CreateUndoDeleteObject(*pObj));
// Objekt aus selektion loesen und loeschen
GetMarkedObjectListWriteAccess().DeleteMark(TryToFindMarkedObject(pObj));
pOL->RemoveObject(nInsPos-1);
}
}
// MarkObj... fehlt... jetzt nicht mehr (AW)
if(aNewMarked.GetMarkCount())
{
// Neue Selektion bilden
for(sal_uInt32 a(0); a < aNewMarked.GetMarkCount(); a++)
{
GetMarkedObjectListWriteAccess().InsertEntry(*aNewMarked.GetMark(a));
}
SortMarkedObjects();
}
SetUndoComment(ImpGetResStr(STR_EditImportMtf),aForTheDescription.GetMarkDescription());
EndUndo();
}