Skip to content

Commit

Permalink
tdf#145226 sw: ODF export: fix table-row/table-cell styles
Browse files Browse the repository at this point in the history
The SwFrameFormat for table lines and table boxes gets an auto-generated
name in SwDoc::MakeTableBoxFormat()/MakeTableLineFormat().

The problem is that xmltble.cxx assumes that these SwFrameFormats never
have a name, and sets names on them temporarily during
exportTextAutoStyles(), then later reads them when exporting the
table-rows and table-cells, then eventually resets them all to an empty
name.

One issue is that it assumes that a non-empty SwFrameFormat name
indicates a style has been exported, but that isn't always the case, and
the name may still be an auto-generated one.

Another issue is that overwriting the names interferes with the use of
the names in Undo operations.

So store the name for the ODF styles in members of the filter classes
instead of the core model.

(regression from commit 083fe09)

Change-Id: I9b17962decbf9f8ecd2a91551230cf0f012e7a9d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/127548
Tested-by: Jenkins
Reviewed-by: Michael Stahl <[email protected]>
  • Loading branch information
mistmist committed Jul 31, 2022
1 parent 80cdfe4 commit 5a9fe1d
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 78 deletions.
4 changes: 3 additions & 1 deletion sw/source/filter/xml/xmlexp.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "xmlitmap.hxx"
#include <xmloff/xmltoken.hxx>

#include <optional>
#include <string_view>
#include <vector>

Expand Down Expand Up @@ -75,7 +76,8 @@ class SwXMLExport : public SvXMLExport
SwXMLTableInfo_Impl& rTableInfo,
bool bTop=false );

void ExportFormat( const SwFormat& rFormat, enum ::xmloff::token::XMLTokenEnum eClass );
void ExportFormat(const SwFormat& rFormat, enum ::xmloff::token::XMLTokenEnum eClass,
::std::optional<OUString> const oStyleName);
void ExportTableFormat( const SwFrameFormat& rFormat, sal_uInt32 nAbsWidth );

void ExportTableColumnStyle( const SwXMLTableColumn_Impl& rCol );
Expand Down
6 changes: 4 additions & 2 deletions sw/source/filter/xml/xmlfmte.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ using namespace ::com::sun::star::drawing;
using namespace ::com::sun::star::lang;
using namespace ::xmloff::token;

void SwXMLExport::ExportFormat( const SwFormat& rFormat, enum XMLTokenEnum eFamily )
void SwXMLExport::ExportFormat(const SwFormat& rFormat, enum XMLTokenEnum eFamily,
::std::optional<OUString> const oStyleName)
{
// <style:style ...>
CheckAttrList();
Expand All @@ -57,9 +58,10 @@ void SwXMLExport::ExportFormat( const SwFormat& rFormat, enum XMLTokenEnum eFami
return;
OSL_ENSURE( eFamily != XML_TOKEN_INVALID, "family must be specified" );
// style:name="..."
assert(oStyleName || (eFamily != XML_TABLE_ROW && eFamily != XML_TABLE_CELL));
bool bEncoded = false;
AddAttribute( XML_NAMESPACE_STYLE, XML_NAME, EncodeStyleName(
rFormat.GetName(), &bEncoded ) );
oStyleName ? *oStyleName : rFormat.GetName(), &bEncoded) );
if( bEncoded )
AddAttribute( XML_NAMESPACE_STYLE, XML_DISPLAY_NAME, rFormat.GetName() );

Expand Down
2 changes: 1 addition & 1 deletion sw/source/filter/xml/xmliteme.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ void SwXMLExport::ExportTableFormat( const SwFrameFormat& rFormat, sal_uInt32 nA
{
static_cast<SwXMLTableItemMapper_Impl *>(m_pTableItemMapper.get())
->SetAbsWidth( nAbsWidth );
ExportFormat( rFormat, XML_TABLE );
ExportFormat(rFormat, XML_TABLE, {});
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
157 changes: 83 additions & 74 deletions sw/source/filter/xml/xmltble.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -185,13 +185,18 @@ class SwXMLTableFrameFormatsSort_Impl
{
private:
SwXMLFrameFormats_Impl m_aFormatList;
SwXMLTextParagraphExport::FormatMap & m_rFormatMap;

public:
bool AddRow( SwFrameFormat& rFrameFormat, std::u16string_view rNamePrefix, sal_uInt32 nLine );
bool AddCell( SwFrameFormat& rFrameFormat, std::u16string_view rNamePrefix,
SwXMLTableFrameFormatsSort_Impl(SwXMLTextParagraphExport::FormatMap & rFormatMap)
: m_rFormatMap(rFormatMap)
{}
::std::optional<OUString> AddRow(SwFrameFormat& rFrameFormat, std::u16string_view rNamePrefix, sal_uInt32 nLine );
::std::optional<OUString> AddCell(SwFrameFormat& rFrameFormat, std::u16string_view rNamePrefix,
sal_uInt32 nCol, sal_uInt32 nRow, bool bTop );
};

bool SwXMLTableFrameFormatsSort_Impl::AddRow( SwFrameFormat& rFrameFormat,
::std::optional<OUString> SwXMLTableFrameFormatsSort_Impl::AddRow(SwFrameFormat& rFrameFormat,
std::u16string_view rNamePrefix,
sal_uInt32 nLine )
{
Expand All @@ -204,10 +209,12 @@ bool SwXMLTableFrameFormatsSort_Impl::AddRow( SwFrameFormat& rFrameFormat,

// empty styles have not to be exported
if( !pFrameSize && !pBrush && !pRowSplit && !pHasTextChangesOnly )
return false;
{
m_rFormatMap.emplace(&rFrameFormat, ::std::optional<OUString>()); // empty just to enable assert
return {};
}

// order is: -/brush, size/-, size/brush
bool bInsert = true;
SwXMLFrameFormats_Impl::iterator i;
for( i = m_aFormatList.begin(); i < m_aFormatList.end(); ++i )
{
Expand Down Expand Up @@ -284,19 +291,19 @@ bool SwXMLTableFrameFormatsSort_Impl::AddRow( SwFrameFormat& rFrameFormat,
continue;

// found!
rFrameFormat.SetName( pTestFormat->GetName() );
bInsert = false;
break;
auto const oName(m_rFormatMap.find(pTestFormat)->second);
assert(oName);
m_rFormatMap.emplace(&rFrameFormat, oName);
return {};
}

if( bInsert )
{
rFrameFormat.SetName( OUString::Concat(rNamePrefix) + "." + OUString::number(nLine+1) );
OUString const name(OUString::Concat(rNamePrefix) + "." + OUString::number(nLine+1));
m_rFormatMap.emplace(&rFrameFormat, ::std::optional<OUString>(name));
if ( i != m_aFormatList.end() ) ++i;
m_aFormatList.insert( i, &rFrameFormat );
return ::std::optional<OUString>(name);
}

return bInsert;
}

static OUString lcl_xmltble_appendBoxPrefix(std::u16string_view rNamePrefix,
Expand All @@ -313,7 +320,7 @@ static OUString lcl_xmltble_appendBoxPrefix(std::u16string_view rNamePrefix,
+ "." + OUString::number(nRow + 1);
}

bool SwXMLTableFrameFormatsSort_Impl::AddCell( SwFrameFormat& rFrameFormat,
::std::optional<OUString> SwXMLTableFrameFormatsSort_Impl::AddCell(SwFrameFormat& rFrameFormat,
std::u16string_view rNamePrefix,
sal_uInt32 nCol, sal_uInt32 nRow, bool bTop )
{
Expand All @@ -330,15 +337,17 @@ bool SwXMLTableFrameFormatsSort_Impl::AddCell( SwFrameFormat& rFrameFormat,

// empty styles have not to be exported
if( !pVertOrient && !pBrush && !pBox && !pNumFormat && !pFrameDir && !pAttCnt )
return false;
{
m_rFormatMap.emplace(&rFrameFormat, ::std::optional<OUString>()); // empty just to enable assert
return {};
}

// order is: -/-/-/num,
// -/-/box/-, -/-/box/num,
// -/brush/-/-, -/brush/-/num, -/brush/box/-, -/brush/box/num,
// vert/-/-/-, vert/-/-/num, vert/-/box/-, ver/-/box/num,
// vert/brush/-/-, vert/brush/-/num, vert/brush/box/-,
// vert/brush/box/num
bool bInsert = true;
SwXMLFrameFormats_Impl::iterator i;
for( i = m_aFormatList.begin(); i < m_aFormatList.end(); ++i )
{
Expand Down Expand Up @@ -454,19 +463,19 @@ bool SwXMLTableFrameFormatsSort_Impl::AddCell( SwFrameFormat& rFrameFormat,
continue;

// found!
rFrameFormat.SetName( pTestFormat->GetName() );
bInsert = false;
break;
auto const oName(m_rFormatMap.find(pTestFormat)->second);
assert(oName);
m_rFormatMap.emplace(&rFrameFormat, oName);
return {};
}

if( bInsert )
{
rFrameFormat.SetName( lcl_xmltble_appendBoxPrefix( rNamePrefix, nCol, nRow, bTop ) );
OUString const name(lcl_xmltble_appendBoxPrefix(rNamePrefix, nCol, nRow, bTop));
m_rFormatMap.emplace(&rFrameFormat, ::std::optional<OUString>(name));
if ( i != m_aFormatList.end() ) ++i;
m_aFormatList.insert( i, &rFrameFormat );
return ::std::optional<OUString>(name);
}

return bInsert;
}

class SwXMLTableInfo_Impl
Expand All @@ -475,10 +484,21 @@ class SwXMLTableInfo_Impl
Reference<XTextSection> m_xBaseSection;
bool m_bBaseSectionValid;
sal_uInt32 m_nPrefix;
SwXMLTextParagraphExport::FormatMap const& m_rLineFormats;
SwXMLTextParagraphExport::FormatMap const& m_rBoxFormats;

public:

inline SwXMLTableInfo_Impl( const SwTable *pTable, sal_uInt16 nPrefix );
inline SwXMLTableInfo_Impl( const SwTable *pTable, sal_uInt16 nPrefix,
SwXMLTextParagraphExport::FormatMap const& rLineFormats,
SwXMLTextParagraphExport::FormatMap const& rBoxFormats)
: m_pTable(pTable)
, m_bBaseSectionValid(false)
, m_nPrefix(nPrefix)
, m_rLineFormats(rLineFormats)
, m_rBoxFormats(rBoxFormats)
{
}

const SwTable *GetTable() const { return m_pTable; }
const SwFrameFormat *GetTableFormat() const { return m_pTable->GetFrameFormat(); }
Expand All @@ -488,15 +508,10 @@ class SwXMLTableInfo_Impl
inline void SetBaseSection( const Reference < XTextSection >& rBase );
/// The namespace (table or loext) that should be used for the elements.
sal_uInt16 GetPrefix() const { return m_nPrefix; }
SwXMLTextParagraphExport::FormatMap const& GetLineFormats() const { return m_rLineFormats; }
SwXMLTextParagraphExport::FormatMap const& GetBoxFormats() const { return m_rBoxFormats; }
};

inline SwXMLTableInfo_Impl::SwXMLTableInfo_Impl(const SwTable *pTable, sal_uInt16 nPrefix) :
m_pTable(pTable),
m_bBaseSectionValid(false),
m_nPrefix(nPrefix)
{
}

inline void SwXMLTableInfo_Impl::SetBaseSection(
const Reference < XTextSection >& rBaseSection )
{
Expand Down Expand Up @@ -631,8 +646,10 @@ void SwXMLExport::ExportTableLinesAutoStyles( const SwTableLines& rLines,
SwTableLine *pLine = rLines[nLine];

SwFrameFormat *pFrameFormat = pLine->GetFrameFormat();
if( rExpRows.AddRow( *pFrameFormat, rNamePrefix, nLine ) )
ExportFormat( *pFrameFormat, XML_TABLE_ROW );
if (auto oNew = rExpRows.AddRow(*pFrameFormat, rNamePrefix, nLine))
{
ExportFormat(*pFrameFormat, XML_TABLE_ROW, oNew);
}

const SwTableBoxes& rBoxes = pLine->GetTabBoxes();
const size_t nBoxes = rBoxes.size();
Expand All @@ -659,9 +676,11 @@ void SwXMLExport::ExportTableLinesAutoStyles( const SwTableLines& rLines,
if( pBoxSttNd )
{
SwFrameFormat *pFrameFormat2 = pBox->GetFrameFormat();
if( rExpCells.AddCell( *pFrameFormat2, rNamePrefix, nOldCol, nLine,
if (auto oNew = rExpCells.AddCell(*pFrameFormat2, rNamePrefix, nOldCol, nLine,
bTop) )
ExportFormat( *pFrameFormat2, XML_TABLE_CELL );
{
ExportFormat(*pFrameFormat2, XML_TABLE_CELL, oNew);
}

Reference < XCell > xCell = SwXCell::CreateXCell(
const_cast<SwFrameFormat *>(rTableInfo.GetTableFormat()),
Expand Down Expand Up @@ -707,8 +726,13 @@ void SwXMLExport::ExportTableLinesAutoStyles( const SwTableLines& rLines,
}
}

void SwXMLExport::ExportTableAutoStyles( const SwTableNode& rTableNd )
void SwXMLExport::ExportTableAutoStyles(const SwTableNode& rTableNd)
{
auto & rFormats(static_cast<SwXMLTextParagraphExport *>(GetTextParagraphExport().get())->GetTableFormats());
auto const it(rFormats.find(&rTableNd));
assert(it != rFormats.end());
SwXMLTextParagraphExport::FormatMap & rRowFormats(it->second.first);
SwXMLTextParagraphExport::FormatMap & rBoxFormats(it->second.second);
const SwTable& rTable = rTableNd.GetTable();
const SwFrameFormat *pTableFormat = rTable.GetFrameFormat();

Expand Down Expand Up @@ -736,9 +760,9 @@ void SwXMLExport::ExportTableAutoStyles( const SwTableNode& rTableNd )
ExportTableFormat( *pTableFormat, nAbsWidth );

SwXMLTableColumnsSortByWidth_Impl aExpCols;
SwXMLTableFrameFormatsSort_Impl aExpRows;
SwXMLTableFrameFormatsSort_Impl aExpCells;
SwXMLTableInfo_Impl aTableInfo( &rTable, XML_NAMESPACE_TABLE );
SwXMLTableFrameFormatsSort_Impl aExpRows(rRowFormats);
SwXMLTableFrameFormatsSort_Impl aExpCells(rBoxFormats);
SwXMLTableInfo_Impl aTableInfo(&rTable, XML_NAMESPACE_TABLE, rRowFormats, rBoxFormats);
ExportTableLinesAutoStyles( rTable.GetTabLines(), nAbsWidth, nBaseWidth,
pTableFormat->GetName(), aExpCols, aExpRows, aExpCells,
aTableInfo, true);
Expand All @@ -756,10 +780,12 @@ void SwXMLExport::ExportTableBox( const SwTableBox& rBox,
const SwFrameFormat *pFrameFormat = rBox.GetFrameFormat();
if( pFrameFormat )
{
const OUString& sName = pFrameFormat->GetName();
if( !sName.isEmpty() )
auto const it(rTableInfo.GetBoxFormats().find(pFrameFormat));
assert(it != rTableInfo.GetBoxFormats().end());
if (it->second)
{
AddAttribute( XML_NAMESPACE_TABLE, XML_STYLE_NAME, EncodeStyleName(sName) );
assert(!it->second->isEmpty());
AddAttribute(XML_NAMESPACE_TABLE, XML_STYLE_NAME, EncodeStyleName(*it->second));
}
}
}
Expand Down Expand Up @@ -889,10 +915,12 @@ void SwXMLExport::ExportTableLine( const SwTableLine& rLine,
const SwFrameFormat *pFrameFormat = rLine.GetFrameFormat();
if( pFrameFormat )
{
const OUString& sName = pFrameFormat->GetName();
if( !sName.isEmpty() )
auto const it(rTableInfo.GetLineFormats().find(pFrameFormat));
assert(it != rTableInfo.GetLineFormats().end());
if (it->second)
{
AddAttribute( XML_NAMESPACE_TABLE, XML_STYLE_NAME, EncodeStyleName(sName) );
assert(!it->second->isEmpty());
AddAttribute(XML_NAMESPACE_TABLE, XML_STYLE_NAME, EncodeStyleName(*it->second));
}
}

Expand All @@ -915,10 +943,12 @@ void SwXMLExport::ExportTableLine( const SwTableLine& rLine,
const SwFrameFormat* pFormat = pBox->GetFrameFormat();
if (pFormat)
{
const OUString& sName = pFormat->GetName();
if (!sName.isEmpty())
auto const it(rTableInfo.GetBoxFormats().find(pFormat));
assert(it != rTableInfo.GetBoxFormats().end());
if (it->second)
{
AddAttribute(XML_NAMESPACE_TABLE, XML_STYLE_NAME, EncodeStyleName(sName));
assert(!it->second->isEmpty());
AddAttribute(XML_NAMESPACE_TABLE, XML_STYLE_NAME, EncodeStyleName(*it->second));
}
}

Expand Down Expand Up @@ -1055,29 +1085,6 @@ void SwXMLExport::ExportTableLines( const SwTableLines& rLines,
delete pLines;
}

static void lcl_xmltble_ClearName_Line( SwTableLine* pLine );

static void lcl_xmltble_ClearName_Box( SwTableBox* pBox )
{
if( !pBox->GetSttNd() )
{
for( SwTableLine* pLine : pBox->GetTabLines() )
lcl_xmltble_ClearName_Line( pLine );
}
else
{
SwFrameFormat *pFrameFormat = pBox->GetFrameFormat();
if( pFrameFormat && !pFrameFormat->GetName().isEmpty() )
pFrameFormat->SetName( OUString() );
}
}

void lcl_xmltble_ClearName_Line( SwTableLine* pLine )
{
for( SwTableBox* pBox : pLine->GetTabBoxes() )
lcl_xmltble_ClearName_Box( pBox );
}

void SwXMLExport::ExportTable( const SwTableNode& rTableNd )
{
::std::optional<sal_uInt16> oPrefix = XML_NAMESPACE_TABLE;
Expand Down Expand Up @@ -1151,14 +1158,15 @@ void SwXMLExport::ExportTable( const SwTableNode& rTableNd )
XML_DDE_SOURCE, true, false);
}

SwXMLTableInfo_Impl aTableInfo(&rTable, *oPrefix);
auto const& rFormats(static_cast<SwXMLTextParagraphExport const*>(GetTextParagraphExport().get())->GetTableFormats());
auto const it(rFormats.find(&rTableNd));
assert(it != rFormats.end());
SwXMLTableInfo_Impl aTableInfo(&rTable, *oPrefix, it->second.first, it->second.second);
ExportTableLines( rTable.GetTabLines(), aTableInfo, rTable.GetRowsToRepeat() );

for( SwTableLine *pLine : const_cast<SwTable &>(rTable).GetTabLines() )
lcl_xmltble_ClearName_Line( pLine );
}

void SwXMLTextParagraphExport::exportTableAutoStyles() {
// note: maTableNodes is used here only to keep the iteration order as before
for (const auto* pTableNode : maTableNodes)
{
static_cast<SwXMLExport&>(GetExport()).ExportTableAutoStyles(*pTableNode);
Expand Down Expand Up @@ -1199,6 +1207,7 @@ void SwXMLTextParagraphExport::exportTable(
&& (bExportStyles || !pFormat->GetDoc()->IsInHeaderFooter(aIdx)))
{
maTableNodes.push_back(pTableNd);
m_TableFormats.emplace(pTableNd, ::std::make_pair(SwXMLTextParagraphExport::FormatMap(), SwXMLTextParagraphExport::FormatMap()));
// Collect all tables inside cells of this table, too
const auto aCellNames = pXTable->getCellNames();
for (const OUString& rCellName : aCellNames)
Expand Down
Loading

0 comments on commit 5a9fe1d

Please sign in to comment.