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

Jakub Trzebiatowski ubap.dev at gmail.com
Mon Jun 13 10:49:23 UTC 2016


 sw/inc/doc.hxx                      |    7 
 sw/inc/tblafmt.hxx                  |   31 +++
 sw/inc/unocoll.hxx                  |    1 
 sw/inc/unostyle.hxx                 |   28 ++-
 sw/qa/python/check_styles.py        |    4 
 sw/source/core/doc/docnew.cxx       |    1 
 sw/source/core/doc/tblafmt.cxx      |   86 +++++++++
 sw/source/core/unocore/unocoll.cxx  |    7 
 sw/source/core/unocore/unostyle.cxx |  316 ++++++++++++++++++++++++++----------
 sw/source/uibase/app/docstyle.cxx   |   34 ++-
 10 files changed, 406 insertions(+), 109 deletions(-)

New commits:
commit 3464befb48ccf1bf9ad4c8f321c7342db43c4019
Author: Jakub Trzebiatowski <ubap.dev at gmail.com>
Date:   Tue Jun 7 21:57:49 2016 +0200

    GSoC Table Styles, CellStyle
    
    - insertByName
    - replaceByName
    - removeByName
    
    Change-Id: I964aa0dc2e7f5a5be9eaec719b8944e847eb9d6a
    Reviewed-on: https://gerrit.libreoffice.org/26037
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Miklos Vajna <vmiklos at collabora.co.uk>

diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index e9b3be5..412b419 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -79,6 +79,7 @@ class SwAutoCompleteWord;
 class SwAutoCorrExceptWord;
 class SwCalc;
 class SwCellFrame;
+class SwCellStyleTable;
 class SwCharFormat;
 class SwCharFormats;
 class SwConditionTextFormatColl;
@@ -344,7 +345,8 @@ class SW_DLLPUBLIC SwDoc :
 
     /// Table styles (autoformats that are applied with table changes).
     std::unique_ptr<SwTableAutoFormatTable> mpTableStyles;
-
+    /// Cell Styles not assigned to a Table Style
+    std::unique_ptr<SwCellStyleTable> mpCellStyles;
 private:
     ::std::unique_ptr< ::sfx2::IXmlIdRegistry > m_pXmlIdRegistry;
 
@@ -1255,6 +1257,9 @@ public:
     SwTableAutoFormatTable& GetTableStyles() { return *mpTableStyles.get(); }
     const SwTableAutoFormatTable& GetTableStyles() const { return *mpTableStyles.get(); }
 
+    const SwCellStyleTable& GetCellStyles() const  { return *mpCellStyles.get(); }
+          SwCellStyleTable& GetCellStyles()        { return *mpCellStyles.get(); }
+
     void AppendUndoForInsertFromDB( const SwPaM& rPam, bool bIsTable );
 
     bool SetColRowWidthHeight( SwTableBox& rAktBox, sal_uInt16 eType,
diff --git a/sw/inc/tblafmt.hxx b/sw/inc/tblafmt.hxx
index 9e5f4a3..6ed138d 100644
--- a/sw/inc/tblafmt.hxx
+++ b/sw/inc/tblafmt.hxx
@@ -344,6 +344,37 @@ public:
     bool Save() const;
 };
 
+class SwCellStyleDescriptor
+{
+    const std::pair<OUString, SwBoxAutoFormat*>& m_rCellStyleDesc;
+public:
+    SwCellStyleDescriptor(const std::pair<OUString, SwBoxAutoFormat*>& rCellStyleDesc) : m_rCellStyleDesc(rCellStyleDesc) { }
+
+    const OUString&  GetName()   { return m_rCellStyleDesc.first; }
+    SwBoxAutoFormat* GetFormat() { return m_rCellStyleDesc.second; }
+};
+
+class SwCellStyleTable
+{
+    std::vector<std::pair<OUString, SwBoxAutoFormat*>> m_aCellStyles;
+public:
+    SwCellStyleTable();
+    ~SwCellStyleTable();
+
+    size_t size() const;
+    SwCellStyleDescriptor operator[](size_t i) const;
+    void clear();
+
+    /// Add a copy of rBoxFormat
+    void AddBoxFormat(const SwBoxAutoFormat& rBoxFormat, const OUString& sName);
+    void RemoveBoxFormat(const OUString& sName);
+    void ChangeBoxFormatName(const OUString& sFromName, const OUString& sToName);
+    /// If found returns its name. If not found returns an empty OUString
+    OUString GetBoxFormatName(const SwBoxAutoFormat& rBoxFormat) const;
+    /// If found returns a ptr to a BoxFormat. If not found returns nullptr
+    SwBoxAutoFormat* GetBoxFormat(const OUString& sName) const;
+};
+
 #endif
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/inc/unocoll.hxx b/sw/inc/unocoll.hxx
index 32979a9..f853fe4 100644
--- a/sw/inc/unocoll.hxx
+++ b/sw/inc/unocoll.hxx
@@ -183,6 +183,7 @@ class SwUnoCollection
 #define SW_SERVICE_VBAPROJECTNAMEPROVIDER               112
 #define SW_SERVICE_VBAGLOBALS                           113
 #define SW_SERVICE_STYLE_TABLE_STYLE                    114
