summaryrefslogtreecommitdiffstats
path: root/svx/source/sidebar/SelectionAnalyzer.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svx/source/sidebar/SelectionAnalyzer.cxx')
-rw-r--r--svx/source/sidebar/SelectionAnalyzer.cxx479
1 files changed, 479 insertions, 0 deletions
diff --git a/svx/source/sidebar/SelectionAnalyzer.cxx b/svx/source/sidebar/SelectionAnalyzer.cxx
new file mode 100644
index 000000000..14134980f
--- /dev/null
+++ b/svx/source/sidebar/SelectionAnalyzer.cxx
@@ -0,0 +1,479 @@
+/* -*- 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/sidebar/SelectionAnalyzer.hxx>
+#include <svx/svdmark.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdotext.hxx>
+#include <svx/svdpage.hxx>
+
+using vcl::EnumContext;
+
+
+namespace svx::sidebar {
+
+EnumContext::Context SelectionAnalyzer::GetContextForSelection_SC (const SdrMarkList& rMarkList)
+{
+ EnumContext::Context eContext = EnumContext::Context::Unknown;
+
+ switch (rMarkList.GetMarkCount())
+ {
+ case 0:
+ // Empty selection. Return Context::Unknown to let the caller
+ // substitute it with the default context.
+ break;
+
+ case 1:
+ {
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ if ( dynamic_cast<const SdrTextObj*>( pObj) != nullptr && static_cast<SdrTextObj*>(pObj)->IsInEditMode() )
+ {
+ eContext = EnumContext::Context::DrawText;
+ }
+ else
+ {
+ const SdrInventor nInv = pObj->GetObjInventor();
+ const sal_uInt16 nObjId = pObj->GetObjIdentifier();
+ if (nInv == SdrInventor::Default)
+ eContext = GetContextForObjectId_SC(nObjId);
+ else if (nInv == SdrInventor::FmForm)
+ eContext = EnumContext::Context::Form;
+ }
+ break;
+ }
+
+ default:
+ {
+ // Multi selection.
+ switch (GetInventorTypeFromMark(rMarkList))
+ {
+ case SdrInventor::Default:
+ {
+ const sal_uInt16 nObjId (GetObjectTypeFromMark(rMarkList));
+ if (nObjId == 0)
+ eContext = EnumContext::Context::MultiObject;
+ else
+ eContext = GetContextForObjectId_SC(nObjId);
+ break;
+ }
+
+ case SdrInventor::FmForm:
+ eContext = EnumContext::Context::Form;
+ break;
+
+ case SdrInventor::Unknown:
+ eContext = EnumContext::Context::MultiObject;
+ break;
+
+ default: break;
+ }
+ }
+ }
+
+ return eContext;
+}
+
+
+EnumContext::Context SelectionAnalyzer::GetContextForSelection_SD (
+ const SdrMarkList& rMarkList,
+ const ViewType eViewType)
+{
+ EnumContext::Context eContext = EnumContext::Context::Unknown;
+
+ // Note that some cases are handled by the caller. They rely on
+ // sd specific data.
+ switch (rMarkList.GetMarkCount())
+ {
+ case 0:
+ switch(eViewType)
+ {
+ case ViewType::Standard:
+ eContext = EnumContext::Context::DrawPage;
+ break;
+ case ViewType::Master:
+ eContext = EnumContext::Context::MasterPage;
+ break;
+ case ViewType::Handout:
+ eContext = EnumContext::Context::HandoutPage;
+ break;
+ case ViewType::Notes:
+ eContext = EnumContext::Context::NotesPage;
+ break;
+ }
+ break;
+
+ case 1:
+ {
+ SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
+ if (dynamic_cast<const SdrTextObj*>( pObj) != nullptr && static_cast<SdrTextObj*>(pObj)->IsInEditMode())
+ {
+ if (pObj->GetObjIdentifier() == OBJ_TABLE)
+ {
+ // Let a table object take precedence over text
+ // edit mode. The panels for text editing are
+ // present for table context as well, anyway.
+ eContext = EnumContext::Context::Table;
+ }
+ else
+ eContext = EnumContext::Context::DrawText;
+ }
+ else
+ {
+ const SdrInventor nInv = pObj->GetObjInventor();
+ sal_uInt16 nObjId = pObj->GetObjIdentifier();
+ if (nInv == SdrInventor::Default)
+ {
+ if (nObjId == OBJ_GRUP)
+ {
+ nObjId = GetObjectTypeFromGroup(pObj);
+ if (nObjId == 0)
+ nObjId = OBJ_GRUP;
+ }
+ eContext = GetContextForObjectId_SD(nObjId, eViewType);
+ }
+ else if (nInv == SdrInventor::E3d)
+ {
+ eContext = EnumContext::Context::ThreeDObject;
+ }
+ else if (nInv == SdrInventor::FmForm)
+ {
+ eContext = EnumContext::Context::Form;
+ }
+ }
+ break;
+ }
+
+ default:
+ {
+ switch (GetInventorTypeFromMark(rMarkList))
+ {
+ case SdrInventor::Default:
+ {
+ const sal_uInt16 nObjId = GetObjectTypeFromMark(rMarkList);
+ if (nObjId == 0)
+ eContext = EnumContext::Context::MultiObject;
+ else
+ eContext = GetContextForObjectId_SD(nObjId, eViewType);
+ break;
+ }
+
+ case SdrInventor::E3d:
+ eContext = EnumContext::Context::ThreeDObject;
+ break;
+
+ case SdrInventor::FmForm:
+ eContext = EnumContext::Context::Form;
+ break;
+
+ case SdrInventor::Unknown:
+ eContext = EnumContext::Context::MultiObject;
+ break;
+
+ default: break;
+ }
+ break;
+ }
+ }
+
+ return eContext;
+}
+
+
+EnumContext::Context SelectionAnalyzer::GetContextForObjectId_SC (const sal_uInt16 nObjectId)
+{
+ switch (nObjectId)
+ {
+ case OBJ_CAPTION:
+ case OBJ_TITLETEXT:
+ case OBJ_OUTLINETEXT:
+ case OBJ_TEXT:
+ case OBJ_MEASURE:
+ case OBJ_RECT:
+ case OBJ_CIRC:
+ case OBJ_FREEFILL:
+ case OBJ_PATHFILL:
+ case OBJ_POLY:
+ case OBJ_SECT:
+ case OBJ_CARC:
+ case OBJ_CCUT:
+ case OBJ_CUSTOMSHAPE:
+ case OBJ_GRUP:
+ return EnumContext::Context::Draw;
+
+ case OBJ_PLIN:
+ case OBJ_PATHLINE:
+ case OBJ_FREELINE:
+ case OBJ_LINE:
+ case OBJ_EDGE:
+ return EnumContext::Context::DrawLine;
+
+ case OBJ_GRAF:
+ return EnumContext::Context::Graphic;
+
+ case OBJ_OLE2:
+ return EnumContext::Context::OLE;
+
+ case OBJ_MEDIA:
+ return EnumContext::Context::Media;
+ break;
+
+ default:
+ return EnumContext::Context::Unknown;
+ }
+}
+
+
+EnumContext::Context SelectionAnalyzer::GetContextForObjectId_SD (
+ const sal_uInt16 nObjectId,
+ const ViewType eViewType)
+{
+ switch (nObjectId)
+ {
+ case OBJ_CAPTION:
+ case OBJ_MEASURE:
+ case OBJ_RECT:
+ case OBJ_CIRC:
+ case OBJ_FREEFILL:
+ case OBJ_PATHFILL:
+ case OBJ_POLY:
+ case OBJ_SECT:
+ case OBJ_CARC:
+ case OBJ_CCUT:
+ case OBJ_CUSTOMSHAPE:
+ case OBJ_GRUP:
+ return EnumContext::Context::Draw;
+
+ case OBJ_EDGE:
+ case OBJ_PATHLINE:
+ case OBJ_FREELINE:
+ case OBJ_PLIN:
+ case OBJ_LINE:
+ return EnumContext::Context::DrawLine;
+
+ case OBJ_TITLETEXT:
+ case OBJ_OUTLINETEXT:
+ case OBJ_TEXT:
+ return EnumContext::Context::TextObject;
+
+ case OBJ_GRAF:
+ return EnumContext::Context::Graphic;
+
+ case OBJ_OLE2:
+ return EnumContext::Context::OLE;
+
+ case OBJ_MEDIA:
+ return EnumContext::Context::Media;
+
+ case OBJ_TABLE:
+ return EnumContext::Context::Table;
+
+ case OBJ_PAGE:
+ switch (eViewType)
+ {
+ case ViewType::Handout:
+ return EnumContext::Context::HandoutPage;
+ case ViewType::Notes:
+ return EnumContext::Context::NotesPage;
+ default:
+ return EnumContext::Context::Unknown;
+ }
+
+ default:
+ return EnumContext::Context::Unknown;
+ }
+}
+
+
+SdrInventor SelectionAnalyzer::GetInventorTypeFromMark (const SdrMarkList& rMarkList)
+{
+ const size_t nMarkCount (rMarkList.GetMarkCount());
+
+ if (nMarkCount < 1)
+ return SdrInventor::Unknown;
+
+ SdrMark* pMark = rMarkList.GetMark(0);
+ SdrObject* pObj = pMark->GetMarkedSdrObj();
+ const SdrInventor nFirstInv = pObj->GetObjInventor();
+
+ for (size_t nIndex=1; nIndex<nMarkCount; ++nIndex)
+ {
+ pMark = rMarkList.GetMark(nIndex);
+ pObj = pMark->GetMarkedSdrObj();
+ const SdrInventor nInv (pObj->GetObjInventor());
+
+ if (nInv != nFirstInv)
+ return SdrInventor::Unknown;
+ }
+
+ return nFirstInv;
+}
+
+
+sal_uInt16 SelectionAnalyzer::GetObjectTypeFromGroup (const SdrObject* pObj)
+{
+ SdrObjList* pObjList = pObj->GetSubList();
+ if (pObjList)
+ {
+ const size_t nSubObjCount (pObjList->GetObjCount());
+
+ if (nSubObjCount>0)
+ {
+ SdrObject* pSubObj = pObjList->GetObj(0);
+ sal_uInt16 nResultType = pSubObj->GetObjIdentifier();
+
+ if (nResultType == OBJ_GRUP)
+ nResultType = GetObjectTypeFromGroup(pSubObj);
+
+ if (IsShapeType(nResultType))
+ nResultType = OBJ_CUSTOMSHAPE;
+
+ if (IsTextObjType(nResultType))
+ nResultType = OBJ_TEXT;
+
+ for (size_t nIndex=1; nIndex<nSubObjCount; ++nIndex)
+ {
+ pSubObj = pObjList->GetObj(nIndex);
+ sal_uInt16 nType (pSubObj->GetObjIdentifier());
+
+ if(nType == OBJ_GRUP)
+ nType = GetObjectTypeFromGroup(pSubObj);
+
+ if (IsShapeType(nType))
+ nType = OBJ_CUSTOMSHAPE;
+
+ if ((nType == OBJ_CUSTOMSHAPE) && (nResultType == OBJ_TEXT))
+ nType = OBJ_TEXT;
+
+ if (IsTextObjType(nType))
+ nType = OBJ_TEXT;
+
+ if ((nType == OBJ_TEXT) && (nResultType == OBJ_CUSTOMSHAPE))
+ nResultType = OBJ_TEXT;
+
+ if (nType != nResultType)
+ return 0;
+ }
+
+ return nResultType;
+ }
+ }
+
+ return 0;
+}
+
+
+sal_uInt16 SelectionAnalyzer::GetObjectTypeFromMark (const SdrMarkList& rMarkList)
+{
+ const size_t nMarkCount (rMarkList.GetMarkCount());
+
+ if (nMarkCount < 1)
+ return 0;
+
+ SdrMark* pMark = rMarkList.GetMark(0);
+ SdrObject* pObj = pMark->GetMarkedSdrObj();
+ sal_uInt16 nResultType = pObj->GetObjIdentifier();
+
+ if(nResultType == OBJ_GRUP)
+ nResultType = GetObjectTypeFromGroup(pObj);
+
+ if (IsShapeType(nResultType))
+ nResultType = OBJ_CUSTOMSHAPE;
+
+ if (IsTextObjType(nResultType))
+ nResultType = OBJ_TEXT;
+
+ for (size_t nIndex=1; nIndex<nMarkCount; ++nIndex)
+ {
+ pMark = rMarkList.GetMark(nIndex);
+ pObj = pMark->GetMarkedSdrObj();
+ sal_uInt16 nType = pObj->GetObjIdentifier();
+
+ if(nType == OBJ_GRUP)
+ nType = GetObjectTypeFromGroup(pObj);
+
+ if (IsShapeType(nType))
+ nType = OBJ_CUSTOMSHAPE;
+
+ if ((nType == OBJ_CUSTOMSHAPE) && (nResultType == OBJ_TEXT))
+ nType = OBJ_TEXT;
+
+ if (IsTextObjType(nType))
+ nType = OBJ_TEXT;
+
+ if ((nType == OBJ_TEXT) && (nResultType == OBJ_CUSTOMSHAPE))
+ nResultType = OBJ_TEXT;
+
+ if (nType != nResultType)
+ return 0;
+ }
+
+ return nResultType;
+}
+
+
+bool SelectionAnalyzer::IsShapeType (const sal_uInt16 nType)
+{
+ switch (nType)
+ {
+ case OBJ_LINE:
+ case OBJ_CARC:
+ case OBJ_PLIN:
+ case OBJ_PATHLINE:
+ case OBJ_RECT:
+ case OBJ_CIRC:
+ case OBJ_SECT:
+ case OBJ_CCUT:
+ case OBJ_PATHFILL:
+ case OBJ_CUSTOMSHAPE:
+ case OBJ_CAPTION:
+ case OBJ_MEASURE:
+ case OBJ_EDGE:
+ case OBJ_POLY:
+ case OBJ_FREELINE:
+ case OBJ_FREEFILL:
+
+ // #122145# adding OBJ_OLE2 since these also allow line/fill style and may
+ // be multiselected/grouped with normal draw objects, e.g. math OLE objects
+ case OBJ_OLE2:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+
+bool SelectionAnalyzer::IsTextObjType (const sal_uInt16 nType)
+{
+ switch(nType)
+ {
+ case OBJ_TEXT:
+ case OBJ_TITLETEXT:
+ case OBJ_OUTLINETEXT:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+
+} // end of namespace svx::sidebar
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */