diff options
Diffstat (limited to 'svx/source/svdraw/svdmark.cxx')
-rw-r--r-- | svx/source/svdraw/svdmark.cxx | 1040 |
1 files changed, 1040 insertions, 0 deletions
diff --git a/svx/source/svdraw/svdmark.cxx b/svx/source/svdraw/svdmark.cxx new file mode 100644 index 000000000000..c871865ac87b --- /dev/null +++ b/svx/source/svdraw/svdmark.cxx @@ -0,0 +1,1040 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org 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 version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +#include <svx/svdmark.hxx> +#include <svx/svdetc.hxx> +#include <svx/svdobj.hxx> +#include <svx/svdpage.hxx> +#include "svditer.hxx" +#include <svx/svdpagv.hxx> +#include <svx/svdopath.hxx> // zur Abschaltung +#include <svx/svdogrp.hxx> // des Cache bei +#include <svx/svdorect.hxx> // GetMarkDescription +#include "svdstr.hrc" // Namen aus der Resource +#include "svdglob.hxx" // StringCache + +//////////////////////////////////////////////////////////////////////////////////////////////////// +#include <svx/obj3d.hxx> +#include <svx/scene3d.hxx> +#include <svl/brdcst.hxx> +#include <svx/svdoedge.hxx> + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +class ImpSdrUShortContSorter: public ContainerSorter +{ +public: + ImpSdrUShortContSorter(Container& rNewCont) + : ContainerSorter(rNewCont) + {} + + virtual int Compare(const void* pElem1, const void* pElem2) const; +}; + +int ImpSdrUShortContSorter::Compare(const void* pElem1, const void* pElem2) const +{ + sal_uInt16 n1((sal_uInt16)((sal_uIntPtr)pElem1)); + sal_uInt16 n2((sal_uInt16)((sal_uIntPtr)pElem2)); + + return ((n1 < n2) ? (-1) : (n1 > n2) ? (1) : (0)); +} + +void SdrUShortCont::Sort() const +{ + ImpSdrUShortContSorter aSort(*((Container*)(&maArray))); + aSort.DoSort(); + ((SdrUShortCont*)this)->mbSorted = sal_True; + + ULONG nNum(GetCount()); + + if(nNum > 1) + { + nNum--; + sal_uInt16 nVal0 = GetObject(nNum); + + while(nNum > 0) + { + nNum--; + sal_uInt16 nVal1 = GetObject(nNum); + + if(nVal1 == nVal0) + { + ((SdrUShortCont*)this)->Remove(nNum); + } + + nVal0 = nVal1; + } + } +} + +void SdrUShortCont::CheckSort(ULONG nPos) +{ + ULONG nAnz(maArray.Count()); + + if(nPos > nAnz) + nPos = nAnz; + + sal_uInt16 nAktVal = GetObject(nPos); + + if(nPos > 0) + { + sal_uInt16 nPrevVal = GetObject(nPos - 1); + + if(nPrevVal >= nAktVal) + mbSorted = sal_False; + } + + if(nPos < nAnz - 1) + { + sal_uInt16 nNextVal = GetObject(nPos + 1); + + if(nNextVal <= nAktVal) + mbSorted = sal_False; + } +} + +std::set< sal_uInt16 > SdrUShortCont::getContainer() +{ + std::set< sal_uInt16 > aSet; + + sal_uInt32 nAnz = maArray.Count(); + while(nAnz) + aSet.insert( GetObject(--nAnz) ); + + return aSet; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +SdrMark::SdrMark(SdrObject* pNewObj, SdrPageView* pNewPageView) +: mpSelectedSdrObject(pNewObj), + mpPageView(pNewPageView), + mpPoints(0L), + mpLines(0L), + mpGluePoints(0L), + mbCon1(sal_False), + mbCon2(sal_False), + mnUser(0) +{ + if(mpSelectedSdrObject) + { + mpSelectedSdrObject->AddObjectUser( *this ); + } +} + +SdrMark::SdrMark(const SdrMark& rMark) +: ObjectUser(), + mpSelectedSdrObject(0L), + mpPageView(0L), + mpPoints(0L), + mpLines(0L), + mpGluePoints(0L), + mbCon1(sal_False), + mbCon2(sal_False), + mnUser(0) +{ + *this = rMark; +} + +SdrMark::~SdrMark() +{ + if(mpSelectedSdrObject) + { + mpSelectedSdrObject->RemoveObjectUser( *this ); + } + + if(mpPoints) + { + delete mpPoints; + } + + if(mpLines) + { + delete mpLines; + } + + if(mpGluePoints) + { + delete mpGluePoints; + } +} + +void SdrMark::ObjectInDestruction(const SdrObject& rObject) +{ + (void) rObject; // avoid warnings + OSL_ENSURE(mpSelectedSdrObject && mpSelectedSdrObject == &rObject, "SdrMark::ObjectInDestruction: called form object different from hosted one (!)"); + OSL_ENSURE(mpSelectedSdrObject, "SdrMark::ObjectInDestruction: still seleceted SdrObject is deleted, deselect first (!)"); + mpSelectedSdrObject = 0L; +} + +void SdrMark::SetMarkedSdrObj(SdrObject* pNewObj) +{ + if(mpSelectedSdrObject) + { + mpSelectedSdrObject->RemoveObjectUser( *this ); + } + + mpSelectedSdrObject = pNewObj; + + if(mpSelectedSdrObject) + { + mpSelectedSdrObject->AddObjectUser( *this ); + } +} + +SdrObject* SdrMark::GetMarkedSdrObj() const +{ + return mpSelectedSdrObject; +} + +SdrMark& SdrMark::operator=(const SdrMark& rMark) +{ + SetMarkedSdrObj(rMark.mpSelectedSdrObject); + mpPageView = rMark.mpPageView; + mbCon1 = rMark.mbCon1; + mbCon2 = rMark.mbCon2; + mnUser = rMark.mnUser; + + if(!rMark.mpPoints) + { + if(mpPoints) + { + delete mpPoints; + mpPoints = 0L; + } + } + else + { + if(!mpPoints) + { + mpPoints = new SdrUShortCont(*rMark.mpPoints); + } + else + { + *mpPoints = *rMark.mpPoints; + } + } + + if(!rMark.mpLines) + { + if(mpLines) + { + delete mpLines; + mpLines = 0L; + } + } + else + { + if(!mpLines) + { + mpLines = new SdrUShortCont(*rMark.mpLines); + } + else + { + *mpLines = *rMark.mpLines; + } + } + + if(!rMark.mpGluePoints) + { + if(mpGluePoints) + { + delete mpGluePoints; + mpGluePoints = 0L; + } + } + else + { + if(!mpGluePoints) + { + mpGluePoints = new SdrUShortCont(*rMark.mpGluePoints); + } + else + { + *mpGluePoints = *rMark.mpGluePoints; + } + } + + return *this; +} + +sal_Bool SdrMark::operator==(const SdrMark& rMark) const +{ + sal_Bool bRet(mpSelectedSdrObject == rMark.mpSelectedSdrObject && mpPageView == rMark.mpPageView && mbCon1 == rMark.mbCon1 && mbCon2 == rMark.mbCon2 && mnUser == rMark.mnUser); + + if((mpPoints != 0L) != (rMark.mpPoints != 0L)) + bRet = sal_False; + + if((mpLines != 0L) != (rMark.mpLines != 0L)) + bRet = sal_False; + + if((mpGluePoints != 0L) != (rMark.mpGluePoints != 0L)) + bRet = sal_False; + + if(bRet && mpPoints && *mpPoints != *rMark.mpPoints) + bRet = sal_False; + + if(bRet && mpLines && *mpLines != *rMark.mpLines) + bRet = sal_False; + + if(bRet && mpGluePoints && *mpGluePoints != *rMark.mpGluePoints) + bRet = sal_False; + + return bRet; +} + +SdrPage* SdrMark::GetPage() const +{ + return (mpSelectedSdrObject ? mpSelectedSdrObject->GetPage() : 0); +} + +SdrObjList* SdrMark::GetObjList() const +{ + return (mpSelectedSdrObject ? mpSelectedSdrObject->GetObjList() : 0); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +class ImpSdrMarkListSorter: public ContainerSorter +{ +public: + ImpSdrMarkListSorter(Container& rNewCont) + : ContainerSorter(rNewCont) + {} + + virtual int Compare(const void* pElem1, const void* pElem2) const; +}; + +int ImpSdrMarkListSorter::Compare(const void* pElem1, const void* pElem2) const +{ + SdrObject* pObj1 = ((SdrMark*)pElem1)->GetMarkedSdrObj(); + SdrObject* pObj2 = ((SdrMark*)pElem2)->GetMarkedSdrObj(); + SdrObjList* pOL1 = (pObj1) ? pObj1->GetObjList() : 0L; + SdrObjList* pOL2 = (pObj2) ? pObj2->GetObjList() : 0L; + + if (pOL1 == pOL2) + { + // AF: Note that I reverted a change from sal_uInt32 to ULONG (made + // for 64bit compliance, #i78198#) because internally in SdrObject + // both nOrdNum and mnNavigationPosition are stored as sal_uInt32. + sal_uInt32 nObjOrd1((pObj1) ? pObj1->GetNavigationPosition() : 0); + sal_uInt32 nObjOrd2((pObj2) ? pObj2->GetNavigationPosition() : 0); + + return (nObjOrd1 < nObjOrd2 ? -1 : 1); + } + else + { + return ((long)pOL1 < (long)pOL2) ? -1 : 1; + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +void SdrMarkList::ForceSort() const +{ + if(!mbSorted) + { + ((SdrMarkList*)this)->ImpForceSort(); + } +} + +void SdrMarkList::ImpForceSort() +{ + if(!mbSorted) + { + mbSorted = sal_True; + ULONG nAnz = maList.Count(); + + // remove invalid + if(nAnz > 0 ) + { + SdrMark* pAkt = (SdrMark*)maList.First(); + while( pAkt ) + { + if(pAkt->GetMarkedSdrObj() == 0) + { + maList.Remove(); + delete pAkt; + } + pAkt= (SdrMark*)maList.Next(); + } + nAnz = maList.Count(); + } + + if(nAnz > 1) + { + ImpSdrMarkListSorter aSort(maList); + aSort.DoSort(); + + // remove duplicates + if(maList.Count() > 1) + { + SdrMark* pAkt = (SdrMark*)maList.Last(); + SdrMark* pCmp = (SdrMark*)maList.Prev(); + + while(pCmp) + { + if(pAkt->GetMarkedSdrObj() == pCmp->GetMarkedSdrObj() && pAkt->GetMarkedSdrObj()) + { + // Con1/Con2 Merging + if(pCmp->IsCon1()) + pAkt->SetCon1(sal_True); + + if(pCmp->IsCon2()) + pAkt->SetCon2(sal_True); + + // pCmp loeschen. + maList.Remove(); + + delete pCmp; + } + else + { + pAkt = pCmp; + } + + pCmp = (SdrMark*)maList.Prev(); + } + } + } + } +} + +void SdrMarkList::Clear() +{ + for(ULONG i(0L); i < GetMarkCount(); i++) + { + SdrMark* pMark = GetMark(i); + delete pMark; + } + + maList.Clear(); + SetNameDirty(); +} + +void SdrMarkList::operator=(const SdrMarkList& rLst) +{ + Clear(); + + for(ULONG i(0L); i < rLst.GetMarkCount(); i++) + { + SdrMark* pMark = rLst.GetMark(i); + SdrMark* pNeuMark = new SdrMark(*pMark); + maList.Insert(pNeuMark, CONTAINER_APPEND); + } + + maMarkName = rLst.maMarkName; + mbNameOk = rLst.mbNameOk; + maPointName = rLst.maPointName; + mbPointNameOk = rLst.mbPointNameOk; + maGluePointName = rLst.maGluePointName; + mbGluePointNameOk = rLst.mbGluePointNameOk; + mbSorted = rLst.mbSorted; +} + +ULONG SdrMarkList::FindObject(const SdrObject* pObj) const +{ + // #109658# + // + // Since relying on OrdNums is not allowed for the selection because objects in the + // selection may not be inserted in a list if they are e.g. modified ATM, i changed + // this loop to just look if the object pointer is in the selection. + // + // Problem is that GetOrdNum() which is const, internally casts to non-const and + // hardly sets the OrdNum member of the object (nOrdNum) to 0 (ZERO) if the object + // is not inserted in a object list. + // Since this may be by purpose and necessary somewhere else i decided that it is + // less dangerous to change this method then changing SdrObject::GetOrdNum(). + if(pObj && maList.Count()) + { + for(ULONG a(0L); a < maList.Count(); a++) + { + if(((SdrMark*)(maList.GetObject(a)))->GetMarkedSdrObj() == pObj) + { + return a; + } + } + } + + return CONTAINER_ENTRY_NOTFOUND; +} + +void SdrMarkList::InsertEntry(const SdrMark& rMark, sal_Bool bChkSort) +{ + SetNameDirty(); + ULONG nAnz(maList.Count()); + + if(!bChkSort || !mbSorted || nAnz == 0) + { + if(!bChkSort) + mbSorted = sal_False; + + maList.Insert(new SdrMark(rMark), CONTAINER_APPEND); + } + else + { + SdrMark* pLast = GetMark(ULONG(nAnz - 1)); + const SdrObject* pLastObj = pLast->GetMarkedSdrObj(); + const SdrObject* pNeuObj = rMark.GetMarkedSdrObj(); + + if(pLastObj == pNeuObj) + { + // Aha, den gibt's schon + // Con1/Con2 Merging + if(rMark.IsCon1()) + pLast->SetCon1(sal_True); + + if(rMark.IsCon2()) + pLast->SetCon2(sal_True); + } + else + { + SdrMark* pKopie = new SdrMark(rMark); + maList.Insert(pKopie, CONTAINER_APPEND); + + // und nun checken, ob die Sortierung noch ok ist + const SdrObjList* pLastOL = pLastObj!=0L ? pLastObj->GetObjList() : 0L; + const SdrObjList* pNeuOL = pNeuObj !=0L ? pNeuObj ->GetObjList() : 0L; + + if(pLastOL == pNeuOL) + { + const ULONG nLastNum(pLastObj!=0L ? pLastObj->GetOrdNum() : 0); + const ULONG nNeuNum(pNeuObj !=0L ? pNeuObj ->GetOrdNum() : 0); + + if(nNeuNum < nLastNum) + { + // irgendwann muss mal sortiert werden + mbSorted = sal_False; + } + } + else + { + // irgendwann muss mal sortiert werden + mbSorted = sal_False; + } + } + } + + return; +} + +void SdrMarkList::DeleteMark(ULONG nNum) +{ + SdrMark* pMark = GetMark(nNum); + DBG_ASSERT(pMark!=0L,"DeleteMark: MarkEntry nicht gefunden"); + + if(pMark) + { + maList.Remove(nNum); + delete pMark; + SetNameDirty(); + } +} + +void SdrMarkList::ReplaceMark(const SdrMark& rNewMark, ULONG nNum) +{ + SdrMark* pMark = GetMark(nNum); + DBG_ASSERT(pMark!=0L,"ReplaceMark: MarkEntry nicht gefunden"); + + if(pMark) + { + delete pMark; + SetNameDirty(); + SdrMark* pKopie = new SdrMark(rNewMark); + maList.Replace(pKopie, nNum); + mbSorted = sal_False; + } +} + +void SdrMarkList::Merge(const SdrMarkList& rSrcList, sal_Bool bReverse) +{ + ULONG nAnz(rSrcList.maList.Count()); + + if(rSrcList.mbSorted) + { + // Merging ohne ein Sort bei rSrcList zu erzwingen + bReverse = sal_False; + } + + if(!bReverse) + { + for(ULONG i(0L); i < nAnz; i++) + { + SdrMark* pM = (SdrMark*)(rSrcList.maList.GetObject(i)); + InsertEntry(*pM); + } + } + else + { + for(ULONG i(nAnz); i > 0;) + { + i--; + SdrMark* pM = (SdrMark*)(rSrcList.maList.GetObject(i)); + InsertEntry(*pM); + } + } +} + +sal_Bool SdrMarkList::DeletePageView(const SdrPageView& rPV) +{ + sal_Bool bChgd(sal_False); + + for(ULONG i(GetMarkCount()); i > 0; ) + { + i--; + SdrMark* pMark = GetMark(i); + + if(pMark->GetPageView()==&rPV) + { + maList.Remove(i); + delete pMark; + SetNameDirty(); + bChgd = sal_True; + } + } + + return bChgd; +} + +sal_Bool SdrMarkList::InsertPageView(const SdrPageView& rPV) +{ + sal_Bool bChgd(sal_False); + DeletePageView(rPV); // erstmal alle raus, dann die ganze Seite hinten dran + SdrObject* pObj; + const SdrObjList* pOL = rPV.GetObjList(); + ULONG nObjAnz(pOL->GetObjCount()); + + for(ULONG nO(0L); nO < nObjAnz; nO++) + { + pObj = pOL->GetObj(nO); + sal_Bool bDoIt(rPV.IsObjMarkable(pObj)); + + if(bDoIt) + { + SdrMark* pM = new SdrMark(pObj, (SdrPageView*)&rPV); + maList.Insert(pM, CONTAINER_APPEND); + SetNameDirty(); + bChgd = sal_True; + } + } + + return bChgd; +} + +const XubString& SdrMarkList::GetMarkDescription() const +{ + ULONG nAnz(GetMarkCount()); + + if(mbNameOk && 1L == nAnz) + { + // Bei Einfachselektion nur Textrahmen cachen + const SdrObject* pObj = GetMark(0)->GetMarkedSdrObj(); + const SdrTextObj* pTextObj = PTR_CAST(SdrTextObj, pObj); + + if(!pTextObj || !pTextObj->IsTextFrame()) + { + ((SdrMarkList*)(this))->mbNameOk = sal_False; + } + } + + if(!mbNameOk) + { + SdrMark* pMark = GetMark(0); + XubString aNam; + + if(!nAnz) + { + ((SdrMarkList*)(this))->maMarkName = ImpGetResStr(STR_ObjNameNoObj); + } + else if(1L == nAnz) + { + if(pMark->GetMarkedSdrObj()) + { + pMark->GetMarkedSdrObj()->TakeObjNameSingul(aNam); + } + } + else + { + if(pMark->GetMarkedSdrObj()) + { + pMark->GetMarkedSdrObj()->TakeObjNamePlural(aNam); + XubString aStr1; + sal_Bool bEq(sal_True); + + for(ULONG i = 1; i < GetMarkCount() && bEq; i++) + { + SdrMark* pMark2 = GetMark(i); + pMark2->GetMarkedSdrObj()->TakeObjNamePlural(aStr1); + bEq = aNam.Equals(aStr1); + } + + if(!bEq) + { + aNam = ImpGetResStr(STR_ObjNamePlural); + } + } + + aNam.Insert(sal_Unicode(' '), 0); + aNam.Insert(UniString::CreateFromInt32(nAnz), 0); + } + + ((SdrMarkList*)(this))->maMarkName = aNam; + ((SdrMarkList*)(this))->mbNameOk = sal_True; + } + + return maMarkName; +} + +const XubString& SdrMarkList::GetPointMarkDescription(sal_Bool bGlue) const +{ + sal_Bool& rNameOk = (sal_Bool&)(bGlue ? mbGluePointNameOk : mbPointNameOk); + XubString& rName = (XubString&)(bGlue ? maGluePointName : maPointName); + ULONG nMarkAnz(GetMarkCount()); + ULONG nMarkPtAnz(0L); + ULONG nMarkPtObjAnz(0L); + ULONG n1stMarkNum(ULONG_MAX); + + for(ULONG nMarkNum(0L); nMarkNum < nMarkAnz; nMarkNum++) + { + const SdrMark* pMark = GetMark(nMarkNum); + const SdrUShortCont* pPts = bGlue ? pMark->GetMarkedGluePoints() : pMark->GetMarkedPoints(); + ULONG nAnz(pPts ? pPts->GetCount() : 0); + + if(nAnz) + { + if(n1stMarkNum == ULONG_MAX) + { + n1stMarkNum = nMarkNum; + } + + nMarkPtAnz += nAnz; + nMarkPtObjAnz++; + } + + if(nMarkPtObjAnz > 1 && rNameOk) + { + // vorzeitige Entscheidung + return rName; + } + } + + if(rNameOk && 1L == nMarkPtObjAnz) + { + // Bei Einfachselektion nur Textrahmen cachen + const SdrObject* pObj = GetMark(0)->GetMarkedSdrObj(); + const SdrTextObj* pTextObj = PTR_CAST(SdrTextObj,pObj); + + if(!pTextObj || !pTextObj->IsTextFrame()) + { + rNameOk = sal_False; + } + } + + if(!nMarkPtObjAnz) + { + rName.Erase(); + rNameOk = sal_True; + } + else if(!rNameOk) + { + const SdrMark* pMark = GetMark(n1stMarkNum); + XubString aNam; + + if(1L == nMarkPtObjAnz) + { + if(pMark->GetMarkedSdrObj()) + { + pMark->GetMarkedSdrObj()->TakeObjNameSingul(aNam); + } + } + else + { + if(pMark->GetMarkedSdrObj()) + { + pMark->GetMarkedSdrObj()->TakeObjNamePlural(aNam); + } + + XubString aStr1; + sal_Bool bEq(sal_True); + + for(ULONG i(n1stMarkNum + 1L); i < GetMarkCount() && bEq; i++) + { + const SdrMark* pMark2 = GetMark(i); + const SdrUShortCont* pPts = bGlue ? pMark2->GetMarkedGluePoints() : pMark2->GetMarkedPoints(); + + if(pPts && pPts->GetCount() && pMark2->GetMarkedSdrObj()) + { + pMark2->GetMarkedSdrObj()->TakeObjNamePlural(aStr1); + bEq = aNam.Equals(aStr1); + } + } + + if(!bEq) + { + aNam = ImpGetResStr(STR_ObjNamePlural); + } + + aNam.Insert(sal_Unicode(' '), 0); + aNam.Insert(UniString::CreateFromInt32(nMarkPtObjAnz), 0); + } + + XubString aStr1; + + if(1L == nMarkPtAnz) + { + aStr1 = (ImpGetResStr(bGlue ? STR_ViewMarkedGluePoint : STR_ViewMarkedPoint)); + } + else + { + aStr1 = (ImpGetResStr(bGlue ? STR_ViewMarkedGluePoints : STR_ViewMarkedPoints)); + aStr1.SearchAndReplaceAscii("%2", UniString::CreateFromInt32(nMarkPtAnz)); + } + + aStr1.SearchAndReplaceAscii("%1", aNam); + rName = aStr1; + rNameOk = sal_True; + } + + return rName; +} + +sal_Bool SdrMarkList::TakeBoundRect(SdrPageView* pPV, Rectangle& rRect) const +{ + sal_Bool bFnd(sal_False); + Rectangle aR; + + for(ULONG i(0L); i < GetMarkCount(); i++) + { + SdrMark* pMark = GetMark(i); + + if(!pPV || pMark->GetPageView() == pPV) + { + if(pMark->GetMarkedSdrObj()) + { + aR = pMark->GetMarkedSdrObj()->GetCurrentBoundRect(); + + if(bFnd) + { + rRect.Union(aR); + } + else + { + rRect = aR; + bFnd = sal_True; + } + } + } + } + + return bFnd; +} + +sal_Bool SdrMarkList::TakeSnapRect(SdrPageView* pPV, Rectangle& rRect) const +{ + sal_Bool bFnd(sal_False); + + for(ULONG i(0L); i < GetMarkCount(); i++) + { + SdrMark* pMark = GetMark(i); + + if(!pPV || pMark->GetPageView() == pPV) + { + if(pMark->GetMarkedSdrObj()) + { + Rectangle aR(pMark->GetMarkedSdrObj()->GetSnapRect()); + + if(bFnd) + { + rRect.Union(aR); + } + else + { + rRect = aR; + bFnd = sal_True; + } + } + } + } + + return bFnd; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + ViewSelection::ViewSelection() + : mbEdgesOfMarkedNodesDirty(sal_False) + { + } + + void ViewSelection::SetEdgesOfMarkedNodesDirty() + { + if(!mbEdgesOfMarkedNodesDirty) + { + mbEdgesOfMarkedNodesDirty = sal_True; + maEdgesOfMarkedNodes.Clear(); + maMarkedEdgesOfMarkedNodes.Clear(); + maAllMarkedObjects.Clear(); + } + } + + const SdrMarkList& ViewSelection::GetEdgesOfMarkedNodes() const + { + if(mbEdgesOfMarkedNodesDirty) + { + ((ViewSelection*)this)->ImpForceEdgesOfMarkedNodes(); + } + + return maEdgesOfMarkedNodes; + } + + const SdrMarkList& ViewSelection::GetMarkedEdgesOfMarkedNodes() const + { + if(mbEdgesOfMarkedNodesDirty) + { + ((ViewSelection*)this)->ImpForceEdgesOfMarkedNodes(); + } + + return maMarkedEdgesOfMarkedNodes; + } + + const List& ViewSelection::GetAllMarkedObjects() const + { + if(mbEdgesOfMarkedNodesDirty) + { + ((ViewSelection*)this)->ImpForceEdgesOfMarkedNodes(); + } + + return maAllMarkedObjects; + } + + void ViewSelection::ImplCollectCompleteSelection(SdrObject* pObj) + { + if(pObj) + { + sal_Bool bIsGroup(pObj->IsGroupObject()); + + if(bIsGroup && pObj->ISA(E3dObject) && !pObj->ISA(E3dScene)) + { + bIsGroup = sal_False; + } + + if(bIsGroup) + { + SdrObjList* pList = pObj->GetSubList(); + + for(ULONG a(0L); a < pList->GetObjCount(); a++) + { + SdrObject* pObj2 = pList->GetObj(a); + ImplCollectCompleteSelection(pObj2); + } + } + + maAllMarkedObjects.Insert(pObj, LIST_APPEND); + } + } + + void ViewSelection::ImpForceEdgesOfMarkedNodes() + { + if(mbEdgesOfMarkedNodesDirty) + { + mbEdgesOfMarkedNodesDirty = sal_False; + maMarkedObjectList.ForceSort(); + maEdgesOfMarkedNodes.Clear(); + maMarkedEdgesOfMarkedNodes.Clear(); + maAllMarkedObjects.Clear(); + + // #126320# GetMarkCount after ForceSort + const ULONG nMarkAnz(maMarkedObjectList.GetMarkCount()); + + for(ULONG a(0L); a < nMarkAnz; a++) + { + SdrObject* pCandidate = maMarkedObjectList.GetMark(a)->GetMarkedSdrObj(); + + if(pCandidate) + { + // build transitive hull + ImplCollectCompleteSelection(pCandidate); + + if(pCandidate->IsNode()) + { + // travel over broadcaster/listener to access edges connected to the selected object + const SfxBroadcaster* pBC = pCandidate->GetBroadcaster(); + + if(pBC) + { + sal_uInt16 nLstAnz(pBC->GetListenerCount()); + + for(sal_uInt16 nl(0); nl < nLstAnz; nl++) + { + SfxListener* pLst = pBC->GetListener(nl); + SdrEdgeObj* pEdge = PTR_CAST(SdrEdgeObj, pLst); + + if(pEdge && pEdge->IsInserted() && pEdge->GetPage() == pCandidate->GetPage()) + { + SdrMark aM(pEdge, maMarkedObjectList.GetMark(a)->GetPageView()); + + if(pEdge->GetConnectedNode(sal_True) == pCandidate) + { + aM.SetCon1(sal_True); + } + + if(pEdge->GetConnectedNode(sal_False) == pCandidate) + { + aM.SetCon2(sal_True); + } + + if(CONTAINER_ENTRY_NOTFOUND == maMarkedObjectList.FindObject(pEdge)) + { + // nachsehen, ob er selbst markiert ist + maEdgesOfMarkedNodes.InsertEntry(aM); + } + else + { + maMarkedEdgesOfMarkedNodes.InsertEntry(aM); + } + } + } + } + } + } + } + + maEdgesOfMarkedNodes.ForceSort(); + maMarkedEdgesOfMarkedNodes.ForceSort(); + } + } +} // end of namespace sdr + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// eof |