+#define SW_SERVICE_STYLE_CELL_STYLE                     115
 
 #define SW_SERVICE_INVALID          USHRT_MAX
 
diff --git a/sw/inc/unostyle.hxx b/sw/inc/unostyle.hxx
index 8b7401a..bac73cf 100644
--- a/sw/inc/unostyle.hxx
+++ b/sw/inc/unostyle.hxx
@@ -317,10 +317,28 @@ class SwXTextCellStyle : public cppu::WeakImplHelper
 >
 {
     SwDocShell* m_pDocShell;
-    SwBoxAutoFormat& m_rBoxAutoFormat;
-    OUString m_sParentStyle;
-public:
-    SwXTextCellStyle(SwDocShell* pDocShell, SwBoxAutoFormat& rBoxAutoFormat, const OUString& sParentStyle);
+    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!
+
+ 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.
+    * @param pDocShell pointer to a SwDocShell.
+    * @param sName Name of a SwBoxAutoFormat to look for.
+    * @param pParentName Optional output. Pointer to a OUString where parsed parent name will be returned.
+    * @return Pointer to a SwBoxAutoFormat, nullptr if not found.
+    */
+    static SwBoxAutoFormat* GetBoxAutoFormat(SwDocShell* pDocShell, const OUString& sName, OUString* pParentName = nullptr);
+    /// returns box format assigned to this style
+    SwBoxAutoFormat* GetBoxFormat();
+    void SetPhysical();
 
     //XStyle
     virtual sal_Bool SAL_CALL isUserDefined() throw (css::uno::RuntimeException, std::exception) override;
@@ -330,7 +348,7 @@ public:
 
     //XNamed
     virtual OUString SAL_CALL getName() throw(css::uno::RuntimeException, std::exception) override;
-    virtual void SAL_CALL setName(const OUString& rName) throw(css::uno::RuntimeException, std::exception) override;
+    virtual void SAL_CALL setName(const OUString& sName) throw(css::uno::RuntimeException, std::exception) override;
 
     //XPropertySet
     virtual css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL getPropertySetInfo() throw(css::uno::RuntimeException, std::exception) override;
diff --git a/sw/qa/python/check_styles.py b/sw/qa/python/check_styles.py
index c435663..d2ea6a9 100644
--- a/sw/qa/python/check_styles.py
+++ b/sw/qa/python/check_styles.py
@@ -188,7 +188,9 @@ class CheckStyle(unittest.TestCase):
         xCellStyles = xDoc.StyleFamilies["CellStyles"]
         vEmptyDocStyles = ['Default Style.1', 'Default Style.2', 'Default Style.3', 'Default Style.4', 'Default Style.5', 'Default Style.6', 'Default Style.7', 'Default Style.8', 'Default Style.9', 'Default Style.10']
         self.__test_StyleFamily(xCellStyles, vEmptyDocStyles, "SwXTextCellStyle")
-        #possibly more depth tests could be added, to test properties of a cell style... yet to come
+        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
         xDoc.dispose()
 
 if __name__ == '__main__':
diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx
index a136c35..68734cf 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -257,6 +257,7 @@ SwDoc::SwDoc()
     mpLayoutCache( nullptr ),
     mpGrammarContact(createGrammarContact()),
     mpTableStyles(new SwTableAutoFormatTable),
+    mpCellStyles(new SwCellStyleTable),
     m_pXmlIdRegistry(),
     mReferenceCount(0),
     mbDtor(false),
diff --git a/sw/source/core/doc/tblafmt.cxx b/sw/source/core/doc/tblafmt.cxx
index 95088b7..6b18c2e 100644
--- a/sw/source/core/doc/tblafmt.cxx
+++ b/sw/source/core/doc/tblafmt.cxx
@@ -1324,4 +1324,90 @@ bool SwTableAutoFormatTable::Save( SvStream& rStream ) const
     return bRet;
 }
 
+SwCellStyleTable::SwCellStyleTable()
+{ }
+
+SwCellStyleTable::~SwCellStyleTable()
+{
+    for (size_t i=0; i < m_aCellStyles.size(); ++i)
+        delete m_aCellStyles[i].second;
+}
+
+size_t SwCellStyleTable::size() const
+{
+    return m_aCellStyles.size();
+}
+
+void SwCellStyleTable::clear()
+{
+    for (size_t i=0; i < m_aCellStyles.size(); ++i)
+        delete m_aCellStyles[i].second;
+
+    m_aCellStyles.clear();
+}
+
+SwCellStyleDescriptor SwCellStyleTable::operator[](size_t i) const
+{
+    return SwCellStyleDescriptor(m_aCellStyles[i]);
+}
+
+void SwCellStyleTable::AddBoxFormat(const SwBoxAutoFormat& rBoxFormat, const OUString& sName)
+{
+    m_aCellStyles.push_back(std::make_pair(sName, new SwBoxAutoFormat(rBoxFormat)));
+}
+
+void SwCellStyleTable::RemoveBoxFormat(const OUString& sName)
+{
+    for (size_t i=0; i < m_aCellStyles.size(); ++i)
+    {
+        if (m_aCellStyles[i].first == sName)
+        {
+            m_aCellStyles.erase(m_aCellStyles.begin() + i);
+            return;
+        }
+    }
+    SAL_INFO("sw.core", "SwCellStyleTable::RemoveBoxFormat, format with given name doesn't exists");
+}
+
+OUString SwCellStyleTable::GetBoxFormatName(const SwBoxAutoFormat& rBoxFormat) const
+{
+    for (size_t i=0; i < m_aCellStyles.size(); ++i)
+    {
+        if (m_aCellStyles[i].second == &rBoxFormat)
+            return m_aCellStyles[i].first;
+    }
+
+    // box format not found
+    return OUString();
+}
+
+SwBoxAutoFormat* SwCellStyleTable::GetBoxFormat(const OUString& sName) const
+{
+    for (size_t i=0; i < m_aCellStyles.size(); ++i)
+    {
+        if (m_aCellStyles[i].first == sName)
+            return m_aCellStyles[i].second;
+    }
+
+    return nullptr;
+}
+
+void SwCellStyleTable::ChangeBoxFormatName(const OUString& sFromName, const OUString& sToName)
+{
+    if (!GetBoxFormat(sToName))
+    {
+        SAL_INFO("sw.core", "SwCellStyleTable::ChangeBoxName, box with given name already exists");
+        return;
+    }
+    for (size_t i=0; i < m_aCellStyles.size(); ++i)
+    {
+        if (m_aCellStyles[i].first == sFromName)
+        {
+            m_aCellStyles[i].first = sToName;
+            // changed succesfully
+            return;
+        }
+    }
+    SAL_INFO("sw.core", "SwCellStyleTable::ChangeBoxName, box with given name not found");
+}
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unocoll.cxx b/sw/source/core/unocore/unocoll.cxx
index 50a4ec6..2cbd5fe 100644
--- a/sw/source/core/unocore/unocoll.cxx
+++ b/sw/source/core/unocore/unocoll.cxx
@@ -455,7 +455,8 @@ const ProvNamesId_Type aProvNamesId[] =
     { CSS_TEXT_FIELDMASTER_SET_EXPRESSION,            SW_SERVICE_FIELDMASTER_SET_EXP },
     { CSS_TEXT_FIELDMASTER_DATABASE,                  SW_SERVICE_FIELDMASTER_DATABASE },
     { CSS_TEXT_FIELDMASTER_BIBLIOGRAPHY,              SW_SERVICE_FIELDMASTER_BIBLIOGRAPHY },
-    { "com.sun.star.style.TableStyle",                SW_SERVICE_STYLE_TABLE_STYLE }
+    { "com.sun.star.style.TableStyle",                SW_SERVICE_STYLE_TABLE_STYLE },
+    { "com.sun.star.style.CellStyle",                 SW_SERVICE_STYLE_CELL_STYLE }
 };
 
 const SvEventDescription* sw_GetSupportedMacroItems()
@@ -671,6 +672,7 @@ SwXServiceProvider::MakeInstance(sal_uInt16 nObjectType, SwDoc & rDoc)
         case SW_SERVICE_STYLE_PAGE_STYLE:
         case SW_SERVICE_STYLE_NUMBERING_STYLE:
         case SW_SERVICE_STYLE_TABLE_STYLE:
+        case SW_SERVICE_STYLE_CELL_STYLE:
         {
             SfxStyleFamily eFamily = SfxStyleFamily::Char;
             switch(nObjectType)
@@ -694,6 +696,9 @@ SwXServiceProvider::MakeInstance(sal_uInt16 nObjectType, SwDoc & rDoc)
                 case SW_SERVICE_STYLE_TABLE_STYLE:
                     eFamily = SfxStyleFamily::Table;
                 break;
+                case SW_SERVICE_STYLE_CELL_STYLE:
+                    eFamily = SfxStyleFamily::Cell;
+                break;
             }
             if(!xRet.is())
                 xRet = SwXStyleFamilies::CreateStyle(eFamily, rDoc);
diff --git a/sw/source/core/unocore/unostyle.cxx b/sw/source/core/unocore/unostyle.cxx
index b87dfe3..ffc9619 100644
--- a/sw/source/core/unocore/unostyle.cxx
+++ b/sw/source/core/unocore/unostyle.cxx
@@ -712,10 +712,25 @@ sal_Int32 lcl_GetCountOrName<SfxStyleFamily::Table>(const SwDoc& rDoc, OUString*
 }
 
 template<>
-sal_Int32 lcl_GetCountOrName<SfxStyleFamily::Cell>(const SwDoc& rDoc, OUString* /*pString*/, sal_Int32 /*nIndex*/)
+sal_Int32 lcl_GetCountOrName<SfxStyleFamily::Cell>(const SwDoc& rDoc, OUString* pString, sal_Int32 nIndex)
 {
-    const auto pAutoFormats = &rDoc.GetTableStyles();
-    const sal_Int32 nCount = pAutoFormats->size() * SwTableAutoFormat::GetTableTemplateMap().size();
+    const auto& rAutoFormats = rDoc.GetTableStyles();
+    const auto& rTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap();
+    const sal_Int32 nUsedCellStylesCount = rAutoFormats.size() * rTableTemplateMap.size();
+    const sal_Int32 nCount = nUsedCellStylesCount + rDoc.GetCellStyles().size();
+    if (0 <= nIndex && nIndex < nCount)
+    {
+        if (nUsedCellStylesCount > nIndex)
+        {
+            const sal_Int32 nAutoFormat = nIndex / rTableTemplateMap.size();
+            const sal_Int32 nBoxFormat = rTableTemplateMap[nIndex % rTableTemplateMap.size()];
+            const SwTableAutoFormat* pTableFormat = &rAutoFormats[nAutoFormat];
+            if (pTableFormat)
+                *pString = pTableFormat->GetName() + pTableFormat->GetTableTemplateCellSubName(pTableFormat->GetBoxFormat(nBoxFormat));
+        }
+        else
+            *pString = rDoc.GetCellStyles()[nIndex-nUsedCellStylesCount].GetName();
+    }
     return nCount;
 }
 
@@ -889,34 +904,49 @@ void XStyleFamily::insertByName(const OUString& rName, const uno::Any& rElement)
         throw container::ElementExistException();
     if(rElement.getValueType().getTypeClass() != uno::TypeClass_INTERFACE)
         throw lang::IllegalArgumentException();
-    uno::Reference<lang::XUnoTunnel> xStyleTunnel = rElement.get<uno::Reference<lang::XUnoTunnel>>();
-    SwXStyle* pNewStyle = nullptr;
-    if(xStyleTunnel.is())
+    if (nsSwGetPoolIdFromName::GET_POOLID_CELLSTYLE == m_rEntry.m_aPoolId)
     {
-        pNewStyle = reinterpret_cast< SwXStyle * >(
-                sal::static_int_cast< sal_IntPtr >( xStyleTunnel->getSomething( SwXStyle::getUnoTunnelId()) ));
+        // handle cell style
+        uno::Reference<style::XStyle> xStyle = rElement.get<uno::Reference<style::XStyle>>();
+        SwXTextCellStyle* pNewStyle = dynamic_cast<SwXTextCellStyle*>(xStyle.get());
+        if (!pNewStyle)
+            throw lang::IllegalArgumentException();
+
+        pNewStyle->setName(sStyleName); // insertByName sets the element name
+        m_pDocShell->GetDoc()->GetCellStyles().AddBoxFormat(*pNewStyle->GetBoxFormat(), sStyleName);
+        pNewStyle->SetPhysical();
     }
+    else
+    {
+        uno::Reference<lang::XUnoTunnel> xStyleTunnel = rElement.get<uno::Reference<lang::XUnoTunnel>>();
+        SwXStyle* pNewStyle = nullptr;
+        if(xStyleTunnel.is())
+        {
+            pNewStyle = reinterpret_cast< SwXStyle * >(
+                    sal::static_int_cast< sal_IntPtr >( xStyleTunnel->getSomething( SwXStyle::getUnoTunnelId()) ));
+        }
 
-    if (!pNewStyle || !pNewStyle->IsDescriptor() || pNewStyle->GetFamily() != m_rEntry.m_eFamily)
-        throw lang::IllegalArgumentException();
+        if (!pNewStyle || !pNewStyle->IsDescriptor() || pNewStyle->GetFamily() != m_rEntry.m_eFamily)
+            throw lang::IllegalArgumentException();
 
-    sal_uInt16 nMask = SFXSTYLEBIT_ALL;
-    if(m_rEntry.m_eFamily == SfxStyleFamily::Para && !pNewStyle->IsConditional())
-        nMask &= ~SWSTYLEBIT_CONDCOLL;
-    m_pBasePool->Make(sStyleName, m_rEntry.m_eFamily, nMask);
-    pNewStyle->SetDoc(m_pDocShell->GetDoc(), m_pBasePool);
-    pNewStyle->SetStyleName(sStyleName);
-    const OUString sParentStyleName(pNewStyle->GetParentStyleName());
-    if (!sParentStyleName.isEmpty())
-    {
-        m_pBasePool->SetSearchMask(m_rEntry.m_eFamily);
-        SfxStyleSheetBase* pParentBase = m_pBasePool->Find(sParentStyleName);
-        if(pParentBase && pParentBase->GetFamily() == m_rEntry.m_eFamily &&
-            &pParentBase->GetPool() == m_pBasePool)
-            m_pBasePool->SetParent(m_rEntry.m_eFamily, sStyleName, sParentStyleName);
+        sal_uInt16 nMask = SFXSTYLEBIT_ALL;
+        if(m_rEntry.m_eFamily == SfxStyleFamily::Para && !pNewStyle->IsConditional())
+            nMask &= ~SWSTYLEBIT_CONDCOLL;
+        m_pBasePool->Make(sStyleName, m_rEntry.m_eFamily, nMask);
+        pNewStyle->SetDoc(m_pDocShell->GetDoc(), m_pBasePool);
+        pNewStyle->SetStyleName(sStyleName);
+        const OUString sParentStyleName(pNewStyle->GetParentStyleName());
+        if (!sParentStyleName.isEmpty())
+        {
+            m_pBasePool->SetSearchMask(m_rEntry.m_eFamily);
+            SfxStyleSheetBase* pParentBase = m_pBasePool->Find(sParentStyleName);
+            if(pParentBase && pParentBase->GetFamily() == m_rEntry.m_eFamily &&
+                &pParentBase->GetPool() == m_pBasePool)
+                m_pBasePool->SetParent(m_rEntry.m_eFamily, sStyleName, sParentStyleName);
+        }
+        // after all, we still need to apply the properties of the descriptor
+        pNewStyle->ApplyDescriptorProperties();
     }
-    // after all, we still need to apply the properties of the descriptor
-    pNewStyle->ApplyDescriptorProperties();
 }
 
 void XStyleFamily::replaceByName(const OUString& rName, const uno::Any& rElement)
@@ -930,22 +960,47 @@ void XStyleFamily::replaceByName(const OUString& rName, const uno::Any& rElement
     // replacements only for userdefined styles
     if(!pBase)
         throw container::NoSuchElementException();
-    if(!pBase->IsUserDefined())
-        throw lang::IllegalArgumentException();
-    //if theres an object available to this style then it must be invalidated
-    uno::Reference<style::XStyle> xStyle = FindStyle(pBase->GetName());
-    if(xStyle.is())
+    if (nsSwGetPoolIdFromName::GET_POOLID_CELLSTYLE == m_rEntry.m_aPoolId)
     {
-        uno::Reference<lang::XUnoTunnel> xTunnel( xStyle, uno::UNO_QUERY);
-        if(xTunnel.is())
+        // handle cell styles, don't call on assigned cell styles (TableStyle child)
+        OUString sParent;
+        SwBoxAutoFormat* pBoxAutoFormat = SwXTextCellStyle::GetBoxAutoFormat(m_pDocShell, rName, &sParent);
+        if (pBoxAutoFormat && sParent.isEmpty())// if parent exists then this style is assigned to a table style. Don't replace.
         {
-            SwXStyle* pStyle = reinterpret_cast< SwXStyle * >(
-                    sal::static_int_cast< sal_IntPtr >( xTunnel->getSomething( SwXStyle::getUnoTunnelId()) ));
-            pStyle->Invalidate();
+            uno::Reference<style::XStyle> xStyle = rElement.get<uno::Reference<style::XStyle>>();
+            SwXTextCellStyle* pStyleToReplaceWith = dynamic_cast<SwXTextCellStyle*>(xStyle.get());
+            if (!pStyleToReplaceWith)
+                throw lang::IllegalArgumentException();
+
+            // copy box style by value
+            *pBoxAutoFormat = *pStyleToReplaceWith->GetBoxFormat();
+            pStyleToReplaceWith->setName(rName);
+            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
         }
     }
-    m_pBasePool->Remove(pBase);
-    insertByName(rName, rElement);
+    else
+    {
+        if(!pBase->IsUserDefined())
+            throw lang::IllegalArgumentException();
+        //if theres an object available to this style then it must be invalidated
+        uno::Reference<style::XStyle> xStyle = FindStyle(pBase->GetName());
+        if(xStyle.is())
+        {
+            uno::Reference<lang::XUnoTunnel> xTunnel( xStyle, uno::UNO_QUERY);
+            if(xTunnel.is())
+            {
+                SwXStyle* pStyle = reinterpret_cast< SwXStyle * >(
+                        sal::static_int_cast< sal_IntPtr >( xTunnel->getSomething( SwXStyle::getUnoTunnelId()) ));
+                pStyle->Invalidate();
+            }
+        }
+        m_pBasePool->Remove(pBase);
+        insertByName(rName, rElement);
+    }
 }
 
 void XStyleFamily::removeByName(const OUString& rName) throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception )
@@ -959,7 +1014,13 @@ void XStyleFamily::removeByName(const OUString& rName) throw( container::NoSuchE
     SfxStyleSheetBase* pBase = m_pBasePool->Find( sName );
     if(!pBase)
         throw container::NoSuchElementException();
-    m_pBasePool->Remove(pBase);
+    if (nsSwGetPoolIdFromName::GET_POOLID_CELLSTYLE == m_rEntry.m_aPoolId)
+    {
+        // handle cell style
+        m_pDocShell->GetDoc()->GetCellStyles().RemoveBoxFormat(rName);
+    }
+    else
+        m_pBasePool->Remove(pBase);
 }
 
 uno::Any SAL_CALL XStyleFamily::getPropertyValue( const OUString& sPropertyName ) throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
@@ -4268,12 +4329,12 @@ SwXTextTableStyle::SwXTextTableStyle(SwDocShell* pDocShell, const OUString& rTab
         assert(aTableTemplateMap.size() == STYLE_COUNT && "can not map SwTableAutoFormat to a SwXTextTableStyle");
         for (sal_Int32 i=0; i<STYLE_COUNT; ++i)
         {
-            SwBoxAutoFormat& rBoxFormat = pAutoFormat->GetBoxFormat(aTableTemplateMap[i]);
-            uno::Reference<style::XStyle> xCellStyle(rBoxFormat.GetXObject(), uno::UNO_QUERY);
+            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, rBoxFormat, m_sTableAutoFormatName));
-                rBoxFormat.SetXObject(xCellStyle);
+                xCellStyle.set(new SwXTextCellStyle(m_pDocShell, pBoxFormat, m_sTableAutoFormatName));
+                pBoxFormat->SetXObject(xCellStyle);
             }
             m_aCellStyles[i] = xCellStyle;
         }
