Advanced Diagram support: Disable enter Diagram (Groups)

Groups which are in Diagram mode should not be entered, to
do so disable at UI and - for security reasons - also at
the executing mehod.
Groups in Diagram mode can still be UnGrouped (which will
remove the Diagram status & data)

Adapted testRegenerateDiagram() to directly act on the
model data to test the same as before. Using triggering
of UI events to enter the diagram group object needs
reorganization, but model op's will always be possible

Change-Id: I199f3821c2a8308a6f015997ce9eaef87623c46a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130541
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx
index 56487deb5..5fabb1f 100644
--- a/sd/qa/unit/tiledrendering/tiledrendering.cxx
+++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx
@@ -2581,31 +2581,12 @@ void SdTiledRenderingTest::testRegenerateDiagram()
    SdPage* pActualPage = pXImpressDocument->GetDocShell()->GetViewShell()->GetActualPage();
    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(4), pActualPage->GetObj(0)->GetSubList()->GetObjCount());

    // select diagram
    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::TAB);
    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::TAB);
    Scheduler::ProcessEventsToIdle();

    // enter group
    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::F3);
    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::F3);
    Scheduler::ProcessEventsToIdle();

    // select shape and delete
    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::TAB);
    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::TAB);
    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::TAB);
    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::TAB);
    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::DELETE);
    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::DELETE);
    Scheduler::ProcessEventsToIdle();

    // exit group
    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::TAB);
    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, awt::Key::TAB);
    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_MOD1 | awt::Key::F3);
    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, KEY_MOD1 | awt::Key::F3);
    Scheduler::ProcessEventsToIdle();
    // For new Diagram funcionality entering group using UI is not allowed as long
    // as the group shape is a diagram. Do the same as before done by triggering UI
    // events directly in the model
    // Remove and free top-left entry (Box showing "A")
    SdrObject* pTopLeftRemoved = pActualPage->GetObj(0)->GetSubList()->RemoveObject(1);
    SdrObject::Free(pTopLeftRemoved);

    // select diagram
    pXImpressDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, awt::Key::TAB);
diff --git a/sd/source/ui/view/drviewsj.cxx b/sd/source/ui/view/drviewsj.cxx
index 9f9a520..40dd8dc 100644
--- a/sd/source/ui/view/drviewsj.cxx
+++ b/sd/source/ui/view/drviewsj.cxx
@@ -132,12 +132,19 @@ void DrawViewShell::GetMenuStateSel( SfxItemSet &rSet )

            /* If it is not a group object or 3D object, we disable "enter
               group". */
            if( !( ( dynamic_cast< const SdrObjGroup *>( pObj ) != nullptr && nInv == SdrInventor::Default ) ||
            const auto* pIsGroup(dynamic_cast<const SdrObjGroup*>(pObj));
            if( !( ( pIsGroup != nullptr && nInv == SdrInventor::Default ) ||
                   ( dynamic_cast< const E3dScene* >(pObj) != nullptr ) ) )
            {
                rSet.DisableItem( SID_ENTER_GROUP );
            }

            // Don't allow enter Diagrams
            if(nullptr != pIsGroup && pIsGroup->isDiagram())
            {
                rSet.DisableItem( SID_ENTER_GROUP );
            }

            // If it is not a group object, we disable "ungroup"
            if(dynamic_cast< const SdrObjGroup *>( pObj ) == nullptr || nInv != SdrInventor::Default)
            {
diff --git a/svx/source/svdraw/svdedtv.cxx b/svx/source/svdraw/svdedtv.cxx
index 47f5c97..c59b1e6 100644
--- a/svx/source/svdraw/svdedtv.cxx
+++ b/svx/source/svdraw/svdedtv.cxx
@@ -676,6 +676,14 @@ void SdrEditView::CheckPossibilities()
            if (pNode1!=nullptr || pNode2!=nullptr) m_bMoveAllowed=false;
        }
    }

    // Don't allow enter Diagrams
    if (1 == nMarkCount && m_bGrpEnterPossible)
    {
        auto* pGroup(dynamic_cast<SdrObjGroup*>(GetMarkedObjectByIndex(0)));
        if(nullptr != pGroup && pGroup->isDiagram())
            m_bGrpEnterPossible = false;
    }
}


