Kaydet (Commit) 5e4d89f5 authored tarafından Justin Luth's avatar Justin Luth Kaydeden (comit) Miklos Vajna

tdf#117297 sw unotbl XCell: apply char/para style props to text

This is specifically for the benefit of DOCX import, but it
also makes sense in general. If a SwXCell is given char/para
properties, then apply those properties (without overwriting)
to the cell's contents.

This allows ANY paragraph or character properties that are applied
to a table style to become the "default" for the table.

This fixes a number of things:
-remove one-off hack to get PROP_PARA_LINE_SPACING to work.
-works for all character and paragraph properties (except those
shared with tables like borders).
-works in multi-paragraph cells. Previously those could return
AMBIGUOUS state, in which case the style wasn't applied at all.

Change-Id: Ia98c129879575c1aa8ca1fe2a64f4991c0a264e8
Reviewed-on: https://gerrit.libreoffice.org/54511Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarJustin Luth <justin_luth@sil.org>
Reviewed-by: 's avatarMiklos Vajna <vmiklos@collabora.co.uk>
üst a73ae323
......@@ -863,6 +863,53 @@ DECLARE_OOXMLEXPORT_TEST(testTableCellWithDirectFormatting, "fdo80800.docx")
}
DECLARE_OOXMLEXPORT_TEST(testFdo80800b_tableStyle, "fdo80800b_tableStyle.docx")
{
uno::Reference<text::XTextTable> xTable(getParagraphOrTable(1), uno::UNO_QUERY);
uno::Reference<text::XTextRange> xCell(xTable->getCellByName("A1"), uno::UNO_QUERY);
uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xCell->getText(), uno::UNO_QUERY);
uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
uno::Reference<text::XTextRange> xPara(xParaEnum->nextElement(), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(OUString("Cell1 1.5lines"), xPara->getString());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell A1 1.5 line spacing", sal_Int16(150), getProperty<style::LineSpacing>(xPara, "ParaLineSpacing").Height);
xCell.set(xTable->getCellByName("B1"), uno::UNO_QUERY);
xParaEnumAccess.set(xCell->getText(), uno::UNO_QUERY);
xParaEnum = xParaEnumAccess->createEnumeration();
xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(OUString("Cell2 Implicit (Single)"), xPara->getString());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell B1 single line spacing", sal_Int16(100), getProperty<style::LineSpacing>(xPara, "ParaLineSpacing").Height);
xCell.set(xTable->getCellByName("C1"), uno::UNO_QUERY);
xParaEnumAccess.set(xCell->getText(), uno::UNO_QUERY);
xParaEnum = xParaEnumAccess->createEnumeration();
xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(OUString("Cell3 Implicit (Single)"), xPara->getString());
CPPUNIT_ASSERT_EQUAL_MESSAGE("C1 paragraph1 single line spacing", sal_Int16(100), getProperty<style::LineSpacing>(xPara, "ParaLineSpacing").Height);
xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL_MESSAGE("C1 paragraph3 line spacing", sal_Int16(212), getProperty<style::LineSpacing>(xPara, "ParaLineSpacing").Height);
}
DECLARE_OOXMLEXPORT_TEST(testTdf117297_tableStyle, "tdf117297_tableStyle.docx")
{
uno::Reference<text::XTextTable> xTable(getParagraphOrTable(1), uno::UNO_QUERY);
uno::Reference<text::XTextRange> xCell(xTable->getCellByName("B1"), uno::UNO_QUERY);
uno::Reference<container::XEnumerationAccess> xParaEnumAccess(xCell->getText(), uno::UNO_QUERY);
uno::Reference<container::XEnumeration> xParaEnum = xParaEnumAccess->createEnumeration();
uno::Reference<text::XTextRange> xPara(xParaEnum->nextElement(), uno::UNO_QUERY);
uno::Reference<text::XText> xText(xPara->getText(), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(OUString("Green text, default size (9), 1.5 spaced"), xPara->getString());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell B1 Paragraph1 green font", sal_Int32(0x70AD47), getProperty<sal_Int32>(getRun(xPara, 1), "CharColor"));
CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell B1 Paragraph1 1.5 line spacing", sal_Int16(150), getProperty<style::LineSpacing>(xPara, "ParaLineSpacing").Height);
xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
xPara.set(xParaEnum->nextElement(), uno::UNO_QUERY);
xText.set(xPara->getText(), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(OUString("TableGrid color (blue), TableGrid size (9), double spacing"), xPara->getString());
CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell B1 Paragraph3 blue font", sal_Int32(0x00B0F0), getProperty<sal_Int32>(getRun(xPara, 1), "CharColor"));
CPPUNIT_ASSERT_EQUAL_MESSAGE("Cell B1 Paragraph3 double spacing", sal_Int16(200), getProperty<style::LineSpacing>(xPara, "ParaLineSpacing").Height);
}
DECLARE_OOXMLEXPORT_TEST(test2colHeader, "2col-header.docx")
{
// Header was lost on export when the document had multiple columns.
......
......@@ -45,6 +45,7 @@
#include <shellres.hxx>
#include <docary.hxx>
#include <ndole.hxx>
#include <ndtxt.hxx>
#include <frame.hxx>
#include <vcl/svapp.hxx>
#include <fmtfsize.hxx>
......@@ -1043,6 +1044,36 @@ void SwXCell::setPropertyValue(const OUString& rPropertyName, const uno::Any& aV
else
{
auto pEntry(m_pPropSet->getPropertyMap().getByName(rPropertyName));
if ( !pEntry )
{
// not a table property: if it is a paragraph/character property, consider applying it to the underlying text.
const SfxItemPropertySet& rParaPropSet = *aSwMapProvider.GetPropertySet(PROPERTY_MAP_PARAGRAPH);
pEntry = rParaPropSet.getPropertyMap().getByName(rPropertyName);
if ( pEntry )
{
SwNodeIndex aIdx( *GetStartNode(), 1 );
const SwNode* pEndNd = aIdx.GetNode().EndOfSectionNode();
while ( &aIdx.GetNode() != pEndNd )
{
const SwTextNode* pNd = aIdx.GetNode().GetTextNode();
if ( pNd )
{
//point and mark selecting the whole paragraph
SwPaM aPaM(*pNd, 0, *pNd, pNd->GetText().getLength());
const bool bHasAttrSet = pNd->HasSwAttrSet();
const SfxItemSet& aSet = pNd->GetSwAttrSet();
// isPARATR: replace DEFAULT_VALUE properties only
// isCHRATR: change the base/auto SwAttr property, but don't remove the DIRECT hints
if ( !bHasAttrSet || SfxItemState::DEFAULT == aSet.GetItemState(pEntry->nWID, /*bSrchInParent=*/false) )
SwUnoCursorHelper::SetPropertyValue(aPaM, rParaPropSet, rPropertyName, aValue, SetAttrMode::DONTREPLACE);
}
++aIdx;
}
return;
}
}
if(!pEntry)
throw beans::UnknownPropertyException(rPropertyName, static_cast<cppu::OWeakObject*>(this));
if(pEntry->nWID != FN_UNO_CELL_ROW_SPAN)
......
......@@ -2037,32 +2037,10 @@ lcl_ApplyCellProperties(
{
xCellPS->setPropertyValue(rName, rValue);
}
catch (const uno::Exception&)
catch (const uno::Exception& e)
{
// Apply the paragraph and char properties to the cell's content
const uno::Reference< text::XText > xCellText(xCell,
uno::UNO_QUERY);
const uno::Reference< text::XTextCursor > xCellCurs =
xCellText->createTextCursor();
xCellCurs->gotoStart( false );
xCellCurs->gotoEnd( true );
const uno::Reference< beans::XPropertyState >
xCellTextPropState(xCellCurs, uno::UNO_QUERY);
try
{
const beans::PropertyState state = xCellTextPropState->getPropertyState(rName);
if (state == beans::PropertyState_DEFAULT_VALUE)
{
const uno::Reference< beans::XPropertySet >
xCellTextProps(xCellCurs, uno::UNO_QUERY);
xCellTextProps->setPropertyValue(rName, rValue);
}
}
catch (const uno::Exception& e)
{
SAL_WARN( "sw.uno", "Exception when getting PropertyState: "
SAL_WARN( "sw.uno", "Exception when getting PropertyState: "
+ rName + ". Message: " + e.Message );
}
}
}
}
......
......@@ -451,14 +451,6 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
aSpacing.Height = sal_Int16(nIntValue * 100 / nSingleLineSpacing );
else
aSpacing.Height = sal_Int16(ConversionHelper::convertTwipToMM100( nIntValue ));
if (m_pImpl->hasTableManager() && m_pImpl->getTableManager().isInCell())
{
// direct formatting is applied for table cell data
TablePropertyMapPtr pTblCellWithDirectFormatting(new TablePropertyMap);
pTblCellWithDirectFormatting->Insert(PROP_PARA_LINE_SPACING, uno::makeAny( aSpacing ), false);
m_pImpl->getTableManager().cellProps(pTblCellWithDirectFormatting);
}
}
else //NS_ooxml::LN_CT_Spacing_lineRule:
{
......@@ -490,16 +482,6 @@ void DomainMapper::lcl_attribute(Id nName, Value & val)
m_pImpl->appendGrabBag(m_pImpl->m_aSubInteropGrabBag, "lineRule", "exact");
aSpacing.Mode = style::LineSpacingMode::FIX;
}
if (m_pImpl->hasTableManager() && m_pImpl->getTableManager().isInCell())
{
// If the table manager got the line rule after
// ooxml::CT_Spacing_line, then it should get the rule
// after lineRule as well.
TablePropertyMapPtr pTblCellWithDirectFormatting(new TablePropertyMap);
pTblCellWithDirectFormatting->Insert(PROP_PARA_LINE_SPACING, uno::makeAny(aSpacing), false);
m_pImpl->getTableManager().cellProps(pTblCellWithDirectFormatting);
}
}
if (pTopContext)
pTopContext->Insert(PROP_PARA_LINE_SPACING, uno::makeAny( aSpacing ));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment