GSoC Table Style Family: insertByName, replaceByName, removeByName
- also implements SwXTextTableStyle::replaceByName
- some refactorization
+ use std::unique_ptr
- fixes some bugs:
+ posible nullptr dereference in tblafmt.cxx
+ SwXTextTableStyle::getName() returned translated name
+ remvoed unnecesary SetXObject in Cell Style Family replacebyName
- tests
Change-Id: Idd25d54695ab5a4bdd4daf7ebf37b05fbc2366e7
Reviewed-on: https://gerrit.libreoffice.org/26578
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
diff --git a/sw/inc/tblafmt.hxx b/sw/inc/tblafmt.hxx
index fc698ef..0eb799a 100644
--- a/sw/inc/tblafmt.hxx
+++ b/sw/inc/tblafmt.hxx
@@ -343,6 +343,7 @@ public:
void InsertAutoFormat(size_t i, std::unique_ptr<SwTableAutoFormat> pFormat);
void EraseAutoFormat(size_t i);
void EraseAutoFormat(const OUString& rName);
std::unique_ptr<SwTableAutoFormat> ReleaseAutoFormat(size_t i);
/// Find table style with the provided name, return nullptr when not found.
diff --git a/sw/inc/unostyle.hxx b/sw/inc/unostyle.hxx
index 07311e8..cc24073 100644
--- a/sw/inc/unostyle.hxx
+++ b/sw/inc/unostyle.hxx
@@ -254,12 +254,16 @@ class SwXTextTableStyle : public cppu::WeakImplHelper
<
css::style::XStyle,
css::beans::XPropertySet,
css::container::XNameAccess,
css::container::XNameContainer,
css::lang::XServiceInfo
>
{
SwDocShell* m_pDocShell;
OUString m_sTableAutoFormatName;
SwTableAutoFormat* m_pTableAutoFormat;
/// Stores SwTableAutoFormat when this is not a physical style.
std::unique_ptr<SwTableAutoFormat> m_pTableAutoFormat_Impl;
/// If true, then it points to a core object, if false, then this is a created, but not-yet-inserted format.
bool m_bPhysical;
enum {
FIRST_ROW_STYLE = 0,
@@ -282,12 +286,21 @@ class SwXTextTableStyle : public cppu::WeakImplHelper
STYLE_COUNT
};
SwTableAutoFormat* GetTableAutoFormat();
/// Fills m_aCellStyles with SwXTextCellStyles pointing to children of this style.
void UpdateCellStylesMapping();
static const CellStyleNameMap& GetCellStyleNameMap();
css::uno::Reference<css::style::XStyle> m_aCellStyles[STYLE_COUNT];
public:
SwXTextTableStyle(SwDocShell* pDocShell, SwTableAutoFormat* pTableAutoFormat);
/// Create non physical style
SwXTextTableStyle(SwDocShell* pDocShell, const OUString& rTableAutoFormatName);
/// This function looks for a SwTableAutoFormat with given name. Returns nullptr if could not be found.
static SwTableAutoFormat* GetTableAutoFormat(SwDocShell* pDocShell, const OUString& sName);
/// Returns box format assigned to this style
SwTableAutoFormat* GetTableFormat();
void SetPhysical();
//XStyle
virtual sal_Bool SAL_CALL isUserDefined() throw (css::uno::RuntimeException, std::exception) override;
virtual sal_Bool SAL_CALL isInUse() throw (css::uno::RuntimeException, std::exception) override;
@@ -312,6 +325,11 @@ public:
virtual css::uno::Sequence<OUString> SAL_CALL getElementNames() throw(css::uno::RuntimeException, std::exception) override;
virtual sal_Bool SAL_CALL hasByName(const OUString& rName) throw(css::uno::RuntimeException, std::exception) override;
//XNameContainer
virtual void SAL_CALL insertByName(const OUString& rName, const css::uno::Any& aElement) throw(css::lang::IllegalArgumentException, css::container::ElementExistException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) override;
virtual void SAL_CALL replaceByName(const OUString& rName, const css::uno::Any& aElement) throw(css::lang::IllegalArgumentException, css::container::NoSuchElementException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) override;
virtual void SAL_CALL removeByName(const OUString& rName) throw(css::container::NoSuchElementException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) override;
//XElementAccess
virtual css::uno::Type SAL_CALL getElementType() throw(css::uno::RuntimeException, std::exception) override;
virtual sal_Bool SAL_CALL hasElements() throw(css::uno::RuntimeException, std::exception) override;
@@ -335,15 +353,17 @@ class SwXTextCellStyle : public cppu::WeakImplHelper
{
SwDocShell* m_pDocShell;
SwBoxAutoFormat* m_pBoxAutoFormat;
OUString m_sParentStyle; // used when style is physical
OUString m_sName; // used when style is not physical
bool m_bPhysical; // delete a m_pBoxAutoFormat when changing from false to true!
/// Stores SwBoxAutoFormat when this is not a physical style.
std::shared_ptr<SwBoxAutoFormat> m_pBoxAutoFormat_Impl;
OUString m_sParentStyle;
OUString m_sName;
/// If true, then it points to a core object, if false, then this is a created, but not-yet-inserted format.
bool m_bPhysical;
public:
SwXTextCellStyle(SwDocShell* pDocShell, SwBoxAutoFormat* pBoxAutoFormat, const OUString& sParentStyle);
/// Create non physical style
SwXTextCellStyle(SwDocShell* pDocShell, const OUString& sName);
virtual ~SwXTextCellStyle();
/**
* This function looks for a SwBoxAutoFormat with given name. Parses the name and returns parent name.
@@ -355,7 +375,10 @@ class SwXTextCellStyle : public cppu::WeakImplHelper
static SwBoxAutoFormat* GetBoxAutoFormat(SwDocShell* pDocShell, const OUString& sName, OUString* pParentName = nullptr);
/// returns box format assigned to this style
SwBoxAutoFormat* GetBoxFormat();
/// Sets the addres of SwBoxAutoFormat this style is bound to. Usable only when style is physical.
void SetBoxFormat(SwBoxAutoFormat* pBoxFormat);
void SetPhysical();
bool IsPhysical();
//XStyle
virtual sal_Bool SAL_CALL isUserDefined() throw (css::uno::RuntimeException, std::exception) override;
diff --git a/sw/qa/python/check_styles.py b/sw/qa/python/check_styles.py
index 144082a..372455e 100644
--- a/sw/qa/python/check_styles.py
+++ b/sw/qa/python/check_styles.py
@@ -171,6 +171,7 @@ class CheckStyle(unittest.TestCase):
vEmptyDocStyles = ['Default Style']
self.__test_StyleFamily(xTableStyles, vEmptyDocStyles, "SwXTextTableStyle")
self.__test_StyleFamilyIndex(xTableStyles, vEmptyDocStyles, "SwXTextTableStyle")
self.__test_StyleFamilyInsert(xDoc, xTableStyles, vEmptyDocStyles, "com.sun.star.style.TableStyle", "com.sun.star.style.CharacterStyle")
for sStyleName in vEmptyDocStyles:
self.assertIsNotNone(xTableStyles.getByName(sStyleName))
#check SwXTextCellStyles
@@ -184,7 +185,6 @@ class CheckStyle(unittest.TestCase):
xDoc.dispose()
def test_tableStyleIsInUse(self):
# extend when TableStyle insertByName comes
xDoc = CheckStyle._uno.openEmptyWriterDoc()
xBodyText = xDoc.getText()
xCursor = xBodyText.createTextCursor()
@@ -201,6 +201,14 @@ class CheckStyle(unittest.TestCase):
xTable.setPropertyValue("TableTemplateName", "")
self.assertFalse(xDefaultTableStyle.isInUse())
self.assertFalse(xDefaultCellStyle.isInUse())
xTableStyle = xDoc.createInstance("com.sun.star.style.TableStyle")
self.assertFalse(xTableStyle.isInUse())
xDoc.StyleFamilies.getByName("TableStyles").insertByName("Test Table Style", xTableStyle)
self.assertFalse(xTableStyle.isInUse())
xTable.setPropertyValue("TableTemplateName", "Test Table Style")
self.assertTrue(xTableStyle.isInUse())
xTable.setPropertyValue("TableTemplateName", "")
self.assertFalse(xTableStyle.isInUse())
xDoc.dispose()
def test_CellFamily(self):
@@ -210,7 +218,25 @@ class CheckStyle(unittest.TestCase):
self.__test_StyleFamily(xCellStyles, vEmptyDocStyles, "SwXTextCellStyle")
self.__test_StyleFamilyIndex(xCellStyles, vEmptyDocStyles, "SwXTextCellStyle")
self.__test_StyleFamilyInsert(xDoc, xCellStyles, vEmptyDocStyles, "com.sun.star.style.CellStyle", "com.sun.star.style.CharacterStyle")
#add more tests when TableStyles will support insertByName
xTableStyle = xDoc.createInstance("com.sun.star.style.TableStyle")
xCellStyle = xTableStyle.getByName("first-row")
xDoc.StyleFamilies.getByName("TableStyles").insertByName("Test Table Style", xTableStyle)
self.assertEqual(xTableStyle.getByName("first-row"), xCellStyle)
self.assertEqual(xTableStyle.getByName("first-row"), xDoc.StyleFamilies.getByName("TableStyles").getByName("Test Table Style").getByName("first-row"))
#replaceByName
with self.assertRaises(NoSuchElementException):
xTableStyle.replaceByName("foobarbaz", xCellStyle)
xCellStyle = xDoc.createInstance("com.sun.star.style.CellStyle")
with self.assertRaises(IllegalArgumentException): #replace with not inserted cell style
xTableStyle.replaceByName("first-row", xCellStyle)
xTableStyle2 = xDoc.createInstance("com.sun.star.style.TableStyle")
with self.assertRaises(IllegalArgumentException): #replace with other family style
xTableStyle.replaceByName("first-row", xTableStyle2)
with self.assertRaises(IllegalArgumentException): #replace with already assigned cell style
xTableStyle.replaceByName("first-row", xTableStyle2.getByName("first-row"))
xDoc.StyleFamilies.getByName("CellStyles").insertByName("Test Cell Style", xCellStyle)
xTableStyle.replaceByName("first-row", xCellStyle)
self.assertEqual(xTableStyle.getByName("first-row"), xCellStyle)
xDoc.dispose()
if __name__ == '__main__':
diff --git a/sw/source/core/doc/tblafmt.cxx b/sw/source/core/doc/tblafmt.cxx
index 481f65f..66202a1 100644
--- a/sw/source/core/doc/tblafmt.cxx
+++ b/sw/source/core/doc/tblafmt.cxx
@@ -930,20 +930,19 @@ void SwTableAutoFormat::StoreTableProperties(const SwTable &table)
bool SwTableAutoFormat::FirstRowEndColumnIsRow()
{
return *aBoxAutoFormat[3] == *aBoxAutoFormat[2];
return GetBoxFormat(3) == GetBoxFormat(2);
}
bool SwTableAutoFormat::FirstRowStartColumnIsRow()
{
return *aBoxAutoFormat[0] == *aBoxAutoFormat[1];
return GetBoxFormat(0) == GetBoxFormat(1);
}
bool SwTableAutoFormat::LastRowEndColumnIsRow()
{
return *aBoxAutoFormat[15] == *aBoxAutoFormat[14];
return GetBoxFormat(14) == GetBoxFormat(15);
}
bool SwTableAutoFormat::LastRowStartColumnIsRow()
{
return *aBoxAutoFormat[12] == *aBoxAutoFormat[13];
return GetBoxFormat(12) == GetBoxFormat(13);
}
bool SwTableAutoFormat::Load( SvStream& rStream, const SwAfVersions& rVersions )
@@ -1156,6 +1155,20 @@ void SwTableAutoFormatTable::EraseAutoFormat(size_t const i)
m_pImpl->m_AutoFormats.erase(m_pImpl->m_AutoFormats.begin() + i);
}
void SwTableAutoFormatTable::EraseAutoFormat(const OUString& rName)
{
for (auto iter = m_pImpl->m_AutoFormats.begin();
iter != m_pImpl->m_AutoFormats.end(); ++iter)
{
if ((*iter)->GetName() == rName)
{
m_pImpl->m_AutoFormats.erase(iter);
return;
}
}
SAL_INFO("sw.core", "SwTableAutoFormatTable::EraseAutoFormat, SwTableAutoFormat with given name not found");
}
std::unique_ptr<SwTableAutoFormat> SwTableAutoFormatTable::ReleaseAutoFormat(size_t const i)
{
auto const iter(m_pImpl->m_AutoFormats.begin() + i);
@@ -1406,11 +1419,12 @@ void SwCellStyleTable::AddBoxFormat(const SwBoxAutoFormat& rBoxFormat, const OUS
void SwCellStyleTable::RemoveBoxFormat(const OUString& sName)
{
for (size_t i=0; i < m_aCellStyles.size(); ++i)
for (auto iter = m_aCellStyles.begin(); iter != m_aCellStyles.end(); ++iter)
{
if (m_aCellStyles[i].first == sName)
if (iter->first == sName)
{
m_aCellStyles.erase(m_aCellStyles.begin() + i);
delete iter->second;
m_aCellStyles.erase(iter);
return;
}
}
diff --git a/sw/source/core/unocore/unostyle.cxx b/sw/source/core/unocore/unostyle.cxx
index 4ea2f08..87e3c55 100644
--- a/sw/source/core/unocore/unostyle.cxx
+++ b/sw/source/core/unocore/unostyle.cxx
@@ -918,6 +918,18 @@ void XStyleFamily::insertByName(const OUString& rName, const uno::Any& rElement)
m_pDocShell->GetDoc()->GetCellStyles().AddBoxFormat(*pNewStyle->GetBoxFormat(), sStyleName);
pNewStyle->SetPhysical();
}
else if (nsSwGetPoolIdFromName::GET_POOLID_TABSTYLE == m_rEntry.m_aPoolId)
{
// handle table style
uno::Reference<style::XStyle> xStyle = rElement.get<uno::Reference<style::XStyle>>();
SwXTextTableStyle* pNewStyle = dynamic_cast<SwXTextTableStyle*>(xStyle.get());
if (!pNewStyle)
throw lang::IllegalArgumentException();
pNewStyle->setName(sStyleName); // insertByName sets the element name
m_pDocShell->GetDoc()->GetTableStyles().AddAutoFormat(*pNewStyle->GetTableFormat());
pNewStyle->SetPhysical();
}
else
{
uno::Reference<lang::XUnoTunnel> xStyleTunnel = rElement.get<uno::Reference<lang::XUnoTunnel>>();
@@ -974,14 +986,25 @@ void XStyleFamily::replaceByName(const OUString& rName, const uno::Any& rElement
if (!pStyleToReplaceWith)
throw lang::IllegalArgumentException();
// copy box style by value
*pBoxAutoFormat = *pStyleToReplaceWith->GetBoxFormat();
pStyleToReplaceWith->setName(rName);
*pBoxAutoFormat = *pStyleToReplaceWith->GetBoxFormat();
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 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();
}
}
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,20 +4701,20 @@ 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();
}
SwXTextCellStyle::~SwXTextCellStyle()
{
if (!m_bPhysical)
delete m_pBoxAutoFormat;
m_pBoxAutoFormat = m_pBoxAutoFormat_Impl.get();
}
SwBoxAutoFormat* SwXTextCellStyle::GetBoxFormat()
@@ -4619,15 +4722,23 @@ SwBoxAutoFormat* SwXTextCellStyle::GetBoxFormat()
return m_pBoxAutoFormat;
}
void SwXTextCellStyle::SetBoxFormat(SwBoxAutoFormat* pBoxFormat)
{
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())