cui/source/dialogs/DiagramDialog.cxx           |    7 -
 include/oox/drawingml/shape.hxx                |    6 
 include/svx/diagram/IDiagramHelper.hxx         |   99 ++++++++++++++++
 include/svx/svdobj.hxx                         |    6 
 include/svx/svdogrp.hxx                        |   89 +-------------
 oox/source/drawingml/diagram/diagramhelper.cxx |    2 
 oox/source/drawingml/diagram/diagramhelper.hxx |    3 
 sc/source/ui/drawfunc/drawsh2.cxx              |    4 
 sc/source/ui/drawfunc/drawsh5.cxx              |    9 -
 sd/source/ui/view/drviews3.cxx                 |    9 -
 solenv/clang-format/excludelist                |    4 
 svx/Library_svxcore.mk                         |    1 
 svx/source/diagram/IDiagramHelper.cxx          |  152 +++++++++++++++++++++++++
 svx/source/svdraw/svdedtv.cxx                  |    5 
 svx/source/svdraw/svdedtv2.cxx                 |    3 
 svx/source/svdraw/svdmrkv.cxx                  |    7 +
 svx/source/svdraw/svdmrkv1.cxx                 |    3 
 svx/source/svdraw/svdobj.cxx                   |    5 
 svx/source/svdraw/svdogrp.cxx                  |   24 +--
 svx/source/svdraw/svdpagv.cxx                  |    3 
 svx/source/svdraw/svdundo.cxx                  |   17 --
 sw/source/core/frmedt/feshview.cxx             |    3 
 sw/source/filter/ww8/docxattributeoutput.cxx   |    3 
 sw/source/uibase/shells/drwbassh.cxx           |   14 +-
 writerfilter/source/dmapper/GraphicImport.cxx  |    2 
 25 files changed, 336 insertions(+), 144 deletions(-)

New commits:
commit 8b4b852a35149b1cfffc681cbb4f57d4c0b671b3
Author:     Armin Le Grand (Allotropia) <armin.le.gr...@me.com>
AuthorDate: Mon May 23 15:48:41 2022 +0200
Commit:     Armin Le Grand <armin.le.gr...@me.com>
CommitDate: Wed May 25 09:59:17 2022 +0200

    Advanced Diagram support: Isolated IDiagramHelper, selection visualization
    
    Moved and isolated IDiagramHelper to own file to get SdrObjGroup smaller
    and less dependent again, all places adapted. isDiagram() now available
    at SdrObject directly, adapted and have less places which need to cast
    for SdrObjGroup for check.
    
    Started to add SdrHdl/selection visualization to seleced Diagram. Only
    as a start, will need to be extended to look good/better, plus evtl.
    functionality in handles/UI.
    
    Corrected error(s) found by failing UnitTests
    More clang-notes (static, namespace) I nneeded to follow
    
    Change-Id: If4675b3270d3ee30259fce49deb017dbbaf5c0c4
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/134825
    Tested-by: Jenkins
    Reviewed-by: Armin Le Grand <armin.le.gr...@me.com>

diff --git a/cui/source/dialogs/DiagramDialog.cxx 
b/cui/source/dialogs/DiagramDialog.cxx
index ea592767461d..c53bafe943c8 100644
--- a/cui/source/dialogs/DiagramDialog.cxx
+++ b/cui/source/dialogs/DiagramDialog.cxx
@@ -15,6 +15,7 @@
 #include <svx/svdundo.hxx>
 #include <com/sun/star/beans/PropertyValue.hpp>
 #include <svx/diagram/datamodel.hxx>
+#include <svx/diagram/IDiagramHelper.hxx>
 
 DiagramDialog::DiagramDialog(weld::Window* pWindow, SdrObjGroup& rDiagram)
     : GenericDialogController(pWindow, "cui/ui/diagramdialog.ui", 
"DiagramDialog")
@@ -61,7 +62,7 @@ IMPL_LINK_NOARG(DiagramDialog, OnAddClick, weld::Button&, 
void)
         return;
 
     OUString sText = mpTextAdd->get_text();
