24#include <com/sun/star/text/SizeType.hpp>
25#include <com/sun/star/text/TableColumnSeparator.hpp>
26#include <com/sun/star/text/WritingMode2.hpp>
29#include <ooxml/resourceids.hxx>
30#include <rtl/math.hxx>
34#include <oox/token/tokens.hxx>
46 m_bPushCurrentWidth(false),
47 m_bTableSizeTypeInserted(false),
65 case NS_ooxml::LN_CT_TblLook_val:
73 case NS_ooxml::LN_CT_TblLook_noVBand:
76 case NS_ooxml::LN_CT_TblLook_noHBand:
79 case NS_ooxml::LN_CT_TblLook_lastColumn:
82 case NS_ooxml::LN_CT_TblLook_lastRow:
85 case NS_ooxml::LN_CT_TblLook_firstColumn:
88 case NS_ooxml::LN_CT_TblLook_firstRow:
110 std::string sSprm = rSprm.
toString();
123 sal_uInt32 nSprmId = rSprm.
getId();
125 sal_Int32 nIntValue = (pValue ? pValue->getInt() : 0);
128 case NS_ooxml::LN_CT_TblPrBase_tblW:
129 case NS_ooxml::LN_CT_TblPrBase_tblInd:
136 pProperties->resolve(*pMeasureHandler);
138 if (nSprmId == sal_uInt32(NS_ooxml::LN_CT_TblPrBase_tblInd))
151 else if( sal::static_int_cast<Id>(pMeasureHandler->getUnit()) == NS_ooxml::LN_Value_ST_TblWidth_pct )
153 sal_Int32 nPercent = pMeasureHandler->getValue() / 50;
160 else if( sal::static_int_cast<Id>(pMeasureHandler->getUnit()) == NS_ooxml::LN_Value_ST_TblWidth_auto )
171 bool bFixed = std::find(pCellWidths->begin(), pCellWidths->end(), -1) == pCellWidths->end();
194 case NS_ooxml::LN_CT_TrPrBase_tblHeader:
209#define HEADER_ROW_LIMIT_FOR_MSO_WORKAROUND 10
224 if ( nIntValue == 0 &&
m_nRow == 0 )
241 case NS_ooxml::LN_CT_TblPrBase_tblStyle:
248 case NS_ooxml::LN_CT_TblGridBase_gridCol:
256 case NS_ooxml::LN_CT_TcPrBase_vMerge :
260 pMergeProps->Insert(
PROP_VERTICAL_MERGE,
uno::Any( sal::static_int_cast<Id>(nIntValue) == NS_ooxml::LN_Value_ST_Merge_restart ) );
264 case NS_ooxml::LN_CT_TcPrBase_hMerge:
272 case NS_ooxml::LN_CT_TcPrBase_gridSpan:
282 case NS_ooxml::LN_CT_TcPrBase_textDirection:
285 bool bInsertCellProps =
true;
288 case NS_ooxml::LN_Value_ST_TextDirection_tbRl:
292 SAL_INFO(
"writerfilter",
"Have inserted textDirection " << nIntValue );
294 case NS_ooxml::LN_Value_ST_TextDirection_btLr:
297 case NS_ooxml::LN_Value_ST_TextDirection_lrTbV:
300 case NS_ooxml::LN_Value_ST_TextDirection_tbRlV:
303 case NS_ooxml::LN_Value_ST_TextDirection_lrTb:
304 case NS_ooxml::LN_Value_ST_TextDirection_tbLrV:
307 bInsertCellProps =
false;
310 if ( bInsertCellProps )
314 case NS_ooxml::LN_CT_TcPrBase_tcW:
323 pProperties->resolve(*pMeasureHandler);
324 if (sal::static_int_cast<Id>(pMeasureHandler->getUnit()) == NS_ooxml::LN_Value_ST_TblWidth_auto)
328 getCurrentCellWidths()->push_back(pMeasureHandler->getMeasureValue() ? pMeasureHandler->getValue() : sal_Int32(0));
334 case NS_ooxml::LN_CT_TblPrBase_tblpPr:
351 case NS_ooxml::LN_CT_TrPrBase_gridBefore:
354 case NS_ooxml::LN_CT_TrPrBase_gridAfter:
357 case NS_ooxml::LN_CT_TblPrBase_tblCaption:
360 case NS_ooxml::LN_CT_TblPrBase_tblDescription:
363 case NS_ooxml::LN_CT_TrPrBase_tblCellSpacing:
366 case NS_ooxml::LN_CT_TblPrBase_tblCellSpacing:
369 case NS_ooxml::LN_CT_TblPrBase_bidiVisual:
372 pPropMap->Insert(
PROP_WRITING_MODE,
uno::Any(sal_Int16(nIntValue ? text::WritingMode2::RL_TB : text::WritingMode2::LR_TB)));
390 throw std::out_of_range(
"no current grid");
430 std::optional<sal_Int32> oCurrentWidth;
436 std::optional<TableParagraph> oParagraph;
443 IntVectorPtr pNewGrid = std::make_shared<std::vector<sal_Int32>>();
444 IntVectorPtr pNewCellWidths = std::make_shared<std::vector<sal_Int32>>();
474 SAL_WARN(
"writerfilter.dmapper",
"Table stack is empty");
481 std::optional<sal_Int32> oCurrentWidth;
512 std::optional<TableParagraph> oParagraph;
527 throw std::out_of_range(
"cell without a table");
536 if (pCellWidths->empty())
538 if (
m_nLayoutType == NS_ooxml::LN_Value_doc_ST_TblLayout_fixed)
540 if (pCellWidths->size() == nGrids)
542 rIsIncompleteGrid =
true;
543 return nGrids > pTableGrid->size();
556 throw std::out_of_range(
"row without a position");
560 bool bSamePosition = ( pTmpPosition == pCurrentPosition ) ||
561 ( pTmpPosition && pCurrentPosition && *pTmpPosition == *pCurrentPosition );
563 OUString sTableStyleName;
565 ( bIsSetTableStyle &&
568 if ( (!bSamePosition || !bSameTableStyle) &&
m_nRow > 0 )
573 sal_uInt32 nTmpCell =
m_nCell.back();
614 for(
const auto& rCell : *pTableGrid )
645 for (
const auto& rGridSpan : rCurrentSpans)
656 size_t nGrids = std::accumulate(rCurrentSpans.begin(), rCurrentSpans.end(), sal::static_int_cast<size_t>(0));
662 int nFullWidthRelative = 0;
663 for (
int i : (*pTableGrid))
666 bool bIsIncompleteGrid =
false;
667 if( pTableGrid->size() == nGrids &&
m_nCell.back( ) > 0 )
673 sal_Int32 nTableWidth(0);
674 sal_Int32 nTableWidthType(text::SizeType::VARIABLE);
677 if ((nTableWidthType == text::SizeType::FIX) && (nTableWidth <
m_nTableWidth))
681 if (nTableWidthType == text::SizeType::VARIABLE )
683 if(nTableWidth > 100 || nTableWidth <= 0)
698 text::TableColumnSeparator* pSeparators = aSeparators.getArray();
699 double nLastRelPos = 0.0;
700 sal_uInt32 nBorderGridIndex = 0;
705 ::std::vector< sal_uInt32 >::const_iterator aSpansIter = rCurrentSpans.begin();
708 double nRelPos, fGridWidth = 0.;
709 for ( sal_Int32 nGridCount = *aSpansIter; nGridCount > 0; --nGridCount )
710 fGridWidth += (*pTableGrid)[nBorderGridIndex++];
712 if (fGridWidth == 0.)
719 if (nFullWidthRelative == 0)
722 nRelPos = (fGridWidth * 10000) / nFullWidthRelative;
725 pSeparators[
nBorder].Position = rtl::math::round(nRelPos + nLastRelPos);
726 pSeparators[
nBorder].IsVisible =
true;
727 nLastRelPos = nLastRelPos + nRelPos;
742 if ( !aMoved.isEmpty() )
744 auto pTrackChangesHandler = std::make_shared<TrackChangesHandler>(
746 ? oox::XML_tableRowDelete
747 : oox::XML_tableRowInsert );
754 else if (
shouldInsertRow(pCellWidths, pTableGrid, nGrids, bIsIncompleteGrid))
767 text::TableColumnSeparator* pSeparators = aSeparators.getArray();
771 if (bIsIncompleteGrid)
772 nFullWidthRelative = 0;
775 if( nFullWidthRelative == 0 )
776 for (
size_t i = 0;
i < pCellWidths->size(); ++
i)
777 nFullWidthRelative += (*pCellWidths)[
i];
779 if (bIsIncompleteGrid)
786 sal_Int32 nTableWidth(0);
787 sal_Int32 nTableWidthType(text::SizeType::VARIABLE);
790 if (nTableWidth < nFullWidth)
796 size_t nWidthsBound = pCellWidths->size() - 1;
801 if ( bIsIncompleteGrid && rCurrentSpans.size()-1 == nWidthsBound )
803 auto aSpansIter = std::next(rCurrentSpans.begin(), nWidthsBound - 1);
804 sal_Int32 nFixLastCellWidth = (*pCellWidths)[nWidthsBound-1] / *aSpansIter * *std::next(aSpansIter);
805 if (nFixLastCellWidth > (*pCellWidths)[nWidthsBound])
806 nFullWidthRelative += nFixLastCellWidth - (*pCellWidths)[nWidthsBound];
810 if (nFullWidthRelative > 0)
812 for (
size_t i = 0;
i < nWidthsBound; ++
i)
814 nSum += (*pCellWidths)[
i];
815 pSeparators[
nPos].Position = (nSum * 10000) / nFullWidthRelative;
816 pSeparators[
nPos].IsVisible =
true;
842 pCellWidths->clear();
#define HEADER_ROW_LIMIT_FOR_MSO_WORKAROUND
css::uno::Sequence< css::beans::PropertyValue > getAsConstPropertyValueList() const
An SPRM: Section, Paragraph and Run Modifier.
virtual sal_uInt32 getId() const =0
Returns id of the SPRM.
virtual writerfilter::Reference< Properties >::Pointer_t getProps()=0
Returns reference to properties contained in the SPRM.
virtual Value::Pointer_t getValue()=0
Returns value of the SPRM.
virtual std::string toString() const =0
Returns string representation of sprm.
static TagLogger & getInstance()
void startElement(const std::string &name)
void chars(const std::string &chars)
void attribute(const std::string &name, const std::string &value)
void element(const std::string &name)
virtual int getInt() const =0
Returns integer representation of the value.
virtual void insertRowProps(const TablePropertyMapPtr &pProps) override
Handle properties of the current row.
OUString getMoved() const
const TableParagraphVectorPtr & getCurrentParagraphs()
bool m_bTableSizeTypeInserted
Remember if table width was already set, when we lack a w:tblW, it should be set manually at the end.
virtual ~DomainMapperTableManager() override
std::shared_ptr< std::vector< sal_Int32 > > IntVectorPtr
void finishTableLook()
Turn the attributes collected so far in m_aTableLook into a property and clear the container.
::std::vector< IntVectorPtr > m_aTableGrid
TablePositionHandler * getCurrentTableRealPosition()
std::stack< TableParagraphVectorPtr > m_aParagraphsToEndTable
Collected table paragraphs for table style handling.
virtual void endOfCellAction() override
Action to be carried out at the end of the last paragraph of a cell.
std::vector< TablePositionHandlerPtr > m_aTablePositions
::std::vector< sal_uInt32 > m_nCell
bool shouldInsertRow(IntVectorPtr pCellWidths, IntVectorPtr pTableGrid, size_t nGrids, bool &rIsIncompleteGrid)
sal_Int32 m_nHeaderRepeat
css::uno::Sequence< css::beans::PropertyValue > getCurrentTablePosition()
std::vector< OUString > m_aMoved
Moved table (in moveRangeFromStart...moveRangeFromEnd or moveRangeToStart...moveRangeToEnd)
std::vector< OUString > m_aTableStyleNames
::std::vector< IntVectorPtr > m_aCellWidths
Individual table cell width values, used only in case the number of cells doesn't match the table gri...
IntVectorPtr const & getCurrentCellWidths()
virtual void startLevel() override
Start a new table level.
std::vector< TablePositionHandlerPtr > m_aTmpPosition
Temporarily stores the position to compare it later.
bool attribute(Id nName, Value const &val)
virtual void endOfRowAction() override
Action to be carried out at the end of the "table row" paragraph.
std::unique_ptr< TablePropertiesHandler > m_pTablePropsHandler
std::vector< TablePropertyMapPtr > m_aTmpTableProperties
Temporarily stores the table properties until end of row.
IntVectorPtr const & getCurrentGrid()
virtual bool sprm(Sprm &rSprm) override
Handle an SPRM at current handle.
sal_uInt32 m_nLayoutType
Table layout algorithm, IOW if we should consider fixed column width or not.
virtual void cellProps(const TablePropertyMapPtr &pProps) override
Handle properties of the current cell.
bool m_bIsInShape
Are we in a shape (text append stack is not empty) or in the body document?
bool m_bPushCurrentWidth
If this is true, then we pushed a width before the next level started, and that should be carried ove...
DomainMapperTableManager()
comphelper::SequenceAsHashMap m_aTableLook
Grab-bag of table look attributes for preserving.
virtual void endLevel() override
End a table level.
virtual void clearData() override
let the derived class clear their table related data
void setIsInShape(bool bIsInShape)
virtual void insertTableProps(const TablePropertyMapPtr &pProps) override
Handle properties of the current table.
Handler for sprms that contain a measure and a unit.
sal_uInt32 getCurrentGridBefore()
virtual bool sprm(Sprm &rSprm)
Handle an SPRM at current handle.
sal_Int32 getTableDepthDifference() const
Return the current table difference, i.e.
TablePropertyMapPtr getTableProps()
bool isInTable()
Tells whether a table has been started or not.
void setCurrentGridBefore(sal_uInt32 nSkipGrids)
virtual void startLevel()
Start a new table level.
virtual void insertTableProps(const TablePropertyMapPtr &pProps)
Handle properties of the current table.
virtual void endLevel()
End a table level.
void setCurrentGridAfter(sal_uInt32 nSkipGrids)
void setKeepUnfinishedRow(bool bKeep)
Should we keep the unfinished row in endLevel to initialize the table data in the following startLeve...
sal_uInt32 getTableDepth() const
void setCurrentGridSpan(sal_uInt32 nGridSpan, bool bFirstCell=false)
std::vector< sal_uInt32 > getCurrentGridSpans()
Handler for floating table positioning.
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
tools::Long const nBorder
constexpr T saturating_add(T a, T b)
double convertTwipToMM100Double(sal_Int32 _t)
OUString getPropertyName(PropertyIds eId)
std::shared_ptr< std::vector< TableParagraph > > TableParagraphVectorPtr
@ META_PROP_TABLE_STYLE_NAME
@ PROP_TABLE_COLUMN_SEPARATORS
@ PROP_TABLE_REDLINE_PARAMS