Files
core/MsBinaryFile/DocFile/TableRowPropertiesMapping.cpp
Alexander Trofimov 76ee07f61c [copyright] Update copyright header
Co-authored-by: Alexander Trofimov <alexander.trofimov@onlyoffice.com>
Co-committed-by: Alexander Trofimov <alexander.trofimov@onlyoffice.com>
2026-05-14 08:23:56 +00:00

294 lines
9.2 KiB
C++

/*
* Copyright (C) Ascensio System SIA, 2009-2026
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation, together with the
* additional terms provided in the LICENSE file.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: https://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA by email at info@onlyoffice.com
* or by postal mail at 20A-6 Ernesta Birznieka-Upisha Street, Riga,
* LV-1050, Latvia, European Union.
*
* The interactive user interfaces in modified versions of the Program
* are required to display Appropriate Legal Notices in accordance with
* Section 5 of the GNU AGPL version 3.
*
* No trademark rights are granted under this License.
*
* All non-code elements of the Product, including illustrations,
* icon sets, and technical writing content, are licensed under the
* Creative Commons Attribution-ShareAlike 4.0 International License:
* https://creativecommons.org/licenses/by-sa/4.0/legalcode
*
* This license applies only to such non-code elements and does not
* modify or replace the licensing terms applicable to the Program's
* source code, which remains licensed under the GNU Affero General
* Public License v3.
*
* SPDX-License-Identifier: AGPL-3.0-only
*/
#include "TableRowPropertiesMapping.h"
namespace DocFileFormat
{
TableRowPropertiesMapping::TableRowPropertiesMapping (XMLTools::CStringXmlWriter* pWriter, CharacterPropertyExceptions* rowEndChpx) : PropertiesMapping(pWriter), _trPr(NULL), _tblPrEx(NULL), _rowEndChpx(NULL)
{
_trPr = new XMLTools::XMLElement(L"w:trPr");
_tblPrEx = new XMLTools::XMLElement(L"w:tblPrEx");
//_tblBorders = new XMLTools::XMLElement(L"w:tblBorders");
_rowEndChpx = rowEndChpx;
}
TableRowPropertiesMapping::~TableRowPropertiesMapping()
{
RELEASEOBJECT(_trPr);
RELEASEOBJECT(_tblPrEx);
}
void TableRowPropertiesMapping::Apply(IVisitable* visited)
{
TablePropertyExceptions* tapx = static_cast<TablePropertyExceptions*>( visited );
std::shared_ptr<BorderCode> brcLeft;
std::shared_ptr<BorderCode> brcTop;
std::shared_ptr<BorderCode> brcBottom;
std::shared_ptr<BorderCode> brcRight;
std::shared_ptr<BorderCode> brcHorz;
std::shared_ptr<BorderCode> brcVert;
XMLTools::XMLElement* _tcMar = NULL;
//delete infos
RevisionData rev( _rowEndChpx );
if ( ( _rowEndChpx != NULL ) && ( rev.Type == Deleted ) )
{
XMLTools::XMLElement del( L"w:del" );
_trPr->AppendChild( del );
}
XMLTools::XMLElement rowHeight(L"w:trHeight");
for ( std::vector<SinglePropertyModifier>::iterator iter = tapx->grpprl->begin(); iter != tapx->grpprl->end(); iter++ )
{
switch (iter->OpCode)
{
case sprmOldTDefTable:
case sprmTDefTable:
{
//SprmTDefTable tdef = new SprmTDefTable(sprm.Arguments);
}break;
case sprmOldTTableHeader:
case sprmTTableHeader:
{ //header row
bool fHeader = (iter->Arguments[0] != 0) ? (true) : (false);
if (fHeader)
{
XMLTools::XMLElement header(L"w:tblHeader");
_trPr->AppendChild(header);
}
}break;
case sprmTWidthAfter:
{ //width after
XMLTools::XMLElement wAfter(L"w:wAfter");
XMLTools::XMLAttribute wAfterValue(L"w:w", FormatUtils::IntToWideString(FormatUtils::BytesToInt16(iter->Arguments, 1, iter->argumentsSize)));
wAfter.AppendAttribute(wAfterValue);
XMLTools::XMLAttribute wAfterType(L"w:type", L"dxa");
wAfter.AppendAttribute(wAfterType);
_trPr->AppendChild(wAfter, true);
}break;
case sprmTWidthBefore:
{ //width before
short before = FormatUtils::BytesToInt16(iter->Arguments, 1, iter->argumentsSize);
if (before != 0)
{
XMLTools::XMLElement wBefore(L"w:wBefore");
XMLTools::XMLAttribute wBeforeValue(L"w:w", FormatUtils::IntToWideString(before));
wBefore.AppendAttribute(wBeforeValue);
XMLTools::XMLAttribute wBeforeType(L"w:type", L"dxa");
wBefore.AppendAttribute(wBeforeType);
_trPr->AppendChild(wBefore, true);
}
}break;
case sprmOldTDyaRowHeight:
case sprmTDyaRowHeight:
{ //row height
XMLTools::XMLAttribute rowHeightVal(L"w:val");
XMLTools::XMLAttribute rowHeightRule(L"w:hRule");
short rH = FormatUtils::BytesToInt16(iter->Arguments, 0, iter->argumentsSize);
if (rH > 0)
{
rowHeightRule.SetValue(L"atLeast");
rowHeightVal.SetValue(FormatUtils::IntToWideString(rH));
rowHeight.AppendAttribute(rowHeightVal);
}
else if (rH == 0)
{
rowHeightRule.SetValue(L"auto");
}
else
{
rowHeightRule.SetValue(L"exact");
rH *= -1;
rowHeightVal.SetValue(FormatUtils::IntToWideString(rH));
rowHeight.AppendAttribute(rowHeightVal);
}
rowHeight.AppendAttribute(rowHeightRule);
}
break;
case sprmOldTFCantSplit:
case sprmTFCantSplit:
break;
case sprmTFCantSplit90:
{ //can't split
if (iter->argumentsSize > 0 && iter->Arguments[0] != 0)
appendFlagElement(_trPr, *iter, L"cantSplit", true);
}break;
case sprmTIpgp:// = PGPInfo.ipgpSelf (PGPInfo structure describes the border and margin properties)
{ //div id
}break;
case sprmTCellSpacing:
case sprmTCellSpacingDefault:
{
unsigned char grfbrc = iter->Arguments[2];
short wSpc = FormatUtils::BytesToInt16(iter->Arguments, 4, iter->argumentsSize);
std::wstring strValue = FormatUtils::IntToWideString(wSpc);
if (FormatUtils::BitmaskToBool((int)grfbrc, 0x01))
{
appendDxaElement(_trPr, L"tblCellSpacing", strValue, true);
}
}break;
case sprmTTableBorders80:
{
const int size = 4;
unsigned char brc80[size];
memcpy(brc80, iter->Arguments, size);
brcTop = std::shared_ptr<BorderCode>(new BorderCode(brc80, size));
memcpy(brc80, (iter->Arguments + 4), size);
brcLeft = std::shared_ptr<BorderCode>(new BorderCode(brc80, size));
memcpy(brc80, (iter->Arguments + 8), size);
brcBottom = std::shared_ptr<BorderCode>(new BorderCode(brc80, size));
memcpy(brc80, (iter->Arguments + 12), size);
brcRight = std::shared_ptr<BorderCode>(new BorderCode(brc80, size));
memcpy(brc80, (iter->Arguments + 16), size);
brcHorz = std::shared_ptr<BorderCode>(new BorderCode(brc80, size));
memcpy(brc80, (iter->Arguments + 20), size);
brcVert = std::shared_ptr<BorderCode>(new BorderCode(brc80, size));
}break;
case sprmTCellPaddingDefault:
case sprmTCellPadding:
case sprmTCellPaddingOuter:
{
unsigned char first = iter->Arguments[0];
unsigned char lim = iter->Arguments[1];
unsigned char ftsMargin = iter->Arguments[3];
short wMargin = FormatUtils::BytesToInt16(iter->Arguments, 4, iter->argumentsSize);
if (!_tcMar) _tcMar = new XMLTools::XMLElement(L"w:tblCellMar");
if (FormatUtils::GetBitFromInt(iter->Arguments[2], 0) == true)
{
appendDxaElement(_tcMar, L"top", FormatUtils::IntToWideString(wMargin), true);
}
if (FormatUtils::GetBitFromInt(iter->Arguments[2], 1) == true)
{
appendDxaElement(_tcMar, L"left", FormatUtils::IntToWideString(wMargin), true);
}
if (FormatUtils::GetBitFromInt(iter->Arguments[2], 2) == true)
{
appendDxaElement(_tcMar, L"bottom", FormatUtils::IntToWideString(wMargin), true);
}
if (FormatUtils::GetBitFromInt(iter->Arguments[2], 3) == true)
{
appendDxaElement(_tcMar, L"right", FormatUtils::IntToWideString(wMargin), true);
}
}
default:
break;
}
}
if (rowHeight.GetAttributeCount() > 0)
{
_trPr->AppendChild(rowHeight);
}
//set borders
XMLTools::XMLElement* _tblBorders = new XMLTools::XMLElement(L"w:tblBorders");
if (brcTop)
{
XMLTools::XMLElement border(L"w:top");
appendBorderAttributes(brcTop.get(), &border);
addOrSetBorder(_tblBorders, &border);
}
if (brcLeft)
{
XMLTools::XMLElement border(L"w:left");
appendBorderAttributes(brcLeft.get(), &border);
addOrSetBorder(_tblBorders, &border);
}
if (brcBottom)
{
XMLTools::XMLElement border(L"w:bottom");
appendBorderAttributes(brcBottom.get(), &border);
addOrSetBorder(_tblBorders, &border);
}
if (brcRight)
{
XMLTools::XMLElement border(L"w:right");
appendBorderAttributes(brcRight.get(), &border);
addOrSetBorder(_tblBorders, &border);
}
if (brcHorz)
{
XMLTools::XMLElement border(L"w:insideH");
appendBorderAttributes(brcHorz.get(), &border);
addOrSetBorder(_tblBorders, &border);
}
if (brcVert)
{
XMLTools::XMLElement border(L"w:insideV");
appendBorderAttributes(brcHorz.get(), &border);
addOrSetBorder(_tblBorders, &border);
}
if (_tblBorders->GetChildCount() > 0)
{
_tblPrEx->AppendChild(*_tblBorders);
}
if (_tcMar && _tcMar->GetChildCount() > 0)
{
_tblPrEx->AppendChild(*(_tcMar));
}
//---------------------------------------------------------------------------
if ( _tblPrEx->GetChildCount() > 0 )
{
m_pXmlWriter->WriteString(_tblPrEx->GetXMLString());
}
if ( ( _trPr->GetChildCount() > 0 ) || ( _trPr->GetAttributeCount() > 0 ) )
{
m_pXmlWriter->WriteString( _trPr->GetXMLString() );
}
RELEASEOBJECT(_tcMar);
}
}