tdf#38225: update API name when renaming using a base class ref

... but don't update it in case it's a predefined API name

Change-Id: I20075a4e085bdeab8374860c16e7eb2a72772c33
Reviewed-on: https://gerrit.libreoffice.org/54879
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
(cherry picked from commit 8a648b82f85d4b0eed67067ed2ddc211ad64ce72)
Reviewed-on: https://gerrit.libreoffice.org/54887
diff --git a/sd/inc/stlsheet.hxx b/sd/inc/stlsheet.hxx
index b863143..ae21105 100644
--- a/sd/inc/stlsheet.hxx
+++ b/sd/inc/stlsheet.hxx
@@ -80,6 +80,9 @@ public:
    static void BroadcastSdStyleSheetChange(SfxStyleSheetBase const * pStyleSheet, PresentationObjects ePO,
        SfxStyleSheetBasePool* pSSPool);

    // SfxStyleSheetBase
    virtual bool SetName(const OUString& rNewName, bool bReindexNow = true) override;

    // XInterface
    virtual void SAL_CALL release(  ) throw () override;

diff --git a/sd/qa/unit/misc-tests.cxx b/sd/qa/unit/misc-tests.cxx
index 9125f23..ace77cd 100644
--- a/sd/qa/unit/misc-tests.cxx
+++ b/sd/qa/unit/misc-tests.cxx
@@ -61,6 +61,7 @@ public:
    void testTdf99396TextEdit();
    void testFillGradient();
    void testTdf44774();
    void testTdf38225();

    CPPUNIT_TEST_SUITE(SdMiscTest);
    CPPUNIT_TEST(testTdf96206);
@@ -69,6 +70,7 @@ public:
    CPPUNIT_TEST(testTdf99396TextEdit);
    CPPUNIT_TEST(testFillGradient);
    CPPUNIT_TEST(testTdf44774);
    CPPUNIT_TEST(testTdf38225);
    CPPUNIT_TEST_SUITE_END();

private:
@@ -327,6 +329,38 @@ void SdMiscTest::testTdf44774()
    CPPUNIT_ASSERT_EQUAL(OUString("StyleA"), pStyle->GetParent());
}

void SdMiscTest::testTdf38225()
{
    sd::DrawDocShellRef xDocShRef = new sd::DrawDocShell(SfxObjectCreateMode::EMBEDDED, false,
        DocumentType::Draw);
    const uno::Reference<frame::XLoadable> xLoadable(xDocShRef->GetModel(), uno::UNO_QUERY_THROW);
    xLoadable->initNew();
    SfxStyleSheetBasePool* pSSPool = xDocShRef->GetStyleSheetPool();

    // Create a new style with a name
    pSSPool->Make("StyleWithName1", SfxStyleFamily::Para, SfxStyleSearchBits::UserDefined);

    // Now save the file and reload
    xDocShRef = saveAndReload(xDocShRef.get(), ODG);
    pSSPool = xDocShRef->GetStyleSheetPool();

    SfxStyleSheetBase* pStyle = pSSPool->Find("StyleWithName1", SfxStyleFamily::Para);
    CPPUNIT_ASSERT(pStyle);

    // Rename the style
    CPPUNIT_ASSERT(pStyle->SetName("StyleWithName2"));

    // Save the file and reload again
    xDocShRef = saveAndReload(xDocShRef.get(), ODG);
    pSSPool = xDocShRef->GetStyleSheetPool();

    // The problem was that the style kept the old name upon reloading
    pStyle = pSSPool->Find("StyleWithName1", SfxStyleFamily::Para);
    CPPUNIT_ASSERT(!pStyle);
    pStyle = pSSPool->Find("StyleWithName2", SfxStyleFamily::Para);
    CPPUNIT_ASSERT(pStyle);
}

CPPUNIT_TEST_SUITE_REGISTRATION(SdMiscTest);

CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sd/source/core/stlsheet.cxx b/sd/source/core/stlsheet.cxx
index 3327304..fed2214 100644
--- a/sd/source/core/stlsheet.cxx
+++ b/sd/source/core/stlsheet.cxx
@@ -580,56 +580,77 @@ bool SdStyleSheet::HasClearParentSupport() const
    return true;
}

namespace
{
struct ApiNameMap
{
    OUStringLiteral mpApiName;
    sal_uInt32 mnHelpId;
} const pApiNameMap[]
    = { { OUStringLiteral("title"), HID_PSEUDOSHEET_TITLE },
        { OUStringLiteral("subtitle"), HID_PSEUDOSHEET_SUBTITLE },
        { OUStringLiteral("background"), HID_PSEUDOSHEET_BACKGROUND },
        { OUStringLiteral("backgroundobjects"), HID_PSEUDOSHEET_BACKGROUNDOBJECTS },
        { OUStringLiteral("notes"), HID_PSEUDOSHEET_NOTES },
        { OUStringLiteral("standard"), HID_STANDARD_STYLESHEET_NAME },
        { OUStringLiteral("objectwithoutfill"), HID_POOLSHEET_OBJWITHOUTFILL },
        { OUStringLiteral("text"), HID_POOLSHEET_TEXT },
        { OUStringLiteral("title"), HID_POOLSHEET_TITLE },
        { OUStringLiteral("headline"), HID_POOLSHEET_HEADLINE },
        { OUStringLiteral("measure"), HID_POOLSHEET_MEASURE },
        { OUStringLiteral("Filled"), HID_POOLSHEET_FILLED },
        { OUStringLiteral("Filled Blue"), HID_POOLSHEET_FILLED_BLUE },
        { OUStringLiteral("Filled Green"), HID_POOLSHEET_FILLED_GREEN },
        { OUStringLiteral("Filled Red"), HID_POOLSHEET_FILLED_RED },
        { OUStringLiteral("Filled Yellow"), HID_POOLSHEET_FILLED_YELLOW },
        { OUStringLiteral("Outlined"), HID_POOLSHEET_OUTLINE },
        { OUStringLiteral("Outlined Blue"), HID_POOLSHEET_OUTLINE_BLUE },
        { OUStringLiteral("Outlined Green"), HID_POOLSHEET_OUTLINE_GREEN },
        { OUStringLiteral("Outlined Red"), HID_POOLSHEET_OUTLINE_RED },
        { OUStringLiteral("Outlined Yellow"), HID_POOLSHEET_OUTLINE_YELLOW } };

OUString GetApiNameForHelpId(sal_uLong nId)
{
    if ((nId >= HID_PSEUDOSHEET_OUTLINE1) && (nId <= HID_PSEUDOSHEET_OUTLINE9))
        return "outline" + OUStringLiteral1('1' + (nId - HID_PSEUDOSHEET_OUTLINE1));

    for (const auto& i : pApiNameMap)
        if (nId == i.mnHelpId)
            return i.mpApiName;

    return OUString();
}

sal_uInt32 GetHelpIdForApiName(const OUString& sName)
{
    OUString sRest;
    if (sName.startsWith("outline", &sRest))
    {
        if (sRest.getLength() == 1)
        {
            sal_Unicode ch = sRest.toChar();
            if ('1' <= ch && ch <= '9')
                return HID_PSEUDOSHEET_OUTLINE1 + ch - '1';
        }
        // No other pre-defined names start with "outline"
        return 0;
    }

    for (const auto& i : pApiNameMap)
        if (sName == i.mpApiName)
            return i.mnHelpId;

    return 0;
}
}

