sc drawstyles: Handle style commands and undo

Change-Id: Ibd81f7aba9ef2efca89556c31cd9b09867419d0e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149203
Tested-by: Jenkins
Reviewed-by: Maxim Monastirsky <momonasmon@gmail.com>
diff --git a/framework/source/uielement/styletoolbarcontroller.cxx b/framework/source/uielement/styletoolbarcontroller.cxx
index 31aed533..3ff1e77 100644
--- a/framework/source/uielement/styletoolbarcontroller.cxx
+++ b/framework/source/uielement/styletoolbarcontroller.cxx
@@ -34,7 +34,8 @@ OUString MapFamilyToCommand( std::u16string_view rFamily )
        return ".uno:CharStyle";
    else if ( rFamily == u"PageStyles" )
        return ".uno:PageStyle";
    else if ( rFamily == u"FrameStyles" )
    else if ( rFamily == u"FrameStyles" ||
              rFamily == u"GraphicStyles" )  // In sc
        return ".uno:FrameStyle";
    else if ( rFamily == u"NumberingStyles" )
        return ".uno:ListStyle";
diff --git a/sc/inc/globstr.hrc b/sc/inc/globstr.hrc
index 88eca11..16fce3f 100644
--- a/sc/inc/globstr.hrc
+++ b/sc/inc/globstr.hrc
@@ -84,6 +84,7 @@
#define STR_UNDO_EDITCELLSTYLE                  NC_("STR_UNDO_EDITCELLSTYLE", "Edit Cell Style")
#define STR_UNDO_APPLYPAGESTYLE                 NC_("STR_UNDO_APPLYPAGESTYLE", "Apply Page Style")
#define STR_UNDO_EDITPAGESTYLE                  NC_("STR_UNDO_EDITPAGESTYLE", "Edit Page Style")
#define STR_UNDO_EDITGRAPHICSTYLE               NC_("STR_UNDO_EDITGRAPHICSTYLE", "Edit Drawing Style")
#define STR_UNDO_DETADDPRED                     NC_("STR_UNDO_DETADDPRED", "Trace Precedents")
#define STR_UNDO_DETDELPRED                     NC_("STR_UNDO_DETDELPRED", "Remove Precedent")
#define STR_UNDO_DETADDSUCC                     NC_("STR_UNDO_DETADDSUCC", "Trace Dependents")
diff --git a/sc/sdi/drawsh.sdi b/sc/sdi/drawsh.sdi
index ccd5d69..13f1d6b 100644
--- a/sc/sdi/drawsh.sdi
+++ b/sc/sdi/drawsh.sdi
@@ -35,18 +35,6 @@ interface TableDraw
    SID_OPENDLG_EDIT_PRINTAREA  [ StateMethod = StateDisableItems; ]
    // others:
    SID_DRAW_CHART              [ StateMethod = StateDisableItems; ]
    SID_STYLE_FAMILY2           [ StateMethod = StateDisableItems; ]
    SID_STYLE_FAMILY4           [ StateMethod = StateDisableItems; ]
    SID_STYLE_APPLY             [ StateMethod = StateDisableItems; ]
    SID_STYLE_WATERCAN          [ StateMethod = StateDisableItems; ]
    SID_STYLE_NEW_BY_EXAMPLE    [ StateMethod = StateDisableItems; ]
    SID_STYLE_UPDATE_BY_EXAMPLE [ StateMethod = StateDisableItems; ]
    SID_STYLE_NEW               [ StateMethod = StateDisableItems; ]
    SID_STYLE_EDIT              [ StateMethod = StateDisableItems; ]
    SID_STYLE_DELETE            [ StateMethod = StateDisableItems; ]
    SID_STYLE_HIDE              [ StateMethod = StateDisableItems; ]
    SID_STYLE_SHOW              [ StateMethod = StateDisableItems; ]


    SID_TEXT_STANDARD       [ ExecMethod = ExecDrawAttr; StateMethod = NoState; ]
    SID_DRAWTEXT_ATTR_DLG   [ ExecMethod = ExecDrawAttr; StateMethod = NoState; ]