@@ -4446,55 +4507,113 @@ css::uno::Sequence<OUString> SAL_CALL SwXTextTableStyle::getSupportedServiceName
 }
 
 // SwXTextCellStyle
-SwXTextCellStyle::SwXTextCellStyle(SwDocShell* pDocShell, SwBoxAutoFormat& rBoxAutoFormat, const OUString& sParentStyle) :
-    m_pDocShell(pDocShell), m_rBoxAutoFormat(rBoxAutoFormat), m_sParentStyle(sParentStyle)
+SwXTextCellStyle::SwXTextCellStyle(SwDocShell* pDocShell, SwBoxAutoFormat* pBoxAutoFormat, const OUString& sParentStyle) :
+    m_pDocShell(pDocShell), m_pBoxAutoFormat(pBoxAutoFormat), m_sParentStyle(sParentStyle), m_bPhysical(true)
 { }
 
-css::uno::Reference<css::style::XStyle> SwXTextCellStyle::CreateXTextCellStyle(SwDocShell* pDocShell, const OUString& sName)
+SwXTextCellStyle::SwXTextCellStyle(SwDocShell* pDocShell, const OUString& sName) :
+    m_pDocShell(pDocShell), m_sName(sName), m_bPhysical(false)
+{
+    // m_bPhysical=false will help to take care deleting it
+    m_pBoxAutoFormat = new SwBoxAutoFormat();
+}
+
+SwXTextCellStyle::~SwXTextCellStyle()
+{
+     if (!m_bPhysical)
+         delete m_pBoxAutoFormat;
+}
+
+SwBoxAutoFormat* SwXTextCellStyle::GetBoxFormat()
+{
+    return m_pBoxAutoFormat;
+}
+
+void SwXTextCellStyle::SetPhysical()
 {
-    SwBoxAutoFormat* pBoxFormat = nullptr;
-    sal_Int32 nSeparatorIndex;
-    sal_uInt32 nTemplateIndex;
-    OUString sParentName, sCellSubName;
+    if (!m_bPhysical)
+    {
+        m_bPhysical = true;
+        delete m_pBoxAutoFormat;
+        SwBoxAutoFormat* pBoxAutoFormat = GetBoxAutoFormat(m_pDocShell, m_sName, &m_sParentStyle);
+        if (pBoxAutoFormat)
+        {
+            m_pBoxAutoFormat = pBoxAutoFormat;
+            m_pBoxAutoFormat->SetXObject(uno::Reference<style::XStyle>(this));
+        }
+        else
+            SAL_WARN("sw.uno", "setting style physical, but SwBoxAutoFormat in document not found");
+    }
+    else
+        SAL_WARN("sw.uno", "calling SetPhysical on a physical SwXTextCellStyle");
+}
+
+SwBoxAutoFormat* SwXTextCellStyle::GetBoxAutoFormat(SwDocShell* pDocShell, const OUString& sName, OUString* pParentName)
+{
+    if (sName.isEmpty())
+        return nullptr;
+
+    SwBoxAutoFormat* pBoxAutoFormat = pDocShell->GetDoc()->GetCellStyles().GetBoxFormat(sName);
+    if (!pBoxAutoFormat)
+    {
+        sal_Int32 nSeparatorIndex, nTemplateIndex;
+        OUString sParentName, sCellSubName;
 
-    try {
         nSeparatorIndex = sName.lastIndexOf('.');
+        if (0 >= nSeparatorIndex)
+            return nullptr;
+
         sParentName = sName.copy(0, nSeparatorIndex);
         sCellSubName = sName.copy(nSeparatorIndex+1);
-        nTemplateIndex = sCellSubName.toInt32()-1;      // -1 because cell styles names start from 1
+        nTemplateIndex = sCellSubName.toInt32()-1; // -1 because cell styles names start from 1, but internally are indexed from 0
+        if (0 > nTemplateIndex)
+            return nullptr;
 
-        auto rTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap();
-        if (nTemplateIndex >= rTableTemplateMap.size())
-            throw;
+        const auto& rTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap();
+        if (rTableTemplateMap.size() <= (size_t)nTemplateIndex)
+            return nullptr;
 
-        SwTableAutoFormat* pFormat = pDocShell->GetDoc()->GetTableStyles().FindAutoFormat(sParentName);
-        if (!pFormat)
-            throw;
+        SwTableAutoFormat* pTableAutoFormat = pDocShell->GetDoc()->GetTableStyles().FindAutoFormat(sParentName);
+        if (!pTableAutoFormat)
+            return nullptr;
 
+        if (pParentName)
+            *pParentName = sParentName;
         sal_uInt32 nBoxIndex = rTableTemplateMap[nTemplateIndex];
-        pBoxFormat = &pFormat->GetBoxFormat(nBoxIndex);
-    }
-    catch (...)
-    {
-        SAL_WARN("sw.uno", "could not get a BoxFormat to create XTextCellStyle for, unexpected error");
+        pBoxAutoFormat = &pTableAutoFormat->GetBoxFormat(nBoxIndex);
     }
 
-    if (!pBoxFormat)
-    {
-        // return a default-dummy style to prevent crash
-        static SwBoxAutoFormat* pDefaultBoxFormat;
-        if (!pDefaultBoxFormat)
-            pDefaultBoxFormat = new SwBoxAutoFormat();
-        pBoxFormat = pDefaultBoxFormat;
-    }
+    return pBoxAutoFormat;
+}
 
+css::uno::Reference<css::style::XStyle> SwXTextCellStyle::CreateXTextCellStyle(SwDocShell* pDocShell, const OUString& sName)
+{
     uno::Reference<style::XStyle> xTextCellStyle;
-    xTextCellStyle.set(pBoxFormat->GetXObject(), uno::UNO_QUERY);
-    if (!xTextCellStyle.is())
+
+    if (!sName.isEmpty()) // create a cell style for a physical box
     {
-        xTextCellStyle.set(new SwXTextCellStyle(pDocShell, *pBoxFormat, sParentName));
-        pBoxFormat->SetXObject(xTextCellStyle);
+        OUString sParentName;
+        SwBoxAutoFormat* pBoxFormat = GetBoxAutoFormat(pDocShell, sName, &sParentName);
+
+        // something went wrong but we don't want a crash
+        if (!pBoxFormat)
+        {
+            // return a default-dummy style to prevent crash
+            static SwBoxAutoFormat* pDefaultBoxFormat;
+            if (!pDefaultBoxFormat)
+                pDefaultBoxFormat = new SwBoxAutoFormat();
+            pBoxFormat = pDefaultBoxFormat;
+        }
+
+        xTextCellStyle.set(pBoxFormat->GetXObject(), uno::UNO_QUERY);
+        if (!xTextCellStyle.is())
+        {
+            xTextCellStyle.set(new SwXTextCellStyle(pDocShell, pBoxFormat, sParentName));
+            pBoxFormat->SetXObject(xTextCellStyle);
+        }
     }
+    else // create a non physical style
+        xTextCellStyle.set(new SwXTextCellStyle(pDocShell, sName));
 
     return xTextCellStyle;
 }
@@ -4502,7 +4621,11 @@ css::uno::Reference<css::style::XStyle> SwXTextCellStyle::CreateXTextCellStyle(S
 // XStyle
 sal_Bool SAL_CALL SwXTextCellStyle::isUserDefined() throw (css::uno::RuntimeException, std::exception)
 {
-    return false;
+    // if this cell belong to first table style then its defaut style
+    if (&m_pDocShell->GetDoc()->GetTableStyles()[0] == m_pDocShell->GetDoc()->GetTableStyles().FindAutoFormat(m_sParentStyle))
+        return false;
+
+    return true;
 }
 
 sal_Bool SAL_CALL SwXTextCellStyle::isInUse() throw (css::uno::RuntimeException, std::exception)
@@ -4525,17 +4648,36 @@ void SAL_CALL SwXTextCellStyle::setParentStyle(const OUString& sParentStyle) thr
 //XNamed
 OUString SAL_CALL SwXTextCellStyle::getName() throw(css::uno::RuntimeException, std::exception)
 {
-    OUString sParentStyle;
-    SwStyleNameMapper::FillUIName(m_sParentStyle, sParentStyle, nsSwGetPoolIdFromName::GET_POOLID_TABSTYLE, true);
-    SwTableAutoFormat* pTableFormat = m_pDocShell->GetDoc()->GetTableStyles().FindAutoFormat(sParentStyle);
-    if (!pTableFormat)
-        return OUString();
+    OUString sName;
 
-    return sParentStyle + pTableFormat->GetTableTemplateCellSubName(m_rBoxAutoFormat);
+    // if style is physical then we request a name from doc
+    if (m_bPhysical)
+    {
+        OUString sParentStyle;
+        SwStyleNameMapper::FillUIName(m_sParentStyle, sParentStyle, nsSwGetPoolIdFromName::GET_POOLID_TABSTYLE, true);
+        SwTableAutoFormat* pTableFormat = m_pDocShell->GetDoc()->GetTableStyles().FindAutoFormat(sParentStyle);
+        if (!pTableFormat)
+        {
+            // if auto format is not found as a child of table formats, look in SwDoc cellstyles
+            sName = m_pDocShell->GetDoc()->GetCellStyles().GetBoxFormatName(*m_pBoxAutoFormat);
+        }
+        else
+            sName = sParentStyle + pTableFormat->GetTableTemplateCellSubName(*m_pBoxAutoFormat);
+    }
+    else
+        sName = m_sName;
+
+    return sName;
 }
 
-void SAL_CALL SwXTextCellStyle::setName(const OUString& /*rName*/) throw(css::uno::RuntimeException, std::exception)
-{ }
+void SAL_CALL SwXTextCellStyle::setName(const OUString& sName) throw(css::uno::RuntimeException, std::exception)
+{
+    // if style is physical then we can not rename it.
+    if (!m_bPhysical)
+        m_sName = sName;
+    // change name if style is unassigned (name is not generated automatically)
+    m_pDocShell->GetDoc()->GetCellStyles().ChangeBoxFormatName(getName(), sName);
+}
 
 //XPropertySet
 css::uno::Reference<css::beans::XPropertySetInfo> SAL_CALL SwXTextCellStyle::getPropertySetInfo() throw(css::uno::RuntimeException, std::exception)
@@ -4554,9 +4696,9 @@ void SAL_CALL SwXTextCellStyle::setPropertyValue(const OUString& rPropertyName,
         {
             case RES_BACKGROUND:
             {
-                SvxBrushItem rBrush( m_rBoxAutoFormat.GetBackground() );
+                SvxBrushItem rBrush( m_pBoxAutoFormat->GetBackground() );
                 rBrush.PutValue(aValue, 0);
-                m_rBoxAutoFormat.SetBackground(rBrush);
+                m_pBoxAutoFormat->SetBackground(rBrush);
                 return;
             }
             default:
@@ -4579,7 +4721,7 @@ css::uno::Any SAL_CALL SwXTextCellStyle::getPropertyValue(const OUString& rPrope
         {
             case RES_BACKGROUND:
             {
-                const SvxBrushItem& rBrush = m_rBoxAutoFormat.GetBackground();
+                const SvxBrushItem& rBrush = m_pBoxAutoFormat->GetBackground();
                 rBrush.QueryValue(aRet);
                 return aRet;
             }
diff --git a/sw/source/uibase/app/docstyle.cxx b/sw/source/uibase/app/docstyle.cxx
index f91c3fc..c25f853 100644
--- a/sw/source/uibase/app/docstyle.cxx
+++ b/sw/source/uibase/app/docstyle.cxx
@@ -323,22 +323,25 @@ static const SwTableAutoFormat* lcl_FindTableStyle(SwDoc& rDoc, const OUString&
 
 static const SwBoxAutoFormat* lcl_FindCellStyle(SwDoc& rDoc, const OUString& rName, SwDocStyleSheet *pStyle = nullptr)
 {
-    const SwBoxAutoFormat* pFormat = nullptr;
+    const SwBoxAutoFormat* pFormat = rDoc.GetCellStyles().GetBoxFormat(rName);
 
-    auto aTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap();
-    SwTableAutoFormatTable& rTableStyles = rDoc.GetTableStyles();
-    for (size_t i=0; i < rTableStyles.size() && !pFormat; ++i)
+    if (!pFormat)
     {
-        const SwTableAutoFormat& rTableStyle = rTableStyles[i];
-        for (size_t nBoxFormat=0; nBoxFormat < aTableTemplateMap.size() && !pFormat; ++nBoxFormat)
+        const auto& aTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap();
+        SwTableAutoFormatTable& rTableStyles = rDoc.GetTableStyles();
+        for (size_t i=0; i < rTableStyles.size() && !pFormat; ++i)
         {
-                const sal_uInt32 nBoxIndex = aTableTemplateMap[nBoxFormat];
-                const SwBoxAutoFormat& rBoxFormat = rTableStyle.GetBoxFormat(nBoxIndex);
-                OUString sBoxFormatName;
-                SwStyleNameMapper::FillProgName(rTableStyle.GetName(), sBoxFormatName, nsSwGetPoolIdFromName::GET_POOLID_CELLSTYLE, true);
-                sBoxFormatName += rTableStyle.GetTableTemplateCellSubName(rBoxFormat);
-                if (rName == sBoxFormatName)
-                    pFormat = &rBoxFormat;
+            const SwTableAutoFormat& rTableStyle = rTableStyles[i];
+            for (size_t nBoxFormat=0; nBoxFormat < aTableTemplateMap.size() && !pFormat; ++nBoxFormat)
+            {
+                    const sal_uInt32 nBoxIndex = aTableTemplateMap[nBoxFormat];
+                    const SwBoxAutoFormat& rBoxFormat = rTableStyle.GetBoxFormat(nBoxIndex);
+                    OUString sBoxFormatName;
+                    SwStyleNameMapper::FillProgName(rTableStyle.GetName(), sBoxFormatName, nsSwGetPoolIdFromName::GET_POOLID_CELLSTYLE, true);
+                    sBoxFormatName += rTableStyle.GetTableTemplateCellSubName(rBoxFormat);
+                    if (rName == sBoxFormatName)
+                        pFormat = &rBoxFormat;
+            }
         }
     }
 
@@ -2993,7 +2996,7 @@ SfxStyleSheetBase*  SwStyleSheetIterator::First()
     if( nSearchFamily == SfxStyleFamily::Cell ||
         nSearchFamily == SfxStyleFamily::All )
     {
-        const std::vector<sal_Int32> aTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap();
+        const auto& aTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap();
         const SwTableAutoFormatTable& rTableStyles = rDoc.GetTableStyles();
         for(size_t i = 0; i < rTableStyles.size(); ++i)
         {
@@ -3008,6 +3011,9 @@ SfxStyleSheetBase*  SwStyleSheetIterator::First()
                 aLst.Append( cCELLSTYLE, sBoxFormatName );
             }
         }
+        const SwCellStyleTable& rCellStyles = rDoc.GetCellStyles();
+        for(size_t i = 0; i < rCellStyles.size(); ++i)
+            aLst.Append( cCELLSTYLE, rCellStyles[i].GetName() );
     }
 
     if(!aLst.empty())


More information about the Libreoffice-commits mailing list