22#include <com/sun/star/text/XTextTable.hpp>
51OString lcl_padStartToLength(OString
const& aString, sal_Int32 nLen,
char cFill)
53 if (nLen > aString.getLength())
55 sal_Int32 nDiff = nLen - aString.getLength();
59 return aBuffer.makeStringAndClear();
68sal_Int32 lcl_getWordCompatibilityMode(
const DocxExport& rDocExport)
75 if (nWordCompatibilityMode == -1 || 14 < nWordCompatibilityMode)
77 nWordCompatibilityMode = 14;
81 return nWordCompatibilityMode;
101 pAttributes->add(
FSNS(XML_w, XML_vertAnchor), sOrientation);
103 if (!sTblpYSpec.isEmpty())
104 pAttributes->add(
FSNS(XML_w, XML_tblpYSpec), sTblpYSpec);
108 pAttributes->add(
FSNS(XML_w, XML_horzAnchor), sOrientation);
110 if (!sTblpXSpec.isEmpty())
111 pAttributes->add(
FSNS(XML_w, XML_tblpXSpec), sTblpXSpec);
115 pAttributes->add(
FSNS(XML_w, XML_bottomFromText), OString::number(nValue));
119 pAttributes->add(
FSNS(XML_w, XML_leftFromText), OString::number(nValue));
123 pAttributes->add(
FSNS(XML_w, XML_rightFromText), OString::number(nValue));
127 pAttributes->add(
FSNS(XML_w, XML_topFromText), OString::number(nValue));
129 if (sTblpXSpec.isEmpty())
135 const SwTableBox* pTabBox = pTableTextNodeInfoInner->getTableBox();
138 sal_Int32 nMode = lcl_getWordCompatibilityMode(rExport);
141 sal_uInt16 nLeftDistance = rBox.
GetDistance(SvxBoxItemLine::LEFT);
153 pAttributes->add(
FSNS(XML_w, XML_tblpX), OString::number(nValue));
156 if (sTblpYSpec.isEmpty())
159 pAttributes->add(
FSNS(XML_w, XML_tblpY), OString::number(nValue));
181 static const sal_Int32 aOrder[] = {
FSNS(XML_w, XML_tblStyle),
182 FSNS(XML_w, XML_tblpPr),
183 FSNS(XML_w, XML_tblOverlap),
184 FSNS(XML_w, XML_bidiVisual),
185 FSNS(XML_w, XML_tblStyleRowBandSize),
186 FSNS(XML_w, XML_tblStyleColBandSize),
187 FSNS(XML_w, XML_tblW),
189 FSNS(XML_w, XML_tblCellSpacing),
190 FSNS(XML_w, XML_tblInd),
191 FSNS(XML_w, XML_tblBorders),
192 FSNS(XML_w, XML_shd),
193 FSNS(XML_w, XML_tblLayout),
194 FSNS(XML_w, XML_tblCellMar),
195 FSNS(XML_w, XML_tblLook),
196 FSNS(XML_w, XML_tblPrChange) };
204 const char* widthType =
"dxa";
207 const SwTable* pTable = pTableTextNodeInfoInner->getTable();
213 if (pFloatingTableFrame)
219 uno::Reference<beans::XPropertySet> xPropertySet(
221 bool isWidthRelative =
false;
222 xPropertySet->getPropertyValue(
"IsWidthRelative") >>= isWidthRelative;
223 if (!isWidthRelative && !nWidthPercent)
226 short nHoriOrient = -1;
227 xPropertySet->getPropertyValue(
"HoriOrient") >>= nHoriOrient;
228 isWidthRelative = nHoriOrient == text::HoriOrientation::FULL;
246 nPageSize = nWidthPercent * 50;
251 bool bRelBoxSize =
false;
259 m_pSerializer->singleElementNS(XML_w, XML_tblW,
FSNS(XML_w, XML_w), OString::number(nPageSize),
266 const std::map<OUString, css::uno::Any>& rGrabBag
271 std::map<SvxBoxItemLine, css::table::BorderLine2>& rTableStyleConf =
m_aTableStyleConfs.back();
272 rTableStyleConf.clear();
274 bool bFloatingTableWritten =
false;
278 CollectFloatingTableAttributes(
m_rExport, *pFloatingTableFrame, pTableTextNodeInfoInner,
280 m_pSerializer->singleElementNS(XML_w, XML_tblpPr, pAttributes);
281 bFloatingTableWritten =
true;
287 for (
const auto& rGrabBagElement : rGrabBag)
289 if (rGrabBagElement.first ==
"TableStyleName")
292 =
OUStringToOString(rGrabBagElement.second.get<OUString>(), RTL_TEXTENCODING_UTF8);
293 m_pSerializer->singleElementNS(XML_w, XML_tblStyle,
FSNS(XML_w, XML_val), sStyleName);
295 else if (rGrabBagElement.first ==
"TableStyleTopBorder")
296 rTableStyleConf[SvxBoxItemLine::TOP] = rGrabBagElement.second.get<table::BorderLine2>();
297 else if (rGrabBagElement.first ==
"TableStyleBottomBorder")
298 rTableStyleConf[SvxBoxItemLine::BOTTOM]
299 = rGrabBagElement.second.get<table::BorderLine2>();
300 else if (rGrabBagElement.first ==
"TableStyleLeftBorder")
301 rTableStyleConf[SvxBoxItemLine::LEFT]
302 = rGrabBagElement.second.get<table::BorderLine2>();
303 else if (rGrabBagElement.first ==
"TableStyleRightBorder")
304 rTableStyleConf[SvxBoxItemLine::RIGHT]
305 = rGrabBagElement.second.get<table::BorderLine2>();
306 else if (rGrabBagElement.first ==
"TableStyleLook")
309 = FastSerializerHelper::createAttrList();
310 const uno::Sequence<beans::PropertyValue> aAttributeList
311 = rGrabBagElement.second.get<uno::Sequence<beans::PropertyValue>>();
313 for (
const auto& rAttribute : aAttributeList)
315 if (rAttribute.Name ==
"val")
317 FSNS(XML_w, XML_val),
318 lcl_padStartToLength(OString::number(rAttribute.Value.get<sal_Int32>(), 16),
323 = { {
"firstRow", XML_firstRow },
324 {
"lastRow", XML_lastRow },
325 {
"firstColumn", XML_firstColumn },
326 {
"lastColumn", XML_lastColumn },
327 {
"noHBand", XML_noHBand },
328 {
"noVBand", XML_noVBand },
333 (rAttribute.Value.get<sal_Int32>() ?
"1" :
"0"));
337 m_pSerializer->singleElementNS(XML_w, XML_tblLook, pAttributeList);
339 else if (rGrabBagElement.first ==
"TablePosition" &&
342 rGrabBagElement.second !=
uno::Any())
345 = FastSerializerHelper::createAttrList();
346 const uno::Sequence<beans::PropertyValue> aTablePosition
347 = rGrabBagElement.second.get<uno::Sequence<beans::PropertyValue>>();
352 CollectFloatingTableAttributes(
m_rExport, *pFrame, pTableTextNodeInfoInner,
358 for (
const auto& rProp : aTablePosition)
360 if (rProp.Name ==
"vertAnchor" && !rProp.Value.get<OUString>().isEmpty())
364 attrListTablePos->add(
FSNS(XML_w, XML_vertAnchor), sOrientation);
366 else if (rProp.Name ==
"tblpYSpec" && !rProp.Value.get<OUString>().isEmpty())
370 attrListTablePos->add(
FSNS(XML_w, XML_tblpYSpec), sOrientation);
372 else if (rProp.Name ==
"horzAnchor" && !rProp.Value.get<OUString>().isEmpty())
376 attrListTablePos->add(
FSNS(XML_w, XML_horzAnchor), sOrientation);
378 else if (rProp.Name ==
"tblpXSpec" && !rProp.Value.get<OUString>().isEmpty())
382 attrListTablePos->add(
FSNS(XML_w, XML_tblpXSpec), sOrientation);
384 else if (rProp.Name ==
"bottomFromText")
386 sal_Int32
nValue = rProp.Value.get<sal_Int32>();
387 attrListTablePos->add(
FSNS(XML_w, XML_bottomFromText),
390 else if (rProp.Name ==
"leftFromText")
392 sal_Int32
nValue = rProp.Value.get<sal_Int32>();
393 attrListTablePos->add(
FSNS(XML_w, XML_leftFromText),
396 else if (rProp.Name ==
"rightFromText")
398 sal_Int32
nValue = rProp.Value.get<sal_Int32>();
399 attrListTablePos->add(
FSNS(XML_w, XML_rightFromText),
402 else if (rProp.Name ==
"topFromText")
404 sal_Int32
nValue = rProp.Value.get<sal_Int32>();
405 attrListTablePos->add(
FSNS(XML_w, XML_topFromText),
408 else if (rProp.Name ==
"tblpX")
410 sal_Int32
nValue = rProp.Value.get<sal_Int32>();
411 attrListTablePos->add(
FSNS(XML_w, XML_tblpX), OString::number(
nValue));
413 else if (rProp.Name ==
"tblpY")
415 sal_Int32
nValue = rProp.Value.get<sal_Int32>();
416 attrListTablePos->add(
FSNS(XML_w, XML_tblpY), OString::number(
nValue));
421 if (!bFloatingTableWritten)
423 m_pSerializer->singleElementNS(XML_w, XML_tblpPr, attrListTablePos);
427 SAL_WARN(
"sw.ww8",
"DocxAttributeOutput::TableDefinition: unhandled property: "
428 << rGrabBagElement.first);
433 sal_Int32 nIndent = 0;
436 case text::HoriOrientation::CENTER:
439 case text::HoriOrientation::RIGHT:
447 case text::HoriOrientation::LEFT_AND_WIDTH:
463 sal_Int32 nMode = lcl_getWordCompatibilityMode(
m_rExport);
466 = pTableTextNodeInfoInner->getTableBox()->GetFrameFormat();
488 FSNS(XML_w, XML_val),
"clear");
500 m_pSerializer->singleElementNS(XML_w, XML_tblInd,
FSNS(XML_w, XML_w), OString::number(nIndent),
512 for (
auto aColumnWidth : *pColumnWidths)
514 sal_Int32 nWidth = sal_Int32(aColumnWidth) - nPrv;
516 OString::number(nWidth));
517 nPrv = sal_Int32(aColumnWidth);
533 const SwTableBox* pTabBox = pTableTextNodeInfoInner->getTableBox();
544 const SwTable* pTable = pTableTextNodeInfoInner->getTable();
545 const SwTableBox* pTableBox = pTableTextNodeInfoInner->getTableBox();
555 if (pRowColorProp && aColor ==
COL_AUTO)
561 if (pTableColorProp && aColor ==
COL_AUTO)
562 aColor = pTableColorProp->
GetColor();
566 const std::map<OUString, css::uno::Any>& rGrabBag
569 OString sOriginalColor;
570 auto aGrabBagIt = rGrabBag.find(
"originalColor");
571 if (aGrabBagIt != rGrabBag.end())
575 if (sOriginalColor !=
sColor)
581 FSNS(XML_w, XML_val),
"clear");
588 for (
const auto & [
name, val ] : rGrabBag)
590 if (!val.has<OUString>())
593 if (
name ==
"themeFill")
595 else if (
name ==
"themeFillTint")
597 else if (
name ==
"themeFillShade")
599 else if (
name ==
"fill")
601 else if (
name ==
"themeColor")
603 else if (
name ==
"themeTint")
605 else if (
name ==
"themeShade")
607 else if (
name ==
"color")
609 else if (
name ==
"val")
619 const SwTableBox* pTabBox = pTableTextNodeInfoInner->getTableBox();
622 bool bRemovePersonalInfo
638 bool bIsInExtra =
false;
644 for (sal_uInt16 nCurRedlinePos = 0; nCurRedlinePos < aExtraRedlineTable.
GetSize();
649 if (pTableRowRedline && &pTableRowRedline->
GetTableLine() == pTabLine)
668 const OUString& rAuthor(
SW_MOD()->GetRedlineAuthor(aRedlineData.
GetAuthor()));
670 bRemovePersonalInfo ?
"Author" + OUString::number(
GetExport().GetInfoID(rAuthor))
672 RTL_TEXTENCODING_UTF8));
675 bool bNoDate = bRemovePersonalInfo
677 && aDateTime.
GetDay() == 1);
681 XML_w, RedlineType::Delete == pRedline->
GetType() ? XML_del : XML_ins,
682 FSNS(XML_w, XML_id), aId,
FSNS(XML_w, XML_author), aAuthor);
685 XML_w, RedlineType::Delete == pRedline->
GetType() ? XML_del : XML_ins,
686 FSNS(XML_w, XML_id), aId,
FSNS(XML_w, XML_author), aAuthor,
FSNS(XML_w, XML_date),
695 const SwTableBox* pTabBox = pTableTextNodeInfoInner->getTableBox();
697 bool bRemovePersonalInfo
708 bool bIsInExtra =
false;
714 for (sal_uInt16 nCurRedlinePos = 0; nCurRedlinePos < aExtraRedlineTable.
GetSize();
719 if (pTableCellRedline && &pTableCellRedline->
GetTableBox() == pTabBox)
737 const OUString& rAuthor(
SW_MOD()->GetRedlineAuthor(aRedlineData.
GetAuthor()));
739 bRemovePersonalInfo ?
"Author" + OUString::number(
GetExport().GetInfoID(rAuthor))
741 RTL_TEXTENCODING_UTF8));
744 bool bNoDate = bRemovePersonalInfo
746 && aDateTime.
GetDay() == 1);
750 XML_w, RedlineType::Delete == pRedline->
GetType() ? XML_cellDel : XML_cellIns,
751 FSNS(XML_w, XML_id), aId,
FSNS(XML_w, XML_author), aAuthor);
754 XML_w, RedlineType::Delete == pRedline->
GetType() ? XML_cellDel : XML_cellIns,
755 FSNS(XML_w, XML_id), aId,
FSNS(XML_w, XML_author), aAuthor,
FSNS(XML_w, XML_date),
763 const SwTableBox* pTabBox = pTableTextNodeInfoInner->getTableBox();
772 const char* pRule =
nullptr;
788 OString::number(nHeight),
FSNS(XML_w, XML_hRule), pRule);
794 const SwTableBox* pTabBox = pTableTextNodeInfoInner->getTableBox();
802 m_pSerializer->singleElementNS(XML_w, XML_cantSplit,
FSNS(XML_w, XML_val),
"true");
807 const SwTable* pTable = pTableTextNodeInfoInner->getTable();
812 m_pSerializer->singleElementNS(XML_w, XML_bidiVisual,
FSNS(XML_w, XML_val),
"true");
819 const SwTableBox* pTabBox = pTableTextNodeInfoInner->getTableBox();
823 m_pSerializer->singleElementNS(XML_w, XML_textDirection,
FSNS(XML_w, XML_val),
"tbRl");
826 m_pSerializer->singleElementNS(XML_w, XML_textDirection,
FSNS(XML_w, XML_val),
"btLr");
830 const auto nRow = pTableTextNodeInfoInner->getRow();
831 if (nRow >= rRows.
size())
833 SAL_WARN(
"sw.ww8",
"DocxAttributeOutput::TableCellProperties: out of range row: " << nRow);
837 sal_uInt32 nCell = pTableTextNodeInfoInner->getCell();
839 if (nCell >= rTableCells.size())
845 case text::VertOrientation::TOP:
847 case text::VertOrientation::CENTER:
848 m_pSerializer->singleElementNS(XML_w, XML_vAlign,
FSNS(XML_w, XML_val),
"center");
850 case text::VertOrientation::BOTTOM:
851 m_pSerializer->singleElementNS(XML_w, XML_vAlign,
FSNS(XML_w, XML_val),
"bottom");
868 SAL_INFO(
"sw.ww8",
"TODO: DocxAttributeOutput::TableOrientation( "
869 "ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )");
875 SAL_INFO(
"sw.ww8",
"TODO: DocxAttributeOutput::TableSpacing( "
876 "ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner )");
881 SAL_INFO(
"sw.ww8",
"TODO: DocxAttributeOutput::TableRowEnd( sal_uInt32 nDepth = 1 )");
ww8::WidthsPtr GetColumnWidths(ww8::WW8TableNodeInfoInner::Pointer_t const &pTableTextNodeInfoInner)
void GetTablePageSize(ww8::WW8TableNodeInfoInner const *pTableTextNodeInfoInner, tools::Long &rPageSize, bool &rRelBoxSize)
sal_Int16 GetYear() const
sal_uInt16 GetDay() const
sal_uInt16 GetMonth() const
virtual void TableRowEnd(sal_uInt32 nDepth) override
virtual void TableDefaultBorders(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
virtual void TableRowRedline(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
static OString convertToOOXMLVertOrient(sal_Int16 nOrient)
virtual void TableNodeInfoInner(ww8::WW8TableNodeInfoInner::Pointer_t pNodeInfoInner) override
virtual void TableDefinition(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
TableReference m_tableReference
virtual void TableBackgrounds(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
virtual void TableInfoRow(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
virtual void TableBidi(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
virtual void TableSpacing(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
std::unique_ptr< SwWriteTable > m_xTableWrt
The current table helper.
virtual void TableHeight(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
static const sal_Int32 Tag_TableDefinition
static OString convertToOOXMLVertOrientRel(sal_Int16 nOrientRel)
virtual void TableInfoCell(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
::sax_fastparser::FSHelperPtr m_pSerializer
Fast serializer to output the data.
virtual DocxExport & GetExport() override
Return the right export class.
sal_Int32 m_nRedlineId
Id of the redline.
virtual void TableVerticalCell(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
DocxExport & m_rExport
Reference to the export, where to get the data from.
static void AddToAttrList(rtl::Reference< sax_fastparser::FastAttributeList > &pAttrList, Args &&... args)
std::vector< std::map< SvxBoxItemLine, css::table::BorderLine2 > > m_aTableStyleConfs
virtual void TableCanSplit(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
static void ImplCellMargins(sax_fastparser::FSHelperPtr const &pSerializer, const SvxBoxItem &rBox, sal_Int32 tag, bool bUseStartEnd, const SvxBoxItem *pDefaultMargins=nullptr)
virtual void TableCellRedline(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
void FinishTableRowCell(ww8::WW8TableNodeInfoInner::Pointer_t const &pInner, bool bForceEmptyParagraph=false)
End cell, row, and even the entire table if necessary.
static OString convertToOOXMLHoriOrientRel(sal_Int16 nOrientRel)
void TableDefaultCellMargins(ww8::WW8TableNodeInfoInner::Pointer_t const &pTableTextNodeInfoInner)
static OString convertToOOXMLHoriOrient(sal_Int16 nOrient, bool bIsPosToggle)
virtual void TableOrientation(ww8::WW8TableNodeInfoInner::Pointer_t pTableTextNodeInfoInner) override
The class that does all the actual DOCX export-related work.
void SetFloatingTableFrame(const ww8::Frame *pF)
const ww8::Frame * GetFloatingTableFrame() const
DocxExportFilter & GetFilter()
sal_Int32 getWordCompatibilityModeFromGrabBag() const
virtual const SwExtraRedlineTable & GetExtraRedlineTable() const =0
virtual const SwRedlineTable & GetRedlineTable() const =0
virtual bool get(DocumentSettingId id) const =0
Return the specified document setting.
SvxFrameDirection TrueFrameDirection(const SwFrameFormat &rFlyFormat) const
Right to left?
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
const editeng::SvxBorderLine * GetLeft() const
sal_uInt16 CalcLineWidth(SvxBoxItemLine nLine) const
sal_Int16 GetDistance(SvxBoxItemLine nLine, bool bAllowNegative=false) const
const Color & GetColor() const
tools::Long GetRight() const
tools::Long GetLeft() const
tools::Long GetHeight() const
sal_uInt16 GetUpper() const
sal_uInt16 GetLower() const
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
IDocumentSettingAccess const & getIDocumentSettingAccess() const
RedlineType GetType(sal_uInt16 nPos=0) const
const SwRedlineData & GetRedlineData(sal_uInt16 nPos=0) const
std::size_t GetAuthor() const
const DateTime & GetTimeStamp() const
RedlineType GetType() const
static constexpr size_type npos
vector_type::size_type size_type
SwTableBox is one table cell in the document model.
SwRedlineTable::size_type GetRedline() const
SwFrameFormat * GetFrameFormat()
Redline that holds information about a table-cell that had some change.
const SwTableBox & GetTableBox() const
const SwRedlineData & GetRedlineData() const
SwTableLine is one table row in the document model.
SwFrameFormat * GetFrameFormat()
SwRedlineTable::size_type UpdateTextChangesOnly(SwRedlineTable::size_type &rRedlinePos, bool bUpdateProperty=true) const
SwRedlineTable::size_type GetTableRedline() const
Redline that holds information about a table-row that had some change.
const SwTableLine & GetTableLine() const
const SwRedlineData & GetRedlineData() const
SwTable is one table in the document model, containing rows (which contain cells).
SwTableFormat * GetFrameFormat()
sal_Int16 GetVertOri() const
const SwWriteTableCells & GetCells() const
static css::uno::Reference< css::text::XTextTable > GetObject(SwFrameFormat &rFormat)
OoxmlVersion getVersion() const
Make exporting a Writer Frame easy.
const SwFrameFormat & GetFrameFormat() const
Get the writer SwFrameFormat that this object describes.
std::shared_ptr< WW8TableNodeInfoInner > Pointer_t
constexpr ::Color COL_AUTO(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
constexpr OUStringLiteral sColor
TOOLS_DLLPUBLIC OString DateTimeToOString(const DateTime &rDateTime)
sal_Int32 DocxStringGetToken(DocxStringTokenMap const *pMap, std::u16string_view rName)
@ Fixed
Frame cannot be moved in Var-direction.
@ Variable
Frame is variable in Var-direction.
@ Minimum
Value in Var-direction gives minimum (can be exceeded but not be less).
constexpr sal_Int32 FSNS(sal_Int32 namespc, sal_Int32 element)
constexpr TypedWhichId< SvxBrushItem > RES_BACKGROUND(111)
constexpr TypedWhichId< SfxGrabBagItem > RES_FRMATR_GRABBAG(136)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
@ DocWarnRemovePersonalInfo
bool IsOptionSet(EOption eOption)
OStringBuffer & padToLength(OStringBuffer &rBuffer, sal_Int32 nLength, char cFill='\0')
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
OString ConvertColor(const Color &rColor)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
std::shared_ptr< Widths > WidthsPtr
sal_uInt32 m_nTableDepth
Remember the current table depth.
std::unique_ptr< char[]> aBuffer
std::vector< std::unique_ptr< SwWriteTableCell > > SwWriteTableCells