diff --git a/sc/sdi/drtxtob.sdi b/sc/sdi/drtxtob.sdi
index 5280430..4670d21 100644
--- a/sc/sdi/drtxtob.sdi
+++ b/sc/sdi/drtxtob.sdi
@@ -33,18 +33,6 @@ interface TableDrawText
    // others:
    SID_DRAW_CHART              [ StateMethod = StateDisableItems; ]
    SID_OPENDLG_FUNCTION        [ StateMethod = StateDisableItems; ]
    SID_STYLE_FAMILY2           [ StateMethod = StateDisableItems; ]
    SID_STYLE_FAMILY4           [ StateMethod = StateDisableItems; ]
    SID_STYLE_APPLY             [ StateMethod = StateDisableItems; ]
    SID_STYLE_WATERCAN          [ StateMethod = StateDisableItems; ]
    SID_STYLE_NEW_BY_EXAMPLE    [ StateMethod = StateDisableItems; ]
    SID_STYLE_UPDATE_BY_EXAMPLE [ StateMethod = StateDisableItems; ]
    SID_STYLE_NEW               [ StateMethod = StateDisableItems; ]
    SID_STYLE_EDIT              [ StateMethod = StateDisableItems; ]
    SID_STYLE_DELETE            [ StateMethod = StateDisableItems; ]
    SID_STYLE_HIDE              [ StateMethod = StateDisableItems; ]
    SID_STYLE_SHOW              [ StateMethod = StateDisableItems; ]


    SID_CUT             [ ExecMethod = Execute; StateMethod = GetState; ]
    SID_COPY            [ ExecMethod = Execute; StateMethod = GetState; ]
diff --git a/sc/sdi/tabvwsh.sdi b/sc/sdi/tabvwsh.sdi
index 5938317..b10d42b 100644
--- a/sc/sdi/tabvwsh.sdi
+++ b/sc/sdi/tabvwsh.sdi
@@ -206,6 +206,7 @@ interface TableEditView
    SID_HELPLINES_MOVE  [ ExecMethod = ExecDrawOpt; StateMethod = GetDrawOptState; ]

    SID_STYLE_FAMILY2           [ ExecMethod = ExecStyle; StateMethod = GetStyleState; ]
    SID_STYLE_FAMILY3           [ ExecMethod = ExecStyle; StateMethod = GetStyleState; ]
    SID_STYLE_FAMILY4           [ ExecMethod = ExecStyle; StateMethod = GetStyleState; ]
    SID_STYLE_APPLY             [ ExecMethod = ExecStyle; StateMethod = GetStyleState; ]
    SID_STYLE_WATERCAN          [ ExecMethod = ExecStyle; StateMethod = GetStyleState; ]
diff --git a/sc/source/ui/drawfunc/drawsh2.cxx b/sc/source/ui/drawfunc/drawsh2.cxx
index 1b83e930..775c00f 100644
--- a/sc/source/ui/drawfunc/drawsh2.cxx
+++ b/sc/source/ui/drawfunc/drawsh2.cxx
@@ -415,7 +415,7 @@ void ScDrawShell::GetDrawAttrState( SfxItemSet& rSet )
    }
    else
    {
        rSet.Put( pDrView->GetDefaultAttr() );
        pDrView->GetAttributes(rSet);
    }

    SdrPageView* pPV = pDrView->GetSdrPageView();
diff --git a/sc/source/ui/drawfunc/fusel.cxx b/sc/source/ui/drawfunc/fusel.cxx
index 03fb8c4..2fd8a9d 100644
--- a/sc/source/ui/drawfunc/fusel.cxx
+++ b/sc/source/ui/drawfunc/fusel.cxx
@@ -46,6 +46,7 @@
#include <charthelper.hxx>
#include <docuno.hxx>
#include <docsh.hxx>
#include <stlpool.hxx>

//  maximal permitted mouse movement to start Drag&Drop
//! fusel,fuconstr,futext - combine them!
@@ -440,6 +441,13 @@ bool FuSelection::MouseButtonUp(const MouseEvent& rMEvt)
                }
            }
        }

        if (SC_MOD()->GetIsWaterCan())
        {
            auto pStyleSheet = rViewData.GetDocument().GetStyleSheetPool()->GetActualStyleSheet();
            if (pStyleSheet && pStyleSheet->GetFamily() == SfxStyleFamily::Frame)
                pView->SetStyleSheet(static_cast<SfxStyleSheet*>(pStyleSheet), false);
        }
    }

    // maybe consider OLE object
diff --git a/sc/source/ui/undo/undostyl.cxx b/sc/source/ui/undo/undostyl.cxx
index 74fd759..0c1ab96 100644
--- a/sc/source/ui/undo/undostyl.cxx
+++ b/sc/source/ui/undo/undostyl.cxx
@@ -91,10 +91,12 @@ ScUndoModifyStyle::~ScUndoModifyStyle()

OUString ScUndoModifyStyle::GetComment() const
{
    TranslateId pId = (eFamily == SfxStyleFamily::Para) ?
                                STR_UNDO_EDITCELLSTYLE :
                                STR_UNDO_EDITPAGESTYLE;
    return ScResId(pId);
    if (eFamily == SfxStyleFamily::Frame)
        return ScResId(STR_UNDO_EDITGRAPHICSTYLE);
    if (eFamily == SfxStyleFamily::Page)
        return ScResId(STR_UNDO_EDITPAGESTYLE);

    return ScResId(STR_UNDO_EDITCELLSTYLE);
}

static void lcl_DocStyleChanged( ScDocument* pDoc, const SfxStyleSheetBase* pStyle, bool bRemoved )
@@ -150,7 +152,7 @@ void ScUndoModifyStyle::DoChange( ScDocShell* pDocSh, const OUString& rName,
        {
            if ( eStyleFamily == SfxStyleFamily::Para )
                lcl_DocStyleChanged( &rDoc, pStyle, true );      // TRUE: remove usage of style
            else
            else if ( eStyleFamily == SfxStyleFamily::Page )
                rDoc.RemovePageStyleInUse( rName );

            // delete style
@@ -174,7 +176,7 @@ void ScUndoModifyStyle::DoChange( ScDocShell* pDocSh, const OUString& rName,
            {
                lcl_DocStyleChanged( &rDoc, pStyle, false );     // cell styles: row heights
            }
            else
            else if ( eStyleFamily == SfxStyleFamily::Page )
            {
                // page styles

@@ -186,6 +188,8 @@ void ScUndoModifyStyle::DoChange( ScDocShell* pDocSh, const OUString& rName,

                pDocSh->PageStyleModified( aNewName, true );
            }
            else
                static_cast<SfxStyleSheet*>(pStyle)->Broadcast(SfxHint(SfxHintId::DataChanged));
        }
    }

diff --git a/sc/source/ui/view/tabview3.cxx b/sc/source/ui/view/tabview3.cxx
index d52968c..dfcd059 100644
--- a/sc/source/ui/view/tabview3.cxx
+++ b/sc/source/ui/view/tabview3.cxx
@@ -255,7 +255,7 @@ void ScTabView::InvalidateAttribs()

    rBindings.Invalidate( SID_STYLE_APPLY );
    rBindings.Invalidate( SID_STYLE_FAMILY2 );
    // StarCalc knows only paragraph- or cell format templates
    rBindings.Invalidate( SID_STYLE_FAMILY3 );

    rBindings.Invalidate( SID_ATTR_CHAR_FONT );
    rBindings.Invalidate( SID_ATTR_CHAR_FONTHEIGHT );
diff --git a/sc/source/ui/view/tabvwsha.cxx b/sc/source/ui/view/tabvwsha.cxx
index 4c9a6e4..62bfe88 100644
--- a/sc/source/ui/view/tabvwsha.cxx
+++ b/sc/source/ui/view/tabvwsha.cxx
@@ -68,6 +68,7 @@
#include <docpool.hxx>
#include <printfun.hxx>
#include <undostyl.hxx>
#include <futext.hxx>

#include <memory>

@@ -918,6 +919,7 @@ void ScTabViewShell::ExecStyle( SfxRequest& rReq )
    ScDocument&         rDoc        = pDocSh->GetDocument();
    ScMarkData&         rMark       = GetViewData().GetMarkData();
    ScModule*           pScMod      = SC_MOD();
    SdrObject*          pEditObject = GetDrawView()->GetTextEditObject();
    OUString            aRefName;
    bool                bUndo       = rDoc.IsUndoEnabled();

@@ -942,6 +944,8 @@ void ScTabViewShell::ExecStyle( SfxRequest& rReq )
            eFamily = SfxStyleFamily::Para;
        else if (sFamily == "PageStyles")
            eFamily = SfxStyleFamily::Page;
        else if (sFamily == "GraphicStyles")
            eFamily = SfxStyleFamily::Frame;
    }

    OUString                aStyleName;
@@ -1343,6 +1347,100 @@ void ScTabViewShell::ExecStyle( SfxRequest& rReq )
        } // case SfxStyleFamily::Page:
        break;

        case SfxStyleFamily::Frame:
        {
            switch ( nSlotId )
            {
                case SID_STYLE_DELETE:
                {
                    if ( pStyleSheet )
                    {
                        pStylePool->Remove( pStyleSheet );
                        InvalidateAttribs();
                        pDocSh->SetDocumentModified();
                        nRetMask = sal_uInt16(true);
                        bAddUndo = true;
                        rReq.Done();
                    }
                    else
                        nRetMask = sal_uInt16(false);
                }
                break;

                case SID_STYLE_HIDE:
                case SID_STYLE_SHOW:
                {
                    if ( pStyleSheet )
                    {
                        pStyleSheet->SetHidden( nSlotId == SID_STYLE_HIDE );
                        InvalidateAttribs();
                        rReq.Done();
                    }
                    else
                        nRetMask = sal_uInt16(false);
                }
                break;

                case SID_STYLE_APPLY:
                {
                    if ( pStyleSheet && !pScMod->GetIsWaterCan() )
                    {
                        GetScDrawView()->ScEndTextEdit();
                        GetScDrawView()->SetStyleSheet(static_cast<SfxStyleSheet*>(pStyleSheet), false);

                        GetScDrawView()->InvalidateAttribs();
                        InvalidateAttribs();
                        rReq.Done();
                    }
                }
                break;

                case SID_STYLE_NEW_BY_EXAMPLE:
                case SID_STYLE_UPDATE_BY_EXAMPLE:
                {
                    if (nSlotId == SID_STYLE_NEW_BY_EXAMPLE)
                    {
                        pStyleSheet = &pStylePool->Make( aStyleName, eFamily, SfxStyleSearchBits::UserDefined );

                        // when a style is present, then this will become
                        // the parent of the new style:
                        if (SfxStyleSheet* pOldStyle = GetDrawView()->GetStyleSheet())
                            pStyleSheet->SetParent(pOldStyle->GetName());
                    }
                    else
                    {
                        pStyleSheet = GetDrawView()->GetStyleSheet();
                        aOldData.InitFromStyle( pStyleSheet );
                    }

                    if ( bUndo )
                    {
                        OUString aUndo = ScResId( STR_UNDO_EDITGRAPHICSTYLE );
                        pDocSh->GetUndoManager()->EnterListAction( aUndo, aUndo, 0, GetViewShellId() );
                        bListAction = true;
                    }

                    SfxItemSet aCoreSet(GetDrawView()->GetModel().GetItemPool());
                    GetDrawView()->GetAttributes(aCoreSet, true);

                    SfxItemSet* pStyleSet = &pStyleSheet->GetItemSet();
                    pStyleSet->Put(aCoreSet);
                    static_cast<SfxStyleSheet*>(pStyleSheet)->Broadcast(SfxHint(SfxHintId::DataChanged));

                    aNewData.InitFromStyle( pStyleSheet );
                    bAddUndo = true;

                    //  call SetStyleSheet after adding the ScUndoModifyStyle
                    //  (pStyleSheet pointer is used!)
                    bStyleToMarked = true;
                    rReq.Done();
                }
                break;
                default:
                    break;
            }
        }
        break;
        default:
            break;
    } // switch ( eFamily )