-    const std::shared_ptr<IDiagramHelper>& 
pDiagramHelper(m_rDiagram.getDiagramHelper());
+    const std::shared_ptr< svx::diagram::IDiagramHelper >& 
pDiagramHelper(m_rDiagram.getDiagramHelper());
 
     if (pDiagramHelper && !sText.isEmpty())
     {
@@ -99,7 +100,7 @@ IMPL_LINK_NOARG(DiagramDialog, OnRemoveClick, weld::Button&, 
void)
         return;
 
     std::unique_ptr<weld::TreeIter> pEntry(mpTreeDiagram->make_iterator());
-    const std::shared_ptr<IDiagramHelper>& 
pDiagramHelper(m_rDiagram.getDiagramHelper());
+    const std::shared_ptr< svx::diagram::IDiagramHelper >& 
pDiagramHelper(m_rDiagram.getDiagramHelper());
 
     if (pDiagramHelper && mpTreeDiagram->get_selected(pEntry.get()))
     {
@@ -135,7 +136,7 @@ void DiagramDialog::populateTree(const weld::TreeIter* 
pParent, const OUString&
     if (!m_rDiagram.isDiagram())
         return;
 
-    const std::shared_ptr<IDiagramHelper>& 
pDiagramHelper(m_rDiagram.getDiagramHelper());
+    const std::shared_ptr< svx::diagram::IDiagramHelper >& 
pDiagramHelper(m_rDiagram.getDiagramHelper());
 
     if (!pDiagramHelper)
         return;
diff --git a/include/oox/drawingml/shape.hxx b/include/oox/drawingml/shape.hxx
index 3d0ee6ebaec8..4318c1e24d2d 100644
--- a/include/oox/drawingml/shape.hxx
+++ b/include/oox/drawingml/shape.hxx
@@ -58,7 +58,9 @@ namespace oox::vml {
     struct OleObjectInfo;
 }
 
-class IDiagramHelper;
+namespace svx::diagram {
+    class IDiagramHelper;
+}
 
 namespace oox::drawingml {
 
@@ -410,7 +412,7 @@ private:
 
     // temporary space for DiagramHelper in preparation for collecting data
     // Note: I tried to use a unique_ptr here, but existing constructor func 
does not allow that
-    IDiagramHelper* mpDiagramHelper;
+    svx::diagram::IDiagramHelper* mpDiagramHelper;
 
     // association-ID to identify the Diagram ModelData
     OUString msDiagramDataModelID;
diff --git a/include/svx/diagram/IDiagramHelper.hxx 
b/include/svx/diagram/IDiagramHelper.hxx
new file mode 100644
index 000000000000..c0bf0539050d
--- /dev/null
+++ b/include/svx/diagram/IDiagramHelper.hxx
@@ -0,0 +1,99 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <vector>
+#include <svx/svxdllapi.h>
+#include <rtl/ustring.hxx>
+
+// Forward declarations
+class SdrObjGroup;
+class SdrHdlList;
+
+namespace svx { namespace diagram {
+
+class DiagramDataState;
+
+// Helper class to allow administer advanced Diagram related
+// data and functionality
+class SVXCORE_DLLPUBLIC IDiagramHelper
+{
+private:
+    // These values define behaviour to where take data from at re-creation 
time.
+    // Different definitions will have different consequences for re-creation
+    // of Diagram visualization (if needed/triggered).
+    // The style attributes per shape e.g. can be re-stored frm either an
+    // existing Theme, or the preserved key/value list of properties per 
XShape.
+    // With the current default settings the re-creation uses the preserved
+    // key/value pairs, but re-creation from Theme may also be desirable. It
+    // is also good to preserve both data packages at initial import to allow
+    // alternatively one of these two methods for re-construction
+
+    // If true, the oox::Theme data from ::DiagramData get/set/ThemeDocument()
+    // aka mxThemeDocument - if it exists - will be used to create the style
+    // attributes for the to-be-created XShapes (theoretically allows 
re-creation
+    // with other Theme)
+    bool mbUseDiagramThemeData; // false
+
+    // If true, the UNO API form of attributes per Point as Key/value list
+    // that was secured after initial XShape creation is used to create the
+    // style attributes for the to-be-created XShapes
+    bool mbUseDiagramModelData; // true
+
+    // If true and mxThemeDocument exists it will be re-imported to
+    // a newly created oox::drawingml::Theme object
+    bool mbForceThemePtrRecreation; // false
+
+protected:
+    void anchorToSdrObjGroup(SdrObjGroup& rTarget);
+
+public:
+    IDiagramHelper();
+    virtual ~IDiagramHelper();
+
+    // re-create XShapes
+    virtual void reLayout(SdrObjGroup& rTarget) = 0;
+
+    // get text representation of data tree
+    virtual OUString getString() const = 0;
+
+    // get children of provided data node
+    // use empty string for top-level nodes
+    // returns vector of (id, text)
+    virtual std::vector<std::pair<OUString, OUString>>
+    getChildren(const OUString& rParentId) const = 0;
+
+    // add/remove new top-level node to data model, returns its id
+    virtual OUString addNode(const OUString& rText) = 0;
+    virtual bool removeNode(const OUString& rNodeId) = 0;
+
+    // Undo/Redo helpers for extracting/restoring Diagram-defining data
+    virtual std::shared_ptr<svx::diagram::DiagramDataState> 
extractDiagramDataState() const = 0;
+    virtual void applyDiagramDataState(const 
std::shared_ptr<svx::diagram::DiagramDataState>& rState) = 0;
+
+    bool UseDiagramThemeData() const { return mbUseDiagramThemeData; }
+    bool UseDiagramModelData() const { return mbUseDiagramModelData; }
+    bool ForceThemePtrRecreation() const { return mbForceThemePtrRecreation; };
+
+    static void AddAdditionalVisualization(const SdrObjGroup& rTarget, 
SdrHdlList& rHdlList);
+};
+
+}} // end of namespace
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/svx/svdobj.hxx b/include/svx/svdobj.hxx
index 5ee18b292deb..2e350c49b0f4 100644
--- a/include/svx/svdobj.hxx
+++ b/include/svx/svdobj.hxx
@@ -88,6 +88,7 @@ namespace sdr::contact { class ViewContact; }
 
 namespace svx { class PropertyChangeNotifier; }
 namespace com::sun::star::drawing { class XShape; }
+namespace svx::diagram { class IDiagramHelper; }
 
 
 struct SVXCORE_DLLPUBLIC SdrObjectFreeOp;
@@ -258,6 +259,11 @@ public:
 /// Abstract DrawObject
 class SVXCORE_DLLPUBLIC SdrObject : public SfxListener, public tools::WeakBase
 {
+public:
+    // Basic DiagramHelper support
+    virtual const std::shared_ptr< svx::diagram::IDiagramHelper >& 
getDiagramHelper() const;
+    bool isDiagram() const { return bool(getDiagramHelper()); }
+
 private:
     friend class                SdrObjListIter;
     friend class                SdrObjList;
diff --git a/include/svx/svdogrp.hxx b/include/svx/svdogrp.hxx
index c411a049c959..4322d56dfc38 100644
--- a/include/svx/svdogrp.hxx
+++ b/include/svx/svdogrp.hxx
@@ -24,84 +24,13 @@
 #include <svx/svxdllapi.h>
 #include <svx/svdpage.hxx>
 
-// Forward declarations
-class SfxItemSet;
-class SdrObjGroup;
-namespace svx
-{
-namespace diagram
-{
-class DiagramDataState;
-}
-}
-
-// Helper class to allow administer advanced Diagram related
-// data and functionality
-class SVXCORE_DLLPUBLIC IDiagramHelper
-{
-private:
-    // These values define behaviour to where take data from at re-creation 
time.
-    // Different definitions will have different consequences for re-creation
-    // of Diagram visualization (if needed/triggered).
-    // The style attributes per shape e.g. can be re-stored frm either an
-    // existing Theme, or the preserved key/value list of properties per 
XShape.
-    // With the current default settings the re-creation uses the preserved
-    // key/value pairs, but re-creation from Theme may also be desirable. It
-    // is also good to preserve both data packages at initial import to allow
-    // alternatively one of these two methods for re-construction
-
-    // If true, the oox::Theme data from ::DiagramData get/set/ThemeDocument()
-    // aka mxThemeDocument - if it exists - will be used to create the style
-    // attributes for the to-be-created XShapes (theoretically allows 
re-creation
-    // with other Theme)
-    bool mbUseDiagramThemeData; // false
-
-    // If true, the UNO API form of attributes per Point as Key/value list
-    // that was secured after initial XShape creation is used to create the
-    // style attributes for the to-be-created XShapes
-    bool mbUseDiagramModelData; // true
-
-    // If true and mxThemeDocument exists it will be re-imported to
-    // a newly created oox::drawingml::Theme object
-    bool mbForceThemePtrRecreation; // false
-
-protected:
-    void anchorToSdrObjGroup(SdrObjGroup& rTarget);
-
-public:
-    IDiagramHelper();
-    virtual ~IDiagramHelper();
-
-    // re-create XShapes
-    virtual void reLayout(SdrObjGroup& rTarget) = 0;
-
-    // get text representation of data tree
-    virtual OUString getString() const = 0;
-
-    // get children of provided data node
-    // use empty string for top-level nodes
-    // returns vector of (id, text)
-    virtual std::vector<std::pair<OUString, OUString>>
-    getChildren(const OUString& rParentId) const = 0;
-
-    // add/remove new top-level node to data model, returns its id
-    virtual OUString addNode(const OUString& rText) = 0;
-    virtual bool removeNode(const OUString& rNodeId) = 0;
-
-    // Undo/Redo helpers for extracting/restoring Diagram-defining data
-    virtual std::shared_ptr<svx::diagram::DiagramDataState> 
extractDiagramDataState() const = 0;
-    virtual void
-    applyDiagramDataState(const 
std::shared_ptr<svx::diagram::DiagramDataState>& rState)
-        = 0;
-
-    bool UseDiagramThemeData() const { return mbUseDiagramThemeData; }
-    bool UseDiagramModelData() const { return mbUseDiagramModelData; }
-    bool ForceThemePtrRecreation() const { return mbForceThemePtrRecreation; };
-};
-
 //   SdrObjGroup
 class SVXCORE_DLLPUBLIC SdrObjGroup final : public SdrObject, public SdrObjList
 {
+public:
+    // Basic DiagramHelper support
+    virtual const std::shared_ptr< svx::diagram::IDiagramHelper >& 
getDiagramHelper() const override;
+
 private:
     virtual std::unique_ptr<sdr::contact::ViewContact> 
CreateObjectSpecificViewContact() override;
     virtual std::unique_ptr<sdr::properties::BaseProperties>
@@ -111,14 +40,9 @@ private:
 
     // Allow *only* DiagramHelper itself to set this internal reference to
     // tightly control usage
-    friend class IDiagramHelper;
-    std::shared_ptr<IDiagramHelper> mp_DiagramHelper;
+    friend class svx::diagram::IDiagramHelper;
+    std::shared_ptr< svx::diagram::IDiagramHelper > mp_DiagramHelper;
 
-public:
-    bool isDiagram() const { return bool(mp_DiagramHelper); }
-    const std::shared_ptr<IDiagramHelper>& getDiagramHelper() { return 
mp_DiagramHelper; }
-
-private:
     // protected destructor - due to final, make private
     virtual ~SdrObjGroup() override;
 
@@ -192,6 +116,7 @@ public:
     virtual SdrObjectUniquePtr DoConvertToPolyObj(bool bBezier, bool bAddText) 
const override;
 
     virtual void dumpAsXml(xmlTextWriterPtr pWriter) const override;
+    virtual void AddToHdlList(SdrHdlList& rHdlList) const override;
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/source/drawingml/diagram/diagramhelper.cxx 
b/oox/source/drawingml/diagram/diagramhelper.cxx
index 7859a9667e7b..7b746e0678ba 100644
--- a/oox/source/drawingml/diagram/diagramhelper.cxx
+++ b/oox/source/drawingml/diagram/diagramhelper.cxx
@@ -42,7 +42,7 @@ AdvancedDiagramHelper::AdvancedDiagramHelper(
     const std::shared_ptr< Diagram >& rDiagramPtr,
     const std::shared_ptr<::oox::drawingml::Theme>& rTheme,
     css::awt::Size aImportSize)
-: IDiagramHelper()
+: svx::diagram::IDiagramHelper()
 , mpDiagramPtr(rDiagramPtr)
 , mpThemePtr(rTheme)
 , maImportSize(aImportSize)
diff --git a/oox/source/drawingml/diagram/diagramhelper.hxx 
b/oox/source/drawingml/diagram/diagramhelper.hxx
index e47047746776..85ca4c45728c 100644
--- a/oox/source/drawingml/diagram/diagramhelper.hxx
+++ b/oox/source/drawingml/diagram/diagramhelper.hxx
@@ -24,6 +24,7 @@
 #include <oox/drawingml/theme.hxx>
 #include <oox/shape/ShapeFilterBase.hxx>
 #include <svx/svdogrp.hxx>
+#include <svx/diagram/IDiagramHelper.hxx>
 
 namespace svx { namespace diagram {
     class DiagramDataState;
@@ -46,7 +47,7 @@ class Diagram;
 // - deliver representative data from the Diagram-Model
 // - modify it eventually
 // - im/export Diagram model to other representations
-class AdvancedDiagramHelper final : public IDiagramHelper
+class AdvancedDiagramHelper final : public svx::diagram::IDiagramHelper
 {
     const std::shared_ptr< Diagram >            mpDiagramPtr;
     std::shared_ptr<::oox::drawingml::Theme>    mpThemePtr;
diff --git a/sc/source/ui/drawfunc/drawsh2.cxx 
b/sc/source/ui/drawfunc/drawsh2.cxx
index c4eb11484aa5..020178be50ce 100644
--- a/sc/source/ui/drawfunc/drawsh2.cxx
+++ b/sc/source/ui/drawfunc/drawsh2.cxx
@@ -270,9 +270,7 @@ void ScDrawShell::GetDrawFuncState( SfxItemSet& rSet )      
// disable functions
             rSet.DisableItem( SID_FITCELLSIZE );
 
         // Support advanced DiagramHelper
-        SdrObjGroup* pAnchorObj = dynamic_cast<SdrObjGroup*>(pObj);
-
-        if(!pAnchorObj || !pAnchorObj->isDiagram())
+        if(!pObj || !pObj->isDiagram())
         {
             rSet.DisableItem( SID_REGENERATE_DIAGRAM );
             rSet.DisableItem( SID_EDIT_DIAGRAM );
diff --git a/sc/source/ui/drawfunc/drawsh5.cxx 
b/sc/source/ui/drawfunc/drawsh5.cxx
index c06b1b646760..b95f77f9339c 100644
--- a/sc/source/ui/drawfunc/drawsh5.cxx
+++ b/sc/source/ui/drawfunc/drawsh5.cxx
@@ -33,6 +33,7 @@
 #include <svx/svdogrp.hxx>
 #include <sfx2/docfile.hxx>
 #include <osl/diagnose.h>
+#include <svx/diagram/IDiagramHelper.hxx>
 
 #include <com/sun/star/form/FormButtonType.hpp>
 #include <com/sun/star/beans/XPropertySet.hpp>
@@ -282,14 +283,12 @@ void ScDrawShell::ExecDrawFunc( SfxRequest& rReq )
                     SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
 
                     // Support advanced DiagramHelper
-                    SdrObjGroup* pAnchorObj = dynamic_cast<SdrObjGroup*>(pObj);
-
-                    if(pAnchorObj && pAnchorObj->isDiagram())
+                    if(nullptr != pObj && pObj->isDiagram())
                     {
                         if(SID_REGENERATE_DIAGRAM == nSlotId)
                         {
                             pView->UnmarkAll();
-                            
pAnchorObj->getDiagramHelper()->reLayout(*pAnchorObj);
+                            
pObj->getDiagramHelper()->reLayout(*static_cast<SdrObjGroup*>(pObj));
                             pView->MarkObj(pObj, pView->GetSdrPageView());
                         }
                         else // SID_EDIT_DIAGRAM
@@ -298,7 +297,7 @@ void ScDrawShell::ExecDrawFunc( SfxRequest& rReq )
                             vcl::Window* pWin = rViewData.GetActiveWin();
                             ScopedVclPtr<VclAbstractDialog> pDlg = 
pFact->CreateDiagramDialog(
                                 pWin ? pWin->GetFrameWeld() : nullptr,
-                                *pAnchorObj);
+                                *static_cast<SdrObjGroup*>(pObj));
                             pDlg->Execute();
                         }
                     }
diff --git a/sd/source/ui/view/drviews3.cxx b/sd/source/ui/view/drviews3.cxx
index 6a7c778d8a6f..5821168bc865 100644
--- a/sd/source/ui/view/drviews3.cxx
+++ b/sd/source/ui/view/drviews3.cxx
@@ -49,6 +49,7 @@
 #include <svx/float3d.hxx>
 #include <svx/sdmetitm.hxx>
 #include <svx/svdogrp.hxx>
+#include <svx/diagram/IDiagramHelper.hxx>
 
 #include <app.hrc>
 #include <strings.hrc>
@@ -491,14 +492,12 @@ void  DrawViewShell::ExecCtrl(SfxRequest& rReq)
                 SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
 
                 // Support advanced DiagramHelper
-                SdrObjGroup* pAnchorObj = dynamic_cast<SdrObjGroup*>(pObj);
-
-                if(pAnchorObj && pAnchorObj->isDiagram())
+                if(nullptr != pObj && pObj->isDiagram())
                 {
                     if(SID_REGENERATE_DIAGRAM == nSlot)
                     {
                         mpDrawView->UnmarkAll();
-                        pAnchorObj->getDiagramHelper()->reLayout(*pAnchorObj);
+                        
pObj->getDiagramHelper()->reLayout(*static_cast<SdrObjGroup*>(pObj));
                         mpDrawView->MarkObj(pObj, 
mpDrawView->GetSdrPageView());
                     }
                     else // SID_EDIT_DIAGRAM
@@ -506,7 +505,7 @@ void  DrawViewShell::ExecCtrl(SfxRequest& rReq)
                         VclAbstractDialogFactory* pFact = 
VclAbstractDialogFactory::Create();
                         ScopedVclPtr<VclAbstractDialog> pDlg = 
pFact->CreateDiagramDialog(
                             GetFrameWeld(),
-                            *pAnchorObj);
+                            *static_cast<SdrObjGroup*>(pObj));
                         pDlg->Execute();
                     }
                 }
diff --git a/solenv/clang-format/excludelist b/solenv/clang-format/excludelist
index 9b8a5d679aac..9a3d34e3d2cf 100644
--- a/solenv/clang-format/excludelist
+++ b/solenv/clang-format/excludelist
@@ -2368,6 +2368,7 @@ cui/source/customize/eventdlg.cxx
 cui/source/customize/eventdlg.hxx
 cui/source/customize/macropg.cxx
 cui/source/customize/macropg_impl.hxx
+cui/source/dialogs/DiagramDialog.cxx
 cui/source/dialogs/SpellAttrib.hxx
 cui/source/dialogs/SpellDialog.cxx
 cui/source/dialogs/about.cxx
@@ -5950,6 +5951,7 @@ include/svx/sdmetitm.hxx
 include/svx/sdooitm.hxx
 include/svx/sdprcitm.hxx
 include/svx/diagram/datamodel.hxx
+include/svx/diagram/IDiagramHelper.hxx
 include/svx/sdr/animation/animationstate.hxx
 include/svx/sdr/animation/objectanimator.hxx
 include/svx/sdr/animation/scheduler.hxx
@@ -6024,6 +6026,7 @@ include/svx/svdocapt.hxx
 include/svx/svdocirc.hxx
 include/svx/svdoedge.hxx
 include/svx/svdograf.hxx
+include/svx/svdogrp.hxx
 include/svx/svdomeas.hxx
 include/svx/svdomedia.hxx
 include/svx/svdoole2.hxx
@@ -11515,6 +11518,7 @@ svx/source/customshapes/EnhancedCustomShapeHandle.cxx
 svx/source/customshapes/EnhancedCustomShapeHandle.hxx
 svx/source/customshapes/EnhancedCustomShapeTypeNames.cxx
 svx/source/diagram/datamodel.cxx
+svx/source/diagram/IDiagramHelper.cxx
 svx/source/dialog/ClassificationDialog.cxx
 svx/source/dialog/ClassificationEditView.cxx
 svx/source/dialog/ClassificationEditView.hxx
diff --git a/svx/Library_svxcore.mk b/svx/Library_svxcore.mk
index 4102c1ddc96e..5cacdf82ebcc 100644
--- a/svx/Library_svxcore.mk
+++ b/svx/Library_svxcore.mk
@@ -111,6 +111,7 @@ $(eval $(call gb_Library_add_exception_objects,svxcore,\
     svx/source/customshapes/EnhancedCustomShapeGeometry \
     svx/source/customshapes/EnhancedCustomShapeTypeNames \
     svx/source/diagram/datamodel \
+    svx/source/diagram/IDiagramHelper \
     svx/source/dialog/dialmgr \
     svx/source/dialog/dlgutil \
     svx/source/dialog/hexcolorcontrol \
diff --git a/svx/source/diagram/IDiagramHelper.cxx 
b/svx/source/diagram/IDiagramHelper.cxx
new file mode 100644
index 000000000000..3c5f7462204d
--- /dev/null
+++ b/svx/source/diagram/IDiagramHelper.cxx
@@ -0,0 +1,152 @@
+/* -*- 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/diagram/IDiagramHelper.hxx>
+#include <svx/svdogrp.hxx>
+
+#include <svx/svdhdl.hxx>
+#include <svx/svdmrkv.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/sdrpagewindow.hxx>
+#include <svx/sdrpaintwindow.hxx>
+#include <svx/sdr/overlay/overlaypolypolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+
+namespace {
+
+class DiagramFrameHdl final : public SdrHdl
+{
+    basegfx::B2DHomMatrix maTransformation;
+
+    // create marker for this kind
+    virtual void CreateB2dIAObject() override;
+
+public:
+    DiagramFrameHdl(const basegfx::B2DHomMatrix& rTransformation);
+    // virtual ~DiagramFrameHdl() override;
+};
+
+void DiagramFrameHdl::CreateB2dIAObject()
+{
+    // first throw away old one
+    GetRidOfIAObject();
+
+    SdrMarkView* pView = pHdlList->GetView();
+
+    if(!pView || pView->areMarkHandlesHidden())
+        return;
+
+    SdrPageView* pPageView = pView->GetSdrPageView();
+
+    if(!pPageView)
+        return;
+
+    for(sal_uInt32 b(0); b < pPageView->PageWindowCount(); b++)
+    {
+        const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b);
+
+        if(rPageWindow.GetPaintWindow().OutputToWindow())
+        {
+            const rtl::Reference< sdr::overlay::OverlayManager >& xManager = 
rPageWindow.GetOverlayManager();
+            if (xManager.is())
+            {
+                OutputDevice& 
rOutDev(rPageWindow.GetPaintWindow().GetOutputDevice());
+                const basegfx::B2DVector 
aDiscreteInLogic(rOutDev.GetInverseViewTransformation() * 
basegfx::B2DVector(1.0, 0.0));
+                const double fDiscretePixelSize(aDiscreteInLogic.getLength());
+                const double fOuterDistance(7.0);
+                const double fInnerDistance(5.0);
+
+                basegfx::B2DRange aRange(0.0, 0.0, 1.0, 1.0);
+                aRange.transform(maTransformation);
+
+                basegfx::B2DRange aOuterRange(aRange);
+                aOuterRange.grow(fDiscretePixelSize * fOuterDistance);
+
+                basegfx::B2DRange aInnerRange(aRange);
+                aInnerRange.grow(fDiscretePixelSize * fInnerDistance);
+
+                basegfx::B2DPolyPolygon aPolyPolygon;
+                
aPolyPolygon.append(basegfx::utils::createPolygonFromRect(aOuterRange));
+                
aPolyPolygon.append(basegfx::utils::createPolygonFromRect(aInnerRange));
+
+                const StyleSettings& 
rStyles(rOutDev.GetSettings().GetStyleSettings());
+                Color aFillColor(rStyles.GetHighlightColor());
+                Color aLineColor(aFillColor);
+                aFillColor.IncreaseLuminance(10);
+                aLineColor.DecreaseLuminance(30);
+
+                std::unique_ptr<sdr::overlay::OverlayObject> pNewOverlayObject(
+                    new sdr::overlay::OverlayPolyPolygon(
+                            aPolyPolygon,
+                            aLineColor,  // Line
+                            fDiscretePixelSize * 2.0,
+                            aFillColor)); // Fill
+
+                // OVERLAYMANAGER
+                insertNewlyCreatedOverlayObjectForSdrHdl(
+                    std::move(pNewOverlayObject),
+                    rPageWindow.GetObjectContact(),
+                    *xManager);
+            }
+        }
+    }
+}
+
+DiagramFrameHdl::DiagramFrameHdl(const basegfx::B2DHomMatrix& rTransformation)
+: SdrHdl(Point(), SdrHdlKind::Move)
+, maTransformation(rTransformation)
+{
+}
+
+// DiagramFrameHdl::~DiagramFrameHdl()
+// {
+// }
+
+} // end of anonymous namespace
+
+namespace svx { namespace diagram {
+
+IDiagramHelper::IDiagramHelper()
+: mbUseDiagramThemeData(false)
+, mbUseDiagramModelData(true)
+, mbForceThemePtrRecreation(false)
+{
+}
+
+IDiagramHelper::~IDiagramHelper() {}
+
+void IDiagramHelper::anchorToSdrObjGroup(SdrObjGroup& rTarget)
+{
+    rTarget.mp_DiagramHelper.reset(this);
+}
+
+void IDiagramHelper::AddAdditionalVisualization(const SdrObjGroup& rTarget, 
SdrHdlList& rHdlList)
+{
+    // create an extra frame visuaization here
+    basegfx::B2DHomMatrix aTransformation;
+    basegfx::B2DPolyPolygon aPolyPolygon;
+    rTarget.TRGetBaseGeometry(aTransformation, aPolyPolygon);
+
+    std::unique_ptr<SdrHdl> pHdl(new DiagramFrameHdl(aTransformation));
+    rHdlList.AddHdl(std::move(pHdl));
+}
+
+}} // end of namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/svdraw/svdedtv.cxx b/svx/source/svdraw/svdedtv.cxx
index df42a3d78dea..b019f26ae47a 100644
--- a/svx/source/svdraw/svdedtv.cxx
+++ b/svx/source/svdraw/svdedtv.cxx
@@ -680,8 +680,9 @@ void SdrEditView::CheckPossibilities()
     // Don't allow enter Diagrams
     if (1 == nMarkCount && m_bGrpEnterPossible)
     {
-        auto* pGroup(dynamic_cast<SdrObjGroup*>(GetMarkedObjectByIndex(0)));
-        if(nullptr != pGroup && pGroup->isDiagram())
+        SdrObject* pCandidate(GetMarkedObjectByIndex(0));
+
+        if(nullptr != pCandidate && pCandidate->isDiagram())
             m_bGrpEnterPossible = false;
     }
 }
diff --git a/svx/source/svdraw/svdedtv2.cxx b/svx/source/svdraw/svdedtv2.cxx
index d1e216c554d7..47e20d82be6a 100644
--- a/svx/source/svdraw/svdedtv2.cxx
+++ b/svx/source/svdraw/svdedtv2.cxx
@@ -1911,8 +1911,7 @@ void SdrEditView::UnGroupMarked()
             size_t nDstCnt=pGrp->GetOrdNum();
             SdrObjList* pDstLst=pM->GetPageView()->GetObjList();
             size_t nObjCount=pSrcLst->GetObjCount();
-            auto* pGroup(dynamic_cast<SdrObjGroup*>(pGrp));
-            const bool bIsDiagram(nullptr != pGroup && pGroup->isDiagram());
+            const bool bIsDiagram(nullptr != pGrp && pGrp->isDiagram());
 
             // If the Group is a Diagram, it has a filler BG object to 
guarantee
             // the Diagam's dimensions. Identify that shape
diff --git a/svx/source/svdraw/svdmrkv.cxx b/svx/source/svdraw/svdmrkv.cxx
index 506125be7d43..01b065f970f1 100644
--- a/svx/source/svdraw/svdmrkv.cxx
+++ b/svx/source/svdraw/svdmrkv.cxx
@@ -1332,6 +1332,13 @@ void SdrMarkView::SetMarkHandles(SfxViewShell* 
pOtherShell)
                 }
             }
 
+            // Diagram selection visualization support
+            // Caution: CppunitTest_sd_tiledrendering shows that mpMarkedObj 
*can* actually be nullptr (!)
+            if(nullptr != mpMarkedObj && mpMarkedObj->isDiagram())
+            {
+                mpMarkedObj->AddToHdlList(maHdlList);
+            }
+
             const size_t nSiz1(maHdlList.GetHdlCount());
 
             // moved setting the missing parameters at SdrHdl here from the
diff --git a/svx/source/svdraw/svdmrkv1.cxx b/svx/source/svdraw/svdmrkv1.cxx
index 693965b10f81..9c732262bcc9 100644
--- a/svx/source/svdraw/svdmrkv1.cxx
+++ b/svx/source/svdraw/svdmrkv1.cxx
@@ -308,9 +308,10 @@ void SdrMarkView::UndirtyMrkPnt() const
             }
             else
             {
-                OSL_FAIL("SdrMarkView::UndirtyMrkPnt(): Selected points on an 
object that is not a PolyObj!");
                 if (!rPts.empty())
                 {
+                    // only fail *if* there are marked points
+                    OSL_FAIL("SdrMarkView::UndirtyMrkPnt(): Selected points on 
an object that is not a PolyObj!");
                     rPts.clear();
                     bChg = true;
                 }
diff --git a/svx/source/svdraw/svdobj.cxx b/svx/source/svdraw/svdobj.cxx
index 000c79937739..e8d41c51b39d 100644
--- a/svx/source/svdraw/svdobj.cxx
+++ b/svx/source/svdraw/svdobj.cxx
@@ -199,6 +199,11 @@ struct SdrObject::Impl
         meRelativeHeightRelation(text::RelOrientation::PAGE_FRAME) {}
 };
 
+const std::shared_ptr< svx::diagram::IDiagramHelper >& 
SdrObject::getDiagramHelper() const
+{
+    static std::shared_ptr< svx::diagram::IDiagramHelper > aEmpty;
+    return aEmpty;
+}
 
 // BaseProperties section
 
diff --git a/svx/source/svdraw/svdogrp.cxx b/svx/source/svdraw/svdogrp.cxx
index f7fb1eb14f79..7fc8e0b12f80 100644
--- a/svx/source/svdraw/svdogrp.cxx
+++ b/svx/source/svdraw/svdogrp.cxx
@@ -30,22 +30,13 @@
 #include <sdr/contact/viewcontactofgroup.hxx>
 #include <basegfx/range/b2drange.hxx>
 #include <basegfx/polygon/b2dpolygontools.hxx>
-#include <basegfx/polygon/b2dpolygon.hxx>
 #include <libxml/xmlwriter.h>
 #include <vcl/canvastools.hxx>
+#include <svx/diagram/IDiagramHelper.hxx>
 
-IDiagramHelper::IDiagramHelper()
-: mbUseDiagramThemeData(false)
-, mbUseDiagramModelData(true)
-, mbForceThemePtrRecreation(false)
+const std::shared_ptr< svx::diagram::IDiagramHelper >& 
SdrObjGroup::getDiagramHelper() const
 {
-}
-
-IDiagramHelper::~IDiagramHelper() {}
-
-void IDiagramHelper::anchorToSdrObjGroup(SdrObjGroup& rTarget)
-{
-    rTarget.mp_DiagramHelper.reset(this);
+    return mp_DiagramHelper;
 }
 
 // BaseProperties section
@@ -95,6 +86,15 @@ SdrObjGroup::SdrObjGroup(SdrModel& rSdrModel, SdrObjGroup 
const & rSource)
     maRefPoint  = rSource.maRefPoint;
 }
 
+void SdrObjGroup::AddToHdlList(SdrHdlList& rHdlList) const
+{
+    // only for diagram, so do nothing for just groups
+    if(!isDiagram())
+        return;
+
+    svx::diagram::IDiagramHelper::AddAdditionalVisualization(*this, rHdlList);
+}
+
 SdrObjGroup::~SdrObjGroup()
 {
 }
diff --git a/svx/source/svdraw/svdpagv.cxx b/svx/source/svdraw/svdpagv.cxx
index 022975f3e5b1..0e35d09b080e 100644
--- a/svx/source/svdraw/svdpagv.cxx
+++ b/svx/source/svdraw/svdpagv.cxx
@@ -730,8 +730,7 @@ bool SdrPageView::EnterGroup(SdrObject* pObj)
         return false;
 
     // Don't allow enter Diagrams
-    auto* pGroup(dynamic_cast<SdrObjGroup*>(pObj));
-    if(nullptr != pGroup && pGroup->isDiagram())
+    if(nullptr != pObj && pObj->isDiagram())
         return false;
 
     const bool bGlueInvalidate(GetView().ImpIsGlueVisible());
diff --git a/svx/source/svdraw/svdundo.cxx b/svx/source/svdraw/svdundo.cxx
index b61ad93fde90..bd2ff6d8c1f9 100644
--- a/svx/source/svdraw/svdundo.cxx
+++ b/svx/source/svdraw/svdundo.cxx
@@ -46,6 +46,7 @@
 #include <sal/log.hxx>
 #include <osl/diagnose.h>
 #include <svx/diagram/datamodel.hxx>
+#include <svx/diagram/IDiagramHelper.hxx>
 
 
 // iterates over all views and unmarks this SdrObject if it is marked
@@ -634,12 +635,8 @@ 
SdrUndoDiagramModelData::SdrUndoDiagramModelData(SdrObject& rNewObj, svx::diagra
 , m_aStartState(rStartState)
 , m_aEndState()
 {
-    SdrObjGroup* pDiagram(dynamic_cast<SdrObjGroup*>(&rNewObj));
-
-    if(pDiagram && pDiagram->isDiagram())
-    {
-        m_aEndState = pDiagram->getDiagramHelper()->extractDiagramDataState();
-    }
+    if(rNewObj.isDiagram())
+        m_aEndState = rNewObj.getDiagramHelper()->extractDiagramDataState();
 }
 
 SdrUndoDiagramModelData::~SdrUndoDiagramModelData()
@@ -651,14 +648,12 @@ void SdrUndoDiagramModelData::implUndoRedo(bool bUndo)
     if(nullptr == pObj)
         return;
 
-    SdrObjGroup* pDiagram(dynamic_cast<SdrObjGroup*>(pObj));
-
-    if(nullptr == pDiagram || !pDiagram->isDiagram())
+    if(!pObj->isDiagram())
         return;
 
-    pDiagram->getDiagramHelper()->applyDiagramDataState(
+    pObj->getDiagramHelper()->applyDiagramDataState(
         bUndo ? m_aStartState : m_aEndState);
-    pDiagram->getDiagramHelper()->reLayout(*pDiagram);
+    pObj->getDiagramHelper()->reLayout(*static_cast<SdrObjGroup*>(pObj));
 }
 
 void SdrUndoDiagramModelData::Undo()
diff --git a/sw/source/core/frmedt/feshview.cxx 
b/sw/source/core/frmedt/feshview.cxx
index 898166f0178a..44fbce476a7a 100644
--- a/sw/source/core/frmedt/feshview.cxx
+++ b/sw/source/core/frmedt/feshview.cxx
@@ -2456,8 +2456,7 @@ bool SwFEShell::IsGroupSelected(bool bAllowDiagams)
                 if(!bAllowDiagams)
                 {
                     // Don't allow enter Diagrams
-                    auto* pGroup(dynamic_cast<SdrObjGroup*>(pObj));
-                    if(nullptr != pGroup && pGroup->isDiagram())
+                    if(pObj->isDiagram())
                     {
                         return false;
                     }
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx 
b/sw/source/filter/ww8/docxattributeoutput.cxx
index db9fd1a873b8..6d179315d456 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -6459,8 +6459,7 @@ void DocxAttributeOutput::WriteFlyFrame(const ww8::Frame& 
rFrame)
                 const SdrObject* pSdrObj = 
rFrame.GetFrameFormat().FindRealSdrObject();
                 if ( pSdrObj )
                 {
-                    const SdrObjGroup* pDiagramCandidate(dynamic_cast<const 
SdrObjGroup*>(pSdrObj));
-                    const bool bIsDiagram(nullptr != pDiagramCandidate && 
pDiagramCandidate->isDiagram());
+                    const bool bIsDiagram(nullptr != pSdrObj && 
pSdrObj->isDiagram());
 
                     if (bIsDiagram)
                     {
diff --git a/sw/source/uibase/shells/drwbassh.cxx 
b/sw/source/uibase/shells/drwbassh.cxx
index 77325a28eddb..766ca0ae81bb 100644
--- a/sw/source/uibase/shells/drwbassh.cxx
+++ b/sw/source/uibase/shells/drwbassh.cxx
@@ -59,6 +59,7 @@
 #include <IDocumentDrawModelAccess.hxx>
 #include <fmtfollowtextflow.hxx>
 #include <textboxhelper.hxx>
+#include <svx/diagram/IDiagramHelper.hxx>
 
 using namespace ::com::sun::star;
 using namespace css::beans;
@@ -446,14 +447,12 @@ void SwDrawBaseShell::Execute(SfxRequest const &rReq)
                     SdrObject* pObj = rMarkList.GetMark(0)->GetMarkedSdrObj();
 
                     // Support advanced DiagramHelper
-                    SdrObjGroup* pAnchorObj = dynamic_cast<SdrObjGroup*>(pObj);
-
-                    if(pAnchorObj && pAnchorObj->isDiagram())
+                    if(nullptr != pObj && pObj->isDiagram())
                     {
                         if(SID_REGENERATE_DIAGRAM == nSlotId)
                         {
                             pSdrView->UnmarkAll();
-                            
pAnchorObj->getDiagramHelper()->reLayout(*pAnchorObj);
+                            
pObj->getDiagramHelper()->reLayout(*static_cast<SdrObjGroup*>(pObj));
                             pSdrView->MarkObj(pObj, 
pSdrView->GetSdrPageView());
                         }
                         else // SID_EDIT_DIAGRAM
@@ -461,7 +460,7 @@ void SwDrawBaseShell::Execute(SfxRequest const &rReq)
                             VclAbstractDialogFactory* pFact = 
VclAbstractDialogFactory::Create();
                             ScopedVclPtr<VclAbstractDialog> pDlg = 
pFact->CreateDiagramDialog(
                                 GetView().GetFrameWeld(),
-                                *pAnchorObj);
+                                *static_cast<SdrObjGroup*>(pObj));
                             pDlg->Execute();
                         }
                     }
@@ -940,8 +939,9 @@ void SwDrawBaseShell::GetState(SfxItemSet& rSet)
                 const SdrMarkList& rMarkList = pSdrView->GetMarkedObjectList();
                 if (nullptr != rMarkList.GetMark(0))
                 {
-                    SdrObjGroup* pSdrObjGroup = 
dynamic_cast<SdrObjGroup*>(rMarkList.GetMark(0)->GetMarkedSdrObj());
-                    if(nullptr != pSdrObjGroup && pSdrObjGroup->isDiagram())
+                    SdrObject* pObj(rMarkList.GetMark(0)->GetMarkedSdrObj());
+
+                    if(nullptr != pObj && pObj->isDiagram())
                     {
                         bDisable = false;
                     }
diff --git a/writerfilter/source/dmapper/GraphicImport.cxx 
b/writerfilter/source/dmapper/GraphicImport.cxx
index 2f006bbd2e5a..49435404c003 100644
--- a/writerfilter/source/dmapper/GraphicImport.cxx
+++ b/writerfilter/source/dmapper/GraphicImport.cxx
@@ -919,7 +919,7 @@ void GraphicImport::lcl_attribute(Id nName, Value& rValue)
                         // tdf#143455: A diagram is imported as group, but has 
no valid object list
                         // and contour wrap is different to Word. As 
workaround diagrams are excluded
                         // here in various places.
-                        const SdrObjGroup* 
pDiagramCandidate(dynamic_cast<const 
SdrObjGroup*>(SdrObject::getSdrObjectFromXShape(m_xShape)));
+                        const SdrObject* 
pDiagramCandidate(SdrObject::getSdrObjectFromXShape(m_xShape));
                         const bool bIsDiagram(nullptr != pDiagramCandidate && 
pDiagramCandidate->isDiagram());
                         // tdf#143476: A lockedCanvas (Word2007) is imported 
as group, but has not
                         // got size and position. Values from m_Impl has to be 
used.

Reply via email to