DocFormatReader - fix user file(table)

This commit is contained in:
ElenaSubbotina
2018-04-16 14:50:51 +03:00
parent c4ca4b5613
commit a395420d59
16 changed files with 153 additions and 116 deletions

View File

@ -685,9 +685,9 @@ namespace DocFileFormat
if ( _bContentWrite )
{
m_pXmlWriter->WriteNodeBegin( L"w:fldChar", true );
m_pXmlWriter->WriteAttribute( L"w:fldCharType", L"begin" );
m_pXmlWriter->WriteNodeEnd( L"", true );
m_pXmlWriter->WriteNodeBegin( L"w:fldChar", true );
m_pXmlWriter->WriteAttribute( L"w:fldCharType", L"begin" );
m_pXmlWriter->WriteNodeEnd( L"", true );
_fieldLevels.back().bBegin = true;
}
@ -702,12 +702,12 @@ namespace DocFileFormat
{
_writeWebHidden = true;
std::wstring _writeTocLink =f1.substr(d + 9);
d = (int)_writeTocLink.find(L" ");
d = (int)_writeTocLink.find(L" ");
_writeTocLink = _writeTocLink.substr(0, d);
_writeAfterRun = std::wstring (L"<w:hyperlink w:anchor = \"");
_writeAfterRun = std::wstring (L"<w:hyperlink w:anchor = \"");
_writeAfterRun += _writeTocLink;
_writeAfterRun += std::wstring (L"\" w:history=\"1\">");
_writeAfterRun += std::wstring (L"\" w:history=\"1\">");
break;
//cp = cpFieldSep1;
@ -717,7 +717,28 @@ namespace DocFileFormat
_skipRuns = 5; //with separator
}
}
else if ( bEMBED || bLINK || bQUOTE)
//else if ( bHYPERLINK )
//{//todooo - выделение гиперссылки отдельно
// std::vector<std::wstring> arRefs;
// boost::algorithm::split(arRefs, f, boost::algorithm::is_any_of(L" "), boost::algorithm::token_compress_on);
//
// std::wstring sLink = arRefs[2];
// m_pXmlWriter->WriteNodeBegin( L"w:hyperlink", true );
// int relID = m_context->_docx->RegisterHyperlink(_caller, sLink);
// m_pXmlWriter->WriteAttribute( L"r:id", L"rId"+ FormatUtils::IntToWideString( relID ) );
// m_pXmlWriter->WriteAttribute( L"w:history", 1 );
// m_pXmlWriter->WriteNodeEnd( L"", true, false );
// if (arRefs.size() > 2)
// {
// writeTextElement(arRefs[3].substr(1, arRefs[3].length() - 2), textType);
// }
// m_pXmlWriter->WriteNodeEnd( L"w:hyperlink", false, true );
// _skipRuns = 1;
//}
else if ( bEMBED || (bLINK && !bHYPERLINK)|| bQUOTE)
{
int cpPic = searchNextTextMark(m_document->Text, cpFieldStart, TextMark::Picture);
int cpFieldSep = searchNextTextMark(m_document->Text, cpFieldStart, TextMark::FieldSeparator);
@ -840,19 +861,21 @@ namespace DocFileFormat
else if (TextMark::FieldEndMark == code)
{
if (!_fieldLevels.empty())
{
_fieldLevels.back().bEnd = true;
if (_fieldLevels.back().bBegin == true && !text.empty())
{
if (!text.empty())
{
writeTextElement(text, textType);
text.clear();
}
}
if (_fieldLevels.back().bBegin)
{
_fieldLevels.back().bEnd = true;
XMLTools::XMLElement elem( L"w:fldChar" );
elem.AppendAttribute( L"w:fldCharType", L"end" );
XMLTools::XMLElement elem( L"w:fldChar" );
elem.AppendAttribute( L"w:fldCharType", L"end" );
m_pXmlWriter->WriteString( elem.GetXMLString());
m_pXmlWriter->WriteString( elem.GetXMLString());
}
_fieldLevels.pop_back();
}
@ -1151,20 +1174,7 @@ namespace DocFileFormat
if ( fc >= nMinVal )
{
ret = m_document->AllPapx->find(nMinVal)->second;
//? if (!ret && m_document->AllPapx->size() > 0)
//? {
//? map<int, ParagraphPropertyExceptions*>::iterator it = m_document->AllPapx->end();
//? it--;
//? do
//? {
//? if (it->first < nMinVal && it->second)
//? break;
//? it--;
//? }
//? while(it != m_document->AllPapx->begin());
//?
//? ret = it->second;
//? }
_lastValidPapx = ret;
}
}
@ -1215,8 +1225,8 @@ namespace DocFileFormat
TableInfo tai( papx, m_document->nWordVersion );
//build the table grid
std::vector<short> grid, grid_write;
buildTableGrid( cp, nestingLevel, grid, grid_write );
std::vector<short> grid;
buildTableGrid( cp, nestingLevel, grid);
//find first row end
int fcRowEnd = findRowEndFc( cp, nestingLevel );
@ -1227,7 +1237,7 @@ namespace DocFileFormat
m_pXmlWriter->WriteNodeBegin( L"w:tbl" );
//Convert it
TablePropertiesMapping *tpMapping = new TablePropertiesMapping( m_pXmlWriter, m_document->Styles, &grid, &grid_write );
TablePropertiesMapping *tpMapping = new TablePropertiesMapping( m_pXmlWriter, m_document->Styles, &grid);
row1Tapx.Convert( tpMapping );
@ -1240,7 +1250,7 @@ namespace DocFileFormat
//only convert the cells with the given nesting level
while ( tai.iTap == nestingLevel )
{
cp = writeTableRow( cp, &grid, &grid_write, nestingLevel );
cp = writeTableRow( cp, &grid, nestingLevel );
//?fc = m_document->FindFileCharPos(cp );
fc = m_document->m_PieceTable->FileCharacterPositions->operator []( cp );
papx = findValidPapx( fc );
@ -1253,7 +1263,7 @@ namespace DocFileFormat
//convert until the end of table is reached
while ( tai.fInTable )
{
cp = writeTableRow( cp, &grid, &grid_write, nestingLevel );
cp = writeTableRow( cp, &grid, nestingLevel );
fc = m_document->FindFileCharPos( cp );
papx = findValidPapx( fc );
@ -1268,12 +1278,11 @@ namespace DocFileFormat
}
// Builds a list that contains the width of the several columns of the table.
bool DocumentMapping::buildTableGrid(int initialCp, unsigned int nestingLevel, std::vector<short>& grid, std::vector<short>& grid_write)
bool DocumentMapping::buildTableGrid(int initialCp, unsigned int nestingLevel, std::vector<short>& grid)
{
ParagraphPropertyExceptions* backup = _lastValidPapx;
std::vector<short> boundaries;
std::vector<short> boundaries_all;
std::map<short, short> boundaries;
int cp = initialCp;
int fc = m_document->FindFileCharPos( cp );
@ -1284,8 +1293,12 @@ namespace DocFileFormat
int fcRowEnd = findRowEndFc( cp, cp, nestingLevel );
ParagraphPropertyExceptions* papx_prev = NULL;
short max_boundary = -1;
short count_column = 0;
while ( tai.fInTable )
{
short current_count_column = 0;
//check all SPRMs of this TAPX
for ( std::list<SinglePropertyModifier>::iterator iter = papx->grpprl->begin(); iter != papx->grpprl->end(); iter++ )
{
@ -1294,43 +1307,33 @@ namespace DocFileFormat
switch(iter->OpCode)
{
case sprmTDefTable:
case sprmOldTDefTable:
{
unsigned char itcMac = iter->Arguments[0];
while(boundaries.size() < itcMac + 1)
boundaries.push_back(-0x7fff);
short boundary0 = -0x7fff;
for (unsigned char i = 0; i < itcMac; i++)
case sprmTDefTable:
case sprmOldTDefTable:
{
short boundary1 = FormatUtils::BytesToInt16( iter->Arguments, 1 + ( i * 2 ), iter->argumentsSize );
short boundary2 = FormatUtils::BytesToInt16( iter->Arguments, 1 + ( ( i + 1 ) * 2 ), iter->argumentsSize );
//SprmTDefTable tdef(iter->Arguments, iter->argumentsSize);
//int itcMac = tdef.numberOfColumns;
if (boundary2 - boundary1 > 1 && boundary1 - boundary0 > 1)
{
if ( boundaries[i] == -0x7fff || boundaries[i+1] == -0x7fff)
{
boundaries[i] = boundary1;
boundaries[i+1] = boundary2;
}
}
if ( find( boundaries_all.begin(), boundaries_all.end(), boundary1 ) == boundaries_all.end() )
{
boundaries_all.push_back( boundary1 );
}
unsigned char itcMac = iter->Arguments[0];
if ( find( boundaries_all.begin(), boundaries_all.end(), boundary2 ) == boundaries_all.end() )
short boundary1, boundary2;
for (unsigned char i = 0; i < itcMac; i++)
{
boundaries_all.push_back( boundary2 );
boundary1 = FormatUtils::BytesToInt16( iter->Arguments + 1, i * 2 , iter->argumentsSize );
boundary2 = FormatUtils::BytesToInt16( iter->Arguments + 1, ( i + 1 ) * 2, iter->argumentsSize );
AddBoundary(boundary1, boundary2, boundaries);
}
boundary0 = boundary1;
}break;
}
if (max_boundary < boundary2)
max_boundary = boundary2;
AddBoundary(boundary2, max_boundary, boundaries);
}break;
}
}
if (current_count_column > count_column)
count_column = current_count_column;
//get the next papx
papx = findValidPapx( fcRowEnd );
tai = TableInfo( papx, m_document->nWordVersion );
@ -1341,21 +1344,11 @@ namespace DocFileFormat
papx_prev = papx;
}
//build the grid based on the boundaries
sort( boundaries_all.begin(), boundaries_all.end() );
if ( !boundaries.empty() )
{
for ( size_t i = 0; i < ( boundaries.size() - 1 ); i++ )
for ( std::map<short, short>::iterator it = boundaries.begin(); it != boundaries.end(); ++it)
{
grid_write.push_back( boundaries[i + 1] - boundaries[i] );
}
}
if ( !boundaries_all.empty() )
{
for ( size_t i = 0; i < ( boundaries_all.size() - 1 ); i++ )
{
grid.push_back( boundaries_all[i + 1] - boundaries_all[i] );
grid.push_back( it->second );
}
}
_lastValidPapx = backup;
@ -1363,6 +1356,40 @@ namespace DocFileFormat
return true;
}
void DocumentMapping::AddBoundary(short boundary1, short boundary2, std::map<short, short> &boundaries)
{
if (boundary2 - boundary1 < 10)
return;
std::map<short, short>::iterator pFind = boundaries.find(boundary1);
while(true)
{
if (pFind == boundaries.end())
{
boundaries.insert(std::make_pair(boundary1, boundary2 - boundary1));
break;
}
else if (pFind->second != boundary2 - boundary1)
{
if (pFind->second > boundary2 - boundary1)
{
short new_size = boundary2 - boundary1;
boundary1 = boundary2;
boundary2 = pFind->second + pFind->first;
pFind->second = new_size;
}
else
{
boundary1 = pFind->second + pFind->first;
}
pFind = boundaries.find(boundary1);
}
else
break;
}
}
// Finds the FC of the next row end mark.
int DocumentMapping::findRowEndFc(int initialCp, int& rowEndCp, unsigned int nestingLevel )
{
@ -1480,7 +1507,7 @@ namespace DocFileFormat
}
/// Writes the table row that starts at the given cp value and ends at the next row end mark
int DocumentMapping::writeTableRow(int initialCp, std::vector<short>* grid, std::vector<short>* grid_write, unsigned int nestingLevel)
int DocumentMapping::writeTableRow(int initialCp, std::vector<short>* grid, unsigned int nestingLevel)
{
int cp = initialCp;
int fc = m_document->FindFileCharPos( cp );
@ -1510,7 +1537,7 @@ namespace DocFileFormat
//Write until the first "inner trailer paragraph" is reached
while ( !( ( m_document->Text->at( cp ) == TextMark::ParagraphEnd ) && ( tai.fInnerTtp ) ) && tai.fInTable )
{
cp = writeTableCell( cp, &tapx, grid, grid_write, gridIndex, cellIndex, nestingLevel );
cp = writeTableCell( cp, &tapx, grid, gridIndex, cellIndex, nestingLevel );
cellIndex++;
//each cell has it's own PAPX
@ -1527,7 +1554,7 @@ namespace DocFileFormat
while ( !( ( m_document->Text->at( cp ) == TextMark::CellOrRowMark ) && ( tai.fTtp ) )
&& tai.fInTable )
{
cp = writeTableCell( cp, &tapx, grid, grid_write, gridIndex, cellIndex, nestingLevel );
cp = writeTableCell( cp, &tapx, grid, gridIndex, cellIndex, nestingLevel );
cellIndex++;
//each cell has it's own PAPX
@ -1550,7 +1577,7 @@ namespace DocFileFormat
}
/// Writes the table cell that starts at the given cp value and ends at the next cell end mark
int DocumentMapping::writeTableCell(int initialCp, TablePropertyExceptions* tapx, std::vector<short>* grid, std::vector<short>* grid_write, int& gridIndex, int cellIndex, unsigned int nestingLevel )
int DocumentMapping::writeTableCell(int initialCp, TablePropertyExceptions* tapx, std::vector<short>* grid, int& gridIndex, int cellIndex, unsigned int nestingLevel )
{
int cp = initialCp;
int cpCellEnd = findCellEndCp( initialCp, nestingLevel );
@ -1558,7 +1585,7 @@ namespace DocFileFormat
//start w:tc
m_pXmlWriter->WriteNodeBegin( L"w:tc" );
TableCellPropertiesMapping* tcpMapping = new TableCellPropertiesMapping( m_pXmlWriter, grid, grid_write, gridIndex, cellIndex );
TableCellPropertiesMapping* tcpMapping = new TableCellPropertiesMapping( m_pXmlWriter, grid, gridIndex, cellIndex );
if ( tapx != NULL )
{