diff --git a/Common/DocxFormat/Source/XlsxFormat/Comments/ThreadedComments.h b/Common/DocxFormat/Source/XlsxFormat/Comments/ThreadedComments.h index 7781cd998b..14980c3f6e 100644 --- a/Common/DocxFormat/Source/XlsxFormat/Comments/ThreadedComments.h +++ b/Common/DocxFormat/Source/XlsxFormat/Comments/ThreadedComments.h @@ -198,12 +198,7 @@ namespace OOX if ( L"person" == sName ) { - CPerson* pPerson = new CPerson(oReader); - if(pPerson->id.IsInit()) - { - m_mapPersonList[pPerson->id.get()] = pPerson; - } - m_arrItems.push_back(pPerson); + m_arrItems.push_back(new CPerson(oReader)); } } } @@ -240,7 +235,19 @@ namespace OOX return m_oReadPath; } public: - std::unordered_map m_mapPersonList; + const nullable> GetPersonList() + { + nullable> mapPersonList; + mapPersonList.Init(); + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + if (m_arrItems[i]->id.IsInit()) + { + (*mapPersonList)[m_arrItems[i]->id.get()] = m_arrItems[i]; + } + } + return mapPersonList; + } private: CPath m_oReadPath; void ReadAttributes(XmlUtils::CXmlLiteReader& oReader) diff --git a/XlsxSerializerCom/Writer/BinaryReader.cpp b/XlsxSerializerCom/Writer/BinaryReader.cpp index 33cd27b763..bfe3b14553 100644 --- a/XlsxSerializerCom/Writer/BinaryReader.cpp +++ b/XlsxSerializerCom/Writer/BinaryReader.cpp @@ -3481,18 +3481,21 @@ void BinaryCommentReader::parseCommentData(SerializeCommon::CommentData* pCommen { if(NULL != pCommentData && false == pCommentData->sText.empty()) { + int nLimit = OOX::Spreadsheet::SpreadsheetCommon::MAX_STRING_LEN; if (pCommentData->sUserName.empty()) { - addCommentRun(oSi, pCommentData->sText, false); + nLimit = addCommentRun(oSi, pCommentData->sText, false, nLimit); } else { - addCommentRun(oSi, pCommentData->sUserName + _T(":"), true); - addCommentRun(oSi, _T("\n") + pCommentData->sText, false); + nLimit = addCommentRun(oSi, pCommentData->sUserName + _T(":"), true, nLimit); + if (nLimit <= 0) + return; + nLimit = addCommentRun(oSi, _T("\n") + pCommentData->sText, false, nLimit); } } } -void BinaryCommentReader::addCommentRun(OOX::Spreadsheet::CSi& oSi, const std::wstring& text, bool isBold) +int BinaryCommentReader::addCommentRun(OOX::Spreadsheet::CSi& oSi, const std::wstring& text, bool isBold, int nLimit) { OOX::Spreadsheet::CRun* pRun = new OOX::Spreadsheet::CRun(); pRun->m_oRPr.Init(); @@ -3509,36 +3512,55 @@ void BinaryCommentReader::addCommentRun(OOX::Spreadsheet::CSi& oSi, const std::w pRPr.m_oSz->m_oVal->SetValue(9); OOX::Spreadsheet::CText* pText = new OOX::Spreadsheet::CText(); - pText->m_sText.append(text); + //Fix Excel recovery error; Fix bug 42968 + pText->m_sText.append(text, 0, nLimit); + nLimit -= text.length(); pRun->m_arrItems.push_back(pText); oSi.m_arrItems.push_back(pRun); + return nLimit; } -void BinaryCommentReader::addThreadedComment(OOX::Spreadsheet::CSi& oSi, OOX::Spreadsheet::CThreadedComment* pThreadedComment) +void BinaryCommentReader::addThreadedComment(OOX::Spreadsheet::CSi& oSi, OOX::Spreadsheet::CThreadedComment* pThreadedComment, nullable>& mapPersonList) { - OOX::Spreadsheet::CText* pText = new OOX::Spreadsheet::CText(); - pText->m_sText.append(L"[Threaded comment]\n\nYour version of Excel allows you to read this threaded comment; however, any edits to it will get removed if the file is opened in a newer version of Excel. Learn more: https://go.microsoft.com/fwlink/?linkid=870924\n\n"); + int nLimit = OOX::Spreadsheet::SpreadsheetCommon::MAX_STRING_LEN; if(pThreadedComment->m_oText.IsInit()) { - pText->m_sText.append(L"Comment:\n "); - pText->m_sText.append(pThreadedComment->m_oText->ToString()); - pText->m_sText.append(L"\n\n"); + std::wstring displayName = getThreadedCommentAuthor(mapPersonList, pThreadedComment->personId, L"Comment"); + nLimit = addCommentRun(oSi, displayName + L":", true, nLimit); + if (nLimit <= 0) + return; + nLimit = addCommentRun(oSi, L"\n" + pThreadedComment->m_oText->ToString() + L"\n", false, nLimit); + if (nLimit <= 0) + return; } for(size_t i = 0; i < pThreadedComment->m_arrReplies.size(); ++i) { if(pThreadedComment->m_arrReplies[i]->m_oText.IsInit()) { - pText->m_sText.append(L"Reply:\n "); - pText->m_sText.append(pThreadedComment->m_arrReplies[i]->m_oText->ToString()); - pText->m_sText.append(L"\n\n"); + std::wstring displayName = getThreadedCommentAuthor(mapPersonList, pThreadedComment->m_arrReplies[i]->personId, L"Reply"); + nLimit = addCommentRun(oSi, displayName + L":", true, nLimit); + if (nLimit <= 0) + return; + nLimit = addCommentRun(oSi, L"\n" + pThreadedComment->m_arrReplies[i]->m_oText->ToString() + L"\n", false, nLimit); + if (nLimit <= 0) + return; } } - //Fix Excel recovery error - if (pText->m_sText.length() > OOX::Spreadsheet::SpreadsheetCommon::MAX_STRING_LEN) +} +std::wstring BinaryCommentReader::getThreadedCommentAuthor(nullable>& mapPersonList, nullable& personId, const std::wstring& sDefault) +{ + if (mapPersonList.IsInit() && personId.IsInit()) { - pText->m_sText.erase(OOX::Spreadsheet::SpreadsheetCommon::MAX_STRING_LEN); + std::unordered_map::iterator it = mapPersonList->find(personId->ToString()); + if (it != mapPersonList->end()) + { + if (it->second->displayName.IsInit()) + { + return it->second->displayName.get(); + } + } } - oSi.m_arrItems.push_back(pText); + return sDefault; } BinaryWorksheetsTableReader::BinaryWorksheetsTableReader(NSBinPptxRW::CBinaryFileReader& oBufferedStream, OOX::Spreadsheet::CWorkbook& oWorkbook, @@ -4067,7 +4089,12 @@ void BinaryWorksheetsTableReader::WriteComments() pCommentItem->m_sAuthor = L"tc=" + pThreadedComment->id->ToString(); pCommentItem->m_oText.Init(); - BinaryCommentReader::addThreadedComment(pCommentItem->m_oText.get2(), pThreadedComment); + nullable> mapPersonList; + if (m_oWorkbook.m_pPersonList) + { + mapPersonList = m_oWorkbook.m_pPersonList->GetPersonList(); + } + BinaryCommentReader::addThreadedComment(pCommentItem->m_oText.get2(), pThreadedComment, mapPersonList); pThreadedComments->m_arrItems.push_back(pThreadedComment); for(size_t i = 0; i < pThreadedComment->m_arrReplies.size(); ++i) @@ -7025,6 +7052,7 @@ int BinaryPersonReader::Read() READ_TABLE_DEF(res, this->ReadPersonList, pPersonList); smart_ptr oFilePersonListFile(pPersonList); m_oWorkbook.Add(oFilePersonListFile); + m_oWorkbook.m_pPersonList = pPersonList; return res; } int BinaryPersonReader::ReadPersonList(BYTE type, long length, void* poResult) @@ -7247,6 +7275,7 @@ int BinaryFileReader::ReadMainTable(OOX::Spreadsheet::CXlsx& oXlsx, NSBinPptxRW: long nOtherOffBits = -1; long nSharedStringsOffBits = -1; long nWorkbookOffBits = -1; + long nPersonListOffBits = -1; BYTE mtLen = oBufferedStream.GetUChar(); for(int i = 0; i < mtLen; ++i) @@ -7267,6 +7296,8 @@ int BinaryFileReader::ReadMainTable(OOX::Spreadsheet::CXlsx& oXlsx, NSBinPptxRW: nSharedStringsOffBits = mtiOffBits; else if(c_oSerTableTypes::Workbook == mtiType) nWorkbookOffBits = mtiOffBits; + else if(c_oSerTableTypes::PersonList == mtiType) + nPersonListOffBits = mtiOffBits; else { aTypes.push_back(mtiType); @@ -7304,6 +7335,13 @@ int BinaryFileReader::ReadMainTable(OOX::Spreadsheet::CXlsx& oXlsx, NSBinPptxRW: if(c_oSerConstants::ReadOk != res) return res; } + if(-1 != nPersonListOffBits) + { + oBufferedStream.Seek(nPersonListOffBits); + res = BinaryPersonReader(oBufferedStream, *oXlsx.m_pWorkbook).Read(); + if(c_oSerConstants::ReadOk != res) + return res; + } for(size_t i = 0, length = aTypes.size(); i < length; ++i) { @@ -7345,11 +7383,6 @@ int BinaryFileReader::ReadMainTable(OOX::Spreadsheet::CXlsx& oXlsx, NSBinPptxRW: oXlsx.Add(oCurFile); } break; - case c_oSerTableTypes::PersonList: - { - res = BinaryPersonReader(oBufferedStream, *oXlsx.m_pWorkbook).Read(); - } - break; case c_oSerTableTypes::Styles: { oXlsx.CreateStyles(); diff --git a/XlsxSerializerCom/Writer/BinaryReader.h b/XlsxSerializerCom/Writer/BinaryReader.h index 3c49ff59dc..a979a7f3f4 100644 --- a/XlsxSerializerCom/Writer/BinaryReader.h +++ b/XlsxSerializerCom/Writer/BinaryReader.h @@ -30,6 +30,7 @@ * */ #pragma once +#include #include "../../DesktopEditor/common/StreamWriter.h" @@ -50,6 +51,7 @@ namespace OOX namespace Spreadsheet { class CPersonList; + class CPerson; class CThreadedComment; class CDxf; class CSortCondition; @@ -251,8 +253,9 @@ namespace BinXlsxRW int ReadThreadedComment(BYTE type, long length, void* poResult); int ReadThreadedCommentMention(BYTE type, long length, void* poResult); void parseCommentData(SerializeCommon::CommentData* pCommentData, OOX::Spreadsheet::CSi& oSi); - void addCommentRun(OOX::Spreadsheet::CSi& oSi, const std::wstring& text, bool isBold); - static void addThreadedComment(OOX::Spreadsheet::CSi& oSi, OOX::Spreadsheet::CThreadedComment* pThreadedComment); + static int addCommentRun(OOX::Spreadsheet::CSi& oSi, const std::wstring& text, bool isBold, int nLimit); + static void addThreadedComment(OOX::Spreadsheet::CSi& oSi, OOX::Spreadsheet::CThreadedComment* pThreadedComment, nullable>& mapPersonList); + static std::wstring getThreadedCommentAuthor(nullable>& mapPersonList, nullable& personId, const std::wstring& sDefault); }; class BinaryWorksheetsTableReader : public Binary_CommonReader {