summaryrefslogtreecommitdiffstats
path: root/svx/source/svdraw/svdmrkv1.cxx
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
commit940b4d1848e8c70ab7642901a68594e8016caffc (patch)
treeeb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /svx/source/svdraw/svdmrkv1.cxx
parentInitial commit. (diff)
downloadlibreoffice-upstream.tar.xz
libreoffice-upstream.zip
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'svx/source/svdraw/svdmrkv1.cxx')
-rw-r--r--svx/source/svdraw/svdmrkv1.cxx545
1 files changed, 545 insertions, 0 deletions
diff --git a/svx/source/svdraw/svdmrkv1.cxx b/svx/source/svdraw/svdmrkv1.cxx
new file mode 100644
index 000000000..0d0ae8dc2
--- /dev/null
+++ b/svx/source/svdraw/svdmrkv1.cxx
@@ -0,0 +1,545 @@
+/* -*- 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 <svx/svdmrkv.hxx>
+#include <svx/svdpagv.hxx>
+
+
+// Point Selection
+
+
+bool SdrMarkView::HasMarkablePoints() const
+{
+ ForceUndirtyMrkPnt();
+ bool bRet=false;
+ if (!ImpIsFrameHandles()) {
+ const size_t nMarkCount=GetMarkedObjectCount();
+ if (nMarkCount<=static_cast<size_t>(mnFrameHandlesLimit)) {
+ for (size_t nMarkNum=0; nMarkNum<nMarkCount && !bRet; ++nMarkNum) {
+ const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
+ const SdrObject* pObj=pM->GetMarkedSdrObj();
+ bRet=pObj->IsPolyObj();
+ }
+ }
+ }
+ return bRet;
+}
+
+sal_Int32 SdrMarkView::GetMarkablePointCount() const
+{
+ ForceUndirtyMrkPnt();
+ sal_Int32 nCount=0;
+ if (!ImpIsFrameHandles()) {
+ const size_t nMarkCount=GetMarkedObjectCount();
+ if (nMarkCount<=static_cast<size_t>(mnFrameHandlesLimit)) {
+ for (size_t nMarkNum=0; nMarkNum<nMarkCount; ++nMarkNum) {
+ const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
+ const SdrObject* pObj=pM->GetMarkedSdrObj();
+ if (pObj->IsPolyObj()) {
+ nCount+=pObj->GetPointCount();
+ }
+ }
+ }
+ }
+ return nCount;
+}
+
+bool SdrMarkView::HasMarkedPoints() const
+{
+ ForceUndirtyMrkPnt();
+ bool bRet=false;
+ if (!ImpIsFrameHandles()) {
+ const size_t nMarkCount=GetMarkedObjectCount();
+ if (nMarkCount<=static_cast<size_t>(mnFrameHandlesLimit)) {
+ for (size_t nMarkNum=0; nMarkNum<nMarkCount && !bRet; ++nMarkNum) {
+ const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
+ const SdrUShortCont& rPts = pM->GetMarkedPoints();
+ bRet = !rPts.empty();
+ }
+ }
+ }
+ return bRet;
+}
+
+bool SdrMarkView::IsPointMarkable(const SdrHdl& rHdl) const
+{
+ return !ImpIsFrameHandles() && !rHdl.IsPlusHdl() && rHdl.GetKind()!=SdrHdlKind::Glue && rHdl.GetKind()!=SdrHdlKind::SmartTag && rHdl.GetObj()!=nullptr && rHdl.GetObj()->IsPolyObj();
+}
+
+bool SdrMarkView::MarkPointHelper(SdrHdl* pHdl, SdrMark* pMark, bool bUnmark)
+{
+ return ImpMarkPoint( pHdl, pMark, bUnmark );
+}
+
+bool SdrMarkView::ImpMarkPoint(SdrHdl* pHdl, SdrMark* pMark, bool bUnmark)
+{
+ if (pHdl==nullptr || pHdl->IsPlusHdl() || pHdl->GetKind()==SdrHdlKind::Glue)
+ return false;
+
+ if (pHdl->IsSelected() != bUnmark)
+ return false;
+
+ SdrObject* pObj=pHdl->GetObj();
+ if (pObj==nullptr || !pObj->IsPolyObj())
+ return false;
+
+ if (pMark==nullptr)
+ {
+ const size_t nMarkNum=TryToFindMarkedObject(pObj);
+ if (nMarkNum==SAL_MAX_SIZE)
+ return false;
+ pMark=GetSdrMarkByIndex(nMarkNum);
+ }
+ const sal_uInt32 nHdlNum(pHdl->GetObjHdlNum());
+ SdrUShortCont& rPts=pMark->GetMarkedPoints();
+ if (!bUnmark)
+ {
+ rPts.insert(static_cast<sal_uInt16>(nHdlNum));
+ }
+ else
+ {
+ SdrUShortCont::const_iterator it = rPts.find( static_cast<sal_uInt16>(nHdlNum) );
+ if (it != rPts.end())
+ {
+ rPts.erase(it);
+ }
+ else
+ {
+ return false; // error case!
+ }
+ }
+
+ pHdl->SetSelected(!bUnmark);
+ if (!mbPlusHdlAlways)
+ {
+ if (!bUnmark)
+ {
+ SdrHdlList plusList(nullptr);
+ pObj->AddToPlusHdlList(plusList, *pHdl);
+ sal_uInt32 nCount(plusList.GetHdlCount());
+ for (sal_uInt32 i=0; i<nCount; i++)
+ {
+ SdrHdl* pPlusHdl=plusList.GetHdl(i);
+ pPlusHdl->SetObj(pObj);
+ pPlusHdl->SetPageView(pMark->GetPageView());
+ pPlusHdl->SetPlusHdl(true);
+ }
+ plusList.MoveTo(maHdlList);
+ }
+ else
+ {
+ for (size_t i = maHdlList.GetHdlCount(); i>0;)
+ {
+ --i;
+ SdrHdl* pPlusHdl=maHdlList.GetHdl(i);
+ if (pPlusHdl->IsPlusHdl() && pPlusHdl->GetSourceHdlNum()==nHdlNum)
+ {
+ maHdlList.RemoveHdl(i);
+ }
+ }
+ }
+ }
+
+ maHdlList.Sort();
+
+ return true;
+}
+
+
+bool SdrMarkView::MarkPoint(SdrHdl& rHdl, bool bUnmark)
+{
+ ForceUndirtyMrkPnt();
+ bool bRet=false;
+ const SdrObject* pObj=rHdl.GetObj();
+ if (IsPointMarkable(rHdl) && rHdl.IsSelected()==bUnmark) {
+ const size_t nMarkNum=TryToFindMarkedObject(pObj);
+ if (nMarkNum!=SAL_MAX_SIZE) {
+ SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
+ if (ImpMarkPoint(&rHdl,pM,bUnmark)) {
+ MarkListHasChanged();
+ bRet=true;
+ }
+ }
+ }
+
+ return bRet;
+}
+
+bool SdrMarkView::MarkPoints(const tools::Rectangle* pRect, bool bUnmark)
+{
+ ForceUndirtyMrkPnt();
+ bool bChgd=false;
+ SortMarkedObjects();
+ const SdrObject* pObj0=nullptr;
+ const SdrPageView* pPV0=nullptr;
+ SdrMark* pM=nullptr;
+ maHdlList.Sort();
+ const size_t nHdlCnt=maHdlList.GetHdlCount();
+ for (size_t nHdlNum=nHdlCnt; nHdlNum>0;) {
+ --nHdlNum;
+ SdrHdl* pHdl=maHdlList.GetHdl(nHdlNum);
+ if (IsPointMarkable(*pHdl) && pHdl->IsSelected()==bUnmark) {
+ const SdrObject* pObj=pHdl->GetObj();
+ const SdrPageView* pPV=pHdl->GetPageView();
+ if (pObj!=pObj0 || pPV!=pPV0 || pM==nullptr) { // This section is for optimization,
+ const size_t nMarkNum=TryToFindMarkedObject(pObj); // so ImpMarkPoint() doesn't always
+ if (nMarkNum!=SAL_MAX_SIZE) { // have to search the object in the MarkList.
+ pM=GetSdrMarkByIndex(nMarkNum);
+ pObj0=pObj;
+ pPV0=pPV;
+ } else {
+#ifdef DBG_UTIL
+ if (pObj->IsInserted()) {
+ OSL_FAIL("SdrMarkView::MarkPoints(const Rectangle* pRect): Selected object not found.");
+ }
+#endif
+ pM=nullptr;
+ }
+ }
+ Point aPos(pHdl->GetPos());
+ if (pM!=nullptr && (pRect==nullptr || pRect->IsInside(aPos))) {
+ if (ImpMarkPoint(pHdl,pM,bUnmark)) bChgd=true;
+ }
+ }
+ }
+ if (bChgd) {
+ MarkListHasChanged();
+ }
+
+ return bChgd;
+}
+
+void SdrMarkView::MarkNextPoint()
+{
+ ForceUndirtyMrkPnt();
+ SortMarkedObjects();
+}
+
+const tools::Rectangle& SdrMarkView::GetMarkedPointsRect() const
+{
+ ForceUndirtyMrkPnt();
+ if (mbMarkedPointsRectsDirty) ImpSetPointsRects();
+ return maMarkedPointsRect;
+}
+
+void SdrMarkView::SetPlusHandlesAlwaysVisible(bool bOn)
+{ // TODO: Optimize HandlePaint!
+ ForceUndirtyMrkPnt();
+ if (bOn!=mbPlusHdlAlways) {
+ mbPlusHdlAlways=bOn;
+ SetMarkHandles(nullptr);
+ MarkListHasChanged();
+ }
+}
+
+
+// ImpSetPointsRects() is for PolyPoints and GluePoints!
+
+
+void SdrMarkView::ImpSetPointsRects() const
+{
+ tools::Rectangle aPnts;
+ tools::Rectangle aGlue;
+ const size_t nHdlCnt=maHdlList.GetHdlCount();
+ for (size_t nHdlNum=0; nHdlNum<nHdlCnt; ++nHdlNum) {
+ const SdrHdl* pHdl=maHdlList.GetHdl(nHdlNum);
+ SdrHdlKind eKind=pHdl->GetKind();
+ if ((eKind==SdrHdlKind::Poly && pHdl->IsSelected()) || eKind==SdrHdlKind::Glue) {
+ Point aPt(pHdl->GetPos());
+ tools::Rectangle& rR=eKind==SdrHdlKind::Glue ? aGlue : aPnts;
+ if (rR.IsEmpty()) {
+ rR=tools::Rectangle(aPt,aPt);
+ } else {
+ if (aPt.X()<rR.Left ()) rR.SetLeft(aPt.X() );
+ if (aPt.X()>rR.Right ()) rR.SetRight(aPt.X() );
+ if (aPt.Y()<rR.Top ()) rR.SetTop(aPt.Y() );
+ if (aPt.Y()>rR.Bottom()) rR.SetBottom(aPt.Y() );
+ }
+ }
+ }
+ const_cast<SdrMarkView*>(this)->maMarkedPointsRect=aPnts;
+ const_cast<SdrMarkView*>(this)->maMarkedGluePointsRect=aGlue;
+ const_cast<SdrMarkView*>(this)->mbMarkedPointsRectsDirty=false;
+}
+
+
+// UndirtyMrkPnt() is for PolyPoints and GluePoints!
+
+
+void SdrMarkView::UndirtyMrkPnt() const
+{
+ bool bChg=false;
+ const size_t nMarkCount=GetMarkedObjectCount();
+ for (size_t nMarkNum=0; nMarkNum<nMarkCount; ++nMarkNum) {
+ SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
+ const SdrObject* pObj=pM->GetMarkedSdrObj();
+ // PolyPoints
+ {
+ SdrUShortCont& rPts = pM->GetMarkedPoints();
+ if (pObj->IsPolyObj()) {
+ // Remove invalid selected points, that is, all
+ // entries above the number of points in the object.
+ sal_uInt32 nMax(pObj->GetPointCount());
+
+ SdrUShortCont::const_iterator it = rPts.lower_bound(nMax);
+ if( it != rPts.end() )
+ {
+ rPts.erase(it, rPts.end());
+ bChg = true;
+ }
+ }
+ else
+ {
+ OSL_FAIL("SdrMarkView::UndirtyMrkPnt(): Selected points on an object that is not a PolyObj!");
+ if (!rPts.empty())
+ {
+ rPts.clear();
+ bChg = true;
+ }
+ }
+ }
+
+ // GluePoints
+ {
+ SdrUShortCont& rPts = pM->GetMarkedGluePoints();
+ const SdrGluePointList* pGPL=pObj->GetGluePointList();
+ if (pGPL!=nullptr) {
+ // Remove invalid selected glue points, that is, all entries
+ // (IDs) that aren't contained in the GluePointList of the
+ // object
+ for(SdrUShortCont::const_iterator it = rPts.begin(); it != rPts.end(); )
+ {
+ sal_uInt16 nId=*it;
+ if (pGPL->FindGluePoint(nId)==SDRGLUEPOINT_NOTFOUND) {
+ it = rPts.erase(it);
+ bChg=true;
+ }
+ else
+ ++it;
+ }
+ } else {
+ if (!rPts.empty()) {
+ rPts.clear(); // object doesn't have any glue points (any more)
+ bChg=true;
+ }
+ }
+ }
+ }
+ if (bChg) const_cast<SdrMarkView*>(this)->mbMarkedPointsRectsDirty=true;
+ const_cast<SdrMarkView*>(this)->mbMrkPntDirty=false;
+}
+
+
+bool SdrMarkView::HasMarkableGluePoints() const
+{
+ bool bRet=false;
+ if (IsGluePointEditMode()) {
+ ForceUndirtyMrkPnt();
+ const size_t nMarkCount=GetMarkedObjectCount();
+ for (size_t nMarkNum=0; nMarkNum<nMarkCount && !bRet; ++nMarkNum) {
+ const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
+ const SdrObject* pObj=pM->GetMarkedSdrObj();
+ const SdrGluePointList* pGPL=pObj->GetGluePointList();
+
+ // #i38892#
+ if(pGPL && pGPL->GetCount())
+ {
+ for(sal_uInt16 a(0); !bRet && a < pGPL->GetCount(); a++)
+ {
+ if((*pGPL)[a].IsUserDefined())
+ {
+ bRet = true;
+ }
+ }
+ }
+ }
+ }
+ return bRet;
+}
+
+bool SdrMarkView::HasMarkedGluePoints() const
+{
+ ForceUndirtyMrkPnt();
+ bool bRet=false;
+ const size_t nMarkCount=GetMarkedObjectCount();
+ for (size_t nMarkNum=0; nMarkNum<nMarkCount && !bRet; ++nMarkNum) {
+ const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
+ const SdrUShortCont& rPts = pM->GetMarkedGluePoints();
+ bRet = !rPts.empty();
+ }
+ return bRet;
+}
+
+bool SdrMarkView::MarkGluePoints(const tools::Rectangle* pRect, bool bUnmark)
+{
+ if (!IsGluePointEditMode() && !bUnmark) return false;
+ ForceUndirtyMrkPnt();
+ bool bChgd=false;
+ SortMarkedObjects();
+ const size_t nMarkCount=GetMarkedObjectCount();
+ for (size_t nMarkNum=0; nMarkNum<nMarkCount; ++nMarkNum) {
+ SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
+ const SdrObject* pObj=pM->GetMarkedSdrObj();
+ const SdrGluePointList* pGPL=pObj->GetGluePointList();
+ SdrUShortCont& rPts = pM->GetMarkedGluePoints();
+ if (bUnmark && pRect==nullptr) { // UnmarkAll
+ if (!rPts.empty()) {
+ rPts.clear();
+ bChgd=true;
+ }
+ } else {
+ if (pGPL!=nullptr) {
+ sal_uInt16 nGluePointCnt=pGPL->GetCount();
+ for (sal_uInt16 nGPNum=0; nGPNum<nGluePointCnt; nGPNum++) {
+ const SdrGluePoint& rGP=(*pGPL)[nGPNum];
+
+ // #i38892#
+ if(rGP.IsUserDefined())
+ {
+ Point aPos(rGP.GetAbsolutePos(*pObj));
+ if (pRect==nullptr || pRect->IsInside(aPos)) {
+ bool bContains = rPts.find( rGP.GetId() ) != rPts.end();
+ if (!bUnmark && !bContains) {
+ bChgd=true;
+ rPts.insert(rGP.GetId());
+ }
+ if (bUnmark && bContains) {
+ bChgd=true;
+ rPts.erase(rGP.GetId());
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ if (bChgd) {
+ AdjustMarkHdl();
+ MarkListHasChanged();
+ }
+ return bChgd;
+}
+
+bool SdrMarkView::PickGluePoint(const Point& rPnt, SdrObject*& rpObj, sal_uInt16& rnId, SdrPageView*& rpPV) const
+{
+ rpObj=nullptr; rpPV=nullptr; rnId=0;
+ if (!IsGluePointEditMode()) return false;
+ OutputDevice* pOut=mpActualOutDev.get();
+ if (pOut==nullptr) pOut=GetFirstOutputDevice();
+ if (pOut==nullptr) return false;
+ SortMarkedObjects();
+ const size_t nMarkCount=GetMarkedObjectCount();
+ size_t nMarkNum=nMarkCount;
+ while (nMarkNum>0) {
+ nMarkNum--;
+ const SdrMark* pM=GetSdrMarkByIndex(nMarkNum);
+ SdrObject* pObj=pM->GetMarkedSdrObj();
+ SdrPageView* pPV=pM->GetPageView();
+ const SdrGluePointList* pGPL=pObj->GetGluePointList();
+ if (pGPL!=nullptr) {
+ sal_uInt16 nNum=pGPL->HitTest(rPnt,*pOut,pObj);
+ if (nNum!=SDRGLUEPOINT_NOTFOUND)
+ {
+ // #i38892#
+ const SdrGluePoint& rCandidate = (*pGPL)[nNum];
+
+ if(rCandidate.IsUserDefined())
+ {
+ rpObj=pObj;
+ rnId=(*pGPL)[nNum].GetId();
+ rpPV=pPV;
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+}
+
+bool SdrMarkView::MarkGluePoint(const SdrObject* pObj, sal_uInt16 nId, bool bUnmark)
+{
+ if (!IsGluePointEditMode()) return false;
+ ForceUndirtyMrkPnt();
+ bool bChgd=false;
+ if (pObj!=nullptr) {
+ const size_t nMarkPos=TryToFindMarkedObject(pObj);
+ if (nMarkPos!=SAL_MAX_SIZE) {
+ SdrMark* pM=GetSdrMarkByIndex(nMarkPos);
+ SdrUShortCont& rPts = pM->GetMarkedGluePoints();
+ bool bContains = rPts.find( nId ) != rPts.end();
+ if (!bUnmark && !bContains) {
+ bChgd=true;
+ rPts.insert(nId);
+ }
+ if (bUnmark && bContains) {
+ bChgd=true;
+ rPts.erase(nId);
+ }
+ } else {
+ // TODO: implement implicit selection of objects
+ }
+ }
+ if (bChgd) {
+ AdjustMarkHdl();
+ MarkListHasChanged();
+ }
+ return bChgd;
+}
+
+bool SdrMarkView::IsGluePointMarked(const SdrObject* pObj, sal_uInt16 nId) const
+{
+ ForceUndirtyMrkPnt();
+ bool bRet=false;
+ const size_t nPos=TryToFindMarkedObject(pObj); // casting to NonConst
+ if (nPos!=SAL_MAX_SIZE) {
+ const SdrMark* pM=GetSdrMarkByIndex(nPos);
+ const SdrUShortCont& rPts = pM->GetMarkedGluePoints();
+ bRet = rPts.find( nId ) != rPts.end();
+ }
+ return bRet;
+}
+
+SdrHdl* SdrMarkView::GetGluePointHdl(const SdrObject* pObj, sal_uInt16 nId) const
+{
+ ForceUndirtyMrkPnt();
+ const size_t nHdlCnt=maHdlList.GetHdlCount();
+ for (size_t nHdlNum=0; nHdlNum<nHdlCnt; ++nHdlNum) {
+ SdrHdl* pHdl=maHdlList.GetHdl(nHdlNum);
+ if (pHdl->GetObj()==pObj &&
+ pHdl->GetKind()==SdrHdlKind::Glue &&
+ pHdl->GetObjHdlNum()==nId ) return pHdl;
+ }
+ return nullptr;
+}
+
+void SdrMarkView::MarkNextGluePoint()
+{
+ ForceUndirtyMrkPnt();
+ SortMarkedObjects();
+}
+
+const tools::Rectangle& SdrMarkView::GetMarkedGluePointsRect() const
+{
+ ForceUndirtyMrkPnt();
+ if (mbMarkedPointsRectsDirty) ImpSetPointsRects();
+ return maMarkedGluePointsRect;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */