tdf#153510: STYLE: try harder to detect when there's nothing to do

1. Find the real style names early, to avoid re-triggering style
application when STYLE arguments use wrong case;
2. Also check a (rare) case when both immediate and delayed styles
are the same as currently applied.

Change-Id: Id8ab2e321ede6d0f8f05ac5d1e63ade0212e5865
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146775
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
(cherry picked from commit 208a4ecafafa97ea7fcc5a135fa8160e91ea0a74)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146768
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/sc/inc/stlpool.hxx b/sc/inc/stlpool.hxx
index f4e3ac7..51694a4 100644
--- a/sc/inc/stlpool.hxx
+++ b/sc/inc/stlpool.hxx
@@ -51,6 +51,8 @@ public:
    bool                HasStandardStyles() const { return bHasStandardStyles; }

    ScStyleSheet*       FindCaseIns( const OUString& rName, SfxStyleFamily eFam );
    // Finds Para style with given name case-insensitively, or STR_STYLENAME_STANDARD
    ScStyleSheet*       FindAutoStyle(const OUString& rName);

    virtual SfxStyleSheetBase& Make( const OUString&, SfxStyleFamily eFam,
                                     SfxStyleSearchBits nMask = SfxStyleSearchBits::All) override;
diff --git a/sc/source/core/data/stlpool.cxx b/sc/source/core/data/stlpool.cxx
index b08b6c2..8f55489 100644
--- a/sc/source/core/data/stlpool.cxx
+++ b/sc/source/core/data/stlpool.cxx
@@ -424,6 +424,16 @@ ScStyleSheet* ScStyleSheetPool::FindCaseIns( const OUString& rName, SfxStyleFami
    return first;
}

ScStyleSheet* ScStyleSheetPool::FindAutoStyle(const OUString& rName)
{
    ScStyleSheet* pStyleSheet = FindCaseIns(rName, SfxStyleFamily::Para);
    if (!pStyleSheet)
        if (auto pFound = Find(ScResId(STR_STYLENAME_STANDARD), SfxStyleFamily::Para))
            if (pFound->isScStyleSheet()) // we do not know what kind of sheets we have
                pStyleSheet = static_cast<ScStyleSheet*>(pFound);
    return pStyleSheet;
}

void ScStyleSheetPool::setAllParaStandard()
{
    SfxStyleSheetBase* pSheet = First(SfxStyleFamily::Para);
diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx
index b1492bb..6ee1de4 100644
--- a/sc/source/core/tool/interpr2.cxx
+++ b/sc/source/core/tool/interpr2.cxx
@@ -41,6 +41,7 @@
#include <dpobject.hxx>
#include <tokenarray.hxx>
#include <globalnames.hxx>
#include <stlpool.hxx>
#include <stlsheet.hxx>
#include <dpcache.hxx>

@@ -2599,38 +2600,54 @@ void ScInterpreter::ScStyle()
    if (!MustHaveParamCount(nParamCount, 1, 3))
        return;

    OUString aStyle2;                           // Template after timer
    OUString aStyle2;                           // Style after timer
    if (nParamCount >= 3)
        aStyle2 = GetString().getString();
    tools::Long nTimeOut = 0;                          // timeout
    if (nParamCount >= 2)
        nTimeOut = static_cast<tools::Long>(GetDouble()*1000.0);
    OUString aStyle1 = GetString().getString(); // Template for immediate
    OUString aStyle1 = GetString().getString(); // Style for immediate

    if (nTimeOut < 0)
        nTimeOut = 0;

    // Execute request to apply template
    // Execute request to apply style
    if ( !mrDoc.IsClipOrUndo() )
    {
        SfxObjectShell* pShell = mrDoc.GetDocumentShell();
        if (pShell)
        {
            // Normalize style names right here, making sure that character case is correct,
            // and that we only apply anything when there's something to apply
            auto pPool = mrDoc.GetStyleSheetPool();
            if (!aStyle1.isEmpty())
            {
                if (auto pNewStyle = pPool->FindAutoStyle(aStyle1))
                    aStyle1 = pNewStyle->GetName();
                else
                    aStyle1.clear();
            }
            if (!aStyle2.isEmpty())
            {
                if (auto pNewStyle = pPool->FindAutoStyle(aStyle2))
                    aStyle2 = pNewStyle->GetName();
                else
                    aStyle2.clear();
            }
            // notify object shell directly!
            bool bNotify = true;
            if (aStyle2.isEmpty())
            if (!aStyle1.isEmpty() || !aStyle2.isEmpty())
            {
                const ScStyleSheet* pStyle = mrDoc.GetStyle(aPos.Col(), aPos.Row(), aPos.Tab());

                if (pStyle && pStyle->GetName() == aStyle1)
                    bNotify = false;
            }

            if (bNotify)
            {
                ScRange aRange(aPos);
                ScAutoStyleHint aHint( aRange, aStyle1, nTimeOut, aStyle2 );
                pShell->Broadcast( aHint );
                const bool bNotify = !pStyle
                                     || (!aStyle1.isEmpty() && pStyle->GetName() != aStyle1)
                                     || (!aStyle2.isEmpty() && pStyle->GetName() != aStyle2);
                if (bNotify)
                {
                    ScRange aRange(aPos);
                    ScAutoStyleHint aHint(aRange, aStyle1, nTimeOut, aStyle2);
                    pShell->Broadcast(aHint);
                }
            }
        }
    }
diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx
index 8b82201..f64ecae 100644
--- a/sc/source/ui/docshell/docsh4.cxx
+++ b/sc/source/ui/docshell/docsh4.cxx
@@ -1558,11 +1558,7 @@ void ScDocShell::DoHardRecalc()
void ScDocShell::DoAutoStyle( const ScRange& rRange, const OUString& rStyle )
{
    ScStyleSheetPool* pStylePool = m_pDocument->GetStyleSheetPool();
    ScStyleSheet* pStyleSheet =
        pStylePool->FindCaseIns( rStyle, SfxStyleFamily::Para );
    if (!pStyleSheet)
        pStyleSheet = static_cast<ScStyleSheet*>(
            pStylePool->Find( ScResId(STR_STYLENAME_STANDARD), SfxStyleFamily::Para ));
    ScStyleSheet* pStyleSheet = pStylePool->FindAutoStyle(rStyle);
    if (!pStyleSheet)
        return;