diff --git a/svx/source/svdraw/svdpagv.cxx b/svx/source/svdraw/svdpagv.cxx
index 791a1fc..022975f3 100644
--- a/svx/source/svdraw/svdpagv.cxx
+++ b/svx/source/svdraw/svdpagv.cxx
@@ -726,51 +726,52 @@ void SdrPageView::SetCurrentGroupAndList(SdrObject* pNewGroup, SdrObjList* pNewL

bool SdrPageView::EnterGroup(SdrObject* pObj)
{
    bool bRet(false);
    if(!pObj || !pObj->IsGroupObject())
        return false;

    if(pObj && pObj->IsGroupObject())
    // Don't allow enter Diagrams
    auto* pGroup(dynamic_cast<SdrObjGroup*>(pObj));
    if(nullptr != pGroup && pGroup->isDiagram())
        return false;

    const bool bGlueInvalidate(GetView().ImpIsGlueVisible());

    if (bGlueInvalidate)
    {
        bool bGlueInvalidate(GetView().ImpIsGlueVisible());

        if(bGlueInvalidate)
        {
            GetView().GlueInvalidate();
        }

        // deselect all
        GetView().UnmarkAll();

        // set current group and list
        SdrObjList* pNewObjList = pObj->GetSubList();
        SetCurrentGroupAndList(pObj, pNewObjList);

        // select contained object if only one object is contained,
        // else select nothing and let the user decide what to do next
        if(pNewObjList && pNewObjList->GetObjCount() == 1)
        {
            SdrObject* pFirstObject = pNewObjList->GetObj(0);

            if(GetView().GetSdrPageView())
            {
                GetView().MarkObj(pFirstObject, GetView().GetSdrPageView());
            }
        }

        // build new handles
        GetView().AdjustMarkHdl();

        // invalidate only when view wants to visualize group entering
        InvalidateAllWin();

        if (bGlueInvalidate)
        {
            GetView().GlueInvalidate();
        }

        bRet = true;
        GetView().GlueInvalidate();
    }

    return bRet;
    // deselect all
    GetView().UnmarkAll();

    // set current group and list
    SdrObjList* pNewObjList = pObj->GetSubList();
    SetCurrentGroupAndList(pObj, pNewObjList);

    // select contained object if only one object is contained,
    // else select nothing and let the user decide what to do next
    if(pNewObjList && pNewObjList->GetObjCount() == 1)
    {
        SdrObject* pFirstObject = pNewObjList->GetObj(0);

        if(GetView().GetSdrPageView())
        {
            GetView().MarkObj(pFirstObject, GetView().GetSdrPageView());
        }
    }

    // build new handles
    GetView().AdjustMarkHdl();

    // invalidate only when view wants to visualize group entering
    InvalidateAllWin();

    if (bGlueInvalidate)
    {
        GetView().GlueInvalidate();
    }

    return true;
}

void SdrPageView::LeaveOneGroup()
diff --git a/sw/inc/fesh.hxx b/sw/inc/fesh.hxx
index 4b7ec6a..3801bac 100644
--- a/sw/inc/fesh.hxx
+++ b/sw/inc/fesh.hxx
@@ -542,7 +542,7 @@ public:
    bool EndMark  ();

    /// Create and destroy group, don't when frame is selected.
    bool IsGroupSelected();     ///< Can be a mixed selection!
    bool IsGroupSelected(bool bAllowDiagams);     ///< Can be a mixed selection!
    void GroupSelection();          ///< Afterwards the group is selected.
    void UnGroupSelection();        /**< The individual objects are selected, but
                                    it is possible that there are groups included. */
diff --git a/sw/source/core/frmedt/feshview.cxx b/sw/source/core/frmedt/feshview.cxx
index 0b4dd1c..30be64d 100644
--- a/sw/source/core/frmedt/feshview.cxx
+++ b/sw/source/core/frmedt/feshview.cxx
@@ -2425,7 +2425,7 @@ Point SwFEShell::GetObjAbsPos() const
    return Imp()->GetDrawView()->GetDragStat().GetActionRect().TopLeft();
}

bool SwFEShell::IsGroupSelected()
bool SwFEShell::IsGroupSelected(bool bAllowDiagams)
{
    if ( IsObjSelected() )
    {
@@ -2441,6 +2441,16 @@ bool SwFEShell::IsGroupSelected()
                 RndStdIds::FLY_AS_CHAR != static_cast<SwDrawContact*>(GetUserCall(pObj))->
                                      GetFormat()->GetAnchor().GetAnchorId() )
            {
                if(!bAllowDiagams)
                {
                    // Don't allow enter Diagrams
                    auto* pGroup(dynamic_cast<SdrObjGroup*>(pObj));
                    if(nullptr != pGroup && pGroup->isDiagram())
                    {
                        return false;
                    }
                }

                return true;
            }
        }
@@ -2565,7 +2575,7 @@ void SwFEShell::GroupSelection()
// The individual objects get a copy of the anchor and the contactobject of the group
void SwFEShell::UnGroupSelection()
{
    if ( IsGroupSelected() )
    if ( IsGroupSelected(true) )
    {
        StartAllAction();
        StartUndo( SwUndoId::START );
diff --git a/sw/source/uibase/shells/drwbassh.cxx b/sw/source/uibase/shells/drwbassh.cxx
index 8cafe32..5beca06 100644
--- a/sw/source/uibase/shells/drwbassh.cxx
+++ b/sw/source/uibase/shells/drwbassh.cxx
@@ -419,7 +419,7 @@ void SwDrawBaseShell::Execute(SfxRequest const &rReq)
            break;

        case SID_UNGROUP:
            if (pSh->IsGroupSelected() && pSh->IsUnGroupAllowed())
            if (pSh->IsGroupSelected(true) && pSh->IsUnGroupAllowed())
            {
                pSh->UnGroupSelection();
                rBind.Invalidate(SID_GROUP);
@@ -427,7 +427,7 @@ void SwDrawBaseShell::Execute(SfxRequest const &rReq)
            break;

        case SID_ENTER_GROUP:
            if (pSh->IsGroupSelected())
            if (pSh->IsGroupSelected(false))
            {
                pSdrView->EnterMarkedGroup();
                rBind.InvalidateAll(false);
@@ -731,11 +731,11 @@ void SwDrawBaseShell::GetState(SfxItemSet& rSet)
                    rSet.DisableItem( nWhich );
                break;
            case SID_UNGROUP:
                if ( !rSh.IsGroupSelected() || bProtected || !rSh.IsUnGroupAllowed() )
                if ( !rSh.IsGroupSelected(true) || bProtected || !rSh.IsUnGroupAllowed() )
                    rSet.DisableItem( nWhich );
                break;
            case SID_ENTER_GROUP:
                if ( !rSh.IsGroupSelected() )
                if ( !rSh.IsGroupSelected(false) )
                    rSet.DisableItem( nWhich );
                break;
            case SID_LEAVE_GROUP: