Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DocFormatReader- fix users file (table) #71

Merged
merged 1 commit into from
Apr 16, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ASCOfficeDocFile/DocDocxConverter/ContentTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ namespace OpenXmlRelationshipTypes
static const wchar_t* GlossaryDocument = L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/glossaryDocument";
static const wchar_t* Package = L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/package";
static const wchar_t* VbaProject = L"http://schemas.microsoft.com/office/2006/relationships/vbaProject";
static const wchar_t* Hyperlink = L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink";
}

namespace MicrosoftWordRelationshipTypes
Expand Down
189 changes: 108 additions & 81 deletions ASCOfficeDocFile/DocDocxConverter/DocumentMapping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -679,9 +679,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;
}
Expand All @@ -703,12 +703,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;
Expand All @@ -718,7 +718,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);
Expand Down Expand Up @@ -841,19 +862,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();
}
Expand Down Expand Up @@ -1152,20 +1175,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;
}
}
Expand Down Expand Up @@ -1215,8 +1225,8 @@ namespace DocFileFormat
TableInfo tai( papx );

//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 );
Expand All @@ -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 );

Expand All @@ -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 );
Expand All @@ -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 );
Expand All @@ -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 );
Expand All @@ -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++ )
{
Expand All @@ -1294,43 +1307,33 @@ namespace DocFileFormat

switch(iter->OpCode)
{
case sprmTDefTable:
case sprmOldTDefTable:
{
unsigned char itcMac = iter->Arguments[0];
case sprmTDefTable:
case sprmOldTDefTable:
{
//SprmTDefTable tdef(iter->Arguments, iter->argumentsSize);
//int itcMac = tdef.numberOfColumns;

while(boundaries.size() < itcMac + 1)
boundaries.push_back(-0x7fff);
unsigned char itcMac = iter->Arguments[0];

short boundary0 = -0x7fff;
short boundary1, boundary2;
for (unsigned char i = 0; i < itcMac; i++)
{
short boundary1 = FormatUtils::BytesToInt16( iter->Arguments, 1 + ( i * 2 ), iter->argumentsSize );
short boundary2 = FormatUtils::BytesToInt16( iter->Arguments, 1 + ( ( i + 1 ) * 2 ), iter->argumentsSize );

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 );
}
boundary1 = FormatUtils::BytesToInt16( iter->Arguments + 1, i * 2 , iter->argumentsSize );
boundary2 = FormatUtils::BytesToInt16( iter->Arguments + 1, ( i + 1 ) * 2, iter->argumentsSize );

if ( find( boundaries_all.begin(), boundaries_all.end(), boundary2 ) == boundaries_all.end() )
{
boundaries_all.push_back( boundary2 );
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 );
Expand All @@ -1341,26 +1344,50 @@ 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] );
grid.push_back( it->second );
}
}
if ( !boundaries_all.empty() )
_lastValidPapx = backup;

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)
{
for ( size_t i = 0; i < ( boundaries_all.size() - 1 ); i++ )
if (pFind == boundaries.end())
{
boundaries.insert(std::make_pair(boundary1, boundary2 - boundary1));
break;
}
else if (pFind->second != boundary2 - boundary1)
{
grid.push_back( boundaries_all[i + 1] - boundaries_all[i] );
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;
}
_lastValidPapx = backup;

return true;
}

// Finds the FC of the next row end mark.
Expand Down Expand Up @@ -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 );
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -1550,15 +1577,15 @@ 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 );

//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 )
{
Expand Down
8 changes: 5 additions & 3 deletions ASCOfficeDocFile/DocDocxConverter/DocumentMapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,15 +110,15 @@ namespace DocFileFormat
// Writes the table starts at the given cp value
int writeTable ( int initialCp, unsigned int nestingLevel );
// Builds a list that contains the width of the several columns of the table.
bool buildTableGrid( int initialCp, unsigned int nestingLevel, std::vector<short>& grid, std::vector<short>& grid_write );
bool buildTableGrid( int initialCp, unsigned int nestingLevel, std::vector<short>& grid);
// Finds the FC of the next row end mark.
int findRowEndFc ( int initialCp, int& rowEndCp, unsigned int nestingLevel );
// Finds the FC of the next row end mark.
int findRowEndFc ( int initialCp, unsigned int nestingLevel );
// Writes the table row that starts at the given cp value and ends at the next row end mark
int writeTableRow ( int initialCp, std::vector<short>* grid, std::vector<short>* grid_write, unsigned int nestingLevel );
int writeTableRow ( int initialCp, std::vector<short>* grid, unsigned int nestingLevel );
// Writes the table cell that starts at the given cp value and ends at the next cell end mark
int writeTableCell ( int initialCp, TablePropertyExceptions* tapx, std::vector<short>* grid, std::vector<short>* grid_write, int& gridIndex, int cellIndex, unsigned int nestingLevel );
int writeTableCell ( int initialCp, TablePropertyExceptions* tapx, std::vector<short>* grid, int& gridIndex, int cellIndex, unsigned int nestingLevel );
int findCellEndCp ( int initialCp, unsigned int nestingLevel );

bool writeBookmarks ( int cp );
Expand All @@ -135,6 +135,8 @@ namespace DocFileFormat
// Searches the given vector for the next FieldEnd character.
int searchNextTextMark( std::vector<wchar_t>* chars, int initialCp, wchar_t mark );
Symbol getSymbol ( const CharacterPropertyExceptions* chpx );

void AddBoundary(short boundary1, short boundary2, std::map<short, short> &boundaries);
//----------------------------------------------------------------------------------------------------------------------
bool m_bInternalXmlWriter;

Expand Down
5 changes: 4 additions & 1 deletion ASCOfficeDocFile/DocDocxConverter/OpenXmlPackage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,10 @@ namespace DocFileFormat

return AddPart( mapping, L"word", fileName, VMLPictureMapping::GetContentType( blipType ), OpenXmlRelationshipTypes::Image );
}

int OpenXmlPackage::RegisterHyperlink(const IMapping* mapping, const std::wstring& link)
{
return AddPart(mapping, L"", link, L"", OpenXmlRelationshipTypes::Hyperlink, L"External");
}
int OpenXmlPackage::RegisterOLEObject(const IMapping* mapping, const std::wstring& objectType)
{
std::wstring fileName = ( std::wstring( L"embeddings/oleObject" ) + FormatUtils::IntToWideString( ++_oleCounter ) + OleObjectMapping::GetTargetExt(objectType));
Expand Down
Loading