void SdStyleSheet::SetHelpId( const OUString& r, sal_uLong nId )
{
    SfxStyleSheet::SetHelpId( r, nId );

    if( (nId >= HID_PSEUDOSHEET_OUTLINE1) && ( nId <= HID_PSEUDOSHEET_OUTLINE9 ) )
    {
        msApiName = "outline";
        msApiName += OUStringLiteral1( '1' + (nId - HID_PSEUDOSHEET_OUTLINE1) );
    }
    else
    {
        static struct ApiNameMap
        {
            OUStringLiteral mpApiName;
            sal_uInt32      mnHelpId;
        }
        const pApiNameMap[] =
        {
            { OUStringLiteral("title"),            HID_PSEUDOSHEET_TITLE },
            { OUStringLiteral("subtitle"),         HID_PSEUDOSHEET_SUBTITLE },
            { OUStringLiteral("background"),       HID_PSEUDOSHEET_BACKGROUND },
            { OUStringLiteral("backgroundobjects"),HID_PSEUDOSHEET_BACKGROUNDOBJECTS },
            { OUStringLiteral("notes"),            HID_PSEUDOSHEET_NOTES },
            { OUStringLiteral("standard"),         HID_STANDARD_STYLESHEET_NAME },
            { OUStringLiteral("objectwithoutfill"),HID_POOLSHEET_OBJWITHOUTFILL },
            { OUStringLiteral("text"),             HID_POOLSHEET_TEXT },
            { OUStringLiteral("title"),            HID_POOLSHEET_TITLE },
            { OUStringLiteral("headline"),         HID_POOLSHEET_HEADLINE },
            { OUStringLiteral("measure"),          HID_POOLSHEET_MEASURE },
            { OUStringLiteral("Filled"),           HID_POOLSHEET_FILLED },
            { OUStringLiteral("Filled Blue"),      HID_POOLSHEET_FILLED_BLUE },
            { OUStringLiteral("Filled Green"),     HID_POOLSHEET_FILLED_GREEN },
            { OUStringLiteral("Filled Red"),       HID_POOLSHEET_FILLED_RED },
            { OUStringLiteral("Filled Yellow"),    HID_POOLSHEET_FILLED_YELLOW },
            { OUStringLiteral("Outlined"),          HID_POOLSHEET_OUTLINE },
            { OUStringLiteral("Outlined Blue"),     HID_POOLSHEET_OUTLINE_BLUE },
            { OUStringLiteral("Outlined Green"),    HID_POOLSHEET_OUTLINE_GREEN },
            { OUStringLiteral("Outlined Red"),      HID_POOLSHEET_OUTLINE_RED },
            { OUStringLiteral("Outlined Yellow"),   HID_POOLSHEET_OUTLINE_YELLOW }
        };

        for (std::size_t i = 0; i != SAL_N_ELEMENTS(pApiNameMap); ++i)
        {
            if( nId == pApiNameMap[i].mnHelpId )
            {
                msApiName = pApiNameMap[i].mpApiName;
                break;
            }
        }
    }
    const OUString sNewApiName = GetApiNameForHelpId(nId);
    if (!sNewApiName.isEmpty())
        msApiName = sNewApiName;
}

OUString SdStyleSheet::GetFamilyString( SfxStyleFamily eFamily )
@@ -829,6 +850,18 @@ Sequence< OUString > SAL_CALL SdStyleSheet::getSupportedServiceNames()
    return aNameSequence;
}

bool SdStyleSheet::SetName(const OUString& rNewName, bool bReindexNow)
{
    const bool bResult = SfxUnoStyleSheet::SetName(rNewName, bReindexNow);
    // Don't overwrite predefined API names
    if (bResult && GetHelpIdForApiName(msApiName) == 0)
    {
        msApiName = rNewName;
        Broadcast(SfxHint(SfxHintId::DataChanged));
    }
    return bResult;
}

// XNamed
OUString SAL_CALL SdStyleSheet::getName()
{
@@ -841,12 +874,7 @@ void SAL_CALL SdStyleSheet::setName( const OUString& rName  )
{
    SolarMutexGuard aGuard;
    throwIfDisposed();

    if( SetName( rName ) )
    {
        msApiName = rName;
        Broadcast(SfxHint(SfxHintId::DataChanged));
    }
    SetName(rName);
}

// XStyle