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 <[email protected]> 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 <[email protected]> Reviewed-by: Miklos Vajna <[email protected]> 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()) _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