@@ -1367,7 +1465,6 @@ void ScTabViewShell::ExecStyle( SfxRequest& rReq )
                    break;

                case SfxStyleFamily::Para:
                default:
                    {
                        SfxItemSet& rSet = pStyleSheet->GetItemSet();

@@ -1409,6 +1506,10 @@ void ScTabViewShell::ExecStyle( SfxRequest& rReq )
                        }
                    }
                    break;

                case SfxStyleFamily::Frame:
                default:
                    break;
            }

            SetInFormatDialog(true);
@@ -1461,7 +1562,7 @@ void ScTabViewShell::ExecStyle( SfxRequest& rReq )

                        rDoc.GetPool()->CellStyleCreated( pStyleSheet->GetName(), rDoc );
                    }
                    else
                    else if ( SfxStyleFamily::Page == eFam )
                    {
                        //! Here also queries for Page Styles

@@ -1476,6 +1577,14 @@ void ScTabViewShell::ExecStyle( SfxRequest& rReq )
                        rDoc.ModifyStyleSheet( *pStyleSheet, *pOutSet );
                        rBindings.Invalidate( FID_RESET_PRINTZOOM );
                    }
                    else
                    {
                        SfxItemSet& rAttr = pStyleSheet->GetItemSet();
                        sdr::properties::CleanupFillProperties(rAttr);

                        static_cast<SfxStyleSheet*>(pStyleSheet)->Broadcast(SfxHint(SfxHintId::DataChanged));
                        GetScDrawView()->InvalidateAttribs();
                    }

                    pDocSh->SetDocumentModified();

@@ -1516,12 +1625,29 @@ void ScTabViewShell::ExecStyle( SfxRequest& rReq )
    {
        //  call SetStyleSheetToMarked after adding the ScUndoModifyStyle,
        //  so redo will find the modified style
        SetStyleSheetToMarked( static_cast<SfxStyleSheet*>(pStyleSheet) );
        if (eFamily == SfxStyleFamily::Para)
        {
            SetStyleSheetToMarked( static_cast<SfxStyleSheet*>(pStyleSheet) );
        }
        else if (eFamily == SfxStyleFamily::Frame)
        {
            GetScDrawView()->ScEndTextEdit();
            GetScDrawView()->SetStyleSheet( static_cast<SfxStyleSheet*>(pStyleSheet), false );
        }
        InvalidateAttribs();
    }

    if ( bListAction )
        pDocSh->GetUndoManager()->LeaveListAction();

    // The above call to ScEndTextEdit left us in an inconsistent state:
    // Text editing isn't active, but the text edit shell still is. And we
    // couldn't just deactivate it fully, because in case of editing a
    // comment, that will make the comment disappear. So let's try to
    // reactivate text editing instead:
    auto pFuText = dynamic_cast<FuText*>(GetDrawFuncPtr());
    if (pFuText && pEditObject != GetDrawView()->GetTextEditObject())
        pFuText->SetInEditMode(pEditObject);
}

void ScTabViewShell::GetStyleState( SfxItemSet& rSet )
@@ -1563,6 +1689,17 @@ void ScTabViewShell::GetStyleState( SfxItemSet& rSet )
            }
            break;

            case SID_STYLE_FAMILY3:     // drawing style sheets
            {
                SfxStyleSheet* pStyleSheet = GetDrawView()->GetStyleSheet();

                if ( pStyleSheet )
                    rSet.Put( SfxTemplateItem( nSlotId, pStyleSheet->GetName() ) );
                else
                    rSet.Put( SfxTemplateItem( nSlotId, OUString() ) );
            }
            break;

            case SID_STYLE_FAMILY4:     // page style sheets
            {
                SCTAB           nCurTab     = GetViewData().GetTabNo();