summaryrefslogtreecommitdiffstats
path: root/svx/source/svdraw/svdmark.cxx
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-15 05:54:39 +0000
commit267c6f2ac71f92999e969232431ba04678e7437e (patch)
tree358c9467650e1d0a1d7227a21dac2e3d08b622b2 /svx/source/svdraw/svdmark.cxx
parentInitial commit. (diff)
downloadlibreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz
libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'svx/source/svdraw/svdmark.cxx')
-rw-r--r--svx/source/svdraw/svdmark.cxx780
1 files changed, 780 insertions, 0 deletions
diff --git a/svx/source/svdraw/svdmark.cxx b/svx/source/svdraw/svdmark.cxx
new file mode 100644
index 0000000000..521e56d44b
--- /dev/null
+++ b/svx/source/svdraw/svdmark.cxx
@@ -0,0 +1,780 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <sal/config.h>
+
+#include <osl/time.h>
+#include <svx/svdmark.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/strings.hrc>
+#include <svx/dialmgr.hxx>
+
+
+#include <svx/obj3d.hxx>
+#include <svx/scene3d.hxx>
+#include <svl/SfxBroadcaster.hxx>
+#include <svx/svdoedge.hxx>
+#include <osl/diagnose.h>
+
+#include <cassert>
+
+void SdrMark::setTime()
+{
+ TimeValue aNow;
+ osl_getSystemTime(&aNow);
+ mnTimeStamp = sal_Int64(aNow.Seconds) * 1000000000 + aNow.Nanosec;
+}
+
+SdrMark::SdrMark(SdrObject* pNewObj, SdrPageView* pNewPageView)
+: mpSelectedSdrObject(pNewObj),
+ mpPageView(pNewPageView),
+ mbCon1(false),
+ mbCon2(false),
+ mnUser(0)
+{
+ if(mpSelectedSdrObject)
+ {
+ mpSelectedSdrObject->AddObjectUser( *this );
+ }
+ setTime();
+}
+
+SdrMark::SdrMark(const SdrMark& rMark)
+: ObjectUser(),
+ mnTimeStamp(0),
+ mpSelectedSdrObject(nullptr),
+ mpPageView(nullptr),
+ mbCon1(false),
+ mbCon2(false),
+ mnUser(0)
+{
+ *this = rMark;
+}
+
+SdrMark::~SdrMark()
+{
+ if (mpSelectedSdrObject)
+ {
+ mpSelectedSdrObject->RemoveObjectUser( *this );
+ }
+}
+
+void SdrMark::ObjectInDestruction(const SdrObject& rObject)
+{
+ (void) rObject; // avoid warnings
+ OSL_ENSURE(mpSelectedSdrObject && mpSelectedSdrObject == &rObject, "SdrMark::ObjectInDestruction: called from object different from hosted one (!)");
+ OSL_ENSURE(mpSelectedSdrObject, "SdrMark::ObjectInDestruction: still selected SdrObject is deleted, deselect first (!)");
+ mpSelectedSdrObject = nullptr;
+}
+
+void SdrMark::SetMarkedSdrObj(SdrObject* pNewObj)
+{
+ if(mpSelectedSdrObject)
+ {
+ mpSelectedSdrObject->RemoveObjectUser( *this );
+ }
+
+ mpSelectedSdrObject = pNewObj;
+
+ if(mpSelectedSdrObject)
+ {
+ mpSelectedSdrObject->AddObjectUser( *this );
+ }
+}
+
+SdrMark& SdrMark::operator=(const SdrMark& rMark)
+{
+ SetMarkedSdrObj(rMark.mpSelectedSdrObject);
+
+ mnTimeStamp = rMark.mnTimeStamp;
+ mpPageView = rMark.mpPageView;
+ mbCon1 = rMark.mbCon1;
+ mbCon2 = rMark.mbCon2;
+ mnUser = rMark.mnUser;
+ maPoints = rMark.maPoints;
+ maGluePoints = rMark.maGluePoints;
+
+ return *this;
+}
+
+static bool ImpSdrMarkListSorter(std::unique_ptr<SdrMark> const& lhs, std::unique_ptr<SdrMark> const& rhs)
+{
+ SdrObject* pObj1 = lhs->GetMarkedSdrObj();
+ SdrObject* pObj2 = rhs->GetMarkedSdrObj();
+ SdrObjList* pOL1 = pObj1 ? pObj1->getParentSdrObjListFromSdrObject() : nullptr;
+ SdrObjList* pOL2 = pObj2 ? pObj2->getParentSdrObjListFromSdrObject() : nullptr;
+
+ if (pOL1 == pOL2)
+ {
+ // AF: Note that I reverted a change from sal_uInt32 to sal_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;
+ }
+ else
+ {
+ return pOL1 < pOL2;
+ }
+}
+
+
+void SdrMarkList::ForceSort() const
+{
+ if(!mbSorted)
+ {
+ const_cast<SdrMarkList*>(this)->ImpForceSort();
+ }
+}
+
+void SdrMarkList::ImpForceSort()
+{
+ if(mbSorted)
+ return;
+
+ mbSorted = true;
+ size_t nCount = maList.size();
+
+ // remove invalid
+ if(nCount > 0 )
+ {
+ std::erase_if(maList, [](std::unique_ptr<SdrMark>& rItem) { return rItem->GetMarkedSdrObj() == nullptr; });
+ nCount = maList.size();
+ }
+
+ if(nCount <= 1)
+ return;
+
+ std::sort(maList.begin(), maList.end(), ImpSdrMarkListSorter);
+
+ // remove duplicates
+ if(maList.size() <= 1)
+ return;
+
+ SdrMark* pCurrent = maList.back().get();
+ for (size_t count = maList.size() - 1; count; --count)
+ {
+ size_t i = count - 1;
+ SdrMark* pCmp = maList[i].get();
+ assert(pCurrent->GetMarkedSdrObj());
+ if(pCurrent->GetMarkedSdrObj() == pCmp->GetMarkedSdrObj())
+ {
+ // Con1/Con2 Merging
+ if(pCmp->IsCon1())
+ pCurrent->SetCon1(true);
+
+ if(pCmp->IsCon2())
+ pCurrent->SetCon2(true);
+
+ // delete pCmp
+ maList.erase(maList.begin() + i);
+ }
+ else
+ {
+ pCurrent = pCmp;
+ }
+ }
+}
+
+void SdrMarkList::Clear()
+{
+ maList.clear();
+ mbSorted = true; //we're empty, so can be considered sorted
+ SetNameDirty();
+}
+
+SdrMarkList& SdrMarkList::operator=(const SdrMarkList& rLst)
+{
+ if (this != &rLst)
+ {
+ Clear();
+
+ for(size_t i = 0; i < rLst.GetMarkCount(); ++i)
+ {
+ SdrMark* pMark = rLst.GetMark(i);
+ maList.emplace_back(new SdrMark(*pMark));
+ }
+
+ maMarkName = rLst.maMarkName;
+ mbNameOk = rLst.mbNameOk;
+ maPointName = rLst.maPointName;
+ mbPointNameOk = rLst.mbPointNameOk;
+ maGluePointName = rLst.maGluePointName;
+ mbSorted = rLst.mbSorted;
+ }
+ return *this;
+}
+
+SdrMark* SdrMarkList::GetMark(size_t nNum) const
+{
+ return (nNum < maList.size()) ? maList[nNum].get() : nullptr;
+}
+
+size_t SdrMarkList::FindObject(const SdrObject* pObj) const
+{
+ // 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 an 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)
+ {
+ for(size_t a = 0; a < maList.size(); ++a)
+ {
+ if(maList[a]->GetMarkedSdrObj() == pObj)
+ {
+ return a;
+ }
+ }
+ }
+
+ return SAL_MAX_SIZE;
+}
+
+void SdrMarkList::InsertEntry(const SdrMark& rMark, bool bChkSort)
+{
+ SetNameDirty();
+ const size_t nCount(maList.size());
+
+ if(!bChkSort || !mbSorted || nCount == 0)
+ {
+ if(!bChkSort)
+ mbSorted = false;
+
+ maList.emplace_back(new SdrMark(rMark));
+ }
+ else
+ {
+ SdrMark* pLast = GetMark(nCount - 1);
+ const SdrObject* pLastObj = pLast->GetMarkedSdrObj();
+ const SdrObject* pNewObj = rMark.GetMarkedSdrObj();
+
+ if(pLastObj == pNewObj)
+ {
+ // This one already exists.
+ // Con1/Con2 Merging
+ if(rMark.IsCon1())
+ pLast->SetCon1(true);
+
+ if(rMark.IsCon2())
+ pLast->SetCon2(true);
+ }
+ else
+ {
+ maList.emplace_back(new SdrMark(rMark));
+
+ // now check if the sort is ok
+ const SdrObjList* pLastOL = pLastObj!=nullptr ? pLastObj->getParentSdrObjListFromSdrObject() : nullptr;
+ const SdrObjList* pNewOL = pNewObj !=nullptr ? pNewObj->getParentSdrObjListFromSdrObject() : nullptr;
+
+ if(pLastOL == pNewOL)
+ {
+ const sal_uLong nLastNum(pLastObj!=nullptr ? pLastObj->GetOrdNum() : 0);
+ const sal_uLong nNewNum(pNewObj !=nullptr ? pNewObj ->GetOrdNum() : 0);
+
+ if(nNewNum < nLastNum)
+ {
+ // at some point, we have to sort
+ mbSorted = false;
+ }
+ }
+ else
+ {
+ // at some point, we have to sort
+ mbSorted = false;
+ }
+ }
+ }
+}
+
+void SdrMarkList::DeleteMark(size_t nNum)
+{
+ SdrMark* pMark = GetMark(nNum);
+ DBG_ASSERT(pMark!=nullptr,"DeleteMark: MarkEntry not found.");
+
+ if(pMark)
+ {
+ maList.erase(maList.begin() + nNum);
+ if (maList.empty())
+ mbSorted = true; //we're empty, so can be considered sorted
+ SetNameDirty();
+ }
+}
+
+void SdrMarkList::ReplaceMark(const SdrMark& rNewMark, size_t nNum)
+{
+ SdrMark* pMark = GetMark(nNum);
+ DBG_ASSERT(pMark!=nullptr,"ReplaceMark: MarkEntry not found.");
+
+ if(pMark)
+ {
+ SetNameDirty();
+ maList[nNum].reset(new SdrMark(rNewMark));
+ mbSorted = false;
+ }
+}
+
+void SdrMarkList::Merge(const SdrMarkList& rSrcList, bool bReverse)
+{
+ const size_t nCount(rSrcList.maList.size());
+
+ if(rSrcList.mbSorted)
+ {
+ // merge without forcing a Sort in rSrcList
+ bReverse = false;
+ }
+
+ if(!bReverse)
+ {
+ for(size_t i = 0; i < nCount; ++i)
+ {
+ SdrMark* pM = rSrcList.maList[i].get();
+ InsertEntry(*pM);
+ }
+ }
+ else
+ {
+ for(size_t i = nCount; i > 0;)
+ {
+ --i;
+ SdrMark* pM = rSrcList.maList[i].get();
+ InsertEntry(*pM);
+ }
+ }
+}
+
+bool SdrMarkList::DeletePageView(const SdrPageView& rPV)
+{
+ bool bChgd(false);
+
+ for(auto it = maList.begin(); it != maList.end(); )
+ {
+ SdrMark* pMark = it->get();
+
+ if(pMark->GetPageView()==&rPV)
+ {
+ it = maList.erase(it);
+ SetNameDirty();
+ bChgd = true;
+ }
+ else
+ ++it;
+ }
+
+ return bChgd;
+}
+
+bool SdrMarkList::InsertPageView(const SdrPageView& rPV)
+{
+ bool bChgd(false);
+ DeletePageView(rPV); // delete all of them, then append the entire page
+ const SdrObjList* pOL = rPV.GetObjList();
+
+ for (const rtl::Reference<SdrObject>& pObj : *pOL)
+ {
+ bool bDoIt(rPV.IsObjMarkable(pObj.get()));
+
+ if(bDoIt)
+ {
+ maList.emplace_back(new SdrMark(pObj.get(), const_cast<SdrPageView*>(&rPV)));
+ SetNameDirty();
+ bChgd = true;
+ }
+ }
+
+ return bChgd;
+}
+
+const OUString& SdrMarkList::GetMarkDescription() const
+{
+ const size_t nCount(GetMarkCount());
+
+ if(mbNameOk && 1 == nCount)
+ {
+ // if it's a single selection, cache only text frame
+ const SdrObject* pObj = GetMark(0)->GetMarkedSdrObj();
+ const SdrTextObj* pTextObj = DynCastSdrTextObj( pObj );
+
+ if(!pTextObj || !pTextObj->IsTextFrame())
+ {
+ const_cast<SdrMarkList*>(this)->mbNameOk = false;
+ }
+ }
+
+ if(!mbNameOk)
+ {
+ SdrMark* pMark = GetMark(0);
+ OUString aNam;
+
+ if(!nCount)
+ {
+ const_cast<SdrMarkList*>(this)->maMarkName = SvxResId(STR_ObjNameNoObj);
+ }
+ else if(1 == nCount)
+ {
+ if(pMark->GetMarkedSdrObj())
+ {
+ aNam = pMark->GetMarkedSdrObj()->TakeObjNameSingul();
+ }
+ }
+ else
+ {
+ if(pMark->GetMarkedSdrObj())
+ {
+ aNam = pMark->GetMarkedSdrObj()->TakeObjNamePlural();
+ bool bEq(true);
+
+ for(size_t i = 1; i < GetMarkCount() && bEq; ++i)
+ {
+ SdrMark* pMark2 = GetMark(i);
+ OUString aStr1(pMark2->GetMarkedSdrObj()->TakeObjNamePlural());
+ bEq = aNam == aStr1;
+ }
+
+ if(!bEq)
+ {
+ aNam = SvxResId(STR_ObjNamePlural);
+ }
+ }
+
+ aNam = OUString::number( nCount ) + " " + aNam;
+ }
+
+ const_cast<SdrMarkList*>(this)->maMarkName = aNam;
+ const_cast<SdrMarkList*>(this)->mbNameOk = true;
+ }
+
+ return maMarkName;
+}
+
+const OUString& SdrMarkList::GetPointMarkDescription(bool bGlue) const
+{
+ bool& rNameOk = const_cast<bool&>(bGlue ? mbGluePointNameOk : mbPointNameOk);
+ OUString& rName = const_cast<OUString&>(bGlue ? maGluePointName : maPointName);
+ const size_t nMarkCount(GetMarkCount());
+ size_t nMarkPtCnt(0);
+ size_t nMarkPtObjCnt(0);
+ size_t n1stMarkNum(SAL_MAX_SIZE);
+
+ for(size_t nMarkNum = 0; nMarkNum < nMarkCount; ++nMarkNum)
+ {
+ const SdrMark* pMark = GetMark(nMarkNum);
+ const SdrUShortCont& rPts = bGlue ? pMark->GetMarkedGluePoints() : pMark->GetMarkedPoints();
+
+ if (!rPts.empty())
+ {
+ if(n1stMarkNum == SAL_MAX_SIZE)
+ {
+ n1stMarkNum = nMarkNum;
+ }
+
+ nMarkPtCnt += rPts.size();
+ nMarkPtObjCnt++;
+ }
+
+ if(nMarkPtObjCnt > 1 && rNameOk)
+ {
+ // preliminary decision
+ return rName;
+ }
+ }
+
+ if(rNameOk && 1 == nMarkPtObjCnt)
+ {
+ // if it's a single selection, cache only text frame
+ const SdrObject* pObj = GetMark(0)->GetMarkedSdrObj();
+ const SdrTextObj* pTextObj = DynCastSdrTextObj( pObj );
+
+ if(!pTextObj || !pTextObj->IsTextFrame())
+ {
+ rNameOk = false;
+ }
+ }
+
+ if(!nMarkPtObjCnt)
+ {
+ rName.clear();
+ rNameOk = true;
+ }
+ else if(!rNameOk)
+ {
+ const SdrMark* pMark = GetMark(n1stMarkNum);
+ OUString aNam;
+
+ if(1 == nMarkPtObjCnt)
+ {
+ if(pMark->GetMarkedSdrObj())
+ {
+ aNam = pMark->GetMarkedSdrObj()->TakeObjNameSingul();
+ }
+ }
+ else
+ {
+ if(pMark->GetMarkedSdrObj())
+ {
+ aNam = pMark->GetMarkedSdrObj()->TakeObjNamePlural();
+ }
+
+ bool bEq(true);
+
+ for(size_t i = n1stMarkNum + 1; i < GetMarkCount() && bEq; ++i)
+ {
+ const SdrMark* pMark2 = GetMark(i);
+ const SdrUShortCont& rPts = bGlue ? pMark2->GetMarkedGluePoints() : pMark2->GetMarkedPoints();
+
+ if (!rPts.empty() && pMark2->GetMarkedSdrObj())
+ {
+ OUString aStr1(pMark2->GetMarkedSdrObj()->TakeObjNamePlural());
+ bEq = aNam == aStr1;
+ }
+ }
+
+ if(!bEq)
+ {
+ aNam = SvxResId(STR_ObjNamePlural);
+ }
+
+ aNam = OUString::number( nMarkPtObjCnt ) + " " + aNam;
+ }
+
+ OUString aStr1;
+
+ if(1 == nMarkPtCnt)
+ {
+ aStr1 = SvxResId(bGlue ? STR_ViewMarkedGluePoint : STR_ViewMarkedPoint);
+ }
+ else
+ {
+ aStr1 = SvxResId(bGlue ? STR_ViewMarkedGluePoints : STR_ViewMarkedPoints);
+ aStr1 = aStr1.replaceFirst("%2", OUString::number( nMarkPtCnt ));
+ }
+
+ aStr1 = aStr1.replaceFirst("%1", aNam);
+ rName = aStr1;
+ rNameOk = true;
+ }
+
+ return rName;
+}
+
+bool SdrMarkList::TakeBoundRect(SdrPageView const * pPV, tools::Rectangle& rRect) const
+{
+ bool bFnd(false);
+ tools::Rectangle aR;
+
+ for(size_t i = 0; 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 = true;
+ }
+ }
+ }
+ }
+
+ return bFnd;
+}
+
+bool SdrMarkList::TakeSnapRect(SdrPageView const * pPV, tools::Rectangle& rRect) const
+{
+ bool bFnd(false);
+
+ for(size_t i = 0; i < GetMarkCount(); ++i)
+ {
+ SdrMark* pMark = GetMark(i);
+
+ if(!pPV || pMark->GetPageView() == pPV)
+ {
+ if(pMark->GetMarkedSdrObj())
+ {
+ tools::Rectangle aR(pMark->GetMarkedSdrObj()->GetSnapRect());
+
+ if(bFnd)
+ {
+ rRect.Union(aR);
+ }
+ else
+ {
+ rRect = aR;
+ bFnd = true;
+ }
+ }
+ }
+ }
+
+ return bFnd;
+}
+
+
+namespace sdr
+{
+ ViewSelection::ViewSelection()
+ : mbEdgesOfMarkedNodesDirty(false)
+ {
+ }
+
+ void ViewSelection::SetEdgesOfMarkedNodesDirty()
+ {
+ if(!mbEdgesOfMarkedNodesDirty)
+ {
+ mbEdgesOfMarkedNodesDirty = true;
+ maEdgesOfMarkedNodes.Clear();
+ maMarkedEdgesOfMarkedNodes.Clear();
+ maAllMarkedObjects.clear();
+ }
+ }
+
+ const SdrMarkList& ViewSelection::GetEdgesOfMarkedNodes() const
+ {
+ if(mbEdgesOfMarkedNodesDirty)
+ {
+ const_cast<ViewSelection*>(this)->ImpForceEdgesOfMarkedNodes();
+ }
+
+ return maEdgesOfMarkedNodes;
+ }
+
+ const SdrMarkList& ViewSelection::GetMarkedEdgesOfMarkedNodes() const
+ {
+ if(mbEdgesOfMarkedNodesDirty)
+ {
+ const_cast<ViewSelection*>(this)->ImpForceEdgesOfMarkedNodes();
+ }
+
+ return maMarkedEdgesOfMarkedNodes;
+ }
+
+ const std::vector<SdrObject*>& ViewSelection::GetAllMarkedObjects() const
+ {
+ if(mbEdgesOfMarkedNodesDirty)
+ const_cast<ViewSelection*>(this)->ImpForceEdgesOfMarkedNodes();
+
+ return maAllMarkedObjects;
+ }
+
+ void ViewSelection::ImplCollectCompleteSelection(SdrObject* pObj)
+ {
+ if(!pObj)
+ return;
+
+ bool bIsGroup(pObj->IsGroupObject());
+
+ if(bIsGroup && DynCastE3dObject(pObj) != nullptr && DynCastE3dScene(pObj) == nullptr)
+ {
+ bIsGroup = false;
+ }
+
+ if(bIsGroup)
+ {
+ SdrObjList* pList = pObj->GetSubList();
+
+ for (const rtl::Reference<SdrObject>& pObj2 : *pList)
+ ImplCollectCompleteSelection(pObj2.get());
+ }
+
+ maAllMarkedObjects.push_back(pObj);
+ }
+
+ void ViewSelection::ImpForceEdgesOfMarkedNodes()
+ {
+ if(!mbEdgesOfMarkedNodesDirty)
+ return;
+
+ mbEdgesOfMarkedNodesDirty = false;
+ maMarkedObjectList.ForceSort();
+ maEdgesOfMarkedNodes.Clear();
+ maMarkedEdgesOfMarkedNodes.Clear();
+ maAllMarkedObjects.clear();
+
+ // GetMarkCount after ForceSort
+ const size_t nMarkCount(maMarkedObjectList.GetMarkCount());
+
+ for(size_t a = 0; a < nMarkCount; ++a)
+ {
+ SdrObject* pCandidate = maMarkedObjectList.GetMark(a)->GetMarkedSdrObj();
+ if(!pCandidate)
+ continue;
+
+ // build transitive hull
+ ImplCollectCompleteSelection(pCandidate);
+
+ // travel over broadcaster/listener to access edges connected to the selected object
+ const SfxBroadcaster* pBC = pCandidate->GetBroadcaster();
+ if(!pBC)
+ continue;
+
+ pBC->ForAllListeners(
+ [this, &pCandidate, &a] (SfxListener* pLst)
+ {
+ SdrEdgeObj* pEdge = dynamic_cast<SdrEdgeObj*>( pLst );
+
+ if(pEdge && pEdge->IsInserted() && pEdge->getSdrPageFromSdrObject() == pCandidate->getSdrPageFromSdrObject())
+ {
+ SdrMark aM(pEdge, maMarkedObjectList.GetMark(a)->GetPageView());
+
+ if(pEdge->GetConnectedNode(true) == pCandidate)
+ {
+ aM.SetCon1(true);
+ }
+
+ if(pEdge->GetConnectedNode(false) == pCandidate)
+ {
+ aM.SetCon2(true);
+ }
+
+ if(SAL_MAX_SIZE == maMarkedObjectList.FindObject(pEdge))
+ {
+ // check if it itself is selected
+ maEdgesOfMarkedNodes.InsertEntry(aM);
+ }
+ else
+ {
+ maMarkedEdgesOfMarkedNodes.InsertEntry(aM);
+ }
+ }
+ return false;
+ });
+ }
+ maEdgesOfMarkedNodes.ForceSort();
+ maMarkedEdgesOfMarkedNodes.ForceSort();
+ }
+} // end of namespace sdr
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */