[Libreoffice-commits] core.git: sw/inc sw/qa sw/source

Jakub Trzebiatowski ubap.dev at gmail.com
Fri Jun 24 08:52:08 UTC 2016


 sw/inc/tblafmt.hxx                  |    1 
 sw/inc/unostyle.hxx                 |   37 +++-
 sw/qa/python/check_styles.py        |   30 +++
 sw/source/core/doc/tblafmt.cxx      |   30 ++-
 sw/source/core/unocore/unostyle.cxx |  294 +++++++++++++++++++++++++-----------
 5 files changed, 286 insertions(+), 106 deletions(-)

New commits:
commit d945e97d8f85465f04f59fd197ded2edb56caac3
Author: Jakub Trzebiatowski <ubap.dev at gmail.com>
Date:   Wed Jun 22 22:40:20 2016 +0200

    GSoC Table Style Family: insertByName, replaceByName, removeByName
    
    - also implements SwXTextTableStyle::replaceByName
    
    - some refactorization
      + use std::unique_ptr
    
    - fixes some bugs:
     + posible nullptr dereference in tblafmt.cxx
     + SwXTextTableStyle::getName() returned translated name
     + remvoed unnecesary SetXObject in Cell Style Family replacebyName
    
    - tests
    
    Change-Id: Idd25d54695ab5a4bdd4daf7ebf37b05fbc2366e7
    Reviewed-on: https://gerrit.libreoffice.org/26578
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>

diff --git a/sw/inc/tblafmt.hxx b/sw/inc/tblafmt.hxx
index fc698ef..0eb799a 100644
--- a/sw/inc/tblafmt.hxx
+++ b/sw/inc/tblafmt.hxx
@@ -343,6 +343,7 @@ public:
 
     void InsertAutoFormat(size_t i, std::unique_ptr<SwTableAutoFormat> pFormat);
     void EraseAutoFormat(size_t i);
+    void EraseAutoFormat(const OUString& rName);
     std::unique_ptr<SwTableAutoFormat> ReleaseAutoFormat(size_t i);
 
     /// Find table style with the provided name, return nullptr when not found.
diff --git a/sw/inc/unostyle.hxx b/sw/inc/unostyle.hxx
index 07311e8..cc24073 100644
--- a/sw/inc/unostyle.hxx
+++ b/sw/inc/unostyle.hxx
@@ -254,12 +254,16 @@ class SwXTextTableStyle : public cppu::WeakImplHelper
 <
     css::style::XStyle,
     css::beans::XPropertySet,
-    css::container::XNameAccess,
+    css::container::XNameContainer,
     css::lang::XServiceInfo
 >
 {
     SwDocShell* m_pDocShell;
-    OUString m_sTableAutoFormatName;
+    SwTableAutoFormat* m_pTableAutoFormat;
+    /// Stores SwTableAutoFormat when this is not a physical style.
+    std::unique_ptr<SwTableAutoFormat> m_pTableAutoFormat_Impl;
+    /// If true, then it points to a core object, if false, then this is a created, but not-yet-inserted format.
+    bool m_bPhysical;
 
     enum {
         FIRST_ROW_STYLE = 0,
@@ -282,12 +286,21 @@ class SwXTextTableStyle : public cppu::WeakImplHelper
         STYLE_COUNT
     };
 
-    SwTableAutoFormat* GetTableAutoFormat();
+    /// Fills m_aCellStyles with SwXTextCellStyles pointing to children of this style.
+    void UpdateCellStylesMapping();
     static const CellStyleNameMap& GetCellStyleNameMap();
     css::uno::Reference<css::style::XStyle> m_aCellStyles[STYLE_COUNT];
 public:
+    SwXTextTableStyle(SwDocShell* pDocShell, SwTableAutoFormat* pTableAutoFormat);
+    /// Create non physical style
     SwXTextTableStyle(SwDocShell* pDocShell, const OUString& rTableAutoFormatName);
 
+    /// This function looks for a SwTableAutoFormat with given name. Returns nullptr if could not be found.
+    static SwTableAutoFormat* GetTableAutoFormat(SwDocShell* pDocShell, const OUString& sName);
+    /// Returns box format assigned to this style
+    SwTableAutoFormat* GetTableFormat();
+    void SetPhysical();
+
     //XStyle
     virtual sal_Bool SAL_CALL isUserDefined() throw (css::uno::RuntimeException, std::exception) override;
     virtual sal_Bool SAL_CALL isInUse() throw (css::uno::RuntimeException, std::exception) override;
@@ -312,6 +325,11 @@ public:
     virtual css::uno::Sequence<OUString> SAL_CALL getElementNames() throw(css::uno::RuntimeException, std::exception) override;
     virtual sal_Bool SAL_CALL hasByName(const OUString& rName) throw(css::uno::RuntimeException, std::exception) override;
 
+    //XNameContainer
+    virtual void SAL_CALL insertByName(const OUString& rName, const css::uno::Any& aElement) throw(css::lang::IllegalArgumentException, css::container::ElementExistException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) override;
+    virtual void SAL_CALL replaceByName(const OUString& rName, const css::uno::Any& aElement) throw(css::lang::IllegalArgumentException, css::container::NoSuchElementException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) override;
+    virtual void SAL_CALL removeByName(const OUString& rName) throw(css::container::NoSuchElementException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) override;
+
     //XElementAccess
     virtual css::uno::Type SAL_CALL getElementType() throw(css::uno::RuntimeException, std::exception) override;
     virtual sal_Bool SAL_CALL hasElements() throw(css::uno::RuntimeException, std::exception) override;
@@ -335,15 +353,17 @@ class SwXTextCellStyle : public cppu::WeakImplHelper
 {
     SwDocShell* m_pDocShell;
     SwBoxAutoFormat* m_pBoxAutoFormat;
-    OUString m_sParentStyle; // used when style is physical
-    OUString m_sName;   // used when style is not physical
-    bool m_bPhysical; // delete a m_pBoxAutoFormat when changing from false to true!
+    /// Stores SwBoxAutoFormat when this is not a physical style.
+    std::shared_ptr<SwBoxAutoFormat> m_pBoxAutoFormat_Impl;
+    OUString m_sParentStyle;
+    OUString m_sName;
+    /// If true, then it points to a core object, if false, then this is a created, but not-yet-inserted format.
+    bool m_bPhysical;
 
  public:
     SwXTextCellStyle(SwDocShell* pDocShell, SwBoxAutoFormat* pBoxAutoFormat, const OUString& sParentStyle);
     /// Create non physical style
     SwXTextCellStyle(SwDocShell* pDocShell, const OUString& sName);
-    virtual ~SwXTextCellStyle();
 
     /**
     * This function looks for a SwBoxAutoFormat with given name. Parses the name and returns parent name.
@@ -355,7 +375,10 @@ class SwXTextCellStyle : public cppu::WeakImplHelper
     static SwBoxAutoFormat* GetBoxAutoFormat(SwDocShell* pDocShell, const OUString& sName, OUString* pParentName = nullptr);
     /// returns box format assigned to this style
     SwBoxAutoFormat* GetBoxFormat();
+    /// Sets the addres of SwBoxAutoFormat this style is bound to. Usable only when style is physical.
+    void SetBoxFormat(SwBoxAutoFormat* pBoxFormat);
     void SetPhysical();
+    bool IsPhysical();
 
     //XStyle
     virtual sal_Bool SAL_CALL isUserDefined() throw (css::uno::RuntimeException, std::exception) override;
diff --git a/sw/qa/python/check_styles.py b/sw/qa/python/check_styles.py
index 144082a..372455e 100644
--- a/sw/qa/python/check_styles.py
+++ b/sw/qa/python/check_styles.py
@@ -171,6 +171,7 @@ class CheckStyle(unittest.TestCase):
         vEmptyDocStyles = ['Default Style']
         self.__test_StyleFamily(xTableStyles, vEmptyDocStyles, "SwXTextTableStyle")
         self.__test_StyleFamilyIndex(xTableStyles, vEmptyDocStyles, "SwXTextTableStyle")
+        self.__test_StyleFamilyInsert(xDoc, xTableStyles, vEmptyDocStyles, "com.sun.star.style.TableStyle", "com.sun.star.style.CharacterStyle")
         for sStyleName in vEmptyDocStyles:
             self.assertIsNotNone(xTableStyles.getByName(sStyleName))
         #check SwXTextCellStyles
@@ -184,7 +185,6 @@ class CheckStyle(unittest.TestCase):
         xDoc.dispose()
 
     def test_tableStyleIsInUse(self):
-        # extend when TableStyle insertByName comes
         xDoc = CheckStyle._uno.openEmptyWriterDoc()
         xBodyText = xDoc.getText()
         xCursor = xBodyText.createTextCursor()
@@ -201,6 +201,14 @@ class CheckStyle(unittest.TestCase):
         xTable.setPropertyValue("TableTemplateName", "")
         self.assertFalse(xDefaultTableStyle.isInUse())
         self.assertFalse(xDefaultCellStyle.isInUse())
+        xTableStyle = xDoc.createInstance("com.sun.star.style.TableStyle")
+        self.assertFalse(xTableStyle.isInUse())
+        xDoc.StyleFamilies.getByName("TableStyles").insertByName("Test Table Style", xTableStyle)
+        self.assertFalse(xTableStyle.isInUse())
+        xTable.setPropertyValue("TableTemplateName", "Test Table Style")
+        self.assertTrue(xTableStyle.isInUse())
+        xTable.setPropertyValue("TableTemplateName", "")
+        self.assertFalse(xTableStyle.isInUse())
         xDoc.dispose()
 
     def test_CellFamily(self):
@@ -210,7 +218,25 @@ class CheckStyle(unittest.TestCase):
         self.__test_StyleFamily(xCellStyles, vEmptyDocStyles, "SwXTextCellStyle")
         self.__test_StyleFamilyIndex(xCellStyles, vEmptyDocStyles, "SwXTextCellStyle")
         self.__test_StyleFamilyInsert(xDoc, xCellStyles, vEmptyDocStyles, "com.sun.star.style.CellStyle", "com.sun.star.style.CharacterStyle")
-        #add more tests when TableStyles will support insertByName
+        xTableStyle = xDoc.createInstance("com.sun.star.style.TableStyle")
+        xCellStyle = xTableStyle.getByName("first-row")
+        xDoc.StyleFamilies.getByName("TableStyles").insertByName("Test Table Style", xTableStyle)
+        self.assertEqual(xTableStyle.getByName("first-row"), xCellStyle)
+        self.assertEqual(xTableStyle.getByName("first-row"), xDoc.StyleFamilies.getByName("TableStyles").getByName("Test Table Style").getByName("first-row"))
+        #replaceByName
+        with self.assertRaises(NoSuchElementException):
+            xTableStyle.replaceByName("foobarbaz", xCellStyle)
+        xCellStyle = xDoc.createInstance("com.sun.star.style.CellStyle")
+        with self.assertRaises(IllegalArgumentException):       #replace with not inserted cell style
+            xTableStyle.replaceByName("first-row", xCellStyle)
+        xTableStyle2 = xDoc.createInstance("com.sun.star.style.TableStyle")
+        with self.assertRaises(IllegalArgumentException):       #replace with other family style
+            xTableStyle.replaceByName("first-row", xTableStyle2)
+        with self.assertRaises(IllegalArgumentException):       #replace with already assigned cell style
+            xTableStyle.replaceByName("first-row", xTableStyle2.getByName("first-row"))
+        xDoc.StyleFamilies.getByName("CellStyles").insertByName("Test Cell Style", xCellStyle)
+        xTableStyle.replaceByName("first-row", xCellStyle)
+        self.assertEqual(xTableStyle.getByName("first-row"), xCellStyle)
         xDoc.dispose()
 
 if __name__ == '__main__':
diff --git a/sw/source/core/doc/tblafmt.cxx b/sw/source/core/doc/tblafmt.cxx
index 481f65f..66202a1 100644
--- a/sw/source/core/doc/tblafmt.cxx
+++ b/sw/source/core/doc/tblafmt.cxx
@@ -930,20 +930,19 @@ void SwTableAutoFormat::StoreTableProperties(const SwTable &table)
 
 bool SwTableAutoFormat::FirstRowEndColumnIsRow()
 {
-    return *aBoxAutoFormat[3] == *aBoxAutoFormat[2];
+    return GetBoxFormat(3) == GetBoxFormat(2);
 }
-
 bool SwTableAutoFormat::FirstRowStartColumnIsRow()
 {
-    return *aBoxAutoFormat[0] == *aBoxAutoFormat[1];
+    return GetBoxFormat(0) == GetBoxFormat(1);
 }
 bool SwTableAutoFormat::LastRowEndColumnIsRow()
 {
-    return *aBoxAutoFormat[15] == *aBoxAutoFormat[14];
+    return GetBoxFormat(14) == GetBoxFormat(15);
 }
 bool SwTableAutoFormat::LastRowStartColumnIsRow()
 {
-    return *aBoxAutoFormat[12] == *aBoxAutoFormat[13];
+    return GetBoxFormat(12) == GetBoxFormat(13);
 }
 
 bool SwTableAutoFormat::Load( SvStream& rStream, const SwAfVersions& rVersions )
@@ -1156,6 +1155,20 @@ void SwTableAutoFormatTable::EraseAutoFormat(size_t const i)
     m_pImpl->m_AutoFormats.erase(m_pImpl->m_AutoFormats.begin() + i);
 }
 
+void SwTableAutoFormatTable::EraseAutoFormat(const OUString& rName)
+{
+    for (auto iter = m_pImpl->m_AutoFormats.begin();
+         iter != m_pImpl->m_AutoFormats.end(); ++iter)
+    {
+        if ((*iter)->GetName() == rName)
+        {
+            m_pImpl->m_AutoFormats.erase(iter);
+            return;
+        }
+    }
+    SAL_INFO("sw.core", "SwTableAutoFormatTable::EraseAutoFormat, SwTableAutoFormat with given name not found");
+}
+
 std::unique_ptr<SwTableAutoFormat> SwTableAutoFormatTable::ReleaseAutoFormat(size_t const i)
 {
     auto const iter(m_pImpl->m_AutoFormats.begin() + i);
@@ -1406,11 +1419,12 @@ void SwCellStyleTable::AddBoxFormat(const SwBoxAutoFormat& rBoxFormat, const OUS
 
 void SwCellStyleTable::RemoveBoxFormat(const OUString& sName)
 {
-    for (size_t i=0; i < m_aCellStyles.size(); ++i)
+    for (auto iter = m_aCellStyles.begin(); iter != m_aCellStyles.end(); ++iter)
     {
-        if (m_aCellStyles[i].first == sName)
+        if (iter->first == sName)
         {
-            m_aCellStyles.erase(m_aCellStyles.begin() + i);
+            delete iter->second;
+            m_aCellStyles.erase(iter);
             return;
         }
     }
diff --git a/sw/source/core/unocore/unostyle.cxx b/sw/source/core/unocore/unostyle.cxx
index 4ea2f08..87e3c55 100644
--- a/sw/source/core/unocore/unostyle.cxx
+++ b/sw/source/core/unocore/unostyle.cxx
@@ -918,6 +918,18 @@ void XStyleFamily::insertByName(const OUString& rName, const uno::Any& rElement)
         m_pDocShell->GetDoc()->GetCellStyles().AddBoxFormat(*pNewStyle->GetBoxFormat(), sStyleName);
         pNewStyle->SetPhysical();
     }
+    else if (nsSwGetPoolIdFromName::GET_POOLID_TABSTYLE == m_rEntry.m_aPoolId)
+    {
+        // handle table style
+        uno::Reference<style::XStyle> xStyle = rElement.get<uno::Reference<style::XStyle>>();
+        SwXTextTableStyle* pNewStyle = dynamic_cast<SwXTextTableStyle*>(xStyle.get());
+        if (!pNewStyle)
+            throw lang::IllegalArgumentException();
+
+        pNewStyle->setName(sStyleName); // insertByName sets the element name
+        m_pDocShell->GetDoc()->GetTableStyles().AddAutoFormat(*pNewStyle->GetTableFormat());
+        pNewStyle->SetPhysical();
+    }
     else
     {
         uno::Reference<lang::XUnoTunnel> xStyleTunnel = rElement.get<uno::Reference<lang::XUnoTunnel>>();
@@ -974,14 +986,25 @@ void XStyleFamily::replaceByName(const OUString& rName, const uno::Any& rElement
             if (!pStyleToReplaceWith)
                 throw lang::IllegalArgumentException();
 
-            // copy box style by value
+            pStyleToReplaceWith->setName(rName);
             *pBoxAutoFormat = *pStyleToReplaceWith->GetBoxFormat();
+            pStyleToReplaceWith->SetPhysical();
+        }
+    }
+    else if (nsSwGetPoolIdFromName::GET_POOLID_TABSTYLE == m_rEntry.m_aPoolId)
+    {
+        // handle table styles
+        SwTableAutoFormat* pTableAutoFormat = SwXTextTableStyle::GetTableAutoFormat(m_pDocShell, rName);
+        if (pTableAutoFormat)
+        {
+            uno::Reference<style::XStyle> xStyle = rElement.get<uno::Reference<style::XStyle>>();
+            SwXTextTableStyle* pStyleToReplaceWith = dynamic_cast<SwXTextTableStyle*>(xStyle.get());
+            if (!pStyleToReplaceWith)
+                throw lang::IllegalArgumentException();
+
             pStyleToReplaceWith->setName(rName);
+            *pTableAutoFormat = *pStyleToReplaceWith->GetTableFormat();
             pStyleToReplaceWith->SetPhysical();
-            // box assign operator does not copy reference to a xobject, we need to set it manually
-            uno::Reference<style::XStyle> xCellStyle(pStyleToReplaceWith);
-            pBoxAutoFormat->SetXObject(xCellStyle);
-            // to handle unassigned styles, because their names aren't generated automatically
         }
     }
     else
@@ -1021,6 +1044,11 @@ void XStyleFamily::removeByName(const OUString& rName) throw( container::NoSuchE
         // handle cell style
         m_pDocShell->GetDoc()->GetCellStyles().RemoveBoxFormat(rName);
     }
+    else if (nsSwGetPoolIdFromName::GET_POOLID_TABSTYLE == m_rEntry.m_aPoolId)
+    {
+        // handle table style
+        m_pDocShell->GetDoc()->GetTableStyles().EraseAutoFormat(rName);
+    }
     else
         m_pBasePool->Remove(pBase);
 }
@@ -4320,50 +4348,35 @@ uno::Sequence< beans::PropertyValue > SwXAutoStyle::getProperties() throw (uno::
     return aRet;
 }
 
-SwXTextTableStyle::SwXTextTableStyle(SwDocShell* pDocShell, const OUString& rTableAutoFormatName) :
-    m_pDocShell(pDocShell), m_sTableAutoFormatName(rTableAutoFormatName)
+SwXTextTableStyle::SwXTextTableStyle(SwDocShell* pDocShell, SwTableAutoFormat* pTableAutoFormat) :
+    m_pDocShell(pDocShell), m_pTableAutoFormat(pTableAutoFormat), m_pTableAutoFormat_Impl(nullptr), m_bPhysical(true)
 {
-    SwTableAutoFormat *pAutoFormat = GetTableAutoFormat();
+    UpdateCellStylesMapping();
+}
 
-    if (pAutoFormat)
-    {
-        const std::vector<sal_Int32> aTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap();
-        assert(aTableTemplateMap.size() == STYLE_COUNT && "can not map SwTableAutoFormat to a SwXTextTableStyle");
-        for (sal_Int32 i=0; i<STYLE_COUNT; ++i)
-        {
-            SwBoxAutoFormat* pBoxFormat = &pAutoFormat->GetBoxFormat(aTableTemplateMap[i]);
-            uno::Reference<style::XStyle> xCellStyle(pBoxFormat->GetXObject(), uno::UNO_QUERY);
-            if (!xCellStyle.is())
-            {
-                xCellStyle.set(new SwXTextCellStyle(m_pDocShell, pBoxFormat, m_sTableAutoFormatName));
-                pBoxFormat->SetXObject(xCellStyle);
-            }
-            m_aCellStyles[i] = xCellStyle;
-        }
-    }
+SwXTextTableStyle::SwXTextTableStyle(SwDocShell* pDocShell, const OUString& rTableAutoFormatName) :
+    m_pDocShell(pDocShell), m_pTableAutoFormat_Impl(new SwTableAutoFormat(rTableAutoFormatName)), m_bPhysical(false)
+{
+    m_pTableAutoFormat = m_pTableAutoFormat_Impl.get();
+    UpdateCellStylesMapping();
 }
 
 uno::Reference<style::XStyle> SwXTextTableStyle::CreateXTextTableStyle(SwDocShell* pDocShell, const OUString& rTableAutoFormatName)
 {
     SolarMutexGuard aGuard;
     uno::Reference<style::XStyle> xTextTableStyle;
-    const size_t nStyles = pDocShell->GetDoc()->GetTableStyles().size();
-    for(size_t i=0; i < nStyles; ++i)
+    SwTableAutoFormat* pAutoFormat = GetTableAutoFormat(pDocShell, rTableAutoFormatName);
+    if (pAutoFormat && pAutoFormat->GetName() == rTableAutoFormatName)
     {
-        SwTableAutoFormat* pAutoFormat = &pDocShell->GetDoc()->GetTableStyles()[i];
-        if (pAutoFormat->GetName() == rTableAutoFormatName)
+        xTextTableStyle.set(pAutoFormat->GetXObject(), uno::UNO_QUERY);
+        if (!xTextTableStyle.is())
         {
-            xTextTableStyle.set(pAutoFormat->GetXObject(), uno::UNO_QUERY);
-            if (!xTextTableStyle.is())
-            {
-                xTextTableStyle.set(new SwXTextTableStyle(pDocShell, rTableAutoFormatName));
-                pAutoFormat->SetXObject(xTextTableStyle);
-            }
-            break;
+            xTextTableStyle.set(new SwXTextTableStyle(pDocShell, pAutoFormat));
+            pAutoFormat->SetXObject(xTextTableStyle);
         }
     }
 
-    // If corresponding AutoFormat doesn't exist create a XStyle but don't register it.
+    // If corresponding AutoFormat doesn't exist create a non physical style.
     if (!xTextTableStyle.is())
     {
         xTextTableStyle.set(new SwXTextTableStyle(pDocShell, rTableAutoFormatName));
@@ -4373,17 +4386,21 @@ uno::Reference<style::XStyle> SwXTextTableStyle::CreateXTextTableStyle(SwDocShel
     return xTextTableStyle;
 }
 
-SwTableAutoFormat* SwXTextTableStyle::GetTableAutoFormat()
+void SwXTextTableStyle::UpdateCellStylesMapping()
 {
-    const size_t nStyles = m_pDocShell->GetDoc()->GetTableStyles().size();
-    for(size_t i=0; i < nStyles; ++i)
+    const std::vector<sal_Int32> aTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap();
+    assert(aTableTemplateMap.size() == STYLE_COUNT && "can not map SwTableAutoFormat to a SwXTextTableStyle");
+    for (sal_Int32 i=0; i<STYLE_COUNT; ++i)
     {
-        SwTableAutoFormat* pAutoFormat = &m_pDocShell->GetDoc()->GetTableStyles()[i];
-        if (pAutoFormat->GetName() == m_sTableAutoFormatName)
-            return pAutoFormat;
+        SwBoxAutoFormat* pBoxFormat = &m_pTableAutoFormat->GetBoxFormat(aTableTemplateMap[i]);
+        uno::Reference<style::XStyle> xCellStyle(pBoxFormat->GetXObject(), uno::UNO_QUERY);
+        if (!xCellStyle.is())
+        {
+            xCellStyle.set(new SwXTextCellStyle(m_pDocShell, pBoxFormat, m_pTableAutoFormat->GetName()));
+            pBoxFormat->SetXObject(xCellStyle);
+        }
+        m_aCellStyles[i] = xCellStyle;
     }
-    SAL_WARN("sw.uno", "lost SwTableAutoFormat and SwXTextTableStyle integrity");
-    return nullptr;
 }
 
 const CellStyleNameMap& SwXTextTableStyle::GetCellStyleNameMap()
@@ -4415,12 +4432,66 @@ const CellStyleNameMap& SwXTextTableStyle::GetCellStyleNameMap()
     return aMap;
 }
 
+SwTableAutoFormat* SwXTextTableStyle::GetTableFormat()
+{
+    return m_pTableAutoFormat;
+}
+
+SwTableAutoFormat* SwXTextTableStyle::GetTableAutoFormat(SwDocShell* pDocShell, const OUString& sName)
+{
+    const size_t nStyles = pDocShell->GetDoc()->GetTableStyles().size();
+    for(size_t i=0; i < nStyles; ++i)
+    {
+        SwTableAutoFormat* pAutoFormat = &pDocShell->GetDoc()->GetTableStyles()[i];
+        if (pAutoFormat->GetName() == sName)
+        {
+            return pAutoFormat;
+        }
+    }
+    // not found
+    return nullptr;
+}
+
+void SwXTextTableStyle::SetPhysical()
+{
+    if (!m_bPhysical)
+    {
+        // find table format in doc
+        SwTableAutoFormat* pTableAutoFormat = GetTableAutoFormat(m_pDocShell, m_pTableAutoFormat->GetName());
+        if (pTableAutoFormat)
+        {
+            m_bPhysical = true;
+            /// take care of children, make SwXTextCellStyles use new core SwBoxAutoFormats
+            const std::vector<sal_Int32> aTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap();
+            for (size_t i=0; i<aTableTemplateMap.size(); ++i)
+            {
+                SwBoxAutoFormat* pOldBoxFormat = &m_pTableAutoFormat->GetBoxFormat(aTableTemplateMap[i]);
+                uno::Reference<style::XStyle> xCellStyle(pOldBoxFormat->GetXObject(), uno::UNO_QUERY);
+                if (!xCellStyle.is())
+                {
+                    SwXTextCellStyle* pStyle = dynamic_cast<SwXTextCellStyle*>(xCellStyle.get());
+                    SwBoxAutoFormat* pNewBoxFormat = &pTableAutoFormat->GetBoxFormat(aTableTemplateMap[i]);
+                    pStyle->SetBoxFormat(pNewBoxFormat);
+                    pNewBoxFormat->SetXObject(uno::Reference<style::XStyle>(xCellStyle));
+                }
+            }
+            m_pTableAutoFormat_Impl = nullptr;
+            m_pTableAutoFormat = pTableAutoFormat;
+            m_pTableAutoFormat->SetXObject(uno::Reference<style::XStyle>(this));
+        }
+        else
+            SAL_WARN("sw.uno", "setting style physical, but SwTableAutoFormat in document not found");
+    }
+    else
+        SAL_WARN("sw.uno", "calling SetPhysical on a physical SwXTextTableStyle");
+}
+
 // XStyle
 sal_Bool SAL_CALL SwXTextTableStyle::isUserDefined() throw (uno::RuntimeException, std::exception)
 {
     SolarMutexGuard aGuard;
     // only first style is not user defined
-    if (m_pDocShell->GetDoc()->GetTableStyles()[0].GetName() == m_sTableAutoFormatName)
+    if (m_pDocShell->GetDoc()->GetTableStyles()[0].GetName() == m_pTableAutoFormat->GetName())
         return false;
 
     return true;
@@ -4429,6 +4500,9 @@ sal_Bool SAL_CALL SwXTextTableStyle::isUserDefined() throw (uno::RuntimeExceptio
 sal_Bool SAL_CALL SwXTextTableStyle::isInUse() throw (uno::RuntimeException, std::exception)
 {
     SolarMutexGuard aGuard;
+    if (!m_bPhysical)
+        return false;
+
     uno::Reference<text::XTextTablesSupplier> xTablesSupp(m_pDocShell->GetModel(), uno::UNO_QUERY);
     if (!xTablesSupp.is())
         return false;
@@ -4444,7 +4518,7 @@ sal_Bool SAL_CALL SwXTextTableStyle::isInUse() throw (uno::RuntimeException, std
         xTables->getByIndex(i) >>= xTablePropertySet;
         OUString sTableTemplateName;
         if (xTablePropertySet.is() && (xTablePropertySet->getPropertyValue("TableTemplateName") >>= sTableTemplateName)
-            && sTableTemplateName == m_sTableAutoFormatName)
+            && sTableTemplateName == m_pTableAutoFormat->GetName())
             return true;
     }
 
@@ -4464,29 +4538,14 @@ OUString SAL_CALL SwXTextTableStyle::getName() throw(uno::RuntimeException, std:
 {
     SolarMutexGuard aGuard;
     OUString sProgName;
-    SwStyleNameMapper::FillProgName(m_sTableAutoFormatName, sProgName, nsSwGetPoolIdFromName::GET_POOLID_TABSTYLE, true);
-    return m_sTableAutoFormatName;
+    SwStyleNameMapper::FillProgName(m_pTableAutoFormat->GetName(), sProgName, nsSwGetPoolIdFromName::GET_POOLID_TABSTYLE, true);
+    return sProgName;
 }
 
 void SAL_CALL SwXTextTableStyle::setName(const OUString& rName) throw(uno::RuntimeException, std::exception)
 {
     SolarMutexGuard aGuard;
-    const size_t nStyles = m_pDocShell->GetDoc()->GetTableStyles().size();
-    for(size_t i=0; i < nStyles; ++i)
-    {
-        SwTableAutoFormat* pAutoFormat = &m_pDocShell->GetDoc()->GetTableStyles()[i];
-        if (pAutoFormat->GetName() == rName)
-        {
-            SAL_INFO("sw.uno", "SwXTextTableStyle with given name already exists");
-            return;
-        }
-    }
-
-    SwTableAutoFormat* pAutoFormat = GetTableAutoFormat();
-    if (pAutoFormat)
-        pAutoFormat->SetName(rName);
-
-    m_sTableAutoFormatName = rName;
+    m_pTableAutoFormat->SetName(rName);
 }
 
 //XPropertySet
@@ -4505,20 +4564,17 @@ css::uno::Any SAL_CALL SwXTextTableStyle::getPropertyValue(const OUString& rProp
 {
     SolarMutexGuard aGuard;
     bool bIsRow = false;
-    SwTableAutoFormat* pFormat = GetTableAutoFormat();
-    if (pFormat)
-    {
-        if (rPropertyName == UNO_NAME_TABLE_FIRST_ROW_END_COLUMN)
-            bIsRow = pFormat->FirstRowEndColumnIsRow();
-        else if (rPropertyName == UNO_NAME_TABLE_FIRST_ROW_START_COLUMN)
-            bIsRow = pFormat->FirstRowStartColumnIsRow();
-        else if (rPropertyName == UNO_NAME_TABLE_LAST_ROW_END_COLUMN)
-            bIsRow = pFormat->LastRowEndColumnIsRow();
-        else if (rPropertyName == UNO_NAME_TABLE_LAST_ROW_START_COLUMN)
-            bIsRow = pFormat->LastRowStartColumnIsRow();
-        else
-            throw css::beans::UnknownPropertyException();
-    }
+
+    if (rPropertyName == UNO_NAME_TABLE_FIRST_ROW_END_COLUMN)
+        bIsRow = m_pTableAutoFormat->FirstRowEndColumnIsRow();
+    else if (rPropertyName == UNO_NAME_TABLE_FIRST_ROW_START_COLUMN)
+        bIsRow = m_pTableAutoFormat->FirstRowStartColumnIsRow();
+    else if (rPropertyName == UNO_NAME_TABLE_LAST_ROW_END_COLUMN)
+        bIsRow = m_pTableAutoFormat->LastRowEndColumnIsRow();
+    else if (rPropertyName == UNO_NAME_TABLE_LAST_ROW_START_COLUMN)
+        bIsRow = m_pTableAutoFormat->LastRowStartColumnIsRow();
+    else
+        throw css::beans::UnknownPropertyException();
 
     return uno::makeAny(bIsRow ? OUString("row") : OUString("column"));
 }
@@ -4569,6 +4625,53 @@ sal_Bool SAL_CALL SwXTextTableStyle::hasByName(const OUString& rName) throw(css:
     return iter != rMap.end();
 }
 
+//XNameContainer
+void SAL_CALL SwXTextTableStyle::insertByName(const OUString& /*Name*/, const uno::Any& /*Element*/) throw(lang::IllegalArgumentException, container::ElementExistException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
+{
+    SAL_WARN("sw.uno", "not implemented");
+}
+
+void SAL_CALL SwXTextTableStyle::replaceByName(const OUString& rName, const uno::Any& rElement) throw(lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
+{
+    SolarMutexGuard aGuard;
+    const CellStyleNameMap& rMap = GetCellStyleNameMap();
+    CellStyleNameMap::const_iterator iter = rMap.find(rName);
+    if(iter == rMap.end())
+        throw container::NoSuchElementException();
+    const sal_Int32 nCellStyle = iter->second;
+
+    uno::Reference<style::XStyle> xStyle = rElement.get<uno::Reference<style::XStyle>>();
+    if (!xStyle.is())
+        throw lang::IllegalArgumentException();
+
+    SwXTextCellStyle* pStyleToReplaceWith = dynamic_cast<SwXTextCellStyle*>(xStyle.get());
+    // replace only with physical ...
+    if (pStyleToReplaceWith && !pStyleToReplaceWith->IsPhysical())
+        throw lang::IllegalArgumentException();
+
+    // ... unassigned cell styles
+    if (!m_pDocShell->GetDoc()->GetCellStyles().GetBoxFormat(xStyle->getName()))
+        throw lang::IllegalArgumentException();
+
+    const auto& rTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap();
+    const sal_Int32 nBoxFormat = rTableTemplateMap[nCellStyle];
+
+    // move SwBoxAutoFormat to dest. SwTableAutoFormat
+    m_pTableAutoFormat->SetBoxFormat(*pStyleToReplaceWith->GetBoxFormat(), nBoxFormat);
+    // make SwXTextCellStyle use new, moved SwBoxAutoFormat
+    pStyleToReplaceWith->SetBoxFormat(&m_pTableAutoFormat->GetBoxFormat(nBoxFormat));
+    m_pTableAutoFormat->GetBoxFormat(nBoxFormat).SetXObject(xStyle);
+    // remove unassigned SwBoxAutoFormat, which is not anymore in use anyways
+    m_pDocShell->GetDoc()->GetCellStyles().RemoveBoxFormat(xStyle->getName());
+    // make this SwXTextTableStyle use new SwXTextCellStyle
+    m_aCellStyles[nCellStyle] = xStyle;
+}
+
+void SAL_CALL SwXTextTableStyle::removeByName(const OUString& /*Name*/) throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
+{
+    SAL_WARN("sw.uno", "not implemented");
+}
+
 //XElementAccess
 uno::Type SAL_CALL SAL_CALL SwXTextTableStyle::getElementType() throw(uno::RuntimeException, std::exception)
 {
@@ -4598,36 +4701,44 @@ css::uno::Sequence<OUString> SAL_CALL SwXTextTableStyle::getSupportedServiceName
 
 // SwXTextCellStyle
 SwXTextCellStyle::SwXTextCellStyle(SwDocShell* pDocShell, SwBoxAutoFormat* pBoxAutoFormat, const OUString& sParentStyle) :
-    m_pDocShell(pDocShell), m_pBoxAutoFormat(pBoxAutoFormat), m_sParentStyle(sParentStyle), m_bPhysical(true)
+    m_pDocShell(pDocShell),
+    m_pBoxAutoFormat(pBoxAutoFormat),
+    m_pBoxAutoFormat_Impl(nullptr),
+    m_sParentStyle(sParentStyle),
+    m_bPhysical(true)
 { }
 
 SwXTextCellStyle::SwXTextCellStyle(SwDocShell* pDocShell, const OUString& sName) :
-    m_pDocShell(pDocShell), m_sName(sName), m_bPhysical(false)
+    m_pDocShell(pDocShell),
+    m_pBoxAutoFormat_Impl(new SwBoxAutoFormat()),
+    m_sName(sName),
+    m_bPhysical(false)
 {
-    // m_bPhysical=false will help to take care deleting it
-    m_pBoxAutoFormat = new SwBoxAutoFormat();
+    m_pBoxAutoFormat = m_pBoxAutoFormat_Impl.get();
 }
 
-SwXTextCellStyle::~SwXTextCellStyle()
+SwBoxAutoFormat* SwXTextCellStyle::GetBoxFormat()
 {
-     if (!m_bPhysical)
-         delete m_pBoxAutoFormat;
+    return m_pBoxAutoFormat;
 }
 
-SwBoxAutoFormat* SwXTextCellStyle::GetBoxFormat()
+void SwXTextCellStyle::SetBoxFormat(SwBoxAutoFormat* pBoxFormat)
 {
-    return m_pBoxAutoFormat;
+    if (m_bPhysical)
+        m_pBoxAutoFormat = pBoxFormat;
+    else
+        SAL_INFO("sw.uno", "trying to call SwXTextCellStyle::SetBoxFormat on non physical style");
 }
 
 void SwXTextCellStyle::SetPhysical()
 {
     if (!m_bPhysical)
     {
-        m_bPhysical = true;
-        delete m_pBoxAutoFormat;
         SwBoxAutoFormat* pBoxAutoFormat = GetBoxAutoFormat(m_pDocShell, m_sName, &m_sParentStyle);
         if (pBoxAutoFormat)
         {
+            m_bPhysical = true;
+            m_pBoxAutoFormat_Impl = nullptr;
             m_pBoxAutoFormat = pBoxAutoFormat;
             m_pBoxAutoFormat->SetXObject(uno::Reference<style::XStyle>(this));
         }
@@ -4638,6 +4749,11 @@ void SwXTextCellStyle::SetPhysical()
         SAL_WARN("sw.uno", "calling SetPhysical on a physical SwXTextCellStyle");
 }
 
+bool SwXTextCellStyle::IsPhysical()
+{
+    return m_bPhysical;
+}
+
 SwBoxAutoFormat* SwXTextCellStyle::GetBoxAutoFormat(SwDocShell* pDocShell, const OUString& sName, OUString* pParentName)
 {
     if (sName.isEmpty())


More information about the Libreoffice-commits mailing list