diff options
author | Jakub Trzebiatowski <ubap.dev@gmail.com> | 2016-06-07 21:57:49 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2016-06-13 10:48:55 +0000 |
commit | 3464befb48ccf1bf9ad4c8f321c7342db43c4019 (patch) | |
tree | 3575268ef66e0490cde203d5162a31002fb7ed64 /sw | |
parent | 8d51397bfd98615e74e116582a50e29846ecb76e (diff) |
GSoC Table Styles, CellStyle
- insertByName
- replaceByName
- removeByName
Change-Id: I964aa0dc2e7f5a5be9eaec719b8944e847eb9d6a
Reviewed-on: https://gerrit.libreoffice.org/26037
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/inc/doc.hxx | 7 | ||||
-rw-r--r-- | sw/inc/tblafmt.hxx | 31 | ||||
-rw-r--r-- | sw/inc/unocoll.hxx | 1 | ||||
-rw-r--r-- | sw/inc/unostyle.hxx | 28 | ||||
-rw-r--r-- | sw/qa/python/check_styles.py | 4 | ||||
-rw-r--r-- | sw/source/core/doc/docnew.cxx | 1 | ||||
-rw-r--r-- | sw/source/core/doc/tblafmt.cxx | 86 | ||||
-rw-r--r-- | sw/source/core/unocore/unocoll.cxx | 7 | ||||
-rw-r--r-- | sw/source/core/unocore/unostyle.cxx | 316 | ||||
-rw-r--r-- | sw/source/uibase/app/docstyle.cxx | 34 |
10 files changed, 406 insertions, 109 deletions
diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx index e9b3be56b8dc..412b419edbb1 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 9e5f4a3be183..6ed138d72ec8 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 32979a958849..f853fe4360b9 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 8b7401a448cc..bac73cf0ddc1 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 c435663a6d9b..d2ea6a9b02af 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 a136c3576b4a..68734cff5298 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 95088b7aed76..6b18c2e6403b 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 50a4ec6859ef..2cbd5fe63075 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 b87dfe3f0ff6..ffc96191fd19 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 f91c3fc1c9e7..c25f853aa237 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()) |