8d8f1ae2d1
2008/04/01 15:51:39 thb 1.16.50.3: #i85898# Stripping all external header guards 2008/04/01 12:49:55 thb 1.16.50.2: #i85898# Stripping all external header guards 2008/03/31 14:23:31 rt 1.16.50.1: #i87441# Change license header to LPGL v3.
1043 lines
27 KiB
C++
1043 lines
27 KiB
C++
/*************************************************************************
|
|
*
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* Copyright 2008 by Sun Microsystems, Inc.
|
|
*
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
*
|
|
* $RCSfile: svdmark.cxx,v $
|
|
* $Revision: 1.17 $
|
|
*
|
|
* 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 <svtools/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
|