diff --git a/Common/3dParty/boost/boost.pri b/Common/3dParty/boost/boost.pri index 7a0278cea4..7d6f30de2d 100644 --- a/Common/3dParty/boost/boost.pri +++ b/Common/3dParty/boost/boost.pri @@ -4,6 +4,7 @@ CORE_BOOST_LIBS = $$PWD/build/$$CORE_BUILDS_PLATFORM_PREFIX/lib core_ios:CONFIG += disable_enum_constexpr_conversion core_android:CONFIG += disable_enum_constexpr_conversion core_mac:CONFIG += disable_enum_constexpr_conversion +core_linux_clang:CONFIG += disable_enum_constexpr_conversion core_android { INCLUDEPATH += $$PWD/build/android/include diff --git a/Common/3dParty/html/fetch.py b/Common/3dParty/html/fetch.py index 4a0d3f5068..4107bfc2d1 100644 --- a/Common/3dParty/html/fetch.py +++ b/Common/3dParty/html/fetch.py @@ -25,3 +25,5 @@ if not base.is_dir("katana-parser"): base.replaceInFileUtf8(base_directory + "/katana-parser/src/tokenizer.c", "static inline bool2 katana_is_html_space(char c);", "static inline bool katana_is_html_space(char c);") base.replaceInFileUtf8(base_directory + "/katana-parser/src/parser.c", "katanaget_text(parser->scanner)", "/*katanaget_text(parser->scanner)*/\"error\"") base.replaceInFileUtf8(base_directory + "/katana-parser/src/parser.c", "#define KATANA_PARSER_STRING(literal) (KatanaParserString){", "#define KATANA_PARSER_STRING(literal) {") + # katana may not be able to handle an empty string correctly in some cases (bug#73485) + base.replaceInFileUtf8(base_directory + "/katana-parser/src/foundation.c", "size_t len = strlen(str);", "if (NULL == str)\n return;\n size_t len = strlen(str);") diff --git a/Common/3dParty/html/htmltoxhtml.h b/Common/3dParty/html/htmltoxhtml.h index 3fdf63a5d1..68a505e59b 100644 --- a/Common/3dParty/html/htmltoxhtml.h +++ b/Common/3dParty/html/htmltoxhtml.h @@ -19,7 +19,6 @@ static std::string nonbreaking_inline = "|a|abbr|acronym|b|bdo|big|cite|code|df static std::string empty_tags = "|area|base|basefont|bgsound|br|command|col|embed|event-source|frame|hr|image|img|input|keygen|link|menuitem|meta|param|source|spacer|track|wbr|"; static std::string preserve_whitespace = "|pre|textarea|script|style|"; static std::string special_handling = "|html|body|"; -static std::string no_entity_sub = ""; //"|style|"; static std::string treat_like_inline = "|p|"; static std::vector html_tags = {"div","span","a","img","p","h1","h2","h3","h4","h5","h6", @@ -436,9 +435,25 @@ static void substitute_xml_entities_into_text(std::string& text) replace_all(text, ">", ">"); } +// After running through Gumbo, the values of type "" are replaced with the corresponding code '0x01' +// Since the attribute value does not use control characters (value <= 0x1F), +// then just delete them, otherwise XmlUtils::CXmlLiteReader crashes on them. +// bug#73486 +static void remove_control_symbols(std::string& text) +{ + std::string::iterator itFound = std::find_if(text.begin(), text.end(), [](char chValue){ return chValue <= 0x1F; }); + + while (itFound != text.end()) + { + itFound = text.erase(itFound); + itFound = std::find_if(itFound, text.end(), [](char chValue){ return chValue <= 0x1F; }); + } +} + // Заменяет сущности " в text static void substitute_xml_entities_into_attributes(std::string& text) { + remove_control_symbols(text); substitute_xml_entities_into_text(text); replace_all(text, "\"", """); } @@ -486,7 +501,7 @@ static void build_doctype(GumboNode* node, NSStringUtils::CStringBuilderA& oBuil } } -static void build_attributes(const GumboVector* attribs, bool no_entities, NSStringUtils::CStringBuilderA& atts) +static void build_attributes(const GumboVector* attribs, NSStringUtils::CStringBuilderA& atts) { std::vector arrRepeat; for (size_t i = 0; i < attribs->length; ++i) @@ -532,8 +547,7 @@ static void build_attributes(const GumboVector* attribs, bool no_entities, NSStr std::string qs ="\""; atts.WriteString("="); atts.WriteString(qs); - if(!no_entities) - substitute_xml_entities_into_attributes(sVal); + substitute_xml_entities_into_attributes(sVal); atts.WriteString(sVal); atts.WriteString(qs); } @@ -542,7 +556,6 @@ static void build_attributes(const GumboVector* attribs, bool no_entities, NSStr static void prettyprint_contents(GumboNode* node, NSStringUtils::CStringBuilderA& contents, bool bCheckValidNode) { std::string key = "|" + get_tag_name(node) + "|"; - bool no_entity_substitution = no_entity_sub.find(key) != std::string::npos; bool keep_whitespace = preserve_whitespace.find(key) != std::string::npos; bool is_inline = nonbreaking_inline.find(key) != std::string::npos; bool is_like_inline = treat_like_inline.find(key) != std::string::npos; @@ -556,8 +569,7 @@ static void prettyprint_contents(GumboNode* node, NSStringUtils::CStringBuilderA if (child->type == GUMBO_NODE_TEXT) { std::string val(child->v.text.text); - if(!no_entity_substitution) - substitute_xml_entities_into_text(val); + substitute_xml_entities_into_text(val); // Избавление от FF size_t found = val.find_first_of("\014"); @@ -613,7 +625,6 @@ static void prettyprint(GumboNode* node, NSStringUtils::CStringBuilderA& oBuilde std::string closeTag = ""; std::string key = "|" + tagname + "|"; bool is_empty_tag = empty_tags.find(key) != std::string::npos; - bool no_entity_substitution = no_entity_sub.find(key) != std::string::npos; // determine closing tag type if (is_empty_tag) @@ -626,7 +637,7 @@ static void prettyprint(GumboNode* node, NSStringUtils::CStringBuilderA& oBuilde // build attr string const GumboVector* attribs = &node->v.element.attributes; - build_attributes(attribs, no_entity_substitution, oBuilder); + build_attributes(attribs, oBuilder); oBuilder.WriteString(close + ">"); // prettyprint your contents diff --git a/Common/OfficeFileFormatChecker.h b/Common/OfficeFileFormatChecker.h index 29fcb2c520..ac4bd1ebf8 100644 --- a/Common/OfficeFileFormatChecker.h +++ b/Common/OfficeFileFormatChecker.h @@ -103,6 +103,7 @@ public: bool isBinaryDoctFormatFile(unsigned char* pBuffer, int dwBytes); bool isBinaryXlstFormatFile(unsigned char* pBuffer, int dwBytes); bool isBinaryPpttFormatFile(unsigned char* pBuffer, int dwBytes); + bool isBinaryVsdtFormatFile(unsigned char* pBuffer, int dwBytes); bool isDjvuFormatFile(unsigned char* pBuffer, int dwBytes); bool isMobiFormatFile(unsigned char* pBuffer, int dwBytes); diff --git a/Common/OfficeFileFormatChecker2.cpp b/Common/OfficeFileFormatChecker2.cpp index 16b8c544e5..0ebc447d9f 100644 --- a/Common/OfficeFileFormatChecker2.cpp +++ b/Common/OfficeFileFormatChecker2.cpp @@ -44,6 +44,7 @@ #include "3dParty/pole/pole.h" #include +#include #include "OfficeFileFormatDefines.h" @@ -222,6 +223,16 @@ bool COfficeFileFormatChecker::isBinaryPpttFormatFile(unsigned char *pBuffer, in return false; } +bool COfficeFileFormatChecker::isBinaryVsdtFormatFile(unsigned char* pBuffer, int dwBytes) +{ + if (pBuffer == NULL) + return false; + + if ((4 <= dwBytes) && ('V' == pBuffer[0] && 'S' == pBuffer[1] && 'D' == pBuffer[2] && 'Y' == pBuffer[3])) + return true; + + return false; +} bool COfficeFileFormatChecker::isPdfFormatFile(unsigned char *pBuffer, int dwBytes, std::wstring &documentID) { if (pBuffer == NULL) @@ -823,6 +834,10 @@ bool COfficeFileFormatChecker::isOfficeFile(const std::wstring &_fileName) { nFileType = AVS_OFFICESTUDIO_FILE_CANVAS_PRESENTATION; } + else if (isBinaryVsdtFormatFile(bufferDetect, sizeRead)) // min size - 4 + { + nFileType = AVS_OFFICESTUDIO_FILE_CANVAS_DRAW; + } else if (isOOXFlatFormatFile(bufferDetect, sizeRead)) { // nFileType; @@ -1157,6 +1172,10 @@ bool COfficeFileFormatChecker::isOnlyOfficeFormatFile(const std::wstring &fileNa { nFileType = AVS_OFFICESTUDIO_FILE_TEAMLAB_PPTY; } + else if (isBinaryVsdtFormatFile(pBuffer, nBufferSize)) + { + nFileType = AVS_OFFICESTUDIO_FILE_TEAMLAB_VSDY; + } delete[] pBuffer; pBuffer = NULL; @@ -1166,58 +1185,222 @@ bool COfficeFileFormatChecker::isOnlyOfficeFormatFile(const std::wstring &fileNa } return false; } -bool COfficeFileFormatChecker::isMacFormatFile(const std::wstring& fileName) + +struct TIWAField +{ + size_t m_unStart; + size_t m_unEnd; + unsigned m_uIndex; + unsigned m_unWireType; + uint64_t m_oValue; +}; + +bool ReadUVar(BYTE* pBuffer, size_t unEndPos, size_t& unPos, uint64_t& unValue) +{ + std::vector arBytes; + arBytes.reserve(8); + + unValue = 0; + + bool bNext = true; + while (unPos < unEndPos && bNext) + { + const unsigned char c = pBuffer[unPos++]; + arBytes.push_back((unsigned char)(c & ~0x80)); + bNext = c & 0x80; + } + + if (bNext && unPos == unEndPos) + return false; + + for (std::vector::const_reverse_iterator it = arBytes.rbegin(); it != arBytes.rend(); ++it) + { + if (std::numeric_limits::max() >> 7 < unValue || + std::numeric_limits::max() - (unValue << 7) < *it) // overflow + return false; + + unValue = (unValue << 7) + *it; + } + + return true; +} + +bool ReadIWAField(BYTE* pBuffer, size_t unEndPos, size_t& unPos, TIWAField& oIWAField) +{ + if (NULL == pBuffer || unPos + 2 > unEndPos) + return false; + + unsigned uSpec; + + uSpec = (unsigned)pBuffer[unPos++]; + oIWAField.m_unWireType = uSpec & 0x7; + + oIWAField.m_unStart = unPos; + + switch (oIWAField.m_unWireType) + { + case 0: + { + if (!ReadUVar(pBuffer, unEndPos, unPos, oIWAField.m_oValue)) + return false; + + break; + } + case 1: + { + unPos += 4; + break; + } + case 2: + { + uint64_t unLen; + if (!ReadUVar(pBuffer, unEndPos, unPos, unLen) || unPos + unLen > unEndPos) + return false; + + oIWAField.m_unStart = unPos; + unPos += unLen; + break; + } + case 5: + { + unPos += 2; + break; + } + default: + return false; + } + + oIWAField.m_unEnd = unPos; + oIWAField.m_uIndex = uSpec >> 3; + + return true; +} + +bool DetectIWorkFormat(const std::wstring& fileName, int &nType) { COfficeUtils OfficeUtils(NULL); - ULONG nBufferSize = 0; + ULONG unSize = 0; BYTE* pBuffer = NULL; - HRESULT hresult = OfficeUtils.LoadFileFromArchive(fileName, L"Index/Document.iwa", &pBuffer, nBufferSize); - if (hresult == S_OK && pBuffer != NULL) + HRESULT hresult = OfficeUtils.LoadFileFromArchive(fileName, L"Index/Document.iwa", &pBuffer, unSize); + + if (hresult != S_OK || NULL == pBuffer) + return false; + + #define CLEAR_BUFFER_AND_RETURN(return_value)\ + do{\ + delete[] pBuffer;\ + return return_value;\ + }while(false) + + if (unSize < 13) + CLEAR_BUFFER_AND_RETURN(false); + + size_t uPos = 6; + + for (; uPos < 12; ++uPos) { - nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_PAGES; - - delete[] pBuffer; - pBuffer = NULL; - - hresult = OfficeUtils.LoadFileFromArchive(fileName, L"Index/Slide.iwa", &pBuffer, nBufferSize); - if (hresult == S_OK && pBuffer != NULL) + if (0x08 == pBuffer[uPos] && 0x01 == pBuffer[uPos + 1]) { - delete[] pBuffer; - pBuffer = NULL; - - nFileType = AVS_OFFICESTUDIO_FILE_PRESENTATION_KEY; - return true; + --uPos; + break; } - hresult = OfficeUtils.LoadFileFromArchive(fileName, L"Index/Tables/DataList.iwa", &pBuffer, nBufferSize); - if (hresult == S_OK && pBuffer != NULL) - { - delete[] pBuffer; - pBuffer = NULL; - - nFileType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_NUMBERS; - return true; - } - std::wstring::size_type nExtPos = fileName.rfind(L'.'); - std::wstring sExt = L"unknown"; - - if (nExtPos != std::wstring::npos) - sExt = fileName.substr(nExtPos); - - std::transform(sExt.begin(), sExt.end(), sExt.begin(), tolower); - - if (0 == sExt.compare(L".pages")) - nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_PAGES; - else if (0 == sExt.compare(L".numbers")) - nFileType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_NUMBERS; - else if (0 == sExt.compare(L".key")) - nFileType = AVS_OFFICESTUDIO_FILE_PRESENTATION_KEY; - - return true; } - return false; + + if (12 == uPos) + CLEAR_BUFFER_AND_RETURN(false); + + uint64_t unHeaderLen; + if (!ReadUVar(pBuffer, unSize, uPos, unHeaderLen)) + CLEAR_BUFFER_AND_RETURN(false); + + const size_t uStartPos = uPos; + + if (unHeaderLen < 8 || unSize < unHeaderLen + uStartPos) + CLEAR_BUFFER_AND_RETURN(false); + + uPos += 2; + + TIWAField oMessageField; + + if (!ReadIWAField(pBuffer, uStartPos + unHeaderLen, uPos, oMessageField) || 2 != oMessageField.m_unWireType || + 2 != oMessageField.m_uIndex) + CLEAR_BUFFER_AND_RETURN(false); + + size_t uSubPos = oMessageField.m_unStart; + TIWAField oField; + + if (!ReadIWAField(pBuffer, oMessageField.m_unEnd, uSubPos, oField) || 0 != oField.m_unWireType || + 1 != oField.m_uIndex) + CLEAR_BUFFER_AND_RETURN(false); + + switch (oField.m_oValue) + { + case 1: + { + uint32_t unDataLen = 0; + + TIWAField oTempField; + if (ReadIWAField(pBuffer, oMessageField.m_unEnd, uSubPos, oTempField) && + ReadIWAField(pBuffer, oMessageField.m_unEnd, uSubPos, oTempField) && 0 == oTempField.m_unWireType && + 3 == oTempField.m_uIndex) + unDataLen += oTempField.m_oValue; + + size_t unTempPos = uStartPos + unHeaderLen; + + // keynote: presentation ref in 2 + // number: sheet ref in 1 + if (ReadIWAField(pBuffer, uStartPos + unDataLen, unTempPos, oTempField) && + (2 != oTempField.m_unWireType || 1 != oTempField.m_uIndex || oTempField.m_unEnd - oTempField.m_unStart < 2)) + { + nType = AVS_OFFICESTUDIO_FILE_PRESENTATION_KEY; + CLEAR_BUFFER_AND_RETURN(true); + } + else if (ReadIWAField(pBuffer, uStartPos + unDataLen, unTempPos, oTempField) && + (2 != oTempField.m_unWireType || 2 != oTempField.m_uIndex || oTempField.m_unEnd - oTempField.m_unStart < 2)) + { + nType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_NUMBERS; + CLEAR_BUFFER_AND_RETURN(true); + } + + break; + } + case 10000: + { + nType = AVS_OFFICESTUDIO_FILE_DOCUMENT_PAGES; + CLEAR_BUFFER_AND_RETURN(true); + } + } + + CLEAR_BUFFER_AND_RETURN(false); } + +bool COfficeFileFormatChecker::isMacFormatFile(const std::wstring& fileName) +{ + if (DetectIWorkFormat(fileName, nFileType)) + return true; + + std::wstring::size_type nExtPos = fileName.rfind(L'.'); + std::wstring sExt = L"unknown"; + + if (nExtPos != std::wstring::npos) + sExt = fileName.substr(nExtPos); + + std::transform(sExt.begin(), sExt.end(), sExt.begin(), tolower); + + if (0 == sExt.compare(L".pages")) + nFileType = AVS_OFFICESTUDIO_FILE_DOCUMENT_PAGES; + else if (0 == sExt.compare(L".numbers")) + nFileType = AVS_OFFICESTUDIO_FILE_SPREADSHEET_NUMBERS; + else if (0 == sExt.compare(L".key")) + nFileType = AVS_OFFICESTUDIO_FILE_PRESENTATION_KEY; + else + return false; + + return true; +} + bool COfficeFileFormatChecker::isOpenOfficeFormatFile(const std::wstring &fileName, std::wstring &documentID) { documentID.clear(); @@ -1503,6 +1686,8 @@ std::wstring COfficeFileFormatChecker::GetExtensionByType(int type) return L".fodp"; case AVS_OFFICESTUDIO_FILE_PRESENTATION_OTP: return L".otp"; + case AVS_OFFICESTUDIO_FILE_PRESENTATION_ODG: + return L".odg"; case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX: return L".xlsx"; @@ -1577,12 +1762,15 @@ std::wstring COfficeFileFormatChecker::GetExtensionByType(int type) case AVS_OFFICESTUDIO_FILE_CANVAS_WORD: case AVS_OFFICESTUDIO_FILE_CANVAS_SPREADSHEET: case AVS_OFFICESTUDIO_FILE_CANVAS_PRESENTATION: + case AVS_OFFICESTUDIO_FILE_CANVAS_DRAW: return L".bin"; case AVS_OFFICESTUDIO_FILE_OTHER_OLD_DOCUMENT: case AVS_OFFICESTUDIO_FILE_TEAMLAB_DOCY: return L".doct"; case AVS_OFFICESTUDIO_FILE_TEAMLAB_XLSY: return L".xlst"; + case AVS_OFFICESTUDIO_FILE_TEAMLAB_VSDY: + return L".vsdt"; case AVS_OFFICESTUDIO_FILE_OTHER_OLD_PRESENTATION: case AVS_OFFICESTUDIO_FILE_OTHER_OLD_DRAWING: case AVS_OFFICESTUDIO_FILE_TEAMLAB_PPTY: @@ -1671,6 +1859,8 @@ int COfficeFileFormatChecker::GetFormatByExtension(const std::wstring &sExt) return AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP_FLAT; if (L".otp" == ext) return AVS_OFFICESTUDIO_FILE_PRESENTATION_OTP; + if (L".odg" == ext) + return AVS_OFFICESTUDIO_FILE_PRESENTATION_ODG; if (L".xlsx" == ext) return AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX; @@ -1746,6 +1936,8 @@ int COfficeFileFormatChecker::GetFormatByExtension(const std::wstring &sExt) return AVS_OFFICESTUDIO_FILE_TEAMLAB_XLSY; if (L".pptt" == ext) return AVS_OFFICESTUDIO_FILE_TEAMLAB_PPTY; + if (L".vsdt" == ext) + return AVS_OFFICESTUDIO_FILE_TEAMLAB_VSDY; if (L".vsdx" == ext) return AVS_OFFICESTUDIO_FILE_DRAW_VSDX; diff --git a/Common/OfficeFileFormats.h b/Common/OfficeFileFormats.h index 6612113c6a..5d3916cee6 100644 --- a/Common/OfficeFileFormats.h +++ b/Common/OfficeFileFormats.h @@ -139,12 +139,14 @@ #define AVS_OFFICESTUDIO_FILE_TEAMLAB_DOCY AVS_OFFICESTUDIO_FILE_TEAMLAB + 0x0001 #define AVS_OFFICESTUDIO_FILE_TEAMLAB_XLSY AVS_OFFICESTUDIO_FILE_TEAMLAB + 0x0002 #define AVS_OFFICESTUDIO_FILE_TEAMLAB_PPTY AVS_OFFICESTUDIO_FILE_TEAMLAB + 0x0003 +#define AVS_OFFICESTUDIO_FILE_TEAMLAB_VSDY AVS_OFFICESTUDIO_FILE_TEAMLAB + 0x0004 #define AVS_OFFICESTUDIO_FILE_CANVAS 0x2000 #define AVS_OFFICESTUDIO_FILE_CANVAS_WORD AVS_OFFICESTUDIO_FILE_CANVAS + 0x0001 #define AVS_OFFICESTUDIO_FILE_CANVAS_SPREADSHEET AVS_OFFICESTUDIO_FILE_CANVAS + 0x0002 #define AVS_OFFICESTUDIO_FILE_CANVAS_PRESENTATION AVS_OFFICESTUDIO_FILE_CANVAS + 0x0003 #define AVS_OFFICESTUDIO_FILE_CANVAS_PDF AVS_OFFICESTUDIO_FILE_CANVAS + 0x0004 +#define AVS_OFFICESTUDIO_FILE_CANVAS_DRAW AVS_OFFICESTUDIO_FILE_CANVAS + 0x0005 #define AVS_OFFICESTUDIO_FILE_DRAW 0x4000 #define AVS_OFFICESTUDIO_FILE_DRAW_VSDX AVS_OFFICESTUDIO_FILE_DRAW + 0x0001 @@ -152,4 +154,4 @@ #define AVS_OFFICESTUDIO_FILE_DRAW_VSTX AVS_OFFICESTUDIO_FILE_DRAW + 0x0003 #define AVS_OFFICESTUDIO_FILE_DRAW_VSDM AVS_OFFICESTUDIO_FILE_DRAW + 0x0004 #define AVS_OFFICESTUDIO_FILE_DRAW_VSSM AVS_OFFICESTUDIO_FILE_DRAW + 0x0005 -#define AVS_OFFICESTUDIO_FILE_DRAW_VSTM AVS_OFFICESTUDIO_FILE_DRAW + 0x0006 +#define AVS_OFFICESTUDIO_FILE_DRAW_VSTM AVS_OFFICESTUDIO_FILE_DRAW + 0x0006 \ No newline at end of file diff --git a/Common/base.pri b/Common/base.pri index e8dc81b132..8e240dfcf5 100644 --- a/Common/base.pri +++ b/Common/base.pri @@ -109,6 +109,31 @@ win32:!contains(QMAKE_TARGET.arch, x86_64): { CONFIG += core_win_32 } +linux-clang-libc++ { + CONFIG += core_linux + CONFIG += core_linux_64 + CONFIG += core_linux_clang + message("linux-64-clang-libc++") +} +linux-clang-libc++-32 { + CONFIG += core_linux + CONFIG += core_linux_32 + CONFIG += core_linux_clang + message("linux-32-clang-libc++") +} +linux-clang { + CONFIG += core_linux + CONFIG += core_linux_64 + CONFIG += core_linux_clang + message("linux-64-clang") +} +linux-clang-32 { + CONFIG += core_linux + CONFIG += core_linux_32 + CONFIG += core_linux_clang + message("linux-32-clang") +} + linux-g++ { CONFIG += core_linux linux-g++:contains(QMAKE_HOST.arch, x86_64): { @@ -196,6 +221,10 @@ core_mac { } } +core_linux_clang { + QMAKE_CFLAGS += -Wno-implicit-function-declaration +} + # PREFIXES core_windows { CONFIG -= debug_and_release debug_and_release_target @@ -416,6 +445,12 @@ message($$CORE_BUILDS_PLATFORM_PREFIX/$$CORE_BUILDS_CONFIGURATION_PREFIX) # COMPILER CONFIG += c++11 +#CONFIG += enable_cpp_17 +enable_cpp_17 { + CONFIG += c++1z + DEFINES += _LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION +} + !core_windows { QMAKE_CXXFLAGS += -Wno-register QMAKE_CFLAGS += -Wno-register @@ -423,7 +458,11 @@ CONFIG += c++11 core_linux { core_static_link_libstd { - QMAKE_LFLAGS += -static-libstdc++ -static-libgcc + !core_linux_clang { + QMAKE_LFLAGS += -static-libstdc++ -static-libgcc + } else { + # TODO: add libc++abi? + } message(core_static_link_libstd) } plugin { diff --git a/DesktopEditor/agg-2.4/include/agg_pixfmt_rgba.h b/DesktopEditor/agg-2.4/include/agg_pixfmt_rgba.h index 50b4e28494..1365926a27 100644 --- a/DesktopEditor/agg-2.4/include/agg_pixfmt_rgba.h +++ b/DesktopEditor/agg-2.4/include/agg_pixfmt_rgba.h @@ -207,9 +207,9 @@ namespace agg } p[Order::A] = (value_type)((alpha + a) - ((alpha * a + base_mask) >> base_shift)); - p[Order::R] = (value_type)((alpha * cr + a * r - ((a * r * alpha + base_mask) >> base_shift)) / p[Order::A]); - p[Order::G] = (value_type)((alpha * cg + a * g - ((a * g * alpha + base_mask) >> base_shift)) / p[Order::A]); - p[Order::B] = (value_type)((alpha * cb + a * b - ((a * b * alpha + base_mask) >> base_shift)) / p[Order::A]); + if (r != cr) p[Order::R] = (value_type)((alpha * cr + a * r - ((a * r * alpha + base_mask) >> base_shift)) / p[Order::A]); + if (g != cg) p[Order::G] = (value_type)((alpha * cg + a * g - ((a * g * alpha + base_mask) >> base_shift)) / p[Order::A]); + if (b != cb) p[Order::B] = (value_type)((alpha * cb + a * b - ((a * b * alpha + base_mask) >> base_shift)) / p[Order::A]); } static AGG_INLINE void blend_pix_subpix(value_type* p, diff --git a/DesktopEditor/common/StringBuilder.cpp b/DesktopEditor/common/StringBuilder.cpp index 99f4eb626b..e86786565d 100644 --- a/DesktopEditor/common/StringBuilder.cpp +++ b/DesktopEditor/common/StringBuilder.cpp @@ -319,7 +319,14 @@ namespace NSStringUtils { WriteEncodeXmlString(sString.c_str(), (int)sString.length()); } - + void CStringBuilder::WriteEncodeXmlString(const std::string& sString) + { + WriteEncodeXmlString(std::wstring(sString.begin(), sString.end())); + } + void CStringBuilder::WriteUtf8EncodeXmlString(const std::string& sString) + { + WriteEncodeXmlString(NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)sString.c_str(), sString.size())); + } void CStringBuilder::WriteEncodeXmlString(const wchar_t* pString, int nCount) { if (sizeof(wchar_t) == 2) diff --git a/DesktopEditor/common/StringBuilder.h b/DesktopEditor/common/StringBuilder.h index e07a734d8f..f822a8b801 100644 --- a/DesktopEditor/common/StringBuilder.h +++ b/DesktopEditor/common/StringBuilder.h @@ -110,6 +110,9 @@ namespace NSStringUtils void WriteEncodeXmlString(const std::wstring& sString); void WriteEncodeXmlString(const wchar_t* pString, int nCount = -1); + void WriteEncodeXmlString(const std::string& sString); + void WriteUtf8EncodeXmlString(const std::string& sString); + void WriteEncodeXmlStringHHHH(const std::wstring& sString); void WriteEncodeXmlStringHHHH(const wchar_t* pString, int nCount = -1); diff --git a/DesktopEditor/cximage/png/pngpriv.h b/DesktopEditor/cximage/png/pngpriv.h index 8bdccccafb..61b95b4c68 100644 --- a/DesktopEditor/cximage/png/pngpriv.h +++ b/DesktopEditor/cximage/png/pngpriv.h @@ -332,6 +332,7 @@ * DBL_MAX Maximum floating point number (can be set to an arbitrary value) */ # include +# include # if (defined(__MWERKS__) && defined(macintosh)) || defined(applec) || \ defined(THINK_C) || defined(__SC__) || defined(TARGET_OS_MAC) diff --git a/DesktopEditor/doctrenderer/addon/docbuilder_addon.h b/DesktopEditor/doctrenderer/addon/docbuilder_addon.h index 7e5bf747ad..ae9b5f8445 100644 --- a/DesktopEditor/doctrenderer/addon/docbuilder_addon.h +++ b/DesktopEditor/doctrenderer/addon/docbuilder_addon.h @@ -33,6 +33,7 @@ #define DOC_BUILDER_ADDON_PRIVATE #include +#include "../docbuilder.h" namespace NSDoctRenderer { @@ -46,11 +47,11 @@ namespace NSDoctRenderer m_sWorkDirectory = sWorkDir; } public: - std::wstring GetX2tSaveAddon() + std::wstring GetX2tSaveAddon(NSDoctRenderer::CDocBuilder* builder, const int& filetype) { return L""; } - int GetX2tPreSaveError() + int GetX2tPreSaveError(NSDoctRenderer::CDocBuilder* builder, const int& filetype) { return 0; } diff --git a/DesktopEditor/doctrenderer/app_builder/main.cpp b/DesktopEditor/doctrenderer/app_builder/main.cpp index 0507c86a16..c05bfc26a2 100644 --- a/DesktopEditor/doctrenderer/app_builder/main.cpp +++ b/DesktopEditor/doctrenderer/app_builder/main.cpp @@ -33,6 +33,7 @@ #include "./../common_deploy.h" #include "../docbuilder.h" #include "../../common/File.h" +#include "../../common/SystemUtils.h" #ifdef LINUX #include "../../../DesktopEditor/common/File.h" @@ -78,6 +79,15 @@ void parse_args(NSDoctRenderer::CDocBuilder* builder, int argc, char *argv[]) } } +bool CheckLicense(const std::wstring& sSrc, const std::wstring& sDst) +{ + if (sDst.empty()) + return false; + NSFile::CFileBinary::Remove(sDst); + NSFile::CFileBinary::Copy(sSrc, sDst); + return NSFile::CFileBinary::Exists(sDst); +} + #ifdef WIN32 int wmain(int argc, wchar_t *argv[]) #else @@ -89,6 +99,7 @@ int main(int argc, char *argv[]) bool bIsHelp = false; bool bIsFonts = false; + bool bIsLicense = false; for (int i = 0; i < argc; ++i) { #ifdef WIN32 @@ -121,6 +132,33 @@ int main(int argc, char *argv[]) { bIsFonts = true; } + else if (sParam == "-register") + { + bIsLicense = true; + } + else + { + if (bIsLicense) + { + std::wstring sLicensePathSrc = UTF8_TO_U(sParam); + if (!NSFile::CFileBinary::Exists(sLicensePathSrc)) + return 1; + + std::wstring sLicensePath = NSSystemUtils::GetEnvVariable(L"ONLYOFFICE_BUILDER_LICENSE"); + if (CheckLicense(sLicensePathSrc, sLicensePath)) + return 0; + + sLicensePath = NSFile::GetProcessDirectory() + L"/license.xml"; + if (CheckLicense(sLicensePathSrc, sLicensePath)) + return 0; + + sLicensePath = NSSystemUtils::GetAppDataDir() + L"/docbuilder/license.xml"; + if (CheckLicense(sLicensePathSrc, sLicensePath)) + return 0; + + return 1; + } + } } if (bIsFonts) diff --git a/DesktopEditor/doctrenderer/docbuilder.h b/DesktopEditor/doctrenderer/docbuilder.h index 5580500cbf..bb0ac82202 100644 --- a/DesktopEditor/doctrenderer/docbuilder.h +++ b/DesktopEditor/doctrenderer/docbuilder.h @@ -475,6 +475,13 @@ namespace NSDoctRenderer */ void SetPropertyW(const wchar_t* param, const wchar_t* value); + /** + * GetProperty method. + * @param param The parameter name in the Unicode format, the value is always --argument. + * @return int value for property + */ + int GetPropertyInt(const wchar_t* param); + /** * Writes data to the log file. It is used for logs in JS code. * @param path The path to the file where all the logs will be written. diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py index ac06615386..e557ff6385 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py @@ -2,6 +2,7 @@ import ctypes import os import platform import atexit +import subprocess OBJECT_HANDLE = ctypes.c_void_p STRING_HANDLE = ctypes.c_void_p @@ -608,8 +609,17 @@ class FileTypes: PNG = _IMAGE_MASK + 0x0005 BMP = _IMAGE_MASK + 0x0008 +# NOTE: do not change builder_path manually! builder_path = os.path.dirname(os.path.realpath(__file__)) _loadLibrary(builder_path) CDocBuilder.Initialize(builder_path) +def registerLibrary(license_path): + docbuilder_bin = os.path.join(builder_path, "docbuilder") + if ("windows" == platform.system().lower()): + docbuilder_bin += ".exe" + return subprocess.call([docbuilder_bin, "-register", license_path], stderr=subprocess.STDOUT, shell=True) + command = docbuilder_bin + " -register \"" + license_path.replace('\"', '\\\"') + "\"" + return subprocess.call(command, stderr=subprocess.STDOUT, shell=True) + atexit.register(CDocBuilder.Dispose) diff --git a/DesktopEditor/doctrenderer/docbuilder_p.cpp b/DesktopEditor/doctrenderer/docbuilder_p.cpp index adb3c60f56..d1c7d73e63 100644 --- a/DesktopEditor/doctrenderer/docbuilder_p.cpp +++ b/DesktopEditor/doctrenderer/docbuilder_p.cpp @@ -1596,6 +1596,15 @@ namespace NSDoctRenderer return this->SetProperty(sA.c_str(), value); } + int CDocBuilder::GetPropertyInt(const wchar_t* param) + { + std::wstring sParam = std::wstring(param); + std::string sParamA = U_TO_UTF8(sParam); + if ("--save-use-only-names" == sParamA) + return m_pInternal->m_bIsServerSafeVersion ? 1 : 0; + return -1; + } + void CDocBuilder::Initialize(const wchar_t* directory) { std::wstring sDirectory = L""; diff --git a/DesktopEditor/doctrenderer/docbuilder_p.h b/DesktopEditor/doctrenderer/docbuilder_p.h index 6603297f22..d0d18f612b 100644 --- a/DesktopEditor/doctrenderer/docbuilder_p.h +++ b/DesktopEditor/doctrenderer/docbuilder_p.h @@ -1003,7 +1003,7 @@ namespace NSDoctRenderer CDocBuilderAddon oSaveAddon(m_sX2tPath); - int nPreSaveError = oSaveAddon.GetX2tPreSaveError(); + int nPreSaveError = oSaveAddon.GetX2tPreSaveError(m_pParent, m_nFileType); if (0 != nPreSaveError) return nPreSaveError; @@ -1090,7 +1090,7 @@ namespace NSDoctRenderer if (!sOptions.empty()) oBuilder.WriteString(UTF8_TO_U(sOptions)); - oBuilder.WriteString(oSaveAddon.GetX2tSaveAddon()); + oBuilder.WriteString(oSaveAddon.GetX2tSaveAddon(m_pParent, m_nFileType)); oBuilder.WriteString(L""); diff --git a/DesktopEditor/doctrenderer/drawingfile.h b/DesktopEditor/doctrenderer/drawingfile.h index 9cb406f0dd..b6433c67cd 100644 --- a/DesktopEditor/doctrenderer/drawingfile.h +++ b/DesktopEditor/doctrenderer/drawingfile.h @@ -171,7 +171,6 @@ public: return m_pFile ? true : false; } - bool OpenFile(BYTE* data, LONG size, const std::wstring& sPassword) { CloseFile(); @@ -284,6 +283,18 @@ public: return NULL; return m_pFile->ConvertToPixels(nPageIndex, nRasterW, nRasterH, true, m_pFontManager, nBackgroundColor, (nBackgroundColor == 0xFFFFFF) ? false : true); } + BYTE* SplitPages(int* arrPageIndex, int nLength) + { + if (m_nType == 0) + return ((CPdfFile*)m_pFile)->SplitPages(arrPageIndex, nLength); + return NULL; + } + bool MergePages(BYTE* data, LONG size, int nMaxID, const std::string& sPrefixForm) + { + if (m_nType == 0) + return ((CPdfFile*)m_pFile)->MergePages(data, size, nMaxID, sPrefixForm); + return false; + } BYTE* GetGlyphs(int nPageIndex) { diff --git a/DesktopEditor/doctrenderer/embed/GraphicsEmbed.cpp b/DesktopEditor/doctrenderer/embed/GraphicsEmbed.cpp index 15bbc60574..f20a2c57e3 100644 --- a/DesktopEditor/doctrenderer/embed/GraphicsEmbed.cpp +++ b/DesktopEditor/doctrenderer/embed/GraphicsEmbed.cpp @@ -165,9 +165,14 @@ JSSmart CGraphicsEmbed::create(JSSmart Native, JSSmart pNativeObject = Native->toObject(); CJSEmbedObject* pNativeEmbedObject = pNativeObject->getNative(); - if (m_pInternal->m_pAppImage) + if (m_pInternal->m_pAppImage && pNativeEmbedObject) + { delete m_pInternal->m_pAppImage; - m_pInternal->m_pAppImage = new CGraphicsAppImage(); + m_pInternal->m_pAppImage = NULL; + } + + if (NULL == m_pInternal->m_pAppImage) + m_pInternal->m_pAppImage = new CGraphicsAppImage(); if (pNativeEmbedObject) { diff --git a/DesktopEditor/fontengine/TextShaper.cpp b/DesktopEditor/fontengine/TextShaper.cpp index 4e509d5cc8..0b2025e5f8 100644 --- a/DesktopEditor/fontengine/TextShaper.cpp +++ b/DesktopEditor/fontengine/TextShaper.cpp @@ -451,7 +451,7 @@ namespace NSShaper CheckUnicodeFaceName(face, family_name, family_name_len); unsigned int nLen1 = (unsigned int)family_name_len; - unsigned int nLen2 = (unsigned int)strlen(face->style_name); + unsigned int nLen2 = (unsigned int)((face->style_name != NULL) ? strlen(face->style_name) : 0); unsigned int nLen = 28 + nLen1 + 1 + nLen2 + 1 + 1 + (int)face->num_fixed_sizes; @@ -693,6 +693,13 @@ namespace NSShaper g_userfeatures_init = true; } + // Turn on ligatures on arabic script + if (nScript == HB_SCRIPT_ARABIC || + nScript == HB_SCRIPT_SYRIAC) + { + nFeatures |= 1; + } + // font hb_font_t* pFont; if (NULL == font) diff --git a/DesktopEditor/fontengine/TextShaper_p.h b/DesktopEditor/fontengine/TextShaper_p.h index 27ec01cdf9..3c8f0933f1 100644 --- a/DesktopEditor/fontengine/TextShaper_p.h +++ b/DesktopEditor/fontengine/TextShaper_p.h @@ -94,11 +94,14 @@ void CheckUnicodeFaceName(FT_Face pFace, int*& UName, unsigned int& ULen) bool isBadASCII = false; unsigned int face_name_len = 0; - while ('\0' != face_name[face_name_len]) + if (NULL != face_name) { - if ('?' == face_name[face_name_len]) - isBadASCII = true; - ++face_name_len; + while ('\0' != face_name[face_name_len]) + { + if ('?' == face_name[face_name_len]) + isBadASCII = true; + ++face_name_len; + } } if (face_name_len > 6 && diff --git a/DesktopEditor/fontengine/js/cpp/text.cpp b/DesktopEditor/fontengine/js/cpp/text.cpp index 9857242738..63503a3dea 100644 --- a/DesktopEditor/fontengine/js/cpp/text.cpp +++ b/DesktopEditor/fontengine/js/cpp/text.cpp @@ -594,6 +594,13 @@ WASM_EXPORT unsigned char* ASC_HB_ShapeText(FT_Face pFace, hb_font_t* pFont, cha g_userfeatures_init = true; } + // Turn on ligatures on arabic script + if (nScript == HB_SCRIPT_ARABIC || + nScript == HB_SCRIPT_SYRIAC) + { + nFeatures |= 1; + } + // font if (NULL == pFont) { diff --git a/DesktopEditor/graphics/commands/AnnotField.cpp b/DesktopEditor/graphics/commands/AnnotField.cpp index c5cb83d205..72a159a22e 100644 --- a/DesktopEditor/graphics/commands/AnnotField.cpp +++ b/DesktopEditor/graphics/commands/AnnotField.cpp @@ -214,6 +214,7 @@ int CAnnotFieldInfo::GetFlag() const { return m_nFlag; } int CAnnotFieldInfo::GetID() const { return m_nID; } int CAnnotFieldInfo::GetAnnotFlag() const { return m_nAnnotFlag; } int CAnnotFieldInfo::GetPage() const { return m_nPage; } +int CAnnotFieldInfo::GetCopyAP() const { return m_nCopyAP; } void CAnnotFieldInfo::GetBE(BYTE& nS, double& dI) { nS = m_pBE.first; dI = m_pBE.second; } BYTE* CAnnotFieldInfo::GetRender(LONG& nLen) { @@ -359,6 +360,8 @@ bool CAnnotFieldInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMeta } if (nFlags & (1 << 7)) m_wsOUserID = pReader->ReadString(); + if (nFlags & (1 << 8)) + m_nCopyAP = pReader->ReadInt(); if (IsMarkup()) { @@ -985,7 +988,7 @@ void CAnnotFieldInfo::CWidgetAnnotPr::CTextWidgetPr::Read(NSOnlineOfficeBinToPdf m_wsV = pReader->ReadString(); if (nFlags & (1 << 10)) m_nMaxLen = pReader->ReadInt(); - if (nWidgetFlag & (1 << 25)) + if (nFlags & (1 << 11)) m_wsRV = pReader->ReadString(); if (nFlags & (1 << 12)) m_wsAPV = pReader->ReadString(); @@ -1104,6 +1107,36 @@ bool CWidgetsInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafil for (int i = 0; i < n; ++i) pParent->arrV.push_back(pReader->ReadString()); } + if (nFlags & (1 << 6)) + { + int n = pReader->ReadInt(); + pParent->arrOpt.reserve(n); + for (int i = 0; i < n; ++i) + { + std::wstring s1 = pReader->ReadString(); + std::wstring s2 = pReader->ReadString(); + pParent->arrOpt.push_back(std::make_pair(s1, s2)); + } + } + if (nFlags & (1 << 7)) + pParent->nFieldFlag = pReader->ReadInt(); + if (nFlags & (1 << 8)) + { + // Action + int nAction = pReader->ReadInt(); + for (int i = 0; i < nAction; ++i) + { + std::wstring wsType = pReader->ReadString(); + CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget* pA = ReadAction(pReader); + if (pA) + { + pA->wsType = wsType; + pParent->arrAction.push_back(pA); + } + } + } + if (nFlags & (1 << 9)) + pParent->nMaxLen = pReader->ReadInt(); m_arrParents.push_back(pParent); } diff --git a/DesktopEditor/graphics/commands/AnnotField.h b/DesktopEditor/graphics/commands/AnnotField.h index fe054d3500..e546fa0cb3 100644 --- a/DesktopEditor/graphics/commands/AnnotField.h +++ b/DesktopEditor/graphics/commands/AnnotField.h @@ -465,6 +465,7 @@ public: int GetID() const; int GetAnnotFlag() const; int GetPage() const; + int GetCopyAP() const; void GetBE(BYTE& nS, double& dI); BYTE* GetRender(LONG& nLen); const std::wstring& GetNM(); @@ -522,6 +523,7 @@ private: int m_nID; int m_nAnnotFlag; int m_nPage; + int m_nCopyAP; std::wstring m_wsNM; std::wstring m_wsLM; std::wstring m_wsOUserID; @@ -567,12 +569,16 @@ public: { int nID; int nFlags; + int nMaxLen; int nParentID; + int nFieldFlag; std::wstring sName; std::wstring sV; std::wstring sDV; std::vector arrI; std::vector arrV; + std::vector arrAction; + std::vector< std::pair > arrOpt; }; CWidgetsInfo(); diff --git a/DesktopEditor/graphics/pro/js/drawingfile.json b/DesktopEditor/graphics/pro/js/drawingfile.json index 681f8f2b6b..efd27ff4eb 100644 --- a/DesktopEditor/graphics/pro/js/drawingfile.json +++ b/DesktopEditor/graphics/pro/js/drawingfile.json @@ -51,6 +51,8 @@ "_IsNeedCMap", "_SetCMapData", "_ScanPage", + "_SplitPages", + "_MergePages", "_GetImageBase64", "_GetImageBase64Len", "_GetImageBase64Ptr", @@ -86,7 +88,7 @@ "NO_CONSOLE_IO", "USE_EXTERNAL_JPEG2000", "USE_JPIP", "OPJ_STATIC", "FONT_ENGINE_DISABLE_FILESYSTEM", "IMAGE_CHECKER_DISABLE_XML", "USE_OPENSSL_HASH", - "DISABLE_FULL_DOCUMENT_CREATION", "DISABLE_FILESYSTEM" + "DISABLE_FULL_DOCUMENT_CREATION", "DISABLE_FILESYSTEM", "CRYPTOPP_DISABLE_ASM", "DISABLE_TYPE_MISMATCH" ], "compile_files_array": [ { @@ -135,7 +137,7 @@ }, { "folder": "./wasm/src/", - "files": ["lib/wasm_jmp.cpp", "drawingfile.cpp", "metafile.cpp", "pdfwriter.cpp", "HTMLRendererText.cpp"] + "files": ["lib/wasm_jmp.cpp", "drawingfile.cpp", "metafile.cpp", "HTMLRendererText.cpp"] }, { "folder": "freetype-2.10.4/src/", @@ -143,7 +145,7 @@ }, { "folder": "../../", - "files": ["GraphicsRenderer.cpp", "pro/pro_Graphics.cpp", "pro/pro_Fonts.cpp", "pro/pro_Image.cpp", "Graphics.cpp", "Brush.cpp", "BaseThread.cpp", "GraphicsPath.cpp", "BooleanOperations.cpp", "Image.cpp", "Matrix.cpp", "Clip.cpp", "TemporaryCS.cpp", "AlphaMask.cpp", "GraphicsLayer.cpp", "commands/DocInfo.cpp", "commands/AnnotField.cpp", "commands/FormField.cpp"] + "files": ["GraphicsRenderer.cpp", "pro/pro_Graphics.cpp", "pro/pro_Fonts.cpp", "pro/pro_Image.cpp", "Graphics.cpp", "Brush.cpp", "BaseThread.cpp", "GraphicsPath.cpp", "BooleanOperations.cpp", "Image.cpp", "Matrix.cpp", "Clip.cpp", "TemporaryCS.cpp", "AlphaMask.cpp", "GraphicsLayer.cpp", "commands/DocInfo.cpp", "commands/AnnotField.cpp", "commands/FormField.cpp", "MetafileToRenderer.cpp", "MetafileToRendererReader.cpp"] }, { "folder": "../../../fontengine/", @@ -155,12 +157,16 @@ }, { "folder": "../../../common/", - "files": ["File.cpp", "Directory.cpp", "ByteBuilder.cpp", "Base64.cpp", "StringExt.cpp", "Path.cpp"] + "files": ["File.cpp", "Directory.cpp", "ByteBuilder.cpp", "Base64.cpp", "StringExt.cpp", "Path.cpp", "SystemUtils.cpp"] }, { "folder": "../../../../Common/3dParty/icu/icu/source/common/", "files": ["ucnv.c", "ustr_wcs.cpp", "ucnv_err.c", "ucnv_bld.cpp", "ustrtrns.cpp", "ucnv_cb.c", "udata.cpp", "ucnv_io.cpp", "uhash.c", "udatamem.c", "cmemory.c", "ustring.cpp", "umutex.cpp", "putil.cpp", "ustr_cnv.cpp", "ucnvmbcs.cpp", "ucnvlat1.c", "ucnv_u16.c", "ucnv_u8.c", "ucnv_u32.c", "ucnv_u7.c", "ucln_cmn.cpp", "ucnv2022.cpp", "ucnv_lmb.c", "ucnvhz.c", "ucnvscsu.c", "ucnvisci.c", "ucnvbocu.cpp", "ucnv_ct.c", "ucnv_cnv.c", "stringpiece.cpp", "charstr.cpp", "umapfile.c", "ucmndata.c", "ucnv_ext.cpp", "uobject.cpp", "umath.c", "ubidi_props.c", "uchar.c", "uinvchar.c", "usprep.cpp", "unistr.cpp", "uniset_props.cpp", "loadednormalizer2impl.cpp", "filterednormalizer2.cpp", "utrie2.cpp", "normalizer2.cpp", "normalizer2impl.cpp", "utrie.cpp", "ucase.cpp", "uniset.cpp", "ruleiter.cpp", "parsepos.cpp", "util.cpp", "uprops.cpp", "uvector.cpp", "unames.cpp", "propname.cpp", "utrie2_builder.cpp", "unifunct.cpp", "bmpset.cpp", "unisetspan.cpp", "unifilt.cpp", "patternprops.cpp", "utf_impl.c", "ustrcase.cpp", "cstring.c", "bytestrie.cpp"] }, + { + "folder": "../../../../Common/3dParty/cryptopp/", + "files": ["cryptlib.cpp", "cpu.cpp", "integer.cpp", "3way.cpp", "adler32.cpp", "algebra.cpp", "algparam.cpp", "allocate.cpp", "arc4.cpp", "aria.cpp", "aria_simd.cpp", "ariatab.cpp", "asn.cpp", "authenc.cpp", "base32.cpp", "base64.cpp", "basecode.cpp", "bfinit.cpp", "blake2.cpp", "blake2s_simd.cpp", "blake2b_simd.cpp", "blowfish.cpp", "blumshub.cpp", "camellia.cpp", "cast.cpp", "casts.cpp", "cbcmac.cpp", "ccm.cpp", "chacha.cpp", "chacha_simd.cpp", "chacha_avx.cpp", "chachapoly.cpp", "cham.cpp", "cham_simd.cpp", "channels.cpp", "cmac.cpp", "crc.cpp", "crc_simd.cpp", "darn.cpp", "default.cpp", "des.cpp", "dessp.cpp", "dh.cpp", "dh2.cpp", "dll.cpp", "donna_32.cpp", "donna_64.cpp", "donna_sse.cpp", "dsa.cpp", "eax.cpp", "ec2n.cpp", "ecp.cpp", "eccrypto.cpp", "eprecomp.cpp", "elgamal.cpp", "emsa2.cpp", "eprecomp.cpp", "esign.cpp", "files.cpp", "filters.cpp", "fips140.cpp", "gcm.cpp", "gcm_simd.cpp", "gf256.cpp", "gf2_32.cpp", "gf2n.cpp", "gf2n_simd.cpp", "gfpcrypt.cpp", "gost.cpp", "gzip.cpp", "hc128.cpp", "hc256.cpp", "hex.cpp", "hight.cpp", "hmac.cpp", "hrtimer.cpp", "ida.cpp", "idea.cpp", "iterhash.cpp", "kalyna.cpp", "md5.cpp", "randpool.cpp", "osrng.cpp", "rijndael.cpp", "modes.cpp", "misc.cpp", "rdtables.cpp", "sha.cpp", "mqueue.cpp", "queue.cpp"] + }, { "folder": "../../../../OfficeUtils/src/", "files": ["OfficeUtils.cpp", "ZipBuffer.cpp", "ZipUtilsCP.cpp", "zlib_addon.c"] @@ -179,7 +185,23 @@ }, { "folder": "../../../../PdfFile/", - "files": ["SrcReader/Adaptors.cpp", "SrcReader/GfxClip.cpp", "SrcReader/RendererOutputDev.cpp", "SrcReader/JPXStream2.cpp", "SrcReader/PdfAnnot.cpp", "Resources/BaseFonts.cpp", "Resources/CMapMemory/cmap_memory.cpp", "lib/fofi/FofiBase.cc", "lib/fofi/FofiEncodings.cc", "lib/fofi/FofiIdentifier.cc", "lib/fofi/FofiTrueType.cc", "lib/fofi/FofiType1.cc", "lib/fofi/FofiType1C.cc", "lib/goo/FixedPoint.cc", "lib/goo/gfile.cc", "lib/goo/GHash.cc", "lib/goo/GList.cc", "lib/goo/gmem.cc", "lib/goo/gmempp.cc", "lib/goo/GString.cc", "lib/goo/parseargs.c", "lib/goo/Trace.cc", "lib/splash/Splash.cc", "lib/splash/SplashBitmap.cc", "lib/splash/SplashClip.cc", "lib/splash/SplashFont.cc", "lib/splash/SplashFontEngine.cc", "lib/splash/SplashFontFile.cc", "lib/splash/SplashFontFileID.cc", "lib/splash/SplashFTFont.cc", "lib/splash/SplashFTFontEngine.cc", "lib/splash/SplashFTFontFile.cc", "lib/splash/SplashPath.cc", "lib/splash/SplashPattern.cc", "lib/splash/SplashScreen.cc", "lib/splash/SplashState.cc", "lib/splash/SplashXPath.cc", "lib/splash/SplashXPathScanner.cc", "lib/xpdf/AcroForm.cc", "lib/xpdf/Annot.cc", "lib/xpdf/Array.cc", "lib/xpdf/BuiltinFont.cc", "lib/xpdf/BuiltinFontTables.cc", "lib/xpdf/Catalog.cc", "lib/xpdf/CharCodeToUnicode.cc", "lib/xpdf/CMap.cc", "lib/xpdf/Decrypt.cc", "lib/xpdf/Dict.cc", "lib/xpdf/DisplayState.cc", "lib/xpdf/Error.cc", "lib/xpdf/FontEncodingTables.cc", "lib/xpdf/Function.cc", "lib/xpdf/Gfx.cc", "lib/xpdf/GfxFont.cc", "lib/xpdf/GfxState.cc", "lib/xpdf/GlobalParams.cc", "lib/xpdf/ImageOutputDev.cc", "lib/xpdf/JArithmeticDecoder.cc", "lib/xpdf/JBIG2Stream.cc", "lib/xpdf/JPXStream.cc", "lib/xpdf/Lexer.cc", "lib/xpdf/Link.cc", "lib/xpdf/NameToCharCode.cc", "lib/xpdf/Object.cc", "lib/xpdf/OptionalContent.cc", "lib/xpdf/Outline.cc", "lib/xpdf/OutputDev.cc", "lib/xpdf/Page.cc", "lib/xpdf/Parser.cc", "lib/xpdf/PDF417Barcode.cc", "lib/xpdf/PDFCore.cc", "lib/xpdf/PDFDoc.cc", "lib/xpdf/PDFDocEncoding.cc", "lib/xpdf/PreScanOutputDev.cc", "lib/xpdf/PSOutputDev.cc", "lib/xpdf/PSTokenizer.cc", "lib/xpdf/SecurityHandler.cc", "lib/xpdf/ShadingImage.cc", "lib/xpdf/SplashOutputDev.cc", "lib/xpdf/Stream.cc", "lib/xpdf/TextOutputDev.cc", "lib/xpdf/TextString.cc", "lib/xpdf/TileCache.cc", "lib/xpdf/TileCompositor.cc", "lib/xpdf/TileMap.cc", "lib/xpdf/UnicodeMap.cc", "lib/xpdf/UnicodeRemapping.cc", "lib/xpdf/UnicodeTypeTable.cc", "lib/xpdf/UTF8.cc", "lib/xpdf/WebFont.cc", "lib/xpdf/XFAScanner.cc", "lib/xpdf/XRef.cc", "lib/xpdf/Zoox.cc", "PdfFile.cpp", "PdfReader.cpp"] + "files": ["PdfFile.cpp", "PdfReader.cpp", "PdfWriter.cpp", "PdfEditor.cpp"] + }, + { + "folder": "../../../../PdfFile/SrcReader/", + "files": ["Adaptors.cpp", "GfxClip.cpp", "RendererOutputDev.cpp", "JPXStream2.cpp", "PdfAnnot.cpp"] + }, + { + "folder": "../../../../PdfFile/SrcWriter/", + "files": ["AcroForm.cpp", "Annotation.cpp", "Catalog.cpp", "Destination.cpp", "Document.cpp", "Encrypt.cpp", "EncryptDictionary.cpp", "Field.cpp", "Font.cpp", "Font14.cpp", "FontCidTT.cpp", "FontTT.cpp", "FontTTWriter.cpp", "GState.cpp", "Image.cpp", "Info.cpp", "Metadata.cpp", "Objects.cpp", "Outline.cpp", "Pages.cpp", "Pattern.cpp", "ResourcesDictionary.cpp", "Shading.cpp", "States.cpp", "Streams.cpp", "Utils.cpp"] + }, + { + "folder": "../../../../PdfFile/Resources/", + "files": ["BaseFonts.cpp", "CMapMemory/cmap_memory.cpp"] + }, + { + "folder": "../../../../PdfFile/lib/", + "files": ["fofi/FofiBase.cc", "fofi/FofiEncodings.cc", "fofi/FofiIdentifier.cc", "fofi/FofiTrueType.cc", "fofi/FofiType1.cc", "fofi/FofiType1C.cc", "goo/FixedPoint.cc", "goo/gfile.cc", "goo/GHash.cc", "goo/GList.cc", "goo/gmem.cc", "goo/gmempp.cc", "goo/GString.cc", "goo/parseargs.c", "goo/Trace.cc", "splash/Splash.cc", "splash/SplashBitmap.cc", "splash/SplashClip.cc", "splash/SplashFont.cc", "splash/SplashFontEngine.cc", "splash/SplashFontFile.cc", "splash/SplashFontFileID.cc", "splash/SplashFTFont.cc", "splash/SplashFTFontEngine.cc", "splash/SplashFTFontFile.cc", "splash/SplashPath.cc", "splash/SplashPattern.cc", "splash/SplashScreen.cc", "splash/SplashState.cc", "splash/SplashXPath.cc", "splash/SplashXPathScanner.cc", "xpdf/AcroForm.cc", "xpdf/Annot.cc", "xpdf/Array.cc", "xpdf/BuiltinFont.cc", "xpdf/BuiltinFontTables.cc", "xpdf/Catalog.cc", "xpdf/CharCodeToUnicode.cc", "xpdf/CMap.cc", "xpdf/Decrypt.cc", "xpdf/Dict.cc", "xpdf/DisplayState.cc", "xpdf/Error.cc", "xpdf/FontEncodingTables.cc", "xpdf/Function.cc", "xpdf/Gfx.cc", "xpdf/GfxFont.cc", "xpdf/GfxState.cc", "xpdf/GlobalParams.cc", "xpdf/ImageOutputDev.cc", "xpdf/JArithmeticDecoder.cc", "xpdf/JBIG2Stream.cc", "xpdf/JPXStream.cc", "xpdf/Lexer.cc", "xpdf/Link.cc", "xpdf/NameToCharCode.cc", "xpdf/Object.cc", "xpdf/OptionalContent.cc", "xpdf/Outline.cc", "xpdf/OutputDev.cc", "xpdf/Page.cc", "xpdf/Parser.cc", "xpdf/PDF417Barcode.cc", "xpdf/PDFCore.cc", "xpdf/PDFDoc.cc", "xpdf/PDFDocEncoding.cc", "xpdf/PreScanOutputDev.cc", "xpdf/PSOutputDev.cc", "xpdf/PSTokenizer.cc", "xpdf/SecurityHandler.cc", "xpdf/ShadingImage.cc", "xpdf/SplashOutputDev.cc", "xpdf/Stream.cc", "xpdf/TextOutputDev.cc", "xpdf/TextString.cc", "xpdf/TileCache.cc", "xpdf/TileCompositor.cc", "xpdf/TileMap.cc", "xpdf/UnicodeMap.cc", "xpdf/UnicodeRemapping.cc", "xpdf/UnicodeTypeTable.cc", "xpdf/UTF8.cc", "xpdf/WebFont.cc", "xpdf/XFAScanner.cc", "xpdf/XRef.cc", "xpdf/Zoox.cc"] }, { "folder": "../../../raster/Jp2/openjpeg/openjpeg-2.4.0/src/lib/openjp2/", diff --git a/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro b/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro index 8f532e4fa5..e823927ba4 100644 --- a/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro +++ b/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro @@ -619,10 +619,7 @@ INCLUDEPATH += \ $$PDF_ROOT_DIR/lib/splash \ $$PDF_ROOT_DIR/lib -HEADERS += \ - $$PDF_ROOT_DIR/lib/aconf.h \ - $$$files($$PDF_ROOT_DIR/lib/*.h) - +HEADERS += $$files($$PDF_ROOT_DIR/lib/*.h, true) SOURCES += $$files($$PDF_ROOT_DIR/lib/*.c, true) SOURCES += $$files($$PDF_ROOT_DIR/lib/*.cc, true) @@ -644,9 +641,7 @@ SOURCES += \ $$PDF_ROOT_DIR/SrcReader/GfxClip.cpp \ $$PDF_ROOT_DIR/SrcReader/PdfAnnot.cpp \ $$PDF_ROOT_DIR/Resources/BaseFonts.cpp \ - $$PDF_ROOT_DIR/Resources/CMapMemory/cmap_memory.cpp \ - $$PDF_ROOT_DIR/PdfReader.cpp \ - $$PDF_ROOT_DIR/PdfFile.cpp + $$PDF_ROOT_DIR/Resources/CMapMemory/cmap_memory.cpp HEADERS +=\ $$PDF_ROOT_DIR/Resources/Fontd050000l.h \ @@ -670,9 +665,87 @@ HEADERS +=\ $$PDF_ROOT_DIR/SrcReader/MemoryUtils.h \ $$PDF_ROOT_DIR/SrcReader/GfxClip.h \ $$PDF_ROOT_DIR/SrcReader/FontsWasm.h \ - $$PDF_ROOT_DIR/SrcReader/PdfAnnot.h \ + $$PDF_ROOT_DIR/SrcReader/PdfAnnot.h + +DEFINES += CRYPTOPP_DISABLE_ASM +LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lCryptoPPLib + +# PdfWriter +HEADERS += \ + $$PDF_ROOT_DIR/SrcWriter/AcroForm.h \ + $$PDF_ROOT_DIR/SrcWriter/Annotation.h \ + $$PDF_ROOT_DIR/SrcWriter/Catalog.h \ + $$PDF_ROOT_DIR/SrcWriter/Consts.h \ + $$PDF_ROOT_DIR/SrcWriter/Destination.h \ + $$PDF_ROOT_DIR/SrcWriter/Document.h \ + $$PDF_ROOT_DIR/SrcWriter/Encodings.h \ + $$PDF_ROOT_DIR/SrcWriter/Encrypt.h \ + $$PDF_ROOT_DIR/SrcWriter/EncryptDictionary.h \ + $$PDF_ROOT_DIR/SrcWriter/Field.h \ + $$PDF_ROOT_DIR/SrcWriter/Font.h \ + $$PDF_ROOT_DIR/SrcWriter/Font14.h \ + $$PDF_ROOT_DIR/SrcWriter/FontCidTT.h \ + $$PDF_ROOT_DIR/SrcWriter/FontTT.h \ + $$PDF_ROOT_DIR/SrcWriter/FontTTWriter.h \ + $$PDF_ROOT_DIR/SrcWriter/GState.h \ + $$PDF_ROOT_DIR/SrcWriter/Image.h \ + $$PDF_ROOT_DIR/SrcWriter/Info.h \ + $$PDF_ROOT_DIR/SrcWriter/Objects.h \ + $$PDF_ROOT_DIR/SrcWriter/Outline.h \ + $$PDF_ROOT_DIR/SrcWriter/Pages.h \ + $$PDF_ROOT_DIR/SrcWriter/Pattern.h \ + $$PDF_ROOT_DIR/SrcWriter/ResourcesDictionary.h \ + $$PDF_ROOT_DIR/SrcWriter/Shading.h \ + $$PDF_ROOT_DIR/SrcWriter/Streams.h \ + $$PDF_ROOT_DIR/SrcWriter/Types.h \ + $$PDF_ROOT_DIR/SrcWriter/Utils.h \ + $$PDF_ROOT_DIR/SrcWriter/Metadata.h \ + $$PDF_ROOT_DIR/SrcWriter/ICCProfile.h \ + $$PDF_ROOT_DIR/SrcWriter/States.h + +SOURCES += \ + $$PDF_ROOT_DIR/SrcWriter/AcroForm.cpp \ + $$PDF_ROOT_DIR/SrcWriter/Annotation.cpp \ + $$PDF_ROOT_DIR/SrcWriter/Catalog.cpp \ + $$PDF_ROOT_DIR/SrcWriter/Destination.cpp \ + $$PDF_ROOT_DIR/SrcWriter/Document.cpp \ + $$PDF_ROOT_DIR/SrcWriter/Encrypt.cpp \ + $$PDF_ROOT_DIR/SrcWriter/EncryptDictionary.cpp \ + $$PDF_ROOT_DIR/SrcWriter/Field.cpp \ + $$PDF_ROOT_DIR/SrcWriter/Font.cpp \ + $$PDF_ROOT_DIR/SrcWriter/Font14.cpp \ + $$PDF_ROOT_DIR/SrcWriter/FontCidTT.cpp \ + $$PDF_ROOT_DIR/SrcWriter/FontTT.cpp \ + $$PDF_ROOT_DIR/SrcWriter/FontTTWriter.cpp \ + $$PDF_ROOT_DIR/SrcWriter/GState.cpp \ + $$PDF_ROOT_DIR/SrcWriter/Image.cpp \ + $$PDF_ROOT_DIR/SrcWriter/Info.cpp \ + $$PDF_ROOT_DIR/SrcWriter/Objects.cpp \ + $$PDF_ROOT_DIR/SrcWriter/Outline.cpp \ + $$PDF_ROOT_DIR/SrcWriter/Pages.cpp \ + $$PDF_ROOT_DIR/SrcWriter/Pattern.cpp \ + $$PDF_ROOT_DIR/SrcWriter/ResourcesDictionary.cpp \ + $$PDF_ROOT_DIR/SrcWriter/Shading.cpp \ + $$PDF_ROOT_DIR/SrcWriter/Streams.cpp \ + $$PDF_ROOT_DIR/SrcWriter/Utils.cpp \ + $$PDF_ROOT_DIR/SrcWriter/Metadata.cpp \ + $$PDF_ROOT_DIR/SrcWriter/States.cpp + +# PdfFile + +HEADERS += \ + $$PDF_ROOT_DIR/PdfFile.h \ + $$PDF_ROOT_DIR/PdfWriter.h \ $$PDF_ROOT_DIR/PdfReader.h \ - $$PDF_ROOT_DIR/PdfFile.h + $$PDF_ROOT_DIR/PdfEditor.h \ + $$PDF_ROOT_DIR/OnlineOfficeBinToPdf.h + +SOURCES += \ + $$PDF_ROOT_DIR/PdfFile.cpp \ + $$PDF_ROOT_DIR/PdfWriter.cpp \ + $$PDF_ROOT_DIR/PdfReader.cpp \ + $$PDF_ROOT_DIR/PdfEditor.cpp \ + $$PDF_ROOT_DIR/OnlineOfficeBinToPdf.cpp # DocxRenderer DOCX_RENDERER_ROOT_DIR = $$CORE_ROOT_DIR/DocxRenderer @@ -729,7 +802,6 @@ HEADERS += \ ../wasm/src/Text.h SOURCES += \ - ../wasm/src/pdfwriter.cpp \ ../wasm/src/HTMLRendererText.cpp \ ../wasm/src/drawingfile.cpp \ ../wasm/src/drawingfile_test.cpp diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js index 608782cf79..f18e773cf4 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js @@ -40,7 +40,7 @@ var UpdateFontsSource = { function CFile() { this.nativeFile = 0; - this.stream = -1; + this.stream = []; this.stream_size = 0; this.type = -1; this.pages = []; @@ -128,23 +128,54 @@ CFile.prototype["close"] = function() this.pages = []; this.info = null; this.StartID = null; - if (this.stream > 0) - this._free(this.stream); - this.stream = -1; + for (let i = 0; i < this.stream.length; i++) + this._free(this.stream[i]); + this.stream = []; self.drawingFile = null; }; CFile.prototype["getFileBinary"] = function() { - if (0 >= this.stream) + if (this.stream.length == 0) return ""; - return new Uint8Array(Module["HEAP8"].buffer, this.stream, this.stream_size); + return new Uint8Array(Module["HEAP8"].buffer, this.stream[0], this.stream_size); }; CFile.prototype["isNeedPassword"] = function() { return this._isNeedPassword; }; +CFile.prototype["SplitPages"] = function(arrPageIndex) +{ + let ptr = this._SplitPages(arrPageIndex); + + if (!ptr) + return null; + + let lenArr = new Int32Array(Module["HEAP8"].buffer, ptr, 1); + if (!lenArr) + { + Module["_free"](ptr); + return null; + } + + let len = lenArr[0]; + if (len <= 4) + { + Module["_free"](ptr); + return null; + } + len -= 4; + + let buffer = new Uint8Array(len); + buffer.set(new Uint8Array(Module["HEAP8"].buffer, ptr + 4, len)); + Module["_free"](ptr); + return buffer; +}; +CFile.prototype["MergePages"] = function(arrayBuffer, maxID, prefixForm) +{ + return this._MergePages(arrayBuffer, maxID, prefixForm); +}; // INFO DOCUMENT CFile.prototype.getInfo = function() @@ -181,6 +212,38 @@ CFile.prototype.getInfo = function() ptr.free(); return this.pages.length > 0; }; +CFile.prototype.getPagesInfo = function() +{ + if (!this.nativeFile) + return []; + + let ptr = this._getInfo(); + let reader = ptr.getReader(); + if (!reader) return []; + + // change StartID + this.StartID = reader.readInt(); + + let _pages = []; + let nPages = reader.readInt(); + for (let i = 0; i < nPages; i++) + { + let rec = {}; + rec["W"] = reader.readInt(); + rec["H"] = reader.readInt(); + rec["Dpi"] = reader.readInt(); + rec["Rotate"] = reader.readInt(); + rec["originIndex"] = i; + rec.fonts = []; + rec.fontsUpdateType = UpdateFontsSource.Undefined; + rec.text = null; + _pages.push(rec); + } + // skip json_info + + ptr.free(); + return _pages; +}; CFile.prototype["getStructure"] = function() { @@ -312,7 +375,7 @@ CFile.prototype["isNeedCMap"] = function() }; // WIDGETS & ANNOTATIONS -function readAction(reader, rec) +function readAction(reader, rec, readDoubleFunc, readStringFunc) { let SType = reader.readByte(); // 0 - Unknown, 1 - GoTo, 2 - GoToR, 3 - GoToE, 4 - Launch @@ -323,7 +386,7 @@ function readAction(reader, rec) rec["S"] = SType; if (SType == 14) { - rec["JS"] = reader.readString(); + rec["JS"] = readStringFunc.call(reader); } else if (SType == 1) { @@ -347,19 +410,19 @@ function readAction(reader, rec) { let nFlag = reader.readByte(); if (nFlag & (1 << 0)) - rec["left"] = reader.readDouble(); + rec["left"] = readDoubleFunc.call(reader); if (nFlag & (1 << 1)) - rec["top"] = reader.readDouble(); + rec["top"] = readDoubleFunc.call(reader); if (nFlag & (1 << 2)) - rec["zoom"] = reader.readDouble(); + rec["zoom"] = readDoubleFunc.call(reader); break; } case 4: { - rec["left"] = reader.readDouble(); - rec["bottom"] = reader.readDouble(); - rec["right"] = reader.readDouble(); - rec["top"] = reader.readDouble(); + rec["left"] = readDoubleFunc.call(reader); + rec["bottom"] = readDoubleFunc.call(reader); + rec["right"] = readDoubleFunc.call(reader); + rec["top"] = readDoubleFunc.call(reader); break; } case 1: @@ -370,11 +433,11 @@ function readAction(reader, rec) } else if (SType == 10) { - rec["N"] = reader.readString(); + rec["N"] = readStringFunc.call(reader); } else if (SType == 6) { - rec["URI"] = reader.readString(); + rec["URI"] = readStringFunc.call(reader); } else if (SType == 9) { @@ -383,7 +446,7 @@ function readAction(reader, rec) rec["T"] = []; // array of annotation names - rec["name"] for (let j = 0; j < m; ++j) - rec["T"].push(reader.readString()); + rec["T"].push(readStringFunc.call(reader)); } else if (SType == 12) { @@ -392,16 +455,16 @@ function readAction(reader, rec) rec["Fields"] = []; // array of annotation names - rec["name"] for (let j = 0; j < m; ++j) - rec["Fields"].push(reader.readString()); + rec["Fields"].push(readStringFunc.call(reader)); } let NextAction = reader.readByte(); if (NextAction) { rec["Next"] = {}; - readAction(reader, rec["Next"]); + readAction(reader, rec["Next"], readDoubleFunc, readStringFunc); } } -function readAnnot(reader, rec) +function readAnnot(reader, rec, readDoubleFunc, readDouble2Func, readStringFunc, isRead = false) { rec["AP"] = {}; // Annot @@ -441,23 +504,23 @@ function readAnnot(reader, rec) rec["page"] = reader.readInt(); // offsets like getStructure and viewer.navigate rec["rect"] = {}; - rec["rect"]["x1"] = reader.readDouble2(); - rec["rect"]["y1"] = reader.readDouble2(); - rec["rect"]["x2"] = reader.readDouble2(); - rec["rect"]["y2"] = reader.readDouble2(); + rec["rect"]["x1"] = readDouble2Func.call(reader); + rec["rect"]["y1"] = readDouble2Func.call(reader); + rec["rect"]["x2"] = readDouble2Func.call(reader); + rec["rect"]["y2"] = readDouble2Func.call(reader); let flags = reader.readInt(); // Unique name - NM if (flags & (1 << 0)) - rec["UniqueName"] = reader.readString(); + rec["UniqueName"] = readStringFunc.call(reader); // Alternate annotation text - Contents if (flags & (1 << 1)) - rec["Contents"] = reader.readString(); + rec["Contents"] = readStringFunc.call(reader); // Border effect - BE if (flags & (1 << 2)) { rec["BE"] = {}; rec["BE"]["S"] = reader.readByte(); - rec["BE"]["I"] = reader.readDouble(); + rec["BE"]["I"] = readDoubleFunc.call(reader); } // Special annotation color - С if (flags & (1 << 3)) @@ -465,31 +528,40 @@ function readAnnot(reader, rec) let n = reader.readInt(); rec["C"] = []; for (let i = 0; i < n; ++i) - rec["C"].push(reader.readDouble2()); + rec["C"].push(readDouble2Func.call(reader)); } // Border/BS if (flags & (1 << 4)) { // 0 - solid, 1 - beveled, 2 - dashed, 3 - inset, 4 - underline rec["border"] = reader.readByte(); - rec["borderWidth"] = reader.readDouble(); + rec["borderWidth"] = readDoubleFunc.call(reader); // Border Dash Pattern if (rec["border"] == 2) { let n = reader.readInt(); rec["dashed"] = []; for (let i = 0; i < n; ++i) - rec["dashed"].push(reader.readDouble()); + rec["dashed"].push(readDoubleFunc.call(reader)); } } // Date of last change - M if (flags & (1 << 5)) - rec["LastModified"] = reader.readString(); + rec["LastModified"] = readStringFunc.call(reader); // AP - rec["AP"]["have"] = (flags >> 6) & 1; + if (flags & (1 << 6)) + { + if (isRead) + rec["AP"]["render"] = reader.readData(); // TODO use Render - Uint8Array + else + rec["AP"]["have"] = (flags >> 6) & 1; + } // User ID if (flags & (1 << 7)) - rec["OUserID"] = reader.readString(); + rec["OUserID"] = readStringFunc.call(reader); + // User ID + if (flags & (1 << 8)) + rec["AP"]["Copy"] = reader.readInt(); } function readAnnotAP(reader, AP) { @@ -519,11 +591,649 @@ function readAnnotAP(reader, AP) // 0 - Normal, 1 - Multiply, 2 - Screen, 3 - Overlay, 4 - Darken, 5 - Lighten, 6 - ColorDodge, 7 - ColorBurn, 8 - HardLight, // 9 - SoftLight, 10 - Difference, 11 - Exclusion, 12 - Hue, 13 - Saturation, 14 - Color, 15 - Luminosity APi["BlendMode"] = reader.readByte(); - let k = reader.readByte(); - if (k != 0) - APi["apValue"] = reader.readString(); } } +function readAnnotType(reader, rec, readDoubleFunc, readDouble2Func, readStringFunc, isRead = false) +{ + // Markup + let flags = 0; + if ((rec["Type"] < 18 && rec["Type"] != 1 && rec["Type"] != 15) || rec["Type"] == 25) + { + flags = reader.readInt(); + if (flags & (1 << 0)) + rec["Popup"] = reader.readInt(); + // T + if (flags & (1 << 1)) + rec["User"] = readStringFunc.call(reader); + // CA + if (flags & (1 << 2)) + rec["CA"] = readDoubleFunc.call(reader); + // RC + if (flags & (1 << 3)) + { + let n = reader.readInt(); + rec["RC"] = []; + for (let i = 0; i < n; ++i) + { + let oFont = {}; + // 0 - left, 1 - centered, 2 - right, 3 - justify + oFont["alignment"] = reader.readByte(); + let nFontFlag = reader.readInt(); + oFont["bold"] = (nFontFlag >> 0) & 1; + oFont["italic"] = (nFontFlag >> 1) & 1; + oFont["strikethrough"] = (nFontFlag >> 3) & 1; + oFont["underlined"] = (nFontFlag >> 4) & 1; + if (nFontFlag & (1 << 5)) + oFont["vertical"] = readDoubleFunc.call(reader); + if (nFontFlag & (1 << 6)) + oFont["actual"] = readStringFunc.call(reader); + oFont["size"] = readDoubleFunc.call(reader); + oFont["color"] = []; + oFont["color"].push(readDouble2Func.call(reader)); + oFont["color"].push(readDouble2Func.call(reader)); + oFont["color"].push(readDouble2Func.call(reader)); + oFont["name"] = readStringFunc.call(reader); + oFont["text"] = readStringFunc.call(reader); + rec["RC"].push(oFont); + } + } + // CreationDate + if (flags & (1 << 4)) + rec["CreationDate"] = readStringFunc.call(reader); + // IRT + if (flags & (1 << 5)) + rec["RefTo"] = reader.readInt(); + // RT + // 0 - R, 1 - Group + if (flags & (1 << 6)) + rec["RefToReason"] = reader.readByte(); + // Subj + if (flags & (1 << 7)) + rec["Subj"] = readStringFunc.call(reader); + } + // Text + if (rec["Type"] == 0) + { + // Background color - C->IC + if (rec["C"]) + { + rec["IC"] = rec["C"]; + delete rec["C"]; + } + rec["Open"] = (flags >> 15) & 1; + // icon - Name + // 0 - Check, 1 - Checkmark, 2 - Circle, 3 - Comment, 4 - Cross, 5 - CrossHairs, 6 - Help, 7 - Insert, 8 - Key, 9 - NewParagraph, 10 - Note, 11 - Paragraph, 12 - RightArrow, 13 - RightPointer, 14 - Star, 15 - UpArrow, 16 - UpLeftArrow + if (flags & (1 << 16)) + rec["Icon"] = reader.readByte(); + // StateModel + // 0 - Marked, 1 - Review + if (flags & (1 << 17)) + rec["StateModel"] = reader.readByte(); + // State + // 0 - Marked, 1 - Unmarked, 2 - Accepted, 3 - Rejected, 4 - Cancelled, 5 - Completed, 6 - None + if (flags & (1 << 18)) + rec["State"] = reader.readByte(); + + } + // Line + else if (rec["Type"] == 3) + { + // L + rec["L"] = []; + for (let i = 0; i < 4; ++i) + rec["L"].push(readDoubleFunc.call(reader)); + // LE + // 0 - Square, 1 - Circle, 2 - Diamond, 3 - OpenArrow, 4 - ClosedArrow, 5 - None, 6 - Butt, 7 - ROpenArrow, 8 - RClosedArrow, 9 - Slash + if (flags & (1 << 15)) + { + rec["LE"] = []; + rec["LE"].push(reader.readByte()); + rec["LE"].push(reader.readByte()); + } + // IC + if (flags & (1 << 16)) + { + let n = reader.readInt(); + rec["IC"] = []; + for (let i = 0; i < n; ++i) + rec["IC"].push(readDouble2Func.call(reader)); + } + // LL + if (flags & (1 << 17)) + rec["LL"] = readDoubleFunc.call(reader); + // LLE + if (flags & (1 << 18)) + rec["LLE"] = readDoubleFunc.call(reader); + // Cap + rec["Cap"] = (flags >> 19) & 1; + // IT + // 0 - LineDimension, 1 - LineArrow + if (flags & (1 << 20)) + rec["IT"] = reader.readByte(); + // LLO + if (flags & (1 << 21)) + rec["LLO"] = readDoubleFunc.call(reader); + // CP + // 0 - Inline, 1 - Top + if (flags & (1 << 22)) + rec["CP"] = reader.readByte(); + // CO + if (flags & (1 << 23)) + { + rec["CO"] = []; + rec["CO"].push(readDoubleFunc.call(reader)); + rec["CO"].push(readDoubleFunc.call(reader)); + } + } + // Ink + else if (rec["Type"] == 14) + { + // offsets like getStructure and viewer.navigate + let n = reader.readInt(); + rec["InkList"] = []; + for (let i = 0; i < n; ++i) + { + rec["InkList"][i] = []; + let m = reader.readInt(); + for (let j = 0; j < m; ++j) + rec["InkList"][i].push(readDoubleFunc.call(reader)); + } + } + // Highlight, Underline, Squiggly, Strikeout + else if (rec["Type"] > 7 && rec["Type"] < 12) + { + // QuadPoints + let n = reader.readInt(); + rec["QuadPoints"] = []; + for (let i = 0; i < n; ++i) + rec["QuadPoints"].push(readDoubleFunc.call(reader)); + } + // Square, Circle + else if (rec["Type"] == 4 || rec["Type"] == 5) + { + // Rect and RD differences + if (flags & (1 << 15)) + { + rec["RD"] = []; + for (let i = 0; i < 4; ++i) + rec["RD"].push(readDoubleFunc.call(reader)); + } + // IC + if (flags & (1 << 16)) + { + let n = reader.readInt(); + rec["IC"] = []; + for (let i = 0; i < n; ++i) + rec["IC"].push(readDouble2Func.call(reader)); + } + } + // Polygon, PolyLine + else if (rec["Type"] == 6 || rec["Type"] == 7) + { + let nVertices = reader.readInt(); + rec["Vertices"] = []; + for (let i = 0; i < nVertices; ++i) + rec["Vertices"].push(readDoubleFunc.call(reader)); + // LE + // 0 - Square, 1 - Circle, 2 - Diamond, 3 - OpenArrow, 4 - ClosedArrow, 5 - None, 6 - Butt, 7 - ROpenArrow, 8 - RClosedArrow, 9 - Slash + if (flags & (1 << 15)) + { + rec["LE"] = []; + rec["LE"].push(reader.readByte()); + rec["LE"].push(reader.readByte()); + } + // IC + if (flags & (1 << 16)) + { + let n = reader.readInt(); + rec["IC"] = []; + for (let i = 0; i < n; ++i) + rec["IC"].push(readDouble2Func.call(reader)); + } + // IT + // 0 - PolygonCloud, 1 - PolyLineDimension, 2 - PolygonDimension + if (flags & (1 << 20)) + rec["IT"] = reader.readByte(); + } + // Popup + /* + else if (rec["Type"] == 15) + { + flags = reader.readInt(); + rec["Open"] = (flags >> 0) & 1; + // Link to parent-annotation + if (flags & (1 << 1)) + rec["PopupParent"] = reader.readInt(); + } + */ + // FreeText + else if (rec["Type"] == 2) + { + // Background color - C->IC + if (!isRead && rec["C"]) + { + rec["IC"] = rec["C"]; + delete rec["C"]; + } + // 0 - left-justified, 1 - centered, 2 - right-justified + rec["alignment"] = reader.readByte(); + rec["Rotate"] = reader.readInt(); + // Rect and RD differences + if (flags & (1 << 15)) + { + rec["RD"] = []; + for (let i = 0; i < 4; ++i) + rec["RD"].push(readDoubleFunc.call(reader)); + } + // CL + if (flags & (1 << 16)) + { + let n = reader.readInt(); + rec["CL"] = []; + for (let i = 0; i < n; ++i) + rec["CL"].push(readDoubleFunc.call(reader)); + } + // Default style (CSS2 format) - DS + if (flags & (1 << 17)) + rec["defaultStyle"] = readStringFunc.call(reader); + // LE + // 0 - Square, 1 - Circle, 2 - Diamond, 3 - OpenArrow, 4 - ClosedArrow, 5 - None, 6 - Butt, 7 - ROpenArrow, 8 - RClosedArrow, 9 - Slash + if (flags & (1 << 18)) + rec["LE"] = reader.readByte(); + // IT + // 0 - FreeText, 1 - FreeTextCallout, 2 - FreeTextTypeWriter + if (flags & (1 << 20)) + rec["IT"] = reader.readByte(); + // Border color - from DA (write to C) + if (flags & (1 << 21)) + { + let n = reader.readInt(); + if (isRead) + { + rec["IC"] = []; + for (let i = 0; i < n; ++i) + rec["IC"].push(readDouble2Func.call(reader)); + } + else + { + rec["C"] = []; + for (let i = 0; i < n; ++i) + rec["C"].push(readDouble2Func.call(reader)); + } + } + } + // Caret + else if (rec["Type"] == 13) + { + // Rect and RD differenses + if (flags & (1 << 15)) + { + rec["RD"] = []; + for (let i = 0; i < 4; ++i) + rec["RD"].push(readDoubleFunc.call(reader)); + } + // Sy + // 0 - None, 1 - P, 2 - S + if (flags & (1 << 16)) + rec["Sy"] = reader.readByte(); + } + // FileAttachment + else if (rec["Type"] == 16) + { + if (flags & (1 << 15)) + rec["Icon"] = readStringFunc.call(reader); + if (flags & (1 << 16)) + rec["FS"] = readStringFunc.call(reader); + if (flags & (1 << 17)) + { + rec["F"] = {}; + rec["F"]["FileName"] = readStringFunc.call(reader); + } + if (flags & (1 << 18)) + { + rec["UF"] = {}; + rec["UF"]["FileName"] = readStringFunc.call(reader); + } + if (flags & (1 << 19)) + { + rec["DOS"] = {}; + rec["DOS"]["FileName"] = readStringFunc.call(reader); + } + if (flags & (1 << 20)) + { + rec["Mac"] = {}; + rec["Mac"]["FileName"] = readStringFunc.call(reader); + } + if (flags & (1 << 21)) + { + rec["Unix"] = {}; + rec["Unix"]["FileName"] = readStringFunc.call(reader); + } + if (flags & (1 << 22)) + { + rec["ID"] = []; + rec["ID"].push(readStringFunc.call(reader)); + rec["ID"].push(readStringFunc.call(reader)); + } + rec["V"] = flags & (1 << 23); + if (flags & (1 << 24)) + { + if (isRead) + { + + } + else + { + let flag = reader.readInt(); + if (flag & (1 << 0)) + { + let n = reader.readInt(); + let np1 = reader.readInt(); + let np2 = reader.readInt(); + let pPoint = np2 << 32 | np1; + rec["F"]["File"] = new Uint8Array(Module["HEAP8"].buffer, pPoint, n); + Module["_free"](pPoint); + } + if (flag & (1 << 1)) + { + let n = reader.readInt(); + let np1 = reader.readInt(); + let np2 = reader.readInt(); + let pPoint = np2 << 32 | np1; + rec["UF"]["File"] = new Uint8Array(Module["HEAP8"].buffer, pPoint, n); + Module["_free"](pPoint); + } + if (flag & (1 << 2)) + { + let n = reader.readInt(); + let np1 = reader.readInt(); + let np2 = reader.readInt(); + let pPoint = np2 << 32 | np1; + rec["DOS"]["File"] = new Uint8Array(Module["HEAP8"].buffer, pPoint, n); + Module["_free"](pPoint); + } + if (flag & (1 << 3)) + { + let n = reader.readInt(); + let np1 = reader.readInt(); + let np2 = reader.readInt(); + let pPoint = np2 << 32 | np1; + rec["Mac"]["File"] = new Uint8Array(Module["HEAP8"].buffer, pPoint, n); + Module["_free"](pPoint); + } + if (flag & (1 << 4)) + { + let n = reader.readInt(); + let np1 = reader.readInt(); + let np2 = reader.readInt(); + let pPoint = np2 << 32 | np1; + rec["Unix"]["File"] = new Uint8Array(Module["HEAP8"].buffer, pPoint, n); + Module["_free"](pPoint); + } + } + + } + if (flags & (1 << 26)) + rec["Desc"] = readStringFunc.call(reader); + } + // Stamp + else if (rec["Type"] == 12) + { + rec["Icon"] = readStringFunc.call(reader); + rec["Rotate"] = readDouble2Func.call(reader); + rec["InRect"] = []; + for (let i = 0; i < 8; ++i) + rec["InRect"].push(readDouble2Func.call(reader)); + } +} +function readWidgetType(reader, rec, readDoubleFunc, readDouble2Func, readStringFunc, isRead = false) +{ + // Widget + rec["font"] = {}; + rec["font"]["name"] = readStringFunc.call(reader); + rec["font"]["size"] = readDoubleFunc.call(reader); + if (isRead) + rec["font"]["sizeAP"] = readDoubleFunc.call(reader); + rec["font"]["style"] = reader.readInt(); + let tc = reader.readInt(); + if (tc) + { + rec["font"]["color"] = []; + for (let i = 0; i < tc; ++i) + rec["font"]["color"].push(readDouble2Func.call(reader)); + } + // 0 - left-justified, 1 - centered, 2 - right-justified + if (!isRead || (rec["Type"] != 29 && rec["Type"] != 28 && rec["Type"] != 27)) + rec["alignment"] = reader.readByte(); + rec["flag"] = reader.readInt(); + // 12.7.3.1 + if (rec["flag"] >= 0) + { + rec["readOnly"] = (rec["flag"] >> 0) & 1; // ReadOnly + rec["required"] = (rec["flag"] >> 1) & 1; // Required + rec["noexport"] = (rec["flag"] >> 2) & 1; // NoExport + } + let flags = reader.readInt(); + // Alternative field name, used in tooltip and error messages - TU + if (flags & (1 << 0)) + rec["userName"] = readStringFunc.call(reader); + // Default style string (CSS2 format) - DS + if (flags & (1 << 1)) + rec["defaultStyle"] = readStringFunc.call(reader); + // Actual font + if (flags & (1 << 2)) + rec["font"]["actual"] = readStringFunc.call(reader); + // Selection mode - H + // 0 - none, 1 - invert, 2 - push, 3 - outline + if (flags & (1 << 3)) + rec["highlight"] = reader.readByte(); + // Font key + if (flags & (1 << 4)) + rec["font"]["key"] = readStringFunc.call(reader); + // Border color - BC. Even if the border is not specified by BS/Border, + // then if BC is present, a default border is provided (solid, thickness 1). + // If the text annotation has MaxLen, borders appear for each character + if (flags & (1 << 5)) + { + let n = reader.readInt(); + rec["BC"] = []; + for (let i = 0; i < n; ++i) + rec["BC"].push(readDouble2Func.call(reader)); + } + // Rotate an annotation relative to the page - R + if (flags & (1 << 6)) + rec["rotate"] = reader.readInt(); + // Annotation background color - BG + if (flags & (1 << 7)) + { + let n = reader.readInt(); + rec["BG"] = []; + for (let i = 0; i < n; ++i) + rec["BG"].push(readDouble2Func.call(reader)); + } + // Default value - DV + if (flags & (1 << 8)) + rec["defaultValue"] = readStringFunc.call(reader); + if (flags & (1 << 17)) + rec["Parent"] = reader.readInt(); + if (flags & (1 << 18)) + rec["name"] = readStringFunc.call(reader); + if (flags & (1 << 19)) + rec["font"]["AP"] = readStringFunc.call(reader); + if (flags & (1 << 20)) + rec["meta"] = readStringFunc.call(reader); + // Action + let nAction = reader.readInt(); + if (nAction > 0) + rec["AA"] = {}; + for (let i = 0; i < nAction; ++i) + { + let AAType = readStringFunc.call(reader); + rec["AA"][AAType] = {}; + readAction(reader, rec["AA"][AAType], readDoubleFunc, readStringFunc); + } + // Widget types + if (rec["type"] == 27) + { + if (flags & (1 << 9)) + rec["value"] = readStringFunc.call(reader); + let IFflags = reader.readInt(); + // Header - СA + if (flags & (1 << 10)) + rec["caption"] = readStringFunc.call(reader); + // Rollover header - RC + if (flags & (1 << 11)) + rec["rolloverCaption"] = readStringFunc.call(reader); + // Alternate header - AC + if (flags & (1 << 12)) + rec["alternateCaption"] = readStringFunc.call(reader); + // Header position - TP + if (flags & (1 << 13)) + // 0 - textOnly, 1 - iconOnly, 2 - iconTextV, 3 - textIconV, 4 - iconTextH, 5 - textIconH, 6 - overlay + rec["position"] = reader.readByte(); + // Icons - IF + if (IFflags & (1 << 0)) + { + rec["IF"] = {}; + // Scaling IF.SW + // 0 - Always, 1 - Never, 2 - too big, 3 - too small + if (IFflags & (1 << 1)) + rec["IF"]["SW"] = reader.readByte(); + // Scaling type - IF.S + // 0 - Proportional, 1 - Anamorphic + if (IFflags & (1 << 2)) + rec["IF"]["S"] = reader.readByte(); + if (IFflags & (1 << 3)) + { + rec["IF"]["A"] = []; + rec["IF"]["A"].push(readDoubleFunc.call(reader)); + rec["IF"]["A"].push(readDoubleFunc.call(reader)); + } + rec["IF"]["FB"] = (IFflags >> 4) & 1; + } + if (isRead) + { + if (IFflags & (1 << 5)) + rec["I"] = reader.readInt(); + if (IFflags & (1 << 6)) + rec["RI"] = reader.readInt(); + if (IFflags & (1 << 7)) + rec["IX"] = reader.readInt(); + } + } + else if (rec["type"] == 29 || rec["type"] == 28) + { + if (flags & (1 << 9)) + rec["value"] = readStringFunc.call(reader); + // 0 - check, 1 - cross, 2 - diamond, 3 - circle, 4 - star, 5 - square + rec["style"] = reader.readByte(); + if (flags & (1 << 14)) + rec["ExportValue"] = readStringFunc.call(reader); + // 12.7.4.2.1 + if (rec["flag"] >= 0) + { + rec["NoToggleToOff"] = (rec["flag"] >> 14) & 1; // NoToggleToOff + rec["radiosInUnison"] = (rec["flag"] >> 25) & 1; // RadiosInUnison + } + } + else if (rec["type"] == 30) + { + if (flags & (1 << 9)) + rec["value"] = readStringFunc.call(reader); + if (flags & (1 << 10)) + rec["maxLen"] = reader.readInt(); + if (flags & (1 << 11)) + rec["richValue"] = readStringFunc.call(reader); + if (isRead) + { + if (flags & (1 << 12)) + rec["AP"]["V"] = readStringFunc.call(reader); + if (flags & (1 << 13)) + rec["AP"]["render"] = reader.readData(); // TODO use Render - Uint8Array + } + // 12.7.4.3 + if (rec["flag"] >= 0) + { + rec["multiline"] = (rec["flag"] >> 12) & 1; // Multiline + rec["password"] = (rec["flag"] >> 13) & 1; // Password + rec["fileSelect"] = (rec["flag"] >> 20) & 1; // FileSelect + rec["doNotSpellCheck"] = (rec["flag"] >> 22) & 1; // DoNotSpellCheck + rec["doNotScroll"] = (rec["flag"] >> 23) & 1; // DoNotScroll + rec["comb"] = (rec["flag"] >> 24) & 1; // Comb + rec["richText"] = (rec["flag"] >> 25) & 1; // RichText + } + } + else if (rec["type"] == 31 || rec["type"] == 32) + { + if (flags & (1 << 9)) + rec["value"] = readStringFunc.call(reader); + if (flags & (1 << 10)) + { + let n = reader.readInt(); + rec["opt"] = []; + for (let i = 0; i < n; ++i) + { + let opt1 = readStringFunc.call(reader); + let opt2 = readStringFunc.call(reader); + if (opt1 == "") + rec["opt"].push(opt2); + else + rec["opt"].push([opt2, opt1]); + } + } + if (flags & (1 << 11)) + rec["TI"] = reader.readInt(); + if (isRead) + { + if (flags & (1 << 12)) + rec["AP"]["V"] = readStringFunc.call(reader); + } + else + { + if (flags & (1 << 12)) + { + let n = reader.readInt(); + rec["curIdxs"] = []; + for (let i = 0; i < n; ++i) + rec["curIdxs"].push(reader.readInt()); + } + } + if (flags & (1 << 13)) + { + let n = reader.readInt(); + rec["value"] = []; + for (let i = 0; i < n; ++i) + rec["value"].push(readStringFunc.call(reader)); + } + if (isRead) + { + if (flags & (1 << 14)) + { + let n = reader.readInt(); + rec["I"] = []; + for (let i = 0; i < n; ++i) + rec["I"].push(reader.readInt()); + } + if (flags & (1 << 15)) + rec["AP"]["render"] = reader.readData(); // TODO use Render - Uint8Array + } + // 12.7.4.4 + if (rec["flag"] >= 0) + { + rec["editable"] = (rec["flag"] >> 18) & 1; // Edit + rec["multipleSelection"] = (rec["flag"] >> 21) & 1; // MultiSelect + rec["doNotSpellCheck"] = (rec["flag"] >> 22) & 1; // DoNotSpellCheck + rec["commitOnSelChange"] = (rec["flag"] >> 26) & 1; // CommitOnSelChange + } + + } + else if (rec["type"] == 33) + { + rec["Sig"] = (flags >> 9) & 1; + } + if (rec["flag"] < 0) + delete rec["flag"]; +} CFile.prototype["getInteractiveFormsInfo"] = function() { @@ -532,214 +1242,45 @@ CFile.prototype["getInteractiveFormsInfo"] = function() if (!reader) return {}; let res = {}; - let k = reader.readInt(); - if (k > 0) - res["CO"] = []; - for (let i = 0; i < k; ++i) - res["CO"].push(reader.readInt()); - - k = reader.readInt(); - if (k > 0) - res["Parents"] = []; - for (let i = 0; i < k; ++i) + while (reader.isValid()) { - let rec = {}; - rec["i"] = reader.readInt(); - let flags = reader.readInt(); - if (flags & (1 << 0)) - rec["name"] = reader.readString(); - if (flags & (1 << 1)) - rec["value"] = reader.readString(); - if (flags & (1 << 2)) - rec["defaultValue"] = reader.readString(); - if (flags & (1 << 3)) + let k = reader.readInt(); + if (k > 0 && res["CO"] == undefined) + res["CO"] = []; + for (let i = 0; i < k; ++i) + res["CO"].push(reader.readInt()); + + k = reader.readInt(); + if (k > 0 && res["Parents"] == undefined) + res["Parents"] = []; + for (let i = 0; i < k; ++i) { - let n = reader.readInt(); - rec["curIdxs"] = []; - for (let i = 0; i < n; ++i) - rec["curIdxs"].push(reader.readInt()); - } - if (flags & (1 << 4)) - rec["Parent"] = reader.readInt(); - if (flags & (1 << 5)) - { - let n = reader.readInt(); - rec["value"] = []; - for (let i = 0; i < n; ++i) - rec["value"].push(reader.readString()); - } - if (flags & (1 << 6)) - { - let n = reader.readInt(); - rec["Opt"] = []; - for (let i = 0; i < n; ++i) - rec["Opt"].push(reader.readString()); - } - res["Parents"].push(rec); - } - - res["Fields"] = []; - k = reader.readInt(); - for (let q = 0; reader.isValid() && q < k; ++q) - { - let rec = {}; - // Widget type - FT - // 26 - Unknown, 27 - button, 28 - radiobutton, 29 - checkbox, 30 - text, 31 - combobox, 32 - listbox, 33 - signature - rec["type"] = reader.readByte(); - // Annot - readAnnot(reader, rec); - // Widget - rec["font"] = {}; - rec["font"]["name"] = reader.readString(); - rec["font"]["size"] = reader.readDouble(); - rec["font"]["style"] = reader.readInt(); - let tc = reader.readInt(); - if (tc) - { - rec["font"]["color"] = []; - for (let i = 0; i < tc; ++i) - rec["font"]["color"].push(reader.readDouble2()); - } - // 0 - left-justified, 1 - centered, 2 - right-justified - rec["alignment"] = reader.readByte(); - rec["flag"] = reader.readInt(); - // 12.7.3.1 - rec["readOnly"] = (rec["flag"] >> 0) & 1; // ReadOnly - rec["required"] = (rec["flag"] >> 1) & 1; // Required - rec["noexport"] = (rec["flag"] >> 2) & 1; // NoExport - let flags = reader.readInt(); - // Alternative field name, used in tooltip and error messages - TU - if (flags & (1 << 0)) - rec["userName"] = reader.readString(); - // Default style string (CSS2 format) - DS - if (flags & (1 << 1)) - rec["defaultStyle"] = reader.readString(); - // Actual font - if (flags & (1 << 2)) - rec["font"]["actual"] = reader.readString(); - // Selection mode - H - // 0 - none, 1 - invert, 2 - push, 3 - outline - if (flags & (1 << 3)) - rec["highlight"] = reader.readByte(); - // Font key - if (flags & (1 << 4)) - rec["font"]["key"] = reader.readString(); - // Border color - BC. Even if the border is not specified by BS/Border, - // then if BC is present, a default border is provided (solid, thickness 1). - // If the text annotation has MaxLen, borders appear for each character - if (flags & (1 << 5)) - { - let n = reader.readInt(); - rec["BC"] = []; - for (let i = 0; i < n; ++i) - rec["BC"].push(reader.readDouble2()); - } - // Rotate an annotation relative to the page - R - if (flags & (1 << 6)) - rec["rotate"] = reader.readInt(); - // Annotation background color - BG - if (flags & (1 << 7)) - { - let n = reader.readInt(); - rec["BG"] = []; - for (let i = 0; i < n; ++i) - rec["BG"].push(reader.readDouble2()); - } - // Default value - DV - if (flags & (1 << 8)) - rec["defaultValue"] = reader.readString(); - if (flags & (1 << 17)) - rec["Parent"] = reader.readInt(); - if (flags & (1 << 18)) - rec["name"] = reader.readString(); - if (flags & (1 << 19)) - rec["font"]["AP"] = reader.readString(); - if (flags & (1 << 20)) - rec["meta"] = reader.readString(); - // Action - let nAction = reader.readInt(); - if (nAction > 0) - rec["AA"] = {}; - for (let i = 0; i < nAction; ++i) - { - let AAType = reader.readString(); - rec["AA"][AAType] = {}; - readAction(reader, rec["AA"][AAType]); - } - // Widget types - if (rec["type"] == 27) - { - if (flags & (1 << 9)) + let rec = {}; + rec["i"] = reader.readInt(); + let flags = reader.readInt(); + if (flags & (1 << 0)) + rec["name"] = reader.readString(); + if (flags & (1 << 1)) rec["value"] = reader.readString(); - let IFflags = reader.readInt(); - // Header - СA - if (flags & (1 << 10)) - rec["caption"] = reader.readString(); - // Rollover header - RC - if (flags & (1 << 11)) - rec["rolloverCaption"] = reader.readString(); - // Alternate header - AC - if (flags & (1 << 12)) - rec["alternateCaption"] = reader.readString(); - // Header position - TP - if (flags & (1 << 13)) - // 0 - textOnly, 1 - iconOnly, 2 - iconTextV, 3 - textIconV, 4 - iconTextH, 5 - textIconH, 6 - overlay - rec["position"] = reader.readByte(); - // Icons - IF - if (IFflags & (1 << 0)) + if (flags & (1 << 2)) + rec["defaultValue"] = reader.readString(); + if (flags & (1 << 3)) { - rec["IF"] = {}; - // Scaling IF.SW - // 0 - Always, 1 - Never, 2 - too big, 3 - too small - if (IFflags & (1 << 1)) - rec["IF"]["SW"] = reader.readByte(); - // Scaling type - IF.S - // 0 - Proportional, 1 - Anamorphic - if (IFflags & (1 << 2)) - rec["IF"]["S"] = reader.readByte(); - if (IFflags & (1 << 3)) - { - rec["IF"]["A"] = []; - rec["IF"]["A"].push(reader.readDouble()); - rec["IF"]["A"].push(reader.readDouble()); - } - rec["IF"]["FB"] = (IFflags >> 4) & 1; + let n = reader.readInt(); + rec["curIdxs"] = []; + for (let i = 0; i < n; ++i) + rec["curIdxs"].push(reader.readInt()); } - } - else if (rec["type"] == 29 || rec["type"] == 28) - { - if (flags & (1 << 9)) - rec["value"] = reader.readString(); - // 0 - check, 1 - cross, 2 - diamond, 3 - circle, 4 - star, 5 - square - rec["style"] = reader.readByte(); - if (flags & (1 << 14)) - rec["ExportValue"] = reader.readString(); - // 12.7.4.2.1 - rec["NoToggleToOff"] = (rec["flag"] >> 14) & 1; // NoToggleToOff - rec["radiosInUnison"] = (rec["flag"] >> 25) & 1; // RadiosInUnison - } - else if (rec["type"] == 30) - { - if (flags & (1 << 9)) - rec["value"] = reader.readString(); - if (flags & (1 << 10)) - rec["maxLen"] = reader.readInt(); - if (rec["flag"] & (1 << 25)) - rec["richValue"] = reader.readString(); - // 12.7.4.3 - rec["multiline"] = (rec["flag"] >> 12) & 1; // Multiline - rec["password"] = (rec["flag"] >> 13) & 1; // Password - rec["fileSelect"] = (rec["flag"] >> 20) & 1; // FileSelect - rec["doNotSpellCheck"] = (rec["flag"] >> 22) & 1; // DoNotSpellCheck - rec["doNotScroll"] = (rec["flag"] >> 23) & 1; // DoNotScroll - rec["comb"] = (rec["flag"] >> 24) & 1; // Comb - rec["richText"] = (rec["flag"] >> 25) & 1; // RichText - } - else if (rec["type"] == 31 || rec["type"] == 32) - { - if (flags & (1 << 9)) - rec["value"] = reader.readString(); - if (flags & (1 << 10)) + if (flags & (1 << 4)) + rec["Parent"] = reader.readInt(); + if (flags & (1 << 5)) + { + let n = reader.readInt(); + rec["value"] = []; + for (let i = 0; i < n; ++i) + rec["value"].push(reader.readString()); + } + if (flags & (1 << 6)) { let n = reader.readInt(); rec["opt"] = []; @@ -753,34 +1294,64 @@ CFile.prototype["getInteractiveFormsInfo"] = function() rec["opt"].push([opt2, opt1]); } } - if (flags & (1 << 11)) - rec["TI"] = reader.readInt(); - if (flags & (1 << 12)) + if (flags & (1 << 7)) { - let n = reader.readInt(); - rec["curIdxs"] = []; - for (let i = 0; i < n; ++i) - rec["curIdxs"].push(reader.readInt()); + rec["flag"] = reader.readInt(); + + rec["readOnly"] = (rec["flag"] >> 0) & 1; // ReadOnly + rec["required"] = (rec["flag"] >> 1) & 1; // Required + rec["noexport"] = (rec["flag"] >> 2) & 1; // NoExport + + rec["NoToggleToOff"] = (rec["flag"] >> 14) & 1; // NoToggleToOff + if ((rec["flag"] >> 15) & 1) // If radiobutton + rec["radiosInUnison"] = (rec["flag"] >> 25) & 1; // RadiosInUnison + else + rec["richText"] = (rec["flag"] >> 25) & 1; // RichText + + rec["multiline"] = (rec["flag"] >> 12) & 1; // Multiline + rec["password"] = (rec["flag"] >> 13) & 1; // Password + rec["fileSelect"] = (rec["flag"] >> 20) & 1; // FileSelect + rec["doNotSpellCheck"] = (rec["flag"] >> 22) & 1; // DoNotSpellCheck + rec["doNotScroll"] = (rec["flag"] >> 23) & 1; // DoNotScroll + rec["comb"] = (rec["flag"] >> 24) & 1; // Comb + + rec["editable"] = (rec["flag"] >> 18) & 1; // Edit + rec["multipleSelection"] = (rec["flag"] >> 21) & 1; // MultiSelect + rec["commitOnSelChange"] = (rec["flag"] >> 26) & 1; // CommitOnSelChange } - if (flags & (1 << 13)) + if (flags & (1 << 8)) { - let n = reader.readInt(); - rec["value"] = []; - for (let i = 0; i < n; ++i) - rec["value"].push(reader.readString()); + let nAction = reader.readInt(); + if (nAction > 0) + rec["AA"] = {}; + for (let i = 0; i < nAction; ++i) + { + let AAType = reader.readString(); + rec["AA"][AAType] = {}; + readAction(reader, rec["AA"][AAType]); + } } - // 12.7.4.4 - rec["editable"] = (rec["flag"] >> 18) & 1; // Edit - rec["multipleSelection"] = (rec["flag"] >> 21) & 1; // MultiSelect - rec["doNotSpellCheck"] = (rec["flag"] >> 22) & 1; // DoNotSpellCheck - rec["commitOnSelChange"] = (rec["flag"] >> 26) & 1; // CommitOnSelChange + if (flags & (1 << 9)) + rec["maxLen"] = reader.readInt(); + res["Parents"].push(rec); } - else if (rec["type"] == 33) + + k = reader.readInt(); + if (k > 0 && res["Fields"] == undefined) + res["Fields"] = []; + for (let q = 0; reader.isValid() && q < k; ++q) { - rec["Sig"] = (flags >> 9) & 1; + let rec = {}; + // Widget type - FT + // 26 - Unknown, 27 - button, 28 - radiobutton, 29 - checkbox, 30 - text, 31 - combobox, 32 - listbox, 33 - signature + rec["type"] = reader.readByte(); + // Annot + readAnnot(reader, rec, reader.readDouble, reader.readDouble2, reader.readString); + // Widget type + readWidgetType(reader, rec, reader.readDouble, reader.readDouble2, reader.readString); + + res["Fields"].push(rec); } - - res["Fields"].push(rec); } ptr.free(); @@ -906,390 +1477,23 @@ CFile.prototype["getAnnotationsInfo"] = function(pageIndex) let res = []; while (reader.isValid()) { - let rec = {}; - // Annotation type - // 0 - Text, 1 - Link, 2 - FreeText, 3 - Line, 4 - Square, 5 - Circle, - // 6 - Polygon, 7 - PolyLine, 8 - Highlight, 9 - Underline, 10 - Squiggly, - // 11 - Strikeout, 12 - Stamp, 13 - Caret, 14 - Ink, 15 - Popup, 16 - FileAttachment, - // 17 - Sound, 18 - Movie, 19 - Widget, 20 - Screen, 21 - PrinterMark, - // 22 - TrapNet, 23 - Watermark, 24 - 3D, 25 - Redact - rec["Type"] = reader.readByte(); - // Annot - readAnnot(reader, rec); - // Markup - let flags = 0; - if ((rec["Type"] < 18 && rec["Type"] != 1 && rec["Type"] != 15) || rec["Type"] == 25) + let n = reader.readInt(); + for (let i = 0; i < n; ++i) { - flags = reader.readInt(); - if (flags & (1 << 0)) - rec["Popup"] = reader.readInt(); - // T - if (flags & (1 << 1)) - rec["User"] = reader.readString(); - // CA - if (flags & (1 << 2)) - rec["CA"] = reader.readDouble(); - // RC - if (flags & (1 << 3)) - { - let n = reader.readInt(); - rec["RC"] = []; - for (let i = 0; i < n; ++i) - { - let oFont = {}; - // 0 - left, 1 - centered, 2 - right, 3 - justify - oFont["alignment"] = reader.readByte(); - let nFontFlag = reader.readInt(); - oFont["bold"] = (nFontFlag >> 0) & 1; - oFont["italic"] = (nFontFlag >> 1) & 1; - oFont["strikethrough"] = (nFontFlag >> 3) & 1; - oFont["underlined"] = (nFontFlag >> 4) & 1; - if (nFontFlag & (1 << 5)) - oFont["vertical"] = reader.readDouble(); - if (nFontFlag & (1 << 6)) - oFont["actual"] = reader.readString(); - oFont["size"] = reader.readDouble(); - oFont["color"] = []; - oFont["color"].push(reader.readDouble2()); - oFont["color"].push(reader.readDouble2()); - oFont["color"].push(reader.readDouble2()); - oFont["name"] = reader.readString(); - oFont["text"] = reader.readString(); - rec["RC"].push(oFont); - } - } - // CreationDate - if (flags & (1 << 4)) - rec["CreationDate"] = reader.readString(); - // IRT - if (flags & (1 << 5)) - rec["RefTo"] = reader.readInt(); - // RT - // 0 - R, 1 - Group - if (flags & (1 << 6)) - rec["RefToReason"] = reader.readByte(); - // Subj - if (flags & (1 << 7)) - rec["Subj"] = reader.readString(); + let rec = {}; + // Annotation type + // 0 - Text, 1 - Link, 2 - FreeText, 3 - Line, 4 - Square, 5 - Circle, + // 6 - Polygon, 7 - PolyLine, 8 - Highlight, 9 - Underline, 10 - Squiggly, + // 11 - Strikeout, 12 - Stamp, 13 - Caret, 14 - Ink, 15 - Popup, 16 - FileAttachment, + // 17 - Sound, 18 - Movie, 19 - Widget, 20 - Screen, 21 - PrinterMark, + // 22 - TrapNet, 23 - Watermark, 24 - 3D, 25 - Redact + rec["Type"] = reader.readByte(); + // Annot + readAnnot(reader, rec, reader.readDouble, reader.readDouble2, reader.readString); + // Annot type + readAnnotType(reader, rec, reader.readDouble, reader.readDouble2, reader.readString); + res.push(rec); } - // Text - if (rec["Type"] == 0) - { - // Bachground color - C->IC - if (rec["C"]) - { - rec["IC"] = rec["C"]; - delete rec["C"]; - } - rec["Open"] = (flags >> 15) & 1; - // icon - Name - // 0 - Check, 1 - Checkmark, 2 - Circle, 3 - Comment, 4 - Cross, 5 - CrossHairs, 6 - Help, 7 - Insert, 8 - Key, 9 - NewParagraph, 10 - Note, 11 - Paragraph, 12 - RightArrow, 13 - RightPointer, 14 - Star, 15 - UpArrow, 16 - UpLeftArrow - if (flags & (1 << 16)) - rec["Icon"] = reader.readByte(); - // StateModel - // 0 - Marked, 1 - Review - if (flags & (1 << 17)) - rec["StateModel"] = reader.readByte(); - // State - // 0 - Marked, 1 - Unmarked, 2 - Accepted, 3 - Rejected, 4 - Cancelled, 5 - Completed, 6 - None - if (flags & (1 << 18)) - rec["State"] = reader.readByte(); - - } - // Line - else if (rec["Type"] == 3) - { - // L - rec["L"] = []; - for (let i = 0; i < 4; ++i) - rec["L"].push(reader.readDouble()); - // LE - // 0 - Square, 1 - Circle, 2 - Diamond, 3 - OpenArrow, 4 - ClosedArrow, 5 - None, 6 - Butt, 7 - ROpenArrow, 8 - RClosedArrow, 9 - Slash - if (flags & (1 << 15)) - { - rec["LE"] = []; - rec["LE"].push(reader.readByte()); - rec["LE"].push(reader.readByte()); - } - // IC - if (flags & (1 << 16)) - { - let n = reader.readInt(); - rec["IC"] = []; - for (let i = 0; i < n; ++i) - rec["IC"].push(reader.readDouble2()); - } - // LL - if (flags & (1 << 17)) - rec["LL"] = reader.readDouble(); - // LLE - if (flags & (1 << 18)) - rec["LLE"] = reader.readDouble(); - // Cap - rec["Cap"] = (flags >> 19) & 1; - // IT - // 0 - LineDimension, 1 - LineArrow - if (flags & (1 << 20)) - rec["IT"] = reader.readByte(); - // LLO - if (flags & (1 << 21)) - rec["LLO"] = reader.readDouble(); - // CP - // 0 - Inline, 1 - Top - if (flags & (1 << 22)) - rec["CP"] = reader.readByte(); - // CO - if (flags & (1 << 23)) - { - rec["CO"] = []; - rec["CO"].push(reader.readDouble()); - rec["CO"].push(reader.readDouble()); - } - } - // Ink - else if (rec["Type"] == 14) - { - // offsets like getStructure and viewer.navigate - let n = reader.readInt(); - rec["InkList"] = []; - for (let i = 0; i < n; ++i) - { - rec["InkList"][i] = []; - let m = reader.readInt(); - for (let j = 0; j < m; ++j) - rec["InkList"][i].push(reader.readDouble()); - } - } - // Highlight, Underline, Squiggly, Strikeout - else if (rec["Type"] > 7 && rec["Type"] < 12) - { - // QuadPoints - let n = reader.readInt(); - rec["QuadPoints"] = []; - for (let i = 0; i < n; ++i) - rec["QuadPoints"].push(reader.readDouble()); - } - // Square, Circle - else if (rec["Type"] == 4 || rec["Type"] == 5) - { - // Rect and RD differences - if (flags & (1 << 15)) - { - rec["RD"] = []; - for (let i = 0; i < 4; ++i) - rec["RD"].push(reader.readDouble()); - } - // IC - if (flags & (1 << 16)) - { - let n = reader.readInt(); - rec["IC"] = []; - for (let i = 0; i < n; ++i) - rec["IC"].push(reader.readDouble2()); - } - } - // Polygon, PolyLine - else if (rec["Type"] == 6 || rec["Type"] == 7) - { - let nVertices = reader.readInt(); - rec["Vertices"] = []; - for (let i = 0; i < nVertices; ++i) - rec["Vertices"].push(reader.readDouble()); - // LE - // 0 - Square, 1 - Circle, 2 - Diamond, 3 - OpenArrow, 4 - ClosedArrow, 5 - None, 6 - Butt, 7 - ROpenArrow, 8 - RClosedArrow, 9 - Slash - if (flags & (1 << 15)) - { - rec["LE"] = []; - rec["LE"].push(reader.readByte()); - rec["LE"].push(reader.readByte()); - } - // IC - if (flags & (1 << 16)) - { - let n = reader.readInt(); - rec["IC"] = []; - for (let i = 0; i < n; ++i) - rec["IC"].push(reader.readDouble2()); - } - // IT - // 0 - PolygonCloud, 1 - PolyLineDimension, 2 - PolygonDimension - if (flags & (1 << 20)) - rec["IT"] = reader.readByte(); - } - // Popup - /* - else if (rec["Type"] == 15) - { - flags = reader.readInt(); - rec["Open"] = (flags >> 0) & 1; - // Link to parent-annotation - if (flags & (1 << 1)) - rec["PopupParent"] = reader.readInt(); - } - */ - // FreeText - else if (rec["Type"] == 2) - { - // Background color - C->IC - if (rec["C"]) - { - rec["IC"] = rec["C"]; - delete rec["C"]; - } - // 0 - left-justified, 1 - centered, 2 - right-justified - rec["alignment"] = reader.readByte(); - rec["Rotate"] = reader.readInt(); - // Rect and RD differences - if (flags & (1 << 15)) - { - rec["RD"] = []; - for (let i = 0; i < 4; ++i) - rec["RD"].push(reader.readDouble()); - } - // CL - if (flags & (1 << 16)) - { - let n = reader.readInt(); - rec["CL"] = []; - for (let i = 0; i < n; ++i) - rec["CL"].push(reader.readDouble()); - } - // Default style (CSS2 format) - DS - if (flags & (1 << 17)) - rec["defaultStyle"] = reader.readString(); - // LE - // 0 - Square, 1 - Circle, 2 - Diamond, 3 - OpenArrow, 4 - ClosedArrow, 5 - None, 6 - Butt, 7 - ROpenArrow, 8 - RClosedArrow, 9 - Slash - if (flags & (1 << 18)) - rec["LE"] = reader.readByte(); - // IT - // 0 - FreeText, 1 - FreeTextCallout, 2 - FreeTextTypeWriter - if (flags & (1 << 20)) - rec["IT"] = reader.readByte(); - // Border color - from DA (write to C) - if (flags & (1 << 21)) - { - let n = reader.readInt(); - rec["C"] = []; - for (let i = 0; i < n; ++i) - rec["C"].push(reader.readDouble2()); - } - } - // Caret - else if (rec["Type"] == 13) - { - // Rect and RD differenses - if (flags & (1 << 15)) - { - rec["RD"] = []; - for (let i = 0; i < 4; ++i) - rec["RD"].push(reader.readDouble()); - } - // Sy - // 0 - None, 1 - P, 2 - S - if (flags & (1 << 16)) - rec["Sy"] = reader.readByte(); - } - // FileAttachment - else if (rec["Type"] == 16) - { - if (flags & (1 << 15)) - rec["Icon"] = reader.readString(); - if (flags & (1 << 16)) - rec["FS"] = reader.readString(); - if (flags & (1 << 17)) - { - rec["F"] = {}; - rec["F"]["FileName"] = reader.readString(); - } - if (flags & (1 << 18)) - { - rec["UF"] = {}; - rec["UF"]["FileName"] = reader.readString(); - } - if (flags & (1 << 19)) - { - rec["DOS"] = {}; - rec["DOS"]["FileName"] = reader.readString(); - } - if (flags & (1 << 20)) - { - rec["Mac"] = {}; - rec["Mac"]["FileName"] = reader.readString(); - } - if (flags & (1 << 21)) - { - rec["Unix"] = {}; - rec["Unix"]["FileName"] = reader.readString(); - } - if (flags & (1 << 22)) - { - rec["ID"] = []; - rec["ID"].push(reader.readString()); - rec["ID"].push(reader.readString()); - } - rec["V"] = flags & (1 << 23); - if (flags & (1 << 24)) - { - let flag = reader.readInt(); - if (flag & (1 << 0)) - { - let n = reader.readInt(); - let np1 = reader.readInt(); - let np2 = reader.readInt(); - let pPoint = np2 << 32 | np1; - rec["F"]["File"] = new Uint8Array(Module["HEAP8"].buffer, pPoint, n); - Module["_free"](pPoint); - } - if (flag & (1 << 1)) - { - let n = reader.readInt(); - let np1 = reader.readInt(); - let np2 = reader.readInt(); - let pPoint = np2 << 32 | np1; - rec["UF"]["File"] = new Uint8Array(Module["HEAP8"].buffer, pPoint, n); - Module["_free"](pPoint); - } - if (flag & (1 << 2)) - { - let n = reader.readInt(); - let np1 = reader.readInt(); - let np2 = reader.readInt(); - let pPoint = np2 << 32 | np1; - rec["DOS"]["File"] = new Uint8Array(Module["HEAP8"].buffer, pPoint, n); - Module["_free"](pPoint); - } - if (flag & (1 << 3)) - { - let n = reader.readInt(); - let np1 = reader.readInt(); - let np2 = reader.readInt(); - let pPoint = np2 << 32 | np1; - rec["Mac"]["File"] = new Uint8Array(Module["HEAP8"].buffer, pPoint, n); - Module["_free"](pPoint); - } - if (flag & (1 << 4)) - { - let n = reader.readInt(); - let np1 = reader.readInt(); - let np2 = reader.readInt(); - let pPoint = np2 << 32 | np1; - rec["Unix"]["File"] = new Uint8Array(Module["HEAP8"].buffer, pPoint, n); - Module["_free"](pPoint); - } - } - if (flags & (1 << 26)) - rec["Desc"] = reader.readString(); - } - // Stamp - else if (rec["Type"] == 12) - { - rec["Icon"] = reader.readString(); - rec["Rotate"] = reader.readDouble2(); - rec["InRect"] = []; - for (let i = 0; i < 8; ++i) - rec["InRect"].push(reader.readDouble2()); - } - res.push(rec); } ptr.free(); @@ -1331,6 +1535,49 @@ CFile.prototype["getAnnotationsAP"] = function(pageIndex, width, height, backgro return res; }; +// AnnotInfo - Uint8Array with ctAnnotField format +CFile.prototype["readAnnotationsInfoFromBinary"] = function(AnnotInfo) +{ + if (!AnnotInfo) + return []; + + let reader = new CBinaryReader(AnnotInfo, 0, AnnotInfo.length); + if (!reader) return []; + + let res = []; + while (reader.isValid()) + { + let nCommand = reader.readByte(); + let nPos = reader.pos; + let nSize = reader.readInt(); + if (nCommand != 164) // ctAnnotField + { + reader.pos = nPos + nSize; + continue; + } + let rec = {}; + // Annotation type + // 0 - Text, 1 - Link, 2 - FreeText, 3 - Line, 4 - Square, 5 - Circle, + // 6 - Polygon, 7 - PolyLine, 8 - Highlight, 9 - Underline, 10 - Squiggly, + // 11 - Strikeout, 12 - Stamp, 13 - Caret, 14 - Ink, 15 - Popup, 16 - FileAttachment, + // 17 - Sound, 18 - Movie, 19 - Widget, 20 - Screen, 21 - PrinterMark, + // 22 - TrapNet, 23 - Watermark, 24 - 3D, 25 - Redact + rec["Type"] = reader.readByte(); + // Annot + readAnnot(reader, rec, reader.readDouble3, reader.readDouble3, reader.readString2, true); + // Annot type + readAnnotType(reader, rec, reader.readDouble3, reader.readDouble3, reader.readString2, true); + if (rec["Type"] >= 26 && rec["Type"] <= 33) + { + // Widget type + readWidgetType(reader, rec, reader.readDouble3, reader.readDouble3, reader.readString2, true); + } + res.push(rec); + } + + return res; +}; + // SCAN PAGES CFile.prototype["scanPage"] = function(page, mode) { diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_native.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_native.js index d43e81dd80..6e9ba2a34e 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_native.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_native.js @@ -94,6 +94,11 @@ CFile.prototype._getError = function() return g_native_drawing_file["GetErrorCode"](); }; +CFile.prototype._addPDF = function(buffer, password) +{ + return g_native_drawing_file["AddPDF"](); +} + // FONTS CFile.prototype._isNeedCMap = function() { diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_wasm.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_wasm.js index f2e81f7cb0..f3d5fd70bb 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_wasm.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_wasm.js @@ -86,8 +86,9 @@ CFile.prototype._openFile = function(buffer, password) { let data = new Uint8Array(buffer); this.stream_size = data.length; - this.stream = Module["_malloc"](this.stream_size); - Module["HEAP8"].set(data, this.stream); + let stream = Module["_malloc"](this.stream_size); + Module["HEAP8"].set(data, stream); + this.stream.push(stream); } let passwordPtr = 0; @@ -98,7 +99,7 @@ CFile.prototype._openFile = function(buffer, password) Module["HEAP8"].set(passwordBuf, passwordPtr); } - this.nativeFile = Module["_Open"](this.stream, this.stream_size, passwordPtr); + this.nativeFile = Module["_Open"](this.stream[0], this.stream_size, passwordPtr); if (passwordPtr) Module["_free"](passwordPtr); @@ -112,7 +113,7 @@ CFile.prototype._closeFile = function() CFile.prototype._getType = function() { - return Module["_GetType"](this.stream, this.stream_size); + return Module["_GetType"](this.stream[0], this.stream_size); }; CFile.prototype._getError = function() @@ -120,6 +121,47 @@ CFile.prototype._getError = function() return Module["_GetErrorCode"](this.nativeFile); }; +CFile.prototype._SplitPages = function(memoryBuffer) +{ + let pointer = Module["_malloc"](memoryBuffer.length * 4); + Module["HEAP32"].set(memoryBuffer, pointer >> 2); + let ptr = Module["_SplitPages"](this.nativeFile, pointer, memoryBuffer.length); + Module["_free"](pointer); + return ptr; +}; + +CFile.prototype._MergePages = function(buffer, maxID, prefixForm) +{ + if (!buffer) + return false; + + let data = (undefined !== buffer.byteLength) ? new Uint8Array(buffer) : buffer; + let stream2 = Module["_malloc"](data.length); + Module["HEAP8"].set(data, stream2); + + if (!maxID) + maxID = 0; + + let prefixPtr = 0; + if (prefixForm) + { + let prefixBuf = prefixForm.toUtf8(); + prefixPtr = Module["_malloc"](prefixBuf.length); + Module["HEAP8"].set(prefixBuf, prefixPtr); + } + + let bRes = Module["_MergePages"](this.nativeFile, stream2, data.length, maxID, prefixPtr); + if (bRes == 1) + this.stream.push(stream2); + else + Module["_free"](stream2); + + if (prefixPtr) + Module["_free"](prefixPtr); + + return bRes == 1; +}; + // FONTS CFile.prototype._isNeedCMap = function() { diff --git a/DesktopEditor/graphics/pro/js/wasm/js/stream.js b/DesktopEditor/graphics/pro/js/wasm/js/stream.js index 2345ff97ff..3527185f6e 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/stream.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/stream.js @@ -42,6 +42,12 @@ CBinaryReader.prototype.readByte = function() this.pos += 1; return val; }; +CBinaryReader.prototype.readShort = function() +{ + let val = this.data[this.pos] | this.data[this.pos + 1] << 8; + this.pos += 2; + return val; +}; CBinaryReader.prototype.readInt = function() { let val = this.data[this.pos] | this.data[this.pos + 1] << 8 | this.data[this.pos + 2] << 16 | this.data[this.pos + 3] << 24; @@ -56,6 +62,10 @@ CBinaryReader.prototype.readDouble2 = function() { return this.readInt() / 10000; }; +CBinaryReader.prototype.readDouble3 = function() +{ + return this.readInt() / 100000; +}; CBinaryReader.prototype.readString = function() { let len = this.readInt(); @@ -63,9 +73,20 @@ CBinaryReader.prototype.readString = function() this.pos += len; return val; }; +CBinaryReader.prototype.readString2 = function() +{ + let len = this.readShort(); + let val = ""; + for (let i = 0; i < len; ++i) + { + let c = this.readShort(); + val += String.fromCharCode(c); + } + return val; +}; CBinaryReader.prototype.readData = function() { - let len = this.readInt(); + let len = this.readInt() - 4; let val = this.data.slice(this.pos, this.pos + len); this.pos += len; return val; diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp index 19bb4b4e3f..7d8b199539 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp @@ -125,7 +125,7 @@ WASM_EXPORT BYTE* GetGlyphs(CDrawingFile* pFile, int nPageIndex) { return pFile->GetGlyphs(nPageIndex); } -WASM_EXPORT BYTE* GetLinks (CDrawingFile* pFile, int nPageIndex) +WASM_EXPORT BYTE* GetLinks(CDrawingFile* pFile, int nPageIndex) { return pFile->GetLinks(nPageIndex); } @@ -177,6 +177,14 @@ WASM_EXPORT BYTE* ScanPage(CDrawingFile* pFile, int nPageIndex, int mode) { return pFile->ScanPage(nPageIndex, mode); } +WASM_EXPORT BYTE* SplitPages(CDrawingFile* pFile, int* arrPageIndex, int nLength) +{ + return pFile->SplitPages(arrPageIndex, nLength); +} +WASM_EXPORT int MergePages(CDrawingFile* pFile, BYTE* data, LONG size, int nMaxID, const char* sPrefixForm) +{ + return pFile->MergePages(data, size, nMaxID, sPrefixForm) ? 1 : 0; +} WASM_EXPORT void* GetImageBase64(CDrawingFile* pFile, int rId) { diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp index d50befd840..0728a890c9 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp @@ -309,7 +309,6 @@ void ReadInteractiveForms(BYTE* pWidgets, int& i) nPathLength = READ_INT(pWidgets + i); i += 4; - std::cout << "Flags " << nPathLength << ", "; int nFlags = nPathLength; if (nFlags & (1 << 0)) @@ -351,7 +350,7 @@ void ReadInteractiveForms(BYTE* pWidgets, int& i) { nPathLength = READ_INT(pWidgets + i); i += 4; - std::cout << "Parent " << nPathLength; + std::cout << "Parent " << nPathLength << ", "; } if (nFlags & (1 << 5)) { @@ -380,9 +379,42 @@ void ReadInteractiveForms(BYTE* pWidgets, int& i) i += 4; std::cout << " " << std::string((char*)(pWidgets + i), nPathLength); i += nPathLength; + + nPathLength = READ_INT(pWidgets + i); + i += 4; + std::cout << " " << std::string((char*)(pWidgets + i), nPathLength); + i += nPathLength; } std::cout << " ], "; } + if (nFlags & (1 << 7)) + { + nPathLength = READ_INT(pWidgets + i); + i += 4; + std::cout << "Ff " << nPathLength << ", "; + } + if (nFlags & (1 << 8)) + { + int nActLength = READ_INT(pWidgets + i); + i += 4; + for (int j = 0; j < nActLength; ++j) + { + std::cout << std::endl; + nPathLength = READ_INT(pWidgets + i); + i += 4; + std::cout << std::to_string(j) << " Action " << std::string((char*)(pWidgets + i), nPathLength) << ", "; + i += nPathLength; + + ReadAction(pWidgets, i); + } + std::cout << std::endl; + } + if (nFlags & (1 << 9)) + { + nPathLength = READ_INT(pWidgets + i); + i += 4; + std::cout << "MaxLen " << nPathLength << ", "; + } std::cout << std::endl; } @@ -676,7 +708,7 @@ void ReadInteractiveForms(BYTE* pWidgets, int& i) i += 4; std::cout << "MaxLen " << nPathLength << ", "; } - if (nFieldFlag & (1 << 25)) + if (nFlags & (1 << 11)) { nPathLength = READ_INT(pWidgets + i); i += 4; @@ -813,17 +845,7 @@ void ReadAnnotAP(BYTE* pWidgetsAP, int& i) i += 1; std::string arrBlendMode[] = { "Normal", "Multiply", "Screen", "Overlay", "Darken", "Lighten", "ColorDodge", "ColorBurn", "HardLight", "SoftLight", "Difference", "Exclusion", "Hue", "Saturation", "Color", "Luminosity" }; - std::cout << "Type " << arrBlendMode[nPathLength] << ", "; - - int bText = READ_BYTE(pWidgetsAP + i); - i += 1; - if (bText != 0) - { - nPathLength = READ_INT(pWidgetsAP + i); - i += 4; - std::cout << "Text " << std::string((char*)(pWidgetsAP + i), nPathLength) << ", "; - i += nPathLength; - } + std::cout << "Type " << arrBlendMode[nPathLength]; } std::cout << std::endl; } @@ -969,6 +991,39 @@ int main(int argc, char* argv[]) } } + // SPLIT & MERGE + BYTE* pSplitPages = NULL; + if (false) + { + std::vector arrPages = { 0 }; + for (int i = 0; i < 3; i++) + { + pSplitPages = SplitPages(pGrFile, arrPages.data(), arrPages.size()); + if (pSplitPages) + { + int nLength = READ_INT(pSplitPages); + + NSFile::CFileBinary oFile; + if (oFile.CreateFileW(NSFile::GetProcessDirectory() + L"/test" + std::to_wstring(i) + L".pdf")) + oFile.WriteFile(pSplitPages + 4, nLength - 4); + oFile.CloseFile(); + + if (MergePages(pGrFile, pSplitPages + 4, nLength - 4, 0, "merge") == 0) + RELEASEARRAYOBJECTS(pSplitPages); + } + } + } + BYTE* pFileMerge = NULL; + if (true) + { + DWORD nFileMergeLen = 0; + if (NSFile::CFileBinary::ReadAllBytes(NSFile::GetProcessDirectory() + L"/test_merge.pdf", &pFileMerge, nFileMergeLen)) + { + if (MergePages(pGrFile, pFileMerge, nFileMergeLen, 0, "merge") == 0) + RELEASEARRAYOBJECTS(pFileMerge); + } + } + // INFO BYTE* pInfo = GetInfo(pGrFile); int nLength = READ_INT(pInfo); @@ -1041,7 +1096,7 @@ int main(int argc, char* argv[]) free(pInfo); // LINKS - if (false && nPagesCount > 0) + if (true && nPagesCount > 0) { BYTE* pLinks = GetLinks(pGrFile, nTestPage); nLength = READ_INT(pLinks); @@ -1077,7 +1132,7 @@ int main(int argc, char* argv[]) } // STRUCTURE - if (false) + if (true) { BYTE* pStructure = GetStructure(pGrFile); nLength = READ_INT(pStructure); @@ -1193,8 +1248,12 @@ int main(int argc, char* argv[]) int i = 4; nLength -= 4; - if (i < nLength) + while (i < nLength) + { + std::cout << "[" << std::endl; ReadInteractiveForms(pWidgets, i); + std::cout << "]" << std::endl; + } if (pWidgets) free(pWidgets); @@ -1308,406 +1367,184 @@ int main(int argc, char* argv[]) while (i < nLength) { - int nPathLength = READ_BYTE(pAnnots + i); - i += 1; - std::string sType = arrAnnots[nPathLength]; - std::cout << "Type " << sType << ", "; - - ReadAnnot(pAnnots, i); - - // Markup - - DWORD nFlags = 0; - if ((nPathLength < 18 && nPathLength != 1 && nPathLength != 15) || nPathLength == 25) + int nAnnotLength = READ_INT(pAnnots + i); + i += 4; + for (int i2 = 0; i2 < nAnnotLength; ++i2) { - nFlags = READ_INT(pAnnots + i); - i += 4; - - if (nFlags & (1 << 0)) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "Popup " << nPathLength << ", "; - } - if (nFlags & (1 << 1)) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "User " << std::string((char*)(pAnnots + i), nPathLength) << ", "; - i += nPathLength; - } - if (nFlags & (1 << 2)) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "CA " << (double)nPathLength / 100.0 << ", "; - } - if (nFlags & (1 << 3)) - { - std::cout << "RC {"; - - int nFontLength = READ_INT(pAnnots + i); - i += 4; - for (int j = 0; j < nFontLength; ++j) - { - std::cout << std::endl << "span" << j << " { "; - - nPathLength = READ_BYTE(pAnnots + i); - i += 1; - std::string arrTextAlign[] = {"Left", "Center", "Right", "Justify"}; - std::cout << "text-align: " << arrTextAlign[nPathLength]; - - std::cout << "; font-style:"; - int nFontFlag = READ_INT(pAnnots + i); - i += 4; - if (nFontFlag & (1 << 0)) - std::cout << "Bold "; - if (nFontFlag & (1 << 1)) - std::cout << "Italic "; - if (nFontFlag & (1 << 3)) - std::cout << "Strike "; - if (nFontFlag & (1 << 4)) - std::cout << "Underline "; - if (nFontFlag & (1 << 5)) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "; vertical-align:" << (double)nPathLength / 100.0; - } - if (nFontFlag & (1 << 6)) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "; font-actual:" << std::string((char*)(pAnnots + i), nPathLength) << "; "; - i += nPathLength; - } - - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "; font-size:" << (double)nPathLength / 100.0; - - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "; font-color:" << (double)nPathLength / 10000.0 << " "; - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << (double)nPathLength / 10000.0 << " "; - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << (double)nPathLength / 10000.0 << "; "; - - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::string sFontName((char*)(pAnnots + i), nPathLength); - std::cout << "font-family:" << sFontName << "; "; - i += nPathLength; - - BYTE* pFont = GetFontBinary(pGrFile, (char*)sFontName.c_str()); - if (pFont) - { - std::cout << "FIND; "; - free(pFont); - } - else - std::cout << "NO; "; - - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::string sText = std::string((char*)(pAnnots + i), nPathLength); - NSStringUtils::string_replaceA(sText, "\r", "\n"); - std::cout << "text:" << sText << " "; - i += nPathLength; - - std::cout << "} "; - } - std::cout << "}, " << std::endl; - } - if (nFlags & (1 << 4)) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "CreationDate " << std::string((char*)(pAnnots + i), nPathLength) << ", "; - i += nPathLength; - } - if (nFlags & (1 << 5)) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "Ref to " << nPathLength << ", "; - } - if (nFlags & (1 << 6)) - { - nPathLength = READ_BYTE(pAnnots + i); - i += 1; - std::cout << "Reason " << nPathLength << ", "; - } - if (nFlags & (1 << 7)) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "Subj " << std::string((char*)(pAnnots + i), nPathLength) << ", "; - i += nPathLength; - } - } - - if (sType == "Text") - { - if (nFlags & (1 << 15)) - std::cout << "Open true, "; - else - std::cout << "Open false, "; - if (nFlags & (1 << 16)) - { - nPathLength = READ_BYTE(pAnnots + i); - i += 1; - std::string arrIcon[] = {"Check", "Checkmark", "Circle", "Comment", "Cross", "CrossHairs", "Help", "Insert", "Key", "NewParagraph", "Note", "Paragraph", "RightArrow", "RightPointer", "Star", "UpArrow", "UpLeftArrow"}; - std::cout << "Icon " << arrIcon[nPathLength] << ", "; - } - if (nFlags & (1 << 17)) - { - nPathLength = READ_BYTE(pAnnots + i); - i += 1; - std::string arrStateModel[] = {"Marked", "Review"}; - std::cout << "State model " << arrStateModel[nPathLength] << ", "; - } - if (nFlags & (1 << 18)) - { - nPathLength = READ_BYTE(pAnnots + i); - i += 1; - std::string arrState[] = {"Marked", "Unmarked", "Accepted", "Rejected", "Cancelled", "Completed", "None"}; - std::cout << "State " << arrState[nPathLength] << ", "; - } - } - else if (sType == "Line") - { - std::cout << "L"; - for (int j = 0; j < 4; ++j) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << " " << (double)nPathLength / 100.0; - } - std::cout << ", "; - if (nFlags & (1 << 15)) - { - std::cout << "LE "; - for (int j = 0; j < 2; ++j) - { - nPathLength = READ_BYTE(pAnnots + i); - i += 1; - std::string arrLE[] = {"Square", "Circle", "Diamond", "OpenArrow", "ClosedArrow", "None", "Butt", "ROpenArrow", "RClosedArrow", "Slash"}; - std::cout << arrLE[nPathLength] << " "; - } - std::cout << ", "; - } - if (nFlags & (1 << 16)) - { - int nICLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "IC"; - - for (int j = 0; j < nICLength; ++j) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << " " << (double)nPathLength / 10000.0; - } - std::cout << ", "; - } - if (nFlags & (1 << 17)) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "LL " << (double)nPathLength / 100.0 << ", "; - } - if (nFlags & (1 << 18)) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "LLE " << (double)nPathLength / 100.0 << ", "; - } - if (nFlags & (1 << 19)) - std::cout << "Cap true, "; - else - std::cout << "Cap false, "; - if (nFlags & (1 << 20)) - { - nPathLength = READ_BYTE(pAnnots + i); - i += 1; - std::string arrIT[] = {"LineDimension", "LineArrow"}; - std::cout << "IT " << arrIT[nPathLength] << ", "; - } - if (nFlags & (1 << 21)) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "LLO " << (double)nPathLength / 100.0 << ", "; - } - if (nFlags & (1 << 22)) - { - nPathLength = READ_BYTE(pAnnots + i); - i += 1; - std::string arrCP[] = {"Inline", "Top"}; - std::cout << "CP " << arrCP[nPathLength] << ", "; - } - if (nFlags & (1 << 23)) - { - std::cout << "CO "; - for (int j = 0; j < 2; ++j) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << (double)nPathLength / 100.0 << " "; - } - std::cout << ", "; - } - } - else if (sType == "Ink") - { - int nInkLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "InkList "; - - for (int j = 0; j < nInkLength; ++j) - { - int nInkJLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "[ "; - - for (int k = 0; k < nInkJLength; ++k) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << (double)nPathLength / 100.0 << " "; - } - std::cout << "] "; - } - std::cout << ", "; - } - else if (sType == "Highlight" || - sType == "Underline" || - sType == "Squiggly" || - sType == "StrikeOut") - { - std::cout << "QuadPoints"; - int nQuadPointsLength = READ_INT(pAnnots + i); - i += 4; - - for (int j = 0; j < nQuadPointsLength; ++j) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << " " << (double)nPathLength / 100.0; - } - std::cout << ", "; - } - else if (sType == "Square" || - sType == "Circle") - { - if (nFlags & (1 << 15)) - { - std::cout << "RD"; - for (int j = 0; j < 4; ++j) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << " " << (double)nPathLength / 100.0; - } - std::cout << ", "; - } - if (nFlags & (1 << 16)) - { - int nICLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "IC "; - - for (int j = 0; j < nICLength; ++j) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << (double)nPathLength / 10000.0 << " "; - } - std::cout << ", "; - } - } - else if (sType == "Polygon" || - sType == "PolyLine") - { - int nVerticesLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "Vertices"; - - for (int j = 0; j < nVerticesLength; ++j) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << " " << (double)nPathLength / 100.0; - } - std::cout << ", "; - - if (nFlags & (1 << 15)) - { - std::cout << "LE"; - for (int j = 0; j < 2; ++j) - { - nPathLength = READ_BYTE(pAnnots + i); - i += 1; - std::string arrLE[] = {"Square", "Circle", "Diamond", "OpenArrow", "ClosedArrow", "None", "Butt", "ROpenArrow", "RClosedArrow", "Slash"}; - std::cout << " " << arrLE[nPathLength]; - } - std::cout << ", "; - } - if (nFlags & (1 << 16)) - { - int nICLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "IC"; - - for (int j = 0; j < nICLength; ++j) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << " " << (double)nPathLength / 10000.0; - } - std::cout << ", "; - } - if (nFlags & (1 << 20)) - { - nPathLength = READ_BYTE(pAnnots + i); - i += 1; - std::string arrIT[] = {"PolygonCloud", "PolyLineDimension", "PolygonDimension"}; - std::cout << "IT " << arrIT[nPathLength] << ", "; - } - } - else if (sType == "Popup") - { - nFlags = READ_INT(pAnnots + i); - i += 4; - if (nFlags & (1 << 0)) - std::cout << "Open true, "; - else - std::cout << "Open false, "; - if (nFlags & (1 << 1)) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "Popup parent " << nPathLength << ", "; - } - } - else if (sType == "FreeText") - { - std::string arrQ[] = {"left-justified", "centered", "right-justified"}; - nPathLength = READ_BYTE(pAnnots + i); + std::cout << "[" << std::endl; + int nPathLength = READ_BYTE(pAnnots + i); i += 1; - std::cout << "Q " << arrQ[nPathLength] << ", "; + std::string sType = arrAnnots[nPathLength]; + std::cout << "Type " << sType << ", "; - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "Rotate " << nPathLength << ", "; + ReadAnnot(pAnnots, i); - if (nFlags & (1 << 15)) + // Markup + + DWORD nFlags = 0; + if ((nPathLength < 18 && nPathLength != 1 && nPathLength != 15) || nPathLength == 25) { - std::cout << "RD"; + nFlags = READ_INT(pAnnots + i); + i += 4; + + if (nFlags & (1 << 0)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "Popup " << nPathLength << ", "; + } + if (nFlags & (1 << 1)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "User " << std::string((char*)(pAnnots + i), nPathLength) << ", "; + i += nPathLength; + } + if (nFlags & (1 << 2)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "CA " << (double)nPathLength / 100.0 << ", "; + } + if (nFlags & (1 << 3)) + { + std::cout << "RC {"; + + int nFontLength = READ_INT(pAnnots + i); + i += 4; + for (int j = 0; j < nFontLength; ++j) + { + std::cout << std::endl << "span" << j << " { "; + + nPathLength = READ_BYTE(pAnnots + i); + i += 1; + std::string arrTextAlign[] = {"Left", "Center", "Right", "Justify"}; + std::cout << "text-align: " << arrTextAlign[nPathLength]; + + std::cout << "; font-style:"; + int nFontFlag = READ_INT(pAnnots + i); + i += 4; + if (nFontFlag & (1 << 0)) + std::cout << "Bold "; + if (nFontFlag & (1 << 1)) + std::cout << "Italic "; + if (nFontFlag & (1 << 3)) + std::cout << "Strike "; + if (nFontFlag & (1 << 4)) + std::cout << "Underline "; + if (nFontFlag & (1 << 5)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "; vertical-align:" << (double)nPathLength / 100.0; + } + if (nFontFlag & (1 << 6)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "; font-actual:" << std::string((char*)(pAnnots + i), nPathLength) << "; "; + i += nPathLength; + } + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "; font-size:" << (double)nPathLength / 100.0; + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "; font-color:" << (double)nPathLength / 10000.0 << " "; + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << (double)nPathLength / 10000.0 << " "; + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << (double)nPathLength / 10000.0 << "; "; + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::string sFontName((char*)(pAnnots + i), nPathLength); + std::cout << "font-family:" << sFontName << "; "; + i += nPathLength; + + BYTE* pFont = GetFontBinary(pGrFile, (char*)sFontName.c_str()); + if (pFont) + { + std::cout << "FIND; "; + free(pFont); + } + else + std::cout << "NO; "; + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::string sText = std::string((char*)(pAnnots + i), nPathLength); + NSStringUtils::string_replaceA(sText, "\r", "\n"); + std::cout << "text:" << sText << " "; + i += nPathLength; + + std::cout << "} "; + } + std::cout << "}, " << std::endl; + } + if (nFlags & (1 << 4)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "CreationDate " << std::string((char*)(pAnnots + i), nPathLength) << ", "; + i += nPathLength; + } + if (nFlags & (1 << 5)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "Ref to " << nPathLength << ", "; + } + if (nFlags & (1 << 6)) + { + nPathLength = READ_BYTE(pAnnots + i); + i += 1; + std::cout << "Reason " << nPathLength << ", "; + } + if (nFlags & (1 << 7)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "Subj " << std::string((char*)(pAnnots + i), nPathLength) << ", "; + i += nPathLength; + } + } + + if (sType == "Text") + { + if (nFlags & (1 << 15)) + std::cout << "Open true, "; + else + std::cout << "Open false, "; + if (nFlags & (1 << 16)) + { + nPathLength = READ_BYTE(pAnnots + i); + i += 1; + std::string arrIcon[] = {"Check", "Checkmark", "Circle", "Comment", "Cross", "CrossHairs", "Help", "Insert", "Key", "NewParagraph", "Note", "Paragraph", "RightArrow", "RightPointer", "Star", "UpArrow", "UpLeftArrow"}; + std::cout << "Icon " << arrIcon[nPathLength] << ", "; + } + if (nFlags & (1 << 17)) + { + nPathLength = READ_BYTE(pAnnots + i); + i += 1; + std::string arrStateModel[] = {"Marked", "Review"}; + std::cout << "State model " << arrStateModel[nPathLength] << ", "; + } + if (nFlags & (1 << 18)) + { + nPathLength = READ_BYTE(pAnnots + i); + i += 1; + std::string arrState[] = {"Marked", "Unmarked", "Accepted", "Rejected", "Cancelled", "Completed", "None"}; + std::cout << "State " << arrState[nPathLength] << ", "; + } + } + else if (sType == "Line") + { + std::cout << "L"; for (int j = 0; j < 4; ++j) { nPathLength = READ_INT(pAnnots + i); @@ -1715,14 +1552,112 @@ int main(int argc, char* argv[]) std::cout << " " << (double)nPathLength / 100.0; } std::cout << ", "; - } - if (nFlags & (1 << 16)) - { - int nCLLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "CL"; + if (nFlags & (1 << 15)) + { + std::cout << "LE "; + for (int j = 0; j < 2; ++j) + { + nPathLength = READ_BYTE(pAnnots + i); + i += 1; + std::string arrLE[] = {"Square", "Circle", "Diamond", "OpenArrow", "ClosedArrow", "None", "Butt", "ROpenArrow", "RClosedArrow", "Slash"}; + std::cout << arrLE[nPathLength] << " "; + } + std::cout << ", "; + } + if (nFlags & (1 << 16)) + { + int nICLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "IC"; - for (int j = 0; j < nCLLength; ++j) + for (int j = 0; j < nICLength; ++j) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << " " << (double)nPathLength / 10000.0; + } + std::cout << ", "; + } + if (nFlags & (1 << 17)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "LL " << (double)nPathLength / 100.0 << ", "; + } + if (nFlags & (1 << 18)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "LLE " << (double)nPathLength / 100.0 << ", "; + } + if (nFlags & (1 << 19)) + std::cout << "Cap true, "; + else + std::cout << "Cap false, "; + if (nFlags & (1 << 20)) + { + nPathLength = READ_BYTE(pAnnots + i); + i += 1; + std::string arrIT[] = {"LineDimension", "LineArrow"}; + std::cout << "IT " << arrIT[nPathLength] << ", "; + } + if (nFlags & (1 << 21)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "LLO " << (double)nPathLength / 100.0 << ", "; + } + if (nFlags & (1 << 22)) + { + nPathLength = READ_BYTE(pAnnots + i); + i += 1; + std::string arrCP[] = {"Inline", "Top"}; + std::cout << "CP " << arrCP[nPathLength] << ", "; + } + if (nFlags & (1 << 23)) + { + std::cout << "CO "; + for (int j = 0; j < 2; ++j) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << (double)nPathLength / 100.0 << " "; + } + std::cout << ", "; + } + } + else if (sType == "Ink") + { + int nInkLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "InkList "; + + for (int j = 0; j < nInkLength; ++j) + { + int nInkJLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "[ "; + + for (int k = 0; k < nInkJLength; ++k) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << (double)nPathLength / 100.0 << " "; + } + std::cout << "] "; + } + std::cout << ", "; + } + else if (sType == "Highlight" || + sType == "Underline" || + sType == "Squiggly" || + sType == "StrikeOut") + { + std::cout << "QuadPoints"; + int nQuadPointsLength = READ_INT(pAnnots + i); + i += 4; + + for (int j = 0; j < nQuadPointsLength; ++j) { nPathLength = READ_INT(pAnnots + i); i += 4; @@ -1730,199 +1665,329 @@ int main(int argc, char* argv[]) } std::cout << ", "; } - if (nFlags & (1 << 17)) + else if (sType == "Square" || + sType == "Circle") { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "DS " << std::string((char*)(pAnnots + i), nPathLength) << ", "; - i += nPathLength; - } - if (nFlags & (1 << 18)) - { - nPathLength = READ_BYTE(pAnnots + i); - i += 1; - std::string arrLE[] = {"Square", "Circle", "Diamond", "OpenArrow", "ClosedArrow", "None", "Butt", "ROpenArrow", "RClosedArrow", "Slash"}; - std::cout << "LE " << arrLE[nPathLength] << ", "; - } - if (nFlags & (1 << 20)) - { - nPathLength = READ_BYTE(pAnnots + i); - i += 1; - std::string arrIT[] = {"FreeText", "FreeTextCallout", "FreeTextTypeWriter"}; - std::cout << "IT " << arrIT[nPathLength] << ", "; - } - if (nFlags & (1 << 21)) - { - int nCLLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "C from DA:"; - - for (int j = 0; j < nCLLength; ++j) + if (nFlags & (1 << 15)) { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << " " << (double)nPathLength / 10000.0; + std::cout << "RD"; + for (int j = 0; j < 4; ++j) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << " " << (double)nPathLength / 100.0; + } + std::cout << ", "; + } + if (nFlags & (1 << 16)) + { + int nICLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "IC "; + + for (int j = 0; j < nICLength; ++j) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << (double)nPathLength / 10000.0 << " "; + } + std::cout << ", "; } - std::cout << ", "; } - } - else if (sType == "Caret") - { - if (nFlags & (1 << 15)) + else if (sType == "Polygon" || + sType == "PolyLine") { - std::cout << "RD"; - for (int j = 0; j < 4; ++j) + int nVerticesLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "Vertices"; + + for (int j = 0; j < nVerticesLength; ++j) { nPathLength = READ_INT(pAnnots + i); i += 4; std::cout << " " << (double)nPathLength / 100.0; } std::cout << ", "; + + if (nFlags & (1 << 15)) + { + std::cout << "LE"; + for (int j = 0; j < 2; ++j) + { + nPathLength = READ_BYTE(pAnnots + i); + i += 1; + std::string arrLE[] = {"Square", "Circle", "Diamond", "OpenArrow", "ClosedArrow", "None", "Butt", "ROpenArrow", "RClosedArrow", "Slash"}; + std::cout << " " << arrLE[nPathLength]; + } + std::cout << ", "; + } + if (nFlags & (1 << 16)) + { + int nICLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "IC"; + + for (int j = 0; j < nICLength; ++j) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << " " << (double)nPathLength / 10000.0; + } + std::cout << ", "; + } + if (nFlags & (1 << 20)) + { + nPathLength = READ_BYTE(pAnnots + i); + i += 1; + std::string arrIT[] = {"PolygonCloud", "PolyLineDimension", "PolygonDimension"}; + std::cout << "IT " << arrIT[nPathLength] << ", "; + } } - if (nFlags & (1 << 16)) + else if (sType == "Popup") { + nFlags = READ_INT(pAnnots + i); + i += 4; + if (nFlags & (1 << 0)) + std::cout << "Open true, "; + else + std::cout << "Open false, "; + if (nFlags & (1 << 1)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "Popup parent " << nPathLength << ", "; + } + } + else if (sType == "FreeText") + { + std::string arrQ[] = {"left-justified", "centered", "right-justified"}; nPathLength = READ_BYTE(pAnnots + i); i += 1; - std::string arrSy[] = {"None", "P", "S"}; - std::cout << "Sy " << arrSy[nPathLength] << ", "; + std::cout << "Q " << arrQ[nPathLength] << ", "; + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "Rotate " << nPathLength << ", "; + + if (nFlags & (1 << 15)) + { + std::cout << "RD"; + for (int j = 0; j < 4; ++j) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << " " << (double)nPathLength / 100.0; + } + std::cout << ", "; + } + if (nFlags & (1 << 16)) + { + int nCLLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "CL"; + + for (int j = 0; j < nCLLength; ++j) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << " " << (double)nPathLength / 100.0; + } + std::cout << ", "; + } + if (nFlags & (1 << 17)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "DS " << std::string((char*)(pAnnots + i), nPathLength) << ", "; + i += nPathLength; + } + if (nFlags & (1 << 18)) + { + nPathLength = READ_BYTE(pAnnots + i); + i += 1; + std::string arrLE[] = {"Square", "Circle", "Diamond", "OpenArrow", "ClosedArrow", "None", "Butt", "ROpenArrow", "RClosedArrow", "Slash"}; + std::cout << "LE " << arrLE[nPathLength] << ", "; + } + if (nFlags & (1 << 20)) + { + nPathLength = READ_BYTE(pAnnots + i); + i += 1; + std::string arrIT[] = {"FreeText", "FreeTextCallout", "FreeTextTypeWriter"}; + std::cout << "IT " << arrIT[nPathLength] << ", "; + } + if (nFlags & (1 << 21)) + { + int nCLLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "C from DA:"; + + for (int j = 0; j < nCLLength; ++j) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << " " << (double)nPathLength / 10000.0; + } + std::cout << ", "; + } } + else if (sType == "Caret") + { + if (nFlags & (1 << 15)) + { + std::cout << "RD"; + for (int j = 0; j < 4; ++j) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << " " << (double)nPathLength / 100.0; + } + std::cout << ", "; + } + if (nFlags & (1 << 16)) + { + nPathLength = READ_BYTE(pAnnots + i); + i += 1; + std::string arrSy[] = {"None", "P", "S"}; + std::cout << "Sy " << arrSy[nPathLength] << ", "; + } + } + else if (sType == "FileAttachment") + { + if (nFlags & (1 << 15)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "Name " << std::string((char*)(pAnnots + i), nPathLength) << ", "; + i += nPathLength; + } + if (nFlags & (1 << 16)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "FS " << std::string((char*)(pAnnots + i), nPathLength) << ", "; + i += nPathLength; + } + if (nFlags & (1 << 17)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "F " << std::string((char*)(pAnnots + i), nPathLength) << ", "; + i += nPathLength; + } + if (nFlags & (1 << 18)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "UF " << std::string((char*)(pAnnots + i), nPathLength) << ", "; + i += nPathLength; + } + if (nFlags & (1 << 19)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "DOS " << std::string((char*)(pAnnots + i), nPathLength) << ", "; + i += nPathLength; + } + if (nFlags & (1 << 20)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "Mac " << std::string((char*)(pAnnots + i), nPathLength) << ", "; + i += nPathLength; + } + if (nFlags & (1 << 21)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "Unix " << std::string((char*)(pAnnots + i), nPathLength) << ", "; + i += nPathLength; + } + if (nFlags & (1 << 22)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "ID " << std::string((char*)(pAnnots + i), nPathLength); + i += nPathLength; + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << " " << std::string((char*)(pAnnots + i), nPathLength) << ", "; + i += nPathLength; + } + if (nFlags & (1 << 23)) + std::cout << "V true, "; + else + std::cout << "V false, "; + if (nFlags & (1 << 24)) + { + int nFlag = READ_INT(pAnnots + i); + i += 4; + + if (nFlag & (1 << 0)) + ReadFileAttachment(pAnnots, i, 0); + if (nFlag & (1 << 1)) + ReadFileAttachment(pAnnots, i, 1); + if (nFlag & (1 << 2)) + ReadFileAttachment(pAnnots, i, 2); + if (nFlag & (1 << 3)) + ReadFileAttachment(pAnnots, i, 3); + if (nFlag & (1 << 4)) + ReadFileAttachment(pAnnots, i, 4); + } + if (nFlags & (1 << 26)) + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "Desc " << std::string((char*)(pAnnots + i), nPathLength) << ", "; + i += nPathLength; + } + } + else if (sType == "Stamp") + { + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "Icon " << std::string((char*)(pAnnots + i), nPathLength) << ", "; + i += nPathLength; + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "Rotate " << nPathLength / 10000.0 << ", "; + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "X1 " << (double)nPathLength / 10000.0 << ", "; + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "Y1 " << (double)nPathLength / 10000.0 << ", "; + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "X2 " << (double)nPathLength / 10000.0 << ", "; + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "Y2 " << (double)nPathLength / 10000.0 << ", "; + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "X3 " << (double)nPathLength / 10000.0 << ", "; + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "Y3 " << (double)nPathLength / 10000.0 << ", "; + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "X4 " << (double)nPathLength / 10000.0 << ", "; + + nPathLength = READ_INT(pAnnots + i); + i += 4; + std::cout << "Y4 " << (double)nPathLength / 10000.0 << ", "; + } + + std::cout << std::endl << "]" << std::endl; } - else if (sType == "FileAttachment") - { - if (nFlags & (1 << 15)) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "Name " << std::string((char*)(pAnnots + i), nPathLength) << ", "; - i += nPathLength; - } - if (nFlags & (1 << 16)) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "FS " << std::string((char*)(pAnnots + i), nPathLength) << ", "; - i += nPathLength; - } - if (nFlags & (1 << 17)) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "F " << std::string((char*)(pAnnots + i), nPathLength) << ", "; - i += nPathLength; - } - if (nFlags & (1 << 18)) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "UF " << std::string((char*)(pAnnots + i), nPathLength) << ", "; - i += nPathLength; - } - if (nFlags & (1 << 19)) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "DOS " << std::string((char*)(pAnnots + i), nPathLength) << ", "; - i += nPathLength; - } - if (nFlags & (1 << 20)) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "Mac " << std::string((char*)(pAnnots + i), nPathLength) << ", "; - i += nPathLength; - } - if (nFlags & (1 << 21)) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "Unix " << std::string((char*)(pAnnots + i), nPathLength) << ", "; - i += nPathLength; - } - if (nFlags & (1 << 22)) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "ID " << std::string((char*)(pAnnots + i), nPathLength); - i += nPathLength; - - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << " " << std::string((char*)(pAnnots + i), nPathLength) << ", "; - i += nPathLength; - } - if (nFlags & (1 << 23)) - std::cout << "V true, "; - else - std::cout << "V false, "; - if (nFlags & (1 << 24)) - { - int nFlag = READ_INT(pAnnots + i); - i += 4; - - if (nFlag & (1 << 0)) - ReadFileAttachment(pAnnots, i, 0); - if (nFlag & (1 << 1)) - ReadFileAttachment(pAnnots, i, 1); - if (nFlag & (1 << 2)) - ReadFileAttachment(pAnnots, i, 2); - if (nFlag & (1 << 3)) - ReadFileAttachment(pAnnots, i, 3); - if (nFlag & (1 << 4)) - ReadFileAttachment(pAnnots, i, 4); - } - if (nFlags & (1 << 26)) - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "Desc " << std::string((char*)(pAnnots + i), nPathLength) << ", "; - i += nPathLength; - } - } - else if (sType == "Stamp") - { - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "Icon " << std::string((char*)(pAnnots + i), nPathLength) << ", "; - i += nPathLength; - - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "Rotate " << nPathLength / 10000.0 << ", "; - - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "X1 " << (double)nPathLength / 10000.0 << ", "; - - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "Y1 " << (double)nPathLength / 10000.0 << ", "; - - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "X2 " << (double)nPathLength / 10000.0 << ", "; - - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "Y2 " << (double)nPathLength / 10000.0 << ", "; - - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "X3 " << (double)nPathLength / 10000.0 << ", "; - - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "Y3 " << (double)nPathLength / 10000.0 << ", "; - - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "X4 " << (double)nPathLength / 10000.0 << ", "; - - nPathLength = READ_INT(pAnnots + i); - i += 4; - std::cout << "Y4 " << (double)nPathLength / 10000.0 << ", "; - } - - std::cout << std::endl << std::endl; } if (pAnnots) @@ -1952,6 +2017,8 @@ int main(int argc, char* argv[]) Close(pGrFile); RELEASEARRAYOBJECTS(pFileData); + RELEASEARRAYOBJECTS(pSplitPages); + RELEASEARRAYOBJECTS(pFileMerge); RELEASEARRAYOBJECTS(pCMapData); return 0; diff --git a/DesktopEditor/graphics/pro/raster.pri b/DesktopEditor/graphics/pro/raster.pri index f5e54810fc..28d4b2d2d8 100644 --- a/DesktopEditor/graphics/pro/raster.pri +++ b/DesktopEditor/graphics/pro/raster.pri @@ -19,6 +19,10 @@ core_linux { QMAKE_CXXFLAGS += -Wno-narrowing } +core_linux_clang { + QMAKE_CFLAGS += -Wno-incompatible-function-pointer-types +} + core_mac { DEFINES += HAVE_UNISTD_H HAVE_FCNTL_H } diff --git a/DesktopEditor/raster/ImageFileFormatChecker.cpp b/DesktopEditor/raster/ImageFileFormatChecker.cpp index 467ee19751..020119a96c 100644 --- a/DesktopEditor/raster/ImageFileFormatChecker.cpp +++ b/DesktopEditor/raster/ImageFileFormatChecker.cpp @@ -58,7 +58,7 @@ CImageFileFormatChecker::CImageFileFormatChecker() { eFileType = _CXIMAGE_FORMAT_UNKNOWN; } -CImageFileFormatChecker::CImageFileFormatChecker(std::wstring sFileName) +CImageFileFormatChecker::CImageFileFormatChecker(const std::wstring& sFileName) { eFileType = _CXIMAGE_FORMAT_UNKNOWN; isImageFile(sFileName); @@ -433,7 +433,7 @@ bool CImageFileFormatChecker::isPicFile(BYTE *pBuffer, DWORD dwBytes) return false; } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -bool CImageFileFormatChecker::isImageFile(std::wstring& fileName) +bool CImageFileFormatChecker::isImageFile(const std::wstring& fileName) { eFileType = _CXIMAGE_FORMAT_UNKNOWN; /////////////////////////////////////////////////////////////////////////////// @@ -673,7 +673,7 @@ bool CImageFileFormatChecker::isImageFile(BYTE* buffer, DWORD sizeRead) if (eFileType) return true; return false; } -bool CImageFileFormatChecker::isSvmFile(std::wstring & fileName) +bool CImageFileFormatChecker::isSvmFile(const std::wstring & fileName) { eFileType = _CXIMAGE_FORMAT_UNKNOWN; //////////////////////////////////////////////////////////////////////////////// @@ -703,7 +703,7 @@ bool CImageFileFormatChecker::isSvmFile(std::wstring & fileName) if (eFileType)return true; else return false; } -bool CImageFileFormatChecker::isPngFile(std::wstring & fileName) +bool CImageFileFormatChecker::isPngFile(const std::wstring & fileName) { eFileType = _CXIMAGE_FORMAT_UNKNOWN; //////////////////////////////////////////////////////////////////////////////// @@ -735,7 +735,7 @@ bool CImageFileFormatChecker::isPngFile(std::wstring & fileName) } -bool CImageFileFormatChecker::isRawFile(std::wstring& fileName) +bool CImageFileFormatChecker::isRawFile(const std::wstring& fileName) { // TODO: return false; @@ -745,7 +745,7 @@ bool CImageFileFormatChecker::isRawFile(BYTE* pBuffer, DWORD dwBytes) // TODO: return false; } -bool CImageFileFormatChecker::isSvgFile(std::wstring& fileName) +bool CImageFileFormatChecker::isSvgFile(const std::wstring& fileName) { #ifndef IMAGE_CHECKER_DISABLE_XML XmlUtils::CXmlLiteReader oReader; diff --git a/DesktopEditor/raster/ImageFileFormatChecker.h b/DesktopEditor/raster/ImageFileFormatChecker.h index a3640274ea..51c06178de 100644 --- a/DesktopEditor/raster/ImageFileFormatChecker.h +++ b/DesktopEditor/raster/ImageFileFormatChecker.h @@ -71,17 +71,17 @@ public: __ENUM_CXIMAGE_FORMATS eFileType; CImageFileFormatChecker(); - CImageFileFormatChecker(std::wstring sFileName); + CImageFileFormatChecker(const std::wstring& sFileName); CImageFileFormatChecker(BYTE* pBuffer, DWORD dwBytes); - bool isImageFileInZip(std::wstring& fileName); + bool isImageFileInZip(const std::wstring& fileName); - bool isImageFile(std::wstring& fileName); - bool isPngFile(std::wstring& fileName); - bool isSvmFile(std::wstring& fileName); + bool isImageFile(const std::wstring& fileName); + bool isPngFile(const std::wstring& fileName); + bool isSvmFile(const std::wstring& fileName); - bool isRawFile(std::wstring& fileName); - bool isSvgFile(std::wstring& fileName); + bool isRawFile(const std::wstring& fileName); + bool isSvgFile(const std::wstring& fileName); bool isImageFile(BYTE* pBuffer,DWORD dwBytes); bool isBmpFile(BYTE* pBuffer,DWORD dwBytes); diff --git a/DesktopEditor/raster/Metafile/Common/MetaFileTypes.h b/DesktopEditor/raster/Metafile/Common/MetaFileTypes.h index 09ff44864a..e3ec2d110b 100644 --- a/DesktopEditor/raster/Metafile/Common/MetaFileTypes.h +++ b/DesktopEditor/raster/Metafile/Common/MetaFileTypes.h @@ -34,6 +34,7 @@ #include #include +#include #include "../../../common/StringExt.h" #ifndef BYTE diff --git a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp index 5ae466d3c1..8fa6c9560b 100644 --- a/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp +++ b/DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp @@ -645,6 +645,9 @@ namespace MetaFile //TODO::реализовать при встрече } + if (BrushDataTransform & unBrushDataFlags) + m_oStream.Skip(24); + if (BrushDataPresetColors & unBrushDataFlags) { unsigned int unPositionCount; diff --git a/DjVuFile/DjVuFileImplementation.cpp b/DjVuFile/DjVuFileImplementation.cpp index a60f149e19..c70ee7a2cd 100644 --- a/DjVuFile/DjVuFileImplementation.cpp +++ b/DjVuFile/DjVuFileImplementation.cpp @@ -247,14 +247,12 @@ void CDjVuFileImplementation::DrawPageOnRenderer(IRenderer* pRenderer, int nPag long lRendererType = c_nUnknownRenderer; pRenderer->get_Type(&lRendererType); -#ifndef BUILDING_WASM_MODULE if (c_nPDFWriter == lRendererType) { XmlUtils::CXmlNode oText = ParseText(pPage); CreatePdfFrame(pRenderer, pPage, nPageIndex, oText); } else -#endif { XmlUtils::CXmlNode oText = ParseText(pPage); CreateFrame(pRenderer, pPage, nPageIndex, oText); diff --git a/HwpFile/HWPFile.pro b/HwpFile/HWPFile.pro index 7814ddb3ea..424f357bff 100644 --- a/HwpFile/HWPFile.pro +++ b/HwpFile/HWPFile.pro @@ -16,7 +16,9 @@ LIBS += -L$$CORE_BUILDS_LIBRARIES_PATH -lCryptoPPLib ADD_DEPENDENCY(kernel, UnicodeConverter, graphics) -DEFINES += HWPFILE_USE_DYNAMIC_LIBRARY +DEFINES += HWPFILE_USE_DYNAMIC_LIBRARY \ + CRYPTOPP_DISABLE_ASM + SOURCES += \ HWPFile.cpp \ diff --git a/HwpFile/HwpDoc/Common/XMLNode.h b/HwpFile/HwpDoc/Common/XMLNode.h index 4070946113..518ea10488 100644 --- a/HwpFile/HwpDoc/Common/XMLNode.h +++ b/HwpFile/HwpDoc/Common/XMLNode.h @@ -19,6 +19,7 @@ public: }; int ConvertWidthToHWP(const std::wstring& wsValue); +int ConvertHexToInt(const std::string& wsValue, const int& _default = 0x00000000); } #endif // XMLNODEH_H diff --git a/HwpFile/HwpDoc/Common/XMLReader.cpp b/HwpFile/HwpDoc/Common/XMLReader.cpp index 8b022f95b5..82d133855b 100644 --- a/HwpFile/HwpDoc/Common/XMLReader.cpp +++ b/HwpFile/HwpDoc/Common/XMLReader.cpp @@ -17,20 +17,7 @@ bool CXMLNode::GetAttributeBool(const std::wstring& wsName) int CXMLNode::GetAttributeColor(const std::wstring& wsName, const int& _default) { - std::wstring sColor = XmlUtils::CXmlNode::GetAttribute(wsName); - - if (L"none" != sColor) - { - if (L'#' == sColor.front()) - sColor.erase(0, 1); - - if (sColor.length() < 6) - return _default; - - return std::stoi(sColor.substr(0, 6), nullptr, 16); - } - - return _default; + return ConvertHexToInt(XmlUtils::CXmlNode::GetAttributeA(wsName), _default); } CXMLNode CXMLNode::GetChild(const std::wstring& wsName) @@ -98,4 +85,36 @@ int ConvertWidthToHWP(const std::wstring& wsValue) return 0; } + +int ConvertHexToInt(const std::string& wsValue, const int& _default) +{ + if (wsValue.empty() || "none" == wsValue) + return _default; + + std::string::const_iterator itStart = wsValue.cbegin(); + + if ('#' == *itStart) + ++itStart; + + if (wsValue.cend() - itStart < 6) + return _default; + + itStart = wsValue.cend() - 6; + + int nResult = 0; + + while (itStart != wsValue.cend()) + { + if ('0' <= *itStart && *itStart <= '9') + nResult = (nResult << 4) | (*itStart++ - '0'); + else if ('A' <= *itStart && *itStart <= 'F') + nResult = (nResult << 4) | (*itStart++ - 'A' + 10); + else if ('a' <= *itStart && *itStart <= 'f') + nResult = (nResult << 4) | (*itStart++ - 'a' + 10); + else + return _default; + } + + return nResult; +} } diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordBorderFill.cpp b/HwpFile/HwpDoc/HWPElements/HWPRecordBorderFill.cpp index 2569ee8618..503586237b 100644 --- a/HwpFile/HwpDoc/HWPElements/HWPRecordBorderFill.cpp +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordBorderFill.cpp @@ -62,12 +62,7 @@ EColorFillPattern GetColorFillPattern(int nPattern) void TBorder::ReadFromNode(CXMLNode& oNode) { m_eStyle = GetLineStyle2(oNode.GetAttribute(L"type")); - - HWP_STRING sColor = std::regex_replace(oNode.GetAttribute(L"color"), std::wregex(L"^#([0-9A-Fa-f]+)$"), L"$1"); - - if (L"none" != sColor) - m_nColor = std::stoi(sColor, 0, 16); - + m_nColor = oNode.GetAttributeColor(L"color"); m_chWidth = (HWP_BYTE)ConvertWidthToHWP(oNode.GetAttribute(L"width")); } @@ -199,7 +194,7 @@ void CFill::ReadGradation(CXMLNode& oNode) m_arColors.resize(arChilds.size()); for (unsigned int unIndex = 0; unIndex < arChilds.size(); ++unIndex) - m_arColors[unIndex] = std::stoi(std::regex_replace(arChilds[unIndex].GetText(), std::wregex(L"\\D"), L""), 0, 16); + m_arColors[unIndex] = ConvertHexToInt(arChilds[unIndex].GetTextA()); } void CFill::ReadImgBrush(CXMLNode& oNode) diff --git a/HwpFile/HwpDoc/HWPElements/HWPRecordBullet.cpp b/HwpFile/HwpDoc/HWPElements/HWPRecordBullet.cpp index 877ebae315..91ee5db3a3 100644 --- a/HwpFile/HwpDoc/HWPElements/HWPRecordBullet.cpp +++ b/HwpFile/HwpDoc/HWPElements/HWPRecordBullet.cpp @@ -48,8 +48,16 @@ CHWPRecordBullet::CHWPRecordBullet(CHWPDocInfo& oDocInfo, int nTagNum, int nLeve CHWPRecordBullet::CHWPRecordBullet(CHWPDocInfo& oDocInfo, CXMLNode& oNode, int nVersion) : CHWPRecord(EHWPTag::HWPTAG_BULLET, 0, 0), m_pParent(&oDocInfo) { - m_chBulletChar = oNode.GetAttribute(L"char").at(0); - m_chCheckBulletChar = oNode.GetAttribute(L"checkedChar").at(0); + std::wstring wsAttributeValue = oNode.GetAttribute(L"char"); + + if (!wsAttributeValue.empty()) + m_chBulletChar = wsAttributeValue.at(0); + + wsAttributeValue = oNode.GetAttribute(L"checkedChar"); + + if (!wsAttributeValue.empty()) + m_chCheckBulletChar = wsAttributeValue.at(0); + m_nBulletImage = oNode.GetAttributeInt(L"useImage"); for (CXMLNode& oChild : oNode.GetChilds()) diff --git a/MsBinaryFile/PptFile/PPTXWriter/Converter.cpp b/MsBinaryFile/PptFile/PPTXWriter/Converter.cpp index 943564f3c6..baa6bb3eb4 100644 --- a/MsBinaryFile/PptFile/PPTXWriter/Converter.cpp +++ b/MsBinaryFile/PptFile/PPTXWriter/Converter.cpp @@ -619,6 +619,7 @@ namespace PPT WriteSlides(); WriteNotes(); + m_pShapeWriter->SetRelsGenerator(NULL); } // todo reforming and refactoring! @@ -1544,6 +1545,8 @@ namespace PPT oRels.StartSlide(nLayout, pSlide->m_lNotesID); } + + m_pShapeWriter->SetRelsGenerator(&oRels); oWriter.WriteString(std::wstring(L"")); oWriter.WriteString(std::wstring(L"m_arNotes[nIndexNotes]; oRels.StartNotes(pNotes->m_lSlideID, m_pDocument->m_pNotesMaster != NULL); + + m_pShapeWriter->SetRelsGenerator(&oRels); oWriter.WriteString(std::wstring(L"")); oWriter.WriteString(std::wstring(L"second) - { - if(!i.empty()) - counter++; - } - return counter; - } - return 0; -} } //namespace XMLSTUFF diff --git a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h index bf9abf6a92..60a3bb8df6 100644 --- a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h +++ b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h @@ -87,15 +87,13 @@ namespace STR }; namespace XMLSTUFF -{; - +{ const std::wstring name2sheet_name(std::wstring name, const std::wstring prefix); const std::wstring xti_indexes2sheet_name(const short tabFirst, const short tabLast, std::vector& names, const std::wstring prefix = L""); unsigned short sheetsnames2ixti(std::wstring name); unsigned int definenames2index(std::wstring name); bool isTableFmla(const std::wstring& tableName, _UINT32& listIndex); bool isColumn(const std::wstring& columnName, _UINT32 listIndex, _UINT16& indexColumn); -unsigned int getColumnsCount(_UINT32 listIndex); unsigned short AddMultysheetXti(const std::wstring& name, const _INT32& firstIxti, const _INT32& secondIxti); unsigned int AddDefinedName(const std::wstring& name); } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/FileSharing.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/FileSharing.h index 080f5a6d5d..0da5c89195 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/FileSharing.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/FileSharing.h @@ -56,7 +56,7 @@ public: static const ElementType type = typeFileSharing; Boolean fReadOnlyRec; - unsigned short wResPassNum; + unsigned short wResPassNum = 0; std::wstring wResPass; _UINT16 iNoResPass; XLUnicodeString stUNUsername; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/XF.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/XF.h index c942072e91..dac43e7223 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/XF.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/XF.h @@ -61,12 +61,12 @@ namespace XLS static const ElementType type = typeXF; - _UINT16 font_index; + _UINT16 font_index = 0; - _UINT16 ifmt; //used - std::wstring format_code; + _UINT16 ifmt = 0; //used + std::wstring format_code = L""; - _UINT16 ixfParent; + _UINT16 ixfParent = 0; bool fLocked = false; bool fHidden = false; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/FRTSqref.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/FRTSqref.cpp index 5bbbb37e68..266c679631 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/FRTSqref.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/FRTSqref.cpp @@ -1,4 +1,4 @@ -/* +/* * (c) Copyright Ascensio System SIA 2010-2021 * * This program is a free software product. You can redistribute it and/or @@ -71,10 +71,9 @@ namespace XLSB void FRTSqref::save(XLS::CFRecord& record) { - _UINT32 flags = 0; + _UINT32 flags = 2; SETBIT(flags, 0, fAdjDelete) - SETBIT(flags, 1, fDoAdjust) SETBIT(flags, 2, fAdjChange) SETBIT(flags, 3, fEdit) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtContainer.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtContainer.cpp index 89b9640792..dd116de631 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtContainer.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ODRAW/OfficeArtContainer.cpp @@ -82,6 +82,7 @@ OfficeArtRecordPtr OfficeArtContainer::CreateOfficeArt(unsigned short type) case FSP: art_record = OfficeArtRecordPtr(new OfficeArtFSP); break; case FOPT: + case SecondaryFOPT: art_record = OfficeArtRecordPtr(new OfficeArtFOPT); break; case ChildAnchor: art_record = OfficeArtRecordPtr(new OfficeArtChildAnchor); break; @@ -116,8 +117,6 @@ OfficeArtRecordPtr OfficeArtContainer::CreateOfficeArt(unsigned short type) art_record = OfficeArtRecordPtr(new OfficeArtBStoreContainer); break; case TertiaryFOPT: art_record = OfficeArtRecordPtr(new OfficeArtTertiaryFOPT); break; - case SecondaryFOPT: - case FPSPL: case FDGSL: case FBSE: diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp index a93b32f0a9..102b59a5c9 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp @@ -617,21 +617,11 @@ const bool SyntaxPtg::extract_PtgList(std::wstring::const_iterator& first, std:: } else if (boost::regex_search(first, last, results_1, reg_inside_table6)) { - auto colCount = XMLSTUFF::getColumnsCount(indexTable); - if(colCount>1) - { - ptgList.columns = 0x02; - ptgList.colFirst = 0; - ptgList.colLast = colCount-1; - first = results_1[0].second; - } - else - { - ptgList.columns = 0x01; - ptgList.colFirst = 0; - ptgList.colLast = 0; - first = results_1[0].second; - } + ptgList.columns = 0; + ptgList.colFirst = 0; + ptgList.colLast = 0; + ptgList.rowType = 0x00; + first = results_1[0].second; return true; } else if(boost::regex_search(first, last, results_1, reg_inside_table4)) diff --git a/OOXML/Base/Nullable.h b/OOXML/Base/Nullable.h index 84811d6121..f04a5f2369 100644 --- a/OOXML/Base/Nullable.h +++ b/OOXML/Base/Nullable.h @@ -918,4 +918,87 @@ namespace NSCommon std::wstring& get()const { return *m_pPointer; } }; + class nullable_astring : public nullable_base + { + public: + nullable_astring() : nullable_base() + { + } + nullable_astring(const nullable_astring& oOther) + { + if (NULL == oOther.m_pPointer) + m_pPointer = NULL; + else + m_pPointer = new std::string(*oOther.m_pPointer); + } + void operator=(const std::string& value) + { + RELEASEOBJECT(m_pPointer); + m_pPointer = new std::string(value); + } + void operator+=(const std::string& value) + { + if (NULL == m_pPointer) + m_pPointer = new std::string(value); + else + *m_pPointer += value; + } + void operator=(std::string* value) + { + RELEASEOBJECT(m_pPointer); + m_pPointer = value; + } + nullable_astring& operator=(const nullable_astring& oSrc) + { + RELEASEOBJECT(m_pPointer); + + if (NULL != oSrc.m_pPointer) + m_pPointer = new std::string(*oSrc); + return *this; + } + const bool operator==(const nullable_astring& oOther) const + { + if (!this->m_pPointer) + return false; + + return (*this->m_pPointer) == *oOther; + } + const bool operator==(const std::string& oOther) const + { + if (!this->m_pPointer) + return false; + + return (*this->m_pPointer) == oOther; + } + std::string get_value_or(const std::string& value) const + { + if (NULL == m_pPointer) + { + std::string ret = value; + return ret; + } + return *m_pPointer; + } + std::string ToAttribute(const std::string& name) const + { + if (m_pPointer) + { + return name + "=\"" + (*m_pPointer) + "\" "; + } + return ""; + } + std::string* GetPointerEmptyNullable() + { + std::string* pOldPointer = this->m_pPointer; + this->m_pPointer = NULL; + return pOldPointer; + } + std::string& operator*() { return *m_pPointer; } + std::string* operator->() { return m_pPointer; } + + std::string& operator*() const { return *m_pPointer; } + std::string* operator->() const { return m_pPointer; } + + std::string& get()const { return *m_pPointer; } + }; } diff --git a/OOXML/Binary/Document/BinReader/Readers.cpp b/OOXML/Binary/Document/BinReader/BinaryReaderD.cpp similarity index 99% rename from OOXML/Binary/Document/BinReader/Readers.cpp rename to OOXML/Binary/Document/BinReader/BinaryReaderD.cpp index e1210e711d..4aa058d45c 100644 --- a/OOXML/Binary/Document/BinReader/Readers.cpp +++ b/OOXML/Binary/Document/BinReader/BinaryReaderD.cpp @@ -30,10 +30,10 @@ * */ -#include "Readers.h" +#include "BinaryReaderD.h" #include "../BinWriter/BinReaderWriterDefines.h" -#include "../../Sheets/Writer/BinaryReader.h" +#include "../../Sheets/Writer/BinaryReaderS.h" #include "../../../PPTXFormat/Logic/HeadingVariant.h" @@ -1570,6 +1570,11 @@ int Binary_pPrReader::Read_SecPr(BYTE type, long length, void* poResult) pSectPr->m_oDocGrid.Init(); READ1_DEF(length, res, this->ReadDocGrid, pSectPr->m_oDocGrid.GetPointer()); } + else if (c_oSerProp_secPrType::bidi == type) + { + pSectPr->m_oBidi.Init(); + pSectPr->m_oBidi->m_oVal.FromBool(m_oBufferedStream.GetBool()); + } else res = c_oSerConstants::ReadUnknown; return res; @@ -2160,21 +2165,21 @@ int Binary_tblPrReader::Read_tblPr(BYTE type, long length, void* poResult) if ( c_oSerProp_tblPrType::RowBandSize == type ) { long nRowBandSize = m_oBufferedStream.GetLong(); - pWiterTblPr->RowBandSize = L""; + pWiterTblPr->Props += L""; } else if ( c_oSerProp_tblPrType::ColBandSize == type ) { long nColBandSize = m_oBufferedStream.GetLong(); - pWiterTblPr->ColBandSize = L""; + pWiterTblPr->Props += L""; } else if ( c_oSerProp_tblPrType::Jc == type ) { BYTE jc = m_oBufferedStream.GetUChar(); switch(jc) { - case align_Right: pWiterTblPr->Jc = std::wstring(_T("")); break; - case align_Center: pWiterTblPr->Jc = std::wstring(_T(""));break; - case align_Justify: pWiterTblPr->Jc = std::wstring(_T("")); break; + case align_Right: pWiterTblPr->Props += L""; break; + case align_Center: pWiterTblPr->Props += L""; break; + case align_Justify: pWiterTblPr->Props += L""; break; case align_Left: break; } } @@ -2182,17 +2187,17 @@ int Binary_tblPrReader::Read_tblPr(BYTE type, long length, void* poResult) { double dInd = m_oBufferedStream.GetDouble(); long nInd = SerializeCommon::Round( g_dKoef_mm_to_twips * dInd); - pWiterTblPr->TableInd = L""; + pWiterTblPr->Props += L""; } else if ( c_oSerProp_tblPrType::TableIndTwips == type ) { - pWiterTblPr->TableInd = L""; + pWiterTblPr->Props += L""; } else if ( c_oSerProp_tblPrType::TableW == type ) { docW odocW; READ2_DEF(length, res, this->ReadW, &odocW); - pWiterTblPr->TableW = odocW.Write(std::wstring(_T("w:tblW"))); + pWiterTblPr->Props += odocW.Write(std::wstring(_T("w:tblW"))); } else if ( c_oSerProp_tblPrType::TableCellMar == type ) { @@ -2200,9 +2205,7 @@ int Binary_tblPrReader::Read_tblPr(BYTE type, long length, void* poResult) READ1_DEF(length, res, this->ReadCellMargins, &oTempWriter); if (oTempWriter.GetCurSize() > 0) { - pWiterTblPr->TableCellMar += L""; - pWiterTblPr->TableCellMar += oTempWriter.GetData(); - pWiterTblPr->TableCellMar += L""; + pWiterTblPr->Props += L"" + oTempWriter.GetData() + L""; } } else if ( c_oSerProp_tblPrType::TableBorders == type ) @@ -2213,7 +2216,7 @@ int Binary_tblPrReader::Read_tblPr(BYTE type, long length, void* poResult) std::wstring sTableBorders = tblBorders.toXML(); if (false == sTableBorders.empty()) { - pWiterTblPr->TableBorders += sTableBorders; + pWiterTblPr->Props += sTableBorders; } } else if ( c_oSerProp_tblPrType::Shd == type ) @@ -2224,30 +2227,26 @@ int Binary_tblPrReader::Read_tblPr(BYTE type, long length, void* poResult) std::wstring sShd = oShd.ToString(); if (false == sShd.empty()) { - pWiterTblPr->Shd = L""; + pWiterTblPr->Props += L""; } } else if ( c_oSerProp_tblPrType::tblpPr == type ) { NSStringUtils::CStringBuilder oTempWriter; READ2_DEF(length, res, this->Read_tblpPr, &oTempWriter); - pWiterTblPr->tblpPr += L"tblpPr += oTempWriter.GetData(); - pWiterTblPr->tblpPr += L"/>"; + pWiterTblPr->Props += L""; } else if ( c_oSerProp_tblPrType::tblpPr2 == type ) { NSStringUtils::CStringBuilder oTempWriter; READ2_DEF(length, res, this->Read_tblpPr2, &oTempWriter); - pWiterTblPr->tblpPr += L"tblpPr += oTempWriter.GetData(); - pWiterTblPr->tblpPr += L"/>"; + pWiterTblPr->Props += L""; } else if ( c_oSerProp_tblPrType::Style == type ) { std::wstring Name(m_oBufferedStream.GetString3(length)); Name = XmlUtils::EncodeXmlString(Name); - pWiterTblPr->Style = L""; + pWiterTblPr->Props += L""; } else if ( c_oSerProp_tblPrType::Look == type ) { @@ -2259,7 +2258,7 @@ int Binary_tblPrReader::Read_tblPr(BYTE type, long length, void* poResult) int nLR = (0 == (nLook & 0x0040)) ? 0 : 1; int nBH = (0 == (nLook & 0x0200)) ? 0 : 1; int nBV = (0 == (nLook & 0x0400)) ? 0 : 1; - pWiterTblPr->Look = L"Props += L""; @@ -2274,7 +2273,7 @@ int Binary_tblPrReader::Read_tblPr(BYTE type, long length, void* poResult) case 2: sLayout = _T("fixed");break; } if (false == sLayout.empty()) - pWiterTblPr->Layout = L""; + pWiterTblPr->Props += L""; } else if ( c_oSerProp_tblPrType::tblPrChange == type ) { @@ -2287,11 +2286,11 @@ int Binary_tblPrReader::Read_tblPr(BYTE type, long length, void* poResult) double dSpacing = m_oBufferedStream.GetDouble(); dSpacing /=2; long nSpacing = SerializeCommon::Round( g_dKoef_mm_to_twips * dSpacing); - pWiterTblPr->TableCellSpacing = L""; + pWiterTblPr->Props += L""; } else if ( c_oSerProp_tblPrType::TableCellSpacingTwips == type ) { - pWiterTblPr->TableCellSpacing = L""; + pWiterTblPr->Props += L""; } else if ( c_oSerProp_tblPrType::tblCaption == type ) { @@ -2306,10 +2305,15 @@ int Binary_tblPrReader::Read_tblPr(BYTE type, long length, void* poResult) BYTE jc = m_oBufferedStream.GetUChar(); switch (jc) { - case 1: pWiterTblPr->Overlap = std::wstring(_T("")); break; - case 2: pWiterTblPr->Overlap = std::wstring(_T("")); break; + case 1: pWiterTblPr->Props += L""; break; + case 2: pWiterTblPr->Props += L""; break; } - + } + else if (c_oSerProp_tblPrType::bidiVisual == type) + { + bool val = m_oBufferedStream.GetBool(); + if (val) + pWiterTblPr->Props += L""; } else res = c_oSerConstants::ReadUnknown; diff --git a/OOXML/Binary/Document/BinReader/Readers.h b/OOXML/Binary/Document/BinReader/BinaryReaderD.h similarity index 100% rename from OOXML/Binary/Document/BinReader/Readers.h rename to OOXML/Binary/Document/BinReader/BinaryReaderD.h diff --git a/OOXML/Binary/Document/BinReader/ReaderClasses.cpp b/OOXML/Binary/Document/BinReader/ReaderClasses.cpp index b7821ba0f7..359de29e8f 100644 --- a/OOXML/Binary/Document/BinReader/ReaderClasses.cpp +++ b/OOXML/Binary/Document/BinReader/ReaderClasses.cpp @@ -1253,40 +1253,15 @@ allowOverlap=\"1\">"; bool CWiterTblPr::IsEmpty() { - return Jc.empty() && TableInd.empty() && TableW.empty() && TableCellMar.empty() && TableBorders.empty() && Shd.empty() && tblpPr.empty()&& Style.empty() && Look.empty() && tblPrChange.empty() && TableCellSpacing.empty() && RowBandSize.empty() && ColBandSize.empty(); + return Props.empty() && tblPrChange.empty() && Caption.empty() && Description.empty(); } std::wstring CWiterTblPr::Write() { std::wstring sRes; sRes += L""; - if (false == Style.empty()) - sRes += (Style); - if (false == tblpPr.empty()) - sRes += (tblpPr); - if (!RowBandSize.empty()) - sRes += (RowBandSize); - if (!ColBandSize.empty()) - sRes += (ColBandSize); - if (!Overlap.empty()) - sRes += (Overlap); - if (false == TableW.empty()) - sRes += (TableW); - if (false == Jc.empty()) - sRes += (Jc); - if (false == TableCellSpacing.empty()) - sRes += (TableCellSpacing); - if (false == TableInd.empty()) - sRes += (TableInd); - if (false == TableBorders.empty()) - sRes += (TableBorders); - if (false == Shd.empty()) - sRes += (Shd); - if (false == Layout.empty()) - sRes += (Layout); - if (false == TableCellMar.empty()) - sRes += (TableCellMar); - if (false == Look.empty()) - sRes += (Look); + + sRes += Props; + if (!Caption.empty()) { sRes += L""; sRes += XmlUtils::EncodeXmlString(Description); sRes += L"\"/>"; } - if (!tblPrChange.empty()) - sRes += (tblPrChange); + + sRes += tblPrChange; sRes += L""; return sRes; } diff --git a/OOXML/Binary/Document/BinReader/ReaderClasses.h b/OOXML/Binary/Document/BinReader/ReaderClasses.h index f4f6a66a56..973ef4831b 100644 --- a/OOXML/Binary/Document/BinReader/ReaderClasses.h +++ b/OOXML/Binary/Document/BinReader/ReaderClasses.h @@ -443,24 +443,11 @@ public: class CWiterTblPr { public: - std::wstring Jc; - std::wstring TableInd; - std::wstring TableW; - std::wstring TableCellMar; - std::wstring TableBorders; - std::wstring Shd; - std::wstring tblpPr; - std::wstring Style; - std::wstring RowBandSize; - std::wstring ColBandSize; - std::wstring Look; - std::wstring Layout; std::wstring tblPrChange; - std::wstring TableCellSpacing; std::wstring Caption; std::wstring Description; - std::wstring Overlap; + std::wstring Props; bool IsEmpty(); std::wstring Write(); }; diff --git a/OOXML/Binary/Document/BinWriter/BinReaderWriterDefines.h b/OOXML/Binary/Document/BinWriter/BinReaderWriterDefines.h index 2be04a9dbf..ae0ce98b01 100644 --- a/OOXML/Binary/Document/BinWriter/BinReaderWriterDefines.h +++ b/OOXML/Binary/Document/BinWriter/BinReaderWriterDefines.h @@ -287,7 +287,8 @@ extern int g_nCurFormatVersion; tblDescription = 18, TableIndTwips = 19, TableCellSpacingTwips = 20, - tblOverlap = 21 + tblOverlap = 21, + bidiVisual = 22 };} namespace c_oSer_tblpPrType{enum c_oSer_tblpPrType { @@ -479,7 +480,8 @@ extern int g_nCurFormatVersion; endnotePr = 11, rtlGutter = 12, lnNumType = 13, - docGrid = 14 + docGrid = 14, + bidi = 15 };} namespace c_oSerProp_secPrSettingsType{enum c_oSerProp_secPrSettingsType { diff --git a/OOXML/Binary/Document/BinWriter/BinWriters.cpp b/OOXML/Binary/Document/BinWriter/BinaryWriterD.cpp similarity index 99% rename from OOXML/Binary/Document/BinWriter/BinWriters.cpp rename to OOXML/Binary/Document/BinWriter/BinaryWriterD.cpp index 85aeee134f..0e50ddb243 100644 --- a/OOXML/Binary/Document/BinWriter/BinWriters.cpp +++ b/OOXML/Binary/Document/BinWriter/BinaryWriterD.cpp @@ -29,7 +29,7 @@ * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ -#include "BinWriters.h" +#include "BinaryWriterD.h" #include "../DocWrapper/FontProcessor.h" #include "../../../../Common/Base64.h" @@ -37,7 +37,7 @@ #include "../../Presentation/FontCutter.h" #include "../../../PPTXFormat/Logic/HeadingVariant.h" -#include "../../Sheets/Reader/BinaryWriter.h" +#include "../../Sheets/Reader/BinaryWriterS.h" #include "BinEquationWriter.h" #include "../../../../OfficeUtils/src/OfficeUtils.h" @@ -1559,6 +1559,12 @@ void Binary_pPrWriter::WriteSectPr (OOX::Logic::CSectionProperty* pSectPr) WriteDocGrid(pSectPr->m_oDocGrid.get()); m_oBcw.WriteItemEnd(nCurPos); } + if (pSectPr->m_oBidi.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerProp_secPrType::bidi); + m_oBcw.m_oStream.WriteBOOL(pSectPr->m_oBidi->m_oVal.ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } } void Binary_pPrWriter::WritePageSettings(OOX::Logic::CSectionProperty* pSectPr) { @@ -2158,14 +2164,12 @@ void Binary_tblPrWriter::WriteTblPr(OOX::Logic::CTableProperty* p_tblPr) m_oBcw.m_oStream.WriteBYTE(c_oSerProp_tblPrType::Style); m_oBcw.m_oStream.WriteStringW(p_tblPr->m_oTblStyle->ToString2()); } - //Look if (p_tblPr->m_oTblLook.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerProp_tblPrType::Look); m_oBcw.m_oStream.WriteLONG(p_tblPr->m_oTblLook->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } - //Layout if (p_tblPr->m_oTblLayout.IsInit() && p_tblPr->m_oTblLayout->m_oType.IsInit()) { nCurPos = m_oBcw.WriteItemStart(c_oSerProp_tblPrType::Layout); @@ -2212,7 +2216,12 @@ void Binary_tblPrWriter::WriteTblPr(OOX::Logic::CTableProperty* p_tblPr) m_oBcw.m_oStream.WriteBYTE((BYTE)p_tblPr->m_oTblOverlap->m_oVal->GetValue()); m_oBcw.WriteItemEnd(nCurPos); } -} + if (p_tblPr->m_oBidiVisual.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerProp_tblPrType::bidiVisual); + m_oBcw.m_oStream.WriteBOOL(p_tblPr->m_oBidiVisual->m_oVal.ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + }} void Binary_tblPrWriter::WriteTblMar(const OOX::Logic::CTblCellMar& cellMar) { int nCurPos = 0; @@ -5110,16 +5119,16 @@ void BinaryDocumentTableWriter::WriteMathRunContent(OOX::Logic::CMRun* pMRun) int nBreakType = -1; switch (pBr->m_oType.GetValue()) { - case SimpleTypes::brtypeColumn: nBreakType = c_oSerRunType::columnbreak; break; - case SimpleTypes::brtypePage: nBreakType = c_oSerRunType::pagebreak; break; + case SimpleTypes::brtypeColumn: nBreakType = c_oSer_OMathContentType::columnbreak; break; + case SimpleTypes::brtypePage: nBreakType = c_oSer_OMathContentType::pagebreak; break; case SimpleTypes::brtypeTextWrapping: { switch (pBr->m_oClear.GetValue()) { - case SimpleTypes::brclearAll: nBreakType = c_oSerRunType::linebreakClearAll; break; - case SimpleTypes::brclearLeft: nBreakType = c_oSerRunType::linebreakClearLeft; break; - case SimpleTypes::brclearRight: nBreakType = c_oSerRunType::linebreakClearRight; break; - default: nBreakType = c_oSerRunType::linebreak; break; + //case SimpleTypes::brclearAll: nBreakType = c_oSer_OMathContentType::linebreakClearAll; break; + //case SimpleTypes::brclearLeft: nBreakType = c_oSer_OMathContentType::linebreakClearLeft; break; + //case SimpleTypes::brclearRight: nBreakType = c_oSer_OMathContentType::linebreakClearRight; break; + default: nBreakType = c_oSer_OMathContentType::linebreak; break; } }break; @@ -9874,7 +9883,7 @@ void BinaryFileWriter::intoBindoc(const std::wstring& sSrcPath) { BinDocxRW::BinaryCommentsTableWriter oBinaryCommentsTableWriter(m_oParamsWriter); int nCurPos = this->WriteTableStart(BinDocxRW::c_oSerTableTypes::DocumentComments); - oBinaryCommentsTableWriter.Write(*pDocx->m_pDocumentComments, pDocx->m_pDocumentCommentsExt, pDocx->m_pDocumentCommentsExtensible, pDocx->m_pCommentsUserData, pDocx->m_pDocumentPeople, pDocx->m_pDocumentCommentsIds, m_oParamsWriter.m_mapIgnoreComments); + oBinaryCommentsTableWriter.Write(*pDocx->m_pDocumentComments, pDocx->m_pDocumentCommentsExt, pDocx->m_pDocumentCommentsExtensible, pDocx->m_pCommentsUserData, pDocx->m_pDocumentPeople, pDocx->m_pDocumentCommentsIds, m_oParamsWriter.m_mapIgnoreDocumentComments); this->WriteTableEnd(nCurPos); } { diff --git a/OOXML/Binary/Document/BinWriter/BinWriters.h b/OOXML/Binary/Document/BinWriter/BinaryWriterD.h similarity index 99% rename from OOXML/Binary/Document/BinWriter/BinWriters.h rename to OOXML/Binary/Document/BinWriter/BinaryWriterD.h index 4bc17e52f7..38d742f38f 100644 --- a/OOXML/Binary/Document/BinWriter/BinWriters.h +++ b/OOXML/Binary/Document/BinWriter/BinaryWriterD.h @@ -91,6 +91,7 @@ namespace BinDocxRW OOX::IFileContainer* m_pCurRels; std::map m_mapIgnoreComments; + std::map m_mapIgnoreDocumentComments; ParamsWriter(NSBinPptxRW::CBinaryFileWriter* pCBufferedStream, DocWrapper::FontProcessor* pFontProcessor, diff --git a/OOXML/Binary/Document/DocWrapper/DocxSerializer.cpp b/OOXML/Binary/Document/DocWrapper/DocxSerializer.cpp index 20b1760ee0..7f28384ea2 100644 --- a/OOXML/Binary/Document/DocWrapper/DocxSerializer.cpp +++ b/OOXML/Binary/Document/DocWrapper/DocxSerializer.cpp @@ -31,8 +31,8 @@ */ #include "DocxSerializer.h" -#include "../BinWriter/BinWriters.h" -#include "../BinReader/Readers.h" +#include "../BinWriter/BinaryWriterD.h" +#include "../BinReader/BinaryReaderD.h" #include "../../../PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.h" #include "../../Presentation/FontPicker.h" @@ -254,7 +254,6 @@ bool BinDocxRW::CDocxSerializer::saveToFile(const std::wstring& sDstFileName, co BYTE* pbBinBuffer = oBufferedStream.GetBuffer(); int nBinBufferLen = oBufferedStream.GetPosition(); - if (m_bIsNoBase64 || m_bIsNoBase64Save) { NSFile::CFileBinary oFile; diff --git a/OOXML/Binary/Document/DocWrapper/VsdxSerializer.cpp b/OOXML/Binary/Document/DocWrapper/VsdxSerializer.cpp new file mode 100644 index 0000000000..4bc68251a0 --- /dev/null +++ b/OOXML/Binary/Document/DocWrapper/VsdxSerializer.cpp @@ -0,0 +1,141 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "VsdxSerializer.h" + +#include "../../../../DesktopEditor/common/Directory.h" +#include "../../../../DesktopEditor/common/File.h" +#include "../../../../DesktopEditor/common/Path.h" + +#include "../../Draw/BinaryWriterV.h" +#include "../../Draw/BinaryReaderV.h" +#include "../../Presentation/FontPicker.h" + +#include "../../../../OfficeUtils/src/OfficeUtils.h" + +namespace BinVsdxRW +{ + int g_nCurFormatVersion = 0; + + CVsdxSerializer::CVsdxSerializer() : m_bIsMacro(false), m_bIsNoBase64(false) + { + m_pExternalDrawingConverter = NULL; + } + CVsdxSerializer::~CVsdxSerializer() + { + } + void CVsdxSerializer::CreateVsdxFolders(const std::wstring& sDstPath, std::wstring& sMediaPath, std::wstring& sEmbedPath) + { + OOX::CPath pathMediaDir = sDstPath + FILE_SEPARATOR_STR + _T("visio") + FILE_SEPARATOR_STR + _T("media"); + OOX::CPath pathEmbedDir = sDstPath + FILE_SEPARATOR_STR + _T("visio") + FILE_SEPARATOR_STR + _T("embeddings"); + + //создавать папку надо даже при сохранении в csv, потому что когда читаем из бинарника тему, она записывается в файл. + OOX::CPath pathVDir = sDstPath + FILE_SEPARATOR_STR + _T("visio"); + + OOX::CPath pathThemeDir = pathVDir + FILE_SEPARATOR_STR + OOX::FileTypes::Theme.DefaultDirectory().GetPath(); + + OOX::CPath pathThemeFile = pathThemeDir + FILE_SEPARATOR_STR + OOX::FileTypes::Theme.DefaultFileName().GetPath(); + + OOX::CPath pathThemeThemeRelsDir = pathThemeDir + FILE_SEPARATOR_STR + _T("_rels"); + + NSDirectory::CreateDirectory(pathVDir.GetPath()); + NSDirectory::CreateDirectory(pathThemeDir.GetPath()); + NSDirectory::CreateDirectory(pathThemeThemeRelsDir.GetPath()); + NSDirectory::CreateDirectory(pathMediaDir.GetPath()); + NSDirectory::CreateDirectory(pathEmbedDir.GetPath()); + + sMediaPath = pathMediaDir.GetPath(); + sEmbedPath = pathEmbedDir.GetPath(); + } + _UINT32 CVsdxSerializer::loadFromFile(const std::wstring& sSrcFileName, const std::wstring& sDstPath, const std::wstring& sMediaDir, const std::wstring& sEmbedDir) + { + std::wstring strFileInDir = NSSystemPath::GetDirectoryName(sSrcFileName); + + NSBinPptxRW::CDrawingConverter oDrawingConverter; + + oDrawingConverter.SetDstPath(sDstPath + FILE_SEPARATOR_STR + L"visio"); + oDrawingConverter.SetSrcPath(strFileInDir, XMLWRITER_DOC_TYPE_VSDX); + + oDrawingConverter.SetMediaDstPath(sMediaDir); + oDrawingConverter.SetEmbedDstPath(sEmbedDir); + oDrawingConverter.SetTempPath(m_sTempDir); + + BinVsdxRW::BinaryFileReader oBinaryFileReader; + return oBinaryFileReader.ReadFile(sSrcFileName, sDstPath, &oDrawingConverter, m_bIsMacro); + } + _UINT32 CVsdxSerializer::saveToFile(const std::wstring& sDstFileName, const std::wstring& sSrcPath) + { + COfficeFontPicker* pFontPicker = new COfficeFontPicker(); + pFontPicker->Init(m_sFontDir); + NSFonts::IFontManager* pFontManager = pFontPicker->get_FontManager(); + DocWrapper::FontProcessor fp; + fp.setFontManager(pFontManager); + + NSBinPptxRW::CDrawingConverter oOfficeDrawingConverter; + oOfficeDrawingConverter.SetFontManager(pFontManager); + oOfficeDrawingConverter.SetFontDir(m_sFontDir); + oOfficeDrawingConverter.SetFontPicker(pFontPicker); + + BinVsdxRW::BinaryFileWriter oBinaryFileWriter(fp); + _UINT32 result = oBinaryFileWriter.Open(sSrcPath, sDstFileName, &oOfficeDrawingConverter, m_bIsNoBase64); + + RELEASEOBJECT(pFontPicker); + return result; + } + void CVsdxSerializer::setTempDir(const std::wstring& sTempDir) + { + m_sTempDir = sTempDir; + } + void CVsdxSerializer::setFontDir(const std::wstring& sFontDir) + { + m_sFontDir = sFontDir; + } + void CVsdxSerializer::setEmbeddedFontsDir(const std::wstring& sEmbeddedFontsDir) + { + m_sEmbeddedFontsDir = sEmbeddedFontsDir; + } + void CVsdxSerializer::setDrawingConverter(NSBinPptxRW::CDrawingConverter* pDrawingConverter) + { + m_pExternalDrawingConverter = pDrawingConverter; + } + void CVsdxSerializer::setIsNoBase64(bool val) + { + m_bIsNoBase64 = val; + } + void CVsdxSerializer::setMacroEnabled(bool val) + { + m_bIsMacro = val; + } + bool CVsdxSerializer::getMacroEnabled() + { + return m_bIsMacro; + } +}; diff --git a/OOXML/Binary/Document/DocWrapper/VsdxSerializer.h b/OOXML/Binary/Document/DocWrapper/VsdxSerializer.h new file mode 100644 index 0000000000..c8e7c0ac2e --- /dev/null +++ b/OOXML/Binary/Document/DocWrapper/VsdxSerializer.h @@ -0,0 +1,78 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include +#include "../../../Base/Base.h" +#include "../../../Base/SmartPtr.h" + +namespace OOX +{ + class File; +} +namespace NSBinPptxRW{ + class CDrawingConverter; +} +namespace NSBinPptxRW{ + class CBinaryFileReader; + class CBinaryFileWriter; +} +namespace BinVsdxRW { + + class CVsdxSerializer + { + private: + std::wstring m_sTempDir; + std::wstring m_sFontDir; + std::wstring m_sEmbeddedFontsDir; + NSBinPptxRW::CDrawingConverter* m_pExternalDrawingConverter; + bool m_bIsNoBase64; + bool m_bIsMacro; + public: + CVsdxSerializer(); + ~CVsdxSerializer(); + + _UINT32 loadFromFile (const std::wstring& sSrcFileName, const std::wstring& sDstPath, const std::wstring& sMediaDir, const std::wstring& sEmbedPath); + _UINT32 saveToFile (const std::wstring& sDstPath, const std::wstring& sSrcFileName); +//------------------------------------------------ + static void CreateVsdxFolders (const std::wstring& sDstPath, std::wstring& sMediaPath, std::wstring& sEmbedPath); + + void setTempDir (const std::wstring& sTempDir); + void setFontDir (const std::wstring& sFontDir); + void setEmbeddedFontsDir(const std::wstring& sEmbeddedFontsDir); + void setDrawingConverter(NSBinPptxRW::CDrawingConverter* pDrawingConverter); + void setIsNoBase64 (bool val); + + void setMacroEnabled (bool val); + bool getMacroEnabled (); + }; +} diff --git a/OOXML/Binary/Document/DocWrapper/XlsxSerializer.cpp b/OOXML/Binary/Document/DocWrapper/XlsxSerializer.cpp index 8155853ffa..3ffd53923c 100644 --- a/OOXML/Binary/Document/DocWrapper/XlsxSerializer.cpp +++ b/OOXML/Binary/Document/DocWrapper/XlsxSerializer.cpp @@ -37,8 +37,8 @@ #include "../../../XlsxFormat/Chart/Chart.h" -#include "../../Sheets/Reader/BinaryWriter.h" -#include "../../Sheets/Writer/BinaryReader.h" +#include "../../Sheets/Reader/BinaryWriterS.h" +#include "../../Sheets/Writer/BinaryReaderS.h" #include "../../Presentation/FontPicker.h" #include "../../../../OfficeUtils/src/OfficeUtils.h" @@ -93,7 +93,7 @@ namespace BinXlsxRW{ NSBinPptxRW::CDrawingConverter oDrawingConverter; oDrawingConverter.SetDstPath(sDstPath + FILE_SEPARATOR_STR + L"xl"); - oDrawingConverter.SetSrcPath(strFileInDir, 2); + oDrawingConverter.SetSrcPath(strFileInDir, XMLWRITER_DOC_TYPE_XLSX); oDrawingConverter.SetMediaDstPath(sMediaDir); oDrawingConverter.SetEmbedDstPath(sEmbedDir); @@ -150,7 +150,7 @@ namespace BinXlsxRW{ NSBinPptxRW::CDrawingConverter oDrawingConverter; oDrawingConverter.SetDstPath(sDstPath + FILE_SEPARATOR_STR + L"xl"); - oDrawingConverter.SetSrcPath(strFileInDir, 2); + oDrawingConverter.SetSrcPath(strFileInDir, XMLWRITER_DOC_TYPE_XLSX); oDrawingConverter.SetFontDir(m_sFontDir); BinXlsxRW::BinaryFileReader oBinaryFileReader; @@ -324,11 +324,4 @@ namespace BinXlsxRW{ NSDirectory::DeleteDirectory(sTempDir); return res; } - bool CXlsxSerializer::hasPivot(const std::wstring& sSrcPath) - { - //todo CXlsx - std::wstring sData; - NSFile::CFileBinary::ReadAllTextUtf8(sSrcPath + FILE_SEPARATOR_STR + L"[Content_Types].xml", sData); - return std::wstring::npos != sData.find(OOX::Spreadsheet::FileTypes::PivotTable.OverrideType()); - } }; diff --git a/OOXML/Binary/Document/DocWrapper/XlsxSerializer.h b/OOXML/Binary/Document/DocWrapper/XlsxSerializer.h index e0d4fc0417..7d9d3bef7e 100644 --- a/OOXML/Binary/Document/DocWrapper/XlsxSerializer.h +++ b/OOXML/Binary/Document/DocWrapper/XlsxSerializer.h @@ -79,6 +79,5 @@ namespace BinXlsxRW { bool saveChart (NSBinPptxRW::CBinaryFileReader* pReader, long lLength, NSCommon::smart_ptr &file); bool writeChartXlsx (const std::wstring& sDstFile, NSCommon::smart_ptr &file); - bool hasPivot (const std::wstring& sSrcPath); }; } diff --git a/OOXML/Binary/Draw/BinReaderWriterDefines.h b/OOXML/Binary/Draw/BinReaderWriterDefines.h new file mode 100644 index 0000000000..eecb5ea2f1 --- /dev/null +++ b/OOXML/Binary/Draw/BinReaderWriterDefines.h @@ -0,0 +1,69 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +namespace BinVsdxRW +{ + const static wchar_t* g_sFormatSignature = L"VSDY"; + const int g_nFormatVersion = 1; + const int g_nFormatVersionNoBase64 = 1; + extern int g_nCurFormatVersion; + + namespace c_oSerConstants{enum c_oSerConstants + { + ErrorFormat = -2, + ErrorUnknown = -1, + ReadOk = 0, + ReadUnknown = 1, + ErrorStream = 0x55 + };} + namespace c_oSerPropLenType{enum c_oSerPropLenType + { + Null = 0, + Byte = 1, + Short = 2, + Three = 3, + Long = 4, + Double = 5, + Variable = 6, + Double64 = 7, + Long64 = 8 + };} + namespace c_oSerTableTypes{enum c_oSerTableTypes + { + Document = 1, + App = 2, + Core = 3, + CustomProperties = 4 + };} + +} diff --git a/OOXML/Binary/Draw/BinaryReaderV.cpp b/OOXML/Binary/Draw/BinaryReaderV.cpp new file mode 100644 index 0000000000..f38f6d0aa2 --- /dev/null +++ b/OOXML/Binary/Draw/BinaryReaderV.cpp @@ -0,0 +1,287 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "BinaryReaderV.h" + +#include "../../../Common/Base64.h" +#include "../../../Common/ATLDefine.h" +#include "../../../Common/OfficeFileErrorDescription.h" + +#include "../../../DesktopEditor/common/Path.h" +#include "../../../DesktopEditor/common/Directory.h" +#include "../../../DesktopEditor/raster/ImageFileFormatChecker.h" + +#include "../../PPTXFormat/Theme.h" +#include "../../PPTXFormat/Logic/HeadingVariant.h" +#include "../../PPTXFormat/Logic/Shape.h" + +#include "../../DocxFormat/Media/VbaProject.h" +#include "../../DocxFormat/Media/JsaProject.h" +#include "../../DocxFormat/App.h" +#include "../../DocxFormat/Core.h" +#include "../../DocxFormat/CustomXml.h" + +#include "../../VsdxFormat/Vsdx.h" +#include "../../VsdxFormat/VisioDocument.h" + +namespace BinVsdxRW +{ + SaveParams::SaveParams(bool bMacro) : bMacroEnabled(bMacro) + { + } + BinaryFileReader::BinaryFileReader() + { + } + int BinaryFileReader::ReadFile(const std::wstring& sSrcFileName, std::wstring sDstPath, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter, bool &bMacro) + { + bool bResultOk = false; + + NSFile::CFileBinary oFile; + + if (false == oFile.OpenFile(sSrcFileName)) return AVS_FILEUTILS_ERROR_CONVERT; + + NSBinPptxRW::CBinaryFileReader& oBufferedStream = *pOfficeDrawingConverter->m_pReader; + + DWORD nBase64DataSize = 0; + BYTE* pBase64Data = new BYTE[oFile.GetFileSize()]; + oFile.ReadFile(pBase64Data, oFile.GetFileSize(), nBase64DataSize); + oFile.CloseFile(); + + //проверяем формат + bool bValidFormat = false; + std::wstring sSignature(g_sFormatSignature); + size_t nSigLength = sSignature.length(); + if (nBase64DataSize > nSigLength) + { + std::string sCurSig((char*)pBase64Data, nSigLength); + std::wstring wsCurSig(sCurSig.begin(), sCurSig.end()); + + if (sSignature == wsCurSig) + { + bValidFormat = true; + } + } + if (bValidFormat) + { + //Читаем из файла версию и длину base64 + int nIndex = (int)nSigLength; + int nType = 0; + std::string version = ""; + std::string dst_len = ""; + + while (nIndex < nBase64DataSize) + { + nIndex++; + BYTE _c = pBase64Data[nIndex]; + if (_c == ';') + { + + if (0 == nType) + { + nType = 1; + continue; + } + else + { + nIndex++; + break; + } + } + if (0 == nType) + version += _c; + else + dst_len += _c; + } + int nVersion = g_nFormatVersion; + if (!version.empty()) + { + version = version.substr(1); + g_nCurFormatVersion = nVersion = std::stoi(version.c_str()); + } + bool bIsNoBase64 = nVersion == g_nFormatVersionNoBase64; + + int nDataSize = 0; + BYTE* pData = NULL; + if (!bIsNoBase64) + { + nDataSize = atoi(dst_len.c_str()); + pData = new BYTE[nDataSize]; + if (Base64::Base64Decode((const char*)(pBase64Data + nIndex), nBase64DataSize - nIndex, pData, &nDataSize)) + { + oBufferedStream.Init(pData, 0, nDataSize); + } + else + { + RELEASEARRAYOBJECTS(pData); + } + } + else + { + nDataSize = nBase64DataSize; + pData = pBase64Data; + oBufferedStream.Init(pData, 0, nDataSize); + oBufferedStream.Seek(nIndex); + } + + if (NULL != pData) + { + bResultOk = true; + + OOX::Draw::CVsdx oVsdx; + SaveParams oSaveParams(bMacro); + + try + { + ReadContent(oVsdx, oBufferedStream, OOX::CPath(sSrcFileName).GetDirectory(), sDstPath, oSaveParams); + } + catch (...) + { + bResultOk = false; + } + OOX::CContentTypes oContentTypes; + oVsdx.Write(sDstPath, oContentTypes); + + bMacro = oSaveParams.bMacroEnabled; + } + if (!bIsNoBase64) + { + RELEASEARRAYOBJECTS(pData); + } + } + RELEASEARRAYOBJECTS(pBase64Data); + + if (bResultOk) return 0; + else return AVS_FILEUTILS_ERROR_CONVERT; + } + int BinaryFileReader::ReadContent(OOX::Draw::CVsdx& oVsdx, NSBinPptxRW::CBinaryFileReader& oBufferedStream, const std::wstring& sFileInDir, const std::wstring& sOutDir, SaveParams& oSaveParams) + { + long res = oBufferedStream.Peek(1) == false ? c_oSerConstants::ErrorStream : c_oSerConstants::ReadOk; + + if (c_oSerConstants::ReadOk != res) + return res; + + OOX::CPath pathMedia = sOutDir + FILE_SEPARATOR_STR + L"visio" + FILE_SEPARATOR_STR + L"media"; + OOX::CPath pathEmbeddings = sOutDir + FILE_SEPARATOR_STR + L"visio" + FILE_SEPARATOR_STR + L"embeddings"; + + oBufferedStream.m_nDocumentType = XMLWRITER_DOC_TYPE_VSDX; + oBufferedStream.m_strFolder = sFileInDir; + oBufferedStream.m_pRels->m_pManager->m_nDocumentType = XMLWRITER_DOC_TYPE_VSDX; + oBufferedStream.m_pRels->m_pManager->SetDstMedia(pathMedia.GetPath()); + oBufferedStream.m_pRels->m_pManager->SetDstEmbed(pathEmbeddings.GetPath()); + + std::vector aTypes; + std::vector aOffBits; + + BYTE mtLen = oBufferedStream.GetUChar(); + + for (int i = 0; i < mtLen; ++i) + { + //mtItem + res = oBufferedStream.Peek(5) == false ? c_oSerConstants::ErrorStream : c_oSerConstants::ReadOk; + if (c_oSerConstants::ReadOk != res) + return res; + + BYTE mtiType = 0; + if (false == oBufferedStream.GetUCharWithResult(&mtiType)) + break; + + long mtiOffBits = oBufferedStream.GetLong(); + + aTypes.push_back(mtiType); + aOffBits.push_back(mtiOffBits); + } + //sOutDir + for (size_t i = 0, length = aTypes.size(); i < length; ++i) + { + BYTE mtiType = aTypes[i]; + long mtiOffBits = aOffBits[i]; + + oBufferedStream.Seek(mtiOffBits); + switch(mtiType) + { + case c_oSerTableTypes::App: + { + OOX::CApp* pApp = new OOX::CApp(NULL); + + smart_ptr oCurFile(pApp); + oVsdx.m_pApp = oCurFile.smart_dynamic_cast(); + + pApp->fromPPTY(&oBufferedStream); + pApp->SetRequiredDefaults(); + + oVsdx.Add(oCurFile); + + }break; + case c_oSerTableTypes::Core: + { + OOX::CCore* pCore = new OOX::CCore(NULL); + + smart_ptr oCurFile(pCore); + oVsdx.m_pCore = oCurFile.smart_dynamic_cast(); + + pCore->fromPPTY(&oBufferedStream); + pCore->SetRequiredDefaults(); + + oVsdx.Add(oCurFile); + }break; + case c_oSerTableTypes::CustomProperties: + { + PPTX::CustomProperties* oCustomProperties = new PPTX::CustomProperties(NULL); + oCustomProperties->fromPPTY(&oBufferedStream); + smart_ptr oCurFile(oCustomProperties); + oVsdx.Add(oCurFile); + }break; + case c_oSerTableTypes::Document: + { + OOX::Draw::CDocumentFile* pDocument = new OOX::Draw::CDocumentFile(&oVsdx); + pDocument->m_bMacroEnabled = oSaveParams.bMacroEnabled; + + smart_ptr oCurFile(pDocument); + oVsdx.m_pDocument = oCurFile.smart_dynamic_cast(); + + pDocument->fromPPTY(&oBufferedStream); + oVsdx.Add(oCurFile); + + oSaveParams.bMacroEnabled = pDocument->m_bMacroEnabled; + }break; + + } + if (c_oSerConstants::ReadOk != res) + return res; + } + + return res; + } + + +} + diff --git a/OOXML/Binary/Draw/BinaryReaderV.h b/OOXML/Binary/Draw/BinaryReaderV.h new file mode 100644 index 0000000000..21cb1c458f --- /dev/null +++ b/OOXML/Binary/Draw/BinaryReaderV.h @@ -0,0 +1,58 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once +#include + +#include "BinReaderWriterDefines.h" +#include "../Presentation/BinaryFileReaderWriter.h" +#include "../Presentation/BinReaderWriterDefines.h" + +#include "../../PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.h" +#include "../../VsdxFormat/Vsdx.h" + +namespace BinVsdxRW +{ + struct SaveParams + { + SaveParams(bool bMacro = false); + + bool bMacroEnabled = false; + }; + + class BinaryFileReader + { + public: + BinaryFileReader(); + int ReadFile(const std::wstring& sSrcFileName, std::wstring sDstPath, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter, bool &bMacro); + int ReadContent(OOX::Draw::CVsdx& oVsdx, NSBinPptxRW::CBinaryFileReader& oBufferedStream, const std::wstring& sFileInDir, const std::wstring& sOutDir, SaveParams& oSaveParams); + }; +} diff --git a/OOXML/Binary/Draw/BinaryWriterV.cpp b/OOXML/Binary/Draw/BinaryWriterV.cpp new file mode 100644 index 0000000000..d5aeea83ff --- /dev/null +++ b/OOXML/Binary/Draw/BinaryWriterV.cpp @@ -0,0 +1,265 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "BinaryWriterV.h" +#include "BinaryReaderV.h" + +#include "../../../Common/OfficeFileFormats.h" +#include "../../../Common/Base64.h" +#include "../../../Common/OfficeFileErrorDescription.h" + +#include "../Presentation/FontCutter.h" +#include "../../PPTXFormat/Logic/HeadingVariant.h" +#include "../../PPTXFormat/Logic/Shape.h" + +#include "../../VsdxFormat/Vsdx.h" +#include "../../VsdxFormat/VisioDocument.h" + +#include "../../SystemUtility/SystemUtility.h" +#include "../../DocxFormat/Media/OleObject.h" +#include "../../DocxFormat/Media/ActiveX.h" +#include "../../DocxFormat/Media/VbaProject.h" +#include "../../DocxFormat/App.h" +#include "../../DocxFormat/Core.h" +//#include "../../DocxFormat/CustomXml.h" + +#include "../../../DesktopEditor/common/Directory.h" +#include "../../../Common/OfficeFileFormatChecker.h" +#include "../../../OfficeUtils/src/OfficeUtils.h" + +namespace BinVsdxRW +{ + BinaryCommonWriter::BinaryCommonWriter(NSBinPptxRW::CBinaryFileWriter& oCBufferedStream) :m_oStream(oCBufferedStream) + { + } + int BinaryCommonWriter::WriteItemStart(BYTE type) + { + m_oStream.WriteBYTE(type); + return WriteItemWithLengthStart(); + } + void BinaryCommonWriter::WriteItemEnd(int nStart) + { + WriteItemWithLengthEnd(nStart); + } + int BinaryCommonWriter::WriteItemWithLengthStart() + { + int nStartPos = m_oStream.GetPosition(); + m_oStream.Skip(4); + return nStartPos; + } + void BinaryCommonWriter::WriteItemWithLengthEnd(int nStart) + { + int nEnd = m_oStream.GetPosition(); + m_oStream.SetPosition(nStart); + m_oStream.WriteLONG(nEnd - nStart - 4); + m_oStream.SetPosition(nEnd); + } + void BinaryCommonWriter::WriteBytesArray(BYTE* pData, long nDataSize) + { + int nCurPos = WriteItemWithLengthStart(); + m_oStream.WriteBYTEArray(pData, nDataSize); + WriteItemWithLengthEnd(nCurPos); + } +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +BinaryFileWriter::BinaryFileWriter(DocWrapper::FontProcessor& oFontProcessor) : m_oBcw(NULL), m_oFontProcessor(oFontProcessor) +{ + m_nRealTableCount = 0; +} +BinaryFileWriter::~BinaryFileWriter() +{ + RELEASEOBJECT(m_oBcw); +} +_UINT32 BinaryFileWriter::Open(const std::wstring& sInputDir, const std::wstring& sFileDst, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter, bool bIsNoBase64) +{ + _UINT32 result = 0; + + OOX::CPath pathDst(sFileDst); +//создаем папку для media + std::wstring mediaDir = pathDst.GetDirectory() + L"media"; + NSDirectory::CreateDirectory(mediaDir); + + pOfficeDrawingConverter->SetDstPath(pathDst.GetDirectory() + FILE_SEPARATOR_STR + L"visio"); + pOfficeDrawingConverter->SetMediaDstPath(mediaDir); + + NSBinPptxRW::CBinaryFileWriter& oBufferedStream = *pOfficeDrawingConverter->m_pBinaryWriter; + oBufferedStream.m_strMainFolder = pathDst.GetDirectory(); + + m_oBcw = new BinaryCommonWriter(oBufferedStream); + + OOX::Draw::CVsdx *pVsdx = new OOX::Draw::CVsdx(OOX::CPath(sInputDir)); + + if (0 != result) + { + RELEASEOBJECT(pVsdx); + return result; + } + + if (bIsNoBase64) + { + oBufferedStream.WriteStringUtf8(WriteFileHeader(0, g_nFormatVersionNoBase64)); + } + int nHeaderLen = oBufferedStream.GetPosition(); + + WriteMainTableStart(oBufferedStream); + WriteContent(pVsdx, pOfficeDrawingConverter); + WriteMainTableEnd(); + + BYTE* pbBinBuffer = oBufferedStream.GetBuffer(); + int nBinBufferLen = oBufferedStream.GetPosition(); + if (bIsNoBase64) + { + NSFile::CFileBinary oFile; + oFile.CreateFileW(sFileDst); + + //write header and main table + oFile.WriteFile(pbBinBuffer, nBinBufferLen); + oFile.CloseFile(); + } + else + { + int nBase64BufferLen = Base64::Base64EncodeGetRequiredLength(nBinBufferLen, Base64::B64_BASE64_FLAG_NOCRLF); + BYTE* pbBase64Buffer = new BYTE[nBase64BufferLen + 64]; + if (true == Base64_1::Base64Encode(pbBinBuffer, nBinBufferLen, pbBase64Buffer, &nBase64BufferLen)) + { + NSFile::CFileBinary oFile; + oFile.CreateFileW(sFileDst); + oFile.WriteStringUTF8(WriteFileHeader(nBinBufferLen, g_nFormatVersion)); + oFile.WriteFile(pbBase64Buffer, nBase64BufferLen); + oFile.CloseFile(); + } + else + { + result = AVS_FILEUTILS_ERROR_CONVERT; + } + RELEASEARRAYOBJECTS(pbBase64Buffer); + } + + + RELEASEOBJECT(pVsdx); + + return result; +} + +void BinaryFileWriter::WriteContent(OOX::Document *pDocument, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter) +{ + OOX::Draw::CVsdx *pVsdx = dynamic_cast(pDocument); + + if (!pVsdx) return; + + int nCurPos = 0; + + if (pVsdx->m_pApp.IsInit()) + { + nCurPos = WriteTableStart(c_oSerTableTypes::App); + pVsdx->m_pApp->toPPTY(&m_oBcw->m_oStream); + this->WriteTableEnd(nCurPos); + } + + if (pVsdx->m_pCore.IsInit()) + { + nCurPos = WriteTableStart(c_oSerTableTypes::Core); + pVsdx->m_pCore->toPPTY(&m_oBcw->m_oStream); + this->WriteTableEnd(nCurPos); + } + + smart_ptr pFile = pVsdx->Find(OOX::FileTypes::CustomProperties); + PPTX::CustomProperties *pCustomProperties = dynamic_cast(pFile.GetPointer()); + if (pCustomProperties) + { + nCurPos = WriteTableStart(c_oSerTableTypes::CustomProperties); + pCustomProperties->toPPTY(&m_oBcw->m_oStream); + this->WriteTableEnd(nCurPos); + } + + if (pVsdx->m_pDocument.IsInit()) + { + nCurPos = WriteTableStart(c_oSerTableTypes::Document); + pVsdx->m_pDocument->toPPTY(&m_oBcw->m_oStream); + WriteTableEnd(nCurPos); + } +} + +std::wstring BinaryFileWriter::WriteFileHeader(int nDataSize, int version) +{ + std::wstring sHeader = std::wstring(g_sFormatSignature) + L";v" + std::to_wstring(version)+ L";" + std::to_wstring(nDataSize) + L";"; + return sHeader; +} +void BinaryFileWriter::WriteMainTableStart(NSBinPptxRW::CBinaryFileWriter &oBufferedStream) +{ + if (!m_oBcw) + m_oBcw = new BinaryCommonWriter(oBufferedStream); + + m_nRealTableCount = 0; + m_nMainTableStart = m_oBcw->m_oStream.GetPosition(); + //вычисляем с какой позиции можно писать таблицы + m_nLastFilePos = m_nMainTableStart + GetMainTableSize(); + //Write mtLen + m_oBcw->m_oStream.WriteBYTE(0); +} +int BinaryFileWriter::GetMainTableSize() +{ + return 128 * 5;//128 items of 5 bytes +} +void BinaryFileWriter::WriteMainTableEnd() +{ + m_oBcw->m_oStream.SetPosition(m_nMainTableStart); + m_oBcw->m_oStream.WriteBYTE(m_nRealTableCount); + + m_oBcw->m_oStream.SetPosition(m_nLastFilePos); +} +int BinaryFileWriter::WriteTableStart(BYTE type, int nStartPos) +{ + if(-1 != nStartPos) + m_oBcw->m_oStream.SetPosition(nStartPos); + //Write mtItem + //Write mtiType + m_oBcw->m_oStream.WriteBYTE(type); + //Write mtiOffBits + m_oBcw->m_oStream.WriteLONG(m_nLastFilePos); + + //Write table + //Запоминаем позицию в MainTable + int nCurPos = m_oBcw->m_oStream.GetPosition(); + //Seek в свободную область + m_oBcw->m_oStream.SetPosition(m_nLastFilePos); + return nCurPos; +} +void BinaryFileWriter::WriteTableEnd(int nCurPos) +{ + //сдвигаем позицию куда можно следующую таблицу + m_nLastFilePos = m_oBcw->m_oStream.GetPosition(); + m_nRealTableCount++; + //Seek вобратно в MainTable + m_oBcw->m_oStream.SetPosition(nCurPos); +} + +} diff --git a/OOXML/Binary/Draw/BinaryWriterV.h b/OOXML/Binary/Draw/BinaryWriterV.h new file mode 100644 index 0000000000..072b4139c0 --- /dev/null +++ b/OOXML/Binary/Draw/BinaryWriterV.h @@ -0,0 +1,92 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "BinReaderWriterDefines.h" +#include "../Presentation/BinaryFileReaderWriter.h" +#include "../Presentation/BinReaderWriterDefines.h" +#include "../Document/DocWrapper/FontProcessor.h" + +#include "../../PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.h" +#include "../../VsdxFormat/Vsdx.h" + +#include "../../../DesktopEditor/common/Directory.h" + +namespace OOX +{ + namespace Visio + { + class CVsdx; + class CDocument; + } +} + +namespace BinVsdxRW +{ + class BinaryCommonWriter + { + public: + NSBinPptxRW::CBinaryFileWriter& m_oStream; + BinaryCommonWriter(NSBinPptxRW::CBinaryFileWriter& oCBufferedStream); + int WriteItemStart(BYTE type); + void WriteItemEnd(int nStart); + int WriteItemWithLengthStart(); + void WriteItemWithLengthEnd(int nStart); + void WriteBytesArray(BYTE* pData, long nDataSize); + }; + + class BinaryFileWriter + { + private: + BinaryCommonWriter* m_oBcw; + int m_nLastFilePos; + int m_nMainTableStart; + int m_nRealTableCount = 0; + DocWrapper::FontProcessor& m_oFontProcessor; + public: + BinaryFileWriter(DocWrapper::FontProcessor& oFontProcessor); + ~BinaryFileWriter(); + + _UINT32 Open(const std::wstring& sInputDir, const std::wstring& sFileDst, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter, bool bIsNoBase64); + + void WriteMainTableStart(NSBinPptxRW::CBinaryFileWriter &oBufferedStream); + void WriteContent(OOX::Document *pDocument, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter); + void WriteMainTableEnd(); + + std::wstring WriteFileHeader(int nDataSize, int version); + int GetMainTableSize(); + + private: + int WriteTableStart(BYTE type, int nStartPos = -1); + void WriteTableEnd(int nCurPos); + }; +} diff --git a/OOXML/Binary/Presentation/BinReaderWriterDefines.h b/OOXML/Binary/Presentation/BinReaderWriterDefines.h index 28af712555..9fa951a0ab 100644 --- a/OOXML/Binary/Presentation/BinReaderWriterDefines.h +++ b/OOXML/Binary/Presentation/BinReaderWriterDefines.h @@ -307,6 +307,7 @@ static std::wstring SchemeClr_GetStringCode(const BYTE& val) #define XMLWRITER_DOC_TYPE_DOCX_GLOSSARY 7 #define XMLWRITER_DOC_TYPE_DIAGRAM 8 #define XMLWRITER_DOC_TYPE_DSP_DRAWING 9 +#define XMLWRITER_DOC_TYPE_VSDX 10 #define XMLWRITER_RECORD_TYPE_SPPR 0 #define XMLWRITER_RECORD_TYPE_CLRMAPOVR 1 diff --git a/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp b/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp index f85aad8ae1..242e22a764 100644 --- a/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp +++ b/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp @@ -226,23 +226,16 @@ namespace NSBinPptxRW return oImageManagerInfo; } - _imageManager2Info CImageManager2::GenerateImage(const std::wstring& strInput, NSCommon::smart_ptr & additionalFile, const std::wstring& oleData, std::wstring strBase64Image) + _imageManager2Info CImageManager2::GenerateImage(const std::wstring& strInput, std::vector>& additionalFiles, const std::wstring& oleData, std::wstring strBase64Image) { if (IsNeedDownload(strInput)) return DownloadImage(strInput); - std::map::const_iterator pPair = m_mapImages.find ((strBase64Image.empty()) ? strInput + oleData : strBase64Image + oleData); - - if (pPair != m_mapImages.end()) - { - smart_ptr mediaFile = additionalFile.smart_dynamic_cast(); - if (mediaFile.IsInit()) - mediaFile->set_filename(pPair->second.sFilepathAdditional, false); - - return pPair->second; - } + std::map::const_iterator pPair = m_mapImages.find((strBase64Image.empty()) ? strInput + oleData : strBase64Image + oleData); std::wstring strExts = L".jpg"; + std::wstring strImage = strInput; + //use GetFileName to avoid defining '.' in the directory as extension std::wstring strFileName = NSFile::GetFileName(strInput); int sizeExt = (int)strFileName.rfind(wchar_t('.')); @@ -252,143 +245,162 @@ namespace NSBinPptxRW sizeExt = (int)strFileName.length() - sizeExt; } else sizeExt = 0; - - int typeAdditional = 0; - std::wstring strAdditional; - std::wstring strImage = strInput; - + int nDisplayType = IsDisplayedImage(strInput); size_t nFileNameLength = strFileName.length(); - - if (0 != nDisplayType && nFileNameLength > sizeExt) + + std::vector> addit; + for (auto additionalFile : additionalFiles) { - OOX::CPath oPath = strInput; - - std::wstring strFolder = oPath.GetDirectory(); - std::wstring strFileName = oPath.GetFilename(); - - strFileName.erase(strFileName.length() - sizeExt, sizeExt); - - if (0 != (nDisplayType & 1)) + if (pPair != m_mapImages.end()) { - std::wstring strVector = strFolder + strFileName + L".wmf"; - if (OOX::CSystemUtility::IsFileExist(strVector)) + for (auto sFilepathAdditional : pPair->second.sFilepathAdditionals) { - strImage = strVector; - strExts = L".wmf"; + smart_ptr mediaFile = additionalFile.smart_dynamic_cast(); + if (mediaFile.IsInit()) + mediaFile->set_filename(sFilepathAdditional, false); } + + return pPair->second; } - if (0 != (nDisplayType & 2)) + + int typeAdditional = 0; + std::wstring strAdditional; + + if (0 != nDisplayType && nFileNameLength > sizeExt) { - std::wstring strVector = strFolder + strFileName + L".emf"; - if (OOX::CSystemUtility::IsFileExist(strVector)) + OOX::CPath oPath = strInput; + + std::wstring strFolder = oPath.GetDirectory(); + std::wstring strFileName = oPath.GetFilename(); + + strFileName.erase(strFileName.length() - sizeExt, sizeExt); + + if (0 != (nDisplayType & 1)) { - m_pContentTypes->AddDefault(L"emf"); - strImage = strVector; - strExts = L".emf"; - } - } - if (0 != (nDisplayType & 4)) - { - smart_ptr oleFile = additionalFile.smart_dynamic_cast(); - if (oleFile.IsInit()) - { - if (OOX::CSystemUtility::IsFileExist(oleFile->filename()) == false) + std::wstring strVector = strFolder + strFileName + L".wmf"; + if (OOX::CSystemUtility::IsFileExist(strVector)) { - typeAdditional = 1; - - std::wstring strOle = strFolder + strFileName + oleFile->filename().GetExtention(); - if (OOX::CSystemUtility::IsFileExist(strOle)) - { - m_pContentTypes->AddDefault(oleFile->filename().GetExtention(false)); - strAdditional = strOle; - } - else - { - strOle = strFolder + strFileName + L".bin"; - if (OOX::CSystemUtility::IsFileExist(strOle)) - strAdditional = strOle; - } + strImage = strVector; + strExts = L".wmf"; } } - } - if (0 != (nDisplayType & 8)) - { - smart_ptr mediaFile = additionalFile.smart_dynamic_cast(); - if (mediaFile.IsInit()) + if (0 != (nDisplayType & 2)) { - if (OOX::CSystemUtility::IsFileExist(mediaFile->filename()) == false) + std::wstring strVector = strFolder + strFileName + L".emf"; + if (OOX::CSystemUtility::IsFileExist(strVector)) { - typeAdditional = 2; - - if (!mediaFile->IsExternal()) + m_pContentTypes->AddDefault(L"emf"); + strImage = strVector; + strExts = L".emf"; + } + } + if (0 != (nDisplayType & 4)) + { + smart_ptr oleFile = additionalFile.smart_dynamic_cast(); + if (oleFile.IsInit()) + { + if (OOX::CSystemUtility::IsFileExist(oleFile->filename()) == false) { - std::wstring strMedia = strFolder + strFileName + mediaFile->filename().GetExtention(); - if (OOX::CSystemUtility::IsFileExist(strMedia)) + typeAdditional = 1; + + std::wstring strOle = strFolder + strFileName + oleFile->filename().GetExtention(); + if (OOX::CSystemUtility::IsFileExist(strOle)) { - m_pContentTypes->AddDefault(mediaFile->filename().GetExtention(false)); - strAdditional = strMedia; + m_pContentTypes->AddDefault(oleFile->filename().GetExtention(false)); + strAdditional = strOle; } else { - strMedia = strFolder + strFileName; - - if (mediaFile.is()) strMedia += L".wav"; - if (mediaFile.is()) strMedia += L".avi"; - + strOle = strFolder + strFileName + L".bin"; + if (OOX::CSystemUtility::IsFileExist(strOle)) + strAdditional = strOle; + } + } + } + } + if (0 != (nDisplayType & 8)) + { + smart_ptr mediaFile = additionalFile.smart_dynamic_cast(); + if (mediaFile.IsInit()) + { + if (OOX::CSystemUtility::IsFileExist(mediaFile->filename()) == false) + { + typeAdditional = 2; + + if (!mediaFile->IsExternal()) + { + std::wstring strMedia = strFolder + strFileName + mediaFile->filename().GetExtention(); if (OOX::CSystemUtility::IsFileExist(strMedia)) + { + m_pContentTypes->AddDefault(mediaFile->filename().GetExtention(false)); strAdditional = strMedia; + } + else + { + strMedia = strFolder + strFileName; + + if (mediaFile.is()) strMedia += L".wav"; + if (mediaFile.is()) strMedia += L".avi"; + + if (OOX::CSystemUtility::IsFileExist(strMedia)) + strAdditional = strMedia; + } } } } } } - } - - if (strExts == L".svg") - { - additionalFile = new OOX::SvgBlip(NULL); - - smart_ptr mediaFile = additionalFile.smart_dynamic_cast(); - if (mediaFile.IsInit()) + if (oleData.empty() == false) { - mediaFile->set_filename(strImage, false); - typeAdditional = 3; - strAdditional = strImage; + //plugins data - generate ole + typeAdditional = 1; } + addit.push_back(std::make_pair(strAdditional, typeAdditional)); } - if (false == strExts.empty()) { m_pContentTypes->AddDefault(strExts.substr(1)); } - - if (oleData.empty() == false) + if (strExts == L".svg") { - //plugins data - generate ole - typeAdditional = 1; - } + additionalFiles.emplace_back(); + additionalFiles.back() = new OOX::SvgBlip(NULL); - _imageManager2Info oImageManagerInfo = GenerateImageExec(strImage, strExts, strAdditional, typeAdditional, oleData); - - if (!oImageManagerInfo.sFilepathAdditional.empty()) - { - smart_ptr mediaFile = additionalFile.smart_dynamic_cast(); - if (false == mediaFile.IsInit()) //??? - { - mediaFile = new OOX::Media(NULL); - additionalFile = mediaFile.smart_dynamic_cast(); - } + smart_ptr mediaFile = additionalFiles.back().smart_dynamic_cast(); if (mediaFile.IsInit()) { - mediaFile->set_filename(oImageManagerInfo.sFilepathAdditional, false); + mediaFile->set_filename(strImage, false); + + addit.push_back(std::make_pair(strImage, 3)); } } - + _imageManager2Info oImageManagerInfo = GenerateImageExec(strImage, strExts, addit, oleData); + + //oImageManagerInfo.sFilepathAdditionals <-> additionalFiles + + for (size_t i = 0; i < oImageManagerInfo.sFilepathAdditionals.size(); ++i) + { + if (!oImageManagerInfo.sFilepathAdditionals[i].empty()) + { + smart_ptr mediaFile = additionalFiles[i].smart_dynamic_cast(); + if (false == mediaFile.IsInit()) //??? + { + mediaFile = new OOX::Media(NULL); + additionalFiles[i] = mediaFile.smart_dynamic_cast(); + } + if (mediaFile.IsInit()) + { + mediaFile->set_filename(oImageManagerInfo.sFilepathAdditionals[i], false); + } + } + } + if (strBase64Image.empty()) m_mapImages[strInput + oleData] = oImageManagerInfo; else - m_mapImages [strBase64Image + oleData] = oImageManagerInfo; + m_mapImages[strBase64Image + oleData] = oImageManagerInfo; + return oImageManagerInfo; } bool CImageManager2::WriteOleData(const std::wstring& sFilePath, const std::wstring& sData) @@ -452,10 +464,10 @@ namespace NSBinPptxRW } return oImageManagerInfo; } - _imageManager2Info CImageManager2::GenerateImageExec(const std::wstring& strInput, const std::wstring& sExts, const std::wstring& strAdditionalImage, int &nAdditionalType, const std::wstring& oleData) + _imageManager2Info CImageManager2::GenerateImageExec(const std::wstring& strInput, const std::wstring& sExts, std::vector>& additional, const std::wstring& oleData) { - OOX::CPath oPathOutput; - _imageManager2Info oImageManagerInfo; + OOX::CPath oPathOutput; + _imageManager2Info oImageManagerInfo; std::wstring strExts = sExts; std::wstring strImage = L"image" + std::to_wstring(++m_lIndexNextImage); @@ -511,49 +523,56 @@ namespace NSBinPptxRW oImageManagerInfo.sFilepathImage = oPathOutput.GetPath(); }break; } - - if ((!strAdditionalImage.empty() || !oleData.empty() ) && (nAdditionalType == 1)) + for (auto add : additional) { - std::wstring strAdditionalExt = L".bin"; + std::wstring& strAdditionalImage = add.first; + int nAdditionalType = add.second; - size_t pos = strAdditionalImage.rfind(L"."); - if (pos != std::wstring::npos) strAdditionalExt = strAdditionalImage.substr(pos); - - std::wstring strImageAdditional = L"oleObject" + std::to_wstring(++m_lIndexCounter) + strAdditionalExt; - - OOX::CPath pathOutput = m_strDstEmbed + FILE_SEPARATOR_STR + strImageAdditional; - - std::wstring strAdditionalImageOut = pathOutput.GetPath(); - - if (!oleData.empty()) + if ((!strAdditionalImage.empty() || !oleData.empty()) && (nAdditionalType == 1)) { - WriteOleData(strAdditionalImageOut, oleData); - oImageManagerInfo.sFilepathAdditional = strAdditionalImageOut; + std::wstring strAdditionalExt = L".bin"; + + size_t pos = strAdditionalImage.rfind(L"."); + if (pos != std::wstring::npos) strAdditionalExt = strAdditionalImage.substr(pos); + + std::wstring strImageAdditional = L"oleObject" + std::to_wstring(++m_lIndexCounter) + strAdditionalExt; + + OOX::CPath pathOutput = m_strDstEmbed + FILE_SEPARATOR_STR + strImageAdditional; + + std::wstring strAdditionalImageOut = pathOutput.GetPath(); + + oImageManagerInfo.sFilepathAdditionals.emplace_back(); + if (!oleData.empty()) + { + WriteOleData(strAdditionalImageOut, oleData); + oImageManagerInfo.sFilepathAdditionals.back() = strAdditionalImageOut; + } + else if (NSFile::CFileBinary::Exists(strAdditionalImage)) + { + NSFile::CFileBinary::Copy(strAdditionalImage, strAdditionalImageOut); + oImageManagerInfo.sFilepathAdditionals.back() = strAdditionalImageOut; + } + } - else if (NSFile::CFileBinary::Exists(strAdditionalImage)) + else if (!strAdditionalImage.empty() && (nAdditionalType == 2 || nAdditionalType == 3)) //nAdditionalType -> enum { - NSFile::CFileBinary::Copy(strAdditionalImage, strAdditionalImageOut); - oImageManagerInfo.sFilepathAdditional = strAdditionalImageOut; - } + std::wstring strAdditionalExt; - } - else if (!strAdditionalImage.empty() && (nAdditionalType == 2 || nAdditionalType == 3)) //nAdditionalType -> enum - { - std::wstring strAdditionalExt; + size_t pos = (int)strAdditionalImage.rfind(L"."); + if (pos != std::wstring::npos) strAdditionalExt = strAdditionalImage.substr(pos); - size_t pos = (int)strAdditionalImage.rfind(L"."); - if (pos != std::wstring::npos) strAdditionalExt = strAdditionalImage.substr(pos); + std::wstring strImageAdditional = L"media" + std::to_wstring(++m_lIndexCounter) + strAdditionalExt; - std::wstring strImageAdditional = L"media" + std::to_wstring(++m_lIndexCounter) + strAdditionalExt; - - OOX::CPath pathOutput = m_strDstMedia + FILE_SEPARATOR_STR + strImageAdditional; - - std::wstring strAdditionalImageOut = pathOutput.GetPath(); + OOX::CPath pathOutput = m_strDstMedia + FILE_SEPARATOR_STR + strImageAdditional; - if (NSFile::CFileBinary::Exists(strAdditionalImage)) - { - NSFile::CFileBinary::Copy(strAdditionalImage, strAdditionalImageOut); - oImageManagerInfo.sFilepathAdditional = strAdditionalImageOut; + std::wstring strAdditionalImageOut = pathOutput.GetPath(); + + if (NSFile::CFileBinary::Exists(strAdditionalImage)) + { + NSFile::CFileBinary::Copy(strAdditionalImage, strAdditionalImageOut); + oImageManagerInfo.sFilepathAdditionals.emplace_back(); + oImageManagerInfo.sFilepathAdditionals.back() = strAdditionalImageOut; + } } } @@ -641,8 +660,8 @@ namespace NSBinPptxRW _imageManager2Info oImageManagerInfo; if (!strImage.empty()) { - int nAdditionalType = 0; - oImageManagerInfo = GenerateImageExec(strImage, strExts, L"", nAdditionalType, L""); + std::vector> additional; + oImageManagerInfo = GenerateImageExec(strImage, strExts, additional, L""); CDirectory::DeleteFile(strImage); } @@ -1058,7 +1077,6 @@ namespace NSBinPptxRW pData += 4; } } - void CBinaryFileWriter::WriteString1(int type, const std::wstring& val) { BYTE bType = (BYTE)type; @@ -1067,17 +1085,48 @@ namespace NSBinPptxRW std::wstring* s = const_cast(&val); _WriteStringWithLength(s->c_str(), (_UINT32)s->length(), false); } + void CBinaryFileWriter::WriteString1(int type, const std::string& val) + { + BYTE bType = (BYTE)type; + WriteBYTE(bType); + + std::string* s = const_cast(&val); + _WriteStringWithLength(s->c_str(), (_UINT32)s->length()); + } void CBinaryFileWriter::WriteString2(int type, const NSCommon::nullable_string& val) { if (val.is_init()) WriteString1(type, *val); } - void CBinaryFileWriter::WriteString(const std::wstring& val) + void CBinaryFileWriter::WriteStringUtf8(int type, const NSCommon::nullable_string& val) + { + if (val.is_init()) + { + BYTE bType = (BYTE)type; + WriteBYTE(bType); + + _WriteStringUtf8WithLength(val->c_str(), (_UINT32)val->length()); + } + } + void CBinaryFileWriter::WriteStringUtf8(int type, const NSCommon::nullable_astring& val) + { + if (val.is_init()) + { + BYTE bType = (BYTE)type; + WriteBYTE(bType); + + _WriteStringWithLength(val->c_str(), (_UINT32)val->length()); + } + } void CBinaryFileWriter::WriteString(const std::wstring& val) { std::wstring* s = const_cast(&val); _WriteStringWithLength(s->c_str(), (_UINT32)s->length(), false); } - + void CBinaryFileWriter::WriteString2(int type, const NSCommon::nullable_astring& val) + { + if (val.is_init()) + WriteString1(type, *val); + } void CBinaryFileWriter::WriteStringData(const WCHAR* pData, _UINT32 len) { _WriteStringWithLength(pData, len, false); @@ -1264,6 +1313,8 @@ namespace NSBinPptxRW } _INT32 CBinaryFileWriter::_WriteString(const WCHAR* sBuffer, _UINT32 lCount) { + if (lCount < 1) return 0; + _INT32 lSizeMem = 0; if (sizeof(wchar_t) == 4) { @@ -1281,6 +1332,35 @@ namespace NSBinPptxRW m_pStreamCur += lSizeMem; return lSizeMem; } + _INT32 CBinaryFileWriter::_WriteString(const char* sBuffer, _UINT32 lCount) + { + if (lCount < 1) return 0; + + _UINT32 lSizeMem = lCount * sizeof(char); + + CheckBufferSize(UINT32_SIZEOF + lSizeMem); + + memcpy(m_pStreamCur, sBuffer, lSizeMem); + + m_lPosition += lSizeMem; + m_pStreamCur += lSizeMem; + return lSizeMem; + } + _INT32 CBinaryFileWriter::_WriteStringUtf8(const WCHAR* sBuffer, _UINT32 lCount) + { + if (lCount < 1) return 0; + + LONG lSizeMem = 0; + + _INT32 lSizeMemMax = 4 * lCount + 2;//2 - for null terminator + CheckBufferSize(lSizeMemMax); + + NSFile::CUtf8Converter::GetUtf8StringFromUnicode(sBuffer, lCount, m_pStreamCur, lSizeMem, false); + + m_lPosition += lSizeMem; + m_pStreamCur += lSizeMem; + return lSizeMem; + } void CBinaryFileWriter::_WriteStringWithLength(const WCHAR* sBuffer, _UINT32 lCount, bool bByte) { if (sizeof(wchar_t) == 4) @@ -1318,6 +1398,59 @@ namespace NSBinPptxRW m_lPosition += lSizeMem; m_pStreamCur += lSizeMem; } + void CBinaryFileWriter::_WriteStringWithLength(const char* sBuffer, _UINT32 lCount) + { + CheckBufferSize(UINT32_SIZEOF + lCount); + + //skip size + m_lPosition += UINT32_SIZEOF; + m_pStreamCur += UINT32_SIZEOF; + //write string + _INT32 lSizeMem = _WriteString(sBuffer, lCount); + + //back to size + m_lPosition -= lSizeMem; + m_pStreamCur -= lSizeMem; + m_lPosition -= UINT32_SIZEOF; + m_pStreamCur -= UINT32_SIZEOF; + + //write size + WriteLONG(lSizeMem); + + //skip string + m_lPosition += lSizeMem; + m_pStreamCur += lSizeMem; + } + void CBinaryFileWriter::_WriteStringUtf8WithLength(const WCHAR* sBuffer, _UINT32 lCount) + { + if (sizeof(wchar_t) == 4) + { + _INT32 lSizeMemMax = 4 * lCount + 2;//2 - for null terminator + CheckBufferSize(UINT32_SIZEOF + lSizeMemMax); + } + else + { + _INT32 lSizeMem = 2 * lCount; + CheckBufferSize(UINT32_SIZEOF + lSizeMem); + } + //skip size + m_lPosition += UINT32_SIZEOF; + m_pStreamCur += UINT32_SIZEOF; + //write string + _INT32 lSizeMem = lCount > 0 ? _WriteStringUtf8(sBuffer, lCount) : 0; + //back to size + m_lPosition -= lSizeMem; + m_pStreamCur -= lSizeMem; + m_lPosition -= UINT32_SIZEOF; + m_pStreamCur -= UINT32_SIZEOF; + + //write size + WriteLONG(lSizeMem); + + //skip string + m_lPosition += lSizeMem; + m_pStreamCur += lSizeMem; + } CStreamBinaryWriter::CStreamBinaryWriter(size_t bufferSize) { @@ -1657,9 +1790,9 @@ namespace NSBinPptxRW return oRelsGeneratorInfo; } - _relsGeneratorInfo CRelsGenerator::WriteImage(const std::wstring& strImage, smart_ptr & additionalFile, const std::wstring& oleData, std::wstring strBase64Image = L"") + _relsGeneratorInfo CRelsGenerator::WriteImage(const std::wstring& strImage, std::vector>& additionalFiles, const std::wstring& oleData, std::wstring strBase64Image = L"") { - _imageManager2Info oImageManagerInfo = m_pManager->GenerateImage(strImage, additionalFile, oleData, strBase64Image); + _imageManager2Info oImageManagerInfo = m_pManager->GenerateImage(strImage, additionalFiles, oleData, strBase64Image); std::wstring strImageRelsPath; @@ -1688,73 +1821,77 @@ namespace NSBinPptxRW L"\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"" + strImageRelsPath + L"\"/>"); } - if (additionalFile.is()) + for (auto additionalFile : additionalFiles) { - smart_ptr oleFile = additionalFile.smart_dynamic_cast(); - - std::wstring strOleRelsPath; - - oRelsGeneratorInfo.nOleRId = m_lNextRelsID++; - oRelsGeneratorInfo.sFilepathOle = oleFile->filename().GetPath(); - - if (m_pManager->m_nDocumentType != XMLWRITER_DOC_TYPE_XLSX) + if (additionalFile.is()) { - std::wstring strRid = L"rId" + std::to_wstring(oRelsGeneratorInfo.nOleRId); + smart_ptr oleFile = additionalFile.smart_dynamic_cast(); - if (m_pManager->m_nDocumentType == XMLWRITER_DOC_TYPE_DOCX) strOleRelsPath = L"embeddings/"; - else strOleRelsPath = L"../embeddings/"; - - strOleRelsPath += oleFile->filename().GetFilename(); + std::wstring strOleRelsPath; - if (oleFile->isMsPackage()) + oRelsGeneratorInfo.nOleRId = m_lNextRelsID++; + oRelsGeneratorInfo.sFilepathOle = oleFile->filename().GetPath(); + + if (m_pManager->m_nDocumentType != XMLWRITER_DOC_TYPE_XLSX) { - m_pWriter->WriteString( L""); - }else{ - m_pWriter->WriteString( L""); + std::wstring strRid = L"rId" + std::to_wstring(oRelsGeneratorInfo.nOleRId); + + if (m_pManager->m_nDocumentType == XMLWRITER_DOC_TYPE_DOCX) strOleRelsPath = L"embeddings/"; + else strOleRelsPath = L"../embeddings/"; + + strOleRelsPath += oleFile->filename().GetFilename(); + + if (oleFile->isMsPackage()) + { + m_pWriter->WriteString(L""); + } + else { + m_pWriter->WriteString(L""); + } } } - } - else if (additionalFile.is()) - { - smart_ptr mediaFile = additionalFile.smart_dynamic_cast(); - - std::wstring strMediaRelsPath; - - oRelsGeneratorInfo.nMediaRId = m_lNextRelsID++; - oRelsGeneratorInfo.sFilepathMedia = mediaFile->filename().GetPath(); - - if (m_pManager->m_nDocumentType != XMLWRITER_DOC_TYPE_XLSX || additionalFile.is()) + else if (additionalFile.is()) { - std::wstring strRid = L"rId" + std::to_wstring(oRelsGeneratorInfo.nMediaRId); + smart_ptr mediaFile = additionalFile.smart_dynamic_cast(); - if (mediaFile->IsExternal()) - { - strMediaRelsPath = mediaFile->filename().GetFilename(); - } - else - { - if (m_pManager->m_nDocumentType == XMLWRITER_DOC_TYPE_DOCX) strMediaRelsPath = L"media/"; - else strMediaRelsPath = L"../media/"; - - const std::wstring filename = mediaFile->filename().GetFilename(); + std::wstring strMediaRelsPath; - if (!filename.empty()) + oRelsGeneratorInfo.nMediaRId = m_lNextRelsID++; + oRelsGeneratorInfo.sFilepathMedia = mediaFile->filename().GetPath(); + + if (m_pManager->m_nDocumentType != XMLWRITER_DOC_TYPE_XLSX || additionalFile.is()) + { + std::wstring strRid = L"rId" + std::to_wstring(oRelsGeneratorInfo.nMediaRId); + + if (mediaFile->IsExternal()) { - strMediaRelsPath += filename; + strMediaRelsPath = mediaFile->filename().GetFilename(); + } + else + { + if (m_pManager->m_nDocumentType == XMLWRITER_DOC_TYPE_DOCX) strMediaRelsPath = L"media/"; + else strMediaRelsPath = L"../media/"; - if (additionalFile.is() || additionalFile.is()) + const std::wstring filename = mediaFile->filename().GetFilename(); + + if (!filename.empty()) { - m_pWriter->WriteString(L"IsExternal() ? L" TargetMode=\"External\"" : L"") + L"/>"); - } - else - { - m_pWriter->WriteString(L"type().RelationType() + L"\" Target=\"" + - strMediaRelsPath + L"\"" + (mediaFile->IsExternal() ? L" TargetMode=\"External\"" : L"") + L"/>"); + strMediaRelsPath += filename; + + if (additionalFile.is() || additionalFile.is()) + { + m_pWriter->WriteString(L"IsExternal() ? L" TargetMode=\"External\"" : L"") + L"/>"); + } + else + { + m_pWriter->WriteString(L"type().RelationType() + L"\" Target=\"" + + strMediaRelsPath + L"\"" + (mediaFile->IsExternal() ? L" TargetMode=\"External\"" : L"") + L"/>"); + } } } } @@ -1821,10 +1958,12 @@ namespace NSBinPptxRW m_pRels = new CRelsGenerator(); m_nCurrentRelsStack = -1; + m_pCurrentContainer = new NSCommon::smart_ptr(); } CBinaryFileReader::~CBinaryFileReader() { RELEASEOBJECT(m_pRels); + RELEASEOBJECT(m_pCurrentContainer); size_t nCountStackRels = m_stackRels.size(); for (size_t i = 0; i < nCountStackRels; ++i) @@ -1834,7 +1973,19 @@ namespace NSBinPptxRW } m_stackRels.clear(); } - + void CBinaryFileReader::SetRels(NSCommon::smart_ptr container) + { + *m_pCurrentContainer = container; + } + void CBinaryFileReader::SetRels(OOX::IFileContainer* container) + { + *m_pCurrentContainer = NSCommon::smart_ptr(container); + m_pCurrentContainer->AddRef(); + } + NSCommon::smart_ptr CBinaryFileReader::GetRels() + { + return *m_pCurrentContainer; + } void CBinaryFileReader::SetMainDocument(BinDocxRW::CDocxSerializer* pMainDoc) { m_pMainDocument = pMainDoc; @@ -2068,7 +2219,24 @@ namespace NSBinPptxRW _INT32 len = GetLong(); return GetString(len, bDeleteZero); } - std::wstring CBinaryFileReader::GetString3(_INT32 len, bool bDeleteZero)//len in byte for utf16 + std::wstring CBinaryFileReader::GetStringUtf8(_INT32 len)//len in byte for utf8 + { + if (len < 1) + return L""; + + if (m_lPos + len > m_lSize) + { + throw; + } + + std::wstring res = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(m_pDataCur, len); + + m_lPos += len; + m_pDataCur += len; + + return res; + } + std::wstring CBinaryFileReader::GetString3(_INT32 len, bool bDeleteZero)//len in byte for utf16 { if (len < 1 ) return L""; @@ -2164,7 +2332,11 @@ namespace NSBinPptxRW return pArray; } */ - + std::wstring CBinaryFileReader::GetStringUtf8() + { + _INT32 len = GetULong(); + return GetStringUtf8(len); + } std::string CBinaryFileReader::GetString2A() { _INT32 len = GetULong(); diff --git a/OOXML/Binary/Presentation/BinaryFileReaderWriter.h b/OOXML/Binary/Presentation/BinaryFileReaderWriter.h index 5a14f63d26..17d99beb4c 100644 --- a/OOXML/Binary/Presentation/BinaryFileReaderWriter.h +++ b/OOXML/Binary/Presentation/BinaryFileReaderWriter.h @@ -63,6 +63,7 @@ namespace NSCommon class nullable_uint; class nullable_double; class nullable_sizet; + class nullable_astring; } namespace NSStringUtils { @@ -100,7 +101,7 @@ namespace NSBinPptxRW struct _imageManager2Info { - std::wstring sFilepathAdditional; + std::vector sFilepathAdditionals; std::wstring sFilepathImage; }; @@ -219,10 +220,10 @@ namespace NSBinPptxRW int IsDisplayedImage(const std::wstring& strInput); _imageManager2Info GenerateMedia(const std::wstring& strInput); - _imageManager2Info GenerateImage(const std::wstring& strInput, NSCommon::smart_ptr & additionalFile, const std::wstring& oleData, std::wstring strBase64Image); + _imageManager2Info GenerateImage(const std::wstring& strInput, std::vector>& additionalFiles, const std::wstring& oleData, std::wstring strBase64Image); _imageManager2Info GenerateMediaExec(const std::wstring& strInput); - _imageManager2Info GenerateImageExec(const std::wstring& strInput, const std::wstring& strExts, const std::wstring& strAdditionalImage, int & nAdditionalType, const std::wstring& oleData); + _imageManager2Info GenerateImageExec(const std::wstring& strInput, const std::wstring& strExts, std::vector> & additional, const std::wstring& oleData); bool SaveImageAsPng(const std::wstring& strFileSrc, const std::wstring& strFileDst); bool SaveImageAsJPG(const std::wstring& strFileSrc, const std::wstring& strFileDst); @@ -315,7 +316,6 @@ namespace NSBinPptxRW void WriteDoubleReal(const double& dValue); void WriteBYTEArray (const BYTE* pBuffer, size_t len); - void WriteStringA (std::string& sBuffer); void WriteStringW (const std::wstring& sBuffer); void WriteStringW2 (const std::wstring& sBuffer); @@ -343,6 +343,13 @@ namespace NSBinPptxRW void WriteString (const std::wstring& val); void WriteStringData(const WCHAR* pData, _UINT32 len); + void WriteString1 (int type, const std::string& val); + void WriteString2 (int type, const NSCommon::nullable_astring& val); + void WriteStringA (std::string& val); + + void WriteStringUtf8(int type, const NSCommon::nullable_string& val); + void WriteStringUtf8(int type, const NSCommon::nullable_astring& val); + void WriteString1Data(int type, const WCHAR* pData, _UINT32 len); void WriteBool1(int type, const bool& val); @@ -439,7 +446,11 @@ namespace NSBinPptxRW bool GetSafearray(BYTE **ppArray, size_t& szCount); private: _INT32 _WriteString(const WCHAR* sBuffer, _UINT32 lCount); + _INT32 _WriteString(const char* sBuffer, _UINT32 lCount); + _INT32 _WriteStringUtf8(const WCHAR* sBuffer, _UINT32 lCount); void _WriteStringWithLength(const WCHAR* sBuffer, _UINT32 lCount, bool bByte); + void _WriteStringWithLength(const char* sBuffer, _UINT32 lCount); + void _WriteStringUtf8WithLength(const WCHAR* sBuffer, _UINT32 lCount); }; class CStreamBinaryWriter : public NSFile::CFileBinary, public CBinaryFileWriter @@ -508,24 +519,30 @@ namespace NSBinPptxRW void AddRels (const std::wstring& strRels); void SaveRels (const std::wstring& strFile); - _relsGeneratorInfo WriteImage (const std::wstring& strImage, NSCommon::smart_ptr& additionalFile, const std::wstring& oleData, std::wstring strBase64Image); + _relsGeneratorInfo WriteImage (const std::wstring& strImage, std::vector>& additionalFiles, const std::wstring& oleData, std::wstring strBase64Image); _relsGeneratorInfo WriteMedia (const std::wstring& strMedia, int type = 0); }; class CBinaryFileReader { protected: - BYTE* m_pData; + + BYTE* m_pData = NULL; LONG m_lSize; LONG m_lPos; - BYTE* m_pDataCur; + BYTE* m_pDataCur = NULL; _INT32 m_lNextId; - std::vector m_stackRels; - int m_nCurrentRelsStack; + std::vector m_stackRels; + int m_nCurrentRelsStack; + NSCommon::smart_ptr* m_pCurrentContainer = NULL; public: - CRelsGenerator* m_pRels; + void SetRels(NSCommon::smart_ptr container); + void SetRels(OOX::IFileContainer* container); + NSCommon::smart_ptr GetRels(); + + CRelsGenerator* m_pRels = NULL; std::wstring m_strFolder; std::wstring m_strFolderThemes; @@ -537,7 +554,7 @@ namespace NSBinPptxRW _INT32 m_nCountActiveX = 1; _INT32 m_nThemeOverrideCount = 1; - BinDocxRW::CDocxSerializer* m_pMainDocument; + BinDocxRW::CDocxSerializer* m_pMainDocument = NULL; int m_nDocumentType; CBinaryFileReader(); @@ -579,9 +596,11 @@ namespace NSBinPptxRW std::wstring GetString2(bool bDeleteZero = false); std::wstring GetString3(_INT32 len, bool bDeleteZero = false); std::wstring GetString4(_INT32 len); + std::wstring GetStringUtf8(_INT32 len); bool GetArray(BYTE *pBuffer, _INT32 len); + std::wstring GetStringUtf8(); std::string GetString2A(); void SkipRecord(); diff --git a/OOXML/Binary/Presentation/XmlWriter.cpp b/OOXML/Binary/Presentation/XmlWriter.cpp index 33c616155b..d398abe007 100644 --- a/OOXML/Binary/Presentation/XmlWriter.cpp +++ b/OOXML/Binary/Presentation/XmlWriter.cpp @@ -199,6 +199,24 @@ void CXmlWriter::WriteAttribute2(const std::wstring& strAttributeName, const std m_oWriter.WriteEncodeXmlString(val); m_oWriter.WriteString(g_bstr_node_quote); } +void CXmlWriter::WriteAttribute2(const std::wstring& strAttributeName, const std::string& val) +{ + m_oWriter.WriteString(g_bstr_node_space); + m_oWriter.WriteString(strAttributeName); + m_oWriter.WriteString(g_bstr_node_equal); + m_oWriter.WriteString(g_bstr_node_quote); + m_oWriter.WriteEncodeXmlString(val); + m_oWriter.WriteString(g_bstr_node_quote); +} +void CXmlWriter::WriteAttributeUtf8(const std::wstring& strAttributeName, const std::string& val) +{ + m_oWriter.WriteString(g_bstr_node_space); + m_oWriter.WriteString(strAttributeName); + m_oWriter.WriteString(g_bstr_node_equal); + m_oWriter.WriteString(g_bstr_node_quote); + m_oWriter.WriteUtf8EncodeXmlString(val); + m_oWriter.WriteString(g_bstr_node_quote); +} void CXmlWriter::WriteAttribute(const std::wstring& strAttributeName, const double& val) { m_oWriter.WriteString(g_bstr_node_space); @@ -428,6 +446,16 @@ void CXmlWriter::WriteAttribute2(const std::wstring& strName, const nullable_str if (value.IsInit()) WriteAttribute2(strName, *value); } +void CXmlWriter::WriteAttribute2(const std::wstring& strName, const nullable_astring& value) +{ + if (value.IsInit()) + WriteAttribute2(strName, *value); +} +void CXmlWriter::WriteAttributeUtf8(const std::wstring& strName, const nullable_astring& value) +{ + if (value.IsInit()) + WriteAttributeUtf8(strName, *value); +} void CXmlWriter::WriteAttribute(const std::wstring& strName, const nullable_bool& value) { if (value.IsInit()) diff --git a/OOXML/Binary/Presentation/XmlWriter.h b/OOXML/Binary/Presentation/XmlWriter.h index 0430af28ad..e6480d6022 100644 --- a/OOXML/Binary/Presentation/XmlWriter.h +++ b/OOXML/Binary/Presentation/XmlWriter.h @@ -124,7 +124,9 @@ namespace NSBinPptxRW // void WriteAttribute(const std::wstring& strAttributeName, const std::wstring& val); void WriteAttribute(const std::wstring& strAttributeName, const wchar_t* val); - void WriteAttribute2(const std::wstring& strAttributeName, const std::wstring& val); + void WriteAttribute2(const std::wstring& strAttributeName, const std::wstring& val); // xml + void WriteAttribute2(const std::wstring& strAttributeName, const std::string& val); + void WriteAttributeUtf8(const std::wstring& strAttributeName, const std::string& val); void WriteAttribute(const std::wstring& strAttributeName, const double& val); void WriteAttribute(const std::wstring& strAttributeName, const int& val); void WriteAttribute(const std::wstring& strAttributeName, const bool& val); @@ -160,8 +162,10 @@ namespace NSBinPptxRW void WriteAttribute(const std::wstring& strName, const nullable_sizet& value); void WriteAttribute(const std::wstring& strName, const nullable_double& value); void WriteAttribute(const std::wstring& strName, const nullable_string& value); - void WriteAttribute2(const std::wstring& strName, const nullable_string& value); + void WriteAttribute2(const std::wstring& strName, const nullable_string& value); // xml void WriteAttribute(const std::wstring& strName, const nullable_bool& value); + void WriteAttribute2(const std::wstring& strName, const nullable_astring& value); + void WriteAttributeUtf8(const std::wstring& strName, const nullable_astring& value); template void WriteAttribute(const std::wstring& strName, const nullable_limit& value) diff --git a/OOXML/Binary/Presentation/imagemanager.cpp b/OOXML/Binary/Presentation/imagemanager.cpp index d501362214..31d38e7989 100644 --- a/OOXML/Binary/Presentation/imagemanager.cpp +++ b/OOXML/Binary/Presentation/imagemanager.cpp @@ -529,9 +529,6 @@ namespace NSShapeImageGen if (!sInternalSvg.empty()) { - // тут размер не проверяем. сохраняем как есть - oInfo.m_eType = itSVG; - NSFile::CFileBinary::SaveToFile(strSaveItemWE + L".svg", sInternalSvg); m_mapMediaFiles.insert(std::make_pair(sMapKey, oInfo)); diff --git a/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h b/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h index 1b01b39012..20ec0466f5 100644 --- a/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h +++ b/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h @@ -238,7 +238,8 @@ namespace BinXlsxRW ExternalLinksAutoRefresh = 26, TimelineCaches = 27, TimelineCache = 28, - Metadata = 29 + Metadata = 29, + XmlMap = 30 };} namespace c_oSerWorkbookProtection {enum c_oSerWorkbookProtection{ AlgorithmName = 0, @@ -456,7 +457,7 @@ namespace BinXlsxRW TimelinesList = 48, Timelines = 49, Timeline = 50, - + TableSingleCells = 51 };} namespace c_oSerWorksheetProtection {enum c_oSerWorksheetPropTypes { @@ -1113,7 +1114,12 @@ namespace BinXlsxRW QueryTableFieldId = 11, TotalsRowCellStyle = 12, TotalsRowDxfId = 13, - UniqueName = 14 + UniqueName = 14, + XmlColumnPr = 15, + MapId = 16, + Xpath = 17, + Denormalized = 18, + XmlDataType = 19 };} namespace c_oSer_SortState{enum c_oSer_SortState { diff --git a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp index 6b6534fb16..0d759d47db 100644 --- a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp +++ b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp @@ -71,6 +71,8 @@ #include "../../../XlsxFormat/Styles/TableStyles.h" #include "../../../XlsxFormat/Timelines/Timeline.h" #include "../../../XlsxFormat/Workbook/Metadata.h" +#include "../../../XlsxFormat/Table/Table.h" +#include "../../../XlsxFormat/Workbook/CustomsXml.h" #include "../../../../DesktopEditor/common/Directory.h" #include "../../../../Common/OfficeFileFormatChecker.h" @@ -990,6 +992,12 @@ void BinaryTableWriter::WriteTableColumn(const OOX::Spreadsheet::CTableColumn& o m_oBcw.m_oStream.WriteBYTE(c_oSer_TableColumns::UniqueName); m_oBcw.m_oStream.WriteStringW(*oTableColumn.m_oUniqueName); } + if (oTableColumn.m_oXmlColumnPr.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TableColumns::XmlColumnPr); + WriteTableXmlColumnPr(oTableColumn.m_oXmlColumnPr.get()); + m_oBcw.WriteItemEnd(nCurPos); + } } void BinaryTableWriter::WriteTableColumns(const OOX::Spreadsheet::CTableColumns& oTableColumns) { @@ -1001,15 +1009,43 @@ void BinaryTableWriter::WriteTableColumns(const OOX::Spreadsheet::CTableColumns& m_oBcw.WriteItemEnd(nCurPos); } } +void BinaryTableWriter::WriteTableXmlColumnPr(const OOX::Spreadsheet::CXmlColumnPr & oXmlColumnPr) +{ + if (oXmlColumnPr.mapId.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TableColumns::MapId); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(*oXmlColumnPr.mapId); + } + if (oXmlColumnPr.xpath.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TableColumns::Xpath); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*oXmlColumnPr.xpath); + } + if (oXmlColumnPr.denormalized.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TableColumns::Denormalized); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(*oXmlColumnPr.denormalized); + } + if (oXmlColumnPr.xmlDataType.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TableColumns::XmlDataType); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(oXmlColumnPr.xmlDataType->GetValue()); + } +} + void BinaryTableWriter::WriteTableStyleInfo(const OOX::Spreadsheet::CTableStyleInfo& oTableStyleInfo) { - if(oTableStyleInfo.m_oName.IsInit()) + if (oTableStyleInfo.m_oName.IsInit()) { m_oBcw.m_oStream.WriteBYTE(c_oSer_TableStyleInfo::Name); m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); m_oBcw.m_oStream.WriteStringW(oTableStyleInfo.m_oName.get2()); } - if(oTableStyleInfo.m_oShowColumnStripes.IsInit()) + if (oTableStyleInfo.m_oShowColumnStripes.IsInit()) { m_oBcw.m_oStream.WriteBYTE(c_oSer_TableStyleInfo::ShowColumnStripes); m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); @@ -2152,7 +2188,7 @@ void BinaryWorkbookTableWriter::WriteWorkbook(OOX::Spreadsheet::CWorkbook& workb } if (workbook.m_oPivotCaches.IsInit()) { - nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::PivotCaches); + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::PivotCachesTmp); WritePivotCaches(workbook, workbook.m_oPivotCaches.get()); if (workbook.m_oExtLst.IsInit()) { @@ -2290,6 +2326,16 @@ void BinaryWorkbookTableWriter::WriteWorkbook(OOX::Spreadsheet::CWorkbook& workb WriteMetadata(pMetadataFile->m_oMetadata.GetPointer()); m_oBcw.WriteItemWithLengthEnd(nCurPos); } + pFile = workbook.Find(OOX::Spreadsheet::FileTypes::XmlMaps); + OOX::Spreadsheet::CXmlMapsFile* pXmlMapFile = dynamic_cast(pFile.GetPointer()); + if (pXmlMapFile) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::XmlMap); + m_oBcw.m_oStream.StartRecord(0); + pXmlMapFile->toPPTY(&m_oBcw.m_oStream); + m_oBcw.m_oStream.EndRecord(); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } } void BinaryWorkbookTableWriter::WriteFileSharing(const OOX::Spreadsheet::CFileSharing& fileSharing) { @@ -4772,7 +4818,7 @@ void BinaryWorksheetTableWriter::WriteWorksheet(OOX::Spreadsheet::CSheet* pSheet if ((pPivotTableFile) && (pPivotTableFile->m_oPivotTableDefinition.IsInit())) { BinaryTableWriter oBinaryTableWriter(m_oBcw.m_oStream); - nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::PivotTable); + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::PivotTableTmp); if(pPivotTableFile->m_oPivotTableDefinition->m_oCacheId.IsInit()) { auto cachePos = m_oBcw.WriteItemStart(c_oSer_PivotTypes::cacheId); @@ -4787,6 +4833,16 @@ void BinaryWorksheetTableWriter::WriteWorksheet(OOX::Spreadsheet::CSheet* pSheet m_oBcw.WriteItemWithLengthEnd(tablePos); m_oBcw.WriteItemWithLengthEnd(nCurPos); } + pFile = oWorksheet.Find(OOX::Spreadsheet::FileTypes::TableSingleCells); + OOX::Spreadsheet::CTableSingleCellsFile* pTableSingleCells = dynamic_cast(pFile.GetPointer()); + if (pTableSingleCells) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::TableSingleCells); + m_oBcw.m_oStream.StartRecord(0); + pTableSingleCells->toPPTY(&m_oBcw.m_oStream); + m_oBcw.m_oStream.EndRecord(); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } } void BinaryWorksheetTableWriter::WriteWorksheetProp(OOX::Spreadsheet::CSheet& oSheet) { @@ -5662,6 +5718,21 @@ void BinaryWorksheetTableWriter::WriteSheetData(const OOX::Spreadsheet::CSheetDa nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Row); WriteRow(*pRow); m_oBcw.WriteItemEnd(nCurPos); + if(pRow->m_oRepeated.IsInit()) + { + _INT32 rowTimes = pRow->m_oRepeated.get() - 1; + while(rowTimes > 0) + { + if(pRow->m_oR.IsInit()) + pRow->m_oR = pRow->m_oR->GetValue() + 1; + if(!pRow->m_arrItems.empty() && pRow->m_arrItems.at(0)->m_oRow.IsInit()) + pRow->m_arrItems.at(0)->m_oRow = pRow->m_oR->GetValue(); + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Row); + WriteRow(*pRow); + m_oBcw.WriteItemEnd(nCurPos); + rowTimes--; + } + } } } } @@ -5723,6 +5794,13 @@ void BinaryWorksheetTableWriter::WriteRow(const OOX::Spreadsheet::CRow& oRows) WriteCells(oRows); m_oBcw.WriteItemWithLengthEnd(nCurPos); } + else + { + m_oBcw.m_oStream.WriteBYTE(c_oSerRowTypes::Cells); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + nCurPos = m_oBcw.WriteItemWithLengthStart(); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } } void BinaryWorksheetTableWriter::WriteCells(const OOX::Spreadsheet::CRow& oRows) { @@ -5733,6 +5811,25 @@ void BinaryWorksheetTableWriter::WriteCells(const OOX::Spreadsheet::CRow& oRows) nCurPos = m_oBcw.WriteItemStart(c_oSerRowTypes::Cell); WriteCell(*oCell); m_oBcw.WriteItemWithLengthEnd(nCurPos); + if(oCell->m_oRepeated.IsInit()) + { + _INT32 cellTimes = oCell->m_oRepeated.get() - 1; + _INT32 originalCol = 0; + if(oCell->m_oCol.IsInit()) + originalCol = oCell->m_oCol.get(); + while(cellTimes > 0) + { + if(oCell->m_oCol.IsInit()) + oCell->m_oCol = oCell->m_oCol.get() + 1; + nCurPos = m_oBcw.WriteItemStart(c_oSerRowTypes::Cell); + WriteCell(*oCell); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + cellTimes--; + } + if(oCell->m_oCol.IsInit()) + oCell->m_oCol = originalCol; + + } } } void BinaryWorksheetTableWriter::WriteCell(const OOX::Spreadsheet::CCell& oCell) @@ -8787,7 +8884,7 @@ _UINT32 BinaryFileWriter::Open(const std::wstring& sInputDir, const std::wstring if (fileType == 1) { - pXlsx->m_pXlsbWriter = &oXlsbWriter; // todooo xlsb -> xlst without xlsx write folder + //pXlsx->m_pXlsbWriter = &oXlsbWriter; // todooo xlsb -> xlst without xlsx write folder } //parse pXlsx->Read(OOX::CPath(sInputDir)); diff --git a/OOXML/Binary/Sheets/Reader/BinaryWriterS.cpp b/OOXML/Binary/Sheets/Reader/BinaryWriterS.cpp new file mode 100644 index 0000000000..17f5582d3c --- /dev/null +++ b/OOXML/Binary/Sheets/Reader/BinaryWriterS.cpp @@ -0,0 +1,9112 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "BinaryWriterS.h" +#include "../Writer/BinaryReaderS.h" + +#include "../../../../Common/OfficeFileFormats.h" +#include "../../../../Common/Base64.h" +#include "../../../../Common/OfficeFileErrorDescription.h" + +#include "../../Presentation/FontCutter.h" +#include "../../../PPTXFormat/Logic/HeadingVariant.h" +#include "../../../PPTXFormat/Logic/Shape.h" + +#include "../../../XlsxFormat/Xlsx.h" +#include "../../../XlsxFormat/XlsxFlat.h" + +#include "../../../SystemUtility/SystemUtility.h" +#include "../../../DocxFormat/Media/OleObject.h" +#include "../../../DocxFormat/Media/ActiveX.h" +#include "../../../DocxFormat/Media/VbaProject.h" +#include "../../../DocxFormat/App.h" +#include "../../../DocxFormat/Core.h" +#include "../../../DocxFormat/CustomXml.h" +#include "../../../DocxFormat/Drawing/DrawingExt.h" +#include "../../../XlsxFormat/SharedStrings/SharedStrings.h" +#include "../../../XlsxFormat/ExternalLinks/ExternalLinkPath.h" +#include "../../../XlsxFormat/Comments/ThreadedComments.h" +#include "../../../XlsxFormat/Slicer/SlicerCache.h" +#include "../../../XlsxFormat/Slicer/SlicerCacheExt.h" +#include "../../../XlsxFormat/Slicer/Slicer.h" +#include "../../../XlsxFormat/NamedSheetViews/NamedSheetViews.h" +#include "../../../XlsxFormat/Drawing/Pos.h" +#include "../../../XlsxFormat/Styles/Borders.h" +#include "../../../XlsxFormat/Styles/Xfs.h" +#include "../../../XlsxFormat/Styles/Colors.h" +#include "../../../XlsxFormat/Styles/Fills.h" +#include "../../../XlsxFormat/Styles/Fonts.h" +#include "../../../XlsxFormat/Styles/NumFmts.h" +#include "../../../XlsxFormat/Styles/CellStyles.h" +#include "../../../XlsxFormat/Styles/dxf.h" +#include "../../../XlsxFormat/Styles/TableStyles.h" +#include "../../../XlsxFormat/Timelines/Timeline.h" +#include "../../../XlsxFormat/Workbook/Metadata.h" + +#include "../../../../DesktopEditor/common/Directory.h" +#include "../../../../Common/OfficeFileFormatChecker.h" +#include "../../../../OfficeUtils/src/OfficeUtils.h" + +namespace BinXlsxRW +{ + +BinaryTableWriter::BinaryTableWriter(NSBinPptxRW::CBinaryFileWriter &oCBufferedStream):m_oBcw(oCBufferedStream) +{ +} +void BinaryTableWriter::Write(const OOX::Spreadsheet::CWorksheet& oWorksheet, const OOX::Spreadsheet::CTableParts& oTableParts) +{ + int nCurPos = 0; + for(size_t i = 0, length = oTableParts.m_arrItems.size(); i < length; ++i) + WriteTablePart(oWorksheet, *oTableParts.m_arrItems[i]); +} +void BinaryTableWriter::WriteTablePart(const OOX::Spreadsheet::CWorksheet& oWorksheet, const OOX::Spreadsheet::CTablePart& oTablePart) +{ + int nCurPos = 0; + if(oTablePart.m_oRId.IsInit()) + { + smart_ptr pFile = oWorksheet.Find(OOX::RId(oTablePart.m_oRId->GetValue())); + if (pFile.IsInit() && OOX::Spreadsheet::FileTypes::Table == pFile->type()) + { + OOX::Spreadsheet::CTableFile* pTableFile = static_cast(pFile.GetPointer()); + if(pTableFile->m_oTable.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TablePart::Table); + WriteTable(pTableFile); + m_oBcw.WriteItemEnd(nCurPos); + } + } + } +} +void BinaryTableWriter::WriteTable(OOX::Spreadsheet::CTableFile* pTableFile) +{ + if (!pTableFile) return; + + OOX::Spreadsheet::CTable* pTable = pTableFile->m_oTable.GetPointer(); + if (!pTable) return; + + int nCurPos = 0; + if(pTable->m_oRef.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TablePart::Ref); + m_oBcw.m_oStream.WriteStringW(pTable->m_oRef->ToString()); + } + if(pTable->m_oHeaderRowCount.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TablePart::HeaderRowCount); + m_oBcw.m_oStream.WriteLONG(pTable->m_oHeaderRowCount->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(pTable->m_oTotalsRowCount.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TablePart::TotalsRowCount); + m_oBcw.m_oStream.WriteLONG(pTable->m_oTotalsRowCount->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(pTable->m_oDisplayName.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TablePart::DisplayName); + m_oBcw.m_oStream.WriteStringW(*pTable->m_oDisplayName); + } + if(pTable->m_oName.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TablePart::Name); + m_oBcw.m_oStream.WriteStringW(*pTable->m_oName); + } + if(pTable->m_oComment.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TablePart::Comment); + m_oBcw.m_oStream.WriteStringW(*pTable->m_oComment); + } + if(pTable->m_oConnectionId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TablePart::ConnectionId); + m_oBcw.m_oStream.WriteLONG(pTable->m_oConnectionId->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(pTable->m_oTableType.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TablePart::TableType); + m_oBcw.m_oStream.WriteLONG(pTable->m_oTableType->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(pTable->m_oDataCellStyle.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TablePart::DataCellStyle); + m_oBcw.m_oStream.WriteStringW(*pTable->m_oDataCellStyle); + } + if(pTable->m_oDataDxfId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TablePart::DataDxfId); + m_oBcw.m_oStream.WriteLONG(pTable->m_oDataDxfId->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(pTable->m_oHeaderRowCellStyle.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TablePart::HeaderRowCellStyle); + m_oBcw.m_oStream.WriteStringW(*pTable->m_oHeaderRowCellStyle); + } + if(pTable->m_oHeaderRowDxfId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TablePart::HeaderRowDxfId); + m_oBcw.m_oStream.WriteLONG(pTable->m_oHeaderRowDxfId->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(pTable->m_oHeaderRowBorderDxfId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TablePart::HeaderRowBorderDxfId); + m_oBcw.m_oStream.WriteLONG(pTable->m_oHeaderRowBorderDxfId->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(pTable->m_oId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TablePart::Id); + m_oBcw.m_oStream.WriteLONG(pTable->m_oId->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(pTable->m_oInsertRow.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TablePart::InsertRow); + m_oBcw.m_oStream.WriteBYTE(*pTable->m_oInsertRow ? 1 : 0); + m_oBcw.WriteItemEnd(nCurPos); + } + if(pTable->m_oInsertRowShift.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TablePart::InsertRowShift); + m_oBcw.m_oStream.WriteBYTE(*pTable->m_oInsertRowShift ? 1 : 0); + m_oBcw.WriteItemEnd(nCurPos); + } + if(pTable->m_oPublished.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TablePart::Published); + m_oBcw.m_oStream.WriteBYTE(*pTable->m_oPublished ? 1 : 0); + m_oBcw.WriteItemEnd(nCurPos); + } + if(pTable->m_oTableBorderDxfId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TablePart::TableBorderDxfId); + m_oBcw.m_oStream.WriteLONG(pTable->m_oTableBorderDxfId->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(pTable->m_oTotalsRowBorderDxfId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TablePart::TotalsRowBorderDxfId); + m_oBcw.m_oStream.WriteLONG(pTable->m_oTotalsRowBorderDxfId->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(pTable->m_oTotalsRowCellStyle.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TablePart::TotalsRowCellStyle); + m_oBcw.m_oStream.WriteStringW(*pTable->m_oTotalsRowCellStyle); + } + if(pTable->m_oTotalsRowDxfId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TablePart::TotalsRowDxfId); + m_oBcw.m_oStream.WriteLONG(pTable->m_oTotalsRowDxfId->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(pTable->m_oTotalsRowShown.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TablePart::TotalsRowShown); + m_oBcw.m_oStream.WriteBYTE(*pTable->m_oTotalsRowShown ? 1 : 0); + m_oBcw.WriteItemEnd(nCurPos); + } + if(pTable->m_oAutoFilter.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TablePart::AutoFilter); + WriteAutoFilter(pTable->m_oAutoFilter.get()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(pTable->m_oSortState.IsInit()) + { + OOX::Spreadsheet::CSortState* pSortState = NULL; + if(pTable->m_oSortState.IsInit()) + pSortState = pTable->m_oSortState.GetPointer(); + else + pSortState = pTable->m_oAutoFilter->m_oSortState.GetPointer(); + + nCurPos = m_oBcw.WriteItemStart(c_oSer_TablePart::SortState); + WriteSortState(*pSortState); + m_oBcw.WriteItemEnd(nCurPos); + } + if(pTable->m_oTableColumns.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TablePart::TableColumns); + WriteTableColumns(pTable->m_oTableColumns.get()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(pTable->m_oTableStyleInfo.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TablePart::TableStyleInfo); + WriteTableStyleInfo(pTable->m_oTableStyleInfo.get()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(pTable->m_oExtLst.IsInit()) + { + for(size_t i = 0; i < pTable->m_oExtLst->m_arrExt.size(); ++i) + { + OOX::Drawing::COfficeArtExtension* pExt = pTable->m_oExtLst->m_arrExt[i]; + if(pExt->m_oAltTextTable.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TablePart::AltTextTable); + WriteAltTextTable(pExt->m_oAltTextTable.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + } + } + smart_ptr pFile = pTableFile->Find(OOX::Spreadsheet::FileTypes::QueryTable); + OOX::Spreadsheet::CQueryTableFile *pQueryTableFile = dynamic_cast(pFile.GetPointer()); + if ((pQueryTableFile) && (pQueryTableFile->m_oQueryTable.IsInit())) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TablePart::QueryTable); + WriteQueryTable(pQueryTableFile->m_oQueryTable.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryTableWriter::WriteQueryTable(const OOX::Spreadsheet::CQueryTable& oQueryTable) +{ + int nCurPos = 0; + if(oQueryTable.m_oName.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_QueryTable::Name); + m_oBcw.m_oStream.WriteStringW(oQueryTable.m_oName.get()); + } + if(oQueryTable.m_oConnectionId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTable::ConnectionId); + m_oBcw.m_oStream.WriteLONG(oQueryTable.m_oConnectionId->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTable.m_oAutoFormatId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTable::AutoFormatId); + m_oBcw.m_oStream.WriteLONG(oQueryTable.m_oAutoFormatId->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTable.m_oGrowShrinkType.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_QueryTable::GrowShrinkType); + m_oBcw.m_oStream.WriteStringW(oQueryTable.m_oGrowShrinkType.get()); + } + if(oQueryTable.m_oAdjustColumnWidth.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTable::AdjustColumnWidth); + m_oBcw.m_oStream.WriteBYTE(*oQueryTable.m_oAdjustColumnWidth ? 1 : 0); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTable.m_oApplyAlignmentFormats.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTable::ApplyAlignmentFormats); + m_oBcw.m_oStream.WriteBYTE(*oQueryTable.m_oApplyAlignmentFormats ? 1 : 0); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTable.m_oApplyBorderFormats.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTable::ApplyBorderFormats); + m_oBcw.m_oStream.WriteBYTE(*oQueryTable.m_oApplyBorderFormats ? 1 : 0); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTable.m_oApplyFontFormats.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTable::ApplyFontFormats); + m_oBcw.m_oStream.WriteBYTE(*oQueryTable.m_oApplyFontFormats ? 1 : 0); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTable.m_oApplyNumberFormats.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTable::ApplyNumberFormats); + m_oBcw.m_oStream.WriteBYTE(*oQueryTable.m_oApplyNumberFormats ? 1 : 0); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTable.m_oApplyPatternFormats.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTable::ApplyPatternFormats); + m_oBcw.m_oStream.WriteBYTE(*oQueryTable.m_oApplyPatternFormats ? 1 : 0); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTable.m_oApplyWidthHeightFormats.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTable::ApplyWidthHeightFormats); + m_oBcw.m_oStream.WriteBYTE(*oQueryTable.m_oApplyWidthHeightFormats ? 1 : 0); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTable.m_oBackgroundRefresh.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTable::BackgroundRefresh); + m_oBcw.m_oStream.WriteBYTE(*oQueryTable.m_oBackgroundRefresh ? 1 : 0); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTable.m_oDisableEdit.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTable::DisableEdit); + m_oBcw.m_oStream.WriteBYTE(*oQueryTable.m_oDisableEdit ? 1 : 0); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTable.m_oDisableRefresh.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTable::DisableRefresh); + m_oBcw.m_oStream.WriteBYTE(*oQueryTable.m_oDisableRefresh ? 1 : 0); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTable.m_oFillFormulas.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTable::FillFormulas); + m_oBcw.m_oStream.WriteBYTE(*oQueryTable.m_oFillFormulas ? 1 : 0); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTable.m_oFirstBackgroundRefresh.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTable::FirstBackgroundRefresh); + m_oBcw.m_oStream.WriteBYTE(*oQueryTable.m_oFirstBackgroundRefresh ? 1 : 0); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTable.m_oHeaders.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTable::Headers); + m_oBcw.m_oStream.WriteBYTE(*oQueryTable.m_oHeaders ? 1 : 0); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTable.m_oIntermediate.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTable::Intermediate); + m_oBcw.m_oStream.WriteBYTE(*oQueryTable.m_oIntermediate ? 1 : 0); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTable.m_oPreserveFormatting.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTable::PreserveFormatting); + m_oBcw.m_oStream.WriteBYTE(*oQueryTable.m_oPreserveFormatting ? 1 : 0); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTable.m_oRefreshOnLoad.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTable::RefreshOnLoad); + m_oBcw.m_oStream.WriteBYTE(*oQueryTable.m_oRefreshOnLoad ? 1 : 0); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTable.m_oQueryTableRefresh.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTable::QueryTableRefresh); + WriteQueryTableRefresh(oQueryTable.m_oQueryTableRefresh.get()); + m_oBcw.WriteItemEnd(nCurPos); + } + //m_oExtLst; +} +void BinaryTableWriter::WriteQueryTableRefresh(const OOX::Spreadsheet::CQueryTableRefresh& oQueryTableRefresh) +{ + int nCurPos = 0; + if(oQueryTableRefresh.m_oNextId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTableRefresh::NextId); + m_oBcw.m_oStream.WriteLONG(oQueryTableRefresh.m_oNextId->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTableRefresh.m_FieldIdWrapped.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTableRefresh::FieldIdWrapped); + m_oBcw.m_oStream.WriteBYTE(*oQueryTableRefresh.m_FieldIdWrapped ? 1 : 0); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTableRefresh.m_HeadersInLastRefresh.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTableRefresh::HeadersInLastRefresh); + m_oBcw.m_oStream.WriteBYTE(*oQueryTableRefresh.m_HeadersInLastRefresh ? 1 : 0); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTableRefresh.m_HeadersInLastRefresh.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTableRefresh::HeadersInLastRefresh); + m_oBcw.m_oStream.WriteBYTE(*oQueryTableRefresh.m_HeadersInLastRefresh ? 1 : 0); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTableRefresh.m_UnboundColumnsLeft.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTableRefresh::UnboundColumnsLeft); + m_oBcw.m_oStream.WriteLONG(oQueryTableRefresh.m_UnboundColumnsLeft->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTableRefresh.m_UnboundColumnsLeft.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTableRefresh::UnboundColumnsLeft); + m_oBcw.m_oStream.WriteLONG(oQueryTableRefresh.m_UnboundColumnsLeft->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTableRefresh.m_UnboundColumnsRight.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTableRefresh::UnboundColumnsRight); + m_oBcw.m_oStream.WriteLONG(oQueryTableRefresh.m_UnboundColumnsRight->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTableRefresh.m_oSortState.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTableRefresh::SortState); + WriteSortState(oQueryTableRefresh.m_oSortState.get()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTableRefresh.m_oQueryTableFields.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTableRefresh::QueryTableFields); + WriteQueryTableFields(oQueryTableRefresh.m_oQueryTableFields.get()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTableRefresh.m_oQueryTableDeletedFields.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTableRefresh::QueryTableDeletedFields); + WriteQueryTableDeletedFields(oQueryTableRefresh.m_oQueryTableDeletedFields.get()); + m_oBcw.WriteItemEnd(nCurPos); + } + + //m_oExt +} +void BinaryTableWriter::WriteQueryTableFields(const OOX::Spreadsheet::CQueryTableFields& oQueryTableFields) +{ + for (size_t i = 0; i < oQueryTableFields.m_arrItems.size(); ++i) + { + if(oQueryTableFields.m_arrItems[i]) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTableField::QueryTableField); + WriteQueryTableField(*oQueryTableFields.m_arrItems[i]); + m_oBcw.WriteItemEnd(nCurPos); + } + } +} +void BinaryTableWriter::WriteQueryTableDeletedFields(const OOX::Spreadsheet::CQueryTableDeletedFields& oQueryTableDeletedFields) +{ + for (size_t i = 0; i < oQueryTableDeletedFields.m_arrItems.size(); ++i) + { + if(oQueryTableDeletedFields.m_arrItems[i]) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTableDeletedField::QueryTableDeletedField); + WriteQueryTableDeletedField(*oQueryTableDeletedFields.m_arrItems[i]); + m_oBcw.WriteItemEnd(nCurPos); + } + } +} +void BinaryTableWriter::WriteQueryTableDeletedField(const OOX::Spreadsheet::CQueryTableDeletedField& oQueryTableDeletedField) +{ + if(oQueryTableDeletedField.m_oName.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_QueryTableDeletedField::Name); + m_oBcw.m_oStream.WriteStringW(oQueryTableDeletedField.m_oName.get()); + } +} +void BinaryTableWriter::WriteQueryTableField(const OOX::Spreadsheet::CQueryTableField& oQueryTableField) +{ + int nCurPos = 0; + if(oQueryTableField.m_oName.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_QueryTableField::Name); + m_oBcw.m_oStream.WriteStringW(oQueryTableField.m_oName.get()); + } + if(oQueryTableField.m_oId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTableField::Id); + m_oBcw.m_oStream.WriteLONG(oQueryTableField.m_oId->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTableField.m_oTableColumnId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTableField::TableColumnId); + m_oBcw.m_oStream.WriteLONG(oQueryTableField.m_oTableColumnId->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTableField.m_oRowNumbers.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTableField::RowNumbers); + m_oBcw.m_oStream.WriteBYTE(*oQueryTableField.m_oRowNumbers ? 1 : 0); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTableField.m_oFillFormulas.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTableField::FillFormulas); + m_oBcw.m_oStream.WriteBYTE(*oQueryTableField.m_oFillFormulas ? 1 : 0); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTableField.m_oDataBound.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTableField::DataBound); + m_oBcw.m_oStream.WriteBYTE(*oQueryTableField.m_oDataBound ? 1 : 0); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oQueryTableField.m_oClipped.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_QueryTableField::Clipped); + m_oBcw.m_oStream.WriteBYTE(*oQueryTableField.m_oClipped ? 1 : 0); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryTableWriter::WriteAltTextTable(const OOX::Spreadsheet::CAltTextTable& oAltTextTable) +{ + int nCurPos = 0; + if(oAltTextTable.m_oAltText.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_AltTextTable::AltText); + m_oBcw.m_oStream.WriteStringW(oAltTextTable.m_oAltText.get()); + } + if(oAltTextTable.m_oAltTextSummary.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_AltTextTable::AltTextSummary); + m_oBcw.m_oStream.WriteStringW(oAltTextTable.m_oAltTextSummary.get()); + } +} +void BinaryTableWriter::WriteAutoFilter(const OOX::Spreadsheet::CAutofilter& oAutofilter) +{ + int nCurPos = 0; + if(oAutofilter.m_oRef.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_AutoFilter::Ref); + m_oBcw.m_oStream.WriteStringW(oAutofilter.m_oRef->ToString()); + } + if(oAutofilter.m_arrItems.size() > 0) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_AutoFilter::FilterColumns); + WriteFilterColumns(oAutofilter.m_arrItems); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oAutofilter.m_oSortState.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_AutoFilter::SortState); + WriteSortState(oAutofilter.m_oSortState.get()); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryTableWriter::WriteFilterColumns(const std::vector& aFilterColumn) +{ + int nCurPos = 0; + for(size_t i = 0, length = aFilterColumn.size(); i < length; ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_AutoFilter::FilterColumn); + WriteFilterColumn(*aFilterColumn[i]); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryTableWriter::WriteFilterColumn(OOX::Spreadsheet::CFilterColumn& oFilterColumn) +{ + int nCurPos = 0; + if(oFilterColumn.m_oColId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_FilterColumn::ColId); + m_oBcw.m_oStream.WriteLONG(oFilterColumn.m_oColId->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oFilterColumn.m_oFilters.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_FilterColumn::Filters); + WriteFilters(oFilterColumn.m_oFilters.get()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oFilterColumn.m_oCustomFilters.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_FilterColumn::CustomFilters); + WriteCustomFilters(oFilterColumn.m_oCustomFilters.get()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oFilterColumn.m_oDynamicFilter.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_FilterColumn::DynamicFilter); + WriteDynamicFilter(oFilterColumn.m_oDynamicFilter.get()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oFilterColumn.m_oColorFilter.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_FilterColumn::ColorFilter); + WriteColorFilter(oFilterColumn.m_oColorFilter.get()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oFilterColumn.m_oTop10.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_FilterColumn::Top10); + WriteTop10(oFilterColumn.m_oTop10.get()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oFilterColumn.m_oShowButton.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_FilterColumn::ShowButton); + m_oBcw.m_oStream.WriteBOOL(oFilterColumn.m_oShowButton->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oFilterColumn.m_oHiddenButton.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_FilterColumn::HiddenButton); + m_oBcw.m_oStream.WriteBOOL(oFilterColumn.m_oHiddenButton->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryTableWriter::WriteFilters(const OOX::Spreadsheet::CFilters& oFilters) +{ + int nCurPos = 0; + if(oFilters.m_oBlank.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_FilterColumn::FiltersBlank); + m_oBcw.m_oStream.WriteBOOL(oFilters.m_oBlank->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + for(size_t i = 0, length = oFilters.m_arrItems.size(); i < length; ++i) + { + OOX::Spreadsheet::WritingElement* we = oFilters.m_arrItems[i]; + if(OOX::et_x_Filter == we->getType()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_FilterColumn::Filter); + WriteFilter(*static_cast(we)); + m_oBcw.WriteItemEnd(nCurPos); + } + else if(OOX::et_x_DateGroupItem == we->getType()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_FilterColumn::DateGroupItem); + WriteDateGroupItem(*static_cast(we)); + m_oBcw.WriteItemEnd(nCurPos); + } + } +} +void BinaryTableWriter::WriteFilter(OOX::Spreadsheet::CFilter& oFilter) +{ + int nCurPos = 0; + if(oFilter.m_oVal.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Filter::Val); + m_oBcw.m_oStream.WriteStringW(oFilter.m_oVal.get2()); + } +} +void BinaryTableWriter::WriteDateGroupItem(OOX::Spreadsheet::CDateGroupItem& oDateGroupItem) +{ + int nCurPos = 0; + if(oDateGroupItem.m_oDateTimeGrouping.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DateGroupItem::DateTimeGrouping); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(oDateGroupItem.m_oDateTimeGrouping->GetValue()); + } + if(oDateGroupItem.m_oDay.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DateGroupItem::Day); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oDateGroupItem.m_oDay->GetValue()); + } + if(oDateGroupItem.m_oHour.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DateGroupItem::Hour); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oDateGroupItem.m_oHour->GetValue()); + } + if(oDateGroupItem.m_oMinute.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DateGroupItem::Minute); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oDateGroupItem.m_oMinute->GetValue()); + } + if(oDateGroupItem.m_oMonth.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DateGroupItem::Month); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oDateGroupItem.m_oMonth->GetValue()); + } + if(oDateGroupItem.m_oSecond.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DateGroupItem::Second); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oDateGroupItem.m_oSecond->GetValue()); + } + if(oDateGroupItem.m_oYear.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DateGroupItem::Year); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oDateGroupItem.m_oYear->GetValue()); + } +} +void BinaryTableWriter::WriteCustomFilters(const OOX::Spreadsheet::CCustomFilters& oCustomFilters) +{ + int nCurPos = 0; + if(oCustomFilters.m_oAnd.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_CustomFilters::And); + m_oBcw.m_oStream.WriteBOOL(oCustomFilters.m_oAnd->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oCustomFilters.m_arrItems.size() > 0) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_CustomFilters::CustomFilters); + WriteCustomFiltersItems(oCustomFilters.m_arrItems); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryTableWriter::WriteCustomFiltersItems(const std::vector& aCustomFilters) +{ + int nCurPos = 0; + for(size_t i = 0, length = aCustomFilters.size(); i < length; ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_CustomFilters::CustomFilter); + WriteCustomFiltersItem(*aCustomFilters[i]); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryTableWriter::WriteCustomFiltersItem(OOX::Spreadsheet::CCustomFilter& oCustomFilter) +{ + int nCurPos = 0; + if(oCustomFilter.m_oOperator.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_CustomFilters::Operator); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(oCustomFilter.m_oOperator->GetValue()); + } + if(oCustomFilter.m_oVal.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_CustomFilters::Val); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(oCustomFilter.m_oVal.get2()); + } +} +void BinaryTableWriter::WriteDynamicFilter(const OOX::Spreadsheet::CDynamicFilter& oDynamicFilter) +{ + if(oDynamicFilter.m_oType.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DynamicFilter::Type); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE((BYTE)oDynamicFilter.m_oType->GetValue()); + } + if(oDynamicFilter.m_oVal.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DynamicFilter::Val); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Double); + m_oBcw.m_oStream.WriteDoubleReal(oDynamicFilter.m_oVal->GetValue()); + } + if(oDynamicFilter.m_oMaxVal.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DynamicFilter::MaxVal); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Double); + m_oBcw.m_oStream.WriteDoubleReal(oDynamicFilter.m_oMaxVal->GetValue()); + } +} +void BinaryTableWriter::WriteColorFilter(const OOX::Spreadsheet::CColorFilter& oColorFilter) +{ + int nCurPos = 0; + if(oColorFilter.m_oCellColor.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_ColorFilter::CellColor); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oColorFilter.m_oCellColor->ToBool()); + } + if(oColorFilter.m_oDxfId.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_ColorFilter::DxfId); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oColorFilter.m_oDxfId->GetValue()); + } +} +void BinaryTableWriter::WriteTop10(const OOX::Spreadsheet::CTop10& oTop10) +{ + int nCurPos = 0; + if(oTop10.m_oFilterVal.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Top10::FilterVal); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Double); + m_oBcw.m_oStream.WriteDoubleReal(oTop10.m_oFilterVal->GetValue()); + } + if(oTop10.m_oPercent.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Top10::Percent); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oTop10.m_oPercent->ToBool()); + } + if(oTop10.m_oTop.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Top10::Top); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oTop10.m_oTop->ToBool()); + } + if(oTop10.m_oVal.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Top10::Val); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Double); + m_oBcw.m_oStream.WriteDoubleReal(oTop10.m_oVal->GetValue()); + } +} +void BinaryTableWriter::WriteSortCondition(const OOX::Spreadsheet::CSortCondition& oSortCondition) +{ + int nCurPos = 0; + if(oSortCondition.m_oRef.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_SortState::ConditionRef); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(oSortCondition.m_oRef->ToString()); + } + if(oSortCondition.m_oSortBy.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_SortState::ConditionSortBy); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(oSortCondition.m_oSortBy->GetValue()); + } + if(oSortCondition.m_oDescending.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_SortState::ConditionDescending); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oSortCondition.m_oDescending->ToBool()); + } + if(oSortCondition.m_oDxfId.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_SortState::ConditionDxfId); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oSortCondition.m_oDxfId->GetValue()); + } +} +void BinaryTableWriter::WriteSortState(const OOX::Spreadsheet::CSortState& oSortState) +{ + int nCurPos = 0; + if(oSortState.m_oRef.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_SortState::Ref); + m_oBcw.m_oStream.WriteStringW(oSortState.m_oRef->ToString()); + } + if(oSortState.m_oCaseSensitive.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SortState::CaseSensitive); + m_oBcw.m_oStream.WriteBOOL(oSortState.m_oCaseSensitive->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oSortState.m_oColumnSort.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SortState::ColumnSort); + m_oBcw.m_oStream.WriteBOOL(oSortState.m_oColumnSort->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oSortState.m_oSortMethod.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SortState::SortMethod); + m_oBcw.m_oStream.WriteBYTE(oSortState.m_oSortMethod->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + int nCurPos2 = m_oBcw.WriteItemStart(c_oSer_SortState::SortConditions); + for(size_t i = 0, length = oSortState.m_arrItems.size(); i < length; ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SortState::SortCondition); + WriteSortCondition(*oSortState.m_arrItems[i]); + m_oBcw.WriteItemEnd(nCurPos); + } + m_oBcw.WriteItemEnd(nCurPos2); +} +void BinaryTableWriter::WriteTableColumn(const OOX::Spreadsheet::CTableColumn& oTableColumn) +{ + int nCurPos = 0; + if(oTableColumn.m_oName.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TableColumns::Name); + m_oBcw.m_oStream.WriteStringW(*oTableColumn.m_oName); + } + if(oTableColumn.m_oTotalsRowLabel.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TableColumns::TotalsRowLabel); + m_oBcw.m_oStream.WriteStringW(*oTableColumn.m_oTotalsRowLabel); + } + if(oTableColumn.m_oTotalsRowFunction.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TableColumns::TotalsRowFunction); + m_oBcw.m_oStream.WriteBYTE(oTableColumn.m_oTotalsRowFunction->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oTableColumn.m_oTotalsRowFormula.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TableColumns::TotalsRowFormula); + m_oBcw.m_oStream.WriteStringW(*oTableColumn.m_oTotalsRowFormula); + } + if(oTableColumn.m_oDataDxfId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TableColumns::DataDxfId); + m_oBcw.m_oStream.WriteLONG(oTableColumn.m_oDataDxfId->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oTableColumn.m_oCalculatedColumnFormula.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TableColumns::CalculatedColumnFormula); + m_oBcw.m_oStream.WriteStringW(*oTableColumn.m_oCalculatedColumnFormula); + } + if(oTableColumn.m_oDataCellStyle.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TableColumns::DataCellStyle); + m_oBcw.m_oStream.WriteStringW(*oTableColumn.m_oDataCellStyle); + } + if(oTableColumn.m_oHeaderRowCellStyle.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TableColumns::HeaderRowCellStyle); + m_oBcw.m_oStream.WriteStringW(*oTableColumn.m_oHeaderRowCellStyle); + } + if(oTableColumn.m_oHeaderRowDxfId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TableColumns::HeaderRowDxfId); + m_oBcw.m_oStream.WriteLONG(oTableColumn.m_oHeaderRowDxfId->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oTableColumn.m_oId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TableColumns::Id); + m_oBcw.m_oStream.WriteLONG(oTableColumn.m_oId->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oTableColumn.m_oQueryTableFieldId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TableColumns::QueryTableFieldId); + m_oBcw.m_oStream.WriteLONG(oTableColumn.m_oQueryTableFieldId->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oTableColumn.m_oTotalsRowCellStyle.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TableColumns::TotalsRowCellStyle); + m_oBcw.m_oStream.WriteStringW(*oTableColumn.m_oTotalsRowCellStyle); + } + if(oTableColumn.m_oTotalsRowDxfId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TableColumns::TotalsRowDxfId); + m_oBcw.m_oStream.WriteLONG(oTableColumn.m_oTotalsRowDxfId->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oTableColumn.m_oUniqueName.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TableColumns::UniqueName); + m_oBcw.m_oStream.WriteStringW(*oTableColumn.m_oUniqueName); + } +} +void BinaryTableWriter::WriteTableColumns(const OOX::Spreadsheet::CTableColumns& oTableColumns) +{ + int nCurPos = 0; + for(size_t i = 0, length = oTableColumns.m_arrItems.size(); i < length; ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TableColumns::TableColumn); + WriteTableColumn(*oTableColumns.m_arrItems[i]); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryTableWriter::WriteTableStyleInfo(const OOX::Spreadsheet::CTableStyleInfo& oTableStyleInfo) +{ + if(oTableStyleInfo.m_oName.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TableStyleInfo::Name); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(oTableStyleInfo.m_oName.get2()); + } + if(oTableStyleInfo.m_oShowColumnStripes.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TableStyleInfo::ShowColumnStripes); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oTableStyleInfo.m_oShowColumnStripes->ToBool()); + } + if(oTableStyleInfo.m_oShowRowStripes.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TableStyleInfo::ShowRowStripes); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oTableStyleInfo.m_oShowRowStripes->ToBool()); + } + if(oTableStyleInfo.m_oShowFirstColumn.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TableStyleInfo::ShowFirstColumn); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oTableStyleInfo.m_oShowFirstColumn->ToBool()); + } + if(oTableStyleInfo.m_oShowLastColumn.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TableStyleInfo::ShowLastColumn); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oTableStyleInfo.m_oShowLastColumn->ToBool()); + } +} + +BinaryStyleTableWriter::BinaryStyleTableWriter(NSBinPptxRW::CBinaryFileWriter &oCBufferedStream, NSFontCutter::CEmbeddedFontsManager* pEmbeddedFontsManager):m_oBcw(oCBufferedStream),m_pEmbeddedFontsManager(pEmbeddedFontsManager) +{ +} +void BinaryStyleTableWriter::Write(OOX::Spreadsheet::CStyles& styles, PPTX::Theme* pTheme, DocWrapper::FontProcessor& oFontProcessor) +{ + int nStart = m_oBcw.WriteItemWithLengthStart(); + WriteStylesContent(styles, pTheme, oFontProcessor); + m_oBcw.WriteItemWithLengthEnd(nStart); +} +void BinaryStyleTableWriter::WriteStylesContent(OOX::Spreadsheet::CStyles& styles, PPTX::Theme* pTheme, DocWrapper::FontProcessor& oFontProcessor) +{ + int nCurPos; + OOX::Spreadsheet::CIndexedColors* pIndexedColors = NULL; + if(styles.m_oColors.IsInit() && styles.m_oColors->m_oIndexedColors.IsInit()) + { + pIndexedColors = styles.m_oColors->m_oIndexedColors.operator ->(); + } +//borders + if(styles.m_oBorders.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerStylesTypes::Borders); + WriteBorders(styles.m_oBorders.get(), pIndexedColors, pTheme); + m_oBcw.WriteItemEnd(nCurPos); + } +//Fills + if(styles.m_oFills.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerStylesTypes::Fills); + WriteFills(styles.m_oFills.get(), pIndexedColors, pTheme); + m_oBcw.WriteItemEnd(nCurPos); + } +//Fonts + if(styles.m_oFonts.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerStylesTypes::Fonts); + WriteFonts(styles.m_oFonts.get(), pIndexedColors, pTheme, oFontProcessor); + m_oBcw.WriteItemEnd(nCurPos); + } +//NumFmts + if(styles.m_oNumFmts.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerStylesTypes::NumFmts); + WriteNumFmts(styles.m_oNumFmts.get()); + m_oBcw.WriteItemEnd(nCurPos); + } +//CellStyleXfs + if(styles.m_oCellStyleXfs.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerStylesTypes::CellStyleXfs); + WriteCellStyleXfs(styles.m_oCellStyleXfs.get()); + m_oBcw.WriteItemEnd(nCurPos); + } +//CellXfs + if(styles.m_oCellXfs.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerStylesTypes::CellXfs); + WriteCellXfs(styles.m_oCellXfs.get()); + m_oBcw.WriteItemEnd(nCurPos); + } +//CellStyles + if(styles.m_oCellStyles.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerStylesTypes::CellStyles); + WriteCellStyles(styles.m_oCellStyles.get()); + m_oBcw.WriteItemEnd(nCurPos); + } +//Dxfs + if(styles.m_oDxfs.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerStylesTypes::Dxfs); + WriteDxfs(styles.m_oDxfs.get(), pIndexedColors, pTheme, oFontProcessor); + m_oBcw.WriteItemEnd(nCurPos); + } +//TableStyles + if(styles.m_oTableStyles.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerStylesTypes::TableStyles); + WriteTableStyles(styles.m_oTableStyles.get()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (styles.m_oExtLst.IsInit()) + { + for(size_t i = 0; i < styles.m_oExtLst->m_arrExt.size(); ++i) + { + OOX::Drawing::COfficeArtExtension* pExt = styles.m_oExtLst->m_arrExt[i]; + if ( pExt->m_oDxfs.IsInit() ) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerStylesTypes::ExtDxfs); + WriteDxfs(pExt->m_oDxfs.get(), pIndexedColors, pTheme, oFontProcessor); + m_oBcw.WriteItemEnd(nCurPos); + } + else if ( pExt->m_oSlicerStyles.IsInit() ) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerStylesTypes::SlicerStyles); + m_oBcw.m_oStream.WriteRecord2(0, pExt->m_oSlicerStyles); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + else if (pExt->m_oTimelineStyles.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerStylesTypes::TimelineStyles); + WriteTimelineStyles(pExt->m_oTimelineStyles.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + } + } +} +void BinaryStyleTableWriter::WriteTimelineStyles(OOX::Spreadsheet::CTimelineStyles* pTimelineStyles) +{ + if (!pTimelineStyles) return; + int nCurPos = 0; + if (pTimelineStyles->m_oDefaultTimelineStyle.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineStyles::DefaultTimelineStyle); + m_oBcw.m_oStream.WriteStringW3(*pTimelineStyles->m_oDefaultTimelineStyle); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + for (size_t i = 0; i < pTimelineStyles->m_arrItems.size(); ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineStyles::TimelineStyle); + WriteTimelineStyle(pTimelineStyles->m_arrItems[i]); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryStyleTableWriter::WriteTimelineStyle(OOX::Spreadsheet::CTimelineStyle* pTimelineStyle) +{ + if (!pTimelineStyle) return; + + int nCurPos = 0; + if (pTimelineStyle->m_oName.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineStyles::TimelineStyleName); + m_oBcw.m_oStream.WriteStringW3(*pTimelineStyle->m_oName); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + for (size_t i = 0; i < pTimelineStyle->m_arrItems.size(); ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineStyles::TimelineStyleElement); + WriteTimelineStyleElement(pTimelineStyle->m_arrItems[i]); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryStyleTableWriter::WriteTimelineStyleElement(OOX::Spreadsheet::CTimelineStyleElement* pTimelineStyleElement) +{ + if (!pTimelineStyleElement) return; + + if (pTimelineStyleElement->m_oType.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TimelineStyles::TimelineStyleElementType); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE((BYTE)pTimelineStyleElement->m_oType->GetValue()); + } + if (pTimelineStyleElement->m_oDxfId.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TimelineStyles::TimelineStyleElementDxfId); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(*pTimelineStyleElement->m_oDxfId); + } +} +void BinaryStyleTableWriter::WriteBorders(const OOX::Spreadsheet::CBorders& borders, OOX::Spreadsheet::CIndexedColors* pIndexedColors, PPTX::Theme* pTheme) +{ + int nCurPos = 0; + for (size_t i = 0, length = borders.m_arrItems.size(); i < length; ++i) + { + OOX::Spreadsheet::CBorder* pBorder = borders.m_arrItems[i]; + nCurPos = m_oBcw.WriteItemStart(c_oSerStylesTypes::Border); + WriteBorder(*pBorder, pIndexedColors, pTheme); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryStyleTableWriter::WriteBorder(const OOX::Spreadsheet::CBorder& border, OOX::Spreadsheet::CIndexedColors* pIndexedColors, PPTX::Theme* pTheme) +{ + int nCurPos = 0; + //Bottom + if(false != border.m_oBottom.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerBorderTypes::Bottom); + WriteBorderProp(border.m_oBottom.get(), pIndexedColors, pTheme); + m_oBcw.WriteItemEnd(nCurPos); + } + //Diagonal + if(false != border.m_oDiagonal.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerBorderTypes::Diagonal); + WriteBorderProp(border.m_oDiagonal.get(), pIndexedColors, pTheme); + m_oBcw.WriteItemEnd(nCurPos); + } + //End + if(false != border.m_oEnd.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerBorderTypes::End); + WriteBorderProp(border.m_oEnd.get(), pIndexedColors, pTheme); + m_oBcw.WriteItemEnd(nCurPos); + } + //Horizontal + if(false != border.m_oHorizontal.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerBorderTypes::Horizontal); + WriteBorderProp(border.m_oHorizontal.get(), pIndexedColors, pTheme); + m_oBcw.WriteItemEnd(nCurPos); + } + //Start + if(false != border.m_oStart.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerBorderTypes::Start); + WriteBorderProp(border.m_oStart.get(), pIndexedColors, pTheme); + m_oBcw.WriteItemEnd(nCurPos); + } + //Top + if(false != border.m_oTop.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerBorderTypes::Top); + WriteBorderProp(border.m_oTop.get(), pIndexedColors, pTheme); + m_oBcw.WriteItemEnd(nCurPos); + } + //Vertical + if(false != border.m_oVertical.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerBorderTypes::Vertical); + WriteBorderProp(border.m_oVertical.get(), pIndexedColors, pTheme); + m_oBcw.WriteItemEnd(nCurPos); + } + //DiagonalDown + if(false != border.m_oDiagonalDown.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerBorderTypes::DiagonalDown); + m_oBcw.m_oStream.WriteBOOL(border.m_oDiagonalDown->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + //DiagonalUp + if(false != border.m_oDiagonalUp.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerBorderTypes::DiagonalUp); + m_oBcw.m_oStream.WriteBOOL(border.m_oDiagonalUp->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + //Outline + if(false != border.m_oOutline.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerBorderTypes::Outline); + m_oBcw.m_oStream.WriteBOOL(border.m_oOutline->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryStyleTableWriter::WriteBorderProp(const OOX::Spreadsheet::CBorderProp& borderProp, OOX::Spreadsheet::CIndexedColors* pIndexedColors, PPTX::Theme* pTheme) +{ + int nCurPos = 0; + //Color + if(false != borderProp.m_oColor.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerBorderPropTypes::Color); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + nCurPos = m_oBcw.WriteItemWithLengthStart(); + m_oBcw.WriteColor(borderProp.m_oColor.get(), pIndexedColors); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + //Style + if(false != borderProp.m_oStyle.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerBorderPropTypes::Style); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE((BYTE)borderProp.m_oStyle->GetValue()); + } +} +void BinaryStyleTableWriter::WriteCellStyleXfs(const OOX::Spreadsheet::CCellStyleXfs& cellStyleXfs) +{ + int nCurPos = 0; + for(size_t i = 0, length = cellStyleXfs.m_arrItems.size(); i < length; ++i) + { + OOX::Spreadsheet::WritingElement* we = cellStyleXfs.m_arrItems[i]; + if(OOX::et_x_Xfs == we->getType()) + { + OOX::Spreadsheet::CXfs* pXfs = static_cast(we); + nCurPos = m_oBcw.WriteItemStart(c_oSerStylesTypes::Xfs); + WriteXfs(*pXfs); + m_oBcw.WriteItemEnd(nCurPos); + } + } +} +void BinaryStyleTableWriter::WriteCellXfs(const OOX::Spreadsheet::CCellXfs& cellXfs) +{ + int nCurPos = 0; + for(size_t i = 0, length = cellXfs.m_arrItems.size(); i < length; ++i) + { + OOX::Spreadsheet::WritingElement* we = cellXfs.m_arrItems[i]; + if(OOX::et_x_Xfs == we->getType()) + { + OOX::Spreadsheet::CXfs* pXfs = static_cast(we); + nCurPos = m_oBcw.WriteItemStart(c_oSerStylesTypes::Xfs); + WriteXfs(*pXfs); + m_oBcw.WriteItemEnd(nCurPos); + } + } +} +void BinaryStyleTableWriter::WriteXfs(const OOX::Spreadsheet::CXfs& xfs) +{ + int nCurPos = 0; + //ApplyAlignment + if (false != xfs.m_oApplyAlignment.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerXfsTypes::ApplyAlignment); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(xfs.m_oApplyAlignment->ToBool()); + } + //ApplyBorder + if(false != xfs.m_oApplyBorder.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerXfsTypes::ApplyBorder); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(xfs.m_oApplyBorder->ToBool()); + } + //ApplyFill + if (false != xfs.m_oApplyFill.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerXfsTypes::ApplyFill); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(xfs.m_oApplyFill->ToBool()); + } + //ApplyFont + if(false != xfs.m_oApplyFont.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerXfsTypes::ApplyFont); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(xfs.m_oApplyFont->ToBool()); + } + //ApplyNumberFormat + if (false != xfs.m_oApplyNumberFormat.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerXfsTypes::ApplyNumberFormat); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(xfs.m_oApplyNumberFormat->ToBool()); + } + //ApplyProtection + if (false != xfs.m_oApplyProtection.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerXfsTypes::ApplyProtection); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(xfs.m_oApplyProtection->ToBool()); + } + //BorderId + if (false != xfs.m_oBorderId.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerXfsTypes::BorderId); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(xfs.m_oBorderId->GetValue()); + } + //FillId + if (false != xfs.m_oFillId.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerXfsTypes::FillId); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(xfs.m_oFillId->GetValue()); + } + //FontId + if (false != xfs.m_oFontId.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerXfsTypes::FontId); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(xfs.m_oFontId->GetValue()); + } + //NumFmtId + if (false != xfs.m_oNumFmtId.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerXfsTypes::NumFmtId); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(xfs.m_oNumFmtId->GetValue()); + } + //QuotePrefix + if (false != xfs.m_oQuotePrefix.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerXfsTypes::QuotePrefix); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(xfs.m_oQuotePrefix->ToBool()); + } + //PivotButton + if (false != xfs.m_oPivotButton.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerXfsTypes::PivotButton); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(xfs.m_oPivotButton->ToBool()); + } + //XfId + if (false != xfs.m_oXfId.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerXfsTypes::XfId); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(xfs.m_oXfId->GetValue()); + } + //Aligment + if (false != xfs.m_oAligment.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerXfsTypes::Aligment); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + nCurPos = m_oBcw.WriteItemWithLengthStart(); + WriteAligment(xfs.m_oAligment.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + //Protection + if (false != xfs.m_oProtection.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerXfsTypes::Protection); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + nCurPos = m_oBcw.WriteItemWithLengthStart(); + WriteProtection(xfs.m_oProtection.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryStyleTableWriter::WriteProtection(const OOX::Spreadsheet::CProtection& protection) +{ + int nCurPos = 0; + if (false != protection.m_oHidden.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerProtectionTypes::Hidden); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(protection.m_oHidden->ToBool()); + } + if (false != protection.m_oLocked.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerProtectionTypes::Locked); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(protection.m_oLocked->ToBool()); + } +} +void BinaryStyleTableWriter::WriteAligment(const OOX::Spreadsheet::CAligment& aligment) +{ + int nCurPos = 0; + //Horizontal + if(false != aligment.m_oHorizontal.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerAligmentTypes::Horizontal); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(aligment.m_oHorizontal->GetValue()); + } + //Indent + if(false != aligment.m_oIndent.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerAligmentTypes::Indent); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(*aligment.m_oIndent); + } + //RelativeIndent + if(false != aligment.m_oRelativeIndent.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerAligmentTypes::RelativeIndent); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(*aligment.m_oRelativeIndent); + } + //ShrinkToFit + if(false != aligment.m_oShrinkToFit.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerAligmentTypes::ShrinkToFit); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(aligment.m_oShrinkToFit->ToBool()); + } + //TextRotation + if(false != aligment.m_oTextRotation.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerAligmentTypes::TextRotation); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(*aligment.m_oTextRotation); + } + //Vertical + if(false != aligment.m_oVertical.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerAligmentTypes::Vertical); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(aligment.m_oVertical->GetValue()); + } + //WrapText + if(false != aligment.m_oWrapText.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerAligmentTypes::WrapText); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(aligment.m_oWrapText->ToBool()); + } +} +void BinaryStyleTableWriter::WriteFills(const OOX::Spreadsheet::CFills& fills, OOX::Spreadsheet::CIndexedColors* pIndexedColors, PPTX::Theme* pTheme) +{ + int nCurPos = 0; + for(size_t i = 0, length = fills.m_arrItems.size(); i < length; ++i) + { + OOX::Spreadsheet::CFill* pFill = fills.m_arrItems[i]; + nCurPos = m_oBcw.WriteItemStart(c_oSerStylesTypes::Fill); + WriteFill(*pFill, pIndexedColors); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryStyleTableWriter::WriteFill(const OOX::Spreadsheet::CFill& fill, OOX::Spreadsheet::CIndexedColors* pIndexedColors) +{ + int nCurPos = 0; + if (fill.m_oPatternFill.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerFillTypes::Pattern); + WritePatternFill(fill.m_oPatternFill.get(), pIndexedColors); + m_oBcw.WriteItemEnd(nCurPos); + } + if (fill.m_oGradientFill.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerFillTypes::Gradient); + WriteGradientFill(fill.m_oGradientFill.get(), pIndexedColors); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryStyleTableWriter::WritePatternFill(const OOX::Spreadsheet::CPatternFill& fill, OOX::Spreadsheet::CIndexedColors* pIndexedColors) +{ + int nCurPos = 0; + if (fill.m_oPatternType.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerFillTypes::PatternType); + m_oBcw.m_oStream.WriteBYTE(fill.m_oPatternType->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (fill.m_oFgColor.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerFillTypes::PatternFgColor); + m_oBcw.WriteColor(fill.m_oFgColor.get(), pIndexedColors); + m_oBcw.WriteItemEnd(nCurPos); + } + if (fill.m_oBgColor.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerFillTypes::PatternBgColor); + m_oBcw.WriteColor(fill.m_oBgColor.get(), pIndexedColors); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryStyleTableWriter::WriteGradientFill(const OOX::Spreadsheet::CGradientFill& fill, OOX::Spreadsheet::CIndexedColors* pIndexedColors) +{ + int nCurPos = 0; + if (fill.m_oType.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerFillTypes::GradientType); + m_oBcw.m_oStream.WriteBYTE(fill.m_oType->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (fill.m_oLeft.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerFillTypes::GradientLeft); + m_oBcw.m_oStream.WriteDoubleReal(fill.m_oLeft->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (fill.m_oTop.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerFillTypes::GradientTop); + m_oBcw.m_oStream.WriteDoubleReal(fill.m_oTop->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (fill.m_oRight.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerFillTypes::GradientRight); + m_oBcw.m_oStream.WriteDoubleReal(fill.m_oRight->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (fill.m_oBottom.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerFillTypes::GradientBottom); + m_oBcw.m_oStream.WriteDoubleReal(fill.m_oBottom->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (fill.m_oDegree.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerFillTypes::GradientDegree); + m_oBcw.m_oStream.WriteDoubleReal(fill.m_oDegree->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + for(size_t i = 0, length = fill.m_arrItems.size(); i < length; ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerFillTypes::GradientStop); + WriteGradientFillStop(*fill.m_arrItems[i], pIndexedColors); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryStyleTableWriter::WriteGradientFillStop(const OOX::Spreadsheet::CGradientStop& stop, OOX::Spreadsheet::CIndexedColors* pIndexedColors) +{ + int nCurPos = 0; + if (stop.m_oPosition.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerFillTypes::GradientStopPosition); + m_oBcw.m_oStream.WriteDoubleReal(stop.m_oPosition->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (stop.m_oColor.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerFillTypes::GradientStopColor); + m_oBcw.WriteColor(stop.m_oColor.get(), pIndexedColors); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryStyleTableWriter::WriteFonts(const OOX::Spreadsheet::CFonts& fonts, OOX::Spreadsheet::CIndexedColors* pIndexedColors, PPTX::Theme* pTheme, DocWrapper::FontProcessor& oFontProcessor) +{ + int nCurPos = 0; + for(size_t i = 0, length = fonts.m_arrItems.size(); i < length; ++i) + { + OOX::Spreadsheet::CFont* pFont = fonts.m_arrItems[i]; + nCurPos = m_oBcw.WriteItemStart(c_oSerStylesTypes::Font); + WriteFont(*pFont, pIndexedColors, pTheme, oFontProcessor); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryStyleTableWriter::WriteFont(const OOX::Spreadsheet::CFont& font, OOX::Spreadsheet::CIndexedColors* pIndexedColors, PPTX::Theme* theme, DocWrapper::FontProcessor& oFontProcessor) +{ + int nCurPos = 0; + //Bold + if(false != font.m_oBold.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFontTypes::Bold); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(font.m_oBold->m_oVal.ToBool()); + } + //Color + if(false != font.m_oColor.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFontTypes::Color); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + nCurPos = m_oBcw.WriteItemWithLengthStart(); + m_oBcw.WriteColor(font.m_oColor.get(), pIndexedColors); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + //Italic + if(false != font.m_oItalic.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFontTypes::Italic); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(font.m_oItalic->m_oVal.ToBool()); + } + //RFont + if(font.m_oRFont.IsInit() && font.m_oRFont->m_sVal.IsInit()) + { + //подбираем шрифт + std::wstring sFont = oFontProcessor.getFont(font.m_oScheme, font.m_oRFont, font.m_oCharset, font.m_oFamily, theme); + + m_oBcw.m_oStream.WriteBYTE(c_oSerFontTypes::RFont); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(sFont); + + if(NULL != m_pEmbeddedFontsManager) + m_pEmbeddedFontsManager->CheckFont(sFont, oFontProcessor.getFontManager()); + } + //Scheme + if(font.m_oScheme.IsInit() && font.m_oScheme->m_oFontScheme.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFontTypes::Scheme); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE((BYTE)font.m_oScheme->m_oFontScheme->GetValue()); + } + //Strike + if(false != font.m_oStrike.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFontTypes::Strike); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(font.m_oStrike->m_oVal.ToBool()); + } + //Sz + if(false != font.m_oSz.IsInit() && font.m_oSz->m_oVal.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFontTypes::Sz); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Double); + m_oBcw.m_oStream.WriteDoubleReal(font.m_oSz->m_oVal->GetValue()); + } + //Underline + if(false != font.m_oUnderline.IsInit()) + { + SimpleTypes::Spreadsheet::EUnderline eType = SimpleTypes::Spreadsheet::underlineSingle; + if(font.m_oUnderline->m_oUnderline.IsInit()) + eType = font.m_oUnderline->m_oUnderline->GetValue(); + + m_oBcw.m_oStream.WriteBYTE(c_oSerFontTypes::Underline); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(eType); + } + //VertAlign + if(false != font.m_oVertAlign.IsInit() && font.m_oVertAlign->m_oVerticalAlign.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFontTypes::VertAlign); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(font.m_oVertAlign->m_oVerticalAlign->GetValue()); + } +} +void BinaryStyleTableWriter::WriteNumFmts(const OOX::Spreadsheet::CNumFmts& numFmts) +{ + int nCurPos = 0; + for(size_t i = 0, length = numFmts.m_arrItems.size(); i < length; ++i) + { + OOX::Spreadsheet::CNumFmt* pNumFmt = numFmts.m_arrItems[i]; + nCurPos = m_oBcw.WriteItemStart(c_oSerStylesTypes::NumFmt); + WriteNumFmt(*pNumFmt); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryStyleTableWriter::WriteNumFmt(const OOX::Spreadsheet::CNumFmt& numFmt) +{ + int nCurPos = 0; + //FormatCode + if(numFmt.m_oFormatCode.IsInit()) + { + std::wstring& sFormatCode = *numFmt.m_oFormatCode; + m_oBcw.m_oStream.WriteBYTE(c_oSerNumFmtTypes::FormatCode); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(sFormatCode); + + if(NULL != m_pEmbeddedFontsManager) + m_pEmbeddedFontsManager->CheckString(sFormatCode); + } + if(numFmt.m_oFormatCode16.IsInit()) + { + std::wstring& sFormatCode = *numFmt.m_oFormatCode16; + m_oBcw.m_oStream.WriteBYTE(c_oSerNumFmtTypes::FormatCode16); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(sFormatCode); + + if(NULL != m_pEmbeddedFontsManager) + m_pEmbeddedFontsManager->CheckString(sFormatCode); + } + //NumFmtId + if(numFmt.m_oNumFmtId.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerNumFmtTypes::NumFmtId); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(numFmt.m_oNumFmtId->GetValue()); + } +} +void BinaryStyleTableWriter::WriteCellStyles(const OOX::Spreadsheet::CCellStyles& oCellStyles) +{ + int nCurPos = 0; + for (size_t i = 0, nLength = oCellStyles.m_arrItems.size(); i < nLength; ++i) + { + OOX::Spreadsheet::WritingElement* we = oCellStyles.m_arrItems[i]; + if (OOX::et_x_CellStyle == we->getType()) + { + OOX::Spreadsheet::CCellStyle* pCellStyle = static_cast(we); + nCurPos = m_oBcw.WriteItemStart(c_oSerStylesTypes::CellStyle); + WriteCellStyle(*pCellStyle); + m_oBcw.WriteItemEnd(nCurPos); + } + } +} +void BinaryStyleTableWriter::WriteCellStyle(const OOX::Spreadsheet::CCellStyle& oCellStyle) +{ + int nCurPos = 0; + if (oCellStyle.m_oBuiltinId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_CellStyle::BuiltinId); + m_oBcw.m_oStream.WriteLONG(oCellStyle.m_oBuiltinId->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oCellStyle.m_oCustomBuiltin.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_CellStyle::CustomBuiltin); + m_oBcw.m_oStream.WriteBOOL(oCellStyle.m_oCustomBuiltin->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oCellStyle.m_oHidden.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_CellStyle::Hidden); + m_oBcw.m_oStream.WriteBOOL(oCellStyle.m_oHidden->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oCellStyle.m_oILevel.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_CellStyle::ILevel); + m_oBcw.m_oStream.WriteLONG(oCellStyle.m_oILevel->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oCellStyle.m_oName.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_CellStyle::Name); + m_oBcw.m_oStream.WriteStringW(*oCellStyle.m_oName); + } + if (oCellStyle.m_oXfId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_CellStyle::XfId); + m_oBcw.m_oStream.WriteLONG(oCellStyle.m_oXfId->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryStyleTableWriter::WriteDxfs(const OOX::Spreadsheet::CDxfs& oDxfs, OOX::Spreadsheet::CIndexedColors* pIndexedColors, PPTX::Theme* pTheme, DocWrapper::FontProcessor& oFontProcessor) +{ + int nCurPos = 0; + for(size_t i = 0, length = oDxfs.m_arrItems.size(); i < length; ++i) + { + OOX::Spreadsheet::CDxf* pDxf = oDxfs.m_arrItems[i]; + nCurPos = m_oBcw.WriteItemStart(c_oSerStylesTypes::Dxf); + WriteDxf(*pDxf, pIndexedColors, pTheme, oFontProcessor); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryStyleTableWriter::WriteDxf(const OOX::Spreadsheet::CDxf& oDxf, OOX::Spreadsheet::CIndexedColors* pIndexedColors, PPTX::Theme* pTheme, DocWrapper::FontProcessor& oFontProcessor) +{ + int nCurPos = 0; + if(oDxf.m_oAlignment.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Dxf::Alignment); + WriteAligment(oDxf.m_oAlignment.get()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oDxf.m_oBorder.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Dxf::Border); + WriteBorder(oDxf.m_oBorder.get(), pIndexedColors, pTheme); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oDxf.m_oFill.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Dxf::Fill); + WriteFill(oDxf.m_oFill.get(), pIndexedColors); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oDxf.m_oFont.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Dxf::Font); + WriteFont(oDxf.m_oFont.get(), pIndexedColors, pTheme, oFontProcessor); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oDxf.m_oNumFmt.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Dxf::NumFmt); + WriteNumFmt(oDxf.m_oNumFmt.get()); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryStyleTableWriter::WriteTableStyles(const OOX::Spreadsheet::CTableStyles& oTableStyles) +{ + int nCurPos = 0; + if(oTableStyles.m_oDefaultTableStyle.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TableStyles::DefaultTableStyle); + m_oBcw.m_oStream.WriteStringW(oTableStyles.m_oDefaultTableStyle.get2()); + } + if(oTableStyles.m_oDefaultPivotStyle.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TableStyles::DefaultPivotStyle); + m_oBcw.m_oStream.WriteStringW(oTableStyles.m_oDefaultPivotStyle.get2()); + } + if(oTableStyles.m_arrItems.size() > 0) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TableStyles::TableStyles); + WriteTableCustomStyles(oTableStyles.m_arrItems); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryStyleTableWriter::WriteTableCustomStyles(const std::vector& aTableStyles) +{ + int nCurPos = 0; + for(size_t i = 0, length = aTableStyles.size(); i < length; ++i) + { + OOX::Spreadsheet::CTableStyle* pTableStyle = aTableStyles[i]; + nCurPos = m_oBcw.WriteItemStart(c_oSer_TableStyles::TableStyle); + WriteTableStyle(*pTableStyle); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryStyleTableWriter::WriteTableStyle(const OOX::Spreadsheet::CTableStyle& oTableStyle) +{ + int nCurPos = 0; + if(oTableStyle.m_oName.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TableStyle::Name); + m_oBcw.m_oStream.WriteStringW(oTableStyle.m_oName.get2()); + } + if(oTableStyle.m_oPivot.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TableStyle::Pivot); + m_oBcw.m_oStream.WriteBOOL(oTableStyle.m_oPivot->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oTableStyle.m_oTable.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TableStyle::Table); + m_oBcw.m_oStream.WriteBOOL(oTableStyle.m_oTable->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oTableStyle.m_arrItems.size() > 0) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TableStyle::Elements); + WriteTableStyleElements(oTableStyle.m_arrItems); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oTableStyle.m_oDisplayName.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TableStyle::DisplayName); + m_oBcw.m_oStream.WriteStringW(oTableStyle.m_oDisplayName.get2()); + } +} +void BinaryStyleTableWriter::WriteTableStyleElements(const std::vector& aTableStyles) +{ + int nCurPos = 0; + for(size_t i = 0, length = aTableStyles.size(); i < length; ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TableStyle::Element); + WriteTableStyleElement(*aTableStyles[i]); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryStyleTableWriter::WriteTableStyleElement(const OOX::Spreadsheet::CTableStyleElement& oTableStyleElement) +{ + int nCurPos = 0; + if(oTableStyleElement.m_oType.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TableStyleElement::Type); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE((BYTE)oTableStyleElement.m_oType->GetValue()); + } + if(oTableStyleElement.m_oSize.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TableStyleElement::Size); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oTableStyleElement.m_oSize->GetValue()); + } + if(oTableStyleElement.m_oDxfId.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TableStyleElement::DxfId); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oTableStyleElement.m_oDxfId->GetValue()); + } +} + +BinarySharedStringTableWriter::BinarySharedStringTableWriter(NSBinPptxRW::CBinaryFileWriter &oCBufferedStream, NSFontCutter::CEmbeddedFontsManager* pEmbeddedFontsManager):m_oBcw(oCBufferedStream),m_pEmbeddedFontsManager(pEmbeddedFontsManager) +{ +} +void BinarySharedStringTableWriter::Write(OOX::Spreadsheet::CSharedStrings& sharedString, OOX::Spreadsheet::CIndexedColors* pIndexedColors, PPTX::Theme* pTheme, DocWrapper::FontProcessor& oFontProcessor) +{ + int nStart = m_oBcw.WriteItemWithLengthStart(); + WriteSharedStrings(sharedString, pIndexedColors, pTheme, oFontProcessor); + m_oBcw.WriteItemWithLengthEnd(nStart); +} +void BinarySharedStringTableWriter::WriteSharedStrings(OOX::Spreadsheet::CSharedStrings& sharedString, OOX::Spreadsheet::CIndexedColors* pIndexedColors, PPTX::Theme* pTheme, DocWrapper::FontProcessor& oFontProcessor) +{ + int nCurPos; + for(size_t i = 0, length = sharedString.m_arrItems.size(); i < length; ++i) + { + OOX::Spreadsheet::WritingElement* we = sharedString.m_arrItems[i]; + if(OOX::et_x_Si == we->getType()) + { + OOX::Spreadsheet::CSi* pSi = static_cast(we); + nCurPos = m_oBcw.WriteItemStart(c_oSerSharedStringTypes::Si); + WriteSharedString(*pSi, pIndexedColors, pTheme, oFontProcessor); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + } +} +void BinarySharedStringTableWriter::WriteSharedString(OOX::Spreadsheet::CSi& si, OOX::Spreadsheet::CIndexedColors* pIndexedColors, PPTX::Theme* pTheme, DocWrapper::FontProcessor& oFontProcessor) +{ + int nCurPos; + for(size_t i = 0, length = si.m_arrItems.size(); i < length; ++i) + { + OOX::Spreadsheet::WritingElement* we = si.m_arrItems[i]; + if(OOX::et_x_r == we->getType()) + { + OOX::Spreadsheet::CRun* pRun = static_cast(we); + nCurPos = m_oBcw.WriteItemStart(c_oSerSharedStringTypes::Run); + WriteRun(*pRun, pIndexedColors, pTheme, oFontProcessor); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + else if(OOX::et_x_t == we->getType()) + { + OOX::Spreadsheet::CText* pText = static_cast(we); + m_oBcw.m_oStream.WriteBYTE(c_oSerSharedStringTypes::Text); + m_oBcw.m_oStream.WriteStringW(pText->m_sText); + + if(NULL != m_pEmbeddedFontsManager) + m_pEmbeddedFontsManager->CheckString(pText->m_sText); + } + } +} +void BinarySharedStringTableWriter::WriteRun(OOX::Spreadsheet::CRun& run, OOX::Spreadsheet::CIndexedColors* pIndexedColors, PPTX::Theme* pTheme, DocWrapper::FontProcessor& oFontProcessor) +{ + int nCurPos; +//rPr + if(run.m_oRPr.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerSharedStringTypes::RPr); + WriteRPr(run.m_oRPr.get(), pIndexedColors, pTheme, oFontProcessor); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + for(size_t i = 0, length = run.m_arrItems.size(); i < length; ++i) + { + OOX::Spreadsheet::WritingElement* we = run.m_arrItems[i]; + if(OOX::et_x_t == we->getType()) + { + OOX::Spreadsheet::CText* pText = static_cast(we); + m_oBcw.m_oStream.WriteBYTE(c_oSerSharedStringTypes::Text); + m_oBcw.m_oStream.WriteStringW(pText->m_sText); + + if(NULL != m_pEmbeddedFontsManager) + m_pEmbeddedFontsManager->CheckString(pText->m_sText); + } + } +} +void BinarySharedStringTableWriter::WriteRPr(const OOX::Spreadsheet::CRPr& rPr, OOX::Spreadsheet::CIndexedColors* pIndexedColors, PPTX::Theme* pTheme, DocWrapper::FontProcessor& oFontProcessor) +{ + int nCurPos = 0; + //Bold + if(false != rPr.m_oBold.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFontTypes::Bold); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(rPr.m_oBold->m_oVal.ToBool()); + } + //Color + if(false != rPr.m_oColor.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFontTypes::Color); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + nCurPos = m_oBcw.WriteItemWithLengthStart(); + m_oBcw.WriteColor(rPr.m_oColor.get(), pIndexedColors); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + //Italic + if(false != rPr.m_oItalic.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFontTypes::Italic); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(rPr.m_oItalic->m_oVal.ToBool()); + } + //RFont + if(false != rPr.m_oRFont.IsInit() && rPr.m_oRFont->m_sVal.IsInit()) + { + std::wstring sFont = oFontProcessor.getFont(rPr.m_oScheme, rPr.m_oRFont, rPr.m_oCharset, rPr.m_oFamily, pTheme); + + m_oBcw.m_oStream.WriteBYTE(c_oSerFontTypes::RFont); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(sFont); + + if(NULL != m_pEmbeddedFontsManager) + m_pEmbeddedFontsManager->CheckFont(sFont, oFontProcessor.getFontManager()); + } + //Scheme + if(rPr.m_oScheme.IsInit() && rPr.m_oScheme->m_oFontScheme.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFontTypes::Scheme); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE((BYTE)rPr.m_oScheme->m_oFontScheme->GetValue()); + } + //Strike + if(false != rPr.m_oStrike.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFontTypes::Strike); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(rPr.m_oStrike->m_oVal.ToBool()); + } + //Sz + if(false != rPr.m_oSz.IsInit() && rPr.m_oSz->m_oVal.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFontTypes::Sz); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Double); + m_oBcw.m_oStream.WriteDoubleReal(rPr.m_oSz->m_oVal->GetValue()); + } + //Underline + if(false != rPr.m_oUnderline.IsInit()) + { + SimpleTypes::Spreadsheet::EUnderline eType = SimpleTypes::Spreadsheet::underlineSingle; + if(rPr.m_oUnderline->m_oUnderline.IsInit()) + eType = rPr.m_oUnderline->m_oUnderline->GetValue(); + + m_oBcw.m_oStream.WriteBYTE(c_oSerFontTypes::Underline); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(eType); + } + //VertAlign + if(false != rPr.m_oVertAlign.IsInit() && rPr.m_oVertAlign->m_oVerticalAlign.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFontTypes::VertAlign); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(rPr.m_oVertAlign->m_oVerticalAlign->GetValue()); + } +} + + +BinaryWorkbookTableWriter::BinaryWorkbookTableWriter(NSBinPptxRW::CBinaryFileWriter &oCBufferedStream, OOX::Document *pDocument) +: m_oBcw(oCBufferedStream), m_pXlsx(NULL), m_pXlsxFlat(NULL) +{ + m_pXlsx = dynamic_cast(pDocument); + m_pXlsxFlat = dynamic_cast(pDocument); +} +void BinaryWorkbookTableWriter::Write(OOX::Spreadsheet::CWorkbook& workbook) +{ + int nStart = m_oBcw.WriteItemWithLengthStart(); + WriteWorkbook(workbook); + m_oBcw.WriteItemWithLengthEnd(nStart); +} +void BinaryWorkbookTableWriter::WriteWorkbook(OOX::Spreadsheet::CWorkbook& workbook) +{ + int nCurPos; +//WorkbookPr + if(workbook.m_oWorkbookPr.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::WorkbookPr); + WriteWorkbookPr(workbook.m_oWorkbookPr.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +//WorkbookProtection + if (workbook.m_oWorkbookProtection.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::Protection); + WriteProtection(workbook.m_oWorkbookProtection.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +//BookViews + if(workbook.m_oBookViews.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::BookViews); + WriteBookViews(workbook.m_oBookViews.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +//DefinedNames + if(workbook.m_oDefinedNames.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::DefinedNames); + WriteDefinedNames(workbook.m_oDefinedNames.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (workbook.m_oCalcPr.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::CalcPr); + WriteCalcPr(workbook.m_oCalcPr.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (workbook.m_oPivotCaches.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::PivotCaches); + WritePivotCaches(workbook, workbook.m_oPivotCaches.get()); + if (workbook.m_oExtLst.IsInit()) + { + for(size_t i = 0; i < workbook.m_oExtLst->m_arrExt.size(); ++i) + { + OOX::Drawing::COfficeArtExtension* pExt = workbook.m_oExtLst->m_arrExt[i]; + if ( pExt->m_oWorkbookPivotCaches.IsInit() ) + { + WritePivotCaches(workbook, pExt->m_oWorkbookPivotCaches.get()); + } + } + } + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +//ExternalReferences + if(workbook.m_oExternalReferences.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::ExternalReferences); + WriteExternalReferences(workbook.m_oExternalReferences.get(), workbook); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +//FileSharing + if (workbook.m_oFileSharing.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::FileSharing); + WriteFileSharing(workbook.m_oFileSharing.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +//Ext + if (workbook.m_oExtLst.IsInit()) + { + for(size_t i = 0; i < workbook.m_oExtLst->m_arrExt.size(); ++i) + { + OOX::Drawing::COfficeArtExtension* pExt = workbook.m_oExtLst->m_arrExt[i]; + if ( pExt->m_oSlicerCaches.IsInit() ) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::SlicerCaches); + WriteSlicerCaches(workbook, pExt->m_oSlicerCaches.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + else if ( pExt->m_oSlicerCachesExt.IsInit() ) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::SlicerCachesExt); + WriteSlicerCaches(workbook, pExt->m_oSlicerCachesExt.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + else if (pExt->m_oExternalLinksAutoRefresh.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::ExternalLinksAutoRefresh); + m_oBcw.m_oStream.WriteBOOL(*pExt->m_oExternalLinksAutoRefresh); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + else if (pExt->m_oTimelineCacheRefs.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::TimelineCaches); + WriteTimelineCaches(workbook, pExt->m_oTimelineCacheRefs.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + } + } +//Write VbaProject + if (m_pXlsx && NULL != m_pXlsx->m_pVbaProject) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::VbaProject); + + m_oBcw.m_oStream.StartRecord(0); + m_pXlsx->m_pVbaProject->toPPTY(&m_oBcw.m_oStream); + m_oBcw.m_oStream.EndRecord(); + + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +//Write JsaProject + if (m_pXlsx && NULL != m_pXlsx->m_pJsaProject) + { + if (m_pXlsx->m_pJsaProject->IsExist() && !m_pXlsx->m_pJsaProject->IsExternal()) + { + std::wstring pathJsa = m_pXlsx->m_pJsaProject->filename().GetPath(); + if (std::wstring::npos != pathJsa.find(m_pXlsx->m_sDocumentPath)) + { + BYTE* pData = NULL; + DWORD nBytesCount; + if (NSFile::CFileBinary::ReadAllBytes(m_pXlsx->m_pJsaProject->filename().GetPath(), &pData, nBytesCount)) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::JsaProject); + m_oBcw.m_oStream.WriteBYTEArray(pData, nBytesCount); + m_oBcw.WriteItemEnd(nCurPos); + RELEASEARRAYOBJECTS(pData); + } + } + } + if (m_pXlsx->m_pJsaProject->IsExternal()) + { + //nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::JsaProjectExternal); + //m_oBcw.m_oStream.WriteStringW3(m_pXlsx->m_pJsaProject->filename().GetPath()); + //m_oBcw.WriteItemEnd(nCurPos); + } + } +//Workbook Comments + if (m_pXlsx && NULL != m_pXlsx->m_pWorkbookComments) + { + BYTE* pData = NULL; + DWORD nBytesCount; + if(NSFile::CFileBinary::ReadAllBytes(m_pXlsx->m_pWorkbookComments->m_oReadPath.GetPath(), &pData, nBytesCount)) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::Comments); + m_oBcw.m_oStream.WriteBYTEArray(pData, nBytesCount); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + } + smart_ptr pFile = workbook.Find(OOX::Spreadsheet::FileTypes::Connections); + OOX::Spreadsheet::CConnectionsFile *pConnectionFile = dynamic_cast(pFile.GetPointer()); + if ((pConnectionFile) && (pConnectionFile->m_oConnections.IsInit())) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::Connections); + WriteConnections(pConnectionFile->m_oConnections.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (workbook.m_oAppName.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::AppName); + m_oBcw.m_oStream.WriteStringW3(*workbook.m_oAppName); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (workbook.m_oOleSize.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::OleSize); + m_oBcw.m_oStream.WriteStringW3(*workbook.m_oOleSize); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + pFile = workbook.Find(OOX::Spreadsheet::FileTypes::Metadata); + OOX::Spreadsheet::CMetadataFile* pMetadataFile = dynamic_cast(pFile.GetPointer()); + if ((pMetadataFile) && (pMetadataFile->m_oMetadata.IsInit())) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::Metadata); + WriteMetadata(pMetadataFile->m_oMetadata.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteFileSharing(const OOX::Spreadsheet::CFileSharing& fileSharing) +{ + if (fileSharing.m_oAlgorithmName.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFileSharing::AlgorithmName); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(fileSharing.m_oAlgorithmName->GetValue()); + } + if (fileSharing.m_oSpinCount.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFileSharing::SpinCount); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteULONG(fileSharing.m_oSpinCount->GetValue()); + } + if (fileSharing.m_oHashValue.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFileSharing::HashValue); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*fileSharing.m_oHashValue); + } + if (fileSharing.m_oSaltValue.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFileSharing::SaltValue); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*fileSharing.m_oSaltValue); + } + if (fileSharing.m_oPassword.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFileSharing::Password); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*fileSharing.m_oPassword); + } + if (fileSharing.m_oUserName.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFileSharing::UserName); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*fileSharing.m_oUserName); + } + if (fileSharing.m_oReadOnlyRecommended.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFileSharing::ReadOnly); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(*fileSharing.m_oReadOnlyRecommended); + } +} +void BinaryWorkbookTableWriter::WriteProtection(const OOX::Spreadsheet::CWorkbookProtection& protection) +{ + if (protection.m_oWorkbookAlgorithmName.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookProtection::AlgorithmName); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(protection.m_oWorkbookAlgorithmName->GetValue()); + } + if (protection.m_oWorkbookSpinCount.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookProtection::SpinCount); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteULONG(protection.m_oWorkbookSpinCount->GetValue()); + } + if (protection.m_oWorkbookHashValue.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookProtection::HashValue); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*protection.m_oWorkbookHashValue); + } + if (protection.m_oWorkbookSaltValue.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookProtection::SaltValue); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*protection.m_oWorkbookSaltValue); + } + if (protection.m_oLockStructure.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookProtection::LockStructure); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(protection.m_oLockStructure->ToBool()); + } + if (protection.m_oLockWindows.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookProtection::LockWindows); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(protection.m_oLockWindows->ToBool()); + } + if (protection.m_oPassword.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookProtection::Password); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*protection.m_oPassword); + } +} +void BinaryWorkbookTableWriter::WriteWorkbookPr(const OOX::Spreadsheet::CWorkbookPr& workbookPr) +{ +//Date1904 + if(workbookPr.m_oDate1904.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookPrTypes::Date1904); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(workbookPr.m_oDate1904->ToBool()); + } +//DateCompatibility + if(workbookPr.m_oDateCompatibility.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookPrTypes::DateCompatibility); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(workbookPr.m_oDateCompatibility->ToBool()); + } + if(workbookPr.m_oHidePivotFieldList.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookPrTypes::HidePivotFieldList); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(workbookPr.m_oHidePivotFieldList->ToBool()); + } + if(workbookPr.m_oShowPivotChartFilter.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookPrTypes::ShowPivotChartFilter); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(workbookPr.m_oShowPivotChartFilter->ToBool()); + } + if (workbookPr.m_oUpdateLinks.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookPrTypes::UpdateLinks); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(workbookPr.m_oUpdateLinks->GetValue()); + } +} +void BinaryWorkbookTableWriter::WriteConnectionTextFields(const OOX::Spreadsheet::CTextFields& textFields) +{ + for (size_t i = 0; i < textFields.m_arrItems.size(); ++i) + { + OOX::Spreadsheet::CTextField* pTextField = static_cast(textFields.m_arrItems[i]); + + int nCurPos = m_oBcw.WriteItemStart(c_oSerTextPrTypes::TextField); + WriteConnectionTextField(*pTextField); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteConnectionTextField(const OOX::Spreadsheet::CTextField& textField) +{ + int nCurPos; + if (textField.m_oType.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerTextPrTypes::TextFieldType); + m_oBcw.m_oStream.WriteLONG(textField.m_oType->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + + if (textField.m_oPosition.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerTextPrTypes::TextFieldPosition); + m_oBcw.m_oStream.WriteLONG(*textField.m_oPosition); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteBookViews(const OOX::Spreadsheet::CBookViews& bookViews) +{ + int nCurPos; + if (false == bookViews.m_arrItems.empty()) + { + OOX::Spreadsheet::CWorkbookView* pWorkbookView = static_cast(bookViews.m_arrItems[0]); + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::WorkbookView); + WriteWorkbookView(*pWorkbookView); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteWorkbookView(const OOX::Spreadsheet::CWorkbookView& workbookView) +{ +//ActiveTab + if (workbookView.m_oActiveTab.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookViewTypes::ActiveTab); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(workbookView.m_oActiveTab->GetValue()); + } + if (workbookView.m_oAutoFilterDateGrouping.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookViewTypes::AutoFilterDateGrouping); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(workbookView.m_oAutoFilterDateGrouping->ToBool()); + } + if (workbookView.m_oFirstSheet.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookViewTypes::FirstSheet); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(workbookView.m_oFirstSheet->GetValue()); + } + if (workbookView.m_oMinimized.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookViewTypes::Minimized); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(workbookView.m_oMinimized->ToBool()); + } + if (workbookView.m_oShowHorizontalScroll.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookViewTypes::ShowHorizontalScroll); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(workbookView.m_oShowHorizontalScroll->ToBool()); + } + if (workbookView.m_oShowSheetTabs.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookViewTypes::ShowSheetTabs); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(workbookView.m_oShowSheetTabs->ToBool()); + } + if (workbookView.m_oShowVerticalScroll.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookViewTypes::ShowVerticalScroll); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(workbookView.m_oShowVerticalScroll->ToBool()); + } + if (workbookView.m_oTabRatio.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookViewTypes::TabRatio); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(workbookView.m_oTabRatio->GetValue()); + } + if (workbookView.m_oVisibility.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookViewTypes::Visibility); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(workbookView.m_oVisibility->GetValue()); + } + if (workbookView.m_oWindowHeight.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookViewTypes::WindowHeight); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(workbookView.m_oWindowHeight->GetValue()); + } + if (workbookView.m_oWindowWidth.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookViewTypes::WindowWidth); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(workbookView.m_oWindowWidth->GetValue()); + } + if (workbookView.m_oXWindow.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookViewTypes::XWindow); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(workbookView.m_oXWindow->GetValue()); + } + if (workbookView.m_oYWindow.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorkbookViewTypes::YWindow); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(workbookView.m_oYWindow->GetValue()); + } +} +void BinaryWorkbookTableWriter::WriteDefinedNames(const OOX::Spreadsheet::CDefinedNames& definedNames) +{ + int nCurPos; + for(size_t i = 0, length = definedNames.m_arrItems.size(); i < length; ++i) + { + OOX::Spreadsheet::CDefinedName* pDefinedName = definedNames.m_arrItems[i]; + //DefinedName + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::DefinedName); + WriteDefinedName(*pDefinedName); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteCalcPr(const OOX::Spreadsheet::CCalcPr& CCalcPr) +{ + int nCurPos = 0; + if(CCalcPr.m_oCalcId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerCalcPrTypes::CalcId); + m_oBcw.m_oStream.WriteULONG(CCalcPr.m_oCalcId->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(CCalcPr.m_oCalcMode.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerCalcPrTypes::CalcMode); + m_oBcw.m_oStream.WriteBYTE((BYTE)CCalcPr.m_oCalcMode->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(CCalcPr.m_oFullCalcOnLoad.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerCalcPrTypes::FullCalcOnLoad); + m_oBcw.m_oStream.WriteBOOL(CCalcPr.m_oFullCalcOnLoad->ToBool()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(CCalcPr.m_oRefMode.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerCalcPrTypes::RefMode); + m_oBcw.m_oStream.WriteBYTE((BYTE)CCalcPr.m_oRefMode->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(CCalcPr.m_oIterate.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerCalcPrTypes::Iterate); + m_oBcw.m_oStream.WriteBOOL(CCalcPr.m_oIterate->ToBool()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(CCalcPr.m_oIterateCount.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerCalcPrTypes::IterateCount); + m_oBcw.m_oStream.WriteULONG(CCalcPr.m_oIterateCount->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(CCalcPr.m_oIterateDelta.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerCalcPrTypes::IterateDelta); + m_oBcw.m_oStream.WriteDoubleReal(CCalcPr.m_oIterateDelta->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(CCalcPr.m_oFullPrecision.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerCalcPrTypes::FullPrecision); + m_oBcw.m_oStream.WriteBOOL(CCalcPr.m_oFullPrecision->ToBool()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(CCalcPr.m_oCalcCompleted.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerCalcPrTypes::CalcCompleted); + m_oBcw.m_oStream.WriteBOOL(CCalcPr.m_oCalcCompleted->ToBool()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(CCalcPr.m_oCalcOnSave.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerCalcPrTypes::CalcOnSave); + m_oBcw.m_oStream.WriteBOOL(CCalcPr.m_oCalcOnSave->ToBool()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(CCalcPr.m_oConcurrentCalc.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerCalcPrTypes::ConcurrentCalc); + m_oBcw.m_oStream.WriteBOOL(CCalcPr.m_oConcurrentCalc->ToBool()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(CCalcPr.m_oConcurrentManualCount.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerCalcPrTypes::ConcurrentManualCount); + m_oBcw.m_oStream.WriteULONG(CCalcPr.m_oConcurrentManualCount->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(CCalcPr.m_oForceFullCalc.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerCalcPrTypes::ForceFullCalc); + m_oBcw.m_oStream.WriteBOOL(CCalcPr.m_oForceFullCalc->ToBool()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WritePivotCaches(OOX::Spreadsheet::CWorkbook& workbook, const OOX::Spreadsheet::CWorkbookPivotCaches& CPivotCaches) +{ + int nCurPos = 0; + for(size_t i = 0, length = CPivotCaches.m_arrItems.size(); i < length; ++i) + { + OOX::Spreadsheet::CWorkbookPivotCache* pivotCache = CPivotCaches.m_arrItems[i]; + //cache + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::PivotCache); + WritePivotCache(workbook, *pivotCache); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WritePivotCache(OOX::Spreadsheet::CWorkbook& workbook, const OOX::Spreadsheet::CWorkbookPivotCache& CPivotCache) +{ + int nCurPos = 0; + + if(CPivotCache.m_oCacheId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_PivotTypes::id); + m_oBcw.m_oStream.WriteULONG(CPivotCache.m_oCacheId->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(CPivotCache.m_oRid.IsInit()) + { + smart_ptr pFile = workbook.Find(OOX::RId(CPivotCache.m_oRid->GetValue())); + if (pFile.IsInit() && OOX::Spreadsheet::FileTypes::PivotCacheDefinition == pFile->type()) + { + auto pivotCacheFile = static_cast(pFile.GetPointer()); + if(pivotCacheFile->m_oPivotCashDefinition.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_PivotTypes::cache); + NSStringUtils::CStringBuilder writer; + pivotCacheFile->m_oPivotCashDefinition->toXML(writer); + auto wstringData = writer.GetData(); + m_oBcw.m_oStream.WriteStringUtf8(wstringData); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + auto records = pivotCacheFile->GetContainer(); + if(!records.empty()) + { + for(auto recordFile:records) + { + if(recordFile.IsInit() && OOX::Spreadsheet::FileTypes::PivotCacheRecords == recordFile->type()) + { + auto record = static_cast(recordFile.GetPointer()); + nCurPos = m_oBcw.WriteItemStart(c_oSer_PivotTypes::record); + m_oBcw.m_oStream.WriteBYTEArray(record->m_pData, record->m_nDataLength); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + } + } + } + } + +} +void BinaryWorkbookTableWriter::WriteConnections(const OOX::Spreadsheet::CConnections& connections) +{ + for (size_t i = 0; i < connections.m_arrItems.size(); ++i) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSerConnectionsTypes::Connection); + WriteConnection(*connections.m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteConnection(const OOX::Spreadsheet::CConnection& connection) +{ + int nCurPos = 0; + if(connection.m_oType.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerConnectionsTypes::Type); + m_oBcw.m_oStream.WriteULONG(*connection.m_oType); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(connection.m_oName.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerConnectionsTypes::Name); + m_oBcw.m_oStream.WriteStringW(*connection.m_oName); + } + if(connection.m_oId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerConnectionsTypes::Id); + m_oBcw.m_oStream.WriteULONG(connection.m_oId->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (connection.m_oUId.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerConnectionsTypes::UId); + m_oBcw.m_oStream.WriteStringW(*connection.m_oUId); + } + if(connection.m_oCredentials.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerConnectionsTypes::Credentials); + m_oBcw.m_oStream.WriteULONG(connection.m_oCredentials->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(connection.m_oBackground.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerConnectionsTypes::Background); + m_oBcw.m_oStream.WriteBYTE(*connection.m_oBackground ? 1 : 0); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(connection.m_oDeleted.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerConnectionsTypes::Deleted); + m_oBcw.m_oStream.WriteBYTE(*connection.m_oDeleted ? 1 : 0); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(connection.m_oDescription.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerConnectionsTypes::Description); + m_oBcw.m_oStream.WriteStringW(*connection.m_oDescription); + } + if(connection.m_oInterval.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerConnectionsTypes::Interval); + m_oBcw.m_oStream.WriteLONG(*connection.m_oInterval); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(connection.m_oKeepAlive.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerConnectionsTypes::KeepAlive); + m_oBcw.m_oStream.WriteBYTE(*connection.m_oKeepAlive ? 1 : 0); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(connection.m_oMinRefreshableVersion.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerConnectionsTypes::MinRefreshableVersion); + m_oBcw.m_oStream.WriteLONG(*connection.m_oMinRefreshableVersion); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(connection.m_oNew.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerConnectionsTypes::New); + m_oBcw.m_oStream.WriteBYTE(*connection.m_oNew ? 1 : 0); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(connection.m_oOdcFile.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerConnectionsTypes::OdcFile); + m_oBcw.m_oStream.WriteStringW(*connection.m_oOdcFile); + } + if(connection.m_oOdcFile.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerConnectionsTypes::OdcFile); + m_oBcw.m_oStream.WriteStringW(*connection.m_oOdcFile); + } + if(connection.m_oOnlyUseConnectionFile.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerConnectionsTypes::OnlyUseConnectionFile); + m_oBcw.m_oStream.WriteBYTE(*connection.m_oOnlyUseConnectionFile ? 1 : 0); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(connection.m_oReconnectionMethod.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerConnectionsTypes::ReconnectionMethod); + m_oBcw.m_oStream.WriteLONG(*connection.m_oReconnectionMethod); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(connection.m_oRefreshedVersion.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerConnectionsTypes::RefreshedVersion); + m_oBcw.m_oStream.WriteLONG(*connection.m_oRefreshedVersion); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(connection.m_oRefreshOnLoad.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerConnectionsTypes::RefreshOnLoad); + m_oBcw.m_oStream.WriteBYTE(*connection.m_oRefreshOnLoad ? 1 : 0); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(connection.m_oSaveData.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerConnectionsTypes::SaveData); + m_oBcw.m_oStream.WriteBYTE(*connection.m_oSaveData ? 1 : 0); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(connection.m_oSavePassword.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerConnectionsTypes::SavePassword); + m_oBcw.m_oStream.WriteBYTE(*connection.m_oSavePassword ? 1 : 0); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(connection.m_oSingleSignOnId.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerConnectionsTypes::SingleSignOnId); + m_oBcw.m_oStream.WriteStringW(*connection.m_oSingleSignOnId); + } + if(connection.m_oSourceFile.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerConnectionsTypes::SourceFile); + m_oBcw.m_oStream.WriteStringW(*connection.m_oSourceFile); + } + if(connection.m_oDbPr.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerConnectionsTypes::DbPr); + WriteConnectionDbPr(connection.m_oDbPr.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(connection.m_oOlapPr.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerConnectionsTypes::OlapPr); + WriteConnectionOlapPr(connection.m_oOlapPr.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(connection.m_oTextPr.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerConnectionsTypes::TextPr); + WriteConnectionTextPr(connection.m_oTextPr.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(connection.m_oWebPr.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerConnectionsTypes::WebPr); + WriteConnectionWebPr(connection.m_oWebPr.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(connection.m_oExtLst.IsInit()) + { + for (size_t i = 0; i < connection.m_oExtLst->m_arrExt.size(); ++i) + { + if (connection.m_oExtLst->m_arrExt[i]->m_oConnection.IsInit()) + { + if(connection.m_oExtLst->m_arrExt[i]->m_oConnection->m_oIdExt.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerConnectionsTypes::IdExt); + m_oBcw.m_oStream.WriteStringW(*connection.m_oExtLst->m_arrExt[i]->m_oConnection->m_oIdExt); + } + if (connection.m_oExtLst->m_arrExt[i]->m_oConnection->m_oRangePr.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerConnectionsTypes::RangePr); + WriteConnectionRangePr(connection.m_oExtLst->m_arrExt[i]->m_oConnection->m_oRangePr.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + } + } + } +} +void BinaryWorkbookTableWriter::WriteConnectionDbPr(const OOX::Spreadsheet::CDbPr& dbPr) +{ + int nCurPos = 0; + if(dbPr.m_oConnection.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerDbPrTypes::Connection); + m_oBcw.m_oStream.WriteStringW(*dbPr.m_oConnection); + } + if(dbPr.m_oCommand.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerDbPrTypes::Command); + m_oBcw.m_oStream.WriteStringW(*dbPr.m_oCommand); + } + if(dbPr.m_oCommandType.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerDbPrTypes::CommandType); + m_oBcw.m_oStream.WriteLONG(*dbPr.m_oCommandType); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(dbPr.m_oServerCommand.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerDbPrTypes::ServerCommand); + m_oBcw.m_oStream.WriteStringW(*dbPr.m_oServerCommand); + } +} +void BinaryWorkbookTableWriter::WriteConnectionOlapPr(const OOX::Spreadsheet::COlapPr& olapPr) +{ + int nCurPos = 0; + if(olapPr.m_oLocalConnection.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerOlapPrTypes::LocalConnection); + m_oBcw.m_oStream.WriteStringW(*olapPr.m_oLocalConnection); + } + if(olapPr.m_oRowDrillCount.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerOlapPrTypes::RowDrillCount); + m_oBcw.m_oStream.WriteLONG(*olapPr.m_oRowDrillCount); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(olapPr.m_oLocal.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerOlapPrTypes::Local); + m_oBcw.m_oStream.WriteBYTE(*olapPr.m_oLocal ? 1 : 0); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(olapPr.m_oLocalRefresh.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerOlapPrTypes::LocalRefresh); + m_oBcw.m_oStream.WriteBYTE(*olapPr.m_oLocalRefresh ? 1 : 0); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(olapPr.m_oSendLocale.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerOlapPrTypes::SendLocale); + m_oBcw.m_oStream.WriteBYTE(*olapPr.m_oSendLocale ? 1 : 0); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(olapPr.m_oServerNumberFormat.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerOlapPrTypes::ServerNumberFormat); + m_oBcw.m_oStream.WriteBYTE(*olapPr.m_oServerNumberFormat ? 1 : 0); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(olapPr.m_oServerFont.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerOlapPrTypes::ServerFont); + m_oBcw.m_oStream.WriteBYTE(*olapPr.m_oServerFont ? 1 : 0); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(olapPr.m_oServerFontColor.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerOlapPrTypes::ServerFontColor); + m_oBcw.m_oStream.WriteBYTE(*olapPr.m_oServerFontColor ? 1 : 0); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteConnectionTextPr(const OOX::Spreadsheet::CTextPr& textPr) +{ + int nCurPos = 0; + if(textPr.m_oCharacterSet.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerTextPrTypes::CharacterSet); + m_oBcw.m_oStream.WriteStringW(*textPr.m_oCharacterSet); + } + if(textPr.m_oSourceFile.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerTextPrTypes::SourceFile); + m_oBcw.m_oStream.WriteStringW(*textPr.m_oSourceFile); + } + if(textPr.m_oDecimal.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerTextPrTypes::Decimal); + m_oBcw.m_oStream.WriteStringW(*textPr.m_oDecimal); + } + if(textPr.m_oDelimiter.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerTextPrTypes::Decimal); + m_oBcw.m_oStream.WriteStringW(*textPr.m_oDelimiter); + } + if(textPr.m_oThousands.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerTextPrTypes::Thousands); + m_oBcw.m_oStream.WriteStringW(*textPr.m_oThousands); + } + if(textPr.m_oFirstRow.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerTextPrTypes::FirstRow); + m_oBcw.m_oStream.WriteLONG(*textPr.m_oFirstRow); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(textPr.m_oQualifier.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerTextPrTypes::Qualifier); + m_oBcw.m_oStream.WriteLONG(textPr.m_oQualifier->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(textPr.m_oFileType.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerTextPrTypes::FileType); + m_oBcw.m_oStream.WriteLONG(textPr.m_oFileType->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(textPr.m_oPrompt.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerTextPrTypes::Prompt); + m_oBcw.m_oStream.WriteBYTE(*textPr.m_oPrompt ? 1 : 0); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(textPr.m_oDelimited.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerTextPrTypes::Delimited); + m_oBcw.m_oStream.WriteBYTE(*textPr.m_oDelimited ? 1 : 0); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(textPr.m_oTab.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerTextPrTypes::Tab); + m_oBcw.m_oStream.WriteBYTE(*textPr.m_oTab ? 1 : 0); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(textPr.m_oSpace.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerTextPrTypes::Space); + m_oBcw.m_oStream.WriteBYTE(*textPr.m_oSpace ? 1 : 0); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(textPr.m_oComma.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerTextPrTypes::Comma); + m_oBcw.m_oStream.WriteBYTE(*textPr.m_oComma ? 1 : 0); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(textPr.m_oSemicolon.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerTextPrTypes::Semicolon); + m_oBcw.m_oStream.WriteBYTE(*textPr.m_oSemicolon ? 1 : 0); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(textPr.m_oConsecutive.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerTextPrTypes::Consecutive); + m_oBcw.m_oStream.WriteBYTE(*textPr.m_oConsecutive ? 1 : 0); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (textPr.m_oCodePage.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerTextPrTypes::CodePage); + m_oBcw.m_oStream.WriteLONG(*textPr.m_oCodePage); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (textPr.m_oTextFields.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerTextPrTypes::TextFields); + WriteConnectionTextFields(textPr.m_oTextFields.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteConnectionRangePr(const OOX::Spreadsheet::CRangePr& rangePr) +{ + int nCurPos = 0; + if (rangePr.m_oSourceName.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerRangePrTypes::SourceName); + m_oBcw.m_oStream.WriteStringW(*rangePr.m_oSourceName); + } +} +void BinaryWorkbookTableWriter::WriteConnectionWebPr(const OOX::Spreadsheet::CWebPr& webPr) +{ + int nCurPos = 0; + if (webPr.m_oUrl.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSerWebPrTypes::Url); + m_oBcw.m_oStream.WriteStringW3(*webPr.m_oUrl); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (webPr.m_oPost.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSerWebPrTypes::Post); + m_oBcw.m_oStream.WriteStringW3(*webPr.m_oPost); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (webPr.m_oEditPage.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSerWebPrTypes::EditPage); + m_oBcw.m_oStream.WriteStringW3(*webPr.m_oEditPage); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (webPr.m_oXml.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSerWebPrTypes::Xml); + m_oBcw.m_oStream.WriteBOOL(*webPr.m_oXml); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (webPr.m_oSourceData.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSerWebPrTypes::SourceData); + m_oBcw.m_oStream.WriteBOOL(*webPr.m_oSourceData); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (webPr.m_oConsecutive.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSerWebPrTypes::Consecutive); + m_oBcw.m_oStream.WriteBOOL(*webPr.m_oConsecutive); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (webPr.m_oFirstRow.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSerWebPrTypes::FirstRow); + m_oBcw.m_oStream.WriteBOOL(*webPr.m_oFirstRow); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (webPr.m_oXl97.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSerWebPrTypes::Xl97); + m_oBcw.m_oStream.WriteBOOL(*webPr.m_oXl97); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (webPr.m_oTextDates.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSerWebPrTypes::TextDates); + m_oBcw.m_oStream.WriteBOOL(*webPr.m_oTextDates); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (webPr.m_oXl2000.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSerWebPrTypes::Xl2000); + m_oBcw.m_oStream.WriteBOOL(*webPr.m_oXl2000); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (webPr.m_oHtmlTables.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSerWebPrTypes::HtmlTables); + m_oBcw.m_oStream.WriteBOOL(*webPr.m_oHtmlTables); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (webPr.m_oHtmlFormat.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSerWebPrTypes::HtmlFormat); + m_oBcw.m_oStream.WriteLONG(webPr.m_oHtmlFormat->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteExternalReferences(const OOX::Spreadsheet::CExternalReferences& externalReferences, OOX::Spreadsheet::CWorkbook& workbook) +{ + for (size_t i = 0, length = externalReferences.m_arrItems.size(); i < length; ++i) + { + OOX::Spreadsheet::CExternalReference* pExternalReference = externalReferences.m_arrItems[i]; + if (!pExternalReference) continue; + + if (false == pExternalReference->m_oRid.IsInit()) continue; + + OOX::Spreadsheet::CExternalLink* pExternalLink = NULL; + + smart_ptr pFile = workbook.Find(OOX::RId(pExternalReference->m_oRid->GetValue())); + + if (pFile.IsInit() && OOX::Spreadsheet::FileTypes::ExternalLinks == pFile->type()) + pExternalLink = static_cast(pFile.operator ->()); + + if (!pExternalLink) continue; + + int nCurPos2 = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::ExternalReference); + + if (pExternalLink->m_oFileKey.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::ExternalFileKey); + m_oBcw.m_oStream.WriteStringW3(*pExternalLink->m_oFileKey); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pExternalLink->m_oInstanceId.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::ExternalInstanceId); + m_oBcw.m_oStream.WriteStringW3(*pExternalLink->m_oInstanceId); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pExternalLink->m_oExternalBook.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::ExternalBook); + WriteExternalBook(pExternalLink->m_oExternalBook.get(), pExternalLink); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + else if (pExternalLink->m_oOleLink.IsInit()) + { + std::wstring sLink; + if (pExternalLink->m_oOleLink->m_oRid.IsInit()) + { + smart_ptr pFile = pExternalLink->Find(OOX::RId(pExternalLink->m_oOleLink->m_oRid.get().GetValue())); + if (pFile.IsInit() && OOX::FileTypes::OleObject == pFile->type()) + { + smart_ptr pLinkFile = pFile.smart_dynamic_cast(); + if (pLinkFile.IsInit()) + { + sLink = pLinkFile->filename().GetPath(); + } + } + } + if (!sLink.empty()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::OleLink); + WriteOleLink(pExternalLink->m_oOleLink.get(), sLink); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + } + else if (pExternalLink->m_oDdeLink.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::DdeLink); + WriteDdeLink(pExternalLink->m_oDdeLink.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + + m_oBcw.WriteItemWithLengthEnd(nCurPos2); + } +} +void BinaryWorkbookTableWriter::WriteExternalBook(const OOX::Spreadsheet::CExternalBook& externalBook, OOX::Spreadsheet::CExternalLink* pExternalLink) +{ + int nCurPos = 0; + + if (pExternalLink && externalBook.m_oRid.IsInit()) + { + smart_ptr pFile = pExternalLink->Find(OOX::RId(externalBook.m_oRid.get().GetValue())); + if (pFile.IsInit() && OOX::FileTypes::ExternalLinkPath == pFile->type()) + { + OOX::Spreadsheet::ExternalLinkPath* pLinkFile = static_cast(pFile.operator ->()); + + nCurPos = m_oBcw.WriteItemStart(c_oSer_ExternalLinkTypes::Id); + m_oBcw.m_oStream.WriteStringW3(pLinkFile->Uri().GetPath()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + } + if (externalBook.m_oSheetNames.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ExternalLinkTypes::SheetNames); + WriteExternalSheetNames(externalBook.m_oSheetNames.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (externalBook.m_oDefinedNames.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ExternalLinkTypes::DefinedNames); + WriteExternalDefinedNames(externalBook.m_oDefinedNames.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (externalBook.m_oSheetDataSet.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ExternalLinkTypes::SheetDataSet); + WriteExternalSheetDataSet(externalBook.m_oSheetDataSet.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (externalBook.m_oAlternateUrls.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ExternalLinkTypes::AlternateUrls); + WriteExternalAlternateUrls(externalBook.m_oAlternateUrls.get(), pExternalLink); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteExternalAlternateUrls(const OOX::Spreadsheet::CAlternateUrls& alternateUrls, OOX::Spreadsheet::CExternalLink* pExternalLink) +{ + int nCurPos = 0; + if (alternateUrls.m_oDriveId.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_ExternalLinkTypes::ExternalAlternateUrlsDriveId); + m_oBcw.m_oStream.WriteStringW3(*alternateUrls.m_oDriveId); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (alternateUrls.m_oItemId.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_ExternalLinkTypes::ExternalAlternateUrlsItemId); + m_oBcw.m_oStream.WriteStringW3(*alternateUrls.m_oItemId); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pExternalLink && alternateUrls.m_oAbsoluteUrlRid.IsInit()) + { + smart_ptr pFile = pExternalLink->Find(OOX::RId(alternateUrls.m_oAbsoluteUrlRid.get().GetValue())); + if (pFile.IsInit() && OOX::FileTypes::ExternalLinkPath == pFile->type()) + { + OOX::Spreadsheet::ExternalLinkPath* pLinkFile = static_cast(pFile.operator ->()); + + nCurPos = m_oBcw.WriteItemStart(c_oSer_ExternalLinkTypes::AbsoluteUrl); + m_oBcw.m_oStream.WriteStringW3(pLinkFile->Uri().GetPath()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + } + if (pExternalLink && alternateUrls.m_oRelativeUrlRid.IsInit()) + { + smart_ptr pFile = pExternalLink->Find(OOX::RId(alternateUrls.m_oRelativeUrlRid.get().GetValue())); + if (pFile.IsInit() && OOX::FileTypes::ExternalLinkPath == pFile->type()) + { + OOX::Spreadsheet::ExternalLinkPath* pLinkFile = static_cast(pFile.operator ->()); + + nCurPos = m_oBcw.WriteItemStart(c_oSer_ExternalLinkTypes::RelativeUrl); + m_oBcw.m_oStream.WriteStringW3(pLinkFile->Uri().GetPath()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + } +} +void BinaryWorkbookTableWriter::WriteExternalSheetNames(const OOX::Spreadsheet::CExternalSheetNames& sheetNames) +{ + int nCurPos = 0; + for (size_t i = 0, length = sheetNames.m_arrItems.size(); i < length; ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ExternalLinkTypes::SheetName); + m_oBcw.m_oStream.WriteStringW3(sheetNames.m_arrItems[i]->ToString2()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteExternalDefinedNames(const OOX::Spreadsheet::CExternalDefinedNames& definedNames) +{ + int nCurPos = 0; + for (size_t i = 0, length = definedNames.m_arrItems.size(); i < length; ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ExternalLinkTypes::DefinedName); + WriteExternalDefinedName(*definedNames.m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteExternalDefinedName(const OOX::Spreadsheet::CExternalDefinedName& definedName) +{ + int nCurPos = 0; + if (definedName.m_oName.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ExternalLinkTypes::DefinedNameName); + m_oBcw.m_oStream.WriteStringW3(definedName.m_oName.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (definedName.m_oRefersTo.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ExternalLinkTypes::DefinedNameRefersTo); + m_oBcw.m_oStream.WriteStringW3(definedName.m_oRefersTo.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (definedName.m_oSheetId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ExternalLinkTypes::DefinedNameSheetId); + m_oBcw.m_oStream.WriteULONG(definedName.m_oSheetId->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteExternalSheetDataSet(const OOX::Spreadsheet::CExternalSheetDataSet& sheetDataSet) +{ + int nCurPos = 0; + for (size_t i = 0, length = sheetDataSet.m_arrItems.size(); i < length; ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ExternalLinkTypes::SheetData); + WriteExternalSheetData(*sheetDataSet.m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteExternalSheetData(const OOX::Spreadsheet::CExternalSheetData& sheetData) +{ + int nCurPos = 0; + if(sheetData.m_oSheetId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ExternalLinkTypes::SheetDataSheetId); + m_oBcw.m_oStream.WriteULONG(sheetData.m_oSheetId->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(sheetData.m_oRefreshError.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ExternalLinkTypes::SheetDataRefreshError); + m_oBcw.m_oStream.WriteBOOL(sheetData.m_oRefreshError->ToBool()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + for (size_t i = 0, length = sheetData.m_arrItems.size(); i < length; ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ExternalLinkTypes::SheetDataRow); + WriteExternalRow(*sheetData.m_arrItems[i]); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteExternalRow(const OOX::Spreadsheet::CExternalRow& row) +{ + int nCurPos = 0; + if(row.m_oR.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ExternalLinkTypes::SheetDataRowR); + m_oBcw.m_oStream.WriteULONG(row.m_oR->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + for (size_t i = 0, length = row.m_arrItems.size(); i < length; ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ExternalLinkTypes::SheetDataRowCell); + WriteExternalCell(*row.m_arrItems[i]); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteExternalCell(const OOX::Spreadsheet::CExternalCell& cell) +{ + int nCurPos = 0; + if(cell.m_oRef.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ExternalLinkTypes::SheetDataRowCellRef); + m_oBcw.m_oStream.WriteStringW3(cell.m_oRef.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(cell.m_oType.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ExternalLinkTypes::SheetDataRowCellType); + m_oBcw.m_oStream.WriteBYTE(cell.m_oType->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(cell.m_oValue.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ExternalLinkTypes::SheetDataRowCellValue); + m_oBcw.m_oStream.WriteStringW3(cell.m_oValue->ToString()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (cell.m_oValueMetadata.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ExternalLinkTypes::ValueMetadata); + m_oBcw.m_oStream.WriteULONG(*cell.m_oValueMetadata); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteOleLink(const OOX::Spreadsheet::COleLink& oleLink, const std::wstring& sLink) +{ + int nCurPos = 0; + nCurPos = m_oBcw.WriteItemStart(c_oSer_OleLinkTypes::Id); + m_oBcw.m_oStream.WriteStringW3(sLink); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + + if (oleLink.m_oProgId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_OleLinkTypes::ProgId); + m_oBcw.m_oStream.WriteStringW3(oleLink.m_oProgId.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (oleLink.m_oOleItems.IsInit()) + { + for(size_t i = 0; i < oleLink.m_oOleItems->m_arrItems.size(); ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_OleLinkTypes::OleItem); + WriteOleItem(*oleLink.m_oOleItems->m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + } +} +void BinaryWorkbookTableWriter::WriteOleItem(const OOX::Spreadsheet::COleItem& oleItem) +{ + int nCurPos = 0; + if (oleItem.m_oName.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_OleLinkTypes::Name); + m_oBcw.m_oStream.WriteStringW3(oleItem.m_oName.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (oleItem.m_oIcon.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_OleLinkTypes::Icon); + m_oBcw.m_oStream.WriteBOOL(oleItem.m_oIcon->ToBool()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (oleItem.m_oAdvise.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_OleLinkTypes::Advise); + m_oBcw.m_oStream.WriteBOOL(oleItem.m_oAdvise->ToBool()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (oleItem.m_oPreferPic.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_OleLinkTypes::PreferPic); + m_oBcw.m_oStream.WriteBOOL(oleItem.m_oPreferPic->ToBool()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteDdeLink(const OOX::Spreadsheet::CDdeLink& ddeLink) +{ + int nCurPos = 0; + if (ddeLink.m_oDdeService.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::DdeService); + m_oBcw.m_oStream.WriteStringW3(ddeLink.m_oDdeService.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (ddeLink.m_oDdeTopic.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::DdeTopic); + m_oBcw.m_oStream.WriteStringW3(ddeLink.m_oDdeTopic.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (ddeLink.m_oDdeItems.IsInit()) + { + for(size_t i = 0; i < ddeLink.m_oDdeItems->m_arrItems.size(); ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::DdeItem); + WriteDdeItem(*ddeLink.m_oDdeItems->m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + } +} +void BinaryWorkbookTableWriter::WriteDdeItem(const OOX::Spreadsheet::CDdeItem& ddeItem) +{ + int nCurPos = 0; + if (ddeItem.m_oName.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::Name); + m_oBcw.m_oStream.WriteStringW3(ddeItem.m_oName.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (ddeItem.m_oOle.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::Ole); + m_oBcw.m_oStream.WriteBOOL(ddeItem.m_oOle->ToBool()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (ddeItem.m_oAdvise.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::Advise); + m_oBcw.m_oStream.WriteBOOL(ddeItem.m_oAdvise->ToBool()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (ddeItem.m_oPreferPic.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::PreferPic); + m_oBcw.m_oStream.WriteBOOL(ddeItem.m_oPreferPic->ToBool()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (ddeItem.m_oDdeValues.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::DdeValues); + WriteDdeValues(ddeItem.m_oDdeValues.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteDdeValues(const OOX::Spreadsheet::CDdeValues& ddeValues) +{ + int nCurPos = 0; + if (ddeValues.m_oRows.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::DdeValuesRows); + m_oBcw.m_oStream.WriteULONG(ddeValues.m_oRows->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (ddeValues.m_oCols.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::DdeValuesCols); + m_oBcw.m_oStream.WriteULONG(ddeValues.m_oCols->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + for(size_t i = 0; i < ddeValues.m_arrItems.size(); ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::DdeValue); + WriteDdeValue(*ddeValues.m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteDdeValue(const OOX::Spreadsheet::CDdeValue& ddeValue) +{ + int nCurPos = 0; + if (ddeValue.m_oType.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::DdeValueType); + m_oBcw.m_oStream.WriteBYTE(ddeValue.m_oType->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + for (size_t i = 0; i < ddeValue.m_arrItems.size(); ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DdeLinkTypes::DdeValueVal); + m_oBcw.m_oStream.WriteStringW3(ddeValue.m_arrItems[i]->ToString()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteDefinedName(const OOX::Spreadsheet::CDefinedName& definedName) +{ + int nCurPos = 0; + //Name + if(definedName.m_oName.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerDefinedNameTypes::Name); + m_oBcw.m_oStream.WriteStringW(*definedName.m_oName); + } + //Ref + if(definedName.m_oRef.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerDefinedNameTypes::Ref); + m_oBcw.m_oStream.WriteStringW(*definedName.m_oRef); + } + //LocalSheetId + if(definedName.m_oLocalSheetId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerDefinedNameTypes::LocalSheetId); + m_oBcw.m_oStream.WriteLONG(definedName.m_oLocalSheetId->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + //Hidden + if(definedName.m_oHidden.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerDefinedNameTypes::Hidden); + m_oBcw.m_oStream.WriteBOOL(definedName.m_oHidden->ToBool()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + //Comment + if (definedName.m_oComment.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerDefinedNameTypes::Comment); + m_oBcw.m_oStream.WriteStringW(*definedName.m_oComment); + } +} +void BinaryWorkbookTableWriter::WriteTimelineCaches(OOX::Spreadsheet::CWorkbook& workbook, const OOX::Spreadsheet::CTimelineCacheRefs& oTimelineCacheRefs) +{ + int nCurPos = 0; + for (size_t i = 0; i < oTimelineCacheRefs.m_arrItems.size(); ++i) + { + if (oTimelineCacheRefs.m_arrItems[i] && oTimelineCacheRefs.m_arrItems[i]->m_oRId.IsInit()) + { + smart_ptr pFile = workbook.Find(OOX::RId(oTimelineCacheRefs.m_arrItems[i]->m_oRId->GetValue())); + if (pFile.IsInit() && OOX::Spreadsheet::FileTypes::TimelineCache == pFile->type()) + { + OOX::Spreadsheet::CTimelineCacheFile* pTimelineCacheFile = static_cast(pFile.GetPointer()); + if (pTimelineCacheFile->m_oTimelineCacheDefinition.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::TimelineCache); + WriteTimelineCache(pTimelineCacheFile->m_oTimelineCacheDefinition.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + } + } + } + +} +void BinaryWorkbookTableWriter::WriteTimelineCache(OOX::Spreadsheet::CTimelineCacheDefinition* pTimelineCache) +{ + if (!pTimelineCache) return; + + int nCurPos = 0; + if (pTimelineCache->m_oName.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineCache::Name); + m_oBcw.m_oStream.WriteStringW3(*pTimelineCache->m_oName); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pTimelineCache->m_oSourceName.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineCache::SourceName); + m_oBcw.m_oStream.WriteStringW3(*pTimelineCache->m_oSourceName); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pTimelineCache->m_oUid.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineCache::Uid); + m_oBcw.m_oStream.WriteStringW3(*pTimelineCache->m_oUid); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pTimelineCache->m_oPivotTables.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineCache::PivotTables); + WriteTimelineCachePivotTables(pTimelineCache->m_oPivotTables.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pTimelineCache->m_oPivotFilter.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineCache::PivotFilter); + WriteTimelinePivotFilter(pTimelineCache->m_oPivotFilter.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pTimelineCache->m_oState.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineCache::State); + WriteTimelineState(pTimelineCache->m_oState.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteTimelineState(OOX::Spreadsheet::CTimelineState* pState) +{ + if (!pState) return; + + int nCurPos = 0; + if (pState->m_oName.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineState::Name); + m_oBcw.m_oStream.WriteStringW3(*pState->m_oName); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pState->m_oSingleRangeFilterState.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineState::FilterState); + m_oBcw.m_oStream.WriteBOOL(*pState->m_oSingleRangeFilterState); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pState->m_oPivotCacheId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineState::PivotCacheId); + m_oBcw.m_oStream.WriteLONG(*pState->m_oPivotCacheId); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pState->m_oMinimalRefreshVersion.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineState::MinimalRefreshVersion); + m_oBcw.m_oStream.WriteLONG(*pState->m_oMinimalRefreshVersion); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pState->m_oLastRefreshVersion.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineState::LastRefreshVersion); + m_oBcw.m_oStream.WriteLONG(*pState->m_oLastRefreshVersion); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pState->m_oFilterType.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineState::FilterType); + m_oBcw.m_oStream.WriteStringW3(*pState->m_oFilterType); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pState->m_oSelection.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineState::Selection); + WriteTimelineRange(pState->m_oSelection.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pState->m_oBounds.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineState::Bounds); + WriteTimelineRange(pState->m_oBounds.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMetadata(OOX::Spreadsheet::CMetadata* pMetadata) +{ + if (!pMetadata) return; + + int nCurPos = 0; + if (pMetadata->m_oMetadataTypes.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Metadata::MetadataTypes); + WriteMetadataTypes(pMetadata->m_oMetadataTypes.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadata->m_oMetadataTypes.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Metadata::MetadataStrings); + WriteMetadataStrings(pMetadata->m_oMetadataStrings.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadata->m_oMdxMetadata.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Metadata::MdxMetadata); + WriteMdxMetadata(pMetadata->m_oMdxMetadata.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadata->m_oCellMetadata.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Metadata::CellMetadata); + WriteMetadataBlocks(pMetadata->m_oCellMetadata.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadata->m_oValueMetadata.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Metadata::ValueMetadata); + WriteMetadataBlocks(pMetadata->m_oValueMetadata.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + for (size_t i = 0; i < pMetadata->m_arFutureMetadata.size(); ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Metadata::FutureMetadata); + WriteFutureMetadata(pMetadata->m_arFutureMetadata[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMetadataTypes(OOX::Spreadsheet::CMetadataTypes* pMetadataTypes) +{ + if (!pMetadataTypes) return; + + for (size_t i = 0; i < pMetadataTypes->m_arrItems.size(); ++i) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::MetadataType); + WriteMetadataType(pMetadataTypes->m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMetadataType(OOX::Spreadsheet::CMetadataType* pMetadataType) +{ + if (!pMetadataType) return; + + if (pMetadataType->m_oName.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::Name); + m_oBcw.m_oStream.WriteStringW3(*pMetadataType->m_oName); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oMinSupportedVersion.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::MinSupportedVersion); + m_oBcw.m_oStream.WriteULONG(*pMetadataType->m_oMinSupportedVersion); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oGhostRow.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::GhostRow); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oGhostRow); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oGhostCol.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::GhostCol); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oGhostCol); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oEdit.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::Edit); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oEdit); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oDelete.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::Delete); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oDelete); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oCopy.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::Copy); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oCopy); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oPasteAll.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::PasteAll); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oPasteAll); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oPasteFormulas.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::PasteFormulas); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oPasteFormulas); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oPasteValues.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::PasteValues); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oPasteValues); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oPasteFormats.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::PasteFormats); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oPasteFormats); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oPasteComments.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::PasteComments); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oPasteComments); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oPasteDataValidation.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::PasteDataValidation); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oPasteDataValidation); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oPasteBorders.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::PasteBorders); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oPasteBorders); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oPasteColWidths.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::PasteColWidths); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oPasteColWidths); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oPasteNumberFormats.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::PasteNumberFormats); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oPasteNumberFormats); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oMerge.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::Merge); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oMerge); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oSplitFirst.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::SplitFirst); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oSplitFirst); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oSplitAll.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::SplitAll); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oSplitAll); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oRowColShift.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::RowColShift); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oRowColShift); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oClearAll.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::ClearAll); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oClearAll); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oClearFormats.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::ClearFormats); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oClearFormats); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oClearContents.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::ClearContents); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oClearContents); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oClearComments.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::ClearComments); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oClearComments); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oAssign.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::Assign); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oAssign); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oCoerce.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::Coerce); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oCoerce); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataType->m_oCellMeta.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataType::CellMeta); + m_oBcw.m_oStream.WriteBOOL(*pMetadataType->m_oCellMeta); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMetadataStrings(OOX::Spreadsheet::CMetadataStrings* pMetadataStrings) +{ + if (!pMetadataStrings) return; + + for (size_t i = 0; i < pMetadataStrings->m_arrItems.size(); ++i) + { + if ((pMetadataStrings->m_arrItems[i]) && (pMetadataStrings->m_arrItems[i]->m_oV.IsInit())) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataString::MetadataString); + m_oBcw.m_oStream.WriteStringW3(pMetadataStrings->m_arrItems[i]->m_oV.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + } +} +void BinaryWorkbookTableWriter::WriteMdxMetadata(OOX::Spreadsheet::CMdxMetadata* pMdxMetadata) +{ + if (!pMdxMetadata) return; + + for (size_t i = 0; i < pMdxMetadata->m_arrItems.size(); ++i) + { + if (!pMdxMetadata->m_arrItems[i]) continue; + + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MdxMetadata::Mdx); + WriteMdx(pMdxMetadata->m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMdx(OOX::Spreadsheet::CMdx* pMdx) +{ + if (!pMdx) return; + + if (pMdx->m_oN.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MdxMetadata::NameIndex); + m_oBcw.m_oStream.WriteULONG(*pMdx->m_oN); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdx->m_oF.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MdxMetadata::FunctionTag); + m_oBcw.m_oStream.WriteBYTE(pMdx->m_oF->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdx->m_oMdxTuple.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MdxMetadata::MdxTuple); + WriteMdxTuple(pMdx->m_oMdxTuple.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdx->m_oMdxSet.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MdxMetadata::MdxSet); + WriteMdxSet(pMdx->m_oMdxSet.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdx->m_oCMdxKPI.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MdxMetadata::MdxKPI); + WriteMdxKPI(pMdx->m_oCMdxKPI.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdx->m_oMdxMemeberProp.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MdxMetadata::MdxMemeberProp); + WriteMdxMemeberProp(pMdx->m_oMdxMemeberProp.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMdxTuple(OOX::Spreadsheet::CMdxTuple* pMdxTuple) +{ + if (!pMdxTuple) return; + + if (pMdxTuple->m_oC.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::IndexCount); + m_oBcw.m_oStream.WriteULONG(*pMdxTuple->m_oC); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxTuple->m_oCt.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::CultureCurrency); + m_oBcw.m_oStream.WriteStringW3(*pMdxTuple->m_oCt); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxTuple->m_oSi.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::StringIndex); + m_oBcw.m_oStream.WriteULONG(*pMdxTuple->m_oSi); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxTuple->m_oFi.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::NumFmtIndex); + m_oBcw.m_oStream.WriteULONG(*pMdxTuple->m_oFi); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxTuple->m_oBc.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::BackColor); + m_oBcw.m_oStream.WriteULONG(*pMdxTuple->m_oBc); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxTuple->m_oFc.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::ForeColor); + m_oBcw.m_oStream.WriteULONG(*pMdxTuple->m_oFc); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxTuple->m_oI.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::Italic); + m_oBcw.m_oStream.WriteBOOL(*pMdxTuple->m_oI); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxTuple->m_oB.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::Bold); + m_oBcw.m_oStream.WriteBOOL(*pMdxTuple->m_oB); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxTuple->m_oU.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::Underline); + m_oBcw.m_oStream.WriteBOOL(*pMdxTuple->m_oU); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxTuple->m_oSt.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::Strike); + m_oBcw.m_oStream.WriteBOOL(*pMdxTuple->m_oSt); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + for (size_t i = 0; i < pMdxTuple->m_arrItems.size(); ++i) + { + if (!pMdxTuple->m_arrItems[i]) continue; + + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxTuple::MetadataStringIndex); + WriteMetadataStringIndex(pMdxTuple->m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMetadataStringIndex(OOX::Spreadsheet::CMetadataStringIndex* pStringIndex) +{ + if (!pStringIndex) return; + + if (pStringIndex->m_oX.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataStringIndex::IndexValue); + m_oBcw.m_oStream.WriteULONG(*pStringIndex->m_oX); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pStringIndex->m_oS.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataStringIndex::StringIsSet); + m_oBcw.m_oStream.WriteULONG(*pStringIndex->m_oS); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMdxSet(OOX::Spreadsheet::CMdxSet* pMdxSet) +{ + if (!pMdxSet) return; + + if (pMdxSet->m_oC.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxSet::Count); + m_oBcw.m_oStream.WriteULONG(*pMdxSet->m_oC); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxSet->m_oNs.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxSet::Index); + m_oBcw.m_oStream.WriteULONG(*pMdxSet->m_oNs); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxSet->m_oO.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxSet::SortOrder); + m_oBcw.m_oStream.WriteBYTE(pMdxSet->m_oO->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + for (size_t i = 0; i < pMdxSet->m_arrItems.size(); ++i) + { + if (!pMdxSet->m_arrItems[i]) continue; + + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxSet::MetadataStringIndex); + WriteMetadataStringIndex(pMdxSet->m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMdxKPI(OOX::Spreadsheet::CMdxKPI* pMdxKPI) +{ + if (!pMdxKPI) return; + + if (pMdxKPI->m_oN.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxKPI::NameIndex); + m_oBcw.m_oStream.WriteULONG(*pMdxKPI->m_oN); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxKPI->m_oNp.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxKPI::Index); + m_oBcw.m_oStream.WriteULONG(*pMdxKPI->m_oNp); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxKPI->m_oP.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMdxKPI::Property); + m_oBcw.m_oStream.WriteBYTE(pMdxKPI->m_oP->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMdxMemeberProp(OOX::Spreadsheet::CMdxMemeberProp* pMdxMemeberProp) +{ + if (!pMdxMemeberProp) return; + + if (pMdxMemeberProp->m_oN.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMemberProperty::NameIndex); + m_oBcw.m_oStream.WriteULONG(*pMdxMemeberProp->m_oN); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMdxMemeberProp->m_oNp.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataMemberProperty::Index); + m_oBcw.m_oStream.WriteULONG(*pMdxMemeberProp->m_oNp); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMetadataBlocks(OOX::Spreadsheet::CMetadataBlocks* pMetadataBlocks) +{ + if (!pMetadataBlocks) return; + + for (size_t i = 0; i < pMetadataBlocks->m_arrItems.size(); ++i) + { + if (!pMetadataBlocks->m_arrItems[i]) continue; + + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataBlock::MetadataBlock); + WriteMetadataBlock(pMetadataBlocks->m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMetadataBlock(OOX::Spreadsheet::CMetadataBlock* pMetadataBlock) +{ + if (!pMetadataBlock) return; + + for (size_t i = 0; i < pMetadataBlock->m_arrItems.size(); ++i) + { + if (!pMetadataBlock->m_arrItems[i]) continue; + + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataBlock::MetadataRecord); + WriteMetadataRecord(pMetadataBlock->m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteMetadataRecord(OOX::Spreadsheet::CMetadataRecord* pMetadataRecord) +{ + if (!pMetadataRecord) return; + + if (pMetadataRecord->m_oT.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataBlock::MetadataRecordType); + m_oBcw.m_oStream.WriteULONG(*pMetadataRecord->m_oT); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pMetadataRecord->m_oV.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_MetadataBlock::MetadataRecordValue); + m_oBcw.m_oStream.WriteULONG(*pMetadataRecord->m_oV); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteFutureMetadataBlock(OOX::Spreadsheet::CFutureMetadataBlock* pFutureMetadataBlock) +{ + if (!pFutureMetadataBlock) return; + if (false == pFutureMetadataBlock->m_oExtLst.IsInit()) return; + + for (size_t i = 0; i < pFutureMetadataBlock->m_oExtLst->m_arrExt.size(); ++i) + { + if (!pFutureMetadataBlock->m_oExtLst->m_arrExt[i]) continue; + + if (pFutureMetadataBlock->m_oExtLst->m_arrExt[i]->m_oDynamicArrayProperties.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_FutureMetadataBlock::DynamicArrayProperties); + { + if (pFutureMetadataBlock->m_oExtLst->m_arrExt[i]->m_oDynamicArrayProperties->m_oFDynamic.IsInit()) + { + int nCurPos2 = m_oBcw.WriteItemStart(c_oSer_FutureMetadataBlock::DynamicArray); + m_oBcw.m_oStream.WriteBOOL(*pFutureMetadataBlock->m_oExtLst->m_arrExt[i]->m_oDynamicArrayProperties->m_oFDynamic); + m_oBcw.WriteItemWithLengthEnd(nCurPos2); + + } + if (pFutureMetadataBlock->m_oExtLst->m_arrExt[i]->m_oDynamicArrayProperties->m_oFCollapsed.IsInit()) + { + int nCurPos2 = m_oBcw.WriteItemStart(c_oSer_FutureMetadataBlock::CollapsedArray); + m_oBcw.m_oStream.WriteBOOL(*pFutureMetadataBlock->m_oExtLst->m_arrExt[i]->m_oDynamicArrayProperties->m_oFCollapsed); + m_oBcw.WriteItemWithLengthEnd(nCurPos2); + } + } + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if ((pFutureMetadataBlock->m_oExtLst->m_arrExt[i]->m_oRichValueBlock.IsInit()) && + (pFutureMetadataBlock->m_oExtLst->m_arrExt[i]->m_oRichValueBlock->m_oI.IsInit())) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_FutureMetadataBlock::RichValueBlock); + m_oBcw.m_oStream.WriteULONG(*pFutureMetadataBlock->m_oExtLst->m_arrExt[i]->m_oRichValueBlock->m_oI); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + } +} +void BinaryWorkbookTableWriter::WriteFutureMetadata(OOX::Spreadsheet::CFutureMetadata* pFutureMetadata) +{ + if (!pFutureMetadata) return; + + if (pFutureMetadata->m_oName.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_FutureMetadataBlock::Name); + m_oBcw.m_oStream.WriteStringW3(*pFutureMetadata->m_oName); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + for (size_t i = 0; i < pFutureMetadata->m_arrItems.size(); ++i) + { + if (!pFutureMetadata->m_arrItems[i]) continue; + + int nCurPos = m_oBcw.WriteItemStart(c_oSer_FutureMetadataBlock::FutureMetadataBlock); + WriteFutureMetadataBlock(pFutureMetadata->m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} + +void BinaryWorkbookTableWriter::WriteTimelineRange(OOX::Spreadsheet::CTimelineRange* pTimelineRange) +{ + if (!pTimelineRange) return; + + if (pTimelineRange->m_oStartDate.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TimelineRange::StartDate); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*pTimelineRange->m_oStartDate); + } + if (pTimelineRange->m_oEndDate.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TimelineRange::EndDate); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*pTimelineRange->m_oEndDate); + } +} +void BinaryWorkbookTableWriter::WriteTimelinePivotFilter(OOX::Spreadsheet::CTimelinePivotFilter* pPivotFilter) +{ + if (!pPivotFilter) return; + + int nCurPos = 0; + if (pPivotFilter->m_oName.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelinePivotFilter::Name); + m_oBcw.m_oStream.WriteStringW3(*pPivotFilter->m_oName); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pPivotFilter->m_oDescription.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelinePivotFilter::Description); + m_oBcw.m_oStream.WriteStringW3(*pPivotFilter->m_oDescription); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pPivotFilter->m_oUseWholeDay.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelinePivotFilter::UseWholeDay); + m_oBcw.m_oStream.WriteBOOL(*pPivotFilter->m_oUseWholeDay); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pPivotFilter->m_oId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelinePivotFilter::Id); + m_oBcw.m_oStream.WriteLONG(*pPivotFilter->m_oId); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pPivotFilter->m_oFld.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelinePivotFilter::Fld); + m_oBcw.m_oStream.WriteLONG(*pPivotFilter->m_oFld); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (pPivotFilter->m_oAutoFilter.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelinePivotFilter::AutoFilter); + BinaryTableWriter oBinaryTableWriter(m_oBcw.m_oStream); + oBinaryTableWriter.WriteAutoFilter(pPivotFilter->m_oAutoFilter.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteTimelineCachePivotTables(OOX::Spreadsheet::CTimelineCachePivotTables* pPivotTables) +{ + if (!pPivotTables) return; + + int nCurPos = 0; + for (size_t i = 0; i < pPivotTables->m_arrItems.size(); ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_TimelineCache::PivotTable); + WriteTimelineCachePivotTable(pPivotTables->m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorkbookTableWriter::WriteTimelineCachePivotTable(OOX::Spreadsheet::CTimelineCachePivotTable* pPivotTable) +{ + if (!pPivotTable) return; + + if (pPivotTable->m_oName.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TimelineCachePivotTable::Name); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*pPivotTable->m_oName); + } + if (pPivotTable->m_oTabId.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_TimelineCachePivotTable::TabId); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(*pPivotTable->m_oTabId); + } +} +void BinaryWorkbookTableWriter::WriteSlicerCaches(OOX::Spreadsheet::CWorkbook& workbook, const OOX::Spreadsheet::CSlicerCaches& oSlicerCaches) +{ + int nCurPos = 0; + for (size_t i = 0; i < oSlicerCaches.m_oSlicerCache.size(); ++i) + { + if(oSlicerCaches.m_oSlicerCache[i].m_oRId.IsInit()) + { + smart_ptr pFile = workbook.Find(OOX::RId(oSlicerCaches.m_oSlicerCache[i].m_oRId->GetValue())); + if (pFile.IsInit() && OOX::Spreadsheet::FileTypes::SlicerCache == pFile->type()) + { + OOX::Spreadsheet::CSlicerCacheFile* pSlicerCacheFile = static_cast(pFile.GetPointer()); + if(pSlicerCacheFile->m_oSlicerCacheDefinition.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorkbookTypes::SlicerCache); + m_oBcw.m_oStream.WriteRecord2(0, pSlicerCacheFile->m_oSlicerCacheDefinition); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + } + } + } +} + +BinaryPersonTableWriter::BinaryPersonTableWriter(NSBinPptxRW::CBinaryFileWriter &oCBufferedStream) : m_oBcw(oCBufferedStream) +{ +} +void BinaryPersonTableWriter::Write(OOX::Spreadsheet::CPersonList& oPersonList) +{ + int nStart = m_oBcw.WriteItemWithLengthStart(); + WritePersonList(oPersonList); + m_oBcw.WriteItemWithLengthEnd(nStart); +} +void BinaryPersonTableWriter::WritePersonList(OOX::Spreadsheet::CPersonList& oPersonList) +{ + int nCurPos = 0; + for(size_t i = 0; i < oPersonList.m_arrItems.size(); ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Person::person); + WritePerson(*oPersonList.m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryPersonTableWriter::WritePerson(OOX::Spreadsheet::CPerson& oPerson) +{ + int nCurPos = 0; + if(oPerson.id.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Person::id); + m_oBcw.m_oStream.WriteStringW3(oPerson.id.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(oPerson.providerId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Person::providerId); + m_oBcw.m_oStream.WriteStringW3(oPerson.providerId.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(oPerson.userId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Person::userId); + m_oBcw.m_oStream.WriteStringW3(oPerson.userId.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(oPerson.displayName.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Person::displayName); + m_oBcw.m_oStream.WriteStringW3(oPerson.displayName.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} + +BinaryWorksheetTableWriter::BinaryWorksheetTableWriter(NSBinPptxRW::CBinaryFileWriter &oCBufferedStream, NSFontCutter::CEmbeddedFontsManager* pEmbeddedFontsManager, OOX::Spreadsheet::CIndexedColors* pIndexedColors, PPTX::Theme* pTheme, DocWrapper::FontProcessor& oFontProcessor, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter) : + m_oBcw(oCBufferedStream), m_pEmbeddedFontsManager(pEmbeddedFontsManager), m_pIndexedColors(pIndexedColors), m_pTheme(pTheme), m_oFontProcessor(oFontProcessor), m_pOfficeDrawingConverter(pOfficeDrawingConverter) +{ +} +void BinaryWorksheetTableWriter::Write(OOX::Spreadsheet::CWorkbook& workbook, std::map& mapWorksheets) +{ + int nStart = m_oBcw.WriteItemWithLengthStart(); + WriteWorksheets(workbook, mapWorksheets); + m_oBcw.WriteItemWithLengthEnd(nStart); +} +void BinaryWorksheetTableWriter::Write(OOX::Spreadsheet::CWorkbook& workbook, std::vector& arrWorksheets) +{ + int nStart = m_oBcw.WriteItemWithLengthStart(); + + for(size_t i = 0; i < arrWorksheets.size(); ++i) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Worksheet); + WriteWorksheet(workbook.m_oSheets->m_arrItems[i], *arrWorksheets[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + + m_oBcw.WriteItemWithLengthEnd(nStart); +} +void BinaryWorksheetTableWriter::WriteWorksheets(OOX::Spreadsheet::CWorkbook& workbook, std::map& mapWorksheets) +{ + int nCurPos; + //определяем порядок следования .. излишне с vector + if(workbook.m_oSheets.IsInit()) + { + for(size_t i = 0; i < workbook.m_oSheets->m_arrItems.size(); ++i) + { + OOX::Spreadsheet::CSheet* pSheet = workbook.m_oSheets->m_arrItems[i]; + + if(pSheet->m_oRid.IsInit()) + { + std::map::const_iterator pFind = mapWorksheets.find(pSheet->m_oRid->GetValue()); + if(mapWorksheets.end() != pFind) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Worksheet); + WriteWorksheet(pSheet, *pFind->second); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + } + } + } +} +void BinaryWorksheetTableWriter::WriteWorksheet(OOX::Spreadsheet::CSheet* pSheet, OOX::Spreadsheet::CWorksheet& oWorksheet) +{ + int nCurPos; + //WorksheetProp + if (pSheet) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::WorksheetProp); + WriteWorksheetProp(*pSheet); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + //Protection + if (oWorksheet.m_oSheetProtection.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Protection); + WriteProtection(oWorksheet.m_oSheetProtection.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + //Cols + if(oWorksheet.m_oCols.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Cols); + WriteCols(oWorksheet.m_oCols.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + //Dimension + if(oWorksheet.m_oDimension.IsInit() && oWorksheet.m_oDimension->m_oRef.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetsTypes::Dimension); + m_oBcw.m_oStream.WriteStringW(*oWorksheet.m_oDimension->m_oRef); + } + //SheetViews + if(oWorksheet.m_oSheetViews.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::SheetViews); + WriteSheetViews(oWorksheet.m_oSheetViews.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (oWorksheet.m_oProtectedRanges.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::ProtectedRanges); + WriteProtectedRanges(oWorksheet.m_oProtectedRanges.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + //SheetFormatPr + if(oWorksheet.m_oSheetFormatPr.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::SheetFormatPr); + WriteSheetFormatPr(oWorksheet.m_oSheetFormatPr.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + //PageMargins + if(oWorksheet.m_oPageMargins.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::PageMargins); + WritePageMargins(oWorksheet.m_oPageMargins.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + //PageSetup + if(oWorksheet.m_oPageSetup.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::PageSetup); + WritePageSetup(oWorksheet.m_oPageSetup.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + //PrintOptions + if(oWorksheet.m_oPrintOptions.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::PrintOptions); + WritePrintOptions(oWorksheet.m_oPrintOptions.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + //Hyperlinks + if(oWorksheet.m_oHyperlinks.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Hyperlinks); + WriteHyperlinks(oWorksheet.m_oHyperlinks.get(), oWorksheet); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + //MergeCells + if(oWorksheet.m_oMergeCells.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::MergeCells); + WriteMergeCells(oWorksheet.m_oMergeCells.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + //SheetData + if(oWorksheet.m_oSheetData.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::SheetData); + WriteSheetData(oWorksheet.m_oSheetData.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + // ConditionalFormatting + if ( !oWorksheet.m_arrConditionalFormatting.empty() ) + { + WriteConditionalFormattings(oWorksheet.m_arrConditionalFormatting, oWorksheet.m_mapConditionalFormattingEx, false); + } + if (oWorksheet.m_oExtLst.IsInit()) + { + for(size_t i = 0; i < oWorksheet.m_oExtLst->m_arrExt.size(); ++i) + { + OOX::Drawing::COfficeArtExtension* pExt = oWorksheet.m_oExtLst->m_arrExt[i]; + if ( !pExt->m_arrConditionalFormatting.empty() ) + { + WriteConditionalFormattings(pExt->m_arrConditionalFormatting, oWorksheet.m_mapConditionalFormattingEx, true); + } + else if ( pExt->m_oSlicerList.IsInit() ) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Slicers); + WriteSlicers(oWorksheet, pExt->m_oSlicerList.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + else if ( pExt->m_oSlicerListExt.IsInit() ) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::SlicersExt); + WriteSlicers(oWorksheet, pExt->m_oSlicerListExt.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + else if (pExt->m_oUserProtectedRanges.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::UserProtectedRanges); + WriteUserProtectedRanges(pExt->m_oUserProtectedRanges.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + else if (pExt->m_oTimelineRefs.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::TimelinesList); + WriteTimelines(oWorksheet, pExt->m_oTimelineRefs.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + } + } + // DataValidations (with ext) + if ( oWorksheet.m_oDataValidations.IsInit() ) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::DataValidations); + WriteDataValidations(oWorksheet.m_oDataValidations.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +//Drawing + smart_ptr currentVmlDrawing; + smart_ptr currentDrawing; + + if (oWorksheet.m_oLegacyDrawing.IsInit() && + oWorksheet.m_oLegacyDrawing->m_oId.IsInit()) + { + smart_ptr oFile = oWorksheet.Find(oWorksheet.m_oLegacyDrawing->m_oId->GetValue()); + currentVmlDrawing = oFile.smart_dynamic_cast(); + } + if (oWorksheet.m_oDrawing.IsInit() && oWorksheet.m_oDrawing->m_oId.IsInit()) + { + smart_ptr oFile = oWorksheet.Find(oWorksheet.m_oDrawing->m_oId->GetValue()); + currentDrawing = oFile.smart_dynamic_cast(); + } + + WriteControls(oWorksheet, currentVmlDrawing.GetPointer()); + + smart_ptr oldRels; + if (currentDrawing.IsInit()) + { + oldRels = m_pOfficeDrawingConverter->GetRels(); + m_pOfficeDrawingConverter->SetRels(currentDrawing.smart_dynamic_cast()); + } + if (currentDrawing.IsInit() || currentVmlDrawing.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Drawings); + WriteDrawings(oWorksheet, currentDrawing.GetPointer(), currentVmlDrawing.GetPointer()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (oldRels.IsInit()) + { + m_pOfficeDrawingConverter->SetRels(oldRels); + } + + if (oWorksheet.m_oLegacyDrawingHF.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::LegacyDrawingHF); + WriteLegacyDrawingHF(oWorksheet); + m_oBcw.WriteItemEnd(nCurPos); + } + //Autofilter + if (oWorksheet.m_oAutofilter.IsInit()) + { + BinaryTableWriter oBinaryTableWriter(m_oBcw.m_oStream); + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Autofilter); + oBinaryTableWriter.WriteAutoFilter(oWorksheet.m_oAutofilter.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + //TableParts + if (oWorksheet.m_oTableParts.IsInit()) + { + BinaryTableWriter oBinaryTableWriter(m_oBcw.m_oStream); + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::TableParts); + oBinaryTableWriter.Write(oWorksheet, oWorksheet.m_oTableParts.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + smart_ptr pFile = oWorksheet.Find(OOX::Spreadsheet::FileTypes::QueryTable); + OOX::Spreadsheet::CQueryTableFile *pQueryTableFile = dynamic_cast(pFile.GetPointer()); + if ((pQueryTableFile) && (pQueryTableFile->m_oQueryTable.IsInit())) + { + BinaryTableWriter oBinaryTableWriter(m_oBcw.m_oStream); + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::QueryTable); + oBinaryTableWriter.WriteQueryTable(pQueryTableFile->m_oQueryTable.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + pFile = oWorksheet.Find(OOX::Spreadsheet::FileTypes::NamedSheetView); + OOX::Spreadsheet::CNamedSheetViewFile *pNamedSheetViewFile = dynamic_cast(pFile.GetPointer()); + if ((pNamedSheetViewFile) && (pNamedSheetViewFile->m_oNamedSheetViews.IsInit())) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::NamedSheetView); + m_oBcw.m_oStream.StartRecord(0); + pNamedSheetViewFile->m_oNamedSheetViews->toPPTY(&m_oBcw.m_oStream); + m_oBcw.m_oStream.EndRecord(); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + //Comments + if (false == oWorksheet.m_mapComments.empty()) + { + bool bIsEmpty = true; + int nCurPos = 0; + + for (std::map::const_iterator it = oWorksheet.m_mapComments.begin(); it != oWorksheet.m_mapComments.end(); ++it) + { + if(it->second->IsValid()) + { + bIsEmpty = false; + break; + } + } + if(false == bIsEmpty) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Comments); + WriteComments(oWorksheet.m_mapComments); + m_oBcw.WriteItemEnd(nCurPos); + } + } + if (oWorksheet.m_oSheetPr.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::SheetPr); + WriteSheetPr(oWorksheet.m_oSheetPr.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (oWorksheet.m_oHeaderFooter.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::HeaderFooter); + WritemHeaderFooter(oWorksheet.m_oHeaderFooter.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (oWorksheet.m_oRowBreaks.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::RowBreaks); + WritemRowColBreaks(oWorksheet.m_oRowBreaks.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (oWorksheet.m_oColBreaks.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::ColBreaks); + WritemRowColBreaks(oWorksheet.m_oColBreaks.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (oWorksheet.m_oCellWatches.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::CellWatches); + WriteCellWatches(oWorksheet.m_oCellWatches.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (oWorksheet.m_oPicture.IsInit() && oWorksheet.m_oPicture->m_oId.IsInit()) + { + smart_ptr pFile = oWorksheet.Find(oWorksheet.m_oPicture->m_oId->GetValue()); + if (pFile.IsInit() && ( OOX::FileTypes::Image == pFile->type())) + { + smart_ptr pImageFileCache = pFile.smart_dynamic_cast(); + if (pImageFileCache.IsInit()) + { + OOX::CPath pathImage = pImageFileCache->filename(); + std::wstring additionalPath; + int additionalType = 0; + double dX = -1.0; //mm + double dY = -1.0; + double dW = -1.0; //mm + double dH = -1.0; + NSShapeImageGen::CMediaInfo oId = m_pOfficeDrawingConverter->m_pBinaryWriter->m_pCommon->m_pMediaManager->WriteImage(pathImage.GetPath(), dX, dY, dW, dH, additionalPath, additionalType); + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Picture); + m_oBcw.m_oStream.WriteStringW3(oId.GetPath2()); + m_oBcw.WriteItemEnd(nCurPos); + } + } + } + if (oWorksheet.m_oSortState.IsInit()) + { + BinaryTableWriter oBinaryTableWriter(m_oBcw.m_oStream); + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::SortState); + oBinaryTableWriter.WriteSortState(oWorksheet.m_oSortState.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if (oWorksheet.m_oExtLst.IsInit()) + { + for(size_t i = 0; i < oWorksheet.m_oExtLst->m_arrExt.size(); ++i) + { + OOX::Drawing::COfficeArtExtension* pExt = oWorksheet.m_oExtLst->m_arrExt[i]; + if( pExt->m_oSparklineGroups.IsInit() ) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::SparklineGroups); + WriteSparklineGroups(pExt->m_oSparklineGroups.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + } + } + pFile = oWorksheet.Find(OOX::Spreadsheet::FileTypes::PivotTable); + OOX::Spreadsheet::CPivotTableFile *pPivotTableFile = dynamic_cast(pFile.GetPointer()); + if ((pPivotTableFile) && (pPivotTableFile->m_oPivotTableDefinition.IsInit())) + { + BinaryTableWriter oBinaryTableWriter(m_oBcw.m_oStream); + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::PivotTable); + if(pPivotTableFile->m_oPivotTableDefinition->m_oCacheId.IsInit()) + { + auto cachePos = m_oBcw.WriteItemStart(c_oSer_PivotTypes::cacheId); + m_oBcw.m_oStream.WriteULONG(pPivotTableFile->m_oPivotTableDefinition->m_oCacheId->GetValue()); + m_oBcw.WriteItemWithLengthEnd(cachePos); + } + NSStringUtils::CStringBuilder writer; + pPivotTableFile->m_oPivotTableDefinition->toXML(writer); + auto wstringData = writer.GetData(); + auto tablePos = m_oBcw.WriteItemStart(c_oSer_PivotTypes::table); + m_oBcw.m_oStream.WriteStringUtf8(wstringData); + m_oBcw.WriteItemWithLengthEnd(tablePos); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorksheetTableWriter::WriteWorksheetProp(OOX::Spreadsheet::CSheet& oSheet) +{ + //Name + if(oSheet.m_oName.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetPropTypes::Name); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*oSheet.m_oName); + } + //SheetId + if(oSheet.m_oSheetId.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetPropTypes::SheetId); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oSheet.m_oSheetId->GetValue()); + } + //State + if(oSheet.m_oState.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetPropTypes::State); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(oSheet.m_oState->GetValue()); + } +} +void BinaryWorksheetTableWriter::WriteCellWatches(const OOX::Spreadsheet::CCellWatches& cellWatches) +{ + for (size_t nIndex = 0, nLength = cellWatches.m_arrItems.size(); nIndex < nLength; ++nIndex) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::CellWatch); + WriteCellWatch(*cellWatches.m_arrItems[nIndex]); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryWorksheetTableWriter::WriteCellWatch(const OOX::Spreadsheet::CCellWatch& cellWatch) +{ + if (cellWatch.m_oR.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetsTypes::CellWatchR); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*cellWatch.m_oR); + } +} +void BinaryWorksheetTableWriter::WriteProtectedRanges(const OOX::Spreadsheet::CProtectedRanges& protectedRanges) +{ + for (size_t nIndex = 0, nLength = protectedRanges.m_arrItems.size(); nIndex < nLength; ++nIndex) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::ProtectedRange); + WriteProtectedRange(*protectedRanges.m_arrItems[nIndex]); + m_oBcw.WriteItemEnd(nCurPos); + } +} + +void BinaryWorksheetTableWriter::WriteProtectedRange(const OOX::Spreadsheet::CProtectedRange& protectedRange) +{ + if (protectedRange.m_oAlgorithmName.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerProtectedRangeTypes::AlgorithmName); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(protectedRange.m_oAlgorithmName->GetValue()); + } + if (protectedRange.m_oSpinCount.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerProtectedRangeTypes::SpinCount); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteULONG(protectedRange.m_oSpinCount->GetValue()); + } + if (protectedRange.m_oHashValue.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerProtectedRangeTypes::HashValue); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*protectedRange.m_oHashValue); + } + if (protectedRange.m_oSaltValue.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerProtectedRangeTypes::SaltValue); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*protectedRange.m_oSaltValue); + } + if (protectedRange.m_oName.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerProtectedRangeTypes::Name); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*protectedRange.m_oName); + } + if (protectedRange.m_oSqref.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerProtectedRangeTypes::SqRef); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*protectedRange.m_oSqref); + } + for (size_t i = 0; i < protectedRange.m_arSecurityDescriptors.size(); ++i) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerProtectedRangeTypes::SecurityDescriptor); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(protectedRange.m_arSecurityDescriptors[i]); + } +} +void BinaryWorksheetTableWriter::WriteProtection(const OOX::Spreadsheet::CSheetProtection& protection) +{ + if (protection.m_oAlgorithmName.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetProtection::AlgorithmName); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(protection.m_oAlgorithmName->GetValue()); + } + if (protection.m_oSpinCount.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetProtection::SpinCount); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteULONG(protection.m_oSpinCount->GetValue()); + } + if (protection.m_oHashValue.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetProtection::HashValue); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*protection.m_oHashValue); + } + if (protection.m_oSaltValue.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetProtection::SaltValue); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*protection.m_oSaltValue); + } + if (protection.m_oPassword.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetProtection::Password); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*protection.m_oPassword); + } + if (protection.m_oAutoFilter.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetProtection::AutoFilter); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(protection.m_oAutoFilter->ToBool()); + } + if (protection.m_oContent.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetProtection::Content); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(protection.m_oContent->ToBool()); + } + if (protection.m_oDeleteColumns.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetProtection::DeleteColumns); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(protection.m_oDeleteColumns->ToBool()); + } + if (protection.m_oDeleteRows.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetProtection::DeleteRows); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(protection.m_oDeleteRows->ToBool()); + } + if (protection.m_oFormatCells.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetProtection::FormatCells); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(protection.m_oFormatCells->ToBool()); + } + if (protection.m_oFormatColumns.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetProtection::FormatColumns); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(protection.m_oFormatColumns->ToBool()); + } + if (protection.m_oFormatRows.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetProtection::FormatRows); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(protection.m_oFormatRows->ToBool()); + } + if (protection.m_oInsertColumns.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetProtection::InsertColumns); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(protection.m_oInsertColumns->ToBool()); + } + if (protection.m_oInsertHyperlinks.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetProtection::InsertHyperlinks); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(protection.m_oInsertHyperlinks->ToBool()); + } + if (protection.m_oInsertRows.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetProtection::InsertRows); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(protection.m_oInsertRows->ToBool()); + } + if (protection.m_oObjects.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetProtection::Objects); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(protection.m_oObjects->ToBool()); + } + if (protection.m_oPivotTables.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetProtection::PivotTables); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(protection.m_oPivotTables->ToBool()); + } + if (protection.m_oScenarios.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetProtection::Scenarios); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(protection.m_oScenarios->ToBool()); + } + if (protection.m_oSelectLockedCells.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetProtection::SelectLockedCells); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(protection.m_oSelectLockedCells->ToBool()); + } + if (protection.m_oSelectUnlockedCells.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetProtection::SelectUnlockedCell); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(protection.m_oSelectUnlockedCells->ToBool()); + } + if (protection.m_oSheet.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetProtection::Sheet); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(protection.m_oSheet->ToBool()); + } + if (protection.m_oSort.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetProtection::Sort); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(protection.m_oSort->ToBool()); + } +} +void BinaryWorksheetTableWriter::WriteCols(const OOX::Spreadsheet::CCols& oCols) +{ + int nCurPos; + for(size_t i = 0, length = oCols.m_arrItems.size(); i < length; ++i) + { + OOX::Spreadsheet::CCol* pCol = oCols.m_arrItems[i]; + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Col); + WriteCol(*pCol); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorksheetTableWriter::WriteCol(const OOX::Spreadsheet::CCol& oCol) +{ + //BestFit + if(oCol.m_oBestFit.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetColTypes::BestFit); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oCol.m_oBestFit->ToBool()); + } + //Hidden + if(oCol.m_oHidden.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetColTypes::Hidden); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oCol.m_oHidden->ToBool()); + } + //Max + if(oCol.m_oMax.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetColTypes::Max); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oCol.m_oMax->GetValue()); + } + //Min + if(oCol.m_oMin.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetColTypes::Min); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oCol.m_oMin->GetValue()); + } + //Style + if(oCol.m_oStyle.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetColTypes::Style); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oCol.m_oStyle->GetValue()); + } + //Width + if(oCol.m_oWidth.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetColTypes::Width); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Double); + m_oBcw.m_oStream.WriteDoubleReal(oCol.m_oWidth->GetValue()); + } + //CustomWidth + if(oCol.m_oCustomWidth.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetColTypes::CustomWidth); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(oCol.m_oCustomWidth->ToBool()); + } + if(oCol.m_oOutlineLevel.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetColTypes::OutLevel); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oCol.m_oOutlineLevel->GetValue()); + } + if(oCol.m_oCollapsed.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetColTypes::Collapsed); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oCol.m_oCollapsed->ToBool()); + } +} + +void BinaryWorksheetTableWriter::WriteSheetViews(const OOX::Spreadsheet::CSheetViews& oSheetViews) +{ + int nCurPos = 0; + for (size_t nIndex = 0, nLength = oSheetViews.m_arrItems.size(); nIndex < nLength; ++nIndex) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::SheetView); + WriteSheetView(*oSheetViews.m_arrItems[nIndex]); + m_oBcw.WriteItemEnd(nCurPos); + } +} + +void BinaryWorksheetTableWriter::WriteSheetView(const OOX::Spreadsheet::CSheetView& oSheetView) +{ + int nCurPos = 0; + if (oSheetView.m_oColorId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetView::ColorId); + m_oBcw.m_oStream.WriteLONG(oSheetView.m_oColorId->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSheetView.m_oDefaultGridColor.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetView::DefaultGridColor); + m_oBcw.m_oStream.WriteBOOL(oSheetView.m_oDefaultGridColor->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSheetView.m_oRightToLeft.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetView::RightToLeft); + m_oBcw.m_oStream.WriteBOOL(oSheetView.m_oRightToLeft->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSheetView.m_oShowFormulas.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetView::ShowFormulas); + m_oBcw.m_oStream.WriteBOOL(oSheetView.m_oShowFormulas->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSheetView.m_oShowGridLines.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetView::ShowGridLines); + m_oBcw.m_oStream.WriteBOOL(oSheetView.m_oShowGridLines->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSheetView.m_oShowOutlineSymbols.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetView::ShowOutlineSymbols); + m_oBcw.m_oStream.WriteBOOL(oSheetView.m_oShowOutlineSymbols->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSheetView.m_oShowRowColHeaders.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetView::ShowRowColHeaders); + m_oBcw.m_oStream.WriteBOOL(oSheetView.m_oShowRowColHeaders->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSheetView.m_oShowRuler.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetView::ShowRuler); + m_oBcw.m_oStream.WriteBOOL(oSheetView.m_oShowRuler->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSheetView.m_oShowWhiteSpace.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetView::ShowWhiteSpace); + m_oBcw.m_oStream.WriteBOOL(oSheetView.m_oShowWhiteSpace->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSheetView.m_oShowZeros.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetView::ShowZeros); + m_oBcw.m_oStream.WriteBOOL(oSheetView.m_oShowZeros->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSheetView.m_oTabSelected.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetView::TabSelected); + m_oBcw.m_oStream.WriteBOOL(oSheetView.m_oTabSelected->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSheetView.m_oTopLeftCell.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetView::TopLeftCell); + m_oBcw.m_oStream.WriteStringW4(*oSheetView.m_oTopLeftCell); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSheetView.m_oView.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetView::View); + m_oBcw.m_oStream.WriteBYTE(oSheetView.m_oView->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSheetView.m_oWindowProtection.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetView::WindowProtection); + m_oBcw.m_oStream.WriteBOOL(oSheetView.m_oWindowProtection->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSheetView.m_oWorkbookViewId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetView::WorkbookViewId); + m_oBcw.m_oStream.WriteLONG(oSheetView.m_oWorkbookViewId->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSheetView.m_oZoomScale.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetView::ZoomScale); + m_oBcw.m_oStream.WriteLONG(oSheetView.m_oZoomScale->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSheetView.m_oZoomScaleNormal.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetView::ZoomScaleNormal); + m_oBcw.m_oStream.WriteLONG(oSheetView.m_oZoomScaleNormal->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSheetView.m_oZoomScalePageLayoutView.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetView::ZoomScalePageLayoutView); + m_oBcw.m_oStream.WriteLONG(oSheetView.m_oZoomScalePageLayoutView->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSheetView.m_oZoomScaleSheetLayoutView.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetView::ZoomScaleSheetLayoutView); + m_oBcw.m_oStream.WriteLONG(oSheetView.m_oZoomScaleSheetLayoutView->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + + if (oSheetView.m_oPane.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetView::Pane); + WritePane(oSheetView.m_oPane.get()); + m_oBcw.WriteItemEnd(nCurPos); + } + for(size_t i = 0; i < oSheetView.m_arrItems.size(); ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetView::Selection); + WriteSelection(*oSheetView.m_arrItems[i]); + m_oBcw.WriteItemEnd(nCurPos); + } +} + +void BinaryWorksheetTableWriter::WritePane(const OOX::Spreadsheet::CPane& oPane) +{ + int nCurPos = 0; + if (oPane.m_oActivePane.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Pane::ActivePane); + m_oBcw.m_oStream.WriteBYTE(oPane.m_oActivePane->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + //State + if (oPane.m_oState.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Pane::State); + m_oBcw.m_oStream.WriteStringW4(oPane.m_oState->ToString()); + m_oBcw.WriteItemEnd(nCurPos); + } + //TopLeftCell + if (oPane.m_oTopLeftCell.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Pane::TopLeftCell); + m_oBcw.m_oStream.WriteStringW(*oPane.m_oTopLeftCell); + } + //XSplit + if (oPane.m_oXSplit.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Pane::XSplit); + m_oBcw.m_oStream.WriteDoubleReal(oPane.m_oXSplit->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + //YSplit + if (oPane.m_oYSplit.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Pane::YSplit); + m_oBcw.m_oStream.WriteDoubleReal(oPane.m_oYSplit->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryWorksheetTableWriter::WriteSelection(const OOX::Spreadsheet::CSelection& oSelection) +{ + int nCurPos = 0; + if (oSelection.m_oActiveCell.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Selection::ActiveCell); + m_oBcw.m_oStream.WriteStringW4(oSelection.m_oActiveCell.get()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSelection.m_oActiveCellId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Selection::ActiveCellId); + m_oBcw.m_oStream.WriteLONG(oSelection.m_oActiveCellId->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSelection.m_oPane.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Selection::Pane); + m_oBcw.m_oStream.WriteBYTE(oSelection.m_oPane->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSelection.m_oSqref.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Selection::Sqref); + m_oBcw.m_oStream.WriteStringW4(oSelection.m_oSqref.get()); + m_oBcw.WriteItemEnd(nCurPos); + } +} + +void BinaryWorksheetTableWriter::WriteSheetFormatPr(const OOX::Spreadsheet::CSheetFormatPr& oSheetFormatPr) +{ + //DefaultColWidth + if(oSheetFormatPr.m_oDefaultColWidth.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerSheetFormatPrTypes::DefaultColWidth); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Double); + m_oBcw.m_oStream.WriteDoubleReal(*oSheetFormatPr.m_oDefaultColWidth); + } + //DefaultRowHeight + if(oSheetFormatPr.m_oDefaultRowHeight.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerSheetFormatPrTypes::DefaultRowHeight); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Double); + m_oBcw.m_oStream.WriteDoubleReal(*oSheetFormatPr.m_oDefaultRowHeight); + } + //BaseColWidth + if(oSheetFormatPr.m_oBaseColWidth.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerSheetFormatPrTypes::BaseColWidth); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(*oSheetFormatPr.m_oBaseColWidth); + } + //CustomHeight + if(oSheetFormatPr.m_oCustomHeight.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerSheetFormatPrTypes::CustomHeight); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(*oSheetFormatPr.m_oCustomHeight); + } + //ZeroHeight + if(oSheetFormatPr.m_oZeroHeight.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerSheetFormatPrTypes::ZeroHeight); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(*oSheetFormatPr.m_oZeroHeight); + } + //OutlineLevelCol + if(oSheetFormatPr.m_oOutlineLevelCol.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerSheetFormatPrTypes::OutlineLevelCol); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(*oSheetFormatPr.m_oOutlineLevelCol); + } + //OutlineLevelRow + if(oSheetFormatPr.m_oOutlineLevelRow.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerSheetFormatPrTypes::OutlineLevelRow); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(*oSheetFormatPr.m_oOutlineLevelRow); + } +} +void BinaryWorksheetTableWriter::WritePageMargins(const OOX::Spreadsheet::CPageMargins& oPageMargins) +{ + //Left + if(oPageMargins.m_oLeft.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PageMargins::Left); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Double); + m_oBcw.m_oStream.WriteDoubleReal(oPageMargins.m_oLeft->ToMm()); + } + //Top + if(oPageMargins.m_oTop.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PageMargins::Top); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Double); + m_oBcw.m_oStream.WriteDoubleReal(oPageMargins.m_oTop->ToMm()); + } + //Right + if(oPageMargins.m_oRight.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PageMargins::Right); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Double); + m_oBcw.m_oStream.WriteDoubleReal(oPageMargins.m_oRight->ToMm()); + } + //Bottom + if(oPageMargins.m_oBottom.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PageMargins::Bottom); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Double); + m_oBcw.m_oStream.WriteDoubleReal(oPageMargins.m_oBottom->ToMm()); + } + //Header + if(oPageMargins.m_oHeader.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PageMargins::Header); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Double); + m_oBcw.m_oStream.WriteDoubleReal(oPageMargins.m_oHeader->ToMm()); + } + //Footer + if(oPageMargins.m_oFooter.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PageMargins::Footer); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Double); + m_oBcw.m_oStream.WriteDoubleReal(oPageMargins.m_oFooter->ToMm()); + } +} +void BinaryWorksheetTableWriter::WritePageSetup(const OOX::Spreadsheet::CPageSetup& oPageSetup) +{ + //PageSize + if(oPageSetup.m_oPaperSize.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PageSetup::PaperSize); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(oPageSetup.m_oPaperSize->GetValue()); + } + if(oPageSetup.m_oBlackAndWhite.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PageSetup::BlackAndWhite); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oPageSetup.m_oBlackAndWhite->ToBool()); + } + if(oPageSetup.m_oCellComments.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PageSetup::CellComments); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(oPageSetup.m_oCellComments->GetValue()); + } + if(oPageSetup.m_oCopies.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PageSetup::Copies); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oPageSetup.m_oCopies->GetValue()); + } + if(oPageSetup.m_oDraft.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PageSetup::Draft); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oPageSetup.m_oDraft->ToBool()); + } + if(oPageSetup.m_oErrors.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PageSetup::Errors); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(oPageSetup.m_oErrors->GetValue()); + } + if(oPageSetup.m_oFirstPageNumber.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PageSetup::FirstPageNumber); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oPageSetup.m_oFirstPageNumber->GetValue()); + } + if(oPageSetup.m_oFitToHeight.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PageSetup::FitToHeight); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oPageSetup.m_oFitToHeight->GetValue()); + } + if(oPageSetup.m_oFitToWidth.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PageSetup::FitToWidth); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oPageSetup.m_oFitToWidth->GetValue()); + } + if(oPageSetup.m_oHorizontalDpi.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PageSetup::HorizontalDpi); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oPageSetup.m_oHorizontalDpi->GetValue()); + } + //Orientation + if(oPageSetup.m_oOrientation.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PageSetup::Orientation); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(oPageSetup.m_oOrientation->GetValue()); + } + if(oPageSetup.m_oPageOrder.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PageSetup::PageOrder); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(oPageSetup.m_oPageOrder->GetValue()); + } + if(oPageSetup.m_oPaperHeight.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PageSetup::PaperHeight); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Double); + m_oBcw.m_oStream.WriteDoubleReal(oPageSetup.m_oPaperHeight->GetValue()); + } + if(oPageSetup.m_oPaperWidth.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PageSetup::PaperWidth); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Double); + m_oBcw.m_oStream.WriteDoubleReal(oPageSetup.m_oPaperWidth->GetValue()); + } + if(oPageSetup.m_oPaperWidth.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PageSetup::PaperWidth); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Double); + m_oBcw.m_oStream.WriteDoubleReal(oPageSetup.m_oPaperWidth->GetValue()); + } + if(oPageSetup.m_oPaperUnits.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PageSetup::PaperUnits); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(oPageSetup.m_oPaperUnits->GetValue()); + } + if(oPageSetup.m_oScale.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PageSetup::Scale); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oPageSetup.m_oScale->GetValue()); + } + if(oPageSetup.m_oUseFirstPageNumber.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PageSetup::UseFirstPageNumber); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oPageSetup.m_oUseFirstPageNumber->ToBool()); + } + if(oPageSetup.m_oUsePrinterDefaults.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PageSetup::UsePrinterDefaults); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oPageSetup.m_oUsePrinterDefaults->ToBool()); + } + if(oPageSetup.m_oVerticalDpi.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PageSetup::VerticalDpi); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oPageSetup.m_oVerticalDpi->GetValue()); + } + +} +void BinaryWorksheetTableWriter::WritePrintOptions(const OOX::Spreadsheet::CPrintOptions& oPrintOptions) +{ + //GridLines + if(oPrintOptions.m_oGridLines.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PrintOptions::GridLines); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oPrintOptions.m_oGridLines->ToBool()); + } + //Headings + if(oPrintOptions.m_oHeadings.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PrintOptions::Headings); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oPrintOptions.m_oHeadings->ToBool()); + } + if (oPrintOptions.m_oGridLinesSet.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PrintOptions::GridLinesSet); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oPrintOptions.m_oGridLinesSet->ToBool()); + } + if (oPrintOptions.m_oHorizontalCentered.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PrintOptions::HorizontalCentered); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oPrintOptions.m_oHorizontalCentered->ToBool()); + } + if (oPrintOptions.m_oVerticalCentered.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_PrintOptions::VerticalCentered); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oPrintOptions.m_oVerticalCentered->ToBool()); + } +} +void BinaryWorksheetTableWriter::WriteHyperlinks(const OOX::Spreadsheet::CHyperlinks& oHyperlinks, OOX::Spreadsheet::CWorksheet& oWorksheet) +{ + int nCurPos; + for(size_t i = 0, length = oHyperlinks.m_arrItems.size(); i < length; ++i) + { + OOX::Spreadsheet::CHyperlink* pHyperlink = oHyperlinks.m_arrItems[i]; + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Hyperlink); + WriteHyperlink(*pHyperlink, oWorksheet); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +}; +void BinaryWorksheetTableWriter::WriteHyperlink(const OOX::Spreadsheet::CHyperlink& oHyperlink, OOX::Spreadsheet::CWorksheet& oWorksheet) +{ + std::wstring sRef; + std::wstring sHyperlink; + std::wstring sLocation; + std::wstring sDisplay; + + if(oHyperlink.m_oRef.IsInit()) + sRef = oHyperlink.m_oRef.get(); + if(oHyperlink.m_oRid.IsInit() && oWorksheet.m_pCurRels.IsInit()) + { + OOX::Rels::CRelationShip* oRels = NULL; + oWorksheet.m_pCurRels->GetRel( OOX::RId(oHyperlink.m_oRid->GetValue()), &oRels); + if(NULL != oRels && _T("http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink") == oRels->Type() ) + { + if(oRels->IsExternal()) + sHyperlink = oRels->Target().GetPath(); + } + } + else if (oHyperlink.m_oLink.IsInit()) + { + sHyperlink = *oHyperlink.m_oLink; + } + if(oHyperlink.m_oLocation.IsInit()) + sLocation = *oHyperlink.m_oLocation; + if (oHyperlink.m_oDisplay.IsInit()) + sDisplay = *oHyperlink.m_oDisplay; + + if (!sRef.empty() && (!sHyperlink.empty() || !sLocation.empty() || !sDisplay.empty())) + { + //Ref + m_oBcw.m_oStream.WriteBYTE(c_oSerHyperlinkTypes::Ref); + m_oBcw.m_oStream.WriteStringW(sRef); + //Hyperlink + if (!sHyperlink.empty()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerHyperlinkTypes::Hyperlink); + m_oBcw.m_oStream.WriteStringW(sHyperlink); + } + //Location + if (!sLocation.empty()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerHyperlinkTypes::Location); + m_oBcw.m_oStream.WriteStringW(sLocation); + } + //Tooltip + if(oHyperlink.m_oTooltip.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerHyperlinkTypes::Tooltip); + m_oBcw.m_oStream.WriteStringW(*oHyperlink.m_oTooltip); + } + //Display + if(oHyperlink.m_oDisplay.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerHyperlinkTypes::Display); + m_oBcw.m_oStream.WriteStringW(*oHyperlink.m_oDisplay); + } + } +} +void BinaryWorksheetTableWriter::WriteMergeCells(const OOX::Spreadsheet::CMergeCells& oMergeCells) +{ + for(size_t i = 0, length = oMergeCells.m_arrItems.size(); i < length; ++i) + { + OOX::Spreadsheet::CMergeCell* pMergeCell = oMergeCells.m_arrItems[i]; + if(pMergeCell->m_oRef.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerWorksheetsTypes::MergeCell); + m_oBcw.m_oStream.WriteStringW(*pMergeCell->m_oRef); + } + } +} +void BinaryWorksheetTableWriter::WriteSheetData(const OOX::Spreadsheet::CSheetData& oSheetData) +{ + int nCurPos; + if(oSheetData.m_oXlsbPos.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::XlsbPos); + m_oBcw.m_oStream.WriteLONG(oSheetData.m_oXlsbPos->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + else + { + for(size_t i = 0, length = oSheetData.m_arrItems.size(); i < length; ++i) + { + OOX::Spreadsheet::CRow* pRow = oSheetData.m_arrItems[i]; + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Row); + WriteRow(*pRow); + m_oBcw.WriteItemEnd(nCurPos); + } + } +} +void BinaryWorksheetTableWriter::WriteRow(const OOX::Spreadsheet::CRow& oRows) +{ + int nCurPos; + //Row + if(oRows.m_oR.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerRowTypes::Row); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oRows.m_oR->GetValue()); + } + //Style + if(oRows.m_oS.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerRowTypes::Style); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oRows.m_oS->GetValue()); + } + //Height + if(oRows.m_oHt.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerRowTypes::Height); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Double); + m_oBcw.m_oStream.WriteDoubleReal(oRows.m_oHt->GetValue()); + } + //Hidden + if(oRows.m_oHidden.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerRowTypes::Hidden); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oRows.m_oHidden->ToBool()); + } + //CustomHeight + if(oRows.m_oCustomHeight.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerRowTypes::CustomHeight); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oRows.m_oCustomHeight->ToBool()); + } + if(oRows.m_oOutlineLevel.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerRowTypes::OutLevel); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oRows.m_oOutlineLevel->GetValue()); + } + if(oRows.m_oCollapsed.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerRowTypes::Collapsed); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oRows.m_oCollapsed->ToBool()); + } + if(oRows.m_arrItems.size() > 0) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerRowTypes::Cells); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + nCurPos = m_oBcw.WriteItemWithLengthStart(); + WriteCells(oRows); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorksheetTableWriter::WriteCells(const OOX::Spreadsheet::CRow& oRows) +{ + int nCurPos; + for(size_t i = 0, length = oRows.m_arrItems.size(); i < length; ++i) + { + OOX::Spreadsheet::CCell* oCell =oRows.m_arrItems[i]; + nCurPos = m_oBcw.WriteItemStart(c_oSerRowTypes::Cell); + WriteCell(*oCell); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorksheetTableWriter::WriteCell(const OOX::Spreadsheet::CCell& oCell) +{ + int nCurPos; +//Ref + int nRow = 0; + int nCol = 0; + if (oCell.isInitRef() && oCell.getRowCol(nRow, nCol)) + { + // Пишем теперь не строку, а 2 числа (чтобы не парсить на JavaScript, т.к. на C++ быстрее парсинг). Ускорение открытия файла. + nCurPos = m_oBcw.WriteItemStart(c_oSerCellTypes::RefRowCol); + m_oBcw.m_oStream.WriteLONG(nRow); + m_oBcw.m_oStream.WriteLONG(nCol); + m_oBcw.WriteItemEnd(nCurPos); + + //m_oBcw.m_oStream.WriteBYTE(c_oSerCellTypes::Ref); + //m_oBcw.m_oStream.WriteStringW(oCell.m_oRef.get2()); + } + //Style + if(oCell.m_oStyle.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerCellTypes::Style); + m_oBcw.m_oStream.WriteLONG(*oCell.m_oStyle); + m_oBcw.WriteItemEnd(nCurPos); + } +//Type + if(oCell.m_oType.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerCellTypes::Type); + m_oBcw.m_oStream.WriteBYTE(oCell.m_oType->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + //Formula + if(oCell.m_oFormula.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerCellTypes::Formula); + WriteFormula(oCell.m_oFormula.get2()); + m_oBcw.WriteItemEnd(nCurPos); + } +//Value + if (oCell.m_oValue.IsInit() && !oCell.m_oValue->ToString().empty()) + { + + double dValue = 0; + if(oCell.m_oType.IsInit() && oCell.m_oType->m_eValue == SimpleTypes::Spreadsheet::celltypeError) + { + auto errorText = oCell.m_oValue->m_sText; + if(errorText == L"#NULL!") + dValue = 0x00; + else if(errorText == L"#DIV/0!") + dValue = 0x07; + else if(errorText == L"#VALUE!") + dValue = 0x0F; + else if(errorText == L"#REF!") + dValue = 0x17; + else if(errorText == L"#NAME?") + dValue = 0x1D; + else if(errorText == L"#NUM!") + dValue = 0x24; + else if(errorText == L"#N/A") + dValue = 0x2A; + else if(errorText == L"#GETTING_DATA") + dValue = 0x2B; + else + dValue = 0x0; + } + else + { + try + { + dValue = XmlUtils::GetDouble(oCell.m_oValue->ToString()); + } + catch(...) + { //1.3912059045063478e-310 + //Lighting Load Calculation.xls + } + } + + + nCurPos = m_oBcw.WriteItemStart(c_oSerCellTypes::Value); + m_oBcw.m_oStream.WriteDoubleReal(dValue); + m_oBcw.WriteItemEnd(nCurPos); + } +//ValueCache + if (oCell.m_oCacheValue.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerCellTypes::ValueCache); + m_oBcw.m_oStream.WriteStringW3(*oCell.m_oCacheValue); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oCell.m_oCellMetadata.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerCellTypes::CellMetadata); + m_oBcw.m_oStream.WriteULONG(*oCell.m_oCellMetadata); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oCell.m_oValueMetadata.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerCellTypes::ValueMetadata); + m_oBcw.m_oStream.WriteULONG(*oCell.m_oValueMetadata); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryWorksheetTableWriter::WriteFormula(OOX::Spreadsheet::CFormula& oFormula) +{ + //Aca + if(oFormula.m_oAca.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFormulaTypes::Aca); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oFormula.m_oAca->ToBool()); + } + //Bx + if(oFormula.m_oBx.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFormulaTypes::Bx); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oFormula.m_oBx->ToBool()); + } + //Ca + if(oFormula.m_oCa.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFormulaTypes::Ca); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oFormula.m_oCa->ToBool()); + } + //Del1 + if(oFormula.m_oDel1.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFormulaTypes::Del1); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oFormula.m_oDel1->ToBool()); + } + //Del2 + if(oFormula.m_oDel2.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFormulaTypes::Del2); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oFormula.m_oDel2->ToBool()); + } + //Dt2D + if(oFormula.m_oDt2D.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFormulaTypes::Dt2D); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oFormula.m_oDt2D->ToBool()); + } + //Dtr + if(oFormula.m_oDtr.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFormulaTypes::Dtr); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oFormula.m_oDtr->ToBool()); + } + //R1 + if(oFormula.m_oR1.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFormulaTypes::R1); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(oFormula.m_oR1.get2()); + } + //R2 + if(oFormula.m_oR2.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFormulaTypes::R2); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(oFormula.m_oR2.get2()); + } + //Ref + if(oFormula.m_oRef.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFormulaTypes::Ref); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(oFormula.m_oRef.get2()); + } + //Si + if(oFormula.m_oSi.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFormulaTypes::Si); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oFormula.m_oSi->GetValue()); + } + //T + if(oFormula.m_oT.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFormulaTypes::T); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(oFormula.m_oT->GetValue()); + } + //Text + if(!oFormula.m_sText.empty()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerFormulaTypes::Text); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(oFormula.m_sText); + + if(NULL != m_pEmbeddedFontsManager) + m_pEmbeddedFontsManager->CheckString(oFormula.m_sText); + } +} + +void BinaryWorksheetTableWriter::WriteOleObjects(const OOX::Spreadsheet::CWorksheet& oWorksheet, OOX::Spreadsheet::CDrawing* pDrawing, OOX::CVmlDrawing *pVmlDrawing) +{ + if(false == oWorksheet.m_oOleObjects.IsInit()) return; + + for (boost::unordered_map::const_iterator it = oWorksheet.m_oOleObjects->m_mapOleObjects.begin(); it != oWorksheet.m_oOleObjects->m_mapOleObjects.end(); ++it) + { + OOX::Spreadsheet::COleObject* pOleObject = it->second; + OOX::WritingElement* pShapeElem = NULL; + + if (!pOleObject) continue; + + nullable oCellAnchor; + + smart_ptr pFileOleObject; + nullable pRId; + + if (pOleObject->m_oRid.IsInit()) + { + pRId = new OOX::RId( pOleObject->m_oRid->GetValue()); + + //ищем физический файл ( rId относительно sheet) + smart_ptr pFile = oWorksheet.Find(pRId.get()); + pFileOleObject = pFile.smart_dynamic_cast(); + } + if (false == pFileOleObject.IsInit()) continue; + + if (!(dynamic_cast(pFileOleObject.GetPointer())->IsExist() || dynamic_cast(pFileOleObject.GetPointer())->IsExternal() )) continue; + + std::wstring sShapeId = L"_x0000_s" + std::to_wstring(pOleObject->m_oShapeId->GetValue()); + if (pVmlDrawing) + { + std::map::iterator pFind = pVmlDrawing->m_mapShapes.find(sShapeId); + + if (pFind != pVmlDrawing->m_mapShapes.end()) + { + pFind->second.bUsed = true; + pShapeElem = pFind->second.pElement; + } + } + if (!pShapeElem && pDrawing) + { + std::map::iterator pFind = pDrawing->m_mapShapes.find(pOleObject->m_oShapeId->GetValue()); + if (pFind != pDrawing->m_mapShapes.end()) + { + pShapeElem = pFind->second; + } + } + SimpleTypes::Spreadsheet::CCellAnchorType eAnchorType; + eAnchorType.SetValue(SimpleTypes::Spreadsheet::cellanchorTwoCell); + bool bSetAnchor = false; + if (pOleObject->m_oObjectPr.IsInit() && pOleObject->m_oObjectPr->m_oAnchor.IsInit() && pOleObject->m_oObjectPr->m_oRid.IsInit()) + { + const OOX::Spreadsheet::CExtAnchor& oAnchor = pOleObject->m_oObjectPr->m_oAnchor.get(); + + if (oAnchor.m_oFrom.IsInit() && oAnchor.m_oTo.IsInit()) + { + if (oAnchor.m_oMoveWithCells.IsInit() && *oAnchor.m_oMoveWithCells) + eAnchorType.SetValue(SimpleTypes::Spreadsheet::cellanchorOneCell); + else if (oAnchor.m_oSizeWithCells.IsInit() && *oAnchor.m_oSizeWithCells) + eAnchorType.SetValue(SimpleTypes::Spreadsheet::cellanchorTwoCell); + else + eAnchorType.SetValue(SimpleTypes::Spreadsheet::cellanchorAbsolute); + + oCellAnchor.reset(new OOX::Spreadsheet::CCellAnchor(eAnchorType)); + + oCellAnchor->m_oFrom = oAnchor.m_oFrom.get(); + oCellAnchor->m_oTo = oAnchor.m_oTo.get(); + + bSetAnchor = true; + } + } + if (false == oCellAnchor.IsInit()) + { + oCellAnchor.reset(new OOX::Spreadsheet::CCellAnchor(eAnchorType)); + } + + oCellAnchor->m_bShapeOle = true; + + PPTX::Logic::Pic *olePic = new PPTX::Logic::Pic; + + olePic->oleObject.Init(); + olePic->blipFill.blip.Init(); + + if (pOleObject->m_oProgId.IsInit()) + olePic->oleObject->m_sProgId = pOleObject->m_oProgId.get(); + + if (pOleObject->m_oObjectPr.IsInit() && pOleObject->m_oObjectPr->m_oAnchor.IsInit()) + { + olePic->oleObject->m_oMoveWithCells = pOleObject->m_oObjectPr->m_oAnchor->m_oMoveWithCells; + olePic->oleObject->m_oSizeWithCells = pOleObject->m_oObjectPr->m_oAnchor->m_oSizeWithCells; + } + + olePic->oleObject->m_oId = pRId; + olePic->oleObject->m_OleObjectFile = pFileOleObject; + + if (pOleObject->m_oDvAspect.IsInit()) + { + olePic->oleObject->m_oDrawAspect = (BYTE)pOleObject->m_oDvAspect->GetValue(); + } + + if (olePic->oleObject->m_OleObjectFile.IsInit()) + { + olePic->blipFill.blip->oleFilepathBin = olePic->oleObject->m_OleObjectFile->filename().GetPath(); + } + + smart_ptr pImageFileCache; + + std::wstring sIdImageFileCache; + if ((NULL != pShapeElem) && (OOX::et_v_shapetype != pShapeElem->getType())) + { + OOX::Vml::CShape* pShapeVml = dynamic_cast(pShapeElem); + for (size_t j = 0; (pShapeVml) && (j < pShapeVml->m_arrItems.size()); ++j) + { + OOX::WritingElement* pChildElemShape = pShapeVml->m_arrItems[j]; + if (!bSetAnchor && OOX::et_v_ClientData == pChildElemShape->getType()) + { + OOX::Vml::CClientData* pClientData = static_cast(pChildElemShape); + pClientData->toCellAnchor(oCellAnchor.GetPointer()); + + olePic->oleObject->m_oMoveWithCells = pClientData->m_oMoveWithCells; + olePic->oleObject->m_oSizeWithCells = pClientData->m_oSizeWithCells; + } + if (OOX::et_v_imagedata == pChildElemShape->getType()) + { + OOX::Vml::CImageData* pImageData = static_cast(pChildElemShape); + + if (pImageData->m_oRelId.IsInit()) sIdImageFileCache = pImageData->m_oRelId->GetValue(); + else if (pImageData->m_rId.IsInit()) sIdImageFileCache = pImageData->m_rId->GetValue(); + else if (pImageData->m_rPict.IsInit()) sIdImageFileCache = pImageData->m_rPict->GetValue(); + + if (!sIdImageFileCache.empty()) + { + //ищем физический файл ( rId относительно vml_drawing) + smart_ptr pFile = pVmlDrawing->Find(sIdImageFileCache); + + if (pFile.IsInit() && (OOX::FileTypes::Image == pFile->type())) + { + pImageFileCache = pFile.smart_dynamic_cast(); + } + } + } + } + + if (!pShapeVml) + { + PPTX::Logic::Shape* pShape = dynamic_cast(pShapeElem); + if (pShape && pShape->spPr.xfrm.IsInit()) + { + olePic->spPr.xfrm = pShape->spPr.xfrm; + } + } + } + + if (false == pImageFileCache.IsInit() && pOleObject->m_oObjectPr.IsInit() && pOleObject->m_oObjectPr->m_oRid.IsInit()) + { + sIdImageFileCache = pOleObject->m_oObjectPr->m_oRid->GetValue(); + + smart_ptr pFile = oWorksheet.Find(sIdImageFileCache); + if (pFile.IsInit() && (OOX::FileTypes::Image == pFile->type())) + { + pImageFileCache = pFile.smart_dynamic_cast(); + } + } + if (pImageFileCache.IsInit()) + { + OOX::CPath pathImage = pImageFileCache->filename(); + + if (olePic->oleObject->m_OleObjectFile.IsInit()) + { + olePic->oleObject->m_OleObjectFile->set_filename_cache(pathImage); + } + + olePic->blipFill.blip->embed = new OOX::RId(sIdImageFileCache); //ваще то тут не важно что - приоритет у того что ниже.. + olePic->blipFill.blip->oleFilepathImage = pathImage.GetPath(); + } + + oCellAnchor->m_oElement = new PPTX::Logic::SpTreeElem(); + oCellAnchor->m_oElement->InitElem(olePic); +//----------------------------------------------------------------------------------------------------- + if (oCellAnchor.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Drawing); + WriteDrawing(oWorksheet, pDrawing, oCellAnchor.GetPointer(), pVmlDrawing, pOleObject); + m_oBcw.WriteItemEnd(nCurPos); + } + } +} +void BinaryWorksheetTableWriter::WriteControls(const OOX::Spreadsheet::CWorksheet& oWorksheet, OOX::CVmlDrawing *pVmlDrawing) +{ + if (false == oWorksheet.m_oControls.IsInit()) return; + if (oWorksheet.m_oControls->m_mapControls.empty()) return; + + int nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Controls); + + for (std::map>::const_iterator it = oWorksheet.m_oControls->m_mapControls.begin(); it != oWorksheet.m_oControls->m_mapControls.end(); ++it) + { + OOX::Spreadsheet::CControl* pControl = it->second.GetPointer(); + + if (!pControl) continue; + + nullable oCellAnchor; + OOX::Spreadsheet::CFormControlPr oFormControlPr; + OOX::Spreadsheet::CFormControlPr* pFormControlPr = &oFormControlPr; + + smart_ptr pFileControl; + + if (pControl->m_oRid.IsInit()) + { + pFileControl = oWorksheet.Find(OOX::RId(pControl->m_oRid->GetValue()));// rId относительно sheet + } + if (false == pFileControl.IsInit()) continue; + + bool bSetAnchor = false; + + smart_ptr pFileCtrlProp = pFileControl.smart_dynamic_cast(); + + if (pFileCtrlProp.IsInit()) + { + pFormControlPr = pFileCtrlProp->m_oFormControlPr.GetPointer(); + } + else + { + smart_ptr pActiveX_xml = pFileControl.smart_dynamic_cast(); + + if ((pActiveX_xml.IsInit()) && (pActiveX_xml->m_oObject.IsInit())) + { + if (pActiveX_xml->m_oObject->m_oObjectType.IsInit() == false) + { + OOX::ActiveXObjectImage* pImage = dynamic_cast(pActiveX_xml->m_oObject.GetPointer()); + + if (pImage) + { + //todooo + } + continue; + } + + pActiveX_xml->m_oObject->toFormControlPr(pFormControlPr); + } + } + + std::wstring sShapeId = L"_x0000_s" + std::to_wstring(pControl->m_oShapeId->GetValue()); + OOX::Vml::CShape* pShape = NULL; + std::map::iterator pFind; + + if (pVmlDrawing) + { + pFind = pVmlDrawing->m_mapShapes.find(sShapeId); + + if (pFind != pVmlDrawing->m_mapShapes.end() && !pFind->second.bUsed) + { + pShape = dynamic_cast(pFind->second.pElement); + } + } + SimpleTypes::Spreadsheet::CCellAnchorType eAnchorType; + eAnchorType.SetValue(SimpleTypes::Spreadsheet::cellanchorTwoCell); + + if (pControl->m_oControlPr.IsInit() && pControl->m_oControlPr->m_oAnchor.IsInit()) + { + const OOX::Spreadsheet::CExtAnchor& oAnchor = pControl->m_oControlPr->m_oAnchor.get(); + + if (oAnchor.m_oFrom.IsInit() && oAnchor.m_oTo.IsInit()) + { + if(oAnchor.m_oMoveWithCells.IsInit() && *oAnchor.m_oMoveWithCells) + eAnchorType.SetValue(SimpleTypes::Spreadsheet::cellanchorOneCell); + else if(oAnchor.m_oSizeWithCells.IsInit() && *oAnchor.m_oSizeWithCells) + eAnchorType.SetValue(SimpleTypes::Spreadsheet::cellanchorTwoCell); + else + eAnchorType.SetValue(SimpleTypes::Spreadsheet::cellanchorAbsolute); + + oCellAnchor.reset(new OOX::Spreadsheet::CCellAnchor(eAnchorType)); + + oCellAnchor->m_oFrom = oAnchor.m_oFrom.get(); + oCellAnchor->m_oTo = oAnchor.m_oTo.get(); + + bSetAnchor = true; + } + } + if (false == oCellAnchor.IsInit()) + { + oCellAnchor.reset(new OOX::Spreadsheet::CCellAnchor(eAnchorType)); + oCellAnchor->m_bShapeOle= true; + } + if ((pShape) && (OOX::et_v_shapetype != pShape->getType())) + { + for(size_t j = 0; (pShape) && (j < pShape->m_arrItems.size()); ++j) + { + OOX::WritingElement* pChildElemShape = pShape->m_arrItems[j]; + if (OOX::et_v_ClientData == pChildElemShape->getType()) + { + OOX::Vml::CClientData* pClientData = static_cast(pChildElemShape); + + if (!bSetAnchor ) + { + bSetAnchor = pClientData->toCellAnchor(oCellAnchor.GetPointer()); + } + pClientData->toFormControlPr(pFormControlPr); + } + else if (OOX::et_v_textbox == pChildElemShape->getType()) + { + OOX::Vml::CTextbox* pTextbox = static_cast(pChildElemShape); + + pFormControlPr->m_oText = pTextbox->m_oText; + } + } + } + + if (!bSetAnchor) + { + continue; + } + if (pShape) + pFind->second.bUsed = true; +//----------------------------------------------------------------------------------------------------- + int nCurPos2 = m_oBcw.WriteItemStart(c_oSerControlTypes::Control); + int nCurPos3 = m_oBcw.WriteItemStart(c_oSerControlTypes::ControlAnchor); + WriteCellAnchor(oCellAnchor.GetPointer()); + m_oBcw.WriteItemEnd(nCurPos3); + + if(pControl->m_oName.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerControlTypes::Name); + m_oBcw.m_oStream.WriteStringW(*pControl->m_oName); + } + WriteControlPr(pControl->m_oControlPr.GetPointer(), pFormControlPr); + m_oBcw.WriteItemEnd(nCurPos2); + } + m_oBcw.WriteItemEnd(nCurPos); +} + +void BinaryWorksheetTableWriter::WriteControlPr(OOX::Spreadsheet::CControlPr* pControlPr, OOX::Spreadsheet::CFormControlPr* pFormControlPr) +{ + if (!pControlPr && !pFormControlPr) return; + + int nCurPos = 0; + + if (pFormControlPr && pFormControlPr->m_oObjectType.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::ObjectType); + m_oBcw.m_oStream.WriteBYTE(pFormControlPr->m_oObjectType->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pControlPr && pControlPr->m_oAltText.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerControlTypes::AltText); + m_oBcw.m_oStream.WriteStringW(*pControlPr->m_oAltText); + } + if (pControlPr && pControlPr->m_oAutoFill.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::AutoFill); + m_oBcw.m_oStream.WriteBOOL(*pControlPr->m_oAutoFill); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pControlPr && pControlPr->m_oAutoLine.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::AutoLine); + m_oBcw.m_oStream.WriteBOOL(*pControlPr->m_oAutoLine); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pControlPr && pControlPr->m_oAutoPict.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::AutoPict); + m_oBcw.m_oStream.WriteBOOL(*pControlPr->m_oAutoPict); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pControlPr && pControlPr->m_oDefaultSize.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::DefaultSize); + m_oBcw.m_oStream.WriteBOOL(*pControlPr->m_oDefaultSize); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pControlPr && pControlPr->m_oDisabled.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Disabled); + m_oBcw.m_oStream.WriteBOOL(*pControlPr->m_oDisabled); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pControlPr && pControlPr->m_oLocked.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Locked); + m_oBcw.m_oStream.WriteBOOL(*pControlPr->m_oLocked); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pControlPr && pControlPr->m_oPrint.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Print); + m_oBcw.m_oStream.WriteBOOL(*pControlPr->m_oPrint); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pControlPr && pControlPr->m_oRecalcAlways.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::RecalcAlways); + m_oBcw.m_oStream.WriteBOOL(*pControlPr->m_oRecalcAlways); + m_oBcw.WriteItemEnd(nCurPos); + } + if(pControlPr && pControlPr->m_oMacro.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerControlTypes::Macro); + m_oBcw.m_oStream.WriteStringW(*pControlPr->m_oMacro); + } + if(pFormControlPr && pFormControlPr->m_oFmlaGroup.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerControlTypes::FmlaGroup); + m_oBcw.m_oStream.WriteStringW(*pFormControlPr->m_oFmlaGroup); + } + if(pFormControlPr && pFormControlPr->m_oFmlaLink.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerControlTypes::FmlaLink); + m_oBcw.m_oStream.WriteStringW(*pFormControlPr->m_oFmlaLink); + } + if(pFormControlPr && pFormControlPr->m_oFmlaRange.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerControlTypes::FmlaRange); + m_oBcw.m_oStream.WriteStringW(*pFormControlPr->m_oFmlaRange); + } + if(pFormControlPr && pFormControlPr->m_oFmlaTxbx.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerControlTypes::FmlaTxbx); + m_oBcw.m_oStream.WriteStringW(*pFormControlPr->m_oFmlaTxbx); + } + if (pFormControlPr && pFormControlPr->m_oDropLines.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::DropLines); + m_oBcw.m_oStream.WriteLONG(pFormControlPr->m_oDropLines->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pFormControlPr && pFormControlPr->m_oChecked.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Checked); + m_oBcw.m_oStream.WriteBYTE(pFormControlPr->m_oChecked->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pFormControlPr && pFormControlPr->m_oDropStyle.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::DropStyle); + m_oBcw.m_oStream.WriteBYTE(pFormControlPr->m_oDropStyle->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pFormControlPr && pFormControlPr->m_oDx.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Dx); + m_oBcw.m_oStream.WriteLONG(pFormControlPr->m_oDx->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pFormControlPr && pFormControlPr->m_oInc.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Inc); + m_oBcw.m_oStream.WriteLONG(pFormControlPr->m_oInc->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pFormControlPr && pFormControlPr->m_oMin.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Min); + m_oBcw.m_oStream.WriteLONG(pFormControlPr->m_oMin->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pFormControlPr && pFormControlPr->m_oMax.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Max); + m_oBcw.m_oStream.WriteLONG(pFormControlPr->m_oMax->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pFormControlPr && pFormControlPr->m_oPage.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Page); + m_oBcw.m_oStream.WriteLONG(pFormControlPr->m_oPage->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pFormControlPr && pFormControlPr->m_oSel.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Sel); + m_oBcw.m_oStream.WriteLONG(pFormControlPr->m_oSel->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pFormControlPr && pFormControlPr->m_oSelType.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::SelType); + m_oBcw.m_oStream.WriteBYTE(pFormControlPr->m_oSelType->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pFormControlPr && pFormControlPr->m_oTextHAlign.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::TextHAlign); + m_oBcw.m_oStream.WriteBYTE(pFormControlPr->m_oTextHAlign->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pFormControlPr && pFormControlPr->m_oTextVAlign.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::TextVAlign); + m_oBcw.m_oStream.WriteBYTE(pFormControlPr->m_oTextVAlign->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pFormControlPr && pFormControlPr->m_oVal.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Val); + m_oBcw.m_oStream.WriteLONG(*pFormControlPr->m_oVal); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pFormControlPr && pFormControlPr->m_oWidthMin.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::WidthMin); + m_oBcw.m_oStream.WriteLONG(pFormControlPr->m_oWidthMin->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pFormControlPr && pFormControlPr->m_oEditVal.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::EditVal); + m_oBcw.m_oStream.WriteBYTE(pFormControlPr->m_oEditVal->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pFormControlPr && pFormControlPr->m_oColored.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Colored); + m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oColored); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pFormControlPr && pFormControlPr->m_oFirstButton.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::FirstButton); + m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oFirstButton); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pFormControlPr && pFormControlPr->m_oHoriz.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::Horiz); + m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oHoriz); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pFormControlPr && pFormControlPr->m_oJustLastX.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::JustLastX); + m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oJustLastX); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pFormControlPr && pFormControlPr->m_oLockText.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::LockText); + m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oLockText); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pFormControlPr && pFormControlPr->m_oNoThreeD.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::NoThreeD); + m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oNoThreeD); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pFormControlPr && pFormControlPr->m_oNoThreeD2.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::NoThreeD2); + m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oNoThreeD2); + m_oBcw.WriteItemEnd(nCurPos); + } + if(pFormControlPr && pFormControlPr->m_oMultiSel.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerControlTypes::MultiSel); + m_oBcw.m_oStream.WriteStringW(*pFormControlPr->m_oMultiSel); + } + if (pFormControlPr && pFormControlPr->m_oMultiLine.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::MultiLine); + m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oMultiLine); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pFormControlPr && pFormControlPr->m_oVerticalBar.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::VerticalBar); + m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oVerticalBar); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pFormControlPr && pFormControlPr->m_oPasswordEdit.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::PasswordEdit); + m_oBcw.m_oStream.WriteBOOL(*pFormControlPr->m_oPasswordEdit); + m_oBcw.WriteItemEnd(nCurPos); + } + if (pFormControlPr && pFormControlPr->m_oText.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerControlTypes::Text); + m_oBcw.m_oStream.WriteStringW(*pFormControlPr->m_oText); + + } + if(pFormControlPr && pFormControlPr->m_oItemLst.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerControlTypes::ItemLst); + for (size_t i = 0; i < pFormControlPr->m_oItemLst->m_arrItems.size(); ++i) + { + if((pFormControlPr->m_oItemLst->m_arrItems[i].IsInit()) && + (pFormControlPr->m_oItemLst->m_arrItems[i]->m_oVal.IsInit())) + { + m_oBcw.m_oStream.WriteBYTE(c_oSerControlTypes::Item); + m_oBcw.m_oStream.WriteStringW(*pFormControlPr->m_oItemLst->m_arrItems[i]->m_oVal); + } + } + m_oBcw.WriteItemEnd(nCurPos); + } +} + +void BinaryWorksheetTableWriter::WriteDrawings(const OOX::Spreadsheet::CWorksheet& oWorksheet, OOX::Spreadsheet::CDrawing* pDrawing, OOX::CVmlDrawing *pVmlDrawing) +{ + for (size_t i = 0; pDrawing && i < pDrawing->m_arrItems.size(); ++i) + { + OOX::Spreadsheet::CCellAnchor* pCellAnchor = pDrawing->m_arrItems[i]; + +//we use legacyDrawing or objectPr in OleObject so skip shape in drawing + + if (!pCellAnchor->m_bShapeOle && !pCellAnchor->m_bShapeControl && pCellAnchor->isValid()) + { + if(oWorksheet.m_oOleObjects.IsInit() && pCellAnchor->m_nId.IsInit()) + { + boost::unordered_map::const_iterator pFind = oWorksheet.m_oOleObjects->m_mapOleObjects.find(pCellAnchor->m_nId.get()); + if (pFind != oWorksheet.m_oOleObjects->m_mapOleObjects.end()) + { + pCellAnchor->m_bShapeOle = true; + continue; + } + } + if(oWorksheet.m_oControls.IsInit() && pCellAnchor->m_nId.IsInit()) + { + std::map>::const_iterator pFind = oWorksheet.m_oControls->m_mapControls.find(pCellAnchor->m_nId.get()); + if (pFind != oWorksheet.m_oControls->m_mapControls.end()) + { + pCellAnchor->m_bShapeControl = true; + continue; + } + } + int nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Drawing); + WriteDrawing(oWorksheet, pDrawing, pCellAnchor, pVmlDrawing); + m_oBcw.WriteItemEnd(nCurPos); + } + } + WriteOleObjects(oWorksheet, pDrawing, pVmlDrawing); + + if (NULL != pVmlDrawing) + { + std::map::iterator it = pVmlDrawing->m_mapShapes.begin(); + + for (; it != pVmlDrawing->m_mapShapes.end(); it++) + { + if (it->second.bUsed == false) + {//Bonetti Martínez. cálculo estructural de pilotes y pilas.xlsx + OOX::WritingElement* pElem = it->second.pElement; + if(OOX::et_v_shapetype != pElem->getType()) + { + OOX::Vml::CShape* pShape = static_cast(pElem); + for(size_t j = 0; j < pShape->m_arrItems.size(); ++j) + { + OOX::WritingElement* pElemShape = pShape->m_arrItems[j]; + if(OOX::et_v_ClientData == pElemShape->getType()) + { + //преобразуем ClientData в CellAnchor + OOX::Vml::CClientData* pClientData = static_cast(pElemShape); + + if (pClientData->m_oObjectType.IsInit() && pClientData->m_oObjectType->GetValue() == SimpleTypes::Vml::vmlclientdataobjecttypeNote) + { + continue; + } + + SimpleTypes::Spreadsheet::CCellAnchorType eAnchorType; + eAnchorType.SetValue(SimpleTypes::Spreadsheet::cellanchorTwoCell); + + OOX::Spreadsheet::CCellAnchor *pCellAnchor = new OOX::Spreadsheet::CCellAnchor(eAnchorType); + if (pClientData->toCellAnchor(pCellAnchor)) + { + pCellAnchor->m_sVmlSpId.Init(); + pCellAnchor->m_sVmlSpId->append(it->first); + + int nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Drawing); + WriteDrawing(oWorksheet, pDrawing, pCellAnchor, pVmlDrawing, NULL); + m_oBcw.WriteItemEnd(nCurPos); + } + delete pCellAnchor; + } + } + } + it->second.bUsed = true; + } + } + } +} +void BinaryWorksheetTableWriter::WriteCellAnchor(OOX::Spreadsheet::CCellAnchor* pCellAnchor) +{ + if (!pCellAnchor) return; + +//Type + int nCurPos; + nCurPos = m_oBcw.WriteItemStart(c_oSer_DrawingType::Type); + m_oBcw.m_oStream.WriteBYTE(pCellAnchor->m_oAnchorType.GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + + if(pCellAnchor->m_oEditAs.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DrawingType::EditAs); + m_oBcw.m_oStream.WriteBYTE(pCellAnchor->m_oEditAs->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } +//From + if(pCellAnchor->m_oFrom.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DrawingType::From); + WriteFromTo(pCellAnchor->m_oFrom.get()); + m_oBcw.WriteItemEnd(nCurPos); + } +//To + if(pCellAnchor->m_oTo.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DrawingType::To); + WriteFromTo(pCellAnchor->m_oTo.get()); + m_oBcw.WriteItemEnd(nCurPos); + } +//Pos + if(pCellAnchor->m_oPos.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DrawingType::Pos); + WritePos(pCellAnchor->m_oPos.get()); + m_oBcw.WriteItemEnd(nCurPos); + } +//Ext + if(pCellAnchor->m_oExt.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DrawingType::Ext); + WriteExt(pCellAnchor->m_oExt.get()); + m_oBcw.WriteItemEnd(nCurPos); + } +//ClientData + if (pCellAnchor->m_oClientData.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DrawingType::ClientData); + WriteClientData(pCellAnchor->m_oClientData.get()); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryWorksheetTableWriter::WriteDrawing(const OOX::Spreadsheet::CWorksheet& oWorksheet, OOX::Spreadsheet::CDrawing* pDrawing, OOX::Spreadsheet::CCellAnchor* pCellAnchor, OOX::CVmlDrawing *pVmlDrawing, OOX::Spreadsheet::COleObject* pOleObject) +{ + if (!pCellAnchor) return; + + if (pCellAnchor->m_oElement.IsInit() == false && + pCellAnchor->m_sVmlSpId.IsInit() == false) return; + + m_oBcw.m_oStream.ClearCurShapePositionAndSizes(); + + WriteCellAnchor(pCellAnchor); + + if (pCellAnchor->m_oExt.IsInit()) + { + m_oBcw.m_oStream.m_dCxCurShape = pCellAnchor->m_oExt->m_oCx.IsInit() ? pCellAnchor->m_oExt->m_oCx->GetValue() : 0; + m_oBcw.m_oStream.m_dCyCurShape = pCellAnchor->m_oExt->m_oCy.IsInit() ? pCellAnchor->m_oExt->m_oCy->GetValue() : 0; + } + if (pCellAnchor->m_sVmlSpId.IsInit() && pVmlDrawing) + { + std::map::iterator pFind = pVmlDrawing->m_mapShapes.find(pCellAnchor->m_sVmlSpId.get2()); + + if (pFind != pVmlDrawing->m_mapShapes.end() && !pFind->second.bUsed) + { + pFind->second.bUsed = true; + + std::wstring sVmlXml = L""; + sVmlXml += pFind->second.sXml; //add vml shape xml + + if (pCellAnchor->m_bShapeOle && NULL != pOleObject) + { + //ищем физический файл, потому что rId относительно sheet.xml, а SetRelsPath(pVmlDrawing + smart_ptr pFile = oWorksheet.Find(OOX::RId(pOleObject->m_oRid->GetValue())); + pOleObject->m_OleObjectFile = pFile.smart_dynamic_cast(); + + NSStringUtils::CStringBuilder writer; + pOleObject->toXMLPptx(writer, L""); + + sVmlXml += writer.GetData(); + } + sVmlXml += L""; + + smart_ptr oldRels = m_pOfficeDrawingConverter->GetRels(); + m_pOfficeDrawingConverter->SetRels(pVmlDrawing); + + std::wstring* bstrOutputXml = NULL; + + m_oBcw.m_oStream.WriteBYTE(c_oSer_DrawingType::pptxDrawing); + int nCurPos = m_oBcw.WriteItemWithLengthStart(); + m_pOfficeDrawingConverter->AddObject(sVmlXml, &bstrOutputXml); + m_pOfficeDrawingConverter->SetRels(oldRels); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + RELEASEOBJECT(bstrOutputXml); + } + } + else if (pCellAnchor->m_oElement.IsInit()) + { + smart_ptr oldRels = m_oBcw.m_oStream.GetRels(); + m_oBcw.m_oStream.SetRels(pDrawing); + + m_oBcw.m_oStream.WriteBYTE(c_oSer_DrawingType::pptxDrawing); + int nCurPos = m_oBcw.WriteItemWithLengthStart(); + + m_oBcw.m_oStream.StartRecord(0); + m_oBcw.m_oStream.WriteRecord2(1, pCellAnchor->m_oElement->GetElem()); + m_oBcw.m_oStream.EndRecord(); + + if (pCellAnchor->m_oElement->GetElemAlternative().IsInit()) + { + m_oBcw.m_oStream.StartRecord(0x99); + m_oBcw.m_oStream.WriteRecord2(1, pCellAnchor->m_oElement->GetElemAlternative()); + m_oBcw.m_oStream.EndRecord(); + } + + m_oBcw.WriteItemWithLengthEnd(nCurPos); + + m_oBcw.m_oStream.SetRels(oldRels); + } +} +void BinaryWorksheetTableWriter::WriteLegacyDrawingHF(const OOX::Spreadsheet::CWorksheet& oWorksheet) +{ + int nCurPos = 0; + const OOX::Spreadsheet::CLegacyDrawingHFWorksheet& oLegacyDrawingHF = oWorksheet.m_oLegacyDrawingHF.get(); + if(oLegacyDrawingHF.m_oCfe.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_LegacyDrawingHF::Cfe); + m_oBcw.m_oStream.WriteLONG(oLegacyDrawingHF.m_oCfe->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oLegacyDrawingHF.m_oCff.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_LegacyDrawingHF::Cff); + m_oBcw.m_oStream.WriteLONG(oLegacyDrawingHF.m_oCff->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oLegacyDrawingHF.m_oCfo.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_LegacyDrawingHF::Cfo); + m_oBcw.m_oStream.WriteLONG(oLegacyDrawingHF.m_oCfo->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oLegacyDrawingHF.m_oChe.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_LegacyDrawingHF::Che); + m_oBcw.m_oStream.WriteLONG(oLegacyDrawingHF.m_oChe->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oLegacyDrawingHF.m_oChf.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_LegacyDrawingHF::Chf); + m_oBcw.m_oStream.WriteLONG(oLegacyDrawingHF.m_oChf->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oLegacyDrawingHF.m_oCho.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_LegacyDrawingHF::Cho); + m_oBcw.m_oStream.WriteLONG(oLegacyDrawingHF.m_oCho->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oLegacyDrawingHF.m_oLfe.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_LegacyDrawingHF::Lfe); + m_oBcw.m_oStream.WriteLONG(oLegacyDrawingHF.m_oLfe->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oLegacyDrawingHF.m_oLff.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_LegacyDrawingHF::Lff); + m_oBcw.m_oStream.WriteLONG(oLegacyDrawingHF.m_oLff->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oLegacyDrawingHF.m_oLfo.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_LegacyDrawingHF::Lfo); + m_oBcw.m_oStream.WriteLONG(oLegacyDrawingHF.m_oLfo->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oLegacyDrawingHF.m_oLhe.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_LegacyDrawingHF::Lhe); + m_oBcw.m_oStream.WriteLONG(oLegacyDrawingHF.m_oLhe->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oLegacyDrawingHF.m_oLhf.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_LegacyDrawingHF::Lhf); + m_oBcw.m_oStream.WriteLONG(oLegacyDrawingHF.m_oLhf->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oLegacyDrawingHF.m_oLho.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_LegacyDrawingHF::Lho); + m_oBcw.m_oStream.WriteLONG(oLegacyDrawingHF.m_oLho->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oLegacyDrawingHF.m_oRfe.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_LegacyDrawingHF::Rfe); + m_oBcw.m_oStream.WriteLONG(oLegacyDrawingHF.m_oRfe->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oLegacyDrawingHF.m_oRff.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_LegacyDrawingHF::Rff); + m_oBcw.m_oStream.WriteLONG(oLegacyDrawingHF.m_oRff->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oLegacyDrawingHF.m_oRfo.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_LegacyDrawingHF::Rfo); + m_oBcw.m_oStream.WriteLONG(oLegacyDrawingHF.m_oRfo->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oLegacyDrawingHF.m_oRhe.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_LegacyDrawingHF::Rhe); + m_oBcw.m_oStream.WriteLONG(oLegacyDrawingHF.m_oRhe->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oLegacyDrawingHF.m_oRhf.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_LegacyDrawingHF::Rhf); + m_oBcw.m_oStream.WriteLONG(oLegacyDrawingHF.m_oRhf->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oLegacyDrawingHF.m_oRho.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_LegacyDrawingHF::Rho); + m_oBcw.m_oStream.WriteLONG(oLegacyDrawingHF.m_oRho->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if(oLegacyDrawingHF.m_oId.IsInit()) + { + smart_ptr oFileV = oWorksheet.Find(oLegacyDrawingHF.m_oId->GetValue()); + if (oFileV.IsInit() && OOX::FileTypes::VmlDrawing == oFileV->type()) + { + OOX::CVmlDrawing* pVmlDrawing = (OOX::CVmlDrawing*)oFileV.GetPointer(); + smart_ptr oldRels = m_pOfficeDrawingConverter->GetRels(); + m_pOfficeDrawingConverter->SetRels(pVmlDrawing); + m_pOfficeDrawingConverter->Clear(); + nCurPos = m_oBcw.WriteItemStart(c_oSer_LegacyDrawingHF::Drawings); + WriteLegacyDrawingHFDrawings(pVmlDrawing); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + m_pOfficeDrawingConverter->SetRels(oldRels); + } + } +} +void BinaryWorksheetTableWriter::WriteLegacyDrawingHFDrawings(OOX::CVmlDrawing* pVmlDrawing) +{ + for (size_t i = 0; i < pVmlDrawing->m_arrShapeTypes.size(); ++i) + { + m_pOfficeDrawingConverter->AddShapeType(pVmlDrawing->m_arrShapeTypes[i].sXml); + } + std::map::iterator it = pVmlDrawing->m_mapShapes.begin(); + for (; it != pVmlDrawing->m_mapShapes.end(); it++) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_LegacyDrawingHF::Drawing); + WriteLegacyDrawingHFDrawing(it->second); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorksheetTableWriter::WriteLegacyDrawingHFDrawing(const OOX::CVmlDrawing::_vml_shape& oVmlShape) +{ + OOX::Vml::CVmlCommonElements* common = dynamic_cast(oVmlShape.pElement); + std::wstring sId; + if (common) + { + if (common->m_sId.IsInit()) + { + sId = *common->m_sId; + } + } + else + { + OOX::Vml::CGroup *group = dynamic_cast(oVmlShape.pElement); + if (group) + { + if (group->m_sId.IsInit()) + { + sId = *group->m_sId; + } + } + } + int nCurPos = m_oBcw.WriteItemStart(c_oSer_LegacyDrawingHF::DrawingId); + m_oBcw.m_oStream.WriteStringW3(sId); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + + std::wstring sVmlXml = L""; + sVmlXml += oVmlShape.sXml; //add vml shape xml + sVmlXml += L""; + + std::wstring* bstrOutputXml = NULL; + nCurPos = m_oBcw.WriteItemStart(c_oSer_LegacyDrawingHF::DrawingShape); + m_pOfficeDrawingConverter->AddObject(sVmlXml, &bstrOutputXml); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + RELEASEOBJECT(bstrOutputXml); +} + +void BinaryWorksheetTableWriter::WriteFromTo(const OOX::Spreadsheet::CFromTo& oFromTo) +{ + //Col + if(oFromTo.m_oCol.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DrawingFromToType::Col); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oFromTo.m_oCol->GetValue()); + } + //ColOff + if(oFromTo.m_oColOff.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DrawingFromToType::ColOff); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Double); + m_oBcw.m_oStream.WriteDoubleReal(oFromTo.m_oColOff->ToMm()); + } + //Row + if(oFromTo.m_oRow.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DrawingFromToType::Row); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oFromTo.m_oRow->GetValue()); + } + //ColOff + if(oFromTo.m_oRowOff.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DrawingFromToType::RowOff); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Double); + m_oBcw.m_oStream.WriteDoubleReal(oFromTo.m_oRowOff->ToMm()); + } +} +void BinaryWorksheetTableWriter::WritePos(const OOX::Spreadsheet::CPos& oPos) +{ + //X + if(oPos.m_oX.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DrawingPosType::X); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Double); + m_oBcw.m_oStream.WriteDoubleReal(oPos.m_oX->ToMm()); + } + //Y + if(oPos.m_oY.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DrawingPosType::Y); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Double); + m_oBcw.m_oStream.WriteDoubleReal(oPos.m_oY->ToMm()); + } +} +void BinaryWorksheetTableWriter::WriteClientData(const OOX::Spreadsheet::CClientData& oClientData) +{ + if (oClientData.fLocksWithSheet.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DrawingClientDataType::fLocksWithSheet); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(*oClientData.fLocksWithSheet); + } + if (oClientData.fPrintsWithSheet.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DrawingClientDataType::fPrintsWithSheet); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(*oClientData.fPrintsWithSheet); + } +} + +void BinaryWorksheetTableWriter::WriteExt(const OOX::Spreadsheet::CExt& oExt) +{ +//Cx + if(oExt.m_oCx.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DrawingExtType::Cx); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Double); + m_oBcw.m_oStream.WriteDoubleReal(oExt.m_oCx->ToMm()); + } +//Cy + if(oExt.m_oCy.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DrawingExtType::Cy); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Double); + m_oBcw.m_oStream.WriteDoubleReal(oExt.m_oCy->ToMm()); + } +} +void BinaryWorksheetTableWriter::WriteComments(std::map& mapComments) +{ + int nCurPos = 0; + + for (std::map::const_iterator it = mapComments.begin(); it != mapComments.end(); ++it) + { + if(it->second->IsValid()) + { + OOX::Spreadsheet::CCommentItem& oComment = *it->second; + std::vector aCommentDatas; + + getSavedComment(oComment, aCommentDatas); + + //записываем тот обьект, который был в бинарнике, подменяем только текст, который мог быть отредактирован в Excel + + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Comment); + WriteComment(oComment, aCommentDatas); + m_oBcw.WriteItemEnd(nCurPos); + + for(size_t i = 0, length = aCommentDatas.size(); i < length; ++i) + { + RELEASEOBJECT(aCommentDatas[i]); + } + aCommentDatas.clear(); + } + } +} +void BinaryWorksheetTableWriter::getSavedComment(OOX::Spreadsheet::CCommentItem& oComment, std::vector& aDatas) +{ + if(oComment.m_sGfxdata.IsInit()) + { + const std::wstring& sGfxData = *oComment.m_sGfxdata; + std::wstring sSignatureBase64Old(_T("WExTV"));//XLST + std::wstring sSignatureBase64(_T("WExTM"));//XLS2 + //compatibility with fact that previously used long that can be 4 or 8 byte + bool bCompatibility = sSignatureBase64Old == sGfxData.substr(0, sSignatureBase64Old.length()); + bool isComment = (sSignatureBase64 == sGfxData.substr(0, sSignatureBase64.length())) || bCompatibility; + if(isComment) + { + std::string sSignature("XLS2"); + int nSignatureSize = (int)sSignature.length(); + int nDataLengthSize = bCompatibility ? sizeof(long) : sizeof(_INT32); + int nJunkSize = 2; + std::string sGfxDataA = std::string(sGfxData.begin(), sGfxData.end()); + int nDataSize = (int)sGfxDataA.length(); + BYTE* pBuffer = new BYTE[nDataSize]; + if(false != Base64::Base64Decode((const char*)sGfxDataA.c_str(), (int)sGfxDataA.length(), pBuffer, &nDataSize)) + { + int nLength; + if (bCompatibility) + { + nLength = *((long*)(pBuffer + nSignatureSize)); + } + else + { + nLength = *((_INT32*)(pBuffer + nSignatureSize)); + } + NSBinPptxRW::CBinaryFileReader oBufferedStream; + oBufferedStream.Init((BYTE*)pBuffer, nSignatureSize + nDataLengthSize, nLength); + + BinaryCommentReader oBinaryCommentReader(oBufferedStream, NULL); + oBinaryCommentReader.ReadExternal(nLength, &aDatas); + } + RELEASEARRAYOBJECTS(pBuffer); + } + } +} +void BinaryWorksheetTableWriter::WriteComment(OOX::Spreadsheet::CCommentItem& oComment, std::vector& aCommentDatas) +{ + int nCurPos = 0; + int nRow = 0; + int nCol = 0; + if(oComment.m_nRow.IsInit()) + { + nRow = oComment.m_nRow.get(); + m_oBcw.m_oStream.WriteBYTE(c_oSer_Comments::Row); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(nRow); + } + if(oComment.m_nCol.IsInit()) + { + nCol = oComment.m_nCol.get(); + m_oBcw.m_oStream.WriteBYTE(c_oSer_Comments::Col); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(nCol); + } + m_oBcw.m_oStream.WriteBYTE(c_oSer_Comments::CommentDatas); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + nCurPos = m_oBcw.WriteItemWithLengthStart(); + WriteCommentData(oComment, aCommentDatas); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + + if(oComment.m_nLeft.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Comments::Left); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oComment.m_nLeft.get()); + } + if(oComment.m_nLeftOffset.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Comments::LeftOffset); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oComment.m_nLeftOffset.get()); + } + if(oComment.m_nTop.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Comments::Top); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oComment.m_nTop.get()); + } + if(oComment.m_nTopOffset.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Comments::TopOffset); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oComment.m_nTopOffset.get()); + } + if(oComment.m_nRight.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Comments::Right); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oComment.m_nRight.get()); + } + if(oComment.m_nRightOffset.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Comments::RightOffset); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oComment.m_nRightOffset.get()); + } + if(oComment.m_nBottom.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Comments::Bottom); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oComment.m_nBottom.get()); + } + if(oComment.m_nBottomOffset.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Comments::BottomOffset); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oComment.m_nBottomOffset.get()); + } + if(oComment.m_dLeftMM.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Comments::LeftMM); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Double); + m_oBcw.m_oStream.WriteDoubleReal(oComment.m_dLeftMM.get()); + } + if(oComment.m_dTopMM.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Comments::TopMM); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Double); + m_oBcw.m_oStream.WriteDoubleReal(oComment.m_dTopMM.get()); + } + if(oComment.m_dWidthMM.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Comments::WidthMM); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Double); + m_oBcw.m_oStream.WriteDoubleReal(oComment.m_dWidthMM.get()); + } + if(oComment.m_dHeightMM.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Comments::HeightMM); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Double); + m_oBcw.m_oStream.WriteDoubleReal(oComment.m_dHeightMM.get()); + } + if(oComment.m_bMove.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Comments::MoveWithCells); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oComment.m_bMove.get()); + } + if(oComment.m_bSize.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Comments::SizeWithCells); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oComment.m_bSize.get()); + } + if(NULL != oComment.m_pThreadedComment) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Comments::ThreadedComment); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + nCurPos = m_oBcw.WriteItemWithLengthStart(); + WriteThreadedComment(*oComment.m_pThreadedComment, oComment.m_bThreadedCommentCopy); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorksheetTableWriter::WriteCommentData(OOX::Spreadsheet::CCommentItem& oComment, std::vector& aCommentDatas) +{ + bool isThreadedComment = NULL != oComment.m_pThreadedComment; + int nCurPos = 0; + if(aCommentDatas.size() > 0) + { + for(size_t i = 0, length = aCommentDatas.size(); i < length; ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Comments::CommentData); + if(0 == i) + WriteCommentDataContent(&oComment, aCommentDatas[i], isThreadedComment); + else + WriteCommentDataContent(NULL, aCommentDatas[i], isThreadedComment); + m_oBcw.WriteItemEnd(nCurPos); + } + } + else + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Comments::CommentData); + WriteCommentDataContent(&oComment, NULL, isThreadedComment); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryWorksheetTableWriter::WriteCommentDataContent(OOX::Spreadsheet::CCommentItem* pComment, SerializeCommon::CommentData* pCommentData, bool isThreadedComment) +{ + int nCurPos = 0; + if(NULL != pCommentData && !pCommentData->sText.empty()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_CommentData::Text); + m_oBcw.m_oStream.WriteStringW(pCommentData->sText); + } + else if(NULL != pComment && pComment->m_oText.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_CommentData::Text); + m_oBcw.m_oStream.WriteStringW(pComment->m_oText->ToString()); + } + if(NULL != pCommentData) + { + if(!pCommentData->sTime.empty()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_CommentData::Time); + m_oBcw.m_oStream.WriteStringW(pCommentData->sTime); + } + if(!pCommentData->sOOTime.empty()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_CommentData::OOTime); + m_oBcw.m_oStream.WriteStringW(pCommentData->sOOTime); + } + if (!pCommentData->sUserId.empty()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_CommentData::UserId); + m_oBcw.m_oStream.WriteStringW(pCommentData->sUserId); + } + if (!pCommentData->sUserName.empty()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_CommentData::UserName); + m_oBcw.m_oStream.WriteStringW(pCommentData->sUserName); + } + if (!pCommentData->sUserData.empty()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_CommentData::UserData); + m_oBcw.m_oStream.WriteStringW(pCommentData->sUserData); + } + if (!pCommentData->sQuoteText.empty()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_CommentData::QuoteText); + m_oBcw.m_oStream.WriteStringW(pCommentData->sQuoteText); + } + if(pCommentData->bSolved) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_CommentData::Solved); + m_oBcw.m_oStream.WriteBOOL(pCommentData->Solved); + m_oBcw.WriteItemEnd(nCurPos); + } + if(pCommentData->bDocument) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_CommentData::Document); + m_oBcw.m_oStream.WriteBOOL(pCommentData->Document); + m_oBcw.WriteItemEnd(nCurPos); + } + if(pCommentData->aReplies.size() > 0) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_CommentData::Replies); + WriteCommentReplies(pCommentData->aReplies, isThreadedComment); + m_oBcw.WriteItemEnd(nCurPos); + } + } + else if(NULL != pComment) + { + if(pComment->m_sAuthor.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_CommentData::UserName); + m_oBcw.m_oStream.WriteStringW(*pComment->m_sAuthor); + } + } + if(!isThreadedComment) + { + if(pCommentData && !pCommentData->sGuid.empty()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_CommentData::Guid); + m_oBcw.m_oStream.WriteStringW(pCommentData->sGuid); + } + else + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_CommentData::Guid); + m_oBcw.m_oStream.WriteStringW(L"{" + XmlUtils::GenerateGuid() + L"}"); + } + } +} +void BinaryWorksheetTableWriter::WriteCommentReplies(std::vector& aReplies, bool isThreadedComment) +{ + int nCurPos = 0; + for(size_t i = 0, length = aReplies.size(); i < length; i++) + { + SerializeCommon::CommentData* pReply = aReplies[i]; + nCurPos = m_oBcw.WriteItemStart(c_oSer_CommentData::Reply); + WriteCommentDataContent(NULL, pReply, isThreadedComment); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryWorksheetTableWriter::WriteThreadedComment(OOX::Spreadsheet::CThreadedComment& oThreadedComment, bool bThreadedCommentCopy) +{ + int nCurPos = 0; + + if(oThreadedComment.dT.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ThreadedComment::dT); + m_oBcw.m_oStream.WriteStringW3(oThreadedComment.dT->ToString()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(oThreadedComment.personId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ThreadedComment::personId); + m_oBcw.m_oStream.WriteStringW3(oThreadedComment.personId->ToString()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(bThreadedCommentCopy || !oThreadedComment.id.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ThreadedComment::id); + m_oBcw.m_oStream.WriteStringW3(L"{" + XmlUtils::GenerateGuid() + L"}"); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + else + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ThreadedComment::id); + m_oBcw.m_oStream.WriteStringW3(oThreadedComment.id->ToString()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(oThreadedComment.done.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ThreadedComment::done); + m_oBcw.m_oStream.WriteBOOL(oThreadedComment.done.get()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(oThreadedComment.m_oText.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ThreadedComment::text); + m_oBcw.m_oStream.WriteStringW3(oThreadedComment.m_oText->ToString()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(oThreadedComment.m_oMentions.IsInit()) + { + for(size_t i = 0; i < oThreadedComment.m_oMentions->m_arrItems.size(); ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ThreadedComment::mention); + WriteThreadedCommentMention(*oThreadedComment.m_oMentions->m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + } + for(size_t i = 0; i < oThreadedComment.m_arrReplies.size(); ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ThreadedComment::reply); + WriteThreadedComment(*oThreadedComment.m_arrReplies[i], bThreadedCommentCopy); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorksheetTableWriter::WriteThreadedCommentMention(OOX::Spreadsheet::CThreadedCommentMention& oMention) +{ + int nCurPos = 0; + if(oMention.mentionpersonId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ThreadedComment::mentionpersonId); + m_oBcw.m_oStream.WriteStringW3(oMention.mentionpersonId->ToString()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(oMention.mentionId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ThreadedComment::mentionId); + m_oBcw.m_oStream.WriteStringW3(oMention.mentionId->ToString()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(oMention.startIndex.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ThreadedComment::startIndex); + m_oBcw.m_oStream.WriteULONG(oMention.startIndex->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + if(oMention.length.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ThreadedComment::length); + m_oBcw.m_oStream.WriteULONG(oMention.length->GetValue()); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryWorksheetTableWriter::WriteSheetPr(const OOX::Spreadsheet::CSheetPr& oSheetPr) +{ + int nCurPos = 0; + if (oSheetPr.m_oCodeName.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetPr::CodeName); + m_oBcw.m_oStream.WriteStringW4(*oSheetPr.m_oCodeName); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSheetPr.m_oEnableFormatConditionsCalculation.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetPr::EnableFormatConditionsCalculation); + m_oBcw.m_oStream.WriteBOOL(oSheetPr.m_oEnableFormatConditionsCalculation->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSheetPr.m_oFilterMode.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetPr::FilterMode); + m_oBcw.m_oStream.WriteBOOL(oSheetPr.m_oFilterMode->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSheetPr.m_oPublished.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetPr::Published); + m_oBcw.m_oStream.WriteBOOL(oSheetPr.m_oPublished->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSheetPr.m_oSyncHorizontal.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetPr::SyncHorizontal); + m_oBcw.m_oStream.WriteBOOL(oSheetPr.m_oSyncHorizontal->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSheetPr.m_oSyncRef.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetPr::SyncRef); + m_oBcw.m_oStream.WriteStringW4(*oSheetPr.m_oSyncRef); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSheetPr.m_oSyncVertical.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetPr::SyncVertical); + m_oBcw.m_oStream.WriteBOOL(oSheetPr.m_oSyncVertical->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSheetPr.m_oTransitionEntry.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetPr::TransitionEntry); + m_oBcw.m_oStream.WriteBOOL(oSheetPr.m_oTransitionEntry->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSheetPr.m_oTransitionEvaluation.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetPr::TransitionEvaluation); + m_oBcw.m_oStream.WriteBOOL(oSheetPr.m_oTransitionEvaluation->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + + if (oSheetPr.m_oTabColor.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetPr::TabColor); + m_oBcw.WriteColor(oSheetPr.m_oTabColor.get(), m_pIndexedColors); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSheetPr.m_oPageSetUpPr.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetPr::PageSetUpPr); + WritePageSetUpPr(oSheetPr.m_oPageSetUpPr.get()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSheetPr.m_oOutlinePr.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetPr::OutlinePr); + WriteOutlinePr(oSheetPr.m_oOutlinePr.get()); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryWorksheetTableWriter::WriteOutlinePr(const OOX::Spreadsheet::COutlinePr& oOutlinePr) +{ + int nCurPos = 0; + if (oOutlinePr.m_oApplyStyles.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetPr::ApplyStyles); + m_oBcw.m_oStream.WriteBOOL(oOutlinePr.m_oApplyStyles->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oOutlinePr.m_oShowOutlineSymbols.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetPr::ShowOutlineSymbols); + m_oBcw.m_oStream.WriteBOOL(oOutlinePr.m_oShowOutlineSymbols->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oOutlinePr.m_oSummaryBelow.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetPr::SummaryBelow); + m_oBcw.m_oStream.WriteBOOL(oOutlinePr.m_oSummaryBelow->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oOutlinePr.m_oSummaryRight.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetPr::SummaryRight); + m_oBcw.m_oStream.WriteBOOL(oOutlinePr.m_oSummaryRight->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryWorksheetTableWriter::WritePageSetUpPr(const OOX::Spreadsheet::CPageSetUpPr& oPageSetUpPr) +{ + int nCurPos = 0; + if (oPageSetUpPr.m_oAutoPageBreaks.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetPr::AutoPageBreaks); + m_oBcw.m_oStream.WriteBOOL(oPageSetUpPr.m_oAutoPageBreaks->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oPageSetUpPr.m_oFitToPage.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_SheetPr::FitToPage); + m_oBcw.m_oStream.WriteBOOL(oPageSetUpPr.m_oFitToPage->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryWorksheetTableWriter::WritemHeaderFooter(const OOX::Spreadsheet::CHeaderFooter& oHeaderFooter) +{ + int nCurPos = 0; + if (oHeaderFooter.m_oAlignWithMargins.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_HeaderFooter::AlignWithMargins); + m_oBcw.m_oStream.WriteBOOL(oHeaderFooter.m_oAlignWithMargins->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oHeaderFooter.m_oDifferentFirst.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_HeaderFooter::DifferentFirst); + m_oBcw.m_oStream.WriteBOOL(oHeaderFooter.m_oDifferentFirst->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oHeaderFooter.m_oDifferentOddEven.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_HeaderFooter::DifferentOddEven); + m_oBcw.m_oStream.WriteBOOL(oHeaderFooter.m_oDifferentOddEven->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oHeaderFooter.m_oScaleWithDoc.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_HeaderFooter::ScaleWithDoc); + m_oBcw.m_oStream.WriteBOOL(oHeaderFooter.m_oScaleWithDoc->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oHeaderFooter.m_oEvenFooter.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_HeaderFooter::EvenFooter); + m_oBcw.m_oStream.WriteStringW3(oHeaderFooter.m_oEvenFooter->m_sText); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oHeaderFooter.m_oEvenHeader.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_HeaderFooter::EvenHeader); + m_oBcw.m_oStream.WriteStringW3(oHeaderFooter.m_oEvenHeader->m_sText); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oHeaderFooter.m_oFirstFooter.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_HeaderFooter::FirstFooter); + m_oBcw.m_oStream.WriteStringW3(oHeaderFooter.m_oFirstFooter->m_sText); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oHeaderFooter.m_oFirstHeader.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_HeaderFooter::FirstHeader); + m_oBcw.m_oStream.WriteStringW3(oHeaderFooter.m_oFirstHeader->m_sText); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oHeaderFooter.m_oOddFooter.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_HeaderFooter::OddFooter); + m_oBcw.m_oStream.WriteStringW3(oHeaderFooter.m_oOddFooter->m_sText); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oHeaderFooter.m_oOddHeader.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_HeaderFooter::OddHeader); + m_oBcw.m_oStream.WriteStringW3(oHeaderFooter.m_oOddHeader->m_sText); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryWorksheetTableWriter::WritemRowColBreaks(const OOX::Spreadsheet::CRowColBreaks& oRowColBreaks) +{ + int nCurPos = 0; + if (oRowColBreaks.m_oCount.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_RowColBreaks::Count); + m_oBcw.m_oStream.WriteLONG(oRowColBreaks.m_oCount->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oRowColBreaks.m_oManualBreakCount.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_RowColBreaks::ManualBreakCount); + m_oBcw.m_oStream.WriteLONG(oRowColBreaks.m_oManualBreakCount->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + for (size_t i = 0; i < oRowColBreaks.m_arrItems.size(); ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_RowColBreaks::Break); + WritemBreak(*oRowColBreaks.m_arrItems[i]); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryWorksheetTableWriter::WritemBreak(const OOX::Spreadsheet::CBreak& oBreak) +{ + int nCurPos = 0; + if (oBreak.m_oId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_RowColBreaks::Id); + m_oBcw.m_oStream.WriteLONG(oBreak.m_oId->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oBreak.m_oMan.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_RowColBreaks::Man); + m_oBcw.m_oStream.WriteBOOL(oBreak.m_oMan->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oBreak.m_oMax.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_RowColBreaks::Max); + m_oBcw.m_oStream.WriteLONG(oBreak.m_oMax->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oBreak.m_oMin.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_RowColBreaks::Min); + m_oBcw.m_oStream.WriteLONG(oBreak.m_oMin->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oBreak.m_oPt.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_RowColBreaks::Pt); + m_oBcw.m_oStream.WriteBOOL(oBreak.m_oPt->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryWorksheetTableWriter::WriteConditionalFormattings(std::vector& arrConditionalFormatting, + std::map& mapCFRuleEx, bool isExt) +{ + int nCurPos = 0; + for (size_t nIndex = 0, nLength = arrConditionalFormatting.size(); nIndex < nLength; ++nIndex) + { + if (arrConditionalFormatting[nIndex]->IsUsage()) continue; + + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::ConditionalFormatting); + WriteConditionalFormatting(*arrConditionalFormatting[nIndex], mapCFRuleEx, isExt); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryWorksheetTableWriter::WriteConditionalFormatting(const OOX::Spreadsheet::CConditionalFormatting& oConditionalFormatting, + std::map& mapCFRuleEx, bool isExt) +{ + int nCurPos = 0; + + if (oConditionalFormatting.m_oPivot.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormatting::Pivot); + m_oBcw.m_oStream.WriteBOOL(oConditionalFormatting.m_oPivot->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oConditionalFormatting.m_oSqRef.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_ConditionalFormatting::SqRef); + m_oBcw.m_oStream.WriteStringW(oConditionalFormatting.m_oSqRef.get()); + } + + if (false == oConditionalFormatting.m_arrItems.empty()) + { + for (size_t i = 0, length = oConditionalFormatting.m_arrItems.size(); i < length; ++i) + { + int nCurPos1 = m_oBcw.WriteItemStart(c_oSer_ConditionalFormatting::ConditionalFormattingRule); + WriteConditionalFormattingRule(*oConditionalFormatting.m_arrItems[i], mapCFRuleEx, isExt); + m_oBcw.WriteItemEnd(nCurPos1); + } + } +} +void BinaryWorksheetTableWriter::WriteConditionalFormattingRule(const OOX::Spreadsheet::CConditionalFormattingRule& oConditionalFormattingRule, + std::map& mapCFRuleEx, bool isExt) +{ + std::map::iterator pFind; + if (oConditionalFormattingRule.m_oExtId.IsInit()) + { + pFind = mapCFRuleEx.find(*oConditionalFormattingRule.m_oExtId); + + if (pFind != mapCFRuleEx.end()) + { + const OOX::Spreadsheet::CConditionalFormattingRule newRule = + OOX::Spreadsheet::CConditionalFormattingRule::Merge(oConditionalFormattingRule, *pFind->second); + + pFind->second->bUsage = true; + return WriteConditionalFormattingRule(newRule, mapCFRuleEx, true); + } + } + int nCurPos = 0; + + if (oConditionalFormattingRule.m_oAboveAverage.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingRule::AboveAverage); + m_oBcw.m_oStream.WriteBOOL(oConditionalFormattingRule.m_oAboveAverage->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oConditionalFormattingRule.m_oBottom.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingRule::Bottom); + m_oBcw.m_oStream.WriteBOOL(oConditionalFormattingRule.m_oBottom->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oConditionalFormattingRule.m_oDxfId.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingRule::DxfId); + m_oBcw.m_oStream.WriteLONG(oConditionalFormattingRule.m_oDxfId->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oConditionalFormattingRule.m_oEqualAverage.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingRule::EqualAverage); + m_oBcw.m_oStream.WriteBOOL(oConditionalFormattingRule.m_oEqualAverage->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oConditionalFormattingRule.m_oOperator.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingRule::Operator); + m_oBcw.m_oStream.WriteBYTE(oConditionalFormattingRule.m_oOperator->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oConditionalFormattingRule.m_oPercent.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingRule::Percent); + m_oBcw.m_oStream.WriteBOOL(oConditionalFormattingRule.m_oPercent->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oConditionalFormattingRule.m_oPriority.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingRule::Priority); + m_oBcw.m_oStream.WriteLONG(oConditionalFormattingRule.m_oPriority->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oConditionalFormattingRule.m_oRank.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingRule::Rank); + m_oBcw.m_oStream.WriteLONG(oConditionalFormattingRule.m_oRank->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oConditionalFormattingRule.m_oStdDev.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingRule::StdDev); + m_oBcw.m_oStream.WriteLONG(oConditionalFormattingRule.m_oStdDev->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oConditionalFormattingRule.m_oStopIfTrue.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingRule::StopIfTrue); + m_oBcw.m_oStream.WriteBOOL(oConditionalFormattingRule.m_oStopIfTrue->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oConditionalFormattingRule.m_oText.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_ConditionalFormattingRule::Text); + m_oBcw.m_oStream.WriteStringW(oConditionalFormattingRule.m_oText.get2()); + } + if (oConditionalFormattingRule.m_oTimePeriod.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_ConditionalFormattingRule::strTimePeriod); + m_oBcw.m_oStream.WriteStringW(oConditionalFormattingRule.m_oTimePeriod->ToString()); + + //m_oBcw.m_oStream.WriteBYTE(c_oSer_ConditionalFormattingRule::TimePeriod); + //m_oBcw.m_oStream.WriteBYTE(oConditionalFormattingRule.m_oTimePeriod->GetValue()); + } + if (oConditionalFormattingRule.m_oType.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingRule::Type); + m_oBcw.m_oStream.WriteBYTE(oConditionalFormattingRule.m_oType->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oConditionalFormattingRule.m_oDxf.IsInit()) + { + BinaryStyleTableWriter oBinaryStyleTableWriter(m_oBcw.m_oStream, m_pEmbeddedFontsManager); + + int nCurPos1 = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingRule::Dxf); + oBinaryStyleTableWriter.WriteDxf(oConditionalFormattingRule.m_oDxf.get(), m_pIndexedColors, m_pTheme, m_oFontProcessor); + m_oBcw.WriteItemEnd(nCurPos1); + } + + if (oConditionalFormattingRule.m_oColorScale.IsInit()) + { + int nCurPos1 = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingRule::ColorScale); + WriteColorScale(oConditionalFormattingRule.m_oColorScale.get()); + m_oBcw.WriteItemEnd(nCurPos1); + } + if (oConditionalFormattingRule.m_oDataBar.IsInit()) + { + int nCurPos1 = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingRule::DataBar); + WriteDataBar(oConditionalFormattingRule.m_oDataBar.get()); + m_oBcw.WriteItemEnd(nCurPos1); + } + for (size_t i = 0; i < oConditionalFormattingRule.m_arrFormula.size(); ++i) + { + if (oConditionalFormattingRule.m_arrFormula[i].IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_ConditionalFormattingRule::FormulaCF); + m_oBcw.m_oStream.WriteStringW(oConditionalFormattingRule.m_arrFormula[i]->m_sText); + } + } + if (oConditionalFormattingRule.m_oIconSet.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingRule::IconSet); + WriteIconSet(oConditionalFormattingRule.m_oIconSet.get()); + m_oBcw.WriteItemEnd(nCurPos); + } + + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingRule::IsExt); + m_oBcw.m_oStream.WriteBOOL(isExt); + m_oBcw.WriteItemEnd(nCurPos); +} + +void BinaryWorksheetTableWriter::WriteColorScale(const OOX::Spreadsheet::CColorScale& oColorScale) +{ + // ToDo более правильно заделать виртуальную функцию, которая будет писать без привидения типов + + for (size_t i = 0, length = oColorScale.m_arrValues.size(); i < length; ++i) + { + if (oColorScale.m_arrValues[i].IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingRuleColorScale::CFVO); + WriteCFVO(oColorScale.m_arrValues[i].get()); + m_oBcw.WriteItemEnd(nCurPos); + } + } + + for (size_t i = 0, length = oColorScale.m_arrColors.size(); i < length; ++i) + { + if (oColorScale.m_arrColors[i].IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingRuleColorScale::Color); + m_oBcw.WriteColor(oColorScale.m_arrColors[i].get(), m_pIndexedColors); + m_oBcw.WriteItemEnd(nCurPos); + } + } +} +void BinaryWorksheetTableWriter::WriteDataBar(const OOX::Spreadsheet::CDataBar& oDataBar) +{ + int nCurPos = 0; + + if (oDataBar.m_oMaxLength.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingDataBar::MaxLength); + m_oBcw.m_oStream.WriteLONG(oDataBar.m_oMaxLength->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oDataBar.m_oMinLength.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingDataBar::MinLength); + m_oBcw.m_oStream.WriteLONG(oDataBar.m_oMinLength->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oDataBar.m_oShowValue.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingDataBar::ShowValue); + m_oBcw.m_oStream.WriteBOOL(oDataBar.m_oShowValue->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oDataBar.m_oGradient.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingDataBar::GradientEnabled); + m_oBcw.m_oStream.WriteBOOL(oDataBar.m_oGradient->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oDataBar.m_oNegativeBarColorSameAsPositive.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingDataBar::NegativeBarColorSameAsPositive); + m_oBcw.m_oStream.WriteBOOL(oDataBar.m_oNegativeBarColorSameAsPositive->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oDataBar.m_oNegativeBarBorderColorSameAsPositive.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingDataBar::NegativeBarBorderColorSameAsPositive); + m_oBcw.m_oStream.WriteBOOL(oDataBar.m_oNegativeBarBorderColorSameAsPositive->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oDataBar.m_oAxisPosition.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingDataBar::AxisPosition); + m_oBcw.m_oStream.WriteLONG(oDataBar.m_oAxisPosition->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oDataBar.m_oDirection.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingDataBar::Direction); + m_oBcw.m_oStream.WriteLONG(oDataBar.m_oDirection->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oDataBar.m_oColor.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingDataBar::Color); + m_oBcw.WriteColor(oDataBar.m_oColor.get(), m_pIndexedColors); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oDataBar.m_oBorderColor.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingDataBar::BorderColor); + m_oBcw.WriteColor(oDataBar.m_oBorderColor.get(), m_pIndexedColors); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oDataBar.m_oAxisColor.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingDataBar::AxisColor); + m_oBcw.WriteColor(oDataBar.m_oAxisColor.get(), m_pIndexedColors); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oDataBar.m_oNegativeFillColor.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingDataBar::NegativeColor); + m_oBcw.WriteColor(oDataBar.m_oNegativeFillColor.get(), m_pIndexedColors); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oDataBar.m_oNegativeBorderColor.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingDataBar::NegativeBorderColor); + m_oBcw.WriteColor(oDataBar.m_oNegativeBorderColor.get(), m_pIndexedColors); + m_oBcw.WriteItemEnd(nCurPos); + } + + for (size_t i = 0, length = oDataBar.m_arrValues.size(); i < length; ++i) + { + if (oDataBar.m_arrValues[i].IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingDataBar::CFVO); + WriteCFVO(oDataBar.m_arrValues[i].get()); + m_oBcw.WriteItemEnd(nCurPos); + } + } +} +void BinaryWorksheetTableWriter::WriteIconSet(const OOX::Spreadsheet::CIconSet& oIconSet) +{ + int nCurPos = 0; + + if (oIconSet.m_oIconSet.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingIconSet::IconSet); + m_oBcw.m_oStream.WriteBYTE(oIconSet.m_oIconSet->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oIconSet.m_oPercent.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingIconSet::Percent); + m_oBcw.m_oStream.WriteBOOL(oIconSet.m_oPercent->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oIconSet.m_oReverse.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingIconSet::Reverse); + m_oBcw.m_oStream.WriteBOOL(oIconSet.m_oReverse->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oIconSet.m_oShowValue.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingIconSet::ShowValue); + m_oBcw.m_oStream.WriteBOOL(oIconSet.m_oShowValue->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + + for (size_t i = 0, length = oIconSet.m_arrValues.size(); i < length; ++i) + { + if (oIconSet.m_arrValues[i].IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingIconSet::CFVO); + WriteCFVO(oIconSet.m_arrValues[i].get()); + m_oBcw.WriteItemEnd(nCurPos); + } + } + for (size_t i = 0, length = oIconSet.m_arrIconSets.size(); i < length; ++i) + { + if (oIconSet.m_arrIconSets[i].IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingIconSet::CFIcon); + WriteCFIcon(oIconSet.m_arrIconSets[i].get()); + m_oBcw.WriteItemEnd(nCurPos); + } + } +} +void BinaryWorksheetTableWriter::WriteCFIcon(const OOX::Spreadsheet::CConditionalFormatIconSet& oCFIcon) +{ + if (oCFIcon.m_oIconSet.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingIcon::iconSet); + m_oBcw.m_oStream.WriteLONG(oCFIcon.m_oIconSet->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oCFIcon.m_oIconId.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingIcon::iconId); + m_oBcw.m_oStream.WriteLONG(oCFIcon.m_oIconId->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryWorksheetTableWriter::WriteCFVO(const OOX::Spreadsheet::CConditionalFormatValueObject& oCFVO) +{ + int nCurPos = 0; + if (oCFVO.m_oGte.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingValueObject::Gte); + m_oBcw.m_oStream.WriteBOOL(oCFVO.m_oGte->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oCFVO.m_oType.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_ConditionalFormattingValueObject::Type); + m_oBcw.m_oStream.WriteBYTE(oCFVO.m_oType->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oCFVO.m_oVal.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_ConditionalFormattingValueObject::Val); + m_oBcw.m_oStream.WriteStringW(oCFVO.m_oVal.get2()); + } + if (oCFVO.m_oFormula.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_ConditionalFormattingValueObject::Formula); + m_oBcw.m_oStream.WriteStringW(oCFVO.m_oFormula->m_sText); + } +} +void BinaryWorksheetTableWriter::WriteSparklineGroups(const OOX::Spreadsheet::CSparklineGroups& oSparklineGroups) +{ + int nCurPos = 0; + for(size_t i = 0; i < oSparklineGroups.m_arrItems.size(); ++i) + { + OOX::Spreadsheet::CSparklineGroup* pSparklineGroup = oSparklineGroups.m_arrItems[i]; + nCurPos = m_oBcw.WriteItemStart(c_oSer_Sparkline::SparklineGroup); + WriteSparklineGroup(*pSparklineGroup); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryWorksheetTableWriter::WriteSparklineGroup(const OOX::Spreadsheet::CSparklineGroup& oSparklineGroup) +{ + int nCurPos = 0; + if (oSparklineGroup.m_oManualMax.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Sparkline::ManualMax); + m_oBcw.m_oStream.WriteDoubleReal(oSparklineGroup.m_oManualMax->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + + } + if (oSparklineGroup.m_oManualMin.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Sparkline::ManualMin); + m_oBcw.m_oStream.WriteDoubleReal(oSparklineGroup.m_oManualMin->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSparklineGroup.m_oLineWeight.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Sparkline::LineWeight); + m_oBcw.m_oStream.WriteDoubleReal(oSparklineGroup.m_oLineWeight->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSparklineGroup.m_oType.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Sparkline::Type); + m_oBcw.m_oStream.WriteBYTE(oSparklineGroup.m_oType->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSparklineGroup.m_oDateAxis.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Sparkline::DateAxis); + m_oBcw.m_oStream.WriteBOOL(oSparklineGroup.m_oDateAxis->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSparklineGroup.m_oDisplayEmptyCellsAs.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Sparkline::DisplayEmptyCellsAs); + m_oBcw.m_oStream.WriteBYTE(*oSparklineGroup.m_oDisplayEmptyCellsAs); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSparklineGroup.m_oMarkers.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Sparkline::Markers); + m_oBcw.m_oStream.WriteBOOL(oSparklineGroup.m_oMarkers->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSparklineGroup.m_oHigh.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Sparkline::High); + m_oBcw.m_oStream.WriteBOOL(oSparklineGroup.m_oHigh->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSparklineGroup.m_oLow.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Sparkline::Low); + m_oBcw.m_oStream.WriteBOOL(oSparklineGroup.m_oLow->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSparklineGroup.m_oFirst.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Sparkline::First); + m_oBcw.m_oStream.WriteBOOL(oSparklineGroup.m_oFirst->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSparklineGroup.m_oLast.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Sparkline::Last); + m_oBcw.m_oStream.WriteBOOL(oSparklineGroup.m_oLast->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSparklineGroup.m_oNegative.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Sparkline::Negative); + m_oBcw.m_oStream.WriteBOOL(oSparklineGroup.m_oNegative->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSparklineGroup.m_oDisplayXAxis.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Sparkline::DisplayXAxis); + m_oBcw.m_oStream.WriteBOOL(oSparklineGroup.m_oDisplayXAxis->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSparklineGroup.m_oDisplayHidden.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Sparkline::DisplayHidden); + m_oBcw.m_oStream.WriteBOOL(oSparklineGroup.m_oDisplayHidden->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSparklineGroup.m_oMinAxisType.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Sparkline::MinAxisType); + m_oBcw.m_oStream.WriteBYTE(oSparklineGroup.m_oMinAxisType->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSparklineGroup.m_oMaxAxisType.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Sparkline::MaxAxisType); + m_oBcw.m_oStream.WriteBYTE(oSparklineGroup.m_oMaxAxisType->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSparklineGroup.m_oRightToLeft.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Sparkline::RightToLeft); + m_oBcw.m_oStream.WriteBOOL(oSparklineGroup.m_oRightToLeft->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSparklineGroup.m_oColorSeries.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Sparkline::ColorSeries); + m_oBcw.WriteColor(oSparklineGroup.m_oColorSeries.get(), m_pIndexedColors); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSparklineGroup.m_oColorNegative.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Sparkline::ColorNegative); + m_oBcw.WriteColor(oSparklineGroup.m_oColorNegative.get(), m_pIndexedColors); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSparklineGroup.m_oColorAxis.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Sparkline::ColorAxis); + m_oBcw.WriteColor(oSparklineGroup.m_oColorAxis.get(), m_pIndexedColors); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSparklineGroup.m_oColorMarkers.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Sparkline::ColorMarkers); + m_oBcw.WriteColor(oSparklineGroup.m_oColorMarkers.get(), m_pIndexedColors); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSparklineGroup.m_oColorFirst.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Sparkline::ColorFirst); + m_oBcw.WriteColor(oSparklineGroup.m_oColorFirst.get(), m_pIndexedColors); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSparklineGroup.m_oColorLast.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Sparkline::ColorLast); + m_oBcw.WriteColor(oSparklineGroup.m_oColorLast.get(), m_pIndexedColors); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSparklineGroup.m_oColorHigh.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Sparkline::ColorHigh); + m_oBcw.WriteColor(oSparklineGroup.m_oColorHigh.get(), m_pIndexedColors); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSparklineGroup.m_oColorLow.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Sparkline::ColorLow); + m_oBcw.WriteColor(oSparklineGroup.m_oColorLow.get(), m_pIndexedColors); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oSparklineGroup.m_oRef.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Sparkline::Ref); + m_oBcw.m_oStream.WriteStringW(oSparklineGroup.m_oRef.get()); + } + if (oSparklineGroup.m_oSparklines.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Sparkline::Sparklines); + WriteSparklines(oSparklineGroup.m_oSparklines.get()); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryWorksheetTableWriter::WriteDataValidations(const OOX::Spreadsheet::CDataValidations& oDataValidations) +{ + int nCurPos = 0; + if (oDataValidations.m_oDisablePrompts.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DataValidation::DisablePrompts); + m_oBcw.m_oStream.WriteBOOL(oDataValidations.m_oDisablePrompts->ToBool()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oDataValidations.m_oXWindow.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DataValidation::XWindow); + m_oBcw.m_oStream.WriteLONG(oDataValidations.m_oXWindow->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oDataValidations.m_oYWindow.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_DataValidation::YWindow); + m_oBcw.m_oStream.WriteLONG(oDataValidations.m_oYWindow->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + + nCurPos = m_oBcw.WriteItemStart(c_oSer_DataValidation::DataValidations); + WriteDataValidationsContent(oDataValidations); + m_oBcw.WriteItemEnd(nCurPos); +} +void BinaryWorksheetTableWriter::WriteUserProtectedRanges(const OOX::Spreadsheet::CUserProtectedRanges& oUserProtectedRanges) +{ + for (size_t i = 0; i < oUserProtectedRanges.m_arrItems.size(); ++i) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_UserProtectedRange::UserProtectedRange); + WriteUserProtectedRange(*oUserProtectedRanges.m_arrItems[i]); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryWorksheetTableWriter::WriteUserProtectedRangeDesc(const OOX::Spreadsheet::CUserProtectedRange::_UsersGroupsDesc& desc) +{ + if (desc.id.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_UserProtectedRangeDesc::Id); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*desc.id); + } + if (desc.name.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_UserProtectedRangeDesc::Name); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*desc.name); + } + if (desc.type.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_UserProtectedRangeDesc::Type); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(desc.type->GetValue()); + } +} +void BinaryWorksheetTableWriter::WriteUserProtectedRange(const OOX::Spreadsheet::CUserProtectedRange& oUserProtectedRange) +{ + if (oUserProtectedRange.m_oName.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_UserProtectedRange::Name); + m_oBcw.m_oStream.WriteStringW3(*oUserProtectedRange.m_oName); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oUserProtectedRange.m_oSqref.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_UserProtectedRange::Sqref); + m_oBcw.m_oStream.WriteStringW3(*oUserProtectedRange.m_oSqref); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oUserProtectedRange.m_oText.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_UserProtectedRange::Text); + m_oBcw.m_oStream.WriteStringW3(*oUserProtectedRange.m_oText); + m_oBcw.WriteItemEnd(nCurPos); + } + if (oUserProtectedRange.m_oType.IsInit()) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_UserProtectedRange::Type); + m_oBcw.m_oStream.WriteBYTE(oUserProtectedRange.m_oType->GetValue()); + m_oBcw.WriteItemEnd(nCurPos); + } + for (size_t i = 0; i < oUserProtectedRange.m_arUsers.size(); ++i) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_UserProtectedRange::User); + WriteUserProtectedRangeDesc(oUserProtectedRange.m_arUsers[i]); + m_oBcw.WriteItemEnd(nCurPos); + } + for (size_t i = 0; i < oUserProtectedRange.m_arUsersGroups.size(); ++i) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_UserProtectedRange::UsersGroup); + WriteUserProtectedRangeDesc(oUserProtectedRange.m_arUsersGroups[i]); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryWorksheetTableWriter::WriteDataValidationsContent(const OOX::Spreadsheet::CDataValidations& oDataValidations) +{ + for(size_t i = 0; i < oDataValidations.m_arrItems.size(); ++i) + { + int nCurPos = m_oBcw.WriteItemStart(c_oSer_DataValidation::DataValidation); + WriteDataValidation(*oDataValidations.m_arrItems[i]); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryWorksheetTableWriter::WriteDataValidation(const OOX::Spreadsheet::CDataValidation& oDataValidation) +{ + if (oDataValidation.m_oType.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DataValidation::Type); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(oDataValidation.m_oType->GetValue()); + } + if (oDataValidation.m_oAllowBlank.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DataValidation::AllowBlank); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oDataValidation.m_oAllowBlank->ToBool()); + } + if (oDataValidation.m_oError.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DataValidation::Error); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(oDataValidation.m_oError.get()); + } + if (oDataValidation.m_oErrorTitle.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DataValidation::ErrorTitle); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(oDataValidation.m_oErrorTitle.get()); + } + if (oDataValidation.m_oErrorStyle.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DataValidation::ErrorStyle); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(oDataValidation.m_oErrorStyle->GetValue()); + } + if (oDataValidation.m_oImeMode.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DataValidation::ImeMode); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(oDataValidation.m_oImeMode->GetValue()); + } + if (oDataValidation.m_oOperator.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DataValidation::Operator); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBYTE(oDataValidation.m_oOperator->GetValue()); + } + if (oDataValidation.m_oPrompt.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DataValidation::Promt); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(oDataValidation.m_oPrompt.get()); + } + if (oDataValidation.m_oPromptTitle.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DataValidation::PromptTitle); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(oDataValidation.m_oPromptTitle.get()); + } + if (oDataValidation.m_oShowDropDown.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DataValidation::ShowDropDown); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oDataValidation.m_oShowDropDown->ToBool()); + } + if (oDataValidation.m_oShowErrorMessage.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DataValidation::ShowErrorMessage); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oDataValidation.m_oShowErrorMessage->ToBool()); + } + if (oDataValidation.m_oShowInputMessage.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DataValidation::ShowInputMessage); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oDataValidation.m_oShowInputMessage->ToBool()); + } + if (oDataValidation.m_oSqRef.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DataValidation::SqRef); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(oDataValidation.m_oSqRef.get()); + } + if (oDataValidation.m_oFormula1.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DataValidation::Formula1); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(oDataValidation.m_oFormula1->m_sText); + } + if (oDataValidation.m_oFormula2.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DataValidation::Formula2); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(oDataValidation.m_oFormula2->m_sText); + } + if (oDataValidation.m_oList.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_DataValidation::List); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*oDataValidation.m_oList); + } +} +void BinaryWorksheetTableWriter::WriteSparklines(const OOX::Spreadsheet::CSparklines& oSparklines) +{ + int nCurPos = 0; + for(size_t i = 0; i < oSparklines.m_arrItems.size(); ++i) + { + nCurPos = m_oBcw.WriteItemStart(c_oSer_Sparkline::Sparkline); + WriteSparkline(*oSparklines.m_arrItems[i]); + m_oBcw.WriteItemEnd(nCurPos); + } +} +void BinaryWorksheetTableWriter::WriteSparkline(const OOX::Spreadsheet::CSparkline& oSparkline) +{ + int nCurPos = 0; + if (oSparkline.m_oRef.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE (c_oSer_Sparkline::SparklineRef); + m_oBcw.m_oStream.WriteStringW (oSparkline.m_oRef.get()); + } + if (oSparkline.m_oSqRef.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE (c_oSer_Sparkline::SparklineSqRef); + m_oBcw.m_oStream.WriteStringW (oSparkline.m_oSqRef.get()); + } +} +void BinaryWorksheetTableWriter::WriteTimelines(OOX::Spreadsheet::CWorksheet& oWorksheet, const OOX::Spreadsheet::CTimelineRefs& oTimelines) +{ + int nCurPos = 0; + for (size_t i = 0; i < oTimelines.m_arrItems.size(); ++i) + { + if (oTimelines.m_arrItems[i] && oTimelines.m_arrItems[i]->m_oRId.IsInit()) + { + smart_ptr pFile = oWorksheet.Find(OOX::RId(oTimelines.m_arrItems[i]->m_oRId->GetValue())); + if (pFile.IsInit() && OOX::Spreadsheet::FileTypes::Timeline == pFile->type()) + { + OOX::Spreadsheet::CTimelineFile* pTimelineFile = static_cast(pFile.GetPointer()); + if (pTimelineFile->m_oTimelines.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Timelines); + WriteTimelines(pTimelineFile->m_oTimelines.GetPointer()); + m_oBcw.WriteItemEnd(nCurPos); + } + } + } + } +} +void BinaryWorksheetTableWriter::WriteTimelines(OOX::Spreadsheet::CTimelines* pTimelines) +{ + if (!pTimelines) return; + + int nCurPos = 0; + for (size_t i = 0; i < pTimelines->m_arrItems.size(); ++i) + { + if (pTimelines->m_arrItems[i]) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Timeline); + WriteTimeline(pTimelines->m_arrItems[i]); + m_oBcw.WriteItemEnd(nCurPos); + } + } +} +void BinaryWorksheetTableWriter::WriteTimeline(OOX::Spreadsheet::CTimeline* pTimeline) +{ + if (!pTimeline) return; + + if (pTimeline->m_oName.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Timeline::Name); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*pTimeline->m_oName); + } + if (pTimeline->m_oCaption.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Timeline::Caption); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*pTimeline->m_oCaption); + } + if (pTimeline->m_oUid.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Timeline::Uid); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*pTimeline->m_oUid); + } + if (pTimeline->m_oScrollPosition.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Timeline::ScrollPosition); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*pTimeline->m_oScrollPosition); + } + if (pTimeline->m_oCache.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Timeline::Cache); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(*pTimeline->m_oCache); + } + if (pTimeline->m_oSelectionLevel.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Timeline::SelectionLevel); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(*pTimeline->m_oSelectionLevel); + } + if (pTimeline->m_oLevel.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Timeline::Level); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(*pTimeline->m_oLevel); + } + if (pTimeline->m_oShowHeader.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Timeline::ShowHeader); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(*pTimeline->m_oShowHeader); + } + if (pTimeline->m_oShowSelectionLabel.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Timeline::ShowSelectionLabel); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(*pTimeline->m_oShowSelectionLabel); + } + if (pTimeline->m_oShowTimeLevel.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Timeline::ShowTimeLevel); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(*pTimeline->m_oShowTimeLevel); + } + if (pTimeline->m_oShowHorizontalScrollbar.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Timeline::ShowHorizontalScrollbar); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(*pTimeline->m_oShowHorizontalScrollbar); + } + if (pTimeline->m_oStyle.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_Timeline::Style); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteLONG(pTimeline->m_oStyle->GetValue()); + } +} + +void BinaryWorksheetTableWriter::WriteSlicers(OOX::Spreadsheet::CWorksheet& oWorksheet, const OOX::Spreadsheet::CSlicerRefs& oSlicers) +{ + int nCurPos = 0; + for(size_t i = 0; i < oSlicers.m_oSlicer.size(); ++i) + { + if(oSlicers.m_oSlicer[i].m_oRId.IsInit()) + { + smart_ptr pFile = oWorksheet.Find(OOX::RId(oSlicers.m_oSlicer[i].m_oRId->GetValue())); + if (pFile.IsInit() && OOX::Spreadsheet::FileTypes::Slicer == pFile->type()) + { + OOX::Spreadsheet::CSlicerFile* pSlicerFile = static_cast(pFile.GetPointer()); + if(pSlicerFile->m_oSlicers.IsInit()) + { + nCurPos = m_oBcw.WriteItemStart(c_oSerWorksheetsTypes::Slicer); + m_oBcw.m_oStream.WriteRecord2(0, pSlicerFile->m_oSlicers); + m_oBcw.WriteItemEnd(nCurPos); + } + } + } + } +} +//--------------------------------------------------------------------------------------------------------------------- +BinaryCalcChainTableWriter::BinaryCalcChainTableWriter(NSBinPptxRW::CBinaryFileWriter &oCBufferedStream) : m_oBcw(oCBufferedStream) +{ +} +void BinaryCalcChainTableWriter::Write(OOX::Spreadsheet::CCalcChain& pCalcChain) +{ + int nStart = m_oBcw.WriteItemWithLengthStart(); + WriteCalcChainTableContent(pCalcChain); + m_oBcw.WriteItemWithLengthEnd(nStart); +} +void BinaryCalcChainTableWriter::WriteCalcChainTableContent(OOX::Spreadsheet::CCalcChain& pCalcChain) +{ + int nCurPos; + for(size_t i = 0, length = pCalcChain.m_arrItems.size(); i < length; ++i) + { + //media + nCurPos = m_oBcw.WriteItemStart(c_oSer_CalcChainType::CalcChainItem); + WriteCalcChain(*pCalcChain.m_arrItems[i]); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} +void BinaryCalcChainTableWriter::WriteCalcChain(OOX::Spreadsheet::CCalcCell& oCalcCell) +{ + //Array + if(oCalcCell.m_oArray.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_CalcChainType::Array); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oCalcCell.m_oArray->ToBool()); + } + //SheetId + if(oCalcCell.m_oSheetId.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_CalcChainType::SheetId); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Long); + m_oBcw.m_oStream.WriteLONG(oCalcCell.m_oSheetId->GetValue()); + } + //DependencyLevel + if(oCalcCell.m_oDependencyLevel.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_CalcChainType::DependencyLevel); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oCalcCell.m_oDependencyLevel->ToBool()); + } + //Ref + if(oCalcCell.m_oRef.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_CalcChainType::Ref); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Variable); + m_oBcw.m_oStream.WriteStringW(oCalcCell.m_oRef.get2()); + } + //ChildChain + if(oCalcCell.m_oChildChain.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_CalcChainType::ChildChain); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oCalcCell.m_oChildChain->ToBool()); + } + //NewThread + if(oCalcCell.m_oNewThread.IsInit()) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_CalcChainType::NewThread); + m_oBcw.m_oStream.WriteBYTE(c_oSerPropLenType::Byte); + m_oBcw.m_oStream.WriteBOOL(oCalcCell.m_oNewThread->ToBool()); + } +} +//----------------------------------------------------------------------------------------------------- +BinaryCustomsTableWriter::BinaryCustomsTableWriter(NSBinPptxRW::CBinaryFileWriter &oCBufferedStream) : m_oBcw(oCBufferedStream) +{ +} +void BinaryCustomsTableWriter::Write(OOX::IFileContainer *pContainer) +{ + if (!pContainer) return; + + int nStart = m_oBcw.WriteItemWithLengthStart(); + + std::vector>& container = pContainer->GetContainer(); + for (size_t k = 0; k < container.size(); ++k) + { + if (OOX::FileTypes::CustomXml == container[k]->type()) + { + OOX::CCustomXML* pCustomXml = dynamic_cast(container[k].GetPointer()); + if (pCustomXml->m_bUsed) continue; + + int nCurPos = m_oBcw.WriteItemStart(c_oSerCustoms::Custom); + + std::vector>& containerCustom = pCustomXml->GetContainer(); + for (size_t i = 0; i < containerCustom.size(); ++i) + { + if (OOX::FileTypes::CustomXmlProps == containerCustom[i]->type()) + { + OOX::CCustomXMLProps* pCustomXmlProps = dynamic_cast(containerCustom[i].GetPointer()); + + int nCurPos1 = m_oBcw.WriteItemStart(c_oSerCustoms::ItemId); + m_oBcw.m_oStream.WriteStringW3(pCustomXmlProps->m_oItemID.ToString()); + m_oBcw.WriteItemEnd(nCurPos1); + + if (pCustomXmlProps->m_oShemaRefs.IsInit()) + { + for (size_t j = 0; j < pCustomXmlProps->m_oShemaRefs->m_arrItems.size(); ++j) + { + nCurPos1 = m_oBcw.WriteItemStart(c_oSerCustoms::Uri); + m_oBcw.m_oStream.WriteStringW3(pCustomXmlProps->m_oShemaRefs->m_arrItems[j]->m_sUri); + m_oBcw.WriteItemEnd(nCurPos1); + } + } + } + } + + int nCurPos2 = m_oBcw.WriteItemStart(c_oSerCustoms::Content); + m_oBcw.m_oStream.WriteStringA(pCustomXml->m_sXmlA); + m_oBcw.WriteItemEnd(nCurPos2); + + m_oBcw.WriteItemEnd(nCurPos); + pCustomXml->m_bUsed = true; + } + } + m_oBcw.WriteItemWithLengthEnd(nStart); +} +//------------------------------------------------------------------------------------------------------ +BinaryOtherTableWriter::BinaryOtherTableWriter(NSBinPptxRW::CBinaryFileWriter &oCBufferedStream, NSFontCutter::CEmbeddedFontsManager* pEmbeddedFontsManager, PPTX::Theme* pTheme, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter) + : m_oBcw (oCBufferedStream), + m_pEmbeddedFontsManager (pEmbeddedFontsManager), + m_pTheme (pTheme), + m_pOfficeDrawingConverter(pOfficeDrawingConverter) +{ +} +void BinaryOtherTableWriter::Write() +{ + int nStart = m_oBcw.WriteItemWithLengthStart(); + WriteOtherTableContent(); + m_oBcw.WriteItemWithLengthEnd(nStart); +} +void BinaryOtherTableWriter::WriteOtherTableContent() +{ + int nCurPos; + //EmbeddedFonts + if(NULL != m_pEmbeddedFontsManager) + { + EmbeddedBinaryWriter oEmbeddedBinaryWriter(m_oBcw.m_oStream); + nCurPos = m_oBcw.WriteItemStart(c_oSer_OtherType::EmbeddedFonts); + m_pEmbeddedFontsManager->WriteEmbeddedFonts(&oEmbeddedBinaryWriter); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } + //Theme + if(NULL != m_pTheme) + { + m_oBcw.m_oStream.WriteBYTE(c_oSer_OtherType::Theme); + + int nCurPos = m_oBcw.WriteItemWithLengthStart(); + m_pTheme->toPPTY(&m_oBcw.m_oStream); + m_oBcw.WriteItemWithLengthEnd(nCurPos); + } +} + +BinaryFileWriter::BinaryFileWriter(DocWrapper::FontProcessor& oFontProcessor) : m_oBcw(NULL), m_oFontProcessor(oFontProcessor) +{ + m_nLastFilePos = 0; + m_nLastFilePosOffset = 0; + m_nRealTableCount = 0; +} +BinaryFileWriter::~BinaryFileWriter() +{ + RELEASEOBJECT(m_oBcw); +} +_UINT32 BinaryFileWriter::Open(const std::wstring& sInputDir, const std::wstring& sFileDst, NSFontCutter::CEmbeddedFontsManager* pEmbeddedFontsManager, + NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter, const std::wstring& sXMLOptions, bool bIsNoBase64) +{ + _UINT32 result = 0; + + OOX::CPath pathDst(sFileDst); +//создаем папку для media + std::wstring mediaDir = pathDst.GetDirectory() + L"media"; + NSDirectory::CreateDirectory(mediaDir); + + pOfficeDrawingConverter->SetDstPath(pathDst.GetDirectory() + FILE_SEPARATOR_STR + L"word"); + pOfficeDrawingConverter->SetMediaDstPath(mediaDir); + + NSBinPptxRW::CBinaryFileWriter& oBufferedStream = *pOfficeDrawingConverter->m_pBinaryWriter; + + m_oBcw = new BinaryCommonWriter(oBufferedStream); + + // File Type + BYTE fileType; + UINT nCodePage; + std::wstring sDelimiter; + BYTE saveFileType; + _INT32 Lcid; + SerializeCommon::ReadFileType(sXMLOptions, fileType, nCodePage, sDelimiter, saveFileType, Lcid); + + m_nLastFilePosOffset = 0; + OOX::Spreadsheet::CXlsx *pXlsx = NULL; + OOX::Spreadsheet::CXlsxFlat *pXlsxFlat = NULL; + switch(fileType) + { + case BinXlsxRW::c_oFileTypes::CSV: + { + CSVReader csvReader; + + pXlsx = new OOX::Spreadsheet::CXlsx(); + result = csvReader.Read(sInputDir, *pXlsx, nCodePage, sDelimiter, Lcid); + }break; + case BinXlsxRW::c_oFileTypes::XLSX: + case BinXlsxRW::c_oFileTypes::XLSB: + default: + { + if (bIsNoBase64 && BinXlsxRW::c_oFileTypes::JSON != saveFileType) + { + if(fileType == BinXlsxRW::c_oFileTypes::XLSB) + pXlsx = new OOX::Spreadsheet::CXlsb(); + else + pXlsx = new OOX::Spreadsheet::CXlsx(); + pXlsx->m_bNeedCalcChain = false; + + NSBinPptxRW::CXlsbBinaryWriter oXlsbWriter; + oXlsbWriter.CreateFileW(sFileDst); + //write dummy header and main table + oXlsbWriter.WriteStringUtf8(WriteFileHeader(0, g_nFormatVersionNoBase64)); + oXlsbWriter.WriteReserved(GetMainTableSize()); + int nDataStartPos = oXlsbWriter.GetPositionAbsolute(); + + // retest fileType - 1 || 4 + COfficeFileFormatChecker checker; + if (checker.isOOXFormatFile(sInputDir, true)) + { + fileType = (checker.nFileType == AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSB) ? 4 : 1; + } + + if (fileType == 1) + { + //pXlsx->m_pXlsbWriter = &oXlsbWriter; // todooo xlsb -> xlst without xlsx write folder + } + //parse + pXlsx->Read(OOX::CPath(sInputDir)); + + pXlsx->m_pXlsbWriter = NULL; + oXlsbWriter.CloseFile(); + m_nLastFilePosOffset = oXlsbWriter.GetPositionAbsolute() - nDataStartPos; + } + else + { + pXlsx = new OOX::Spreadsheet::CXlsx(OOX::CPath(sInputDir)); + } + }break; + } + if (0 != result && AVS_FILEUTILS_ERROR_CONVERT_ROWLIMITS != result && AVS_FILEUTILS_ERROR_CONVERT_CELLLIMITS != result) + { + RELEASEOBJECT(pXlsx); + return result; + } + if (pXlsx && !pXlsx->m_pWorkbook && pXlsx->m_arWorksheets.empty()) + { + delete pXlsx; pXlsx = NULL; + pXlsxFlat = new OOX::Spreadsheet::CXlsxFlat(OOX::CPath(sInputDir)); + + if (pXlsxFlat && pXlsxFlat->m_arWorksheets.empty()) + { + delete pXlsxFlat; pXlsxFlat = NULL; + } + } + if (pXlsx) + { + pXlsx->PrepareWorkbook(); + + if (NULL == pXlsx->m_pWorkbook) + { + RELEASEOBJECT(pXlsx); + return AVS_FILEUTILS_ERROR_CONVERT; + } + + if (fileType == BinXlsxRW::c_oFileTypes::XLSB) + { + dynamic_cast(pXlsx)->PrepareSi(); + dynamic_cast(pXlsx)->PrepareTableFormula(); + dynamic_cast(pXlsx)->ReadSheetData(); + } + } + + if (BinXlsxRW::c_oFileTypes::JSON == saveFileType) + { +//todo 46 временно CP_UTF8 + + CSVWriter oCSVWriter; + oCSVWriter.Xlsx2Csv(sFileDst, *pXlsx, 46, std::wstring(L","), Lcid, true); + } + else + { + if (bIsNoBase64) + { + oBufferedStream.WriteStringUtf8(WriteFileHeader(0, g_nFormatVersionNoBase64)); + } + int nHeaderLen = oBufferedStream.GetPosition(); + + WriteMainTableStart(oBufferedStream); + WriteContent(pXlsx ? dynamic_cast(pXlsx) : dynamic_cast(pXlsxFlat), pEmbeddedFontsManager, pOfficeDrawingConverter); + WriteMainTableEnd(); + + BYTE* pbBinBuffer = oBufferedStream.GetBuffer(); + int nBinBufferLen = oBufferedStream.GetPosition(); + if (bIsNoBase64) + { + int nMidPoint = nHeaderLen + GetMainTableSize(); + + NSFile::CFileBinary oFile; + if(0 != m_nLastFilePosOffset) + { + oFile.OpenFile(sFileDst, true); + } + else + { + oFile.CreateFileW(sFileDst); + } + //write header and main table + oFile.WriteFile(pbBinBuffer, nMidPoint); + //skip xlsb records written on xml reading + oFile.SeekFile(0, SEEK_END); + //write other records + oFile.WriteFile(pbBinBuffer + nMidPoint, nBinBufferLen - nMidPoint); + oFile.CloseFile(); + } + else + { + int nBase64BufferLen = Base64::Base64EncodeGetRequiredLength(nBinBufferLen, Base64::B64_BASE64_FLAG_NOCRLF); + BYTE* pbBase64Buffer = new BYTE[nBase64BufferLen + 64]; + if(true == Base64_1::Base64Encode(pbBinBuffer, nBinBufferLen, pbBase64Buffer, &nBase64BufferLen)) + { + NSFile::CFileBinary oFile; + oFile.CreateFileW(sFileDst); + oFile.WriteStringUTF8(WriteFileHeader(nBinBufferLen, g_nFormatVersion)); + oFile.WriteFile(pbBase64Buffer, nBase64BufferLen); + oFile.CloseFile(); + } + else + { + result = AVS_FILEUTILS_ERROR_CONVERT; + } + RELEASEARRAYOBJECTS(pbBase64Buffer); + } + + if (fileType == BinXlsxRW::c_oFileTypes::XLSB && pXlsx->hasPivot()) + { + std::wstring sDstFileXlsx = pathDst.GetDirectory() + FILE_SEPARATOR_STR + L"Editor.xlsx"; + std::wstring sTempUnpackedXLSX = pathDst.GetDirectory() + FILE_SEPARATOR_STR + L"xlsx_unpacked"; + NSDirectory::CreateDirectory(sTempUnpackedXLSX); + + OOX::CContentTypes oContentTypes; + dynamic_cast(pXlsx)->SetPropForWriteSheet(sTempUnpackedXLSX, oContentTypes); + + if (true == pXlsx->WriteNative(sTempUnpackedXLSX, oContentTypes)) + { + COfficeUtils oOfficeUtils(NULL); + oOfficeUtils.CompressFileOrDirectory(sTempUnpackedXLSX, sDstFileXlsx, true); + } + NSDirectory::DeleteDirectory(sTempUnpackedXLSX); + } + } + + RELEASEOBJECT(pXlsx); + RELEASEOBJECT(pXlsxFlat); + + return result; +} +void BinaryFileWriter::WriteBinaryTable(const BYTE* pBuffer, size_t size) +{ + int nCurPos = m_oBcw->m_oStream.GetPosition(); + + m_oBcw->m_oStream.SetPosition(m_nLastFilePos); + m_oBcw->m_oStream.WriteBYTEArray(pBuffer, size); + m_nLastFilePos = m_oBcw->m_oStream.GetPosition(); + + m_oBcw->m_oStream.SetPosition(nCurPos); +} + +void BinaryFileWriter::WriteContent(OOX::Document *pDocument, NSFontCutter::CEmbeddedFontsManager* pEmbeddedFontsManager, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter) +{ + OOX::Spreadsheet::CXlsx *pXlsx = dynamic_cast(pDocument); + OOX::Spreadsheet::CXlsxFlat *pXlsxFlat = dynamic_cast(pDocument); + + OOX::Spreadsheet::CStyles *pStyles = NULL; + OOX::Spreadsheet::CWorkbook *pWorkbook = NULL; + OOX::Spreadsheet::CSharedStrings *pSharedStrings = NULL; + + if (pXlsx) + { + pWorkbook = pXlsx->m_pWorkbook; + pStyles = pXlsx->m_pStyles; + pSharedStrings = pXlsx->m_pSharedStrings; + } + if (pXlsxFlat) + { + pWorkbook = pXlsxFlat->m_pWorkbook.GetPointer(); + pStyles = pXlsxFlat->m_pStyles.GetPointer(); + pSharedStrings = pXlsxFlat->m_pSharedStrings.GetPointer(); + } + + int nCurPos; +//SharedString + OOX::Spreadsheet::CIndexedColors* pIndexedColors = NULL; + + if( pStyles && pStyles->m_oColors.IsInit() && pStyles->m_oColors->m_oIndexedColors.IsInit()) + { + pIndexedColors = pStyles->m_oColors->m_oIndexedColors.operator ->(); + } + + if(pXlsx && pXlsx->m_pApp) + { + nCurPos = this->WriteTableStart(c_oSerTableTypes::App); + pXlsx->m_pApp->toPPTY(&m_oBcw->m_oStream); + this->WriteTableEnd(nCurPos); + } + + if(pXlsx && pXlsx->m_pCore) + { + nCurPos = this->WriteTableStart(c_oSerTableTypes::Core); + pXlsx->m_pCore->toPPTY(&m_oBcw->m_oStream); + this->WriteTableEnd(nCurPos); + } + + if (pXlsx) + { + smart_ptr pFile = pXlsx->Find(OOX::FileTypes::CustomProperties); + PPTX::CustomProperties *pCustomProperties = dynamic_cast(pFile.GetPointer()); + if (pCustomProperties) + { + nCurPos = this->WriteTableStart(c_oSerTableTypes::CustomProperties); + pCustomProperties->toPPTY(&m_oBcw->m_oStream); + this->WriteTableEnd(nCurPos); + } + } + + if(pSharedStrings) + { + nCurPos = WriteTableStart(c_oSerTableTypes::SharedStrings); + BinarySharedStringTableWriter oBinarySharedStringTableWriter(m_oBcw->m_oStream, pEmbeddedFontsManager); + oBinarySharedStringTableWriter.Write(*pSharedStrings, pIndexedColors, pXlsx ? pXlsx->GetTheme() : NULL, m_oFontProcessor); + WriteTableEnd(nCurPos); + } + + if(pWorkbook && pWorkbook->m_pPersonList) + { + nCurPos = WriteTableStart(c_oSerTableTypes::PersonList); + BinaryPersonTableWriter oBinaryPersonTableWriter(m_oBcw->m_oStream); + oBinaryPersonTableWriter.Write(*pXlsx->m_pWorkbook->m_pPersonList); + WriteTableEnd(nCurPos); + } +//Styles + if(pStyles) + { + nCurPos = WriteTableStart(c_oSerTableTypes::Styles); + BinaryStyleTableWriter oBinaryStyleTableWriter(m_oBcw->m_oStream, pEmbeddedFontsManager); + oBinaryStyleTableWriter.Write(*pStyles, pXlsx ? pXlsx->GetTheme() : NULL, m_oFontProcessor); + WriteTableEnd(nCurPos); + } +////CalcChain + //OOX::Spreadsheet::CCalcChain* pCalcChain = oXlsx.GetCalcChain(); + //if(NULL != pCalcChain) + //{ + // nCurPos = WriteTableStart(c_oSerTableTypes::CalcChain); + // BinaryCalcChainTableWriter oBinaryCalcChainTableWriter(oBufferedStream); + // oBinaryCalcChainTableWriter.Write(*pCalcChain); + // WriteTableEnd(nCurPos); + //} + +//Workbook + if ( pWorkbook) + { + nCurPos = WriteTableStart(c_oSerTableTypes::Workbook); + BinaryWorkbookTableWriter oBinaryWorkbookTableWriter(m_oBcw->m_oStream, pXlsx ? dynamic_cast(pXlsx) : dynamic_cast(pXlsxFlat)); + oBinaryWorkbookTableWriter.Write(*pWorkbook); + WriteTableEnd(nCurPos); + } + if(pXlsx) + { + //Worksheets + nCurPos = WriteTableStart(c_oSerTableTypes::Worksheets); + BinaryWorksheetTableWriter oBinaryWorksheetTableWriter(m_oBcw->m_oStream, pEmbeddedFontsManager, pIndexedColors, pXlsx->GetTheme(), m_oFontProcessor, pOfficeDrawingConverter); + oBinaryWorksheetTableWriter.Write(*pXlsx->m_pWorkbook, pXlsx->m_mapWorksheets); + WriteTableEnd(nCurPos); + + //OtherTable + nCurPos = WriteTableStart(c_oSerTableTypes::Other); + BinaryOtherTableWriter oBinaryOtherTableWriter(m_oBcw->m_oStream, pEmbeddedFontsManager, pXlsx->GetTheme(), pOfficeDrawingConverter); + oBinaryOtherTableWriter.Write(); + WriteTableEnd(nCurPos); + + //Customs from Workbook (todooo - другие) + nCurPos = WriteTableStart(c_oSerTableTypes::Customs); + BinaryCustomsTableWriter oBinaryCustomsTableWriter(m_oBcw->m_oStream); + oBinaryCustomsTableWriter.Write(pXlsx->m_pWorkbook); + WriteTableEnd(nCurPos); + } + else if (pXlsxFlat) + { + nCurPos = WriteTableStart(c_oSerTableTypes::Worksheets); + BinaryWorksheetTableWriter oBinaryWorksheetTableWriter(m_oBcw->m_oStream, pEmbeddedFontsManager, pIndexedColors, NULL, m_oFontProcessor, pOfficeDrawingConverter); + oBinaryWorksheetTableWriter.Write(*pXlsxFlat->m_pWorkbook.GetPointer(), pXlsxFlat->m_arWorksheets); + WriteTableEnd(nCurPos); + } +} + +std::wstring BinaryFileWriter::WriteFileHeader(int nDataSize, int version) +{ + std::wstring sHeader = std::wstring(g_sFormatSignature) + L";v" + std::to_wstring(version)+ L";" + std::to_wstring(nDataSize) + L";"; + return sHeader; +} +void BinaryFileWriter::WriteMainTableStart(NSBinPptxRW::CBinaryFileWriter &oBufferedStream) +{ + if (!m_oBcw) + m_oBcw = new BinaryCommonWriter(oBufferedStream); + + m_nRealTableCount = 0; + m_nMainTableStart = m_oBcw->m_oStream.GetPosition(); + //вычисляем с какой позиции можно писать таблицы + m_nLastFilePos = m_nMainTableStart + GetMainTableSize(); + //Write mtLen + m_oBcw->m_oStream.WriteBYTE(0); +} +int BinaryFileWriter::GetMainTableSize() +{ + return 128 * 5;//128 items of 5 bytes +} +void BinaryFileWriter::WriteMainTableEnd() +{ +//Количество таблиц + m_oBcw->m_oStream.SetPosition(m_nMainTableStart); + m_oBcw->m_oStream.WriteBYTE(m_nRealTableCount); + + m_oBcw->m_oStream.SetPosition(m_nLastFilePos); +} +int BinaryFileWriter::WriteTableStart(BYTE type, int nStartPos) +{ + if(-1 != nStartPos) + m_oBcw->m_oStream.SetPosition(nStartPos); + //Write mtItem + //Write mtiType + m_oBcw->m_oStream.WriteBYTE(type); + //Write mtiOffBits + m_oBcw->m_oStream.WriteLONG(m_nLastFilePos + m_nLastFilePosOffset); + + //Write table + //Запоминаем позицию в MainTable + int nCurPos = m_oBcw->m_oStream.GetPosition(); + //Seek в свободную область + m_oBcw->m_oStream.SetPosition(m_nLastFilePos); + return nCurPos; +} +void BinaryFileWriter::WriteTableEnd(int nCurPos) +{ + //сдвигаем позицию куда можно следующую таблицу + m_nLastFilePos = m_oBcw->m_oStream.GetPosition(); + m_nRealTableCount++; + //Seek вобратно в MainTable + m_oBcw->m_oStream.SetPosition(nCurPos); +} + +} diff --git a/OOXML/Binary/Sheets/Reader/BinaryWriter.h b/OOXML/Binary/Sheets/Reader/BinaryWriterS.h similarity index 99% rename from OOXML/Binary/Sheets/Reader/BinaryWriter.h rename to OOXML/Binary/Sheets/Reader/BinaryWriterS.h index 558520db18..26b7f9d1e2 100644 --- a/OOXML/Binary/Sheets/Reader/BinaryWriter.h +++ b/OOXML/Binary/Sheets/Reader/BinaryWriterS.h @@ -84,6 +84,7 @@ namespace OOX class CTimelineStyle; class CTimelineStyles; class CTimelineStyleElement; + class CXmlColumnPr; class CMetadata; class CFutureMetadata; @@ -138,6 +139,7 @@ namespace BinXlsxRW void WriteQueryTableField(const OOX::Spreadsheet::CQueryTableField& oQueryTableField); void WriteQueryTableDeletedFields(const OOX::Spreadsheet::CQueryTableDeletedFields& oQueryTableDeletedFields); void WriteQueryTableDeletedField(const OOX::Spreadsheet::CQueryTableDeletedField& oQueryTableDeletedField); + void WriteTableXmlColumnPr(const OOX::Spreadsheet::CXmlColumnPr & oXmlColumnPr); }; class BinaryStyleTableWriter { diff --git a/OOXML/Binary/Sheets/Reader/ChartFromToBinary.cpp b/OOXML/Binary/Sheets/Reader/ChartFromToBinary.cpp index c076daa70b..56b0bf7acc 100644 --- a/OOXML/Binary/Sheets/Reader/ChartFromToBinary.cpp +++ b/OOXML/Binary/Sheets/Reader/ChartFromToBinary.cpp @@ -30,7 +30,7 @@ * */ -#include "../Writer/BinaryReader.h" +#include "../Writer/BinaryReaderS.h" #include "../../Presentation/BinReaderWriterDefines.h" #include "../../Document/BinReader/DefaultThemeWriter.h" @@ -1339,7 +1339,7 @@ namespace BinXlsxRW oDrawingConverter.m_pReader->Init(pData, 0, length); oDrawingConverter.SetDstPath(sDstEmbeddedTemp + FILE_SEPARATOR_STR + L"xl"); - oDrawingConverter.SetSrcPath(m_pOfficeDrawingConverter->m_pReader->m_strFolder, 2); + oDrawingConverter.SetSrcPath(m_pOfficeDrawingConverter->m_pReader->m_strFolder, XMLWRITER_DOC_TYPE_XLSX); oDrawingConverter.SetMediaDstPath(sMediaPath); oDrawingConverter.SetEmbedDstPath(sEmbedPath); diff --git a/OOXML/Binary/Sheets/Reader/CommonWriter.h b/OOXML/Binary/Sheets/Reader/CommonWriter.h index 7c332ec178..53a4e1c995 100644 --- a/OOXML/Binary/Sheets/Reader/CommonWriter.h +++ b/OOXML/Binary/Sheets/Reader/CommonWriter.h @@ -29,8 +29,7 @@ * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ -#ifndef COMMON_WRITER -#define COMMON_WRITER +#pragma once #include "../../Presentation/BinaryFileReaderWriter.h" #include "../../../XlsxFormat/Xlsx.h" @@ -59,4 +58,3 @@ namespace BinXlsxRW void WriteBytesArray(BYTE* pData, long nDataSize); }; } -#endif // #ifndef COMMON_WRITER diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index f2b4fa8c9c..c22c82c793 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp @@ -72,6 +72,7 @@ #include "../../../XlsxFormat/Controls/Controls.h" #include "../../../XlsxFormat/Timelines/Timeline.h" #include "../../../XlsxFormat/Workbook/Metadata.h" +#include "../../../XlsxFormat/Workbook/CustomsXml.h" #include "../../../DocxFormat/Media/VbaProject.h" #include "../../../DocxFormat/Media/JsaProject.h" @@ -410,7 +411,12 @@ int BinaryTableReader::ReadQueryTableField(BYTE type, long length, void* poResul res = c_oSerConstants::ReadUnknown; return res; } - +int BinaryTableReader::ReadTableCache(long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + READ1_DEF(length, res, this->ReadCacheParts, poResult); + return res; +} int BinaryTableReader::ReadTablePart(BYTE type, long length, void* poResult) { int res = c_oSerConstants::ReadOk; @@ -418,12 +424,17 @@ int BinaryTableReader::ReadTablePart(BYTE type, long length, void* poResult) if (c_oSer_TablePart::Table == type) { OOX::Spreadsheet::CTableFile* pTable = new OOX::Spreadsheet::CTableFile(NULL); + if(m_pCurWorksheet->OOX::File::m_pMainDocument) + { + pTable->OOX::File::m_pMainDocument = m_pCurWorksheet->OOX::File::m_pMainDocument; + } pTable->m_oTable.Init(); READ1_DEF(length, res, this->ReadTable, pTable); OOX::Spreadsheet::CTablePart* pTablePart = new OOX::Spreadsheet::CTablePart(); NSCommon::smart_ptr pTableFile(pTable); const OOX::RId oRId = m_pCurWorksheet->Add(pTableFile); + pTablePart->m_oRId.Init(); pTablePart->m_oRId->SetValue(oRId.get()); pTableParts->m_arrItems.push_back(pTablePart); @@ -432,6 +443,72 @@ int BinaryTableReader::ReadTablePart(BYTE type, long length, void* poResult) res = c_oSerConstants::ReadUnknown; return res; }; +int BinaryTableReader::ReadCacheParts(BYTE type,long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + if (c_oSer_TablePart::Table == type) + { + OOX::Spreadsheet::CTable Table; + READ1_DEF(length, res, this->ReadCachePart, &Table); + if(Table.m_oId.IsInit() && Table.m_oTableColumns.IsInit() && !Table.m_oTableColumns->m_arrItems.empty()) + { + XLS::GlobalWorkbookInfo::mapTableColumnNames_static.emplace(Table.m_oId->GetValue(), + std::vector(Table.m_oTableColumns->m_arrItems.size())); + auto colInd = 0; + for(auto i:Table.m_oTableColumns->m_arrItems) + { + if(i->m_oName.IsInit()) + { + i->m_oName = boost::algorithm::replace_all_copy(i->m_oName.get(), L"_x000a_", L"\n"); + std::unordered_map>::iterator pFind = XLS::GlobalWorkbookInfo::mapTableColumnNames_static.find(Table.m_oId->GetValue()); + if (pFind != XLS::GlobalWorkbookInfo::mapTableColumnNames_static.end()) + { + if (colInd < pFind->second.size()) + { + pFind->second[colInd] = i->m_oName.get(); + } + } + } + colInd++; + } + } + if(Table.m_oId.IsInit() && Table.m_oName.IsInit()) + { + XLS::GlobalWorkbookInfo::mapTableNames_static.emplace(Table.m_oId->GetValue(), Table.m_oName.get()); + auto curXti = XLS::GlobalWorkbookInfo::arXti_External_static.size()-1; + if(!XLS::GlobalWorkbookInfo::mapXtiTables_static.count(curXti)) + { + XLS::GlobalWorkbookInfo::mapXtiTables_static.emplace(curXti, std::vector()); + } + XLS::GlobalWorkbookInfo::mapXtiTables_static.at(curXti).push_back(Table.m_oId->GetValue()); + } + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryTableReader::ReadCachePart(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + auto tablePtr = static_cast(poResult); + if (c_oSer_TablePart::Id == type) + { + tablePtr->m_oId.Init(); + tablePtr->m_oId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_TablePart::Name == type) + { + tablePtr->m_oName = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_TablePart::TableColumns == type) + { + tablePtr->m_oTableColumns.Init(); + READ1_DEF(length, res, this->ReadTableColumns, tablePtr->m_oTableColumns.GetPointer()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} int BinaryTableReader::ReadTable(BYTE type, long length, void* poResult) { int res = c_oSerConstants::ReadOk; @@ -996,6 +1073,32 @@ int BinaryTableReader::ReadTableColumns(BYTE type, long length, void* poResult) res = c_oSerConstants::ReadUnknown; return res; } +int BinaryTableReader::ReadTableXmlColumnPr(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CXmlColumnPr* pXmlColumnPr = static_cast(poResult); + + if (c_oSer_TableColumns::MapId == type) + { + pXmlColumnPr->mapId = m_oBufferedStream.GetLong(); + } + else if (c_oSer_TableColumns::Xpath == type) + { + pXmlColumnPr->xpath = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_TableColumns::Denormalized == type) + { + pXmlColumnPr->denormalized = m_oBufferedStream.GetBool(); + } + else if (c_oSer_TableColumns::XmlDataType == type) + { + pXmlColumnPr->xmlDataType.Init(); + pXmlColumnPr->xmlDataType->SetValueFromByte(m_oBufferedStream.GetUChar()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} int BinaryTableReader::ReadTableColumn(BYTE type, long length, void* poResult) { int res = c_oSerConstants::ReadOk; @@ -1063,6 +1166,11 @@ int BinaryTableReader::ReadTableColumn(BYTE type, long length, void* poResult) { pTableColumn->m_oUniqueName = m_oBufferedStream.GetString4(length); } + else if (c_oSer_TableColumns::XmlColumnPr == type) + { + pTableColumn->m_oXmlColumnPr.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadTableXmlColumnPr, pTableColumn->m_oXmlColumnPr.GetPointer()); + } else res = c_oSerConstants::ReadUnknown; return res; @@ -2149,6 +2257,8 @@ BinaryWorkbookTableReader::BinaryWorkbookTableReader(NSBinPptxRW::CBinaryFileRea } int BinaryWorkbookTableReader::Read() { + if(m_pXlsb) + m_oWorkbook.OOX::File::m_pMainDocument= m_pXlsb; int res = c_oSerConstants::ReadOk; READ_TABLE_DEF(res, this->ReadWorkbookTableContent, this); @@ -2189,7 +2299,8 @@ int BinaryWorkbookTableReader::ReadWorkbookTableContent(BYTE type, long length, m_oWorkbook.m_oExternalReferences.Init(); READ1_DEF(length, res, this->ReadExternalReferences, poResult); } - else if (c_oSerWorkbookTypes::PivotCaches == type) + else if (c_oSerWorkbookTypes::PivotCaches == type || + c_oSerWorkbookTypes::PivotCachesTmp == type) { m_oWorkbook.m_oPivotCachesXml.Init(); m_oWorkbook.m_oPivotCachesXml->append(L""); @@ -2275,6 +2386,8 @@ int BinaryWorkbookTableReader::ReadWorkbookTableContent(BYTE type, long length, else if (c_oSerWorkbookTypes::Connections == type) { smart_ptr oConnection(new OOX::Spreadsheet::CConnectionsFile(NULL)); + if(m_pXlsb) + oConnection->OOX::File::m_pMainDocument = m_pXlsb; oConnection->m_oConnections.Init(); READ1_DEF(length, res, this->ReadConnections, oConnection->m_oConnections.GetPointer()); @@ -2332,6 +2445,16 @@ int BinaryWorkbookTableReader::ReadWorkbookTableContent(BYTE type, long length, smart_ptr oFile = oMetadataFile.smart_dynamic_cast(); m_oWorkbook.Add(oFile); } + else if (c_oSerWorkbookTypes::XmlMap == type) + { + m_oBufferedStream.Skip(1); //skip type + + smart_ptr oXmlMapFile(new OOX::Spreadsheet::CXmlMapsFile(NULL)); + oXmlMapFile->fromPPTY(&m_oBufferedStream); + + smart_ptr oFile = oXmlMapFile.smart_dynamic_cast(); + m_oWorkbook.Add(oFile); + } else res = c_oSerConstants::ReadUnknown; return res; @@ -2995,6 +3118,8 @@ int BinaryWorkbookTableReader::ReadDefinedName(BYTE type, long length, void* poR if (c_oSerDefinedNameTypes::Name == type) { pDefinedName->m_oName = m_oBufferedStream.GetString4(length); + if(m_pXlsb) + XLS::GlobalWorkbookInfo::arDefineNames_static.push_back(pDefinedName->m_oName.get()); } else if (c_oSerDefinedNameTypes::Ref == type) { @@ -3487,23 +3612,36 @@ int BinaryWorkbookTableReader::ReadPivotCaches(BYTE type, long length, void* poR if (-1 != oPivotCachesTemp.nId && NULL != oPivotCachesTemp.pDefinitionData) { OOX::Spreadsheet::CPivotCacheDefinitionFile* pDefinitionFile = new OOX::Spreadsheet::CPivotCacheDefinitionFile(NULL); + if(m_pXlsb) + pDefinitionFile->OOX::File::m_pMainDocument = m_pXlsb; std::wstring srIdRecords; if (NULL != oPivotCachesTemp.pRecords) { NSCommon::smart_ptr pFileRecords(oPivotCachesTemp.pRecords); + if(m_pXlsb) + pFileRecords->OOX::File::m_pMainDocument = m_pXlsb; srIdRecords = pDefinitionFile->Add(pFileRecords).ToString(); } pDefinitionFile->setData(oPivotCachesTemp.pDefinitionData, oPivotCachesTemp.nDefinitionLength, srIdRecords); NSCommon::smart_ptr pFile(pDefinitionFile); OOX::RId rIdDefinition = m_oWorkbook.Add(pFile); - - m_oWorkbook.m_oPivotCachesXml->append(L"append(std::to_wstring(oPivotCachesTemp.nId)); - m_oWorkbook.m_oPivotCachesXml->append(L"\" r:id=\""); - m_oWorkbook.m_oPivotCachesXml->append(rIdDefinition.ToString()); - m_oWorkbook.m_oPivotCachesXml->append(L"\"/>"); - + if(!m_pXlsb) + { + m_oWorkbook.m_oPivotCachesXml->append(L"append(std::to_wstring(oPivotCachesTemp.nId)); + m_oWorkbook.m_oPivotCachesXml->append(L"\" r:id=\""); + m_oWorkbook.m_oPivotCachesXml->append(rIdDefinition.ToString()); + m_oWorkbook.m_oPivotCachesXml->append(L"\"/>"); + } + else + { auto bookPivotCache = new OOX::Spreadsheet::CWorkbookPivotCache; + bookPivotCache->m_oCacheId = (_UINT32)oPivotCachesTemp.nId; + bookPivotCache->m_oRid = rIdDefinition.ToString(); + if(!m_oWorkbook.m_oPivotCaches.IsInit()) + m_oWorkbook.m_oPivotCaches.Init(); + m_oWorkbook.m_oPivotCaches->m_arrItems.push_back(bookPivotCache); + } m_mapPivotCacheDefinitions[oPivotCachesTemp.nId] = pFile; } else @@ -3544,6 +3682,8 @@ int BinaryWorkbookTableReader::ReadSlicerCaches(BYTE type, long length, void* po if (c_oSerWorkbookTypes::SlicerCache == type) { OOX::Spreadsheet::CSlicerCacheFile* pSlicerCache = new OOX::Spreadsheet::CSlicerCacheFile(NULL); + if(m_pXlsb) + pSlicerCache->OOX::File::m_pMainDocument = m_pXlsb; pSlicerCache->m_oSlicerCacheDefinition.Init(); m_oBufferedStream.GetUChar();//type @@ -4134,6 +4274,19 @@ int BinaryWorksheetsTableReader::Read() READ_TABLE_DEF(res, this->ReadWorksheetsTableContent, this); return res; } +int BinaryWorksheetsTableReader::Read2xlsb(OOX::Spreadsheet::CXlsb &xlsb) +{ + m_pXlsb = &xlsb; + int res = c_oSerConstants::ReadOk; + //читаем листы для получения их имен и названий таблиц(используется в формулах) + auto worksheetsPos = m_oBufferedStream.GetPos(); + READ_TABLE_DEF(res, this->ReadWorksheetsCache, this); + m_oWorkbook.m_oSheets->m_arrItems.resize(0); + m_oBufferedStream.Seek(worksheetsPos); + + READ_TABLE_DEF(res, this->ReadWorksheetsTableContent, this); + return res; +} int BinaryWorksheetsTableReader::ReadWorksheetsTableContent(BYTE type, long length, void* poResult) { int res = c_oSerConstants::ReadOk; @@ -4150,22 +4303,35 @@ int BinaryWorksheetsTableReader::ReadWorksheetsTableContent(BYTE type, long leng boost::unordered_map> mapPos; READ1_DEF(length, res, this->ReadWorksheetSeekPositions, &mapPos); - - m_pCurWorksheet->m_bWriteDirectlyToFile = true; + m_pCurWorksheet->m_bWriteDirectlyToFile = true; smart_ptr oCurWorksheetFile = m_pCurWorksheet.smart_dynamic_cast(); + //for correct file extension + if(m_bWriteToXlsb) + { + oCurWorksheetFile->m_pMainDocument = m_pXlsb; + } m_oWorkbook.AssignOutputFilename(oCurWorksheetFile); std::wstring sWsPath = m_sDestinationDir + FILE_SEPARATOR_STR + _T("xl") + FILE_SEPARATOR_STR + m_pCurWorksheet->DefaultDirectory().GetPath(); NSDirectory::CreateDirectories(sWsPath); sWsPath += FILE_SEPARATOR_STR + m_pCurWorksheet->m_sOutputFilename; - NSFile::CStreamWriter oStreamWriter; - oStreamWriter.CreateFileW(sWsPath); - - m_pCurStreamWriter = &oStreamWriter; - res = ReadWorksheet(mapPos, oStreamWriter, poResult); - oStreamWriter.CloseFile(); + if(!m_bWriteToXlsb) + { + NSFile::CStreamWriter oStreamWriter; + oStreamWriter.CreateFileW(sWsPath); + m_pCurStreamWriter = &oStreamWriter; + res = ReadWorksheet(mapPos, oStreamWriter, poResult); + oStreamWriter.CloseFile(); + } + else + { + auto streamWriter = m_pXlsb->GetFileWriter(sWsPath); + m_pCurStreamWriterBin = streamWriter; + res = ReadWorksheet(mapPos, streamWriter, poResult); + m_pXlsb->WriteSreamCache(streamWriter); + } if (m_pCurSheet->m_oName.IsInit()) { const OOX::RId oRId = m_oWorkbook.Add(oCurWorksheetFile); @@ -4174,7 +4340,8 @@ int BinaryWorksheetsTableReader::ReadWorksheetsTableContent(BYTE type, long leng m_arWorksheets.push_back(m_pCurWorksheet.GetPointer()); m_pCurWorksheet.AddRef(); m_mapWorksheets [m_pCurSheet->m_oName.get()] = m_pCurWorksheet.GetPointer(); //for csv - + if(!m_oWorkbook.m_oSheets.IsInit()) + m_oWorkbook.m_oSheets.Init(); m_oWorkbook.m_oSheets->m_arrItems.push_back(m_pCurSheet.GetPointer()); m_pCurSheet.AddRef(); } } @@ -4182,6 +4349,21 @@ int BinaryWorksheetsTableReader::ReadWorksheetsTableContent(BYTE type, long leng res = c_oSerConstants::ReadUnknown; return res; } +int BinaryWorksheetsTableReader::ReadWorksheetsCache(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + if (c_oSerWorksheetsTypes::Worksheet == type) + { + m_pCurSheet.reset(new OOX::Spreadsheet::CSheet()); + boost::unordered_map> mapPos; + READ1_DEF(length, res, this->ReadWorksheetSeekPositions, &mapPos); + ReadSheetCache(mapPos, poResult); + m_pCurSheet.Release(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} int BinaryWorksheetsTableReader::ReadWorksheetSeekPositions(BYTE type, long length, void* poResult) { boost::unordered_map>* mapPos = static_cast>*>(poResult); @@ -4245,7 +4427,7 @@ int BinaryWorksheetsTableReader::ReadWorksheet(boost::unordered_mapReadWorksheetCols, &oCols); SEEK_TO_POS_END(oCols); //------------------------------------------------------------------------------------------------------------- - SEEK_TO_POS_START(c_oSerWorksheetsTypes::SheetData) + SEEK_TO_POS_START(c_oSerWorksheetsTypes::SheetData) if (NULL == m_oSaveParams.pCSVWriter) { OOX::Spreadsheet::CSheetData oSheetData; @@ -4561,7 +4743,7 @@ int BinaryWorksheetsTableReader::ReadWorksheet(boost::unordered_mapm_oSlicerList.Init(); READ1_DEF(length, res, this->ReadSlicers, pOfficeArtExtension->m_oSlicerList.GetPointer()); - pOfficeArtExtension->m_sUri = L"{A8765BA9-456A-4dab-B4F3-ACF838C121DE}"; + pOfficeArtExtension->m_sUri = L"{A8765BA9-456A-4dab-B4F3-ACF838C121DE}"; pOfficeArtExtension->m_sAdditionalNamespace = L"xmlns:x14=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/main\""; if (m_pCurWorksheet->m_oExtLst.IsInit() == false) @@ -4621,7 +4803,25 @@ int BinaryWorksheetsTableReader::ReadWorksheet(boost::unordered_mapReadPivotTable, &oPivotCachesTemp); + boost::unordered_map>::const_iterator pair = m_mapPivotCacheDefinitions.find(oPivotCachesTemp.nCacheId); + + if (m_mapPivotCacheDefinitions.end() != pair && NULL != oPivotCachesTemp.pTable) + { + NSCommon::smart_ptr pFileTable(oPivotCachesTemp.pTable); + oPivotCachesTemp.pTable->AddNoWrite(pair->second, L"../pivotCache"); + m_pCurWorksheet->Add(pFileTable); + } + else + { + RELEASEOBJECT(oPivotCachesTemp.pTable); + } + SEEK_TO_POS_END2(); +//tmp------------------------------------------------------------------------------------------------------------- SEEK_TO_POS_START(c_oSerWorksheetsTypes::NamedSheetView); smart_ptr pNamedSheetViewFile(new OOX::Spreadsheet::CNamedSheetViewFile(NULL)); pNamedSheetViewFile->m_oNamedSheetViews.Init(); @@ -4629,11 +4829,389 @@ int BinaryWorksheetsTableReader::ReadWorksheet(boost::unordered_map oFile = pNamedSheetViewFile.smart_dynamic_cast(); m_pCurWorksheet->Add(oFile); SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::TableSingleCells); + + m_oBufferedStream.Skip(1); //skip type + + smart_ptr pTableSingleCellsFile(new OOX::Spreadsheet::CTableSingleCellsFile(NULL)); + pTableSingleCellsFile->fromPPTY(&m_oBufferedStream); + smart_ptr oFile = pTableSingleCellsFile.smart_dynamic_cast(); + m_pCurWorksheet->Add(oFile); + SEEK_TO_POS_END2(); //------------------------------------------------------------------------------------------------------------- m_oBufferedStream.Seek(nOldPos); m_pCurWorksheet->toXMLEnd(oStreamWriter); return res; } +int BinaryWorksheetsTableReader::ReadWorksheet(boost::unordered_map>& mapPos, XLS::StreamCacheWriterPtr& oStreamWriter, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + { + auto beginSHeet = oStreamWriter->getNextRecord(XLSB::rt_BeginSheet); + oStreamWriter->storeNextRecord(beginSHeet); + } + boost::unordered_map>::iterator pFind; + LONG nPos; + LONG length; + LONG nOldPos = m_oBufferedStream.GetPos(); + //------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::WorksheetProp); + READ2_DEF_SPREADSHEET(length, res, this->ReadWorksheetProp, poResult); + SEEK_TO_POS_END2(); + //------------------------------------------------------------------------------------------------------------- + m_pCurWorksheet->m_oSheetViews.Init(); + SEEK_TO_POS_START(c_oSerWorksheetsTypes::SheetViews); + READ1_DEF(length, res, this->ReadSheetViews, m_pCurWorksheet->m_oSheetViews.GetPointer()); + SEEK_TO_POS_END2(); + if (m_pCurWorksheet->m_oSheetViews->m_arrItems.empty()) + m_pCurWorksheet->m_oSheetViews->m_arrItems.push_back(new OOX::Spreadsheet::CSheetView()); + OOX::Spreadsheet::CSheetView* pSheetView = m_pCurWorksheet->m_oSheetViews->m_arrItems.front(); + if (false == pSheetView->m_oWorkbookViewId.IsInit()) + { + pSheetView->m_oWorkbookViewId.Init(); + pSheetView->m_oWorkbookViewId->SetValue(0); + } + m_pCurWorksheet->m_oSheetViews->toBin(oStreamWriter); +//------------------------------------------------------------------------------------------------------------- + OOX::Spreadsheet::CSheetFormatPr oSheetFormatPr; + SEEK_TO_POS_START(c_oSerWorksheetsTypes::SheetFormatPr); + READ2_DEF_SPREADSHEET(length, res, this->ReadSheetFormatPr, &oSheetFormatPr); + SEEK_TO_POS_END2(); + if (!oSheetFormatPr.m_oDefaultRowHeight.IsInit()) + { + oSheetFormatPr.m_oDefaultRowHeight = 15.; + } + oSheetFormatPr.toBin(oStreamWriter); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::Cols); + OOX::Spreadsheet::CCols oCols; + READ1_DEF(length, res, this->ReadWorksheetCols, &oCols); + oCols.toBin(oStreamWriter); + SEEK_TO_POS_END2() +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::SheetData) + { + auto begin = m_pCurStreamWriterBin->getNextRecord(XLSB::rt_BeginSheetData); + m_pCurStreamWriterBin->storeNextRecord(begin); + } + READ1_DEF(length, res, this->ReadSheetData, NULL); + m_pCurWorksheet->m_oSheetData->ClearSharedFmlaRefs(); + { + auto end = m_pCurStreamWriterBin->getNextRecord(XLSB::rt_EndSheetData); + m_pCurStreamWriterBin->storeNextRecord(end); + } + SEEK_TO_POS_END2() +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::Protection); + OOX::Spreadsheet::CSheetProtection oProtection; + READ2_DEF_SPREADSHEET(length, res, this->ReadProtection, &oProtection); + oProtection.toBin(oStreamWriter); + SEEK_TO_POS_END2() +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::ProtectedRanges); + OOX::Spreadsheet::CProtectedRanges oProtectedRanges; + READ1_DEF(length, res, this->ReadProtectedRanges, &oProtectedRanges); + oProtectedRanges.toBin(oStreamWriter); + SEEK_TO_POS_END2() +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::Autofilter); + OOX::Spreadsheet::CAutofilter oAutofilter; + BinaryTableReader oBinaryTableReader(m_oBufferedStream, m_pCurWorksheet.GetPointer()); + READ1_DEF(length, res, oBinaryTableReader.ReadAutoFilter, &oAutofilter); + oAutofilter.toBin(oStreamWriter); + SEEK_TO_POS_END2() +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::SortState); + OOX::Spreadsheet::CSortState oSortState; + BinaryTableReader oBinaryTableReader(m_oBufferedStream, m_pCurWorksheet.GetPointer()); + READ1_DEF(length, res, oBinaryTableReader.ReadSortState, &oSortState); + oSortState.toBin(oStreamWriter); + SEEK_TO_POS_END2() +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::MergeCells); + OOX::Spreadsheet::CMergeCells oMergeCells; + READ1_DEF(length, res, this->ReadMergeCells, &oMergeCells); + oMergeCells.m_oCount.Init(); + oMergeCells.m_oCount->SetValue((unsigned int)oMergeCells.m_arrItems.size()); + oMergeCells.toBin(oStreamWriter); + SEEK_TO_POS_END2() +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::ConditionalFormatting); + OOX::Drawing::COfficeArtExtension* pOfficeArtExtensionCF = new OOX::Drawing::COfficeArtExtension(); + OOX::Spreadsheet::CConditionalFormatting *pConditionalFormatting = new OOX::Spreadsheet::CConditionalFormatting(); + READ1_DEF(length, res, this->ReadConditionalFormatting, pConditionalFormatting); + if (pConditionalFormatting->IsExtended()) + { + pOfficeArtExtensionCF->m_arrConditionalFormatting.push_back(pConditionalFormatting); + } + else + { + pConditionalFormatting->toBin(oStreamWriter); + delete pConditionalFormatting; + } + if (pOfficeArtExtensionCF->m_arrConditionalFormatting.empty()) + { + delete pOfficeArtExtensionCF; + } + else + { + pOfficeArtExtensionCF->m_sUri = L"{78C0D931-6437-407d-A8EE-F0AAD7539E65}"; + + if (m_pCurWorksheet->m_oExtLst.IsInit() == false) + m_pCurWorksheet->m_oExtLst.Init(); + m_pCurWorksheet->m_oExtLst->m_arrExt.push_back(pOfficeArtExtensionCF); + } + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::DataValidations); + OOX::Spreadsheet::CDataValidations oDataValidations; + READ1_DEF(length, res, this->ReadDataValidations, &oDataValidations); + oDataValidations.toBin(oStreamWriter); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::Hyperlinks); + OOX::Spreadsheet::CHyperlinks oHyperlinks; + READ1_DEF(length, res, this->ReadHyperlinks, &oHyperlinks); + oHyperlinks.toBin(oStreamWriter); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::PrintOptions); + OOX::Spreadsheet::CPrintOptions oPrintOptions; + READ2_DEF_SPREADSHEET(length, res, this->ReadPrintOptions, &oPrintOptions); + oPrintOptions.toBin(oStreamWriter); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::PageMargins); + OOX::Spreadsheet::CPageMargins oPageMargins; + READ2_DEF_SPREADSHEET(length, res, this->ReadPageMargins, &oPageMargins); + oPageMargins.toBin(oStreamWriter); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::PageSetup); + OOX::Spreadsheet::CPageSetup oPageSetup; + READ2_DEF_SPREADSHEET(length, res, this->ReadPageSetup, &oPageSetup); + oPageSetup.toBin(oStreamWriter); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::HeaderFooter); + OOX::Spreadsheet::CHeaderFooter oHeaderFooter; + READ1_DEF(length, res, this->ReadHeaderFooter, &oHeaderFooter); + oHeaderFooter.toBin(oStreamWriter); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::RowBreaks); + OOX::Spreadsheet::CRowColBreaks oRowBreaks; + READ1_DEF(length, res, this->ReadRowColBreaks, &oRowBreaks); + oRowBreaks.toBinRow(oStreamWriter); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::ColBreaks); + OOX::Spreadsheet::CRowColBreaks oColBreaks; + READ1_DEF(length, res, this->ReadRowColBreaks, &oColBreaks); + oColBreaks.toBinColumn(oStreamWriter); + SEEK_TO_POS_END2(); + +//------------------------------------------------------------------------------------------------------------- + //important before Drawings + SEEK_TO_POS_START(c_oSerWorksheetsTypes::Comments); + BinaryCommentReader oBinaryCommentReader(m_oBufferedStream, m_pCurWorksheet.GetPointer()); + oBinaryCommentReader.Read(length, poResult); + WriteComments(); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::Drawings); + + m_pOfficeDrawingConverter->SetDstContentRels(); + READ1_DEF(length, res, this->ReadDrawings, m_pCurDrawing.GetPointer()); + + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + OOX::Spreadsheet::CControls oControls; + + SEEK_TO_POS_START(c_oSerWorksheetsTypes::Controls); + READ1_DEF(length, res, this->ReadControls, &oControls); + //SEEK_TO_POS_END(oControls); ниже ... + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + OOX::CPath pathDrawingsDir = m_sDestinationDir + FILE_SEPARATOR_STR + _T("xl") + FILE_SEPARATOR_STR + _T("drawings"); + OOX::CPath pathDrawingsRelsDir = pathDrawingsDir.GetPath() + FILE_SEPARATOR_STR + _T("_rels"); + + if (false == m_pCurDrawing->IsEmpty() || false == m_pCurVmlDrawing->IsEmpty()) + { + OOX::CSystemUtility::CreateDirectories(pathDrawingsDir.GetPath()); + OOX::CSystemUtility::CreateDirectories(pathDrawingsRelsDir.GetPath()); + } + + if (false == m_pCurDrawing->IsEmpty()) + { + NSCommon::smart_ptr pFile = m_pCurDrawing.smart_dynamic_cast(); + const OOX::RId oRId = m_pCurWorksheet->Add(pFile); + + OOX::Spreadsheet::CDrawingWorksheet oDrawingWorksheet; + oDrawingWorksheet.m_oId.Init(); + oDrawingWorksheet.m_oId->SetValue(oRId.get()); + oDrawingWorksheet.toBin(oStreamWriter); + + OOX::CPath pathDrawingsRels = pathDrawingsRelsDir.GetPath() + FILE_SEPARATOR_STR + m_pCurDrawing->m_sOutputFilename + _T(".rels"); + m_pOfficeDrawingConverter->SaveDstContentRels(pathDrawingsRels.GetPath()); + } +//------------------------------------------------------------------------------------------------------------- + if (false == m_pCurVmlDrawing->IsEmpty()) + { + NSCommon::smart_ptr pFile = m_pCurVmlDrawing.smart_dynamic_cast(); + const OOX::RId oRId = m_pCurWorksheet->Add(pFile); + OOX::Spreadsheet::CLegacyDrawingWorksheet oLegacyDrawing; + oLegacyDrawing.m_oId.Init(); + oLegacyDrawing.m_oId->SetValue(oRId.get()); + oLegacyDrawing.toBin(oStreamWriter); + } +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::LegacyDrawingHF); + OOX::Spreadsheet::CLegacyDrawingHFWorksheet oLegacyDrawingHF; + READ1_DEF(length, res, this->ReadLegacyDrawingHF, &oLegacyDrawingHF); + oLegacyDrawingHF.toBin(oStreamWriter); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::Picture); + std::wstring sPicture = m_pOfficeDrawingConverter->m_pReader->m_strFolder + FILE_SEPARATOR_STR + _T("media") + FILE_SEPARATOR_STR + m_oBufferedStream.GetString4(length); + smart_ptr additionalFile; + NSBinPptxRW::_relsGeneratorInfo oRelsGeneratorInfo = m_pOfficeDrawingConverter->m_pReader->m_pRels->WriteImage(sPicture, additionalFile, L"", L""); + + NSCommon::smart_ptr pImageFileWorksheet(new OOX::Image(NULL, false)); + pImageFileWorksheet->set_filename(oRelsGeneratorInfo.sFilepathImage, false); + smart_ptr pFileWorksheet = pImageFileWorksheet.smart_dynamic_cast(); + OOX::RId oRId = m_pCurWorksheet->Add(pFileWorksheet); + + OOX::Spreadsheet::CPictureWorksheet oPicture; + oPicture.m_oId.Init(); + oPicture.m_oId->SetValue(oRId.get()); + oPicture.toBin(oStreamWriter); + SEEK_TO_POS_END2(); + + if (false == m_pCurOleObjects->m_mapOleObjects.empty()) + { + m_pCurOleObjects->toBin(oStreamWriter); + } + + oControls.toBin(oStreamWriter); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::TableParts); + BinaryTableReader oBinaryTableReader(m_oBufferedStream, m_pCurWorksheet.GetPointer()); + OOX::Spreadsheet::CTableParts oTableParts; + oBinaryTableReader.Read(length, &oTableParts); + oTableParts.m_oCount.Init(); + oTableParts.m_oCount->SetValue((unsigned int)oTableParts.m_arrItems.size()); + oTableParts.toBin(oStreamWriter); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::QueryTable); + BinaryTableReader oBinaryTableReader(m_oBufferedStream, m_pCurWorksheet.GetPointer()); + smart_ptr pQueryTableFile(new OOX::Spreadsheet::CQueryTableFile(NULL)); + pQueryTableFile->m_oQueryTable.Init(); + + oBinaryTableReader.ReadQueryTable(length, pQueryTableFile->m_oQueryTable.GetPointer()); + + smart_ptr oFile = pQueryTableFile.smart_dynamic_cast(); + m_pCurWorksheet->Add(oFile); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::SparklineGroups); + OOX::Drawing::COfficeArtExtension* pOfficeArtExtension = new OOX::Drawing::COfficeArtExtension(); + pOfficeArtExtension->m_oSparklineGroups.Init(); + + READ1_DEF(length, res, this->ReadSparklineGroups, pOfficeArtExtension->m_oSparklineGroups.GetPointer()); + + pOfficeArtExtension->m_sUri = L"{05C60535-1F16-4fd2-B633-F4F36F0B64E0}"; + if (m_pCurWorksheet->m_oExtLst.IsInit() == false) + m_pCurWorksheet->m_oExtLst.Init(); + m_pCurWorksheet->m_oExtLst->m_arrExt.push_back(pOfficeArtExtension); + + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::Slicers); + OOX::Drawing::COfficeArtExtension* pOfficeArtExtension = new OOX::Drawing::COfficeArtExtension(); + pOfficeArtExtension->m_oSlicerList.Init(); + READ1_DEF(length, res, this->ReadSlicers, pOfficeArtExtension->m_oSlicerList.GetPointer()); + + pOfficeArtExtension->m_sUri = L"{A8765BA9-456A-4dab-B4F3-ACF838C121DE}"; + pOfficeArtExtension->m_sAdditionalNamespace = L"xmlns:x14=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/main\""; + + if (m_pCurWorksheet->m_oExtLst.IsInit() == false) + m_pCurWorksheet->m_oExtLst.Init(); + m_pCurWorksheet->m_oExtLst->m_arrExt.push_back(pOfficeArtExtension); + SEEK_TO_POS_END2(); + + SEEK_TO_POS_START(c_oSerWorksheetsTypes::SlicersExt); + OOX::Drawing::COfficeArtExtension* pOfficeArtExtension = new OOX::Drawing::COfficeArtExtension(); + pOfficeArtExtension->m_oSlicerListExt.Init(); + READ1_DEF(length, res, this->ReadSlicers, pOfficeArtExtension->m_oSlicerListExt.GetPointer()); + + pOfficeArtExtension->m_sUri = L"{3A4CF648-6AED-40f4-86FF-DC5316D8AED3}"; + pOfficeArtExtension->m_sAdditionalNamespace = L"xmlns:x15=\"http://schemas.microsoft.com/office/spreadsheetml/2010/11/main\""; + + if (m_pCurWorksheet->m_oExtLst.IsInit() == false) + m_pCurWorksheet->m_oExtLst.Init(); + m_pCurWorksheet->m_oExtLst->m_arrExt.push_back(pOfficeArtExtension); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + if (m_pCurWorksheet->m_oExtLst.IsInit()) + { + auto extLst = m_pCurWorksheet->m_oExtLst->toBinWorksheet(); + extLst->write(oStreamWriter, nullptr); + } + SEEK_TO_POS_START(c_oSerWorksheetsTypes::PivotTable); + PivotCachesTemp oPivotCachesTemp; + + READ1_DEF(length, res, this->ReadPivotTable, &oPivotCachesTemp); + boost::unordered_map>::const_iterator pair = m_mapPivotCacheDefinitions.find(oPivotCachesTemp.nCacheId); + + if (m_mapPivotCacheDefinitions.end() != pair && NULL != oPivotCachesTemp.pTable) + { + NSCommon::smart_ptr pFileTable(oPivotCachesTemp.pTable); + if(m_pXlsb) + pFileTable->m_pMainDocument = m_pXlsb; + oPivotCachesTemp.pTable->AddNoWrite(pair->second, L"../pivotCache"); + m_pCurWorksheet->Add(pFileTable); + } + else + { + RELEASEOBJECT(oPivotCachesTemp.pTable); + } + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + m_oBufferedStream.Seek(nOldPos); + { + auto endSheet = oStreamWriter->getNextRecord(XLSB::rt_EndSheet); + oStreamWriter->storeNextRecord(endSheet); + } + return res; +} +int BinaryWorksheetsTableReader::ReadSheetCache(boost::unordered_map>& mapPos, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + boost::unordered_map>::iterator pFind; + LONG nPos; + LONG length; + LONG nOldPos = m_oBufferedStream.GetPos(); + SEEK_TO_POS_START(c_oSerWorksheetsTypes::WorksheetProp); + READ2_DEF_SPREADSHEET(length, res, this->ReadWorksheetProp, poResult); + SEEK_TO_POS_END2(); + if(!m_oWorkbook.m_oSheets.IsInit()) + m_oWorkbook.m_oSheets.Init(); + if (m_pCurSheet->m_oName.IsInit()) + { + m_oWorkbook.m_oSheets->AddSheetRef(m_pCurSheet->m_oName.get(), m_oWorkbook.m_oSheets->m_arrItems.size()); + m_oWorkbook.m_oSheets->m_arrItems.push_back(m_pCurSheet.GetPointer()); + } + SEEK_TO_POS_START(c_oSerWorksheetsTypes::TableParts); + BinaryTableReader oBinaryTableReader(m_oBufferedStream, m_pCurWorksheet.GetPointer()); + OOX::Spreadsheet::CTableParts oTableParts; + oBinaryTableReader.ReadTableCache(length, &oTableParts); + SEEK_TO_POS_END2(); + m_oBufferedStream.Seek(nOldPos); + return res; +} void BinaryWorksheetsTableReader::WriteComments() { if (m_pCurWorksheet->m_mapComments.empty()) return; @@ -4642,6 +5220,8 @@ void BinaryWorksheetsTableReader::WriteComments() boost::unordered_map mapByAuthors; OOX::Spreadsheet::CComments* pComments = new OOX::Spreadsheet::CComments(NULL); + if(m_pXlsb && m_bWriteToXlsb) + pComments->File::m_pMainDocument = m_pXlsb; pComments->m_oCommentList.Init(); std::vector& aComments = pComments->m_oCommentList->m_arrItems; @@ -6320,12 +6900,17 @@ int BinaryWorksheetsTableReader::ReadRow(BYTE type, long length, void* poResult) } else if (c_oSerRowTypes::Cells == type) { - if (NULL == m_oSaveParams.pCSVWriter) + if (NULL == m_oSaveParams.pCSVWriter && NULL == m_pCurStreamWriterBin) { pRow->toXMLStart(*m_pCurStreamWriter); READ1_DEF(length, res, this->ReadCells, pRow); pRow->toXMLEnd(*m_pCurStreamWriter); } + else if(m_pCurStreamWriterBin != NULL) + { + pRow->WriteAttributes(m_pCurStreamWriterBin); + READ1_DEF(length, res, this->ReadCells, pRow); + } else { m_oSaveParams.pCSVWriter->WriteRowStart(pRow); @@ -6399,10 +6984,16 @@ int BinaryWorksheetsTableReader::ReadCells(BYTE type, long length, void* poResul oCell.m_oValue->m_sText = errText; } } - if (NULL == m_oSaveParams.pCSVWriter) + if (NULL == m_oSaveParams.pCSVWriter && m_pCurStreamWriterBin == NULL) { oCell.toXML(*m_pCurStreamWriter); } + else if(m_pCurStreamWriterBin != NULL) + { + if(oCell.m_oRow.IsInit()) + *(oCell.m_oRow) += 1; + oCell.toBin(m_pCurStreamWriterBin); + } else { m_oSaveParams.pCSVWriter->WriteCell(&oCell); @@ -7721,6 +8312,8 @@ int BinaryWorksheetsTableReader::ReadSlicers(BYTE type, long length, void* poRes if (c_oSerWorksheetsTypes::Slicer == type) { OOX::Spreadsheet::CSlicerFile* pSlicer = new OOX::Spreadsheet::CSlicerFile(NULL); + if(m_pXlsb && m_bWriteToXlsb) + pSlicer->OOX::File::m_pMainDocument = m_pXlsb; pSlicer->m_oSlicers.Init(); m_oBufferedStream.GetUChar();//type @@ -8787,7 +9380,14 @@ int BinaryFileReader::ReadFile(const std::wstring& sSrcFileName, std::wstring sD bResultOk = false; } + OOX::CPath oXlPath = OOX::CPath(sDstPath).GetDirectory() / oXlsb.m_pWorkbook->DefaultDirectory(); + oXlsb.WriteWorkbook(oXlPath); + if(oXlsb.m_pStyles) + oXlsb.m_pStyles->OOX::File::m_pMainDocument = &oXlsb; + if(oXlsb.m_pSharedStrings) + oXlsb.m_pSharedStrings->OOX::File::m_pMainDocument = &oXlsb; oXlsb.PrepareToWrite(); + oXlsb.PrepareRichStr(); oXlsb.WriteBin(sDstPath, *oSaveParams.pContentTypes); bMacro = oSaveParams.bMacroEnabled; @@ -8900,7 +9500,13 @@ int BinaryFileReader::ReadMainTable(OOX::Spreadsheet::CXlsx& oXlsx, NSBinPptxRW: oXlsx.m_pWorkbook->m_bMacroEnabled = oSaveParams.bMacroEnabled; oBufferedStream.Seek(nWorkbookOffBits); - res = BinaryWorkbookTableReader(oBufferedStream, *oXlsx.m_pWorkbook, m_mapPivotCacheDefinitions, sOutDir, pOfficeDrawingConverter).Read(); + auto bookReader = BinaryWorkbookTableReader(oBufferedStream, *oXlsx.m_pWorkbook, m_mapPivotCacheDefinitions, sOutDir, pOfficeDrawingConverter); + OOX::Spreadsheet::CXlsb* xlsb = dynamic_cast(&oXlsx); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + bookReader.m_pXlsb = xlsb; + } + res = bookReader.Read(); if (c_oSerConstants::ReadOk != res) return res; oSaveParams.bMacroEnabled = oXlsx.m_pWorkbook->m_bMacroEnabled; @@ -8953,7 +9559,15 @@ int BinaryFileReader::ReadMainTable(OOX::Spreadsheet::CXlsx& oXlsx, NSBinPptxRW: }break; case c_oSerTableTypes::Worksheets: { - res = BinaryWorksheetsTableReader(oBufferedStream, *oXlsx.m_pWorkbook, oXlsx.m_pSharedStrings, oXlsx.m_arWorksheets, oXlsx.m_mapWorksheets, mapMedia, sOutDir, sMediaDir, oSaveParams, pOfficeDrawingConverter, m_mapPivotCacheDefinitions).Read(); + auto sheetreader = BinaryWorksheetsTableReader(oBufferedStream, *oXlsx.m_pWorkbook, oXlsx.m_pSharedStrings, oXlsx.m_arWorksheets, oXlsx.m_mapWorksheets, mapMedia, sOutDir, sMediaDir, oSaveParams, pOfficeDrawingConverter, m_mapPivotCacheDefinitions); + OOX::Spreadsheet::CXlsb* xlsb = dynamic_cast(&oXlsx); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + sheetreader.m_bWriteToXlsb = true; + res = sheetreader.Read2xlsb(*xlsb); + } + else + res = sheetreader.Read(); }break; case c_oSerTableTypes::Customs: { diff --git a/OOXML/Binary/Sheets/Writer/BinaryReaderS.cpp b/OOXML/Binary/Sheets/Writer/BinaryReaderS.cpp new file mode 100644 index 0000000000..4ea9ce69b6 --- /dev/null +++ b/OOXML/Binary/Sheets/Writer/BinaryReaderS.cpp @@ -0,0 +1,9548 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "BinaryReaderS.h" + +#include "../../../../Common/Base64.h" +#include "../../../../Common/ATLDefine.h" +#include "../../../../Common/OfficeFileErrorDescription.h" + +#include "../../../../DesktopEditor/common/Path.h" +#include "../../../../DesktopEditor/common/Directory.h" +#include "../../../../DesktopEditor/raster/ImageFileFormatChecker.h" + +#include "../Writer/CSVWriter.h" +#include "BinaryCommonReader.h" + +#include "../../Document/BinReader/DefaultThemeWriter.h" + +#include "../../../PPTXFormat/Theme.h" +#include "../../../../MsBinaryFile/Common/Vml/toVmlConvert.h" +#include "../../../PPTXFormat/Logic/HeadingVariant.h" +#include "../../../PPTXFormat/Logic/Shape.h" + +#include "../../../XlsxFormat/Worksheets/Sparkline.h" +#include "../../../XlsxFormat/Drawing/Drawing.h" +#include "../../../XlsxFormat/Drawing/Pos.h" +#include "../../../XlsxFormat/Comments/Comments.h" +#include "../../../XlsxFormat/SharedStrings/SharedStrings.h" +#include "../../../XlsxFormat/Styles/Styles.h" +#include "../../../XlsxFormat/Styles/Borders.h" +#include "../../../XlsxFormat/Styles/Fills.h" +#include "../../../XlsxFormat/Styles/Fonts.h" +#include "../../../XlsxFormat/Styles/NumFmts.h" +#include "../../../XlsxFormat/Styles/Xfs.h" +#include "../../../XlsxFormat/Styles/dxf.h" +#include "../../../XlsxFormat/Styles/CellStyles.h" +#include "../../../XlsxFormat/Styles/TableStyles.h" +#include "../../../XlsxFormat/CalcChain/CalcChain.h" +#include "../../../XlsxFormat/ExternalLinks/ExternalLinks.h" +#include "../../../XlsxFormat/ExternalLinks/ExternalLinkPath.h" +#include "../../../XlsxFormat/WorkbookComments.h" +#include "../../../XlsxFormat/Table/Connections.h" +#include "../../../XlsxFormat/Controls/Controls.h" +#include "../../../XlsxFormat/Timelines/Timeline.h" +#include "../../../XlsxFormat/Workbook/Metadata.h" + +#include "../../../DocxFormat/Media/VbaProject.h" +#include "../../../DocxFormat/Media/JsaProject.h" +#include "../../../DocxFormat/VmlDrawing.h" +#include "../../../DocxFormat/App.h" +#include "../../../DocxFormat/Core.h" +#include "../../../DocxFormat/CustomXml.h" +#include "../../../DocxFormat/Drawing/DrawingExt.h" + +#include "../../../XlsxFormat/Comments/ThreadedComments.h" +#include "../../../XlsxFormat/Slicer/SlicerCache.h" +#include "../../../XlsxFormat/Slicer/SlicerCacheExt.h" +#include "../../../XlsxFormat/Slicer/Slicer.h" +#include "../../../XlsxFormat/NamedSheetViews/NamedSheetViews.h" + +namespace BinXlsxRW +{ + #define SEEK_TO_POS_START(type) \ + pFind = mapPos.find(type); \ + if (pFind != mapPos.end()) \ + { \ + for (size_t i = 0; i < pFind->second.size() - 1; i+=2) \ + { \ + nPos = pFind->second[i]; \ + length = pFind->second[i + 1]; \ + m_oBufferedStream.Seek(nPos); \ + +#define SEEK_TO_POS_END(elem) \ + elem.toXML(oStreamWriter); \ + } \ + } + +#define SEEK_TO_POS_END2() \ + } \ + } + +#define SEEK_TO_POS_ELSE() \ + else \ + { + +#define SEEK_TO_POS_ELSE_END() \ + } + +Binary_CommonReader2::Binary_CommonReader2(NSBinPptxRW::CBinaryFileReader& poBufferedStream):m_poBufferedStream(poBufferedStream) +{ +} +int Binary_CommonReader2::ReadColor(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CColor* pColor = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_ColorObjectType::Type == type) + { + BYTE byteColorType = m_poBufferedStream.GetUChar(); + if (c_oSer_ColorType::Auto == byteColorType) + { + pColor->m_oAuto.Init(); + pColor->m_oAuto->SetValue(SimpleTypes::onoffTrue); + } + } + else if (c_oSer_ColorObjectType::Rgb == type) + { + pColor->m_oRgb.Init(); + pColor->m_oRgb->FromInt(m_poBufferedStream.GetLong()); + } + else if (c_oSer_ColorObjectType::Theme == type) + { + pColor->m_oThemeColor.Init(); + pColor->m_oThemeColor->SetValue((SimpleTypes::Spreadsheet::EThemeColor)m_poBufferedStream.GetUChar()); + } + else if (c_oSer_ColorObjectType::Tint == type) + { + pColor->m_oTint.Init(); + pColor->m_oTint->SetValue(m_poBufferedStream.GetDoubleReal()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} + +BinaryTableReader::BinaryTableReader(NSBinPptxRW::CBinaryFileReader& oBufferedStream, OOX::Spreadsheet::CWorksheet* pCurWorksheet):Binary_CommonReader(oBufferedStream), m_pCurWorksheet(pCurWorksheet) +{ +} +int BinaryTableReader::Read(long length, OOX::Spreadsheet::CTableParts* pTableParts) +{ + int res = c_oSerConstants::ReadOk; + READ1_DEF(length, res, this->ReadTablePart, pTableParts); + return res; +} +int BinaryTableReader::ReadQueryTable(long length, OOX::Spreadsheet::CQueryTable* pQueryTable) +{ + int res = c_oSerConstants::ReadOk; + READ1_DEF(length, res, this->ReadQueryTableContent, pQueryTable); + return res; +} +int BinaryTableReader::ReadQueryTableContent(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CQueryTable* pQueryTable = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_QueryTable::ConnectionId == type) + { + pQueryTable->m_oConnectionId.Init(); + pQueryTable->m_oConnectionId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_QueryTable::Name == type) + { + pQueryTable->m_oName = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_QueryTable::AutoFormatId == type) + { + pQueryTable->m_oAutoFormatId.Init(); + pQueryTable->m_oAutoFormatId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_QueryTable::GrowShrinkType == type) + { + pQueryTable->m_oGrowShrinkType = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_QueryTable::AdjustColumnWidth == type) + { + pQueryTable->m_oAdjustColumnWidth = m_oBufferedStream.GetBool(); + } + else if (c_oSer_QueryTable::ApplyAlignmentFormats == type) + { + pQueryTable->m_oApplyAlignmentFormats = m_oBufferedStream.GetBool(); + } + else if (c_oSer_QueryTable::ApplyBorderFormats == type) + { + pQueryTable->m_oApplyBorderFormats = m_oBufferedStream.GetBool(); + } + else if (c_oSer_QueryTable::ApplyFontFormats == type) + { + pQueryTable->m_oApplyFontFormats = m_oBufferedStream.GetBool(); + } + else if (c_oSer_QueryTable::ApplyNumberFormats == type) + { + pQueryTable->m_oApplyNumberFormats = m_oBufferedStream.GetBool(); + } + else if (c_oSer_QueryTable::ApplyPatternFormats == type) + { + pQueryTable->m_oApplyPatternFormats = m_oBufferedStream.GetBool(); + } + else if (c_oSer_QueryTable::ApplyWidthHeightFormats == type) + { + pQueryTable->m_oApplyWidthHeightFormats = m_oBufferedStream.GetBool(); + } + else if (c_oSer_QueryTable::BackgroundRefresh == type) + { + pQueryTable->m_oBackgroundRefresh = m_oBufferedStream.GetBool(); + } + else if (c_oSer_QueryTable::DisableEdit == type) + { + pQueryTable->m_oDisableEdit = m_oBufferedStream.GetBool(); + } + else if (c_oSer_QueryTable::DisableRefresh == type) + { + pQueryTable->m_oDisableRefresh = m_oBufferedStream.GetBool(); + } + else if (c_oSer_QueryTable::FillFormulas == type) + { + pQueryTable->m_oFillFormulas = m_oBufferedStream.GetBool(); + } + else if (c_oSer_QueryTable::FirstBackgroundRefresh == type) + { + pQueryTable->m_oFirstBackgroundRefresh = m_oBufferedStream.GetBool(); + } + else if (c_oSer_QueryTable::Headers == type) + { + pQueryTable->m_oHeaders = m_oBufferedStream.GetBool(); + } + else if (c_oSer_QueryTable::Intermediate == type) + { + pQueryTable->m_oIntermediate = m_oBufferedStream.GetBool(); + } + else if (c_oSer_QueryTable::PreserveFormatting == type) + { + pQueryTable->m_oPreserveFormatting = m_oBufferedStream.GetBool(); + } + else if (c_oSer_QueryTable::RefreshOnLoad == type) + { + pQueryTable->m_oRefreshOnLoad = m_oBufferedStream.GetBool(); + } + else if (c_oSer_QueryTable::RemoveDataOnSave == type) + { + pQueryTable->m_oRemoveDataOnSave = m_oBufferedStream.GetBool(); + } + else if (c_oSer_QueryTable::RowNumbers == type) + { + pQueryTable->m_oRowNumbers = m_oBufferedStream.GetBool(); + } + else if (c_oSer_QueryTable::QueryTableRefresh == type) + { + pQueryTable->m_oQueryTableRefresh.Init(); + READ1_DEF(length, res, this->ReadQueryTableRefresh, pQueryTable->m_oQueryTableRefresh.GetPointer()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryTableReader::ReadQueryTableRefresh(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CQueryTableRefresh* pQueryTableRefresh = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_QueryTableRefresh::NextId == type) + { + pQueryTableRefresh->m_oNextId.Init(); + pQueryTableRefresh->m_oNextId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_QueryTableRefresh::MinimumVersion == type) + { + pQueryTableRefresh->m_oMinimumVersion.Init(); + pQueryTableRefresh->m_oMinimumVersion->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_QueryTableRefresh::UnboundColumnsLeft == type) + { + pQueryTableRefresh->m_UnboundColumnsLeft.Init(); + pQueryTableRefresh->m_UnboundColumnsLeft->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_QueryTableRefresh::UnboundColumnsRight == type) + { + pQueryTableRefresh->m_UnboundColumnsRight.Init(); + pQueryTableRefresh->m_UnboundColumnsRight->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_QueryTableRefresh::FieldIdWrapped == type) + { + pQueryTableRefresh->m_FieldIdWrapped = m_oBufferedStream.GetBool(); + } + else if (c_oSer_QueryTableRefresh::HeadersInLastRefresh == type) + { + pQueryTableRefresh->m_HeadersInLastRefresh = m_oBufferedStream.GetBool(); + } + else if (c_oSer_QueryTableRefresh::PreserveSortFilterLayout == type) + { + pQueryTableRefresh->m_PreserveSortFilterLayout = m_oBufferedStream.GetBool(); + } + else if (c_oSer_QueryTableRefresh::SortState == type) + { + pQueryTableRefresh->m_oSortState.Init(); + READ1_DEF(length, res, this->ReadSortState, pQueryTableRefresh->m_oSortState.GetPointer()); + } + else if (c_oSer_QueryTableRefresh::QueryTableFields == type) + { + pQueryTableRefresh->m_oQueryTableFields.Init(); + READ1_DEF(length, res, this->ReadQueryTableFields, pQueryTableRefresh->m_oQueryTableFields.GetPointer()); + } + else if (c_oSer_QueryTableRefresh::QueryTableDeletedFields == type) + { + pQueryTableRefresh->m_oQueryTableDeletedFields.Init(); + READ1_DEF(length, res, this->ReadQueryTableDeletedFields, pQueryTableRefresh->m_oQueryTableDeletedFields.GetPointer()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryTableReader::ReadQueryTableFields(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CQueryTableFields* pQueryTableFields = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_QueryTableField::QueryTableField == type) + { + OOX::Spreadsheet::CQueryTableField* pQueryTableField = new OOX::Spreadsheet::CQueryTableField(); + READ1_DEF(length, res, this->ReadQueryTableField, pQueryTableField); + + pQueryTableFields->m_arrItems.push_back(pQueryTableField); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryTableReader::ReadQueryTableDeletedField(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CQueryTableDeletedField* pQueryTableDeletedField = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_QueryTableDeletedField::Name == type) + { + pQueryTableDeletedField->m_oName = m_oBufferedStream.GetString4(length); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryTableReader::ReadQueryTableDeletedFields(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CQueryTableDeletedFields* pQueryTableDeletedFields = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_QueryTableDeletedField::QueryTableDeletedField == type) + { + OOX::Spreadsheet::CQueryTableDeletedField* pQueryTableDeletedField = new OOX::Spreadsheet::CQueryTableDeletedField(); + READ1_DEF(length, res, this->ReadQueryTableDeletedField, pQueryTableDeletedField); + + pQueryTableDeletedFields->m_arrItems.push_back(pQueryTableDeletedField); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryTableReader::ReadQueryTableField(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CQueryTableField* pQueryTableField = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_QueryTableField::Name == type) + { + pQueryTableField->m_oName = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_QueryTableField::Id == type) + { + pQueryTableField->m_oId.Init(); + pQueryTableField->m_oId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_QueryTableField::TableColumnId == type) + { + pQueryTableField->m_oTableColumnId.Init(); + pQueryTableField->m_oTableColumnId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_QueryTableField::RowNumbers == type) + { + pQueryTableField->m_oRowNumbers = m_oBufferedStream.GetBool(); + } + else if (c_oSer_QueryTableField::FillFormulas == type) + { + pQueryTableField->m_oFillFormulas = m_oBufferedStream.GetBool(); + } + else if (c_oSer_QueryTableField::DataBound == type) + { + pQueryTableField->m_oDataBound = m_oBufferedStream.GetBool(); + } + else if (c_oSer_QueryTableField::Clipped == type) + { + pQueryTableField->m_oClipped = m_oBufferedStream.GetBool(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryTableReader::ReadTableCache(long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + READ1_DEF(length, res, this->ReadCacheParts, poResult); + return res; +} +int BinaryTableReader::ReadTablePart(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CTableParts* pTableParts = static_cast(poResult); + if (c_oSer_TablePart::Table == type) + { + OOX::Spreadsheet::CTableFile* pTable = new OOX::Spreadsheet::CTableFile(NULL); + if(m_pCurWorksheet->OOX::File::m_pMainDocument) + { + pTable->OOX::File::m_pMainDocument = m_pCurWorksheet->OOX::File::m_pMainDocument; + } + pTable->m_oTable.Init(); + READ1_DEF(length, res, this->ReadTable, pTable); + + OOX::Spreadsheet::CTablePart* pTablePart = new OOX::Spreadsheet::CTablePart(); + NSCommon::smart_ptr pTableFile(pTable); + const OOX::RId oRId = m_pCurWorksheet->Add(pTableFile); + + pTablePart->m_oRId.Init(); + pTablePart->m_oRId->SetValue(oRId.get()); + pTableParts->m_arrItems.push_back(pTablePart); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +}; +int BinaryTableReader::ReadCacheParts(BYTE type,long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + if (c_oSer_TablePart::Table == type) + { + OOX::Spreadsheet::CTable Table; + READ1_DEF(length, res, this->ReadCachePart, &Table); + if(Table.m_oId.IsInit() && Table.m_oTableColumns.IsInit() && !Table.m_oTableColumns->m_arrItems.empty()) + { + XLS::GlobalWorkbookInfo::mapTableColumnNames_static.emplace(Table.m_oId->GetValue(), + std::vector(Table.m_oTableColumns->m_arrItems.size())); + auto colInd = 0; + for(auto i:Table.m_oTableColumns->m_arrItems) + { + if(i->m_oName.IsInit()) + { + i->m_oName = boost::algorithm::replace_all_copy(i->m_oName.get(), L"_x000a_", L"\n"); + std::unordered_map>::iterator pFind = XLS::GlobalWorkbookInfo::mapTableColumnNames_static.find(Table.m_oId->GetValue()); + if (pFind != XLS::GlobalWorkbookInfo::mapTableColumnNames_static.end()) + { + if (colInd < pFind->second.size()) + { + pFind->second[colInd] = i->m_oName.get(); + } + } + } + colInd++; + } + } + if(Table.m_oId.IsInit() && Table.m_oName.IsInit()) + { + XLS::GlobalWorkbookInfo::mapTableNames_static.emplace(Table.m_oId->GetValue(), Table.m_oName.get()); + auto curXti = XLS::GlobalWorkbookInfo::arXti_External_static.size()-1; + if(!XLS::GlobalWorkbookInfo::mapXtiTables_static.count(curXti)) + { + XLS::GlobalWorkbookInfo::mapXtiTables_static.emplace(curXti, std::vector()); + } + XLS::GlobalWorkbookInfo::mapXtiTables_static.at(curXti).push_back(Table.m_oId->GetValue()); + } + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryTableReader::ReadCachePart(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + auto tablePtr = static_cast(poResult); + if (c_oSer_TablePart::Id == type) + { + tablePtr->m_oId.Init(); + tablePtr->m_oId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_TablePart::Name == type) + { + tablePtr->m_oName = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_TablePart::TableColumns == type) + { + tablePtr->m_oTableColumns.Init(); + READ1_DEF(length, res, this->ReadTableColumns, tablePtr->m_oTableColumns.GetPointer()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryTableReader::ReadTable(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + + OOX::Spreadsheet::CTableFile* pTableFile = static_cast(poResult); + if (!pTableFile) return c_oSerConstants::ReadUnknown; + + OOX::Spreadsheet::CTable* pTable = pTableFile->m_oTable.GetPointer(); + if (!pTable) return c_oSerConstants::ReadUnknown; + + if (c_oSer_TablePart::Ref == type) + { + pTable->m_oRef.Init(); + pTable->m_oRef->SetValue(m_oBufferedStream.GetString3(length)); + } + else if (c_oSer_TablePart::HeaderRowCount == type) + { + pTable->m_oHeaderRowCount.Init(); + pTable->m_oHeaderRowCount->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_TablePart::TotalsRowCount == type) + { + pTable->m_oTotalsRowCount.Init(); + pTable->m_oTotalsRowCount->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_TablePart::DisplayName == type) + { + pTable->m_oDisplayName = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_TablePart::Name == type) + { + pTable->m_oName = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_TablePart::Comment == type) + { + pTable->m_oComment = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_TablePart::ConnectionId == type) + { + pTable->m_oConnectionId.Init(); + pTable->m_oConnectionId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_TablePart::TableType == type) + { + pTable->m_oTableType.Init(); + pTable->m_oTableType->SetValue((SimpleTypes::Spreadsheet::ETableType)m_oBufferedStream.GetLong()); + } + else if (c_oSer_TablePart::DataCellStyle == type) + { + pTable->m_oDataCellStyle = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_TablePart::DataDxfId == type) + { + pTable->m_oDataDxfId.Init(); + pTable->m_oDataDxfId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_TablePart::HeaderRowCellStyle == type) + { + pTable->m_oHeaderRowCellStyle = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_TablePart::HeaderRowDxfId == type) + { + pTable->m_oHeaderRowDxfId.Init(); + pTable->m_oHeaderRowDxfId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_TablePart::HeaderRowBorderDxfId == type) + { + pTable->m_oHeaderRowBorderDxfId.Init(); + pTable->m_oHeaderRowBorderDxfId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_TablePart::Id == type) + { + pTable->m_oId.Init(); + pTable->m_oId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_TablePart::InsertRow == type) + { + pTable->m_oInsertRow = m_oBufferedStream.GetBool(); + } + else if (c_oSer_TablePart::InsertRowShift == type) + { + pTable->m_oInsertRowShift = m_oBufferedStream.GetBool(); + } + else if (c_oSer_TablePart::Published == type) + { + pTable->m_oPublished = m_oBufferedStream.GetBool(); + } + else if (c_oSer_TablePart::TableBorderDxfId == type) + { + pTable->m_oTableBorderDxfId.Init(); + pTable->m_oTableBorderDxfId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_TablePart::TotalsRowBorderDxfId == type) + { + pTable->m_oTotalsRowBorderDxfId.Init(); + pTable->m_oTotalsRowBorderDxfId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_TablePart::TotalsRowCellStyle == type) + { + pTable->m_oTotalsRowCellStyle = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_TablePart::TotalsRowDxfId == type) + { + pTable->m_oTotalsRowDxfId.Init(); + pTable->m_oTotalsRowDxfId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_TablePart::TotalsRowShown == type) + { + pTable->m_oTotalsRowShown = m_oBufferedStream.GetBool(); + } + else if (c_oSer_TablePart::AutoFilter == type) + { + pTable->m_oAutoFilter.Init(); + READ1_DEF(length, res, this->ReadAutoFilter, pTable->m_oAutoFilter.GetPointer()); + } + else if (c_oSer_TablePart::SortState == type) + { + pTable->m_oSortState.Init(); + READ1_DEF(length, res, this->ReadSortState, pTable->m_oSortState.GetPointer()); + } + else if (c_oSer_TablePart::TableColumns == type) + { + pTable->m_oTableColumns.Init(); + READ1_DEF(length, res, this->ReadTableColumns, pTable->m_oTableColumns.GetPointer()); + } + else if (c_oSer_TablePart::TableStyleInfo == type) + { + pTable->m_oTableStyleInfo.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadTableStyleInfo, pTable->m_oTableStyleInfo.GetPointer()); + } + else if (c_oSer_TablePart::AltTextTable == type) + { + OOX::Drawing::COfficeArtExtension* pOfficeArtExtension = new OOX::Drawing::COfficeArtExtension(); + pOfficeArtExtension->m_oAltTextTable.Init(); + + READ1_DEF(length, res, this->ReadAltTextTable, pOfficeArtExtension->m_oAltTextTable.GetPointer()); + + pOfficeArtExtension->m_sUri = L"{504A1905-F514-4f6f-8877-14C23A59335A}"; + pOfficeArtExtension->m_sAdditionalNamespace = L"xmlns:x14=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/main\""; + pTable->m_oExtLst.Init(); + pTable->m_oExtLst->m_arrExt.push_back(pOfficeArtExtension); + } + else if (c_oSer_TablePart::QueryTable == type) + { + smart_ptr pQueryTableFile(new OOX::Spreadsheet::CQueryTableFile(NULL)); + pQueryTableFile->m_oQueryTable.Init(); + READ1_DEF(length, res, this->ReadQueryTableContent, pQueryTableFile->m_oQueryTable.GetPointer()); + + smart_ptr oFile = pQueryTableFile.smart_dynamic_cast(); + pTableFile->Add(oFile); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryTableReader::ReadAltTextTable(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CAltTextTable* pAltTextTable = static_cast(poResult); + if (c_oSer_AltTextTable::AltText == type) + { + pAltTextTable->m_oAltText.Init(); + pAltTextTable->m_oAltText->append(m_oBufferedStream.GetString3(length)); + } + else if (c_oSer_AltTextTable::AltTextSummary == type) + { + pAltTextTable->m_oAltTextSummary.Init(); + pAltTextTable->m_oAltTextSummary->append(m_oBufferedStream.GetString3(length)); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryTableReader::ReadAutoFilter(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CAutofilter* pAutofilter = static_cast(poResult); + if (c_oSer_AutoFilter::Ref == type) + { + pAutofilter->m_oRef.Init(); + pAutofilter->m_oRef->SetValue(m_oBufferedStream.GetString3(length)); + } + else if (c_oSer_AutoFilter::FilterColumns == type) + { + READ1_DEF(length, res, this->ReadFilterColumns, poResult); + } + else if (c_oSer_AutoFilter::SortState == type) + { + pAutofilter->m_oSortState.Init(); + READ1_DEF(length, res, this->ReadSortState, pAutofilter->m_oSortState.GetPointer()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryTableReader::ReadFilterColumns(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CAutofilter* pAutofilter = static_cast(poResult); + if (c_oSer_AutoFilter::FilterColumn == type) + { + OOX::Spreadsheet::CFilterColumn* pFilterColumn = new OOX::Spreadsheet::CFilterColumn(); + READ1_DEF(length, res, this->ReadFilterColumn, pFilterColumn); + pAutofilter->m_arrItems.push_back(pFilterColumn); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryTableReader::ReadFilterColumnExternal(OOX::Spreadsheet::CFilterColumn* pFilterColumn) +{ + int res = c_oSerConstants::ReadOk; + ULONG length = m_oBufferedStream.GetULong(); + READ1_DEF(length, res, this->ReadFilterColumn, pFilterColumn); + return res; +} +int BinaryTableReader::ReadFilterColumn(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CFilterColumn* pFilterColumn = static_cast(poResult); + if (c_oSer_FilterColumn::ColId == type) + { + pFilterColumn->m_oColId.Init(); + pFilterColumn->m_oColId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_FilterColumn::Filters == type) + { + pFilterColumn->m_oFilters.Init(); + READ1_DEF(length, res, this->ReadFilterFilters, pFilterColumn->m_oFilters.GetPointer()); + } + else if (c_oSer_FilterColumn::CustomFilters == type) + { + pFilterColumn->m_oCustomFilters.Init(); + READ1_DEF(length, res, this->ReadCustomFilters, pFilterColumn->m_oCustomFilters.GetPointer()); + } + else if (c_oSer_FilterColumn::DynamicFilter == type) + { + pFilterColumn->m_oDynamicFilter.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadDynamicFilter, pFilterColumn->m_oDynamicFilter.GetPointer()); + } + else if (c_oSer_FilterColumn::ColorFilter == type) + { + pFilterColumn->m_oColorFilter.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadColorFilter, pFilterColumn->m_oColorFilter.GetPointer()); + } + else if (c_oSer_FilterColumn::Top10 == type) + { + pFilterColumn->m_oTop10.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadTop10, pFilterColumn->m_oTop10.GetPointer()); + } + else if (c_oSer_FilterColumn::HiddenButton == type) + { + pFilterColumn->m_oHiddenButton.Init(); + pFilterColumn->m_oHiddenButton->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_FilterColumn::ShowButton == type) + { + pFilterColumn->m_oShowButton.Init(); + pFilterColumn->m_oShowButton->FromBool(m_oBufferedStream.GetBool()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryTableReader::ReadFilterFilters(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CFilters* pFilters = static_cast(poResult); + if (c_oSer_FilterColumn::Filter == type) + { + OOX::Spreadsheet::CFilter* pFilter = new OOX::Spreadsheet::CFilter(); + READ1_DEF(length, res, this->ReadFilterFilter, pFilter); + pFilters->m_arrItems.push_back(pFilter); + } + else if (c_oSer_FilterColumn::DateGroupItem == type) + { + OOX::Spreadsheet::CDateGroupItem* pDateGroupItem = new OOX::Spreadsheet::CDateGroupItem(); + READ2_DEF_SPREADSHEET(length, res, this->ReadDateGroupItem, pDateGroupItem); + pFilters->m_arrItems.push_back(pDateGroupItem); + } + else if (c_oSer_FilterColumn::FiltersBlank == type) + { + pFilters->m_oBlank.Init(); + pFilters->m_oBlank->FromBool(m_oBufferedStream.GetBool()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryTableReader::ReadFilterFilter(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CFilter* pFilters = static_cast(poResult); + if (c_oSer_Filter::Val == type) + { + pFilters->m_oVal.Init(); + pFilters->m_oVal->append(m_oBufferedStream.GetString4(length)); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryTableReader::ReadDateGroupItem(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CDateGroupItem* pDateGroupItem = static_cast(poResult); + if (c_oSer_DateGroupItem::DateTimeGrouping == type) + { + pDateGroupItem->m_oDateTimeGrouping.Init(); + pDateGroupItem->m_oDateTimeGrouping->SetValue((SimpleTypes::Spreadsheet::EDateTimeGroup)m_oBufferedStream.GetUChar()); + } + else if (c_oSer_DateGroupItem::Day == type) + { + pDateGroupItem->m_oDay.Init(); + pDateGroupItem->m_oDay->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_DateGroupItem::Hour == type) + { + pDateGroupItem->m_oHour.Init(); + pDateGroupItem->m_oHour->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_DateGroupItem::Minute == type) + { + pDateGroupItem->m_oMinute.Init(); + pDateGroupItem->m_oMinute->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_DateGroupItem::Month == type) + { + pDateGroupItem->m_oMonth.Init(); + pDateGroupItem->m_oMonth->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_DateGroupItem::Second == type) + { + pDateGroupItem->m_oSecond.Init(); + pDateGroupItem->m_oSecond->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_DateGroupItem::Year == type) + { + pDateGroupItem->m_oYear.Init(); + pDateGroupItem->m_oYear->SetValue(m_oBufferedStream.GetLong()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryTableReader::ReadCustomFilters(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CCustomFilters* pCustomFilters = static_cast(poResult); + if (c_oSer_CustomFilters::And == type) + { + pCustomFilters->m_oAnd.Init(); + pCustomFilters->m_oAnd->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_CustomFilters::CustomFilters == type) + { + READ1_DEF(length, res, this->ReadCustomFilter, poResult); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryTableReader::ReadCustomFilter(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CCustomFilters* pCustomFilters = static_cast(poResult); + if (c_oSer_CustomFilters::CustomFilter == type) + { + OOX::Spreadsheet::CCustomFilter* pCustomFilter = new OOX::Spreadsheet::CCustomFilter(); + READ2_DEF_SPREADSHEET(length, res, this->ReadCustomFiltersItem, pCustomFilter); + pCustomFilters->m_arrItems.push_back(pCustomFilter); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryTableReader::ReadCustomFiltersItem(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CCustomFilter* pCustomFilter = static_cast(poResult); + if (c_oSer_CustomFilters::Operator == type) + { + pCustomFilter->m_oOperator.Init(); + pCustomFilter->m_oOperator->SetValue((SimpleTypes::Spreadsheet::ECustomFilter)m_oBufferedStream.GetUChar()); + } + else if (c_oSer_CustomFilters::Val == type) + { + pCustomFilter->m_oVal.Init(); + pCustomFilter->m_oVal->append(m_oBufferedStream.GetString4(length)); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryTableReader::ReadDynamicFilter(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CDynamicFilter* pDynamicFilter = static_cast(poResult); + if (c_oSer_DynamicFilter::Type == type) + { + pDynamicFilter->m_oType.Init(); + pDynamicFilter->m_oType->SetValue((SimpleTypes::Spreadsheet::EDynamicFilterType)m_oBufferedStream.GetUChar()); + } + else if (c_oSer_DynamicFilter::Val == type) + { + pDynamicFilter->m_oVal.Init(); + pDynamicFilter->m_oVal->SetValue(m_oBufferedStream.GetDoubleReal()); + } + else if (c_oSer_DynamicFilter::MaxVal == type) + { + pDynamicFilter->m_oMaxVal.Init(); + pDynamicFilter->m_oMaxVal->SetValue(m_oBufferedStream.GetDoubleReal()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryTableReader::ReadColorFilter(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CColorFilter* pColorFilter = static_cast(poResult); + if (c_oSer_ColorFilter::CellColor == type) + { + pColorFilter->m_oCellColor.Init(); + pColorFilter->m_oCellColor->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_ColorFilter::DxfId == type) + { + pColorFilter->m_oDxfId.Init(); + pColorFilter->m_oDxfId->SetValue(m_oBufferedStream.GetLong()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryTableReader::ReadTop10(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CTop10* pTop10 = static_cast(poResult); + if (c_oSer_Top10::FilterVal == type) + { + pTop10->m_oFilterVal.Init(); + pTop10->m_oFilterVal->SetValue(m_oBufferedStream.GetDoubleReal()); + } + else if (c_oSer_Top10::Percent == type) + { + pTop10->m_oPercent.Init(); + pTop10->m_oPercent->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_Top10::Top == type) + { + pTop10->m_oTop.Init(); + pTop10->m_oTop->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_Top10::Val == type) + { + pTop10->m_oVal.Init(); + pTop10->m_oVal->SetValue(m_oBufferedStream.GetDoubleReal()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryTableReader::ReadSortState(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CSortState* pSortState = static_cast(poResult); + if (c_oSer_SortState::Ref == type) + { + pSortState->m_oRef.Init(); + pSortState->m_oRef->SetValue(m_oBufferedStream.GetString3(length)); + } + else if (c_oSer_SortState::CaseSensitive == type) + { + pSortState->m_oCaseSensitive.Init(); + pSortState->m_oCaseSensitive->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_SortState::ColumnSort == type) + { + pSortState->m_oColumnSort.Init(); + pSortState->m_oColumnSort->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_SortState::SortMethod == type) + { + pSortState->m_oSortMethod.Init(); + pSortState->m_oSortMethod->SetValue((SimpleTypes::Spreadsheet::ESortMethod)m_oBufferedStream.GetUChar()); + } + else if (c_oSer_SortState::SortConditions == type) + { + READ1_DEF(length, res, this->ReadSortConditions, pSortState); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryTableReader::ReadSortConditions(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CSortState* pSortState = static_cast(poResult); + if (c_oSer_SortState::SortCondition == type) + { + OOX::Spreadsheet::CSortCondition* pSortCondition = new OOX::Spreadsheet::CSortCondition(); + READ2_DEF_SPREADSHEET(length, res, this->ReadSortCondition, pSortCondition); + pSortState->m_arrItems.push_back(pSortCondition); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryTableReader::ReadSortConditionExternal(OOX::Spreadsheet::CSortCondition* pSortCondition) +{ + int res = c_oSerConstants::ReadOk; + ULONG length = m_oBufferedStream.GetULong(); + READ2_DEF_SPREADSHEET(length, res, this->ReadSortCondition, pSortCondition); + return res; +} +int BinaryTableReader::ReadSortCondition(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CSortCondition* pSortCondition = static_cast(poResult); + if (c_oSer_SortState::ConditionRef == type) + { + pSortCondition->m_oRef.Init(); + pSortCondition->m_oRef->SetValue(m_oBufferedStream.GetString3(length)); + } + else if (c_oSer_SortState::ConditionSortBy == type) + { + pSortCondition->m_oSortBy.Init(); + pSortCondition->m_oSortBy->SetValue((SimpleTypes::Spreadsheet::ESortBy)m_oBufferedStream.GetUChar()); + } + else if (c_oSer_SortState::ConditionDescending == type) + { + pSortCondition->m_oDescending.Init(); + pSortCondition->m_oDescending->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_SortState::ConditionDxfId == type) + { + pSortCondition->m_oDxfId.Init(); + pSortCondition->m_oDxfId->SetValue(m_oBufferedStream.GetLong()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryTableReader::ReadTableColumns(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CTableColumns* pTableColumns = static_cast(poResult); + if (c_oSer_TableColumns::TableColumn == type) + { + OOX::Spreadsheet::CTableColumn* pTableColumn = new OOX::Spreadsheet::CTableColumn(); + READ1_DEF(length, res, this->ReadTableColumn, pTableColumn); + + if (!pTableColumn->m_oId.IsInit()) + { + pTableColumn->m_oId.Init(); + pTableColumn->m_oId->SetValue((unsigned int)pTableColumns->m_arrItems.size() + 1); + } + pTableColumns->m_arrItems.push_back(pTableColumn); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryTableReader::ReadTableColumn(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CTableColumn* pTableColumn = static_cast(poResult); + + if (c_oSer_TableColumns::Name == type) + { + pTableColumn->m_oName = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_TableColumns::TotalsRowLabel == type) + { + pTableColumn->m_oTotalsRowLabel = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_TableColumns::TotalsRowFunction == type) + { + pTableColumn->m_oTotalsRowFunction.Init(); + pTableColumn->m_oTotalsRowFunction->SetValue((SimpleTypes::Spreadsheet::ETotalsRowFunction)m_oBufferedStream.GetUChar()); + } + else if (c_oSer_TableColumns::TotalsRowFormula == type) + { + pTableColumn->m_oTotalsRowFormula = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_TableColumns::DataDxfId == type) + { + pTableColumn->m_oDataDxfId.Init(); + pTableColumn->m_oDataDxfId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_TableColumns::CalculatedColumnFormula == type) + { + pTableColumn->m_oCalculatedColumnFormula = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_TableColumns::DataCellStyle == type) + { + pTableColumn->m_oDataCellStyle = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_TableColumns::HeaderRowCellStyle == type) + { + pTableColumn->m_oHeaderRowCellStyle = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_TableColumns::HeaderRowDxfId == type) + { + pTableColumn->m_oHeaderRowDxfId.Init(); + pTableColumn->m_oHeaderRowDxfId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_TableColumns::Id == type) + { + pTableColumn->m_oId.Init(); + pTableColumn->m_oId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_TableColumns::QueryTableFieldId == type) + { + pTableColumn->m_oQueryTableFieldId.Init(); + pTableColumn->m_oQueryTableFieldId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_TableColumns::TotalsRowCellStyle == type) + { + pTableColumn->m_oTotalsRowCellStyle = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_TableColumns::TotalsRowDxfId == type) + { + pTableColumn->m_oTotalsRowDxfId.Init(); + pTableColumn->m_oTotalsRowDxfId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_TableColumns::UniqueName == type) + { + pTableColumn->m_oUniqueName = m_oBufferedStream.GetString4(length); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryTableReader::ReadTableStyleInfo(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CTableStyleInfo* pTableStyleInfo = static_cast(poResult); + if (c_oSer_TableStyleInfo::Name == type) + { + pTableStyleInfo->m_oName.Init(); + pTableStyleInfo->m_oName->append(m_oBufferedStream.GetString4(length)); + } + else if (c_oSer_TableStyleInfo::ShowColumnStripes == type) + { + pTableStyleInfo->m_oShowColumnStripes.Init(); + pTableStyleInfo->m_oShowColumnStripes->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_TableStyleInfo::ShowRowStripes == type) + { + pTableStyleInfo->m_oShowRowStripes.Init(); + pTableStyleInfo->m_oShowRowStripes->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_TableStyleInfo::ShowFirstColumn == type) + { + pTableStyleInfo->m_oShowFirstColumn.Init(); + pTableStyleInfo->m_oShowFirstColumn->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_TableStyleInfo::ShowLastColumn == type) + { + pTableStyleInfo->m_oShowLastColumn.Init(); + pTableStyleInfo->m_oShowLastColumn->FromBool(m_oBufferedStream.GetBool()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} + +BinarySharedStringTableReader::BinarySharedStringTableReader(NSBinPptxRW::CBinaryFileReader& oBufferedStream, OOX::Spreadsheet::CSharedStrings& oSharedStrings):Binary_CommonReader(oBufferedStream), m_oSharedStrings(oSharedStrings), m_oBcr(oBufferedStream) +{ +} +int BinarySharedStringTableReader::Read() +{ + int res = c_oSerConstants::ReadOk; + READ_TABLE_DEF(res, this->ReadSharedStringTableContent, this); + + m_oSharedStrings.m_oCount.Init(); + m_oSharedStrings.m_oCount->SetValue((unsigned int)m_oSharedStrings.m_nCount); + + m_oSharedStrings.m_oUniqueCount.Init(); + m_oSharedStrings.m_oUniqueCount->SetValue((unsigned int)m_oSharedStrings.m_nCount); + return res; +}; +int BinarySharedStringTableReader::ReadSharedStringTableContent(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + if (c_oSerSharedStringTypes::Si == type) + { + OOX::Spreadsheet::CSi* pSi = new OOX::Spreadsheet::CSi(); + READ1_DEF(length, res, this->ReadSi, pSi); + m_oSharedStrings.AddSi(pSi); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +}; +int BinarySharedStringTableReader::ReadSi(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CSi* pSi = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerSharedStringTypes::Run == type) + { + OOX::Spreadsheet::CRun* pRun = new OOX::Spreadsheet::CRun(); + READ1_DEF(length, res, this->ReadRun, pRun); + pSi->m_arrItems.push_back(pRun); + } + else if (c_oSerSharedStringTypes::Text == type) + { + std::wstring sText(m_oBufferedStream.GetString4(length)); + OOX::Spreadsheet::CText* pText = new OOX::Spreadsheet::CText(); + pText->m_sText = sText; + if (std::wstring::npos != sText.find(_T(" "))) + { + pText->m_oSpace.Init(); + pText->m_oSpace->SetValue(SimpleTypes::xmlspacePreserve); + } + pSi->m_arrItems.push_back(pText); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +}; +int BinarySharedStringTableReader::ReadRun(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CRun* pRun = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerSharedStringTypes::RPr == type) + { + pRun->m_oRPr.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadRPr, pRun->m_oRPr.GetPointer()); + } + else if (c_oSerSharedStringTypes::Text == type) + { + std::wstring sText(m_oBufferedStream.GetString4(length)); + OOX::Spreadsheet::CText* pText = new OOX::Spreadsheet::CText(); + pText->m_sText = sText; + + bool bHHHH = std::wstring::npos != sText.find('\xA') || std::wstring::npos != sText.find('\x9'); + if (std::wstring::npos != sText.find(L" ") || bHHHH) + { + pText->m_oSpace.Init(); + pText->m_oSpace->SetValue(SimpleTypes::xmlspacePreserve); + } + pRun->m_arrItems.push_back(pText); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +}; +int BinarySharedStringTableReader::ReadRPr(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CRPr* pFont = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerFontTypes::Bold == type) + { + pFont->m_oBold.Init(); + pFont->m_oBold->m_oVal.SetValue((false != m_oBufferedStream.GetBool()) ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerFontTypes::Color == type) + { + pFont->m_oColor.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadColor, pFont->m_oColor.GetPointer()); + } + else if (c_oSerFontTypes::Italic == type) + { + pFont->m_oItalic.Init(); + pFont->m_oItalic->m_oVal.SetValue((false != m_oBufferedStream.GetBool()) ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerFontTypes::RFont == type) + { + pFont->m_oRFont.Init(); + pFont->m_oRFont->m_sVal = m_oBufferedStream.GetString4(length); + } + else if (c_oSerFontTypes::Scheme == type) + { + pFont->m_oScheme.Init(); + pFont->m_oScheme->m_oFontScheme.Init(); + pFont->m_oScheme->m_oFontScheme->SetValue((SimpleTypes::Spreadsheet::EFontScheme)m_oBufferedStream.GetUChar()); + } + else if (c_oSerFontTypes::Strike == type) + { + pFont->m_oStrike.Init(); + pFont->m_oStrike->m_oVal.SetValue((false != m_oBufferedStream.GetBool()) ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerFontTypes::Sz == type) + { + pFont->m_oSz.Init(); + pFont->m_oSz->m_oVal.Init(); + pFont->m_oSz->m_oVal->SetValue(m_oBufferedStream.GetDoubleReal()); + } + else if (c_oSerFontTypes::Underline == type) + { + pFont->m_oUnderline.Init(); + pFont->m_oUnderline->m_oUnderline.Init(); + pFont->m_oUnderline->m_oUnderline->SetValue((SimpleTypes::Spreadsheet::EUnderline)m_oBufferedStream.GetUChar()); + } + else if (c_oSerFontTypes::VertAlign == type) + { + pFont->m_oVertAlign.Init(); + pFont->m_oVertAlign->m_oVerticalAlign.Init(); + pFont->m_oVertAlign->m_oVerticalAlign->SetValue((SimpleTypes::EVerticalAlignRun)m_oBufferedStream.GetUChar()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +}; +int BinarySharedStringTableReader::ReadColor(BYTE type, long length, void* poResult) +{ + return m_oBcr.ReadColor(type, length, poResult); +} + +BinaryStyleTableReader::BinaryStyleTableReader(NSBinPptxRW::CBinaryFileReader& oBufferedStream, OOX::Spreadsheet::CStyles& oStyles):Binary_CommonReader(oBufferedStream), m_oStyles(oStyles), m_oBcr(oBufferedStream) +{ +} +int BinaryStyleTableReader::Read() +{ + int res = c_oSerConstants::ReadOk; + READ_TABLE_DEF(res, this->ReadStyleTableContent, this); + return res; +}; +int BinaryStyleTableReader::ReadStyleTableContent(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + if (c_oSerStylesTypes::Borders == type) + { + m_oStyles.m_oBorders.Init(); + READ1_DEF(length, res, this->ReadBorders, poResult); + + m_oStyles.m_oBorders->m_oCount.Init(); + m_oStyles.m_oBorders->m_oCount->SetValue((unsigned int)m_oStyles.m_oBorders->m_arrItems.size()); + } + else if (c_oSerStylesTypes::Fills == type) + { + m_oStyles.m_oFills.Init(); + READ1_DEF(length, res, this->ReadFills, poResult); + + m_oStyles.m_oFills->m_oCount.Init(); + m_oStyles.m_oFills->m_oCount->SetValue((unsigned int)m_oStyles.m_oFills->m_arrItems.size()); + } + else if (c_oSerStylesTypes::Fonts == type) + { + m_oStyles.m_oFonts.Init(); + READ1_DEF(length, res, this->ReadFonts, poResult); + + m_oStyles.m_oFonts->m_oCount.Init(); + m_oStyles.m_oFonts->m_oCount->SetValue((unsigned int)m_oStyles.m_oFonts->m_arrItems.size()); + } + else if (c_oSerStylesTypes::NumFmts == type) + { + m_oStyles.m_oNumFmts.Init(); + READ1_DEF(length, res, this->ReadNumFmts, poResult); + + m_oStyles.m_oNumFmts->m_oCount.Init(); + m_oStyles.m_oNumFmts->m_oCount->SetValue((unsigned int)m_oStyles.m_oNumFmts->m_arrItems.size()); + } + else if (c_oSerStylesTypes::CellStyleXfs == type) + { + m_oStyles.m_oCellStyleXfs.Init(); + READ1_DEF(length, res, this->ReadCellStyleXfs, poResult); + + m_oStyles.m_oCellStyleXfs->m_oCount.Init(); + m_oStyles.m_oCellStyleXfs->m_oCount->SetValue((unsigned int)m_oStyles.m_oCellStyleXfs->m_arrItems.size()); + } + else if (c_oSerStylesTypes::CellXfs == type) + { + m_oStyles.m_oCellXfs.Init(); + READ1_DEF(length, res, this->ReadCellXfs, poResult); + + m_oStyles.m_oCellXfs->m_oCount.Init(); + m_oStyles.m_oCellXfs->m_oCount->SetValue((unsigned int)m_oStyles.m_oCellXfs->m_arrItems.size()); + } + else if (c_oSerStylesTypes::CellStyles == type) + { + m_oStyles.m_oCellStyles.Init(); + READ1_DEF(length, res, this->ReadCellStyles, poResult); + + m_oStyles.m_oCellStyles->m_oCount.Init(); + m_oStyles.m_oCellStyles->m_oCount->SetValue((unsigned int)m_oStyles.m_oCellStyles->m_arrItems.size()); + } + else if (c_oSerStylesTypes::Dxfs == type) + { + m_oStyles.m_oDxfs.Init(); + READ1_DEF(length, res, this->ReadDxfs, m_oStyles.m_oDxfs.GetPointer()); + + m_oStyles.m_oDxfs->m_oCount.Init(); + m_oStyles.m_oDxfs->m_oCount->SetValue((unsigned int)m_oStyles.m_oDxfs->m_arrItems.size()); + } + else if (c_oSerStylesTypes::TableStyles == type) + { + m_oStyles.m_oTableStyles.Init(); + READ1_DEF(length, res, this->ReadTableStyles, m_oStyles.m_oTableStyles.GetPointer()); + if (false == m_oStyles.m_oTableStyles->m_oCount.IsInit()) + { + m_oStyles.m_oTableStyles->m_oCount.Init(); + m_oStyles.m_oTableStyles->m_oCount->SetValue(0); + } + } + else if (c_oSerStylesTypes::ExtDxfs == type) + { + OOX::Drawing::COfficeArtExtension* pOfficeArtExtension = new OOX::Drawing::COfficeArtExtension(); + + pOfficeArtExtension->m_oDxfs.Init(); + READ1_DEF(length, res, this->ReadDxfs, pOfficeArtExtension->m_oDxfs.GetPointer()); + + pOfficeArtExtension->m_oDxfs->m_oCount.Init(); + pOfficeArtExtension->m_oDxfs->m_oCount->SetValue((unsigned int)pOfficeArtExtension->m_oDxfs->m_arrItems.size()); + + pOfficeArtExtension->m_sUri = L"{46F421CA-312F-682f-3DD2-61675219B42D}"; + pOfficeArtExtension->m_sAdditionalNamespace = L"xmlns:x14=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/main\""; + + if (m_oStyles.m_oExtLst.IsInit() == false) + m_oStyles.m_oExtLst.Init(); + m_oStyles.m_oExtLst->m_arrExt.push_back(pOfficeArtExtension); + } + else if (c_oSerStylesTypes::SlicerStyles == type) + { + OOX::Drawing::COfficeArtExtension* pOfficeArtExtension = new OOX::Drawing::COfficeArtExtension(); + pOfficeArtExtension->m_oSlicerStyles.Init(); + + m_oBufferedStream.GetUChar();//type + pOfficeArtExtension->m_oSlicerStyles->fromPPTY(&m_oBufferedStream); + + pOfficeArtExtension->m_sUri = L"{EB79DEF2-80B8-43e5-95BD-54CBDDF9020C}"; + pOfficeArtExtension->m_sAdditionalNamespace = L"xmlns:x14=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/main\""; + + if (m_oStyles.m_oExtLst.IsInit() == false) + m_oStyles.m_oExtLst.Init(); + m_oStyles.m_oExtLst->m_arrExt.push_back(pOfficeArtExtension); + } + else if (c_oSerStylesTypes::TimelineStyles == type) + { + OOX::Drawing::COfficeArtExtension* pOfficeArtExtension = new OOX::Drawing::COfficeArtExtension(); + pOfficeArtExtension->m_oTimelineStyles.Init(); + pOfficeArtExtension->m_sUri = L"{9260A510-F301-46a8-8635-F512D64BE5F5}"; + pOfficeArtExtension->m_sAdditionalNamespace = L"xmlns:x15=\"http://schemas.microsoft.com/office/spreadsheetml/2010/11/main\""; + + READ1_DEF(length, res, this->ReadTimelineStyles, pOfficeArtExtension->m_oTimelineStyles.GetPointer()); + + if (m_oStyles.m_oExtLst.IsInit() == false) + m_oStyles.m_oExtLst.Init(); + m_oStyles.m_oExtLst->m_arrExt.push_back(pOfficeArtExtension); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryStyleTableReader::ReadTimelineStyles(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CTimelineStyles* pTimelineStyles = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_TimelineStyles::DefaultTimelineStyle == type) + { + pTimelineStyles->m_oDefaultTimelineStyle = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_TimelineStyles::TimelineStyle == type) + { + pTimelineStyles->m_arrItems.push_back(new OOX::Spreadsheet::CTimelineStyle()); + READ1_DEF(length, res, this->ReadTimelineStyle, pTimelineStyles->m_arrItems.back()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryStyleTableReader::ReadTimelineStyle(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CTimelineStyle* pTimelineStyle = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_TimelineStyles::TimelineStyleName == type) + { + pTimelineStyle->m_oName = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_TimelineStyles::TimelineStyle == type) + { + pTimelineStyle->m_arrItems.push_back(new OOX::Spreadsheet::CTimelineStyleElement()); + READ2_DEF_SPREADSHEET(length, res, this->ReadTimelineStyleElement, pTimelineStyle->m_arrItems.back()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryStyleTableReader::ReadTimelineStyleElement(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CTimelineStyleElement* pTimelineStyleElement = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_TimelineStyles::TimelineStyleElementType == type) + { + pTimelineStyleElement->m_oType.Init(); + pTimelineStyleElement->m_oType->SetValueFromByte(m_oBufferedStream.GetUChar()); + } + else if (c_oSer_TimelineStyles::TimelineStyleElementDxfId == type) + { + pTimelineStyleElement->m_oDxfId = m_oBufferedStream.GetLong(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} + +int BinaryStyleTableReader::ReadBorders(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + if (c_oSerStylesTypes::Border == type) + { + OOX::Spreadsheet::CBorder* pBorder = new OOX::Spreadsheet::CBorder(); + READ1_DEF(length, res, this->ReadBorder, pBorder); + m_oStyles.m_oBorders->m_arrItems.push_back(pBorder); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +}; +int BinaryStyleTableReader::ReadBorder(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CBorder* pBorder = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerBorderTypes::Bottom == type) + { + pBorder->m_oBottom.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadBorderProp, pBorder->m_oBottom.GetPointer()); + } + else if (c_oSerBorderTypes::Diagonal == type) + { + pBorder->m_oDiagonal.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadBorderProp, pBorder->m_oDiagonal.GetPointer()); + } + else if (c_oSerBorderTypes::End == type) + { + pBorder->m_oEnd.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadBorderProp, pBorder->m_oEnd.GetPointer()); + } + else if (c_oSerBorderTypes::Horizontal == type) + { + pBorder->m_oHorizontal.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadBorderProp, pBorder->m_oHorizontal.GetPointer()); + } + else if (c_oSerBorderTypes::Start == type) + { + pBorder->m_oStart.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadBorderProp, pBorder->m_oStart.GetPointer()); + } + else if (c_oSerBorderTypes::Top == type) + { + pBorder->m_oTop.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadBorderProp, pBorder->m_oTop.GetPointer()); + } + else if (c_oSerBorderTypes::Vertical == type) + { + pBorder->m_oVertical.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadBorderProp, pBorder->m_oVertical.GetPointer()); + } + else if (c_oSerBorderTypes::DiagonalDown == type) + { + pBorder->m_oDiagonalDown.Init(); + bool bDD = m_oBufferedStream.GetBool(); + pBorder->m_oDiagonalDown->SetValue((false != bDD) ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerBorderTypes::DiagonalUp == type) + { + pBorder->m_oDiagonalUp.Init(); + bool bDU = m_oBufferedStream.GetBool(); + pBorder->m_oDiagonalUp->SetValue((false != bDU) ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +}; +int BinaryStyleTableReader::ReadBorderProp(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CBorderProp* pBorderProp = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerBorderPropTypes::Style == type) + { + pBorderProp->m_oStyle.Init(); + pBorderProp->m_oStyle->SetValue((SimpleTypes::Spreadsheet::EBorderStyle)m_oBufferedStream.GetUChar()); + } + else if (c_oSerBorderPropTypes::Color == type) + { + pBorderProp->m_oColor.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadColor, pBorderProp->m_oColor.GetPointer()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +}; +int BinaryStyleTableReader::ReadColor(BYTE type, long length, void* poResult) +{ + return m_oBcr.ReadColor(type, length, poResult); +} +int BinaryStyleTableReader::ReadFills(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + if (c_oSerStylesTypes::Fill == type) + { + OOX::Spreadsheet::CFill* pFill = new OOX::Spreadsheet::CFill(); + READ1_DEF(length, res, this->ReadFill, pFill); + m_oStyles.m_oFills->m_arrItems.push_back(pFill); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +}; +int BinaryStyleTableReader::ReadFill(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CFill* pFill = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerFillTypes::Pattern == type) + { + pFill->m_oPatternFill.Init(); + READ1_DEF(length, res, this->ReadPatternFill, pFill->m_oPatternFill.GetPointer()); + } + else if (c_oSerFillTypes::Gradient == type) + { + pFill->m_oGradientFill.Init(); + READ1_DEF(length, res, this->ReadGradientFill, pFill->m_oGradientFill.GetPointer()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +}; +int BinaryStyleTableReader::ReadPatternFill(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CPatternFill* pPatternFill = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerFillTypes::PatternBgColor_deprecated == type) + { + pPatternFill->m_oPatternType.Init(); + pPatternFill->m_oPatternType->SetValue(SimpleTypes::Spreadsheet::patterntypeSolid); + + LONG colorPos = m_oBufferedStream.GetPos(); + pPatternFill->m_oFgColor.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadColor, pPatternFill->m_oFgColor.GetPointer()); + //todo copy + m_oBufferedStream.Seek(colorPos); + pPatternFill->m_oBgColor.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadColor, pPatternFill->m_oBgColor.GetPointer()); + } + else if (c_oSerFillTypes::PatternType == type) + { + pPatternFill->m_oPatternType.Init(); + pPatternFill->m_oPatternType->SetValue((SimpleTypes::Spreadsheet::EPatternType)m_oBufferedStream.GetUChar()); + } + else if (c_oSerFillTypes::PatternFgColor == type) + { + pPatternFill->m_oFgColor.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadColor, pPatternFill->m_oFgColor.GetPointer()); + } + else if (c_oSerFillTypes::PatternBgColor == type) + { + pPatternFill->m_oBgColor.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadColor, pPatternFill->m_oBgColor.GetPointer()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +}; +int BinaryStyleTableReader::ReadGradientFill(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CGradientFill* pGradientFill = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerFillTypes::GradientType == type) + { + pGradientFill->m_oType.Init(); + pGradientFill->m_oType->SetValue((SimpleTypes::Spreadsheet::EGradientType)m_oBufferedStream.GetUChar()); + } + else if (c_oSerFillTypes::GradientLeft == type) + { + pGradientFill->m_oLeft.Init(); + pGradientFill->m_oLeft->SetValue(m_oBufferedStream.GetDoubleReal()); + } + else if (c_oSerFillTypes::GradientTop == type) + { + pGradientFill->m_oTop.Init(); + pGradientFill->m_oTop->SetValue(m_oBufferedStream.GetDoubleReal()); + } + else if (c_oSerFillTypes::GradientRight == type) + { + pGradientFill->m_oRight.Init(); + pGradientFill->m_oRight->SetValue(m_oBufferedStream.GetDoubleReal()); + } + else if (c_oSerFillTypes::GradientBottom == type) + { + pGradientFill->m_oBottom.Init(); + pGradientFill->m_oBottom->SetValue(m_oBufferedStream.GetDoubleReal()); + } + else if (c_oSerFillTypes::GradientDegree == type) + { + pGradientFill->m_oDegree.Init(); + pGradientFill->m_oDegree->SetValue(m_oBufferedStream.GetDoubleReal()); + } + else if (c_oSerFillTypes::GradientStop == type) + { + OOX::Spreadsheet::CGradientStop* pGradientStop = new OOX::Spreadsheet::CGradientStop(); + READ1_DEF(length, res, this->ReadGradientFillStop, pGradientStop); + pGradientFill->m_arrItems.push_back(pGradientStop); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +}; +int BinaryStyleTableReader::ReadGradientFillStop(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CGradientStop* pGradientStop = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerFillTypes::GradientStopPosition == type) + { + pGradientStop->m_oPosition.Init(); + pGradientStop->m_oPosition->SetValue(m_oBufferedStream.GetDoubleReal()); + } + else if (c_oSerFillTypes::GradientStopColor == type) + { + pGradientStop->m_oColor.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadColor, pGradientStop->m_oColor.GetPointer()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +}; +int BinaryStyleTableReader::ReadFonts(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + if (c_oSerStylesTypes::Font == type) + { + OOX::Spreadsheet::CFont* pFont = new OOX::Spreadsheet::CFont(); + READ2_DEF_SPREADSHEET(length, res, this->ReadFont, pFont); + m_oStyles.m_oFonts->m_arrItems.push_back(pFont); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +}; +int BinaryStyleTableReader::ReadFont(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CFont* pFont = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerFontTypes::Bold == type) + { + pFont->m_oBold.Init(); + pFont->m_oBold->m_oVal.SetValue((false != m_oBufferedStream.GetBool()) ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerFontTypes::Color == type) + { + pFont->m_oColor.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadColor, pFont->m_oColor.GetPointer()); + } + else if (c_oSerFontTypes::Italic == type) + { + pFont->m_oItalic.Init(); + pFont->m_oItalic->m_oVal.SetValue((false != m_oBufferedStream.GetBool()) ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerFontTypes::RFont == type) + { + std::wstring sFontName(m_oBufferedStream.GetString4(length)); + pFont->m_oRFont.Init(); + pFont->m_oRFont->m_sVal = sFontName; + } + else if (c_oSerFontTypes::Scheme == type) + { + pFont->m_oScheme.Init(); + pFont->m_oScheme->m_oFontScheme.Init(); + pFont->m_oScheme->m_oFontScheme->SetValue((SimpleTypes::Spreadsheet::EFontScheme)m_oBufferedStream.GetUChar()); + } + else if (c_oSerFontTypes::Strike == type) + { + pFont->m_oStrike.Init(); + pFont->m_oStrike->m_oVal.SetValue((false != m_oBufferedStream.GetBool()) ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerFontTypes::Sz == type) + { + pFont->m_oSz.Init(); + pFont->m_oSz->m_oVal.Init(); + pFont->m_oSz->m_oVal->SetValue(m_oBufferedStream.GetDoubleReal()); + } + else if (c_oSerFontTypes::Underline == type) + { + pFont->m_oUnderline.Init(); + pFont->m_oUnderline->m_oUnderline.Init(); + pFont->m_oUnderline->m_oUnderline->SetValue((SimpleTypes::Spreadsheet::EUnderline)m_oBufferedStream.GetUChar()); + } + else if (c_oSerFontTypes::VertAlign == type) + { + pFont->m_oVertAlign.Init(); + pFont->m_oVertAlign->m_oVerticalAlign.Init(); + pFont->m_oVertAlign->m_oVerticalAlign->SetValue((SimpleTypes::EVerticalAlignRun)m_oBufferedStream.GetUChar()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +}; +int BinaryStyleTableReader::ReadNumFmts(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + if (c_oSerStylesTypes::NumFmt == type) + { + OOX::Spreadsheet::CNumFmt* pNumFmt = new OOX::Spreadsheet::CNumFmt(); + READ2_DEF_SPREADSHEET(length, res, this->ReadNumFmt, pNumFmt); + m_oStyles.m_oNumFmts->m_arrItems.push_back(pNumFmt); + + if (pNumFmt->m_oNumFmtId.IsInit()) + { + m_oStyles.m_oNumFmts->m_mapNumFmtIndex.insert(std::make_pair(pNumFmt->m_oNumFmtId->GetValue(), m_oStyles.m_oNumFmts->m_arrItems.size() - 1)); + } + + } + else + res = c_oSerConstants::ReadUnknown; + return res; +}; +int BinaryStyleTableReader::ReadNumFmt(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CNumFmt* pNumFmt = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerNumFmtTypes::FormatCode == type) + { + pNumFmt->m_oFormatCode = m_oBufferedStream.GetString4(length); + } + else if (c_oSerNumFmtTypes::FormatCode16 == type) + { + pNumFmt->m_oFormatCode16 = m_oBufferedStream.GetString4(length); + } + else if (c_oSerNumFmtTypes::NumFmtId == type) + { + pNumFmt->m_oNumFmtId.Init(); + pNumFmt->m_oNumFmtId->SetValue(m_oBufferedStream.GetLong()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +}; +int BinaryStyleTableReader::ReadCellStyleXfs(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + if (c_oSerStylesTypes::Xfs == type) + { + OOX::Spreadsheet::CXfs* pXfs = new OOX::Spreadsheet::CXfs(); + READ2_DEF_SPREADSHEET(length, res, this->ReadXfs, pXfs); + m_oStyles.m_oCellStyleXfs->m_arrItems.push_back(pXfs); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryStyleTableReader::ReadCellXfs(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + if (c_oSerStylesTypes::Xfs == type) + { + OOX::Spreadsheet::CXfs* pXfs = new OOX::Spreadsheet::CXfs(); + READ2_DEF_SPREADSHEET(length, res, this->ReadXfs, pXfs); + m_oStyles.m_oCellXfs->m_arrItems.push_back(pXfs); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +}; +int BinaryStyleTableReader::ReadXfs(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CXfs* pXfs = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerXfsTypes::ApplyAlignment == type) + { + pXfs->m_oApplyAlignment.Init(); + pXfs->m_oApplyAlignment->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerXfsTypes::ApplyBorder == type) + { + pXfs->m_oApplyBorder.Init(); + pXfs->m_oApplyBorder->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerXfsTypes::ApplyFill == type) + { + pXfs->m_oApplyFill.Init(); + pXfs->m_oApplyFill->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerXfsTypes::ApplyFont == type) + { + pXfs->m_oApplyFont.Init(); + pXfs->m_oApplyFont->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerXfsTypes::ApplyNumberFormat == type) + { + pXfs->m_oApplyNumberFormat.Init(); + pXfs->m_oApplyNumberFormat->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerXfsTypes::ApplyProtection == type) + { + pXfs->m_oApplyProtection.Init(); + pXfs->m_oApplyProtection->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerXfsTypes::BorderId == type) + { + pXfs->m_oBorderId.Init(); + pXfs->m_oBorderId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSerXfsTypes::FillId == type) + { + pXfs->m_oFillId.Init(); + pXfs->m_oFillId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSerXfsTypes::FontId == type) + { + pXfs->m_oFontId.Init(); + pXfs->m_oFontId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSerXfsTypes::NumFmtId == type) + { + pXfs->m_oNumFmtId.Init(); + pXfs->m_oNumFmtId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSerXfsTypes::QuotePrefix == type) + { + pXfs->m_oQuotePrefix.Init(); + pXfs->m_oQuotePrefix->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerXfsTypes::PivotButton == type) + { + pXfs->m_oPivotButton.Init(); + pXfs->m_oPivotButton->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerXfsTypes::Aligment == type) + { + pXfs->m_oAligment.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadAligment, pXfs->m_oAligment.GetPointer()); + } + else if (c_oSerXfsTypes::Protection == type) + { + pXfs->m_oProtection.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadProtection, pXfs->m_oProtection.GetPointer()); + } + else if (c_oSerXfsTypes::XfId == type) + { + pXfs->m_oXfId.Init(); + pXfs->m_oXfId->SetValue(m_oBufferedStream.GetLong()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +}; +int BinaryStyleTableReader::ReadProtection(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CProtection* pProtection = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerProtectionTypes::Hidden == type) + { + pProtection->m_oHidden.Init(); + pProtection->m_oHidden->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerProtectionTypes::Locked == type) + { + pProtection->m_oLocked.Init(); + pProtection->m_oLocked->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryStyleTableReader::ReadAligment(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CAligment* pAligment = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerAligmentTypes::Horizontal == type) + { + pAligment->m_oHorizontal.Init(); + pAligment->m_oHorizontal->SetValue((SimpleTypes::Spreadsheet::EHorizontalAlignment)m_oBufferedStream.GetUChar()); + } + else if (c_oSerAligmentTypes::Indent == type) + { + pAligment->m_oIndent = m_oBufferedStream.GetLong(); + } + else if (c_oSerAligmentTypes::RelativeIndent == type) + { + pAligment->m_oRelativeIndent = m_oBufferedStream.GetLong(); + } + else if (c_oSerAligmentTypes::ShrinkToFit == type) + { + pAligment->m_oShrinkToFit.Init(); + pAligment->m_oShrinkToFit->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerAligmentTypes::TextRotation == type) + { + pAligment->m_oTextRotation = m_oBufferedStream.GetLong(); + } + else if (c_oSerAligmentTypes::Vertical == type) + { + pAligment->m_oVertical.Init(); + pAligment->m_oVertical->SetValue((SimpleTypes::Spreadsheet::EVerticalAlignment)m_oBufferedStream.GetUChar()); + } + else if (c_oSerAligmentTypes::WrapText == type) + { + pAligment->m_oWrapText.Init(); + pAligment->m_oWrapText->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +}; +int BinaryStyleTableReader::ReadDxfs(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CDxfs* pDxfs = static_cast(poResult); + if (c_oSerStylesTypes::Dxf == type) + { + OOX::Spreadsheet::CDxf* pDxf = new OOX::Spreadsheet::CDxf(); + READ1_DEF(length, res, this->ReadDxf, pDxf); + pDxfs->m_arrItems.push_back(pDxf); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryStyleTableReader::ReadDxfExternal(OOX::Spreadsheet::CDxf* pDxf) +{ + int res = c_oSerConstants::ReadOk; + ULONG length = m_oBufferedStream.GetULong(); + READ1_DEF(length, res, this->ReadDxf, pDxf); + return res; +} +int BinaryStyleTableReader::ReadDxf(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CDxf* pDxf = static_cast(poResult); + if (c_oSer_Dxf::Alignment == type) + { + pDxf->m_oAlignment.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadAligment, pDxf->m_oAlignment.GetPointer()); + } + else if (c_oSer_Dxf::Border == type) + { + pDxf->m_oBorder.Init(); + READ1_DEF(length, res, this->ReadBorder, pDxf->m_oBorder.GetPointer()); + } + else if (c_oSer_Dxf::Fill == type) + { + pDxf->m_oFill.Init(); + READ1_DEF(length, res, this->ReadFill, pDxf->m_oFill.GetPointer()); + } + else if (c_oSer_Dxf::Font == type) + { + pDxf->m_oFont.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadFont, pDxf->m_oFont.GetPointer()); + } + else if (c_oSer_Dxf::NumFmt == type) + { + pDxf->m_oNumFmt.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadNumFmt, pDxf->m_oNumFmt.GetPointer()); + //todooo в m_mapNumFmtIndex + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryStyleTableReader::ReadCellStyles(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + if (c_oSerStylesTypes::CellStyle == type) + { + OOX::Spreadsheet::CCellStyle* pCellStyle = new OOX::Spreadsheet::CCellStyle(); + READ1_DEF(length, res, this->ReadCellStyle, pCellStyle); + m_oStyles.m_oCellStyles->m_arrItems.push_back(pCellStyle); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryStyleTableReader::ReadCellStyle(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CCellStyle* pCellStyle = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_CellStyle::BuiltinId == type) + { + pCellStyle->m_oBuiltinId.Init(); + pCellStyle->m_oBuiltinId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_CellStyle::CustomBuiltin == type) + { + pCellStyle->m_oCustomBuiltin.Init(); + pCellStyle->m_oCustomBuiltin->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSer_CellStyle::Hidden == type) + { + pCellStyle->m_oHidden.Init(); + pCellStyle->m_oHidden->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSer_CellStyle::ILevel == type) + { + pCellStyle->m_oILevel.Init(); + pCellStyle->m_oILevel->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_CellStyle::Name == type) + { + pCellStyle->m_oName = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_CellStyle::XfId == type) + { + pCellStyle->m_oXfId.Init(); + pCellStyle->m_oXfId->SetValue(m_oBufferedStream.GetLong()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryStyleTableReader::ReadTableStyles(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CTableStyles* pTableStyles = static_cast(poResult); + if (c_oSer_TableStyles::DefaultTableStyle == type) + { + pTableStyles->m_oDefaultTableStyle.Init(); + pTableStyles->m_oDefaultTableStyle->append(m_oBufferedStream.GetString4(length)); + } + else if (c_oSer_TableStyles::DefaultPivotStyle == type) + { + pTableStyles->m_oDefaultPivotStyle.Init(); + pTableStyles->m_oDefaultPivotStyle->append(m_oBufferedStream.GetString4(length)); + } + else if (c_oSer_TableStyles::TableStyles == type) + { + READ1_DEF(length, res, this->ReadTableCustomStyles, pTableStyles); + + pTableStyles->m_oCount.Init(); + pTableStyles->m_oCount->SetValue((unsigned int)pTableStyles->m_arrItems.size()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryStyleTableReader::ReadTableCustomStyles(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CTableStyles* pTableStyles = static_cast(poResult); + if (c_oSer_TableStyles::TableStyle == type) + { + OOX::Spreadsheet::CTableStyle* pTableStyle = new OOX::Spreadsheet::CTableStyle(); + READ1_DEF(length, res, this->ReadTableCustomStyle, pTableStyle); + pTableStyles->m_arrItems.push_back(pTableStyle); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryStyleTableReader::ReadTableCustomStyle(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CTableStyle* pTableStyle = static_cast(poResult); + if (c_oSer_TableStyle::Name == type) + { + pTableStyle->m_oName.Init(); + pTableStyle->m_oName->append(m_oBufferedStream.GetString4(length)); + } + else if (c_oSer_TableStyle::Pivot == type) + { + pTableStyle->m_oPivot.Init(); + pTableStyle->m_oPivot->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_TableStyle::Table == type) + { + pTableStyle->m_oTable.Init(); + pTableStyle->m_oTable->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_TableStyle::Elements == type) + { + READ1_DEF(length, res, this->ReadTableCustomStyleElements, pTableStyle); + + pTableStyle->m_oCount.Init(); + pTableStyle->m_oCount->SetValue((unsigned int)pTableStyle->m_arrItems.size()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryStyleTableReader::ReadTableCustomStyleElements(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CTableStyle* pTableStyle = static_cast(poResult); + if (c_oSer_TableStyle::Element == type) + { + OOX::Spreadsheet::CTableStyleElement* pTableStyleElement = new OOX::Spreadsheet::CTableStyleElement(); + READ2_DEF_SPREADSHEET(length, res, this->ReadTableCustomStyleElement, pTableStyleElement); + pTableStyle->m_arrItems.push_back(pTableStyleElement); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryStyleTableReader::ReadTableCustomStyleElement(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CTableStyleElement* pTableStyleElement = static_cast(poResult); + if (c_oSer_TableStyleElement::Type == type) + { + pTableStyleElement->m_oType.Init(); + pTableStyleElement->m_oType->SetValue((SimpleTypes::Spreadsheet::ETableStyleType)m_oBufferedStream.GetUChar()); + } + else if (c_oSer_TableStyleElement::Size == type) + { + pTableStyleElement->m_oSize.Init(); + pTableStyleElement->m_oSize->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_TableStyleElement::DxfId == type) + { + pTableStyleElement->m_oDxfId.Init(); + pTableStyleElement->m_oDxfId->SetValue(m_oBufferedStream.GetLong()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} + +BinaryWorkbookTableReader::BinaryWorkbookTableReader(NSBinPptxRW::CBinaryFileReader& oBufferedStream, OOX::Spreadsheet::CWorkbook& oWorkbook, boost::unordered_map>& mapPivotCacheDefinitions, const std::wstring& sDestinationDir, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter) + : Binary_CommonReader(oBufferedStream), m_oWorkbook(oWorkbook), m_mapPivotCacheDefinitions(mapPivotCacheDefinitions), m_sDestinationDir(sDestinationDir), m_pOfficeDrawingConverter(pOfficeDrawingConverter) +{ +} +int BinaryWorkbookTableReader::Read() +{ + if(m_pXlsb) + m_oWorkbook.OOX::File::m_pMainDocument= m_pXlsb; + int res = c_oSerConstants::ReadOk; + READ_TABLE_DEF(res, this->ReadWorkbookTableContent, this); + + if (!m_bMacroRead) + m_oWorkbook.m_bMacroEnabled = false; + return res; +} +int BinaryWorkbookTableReader::ReadWorkbookTableContent(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + if (c_oSerWorkbookTypes::WorkbookPr == type) + { + m_oWorkbook.m_oWorkbookPr.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadWorkbookPr, poResult); + } + else if (c_oSerWorkbookTypes::Protection == type) + { + m_oWorkbook.m_oWorkbookProtection.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadProtection, poResult); + } + else if (c_oSerWorkbookTypes::BookViews == type) + { + m_oWorkbook.m_oBookViews.Init(); + READ1_DEF(length, res, this->ReadBookViews, poResult); + } + else if (c_oSerWorkbookTypes::DefinedNames == type) + { + m_oWorkbook.m_oDefinedNames.Init(); + READ1_DEF(length, res, this->ReadDefinedNames, poResult); + } + else if (c_oSerWorkbookTypes::CalcPr == type) + { + m_oWorkbook.m_oCalcPr.Init(); + READ1_DEF(length, res, this->ReadCalcPr, m_oWorkbook.m_oCalcPr.GetPointer()); + } + else if (c_oSerWorkbookTypes::ExternalReferences == type) + { + m_oWorkbook.m_oExternalReferences.Init(); + READ1_DEF(length, res, this->ReadExternalReferences, poResult); + } + else if (c_oSerWorkbookTypes::PivotCaches == type) + { + m_oWorkbook.m_oPivotCachesXml.Init(); + m_oWorkbook.m_oPivotCachesXml->append(L""); + READ1_DEF(length, res, this->ReadPivotCaches, poResult); + m_oWorkbook.m_oPivotCachesXml->append(L""); + } + else if (c_oSerWorkbookTypes::AppName == type) + { + m_oWorkbook.m_oAppName = m_oBufferedStream.GetString4(length); + } + else if (c_oSerWorkbookTypes::OleSize == type) + { + m_oWorkbook.m_oOleSize = m_oBufferedStream.GetString4(length); + } + else if (c_oSerWorkbookTypes::FileSharing == type) + { + m_oWorkbook.m_oFileSharing.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadFileSharing, m_oWorkbook.m_oFileSharing.GetPointer()); + } + else if (c_oSerWorkbookTypes::ExternalLinksAutoRefresh == type) + { + OOX::Drawing::COfficeArtExtension* pOfficeArtExtension = new OOX::Drawing::COfficeArtExtension(); + pOfficeArtExtension->m_oExternalLinksAutoRefresh = m_oBufferedStream.GetBool(); + + pOfficeArtExtension->m_sUri = L"{FCE6A71B-6B00-49CD-AB44-F6B1AE7CDE65}"; + pOfficeArtExtension->m_sAdditionalNamespace = L"xmlns:xxlnp=\"http://schemas.microsoft.com/office/spreadsheetml/2019/extlinksprops\""; + + if (m_oWorkbook.m_oExtLst.IsInit() == false) + m_oWorkbook.m_oExtLst.Init(); + m_oWorkbook.m_oExtLst->m_arrExt.push_back(pOfficeArtExtension); + } + else if (c_oSerWorkbookTypes::VbaProject == type) + { + m_bMacroRead = true; + m_oBufferedStream.Skip(1); //skip type + + if (m_oWorkbook.m_bMacroEnabled) + { + smart_ptr oFileVbaProject(new OOX::VbaProject(NULL)); + + oFileVbaProject->fromPPTY(&m_oBufferedStream); + + smart_ptr oFile = oFileVbaProject.smart_dynamic_cast(); + const OOX::RId oRId = m_oWorkbook.Add(oFile); + } + else + { + m_oBufferedStream.SkipRecord(); + } + } + else if (c_oSerWorkbookTypes::JsaProject == type) + { + BYTE* pData = m_oBufferedStream.GetPointer(length); + OOX::CPath oJsaProject = OOX::FileTypes::JsaProject.DefaultFileName(); + std::wstring filePath = m_sDestinationDir + FILE_SEPARATOR_STR + _T("xl") + FILE_SEPARATOR_STR + oJsaProject.GetPath(); + + NSFile::CFileBinary oFile; + oFile.CreateFileW(filePath); + oFile.WriteFile(pData, length); + oFile.CloseFile(); + + smart_ptr oFileJsaProject(new OOX::JsaProject(NULL)); + smart_ptr oFileJsaProjectFile = oFileJsaProject.smart_dynamic_cast(); + m_oWorkbook.Add(oFileJsaProjectFile); + m_pOfficeDrawingConverter->m_pImageManager->m_pContentTypes->AddDefault(oJsaProject.GetExtention(false)); + } + else if (c_oSerWorkbookTypes::Comments == type) + { + BYTE* pData = m_oBufferedStream.GetPointer(length); + OOX::CPath oWorkbookComments = OOX::Spreadsheet::FileTypes::WorkbookComments.DefaultFileName(); + std::wstring filePath = m_sDestinationDir + FILE_SEPARATOR_STR + _T("xl") + FILE_SEPARATOR_STR + oWorkbookComments.GetPath(); + + NSFile::CFileBinary oFile; + oFile.CreateFileW(filePath); + oFile.WriteFile(pData, length); + oFile.CloseFile(); + + smart_ptr oFileWorkbookComments(new OOX::Spreadsheet::WorkbookComments(NULL)); + smart_ptr oFileWorkbookCommentsFile = oFileWorkbookComments.smart_dynamic_cast(); + m_oWorkbook.Add(oFileWorkbookCommentsFile); + m_pOfficeDrawingConverter->m_pImageManager->m_pContentTypes->AddDefault(oWorkbookComments.GetExtention(false)); + } + else if (c_oSerWorkbookTypes::Connections == type) + { + smart_ptr oConnection(new OOX::Spreadsheet::CConnectionsFile(NULL)); + if(m_pXlsb) + oConnection->OOX::File::m_pMainDocument = m_pXlsb; + oConnection->m_oConnections.Init(); + READ1_DEF(length, res, this->ReadConnections, oConnection->m_oConnections.GetPointer()); + + smart_ptr oFile = oConnection.smart_dynamic_cast(); + m_oWorkbook.Add(oFile); + } + else if (c_oSerWorkbookTypes::TimelineCaches == type) + { + OOX::Drawing::COfficeArtExtension* pOfficeArtExtension = new OOX::Drawing::COfficeArtExtension(); + pOfficeArtExtension->m_oTimelineCacheRefs.Init(); + + READ1_DEF(length, res, this->ReadTimelineCaches, pOfficeArtExtension->m_oTimelineCacheRefs.GetPointer()); + + pOfficeArtExtension->m_sUri = L"{D0CA8CA8-9F24-4464-BF8E-62219DCF47F9}"; + pOfficeArtExtension->m_sAdditionalNamespace = L"xmlns:x15=\"http://schemas.microsoft.com/office/spreadsheetml/2010/11/main\""; + + if (m_oWorkbook.m_oExtLst.IsInit() == false) + m_oWorkbook.m_oExtLst.Init(); + m_oWorkbook.m_oExtLst->m_arrExt.push_back(pOfficeArtExtension); + } + else if (c_oSerWorkbookTypes::SlicerCaches == type) + { + OOX::Drawing::COfficeArtExtension* pOfficeArtExtension = new OOX::Drawing::COfficeArtExtension(); + pOfficeArtExtension->m_oSlicerCaches.Init(); + + READ1_DEF(length, res, this->ReadSlicerCaches, pOfficeArtExtension->m_oSlicerCaches.GetPointer()); + + pOfficeArtExtension->m_sUri = L"{BBE1A952-AA13-448e-AADC-164F8A28A991}"; + pOfficeArtExtension->m_sAdditionalNamespace = L"xmlns:x14=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/main\""; + + if (m_oWorkbook.m_oExtLst.IsInit() == false) + m_oWorkbook.m_oExtLst.Init(); + m_oWorkbook.m_oExtLst->m_arrExt.push_back(pOfficeArtExtension); + } + else if (c_oSerWorkbookTypes::SlicerCachesExt == type) + { + OOX::Drawing::COfficeArtExtension* pOfficeArtExtension = new OOX::Drawing::COfficeArtExtension(); + pOfficeArtExtension->m_oSlicerCachesExt.Init(); + + READ1_DEF(length, res, this->ReadSlicerCaches, pOfficeArtExtension->m_oSlicerCachesExt.GetPointer()); + + pOfficeArtExtension->m_sUri = L"{46BE6895-7355-4a93-B00E-2C351335B9C9}"; + pOfficeArtExtension->m_sAdditionalNamespace = L"xmlns:x15=\"http://schemas.microsoft.com/office/spreadsheetml/2010/11/main\""; + + if (m_oWorkbook.m_oExtLst.IsInit() == false) + m_oWorkbook.m_oExtLst.Init(); + m_oWorkbook.m_oExtLst->m_arrExt.push_back(pOfficeArtExtension); + } + else if (c_oSerWorkbookTypes::Metadata == type) + { + smart_ptr oMetadataFile(new OOX::Spreadsheet::CMetadataFile(NULL)); + oMetadataFile->m_oMetadata.Init(); + READ1_DEF(length, res, this->ReadMetadata, oMetadataFile->m_oMetadata.GetPointer()); + + smart_ptr oFile = oMetadataFile.smart_dynamic_cast(); + m_oWorkbook.Add(oFile); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadConnections(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CConnections* pConnections = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSerConnectionsTypes::Connection == type) + { + OOX::Spreadsheet::CConnection* pConnection = new OOX::Spreadsheet::CConnection(); + READ1_DEF(length, res, this->ReadConnection, pConnection); + pConnections->m_arrItems.push_back(pConnection); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadConnection(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CConnection* pConnection = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSerConnectionsTypes::Type == type) + { + pConnection->m_oType = m_oBufferedStream.GetLong(); + } + else if (c_oSerConnectionsTypes::Name == type) + { + pConnection->m_oName = m_oBufferedStream.GetString4(length); + } + else if (c_oSerConnectionsTypes::Id == type) + { + pConnection->m_oId.Init(); + pConnection->m_oId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSerConnectionsTypes::UId == type) + { + pConnection->m_oUId = m_oBufferedStream.GetString4(length); + } + else if (c_oSerConnectionsTypes::Credentials == type) + { + pConnection->m_oCredentials.Init(); + pConnection->m_oCredentials->SetValue((SimpleTypes::Spreadsheet::ECredMethod)m_oBufferedStream.GetLong()); + } + else if (c_oSerConnectionsTypes::Background == type) + { + pConnection->m_oBackground = m_oBufferedStream.GetBool(); + } + else if (c_oSerConnectionsTypes::Deleted == type) + { + pConnection->m_oDeleted = m_oBufferedStream.GetBool(); + } + else if (c_oSerConnectionsTypes::Description == type) + { + pConnection->m_oDescription = m_oBufferedStream.GetString4(length); + } + else if (c_oSerConnectionsTypes::Interval == type) + { + pConnection->m_oInterval = m_oBufferedStream.GetLong(); + } + else if (c_oSerConnectionsTypes::KeepAlive == type) + { + pConnection->m_oKeepAlive = m_oBufferedStream.GetBool(); + } + else if (c_oSerConnectionsTypes::MinRefreshableVersion == type) + { + pConnection->m_oMinRefreshableVersion = m_oBufferedStream.GetLong(); + } + else if (c_oSerConnectionsTypes::New == type) + { + pConnection->m_oNew = m_oBufferedStream.GetBool(); + } + else if (c_oSerConnectionsTypes::OdcFile == type) + { + pConnection->m_oOdcFile = m_oBufferedStream.GetString4(length); + } + else if (c_oSerConnectionsTypes::OnlyUseConnectionFile == type) + { + pConnection->m_oOnlyUseConnectionFile = m_oBufferedStream.GetBool(); + } + else if (c_oSerConnectionsTypes::ReconnectionMethod == type) + { + pConnection->m_oReconnectionMethod = m_oBufferedStream.GetLong(); + } + else if (c_oSerConnectionsTypes::RefreshedVersion == type) + { + pConnection->m_oRefreshedVersion = m_oBufferedStream.GetLong(); + } + else if (c_oSerConnectionsTypes::RefreshOnLoad == type) + { + pConnection->m_oRefreshOnLoad = m_oBufferedStream.GetBool(); + } + else if (c_oSerConnectionsTypes::SaveData == type) + { + pConnection->m_oSaveData = m_oBufferedStream.GetBool(); + } + else if (c_oSerConnectionsTypes::SavePassword == type) + { + pConnection->m_oSavePassword = m_oBufferedStream.GetBool(); + } + else if (c_oSerConnectionsTypes::SingleSignOnId == type) + { + pConnection->m_oSingleSignOnId = m_oBufferedStream.GetString4(length); + } + else if (c_oSerConnectionsTypes::SourceFile == type) + { + pConnection->m_oSourceFile = m_oBufferedStream.GetString4(length); + } + else if (c_oSerConnectionsTypes::DbPr == type) + { + pConnection->m_oDbPr.Init(); + READ1_DEF(length, res, this->ReadConnectionDbPr, pConnection->m_oDbPr.GetPointer()); + } + else if (c_oSerConnectionsTypes::OlapPr == type) + { + pConnection->m_oOlapPr.Init(); + READ1_DEF(length, res, this->ReadConnectionOlapPr, pConnection->m_oOlapPr.GetPointer()); + } + else if (c_oSerConnectionsTypes::TextPr == type) + { + pConnection->m_oTextPr.Init(); + READ1_DEF(length, res, this->ReadConnectionTextPr, pConnection->m_oTextPr.GetPointer()); + } + else if (c_oSerConnectionsTypes::WebPr == type) + { + pConnection->m_oWebPr.Init(); + READ1_DEF(length, res, this->ReadConnectionWebPr, pConnection->m_oWebPr.GetPointer()); + } + else if (c_oSerConnectionsTypes::IdExt == type) + { + pConnection->m_oIdExt = m_oBufferedStream.GetString4(length); + } + else if (c_oSerConnectionsTypes::RangePr == type) + { + pConnection->m_oRangePr.Init(); + READ1_DEF(length, res, this->ReadConnectionRangePr, pConnection->m_oRangePr.GetPointer()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadConnectionDbPr(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CDbPr* pDbPr = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSerDbPrTypes::CommandType == type) + { + pDbPr->m_oCommandType = m_oBufferedStream.GetLong(); + } + else if (c_oSerDbPrTypes::Connection == type) + { + pDbPr->m_oConnection = m_oBufferedStream.GetString4(length); + } + else if (c_oSerDbPrTypes::Command == type) + { + pDbPr->m_oCommand = m_oBufferedStream.GetString4(length); + } + else if (c_oSerDbPrTypes::ServerCommand == type) + { + pDbPr->m_oServerCommand = m_oBufferedStream.GetString4(length); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadConnectionOlapPr(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::COlapPr* pOlapPr = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSerOlapPrTypes::RowDrillCount == type) + { + pOlapPr->m_oRowDrillCount = m_oBufferedStream.GetLong(); + } + else if (c_oSerOlapPrTypes::LocalConnection == type) + { + pOlapPr->m_oLocalConnection = m_oBufferedStream.GetString4(length); + } + else if (c_oSerOlapPrTypes::Local == type) + { + pOlapPr->m_oLocal = m_oBufferedStream.GetBool(); + } + else if (c_oSerOlapPrTypes::LocalRefresh == type) + { + pOlapPr->m_oLocalRefresh = m_oBufferedStream.GetBool(); + } + else if (c_oSerOlapPrTypes::SendLocale == type) + { + pOlapPr->m_oSendLocale = m_oBufferedStream.GetBool(); + } + else if (c_oSerOlapPrTypes::ServerNumberFormat == type) + { + pOlapPr->m_oServerNumberFormat = m_oBufferedStream.GetBool(); + } + else if (c_oSerOlapPrTypes::ServerFont == type) + { + pOlapPr->m_oServerFont = m_oBufferedStream.GetBool(); + } + else if (c_oSerOlapPrTypes::ServerFontColor == type) + { + pOlapPr->m_oServerFontColor = m_oBufferedStream.GetBool(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadConnectionRangePr(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CRangePr* pRangePr = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSerRangePrTypes::SourceName == type) + { + pRangePr->m_oSourceName = m_oBufferedStream.GetString4(length); + } + return res; +} +int BinaryWorkbookTableReader::ReadConnectionTextPr(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CTextPr* pTextPr = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSerTextPrTypes::CharacterSet == type) + { + pTextPr->m_oCharacterSet = m_oBufferedStream.GetString4(length); + } + else if (c_oSerTextPrTypes::SourceFile == type) + { + pTextPr->m_oSourceFile = m_oBufferedStream.GetString4(length); + } + else if (c_oSerTextPrTypes::Decimal == type) + { + pTextPr->m_oDecimal = m_oBufferedStream.GetString4(length); + } + else if (c_oSerTextPrTypes::Delimiter == type) + { + pTextPr->m_oDelimiter = m_oBufferedStream.GetString4(length); + } + else if (c_oSerTextPrTypes::Thousands == type) + { + pTextPr->m_oThousands = m_oBufferedStream.GetString4(length); + } + else if (c_oSerTextPrTypes::FirstRow == type) + { + pTextPr->m_oFirstRow = m_oBufferedStream.GetLong(); + } + else if (c_oSerTextPrTypes::CodePage == type) + { + pTextPr->m_oCodePage = m_oBufferedStream.GetLong(); + } + else if (c_oSerTextPrTypes::Qualifier == type) + { + pTextPr->m_oQualifier.Init(); + pTextPr->m_oQualifier->SetValue((SimpleTypes::Spreadsheet::EQualifier)m_oBufferedStream.GetLong()); + } + else if (c_oSerTextPrTypes::FileType == type) + { + pTextPr->m_oFileType.Init(); + pTextPr->m_oFileType->SetValue((SimpleTypes::Spreadsheet::EFileType)m_oBufferedStream.GetLong()); + } + else if (c_oSerTextPrTypes::Prompt == type) + { + pTextPr->m_oPrompt = m_oBufferedStream.GetBool(); + } + else if (c_oSerTextPrTypes::Delimited == type) + { + pTextPr->m_oDelimited = m_oBufferedStream.GetBool(); + } + else if (c_oSerTextPrTypes::Tab == type) + { + pTextPr->m_oTab = m_oBufferedStream.GetBool(); + } + else if (c_oSerTextPrTypes::Space == type) + { + pTextPr->m_oSpace = m_oBufferedStream.GetBool(); + } + else if (c_oSerTextPrTypes::Comma == type) + { + pTextPr->m_oComma = m_oBufferedStream.GetBool(); + } + else if (c_oSerTextPrTypes::Semicolon == type) + { + pTextPr->m_oSemicolon = m_oBufferedStream.GetBool(); + } + else if (c_oSerTextPrTypes::Consecutive == type) + { + pTextPr->m_oConsecutive = m_oBufferedStream.GetBool(); + } + else if (c_oSerTextPrTypes::TextFields == type) + { + pTextPr->m_oTextFields.Init(); + READ1_DEF(length, res, this->ReadConnectionTextFields, pTextPr->m_oTextFields.GetPointer()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadConnectionTextFields(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CTextFields* pTextFields = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + + if (c_oSerTextPrTypes::TextField == type) + { + pTextFields->m_arrItems.push_back(new OOX::Spreadsheet::CTextField()); + READ1_DEF(length, res, this->ReadConnectionTextField, pTextFields->m_arrItems.back()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadConnectionTextField(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CTextField* pTextField = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + + if (c_oSerTextPrTypes::TextFieldType == type) + { + pTextField->m_oType.Init(); + pTextField->m_oType->SetValue((SimpleTypes::Spreadsheet::EExternalConnectionType)m_oBufferedStream.GetLong()); + } + else if (c_oSerTextPrTypes::TextFieldPosition == type) + { + pTextField->m_oPosition = m_oBufferedStream.GetLong(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadConnectionWebPr(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CWebPr* pWebPr = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSerWebPrTypes::Url == type) + { + pWebPr->m_oUrl = m_oBufferedStream.GetString4(length); + } + else if (c_oSerWebPrTypes::Post == type) + { + pWebPr->m_oPost = m_oBufferedStream.GetString4(length); + } + else if (c_oSerWebPrTypes::EditPage == type) + { + pWebPr->m_oEditPage = m_oBufferedStream.GetString4(length); + } + else if (c_oSerWebPrTypes::HtmlFormat == type) + { + pWebPr->m_oHtmlFormat.Init(); + pWebPr->m_oHtmlFormat->SetValue((SimpleTypes::Spreadsheet::EHtmlFormat)m_oBufferedStream.GetLong()); + } + else if (c_oSerWebPrTypes::Xml == type) + { + pWebPr->m_oXml = m_oBufferedStream.GetBool(); + } + else if (c_oSerWebPrTypes::SourceData == type) + { + pWebPr->m_oSourceData = m_oBufferedStream.GetBool(); + } + else if (c_oSerWebPrTypes::Consecutive == type) + { + pWebPr->m_oConsecutive = m_oBufferedStream.GetBool(); + } + else if (c_oSerWebPrTypes::FirstRow == type) + { + pWebPr->m_oFirstRow = m_oBufferedStream.GetBool(); + } + else if (c_oSerWebPrTypes::Xl97 == type) + { + pWebPr->m_oXl97 = m_oBufferedStream.GetBool(); + } + else if (c_oSerWebPrTypes::TextDates == type) + { + pWebPr->m_oTextDates = m_oBufferedStream.GetBool(); + } + else if (c_oSerWebPrTypes::Xl2000 == type) + { + pWebPr->m_oXl2000 = m_oBufferedStream.GetBool(); + } + else if (c_oSerWebPrTypes::HtmlTables == type) + { + pWebPr->m_oHtmlTables = m_oBufferedStream.GetBool(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadFileSharing(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CFileSharing* pFileSharing = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSerFileSharing::AlgorithmName == type) + { + pFileSharing->m_oAlgorithmName.Init(); + pFileSharing->m_oAlgorithmName->SetValue((SimpleTypes::ECryptAlgoritmName)m_oBufferedStream.GetUChar()); + } + else if (c_oSerFileSharing::SpinCount == type) + { + pFileSharing->m_oSpinCount.Init(); + pFileSharing->m_oSpinCount->SetValue(m_oBufferedStream.GetULong()); + } + else if (c_oSerFileSharing::HashValue == type) + { + pFileSharing->m_oHashValue = m_oBufferedStream.GetString4(length); + } + else if (c_oSerFileSharing::SaltValue == type) + { + pFileSharing->m_oSaltValue = m_oBufferedStream.GetString4(length); + } + else if (c_oSerFileSharing::Password == type) + { + pFileSharing->m_oPassword = m_oBufferedStream.GetString4(length); + } + else if (c_oSerFileSharing::UserName == type) + { + pFileSharing->m_oUserName= m_oBufferedStream.GetString4(length); + } + else if (c_oSerFileSharing::ReadOnly == type) + { + pFileSharing->m_oReadOnlyRecommended = m_oBufferedStream.GetBool(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadProtection(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + if (c_oSerWorkbookProtection::AlgorithmName == type) + { + m_oWorkbook.m_oWorkbookProtection->m_oWorkbookAlgorithmName.Init(); + m_oWorkbook.m_oWorkbookProtection->m_oWorkbookAlgorithmName->SetValue((SimpleTypes::ECryptAlgoritmName)m_oBufferedStream.GetUChar()); + } + else if (c_oSerWorkbookProtection::SpinCount == type) + { + m_oWorkbook.m_oWorkbookProtection->m_oWorkbookSpinCount.Init(); + m_oWorkbook.m_oWorkbookProtection->m_oWorkbookSpinCount->SetValue(m_oBufferedStream.GetULong()); + } + else if (c_oSerWorkbookProtection::HashValue == type) + { + m_oWorkbook.m_oWorkbookProtection->m_oWorkbookHashValue = m_oBufferedStream.GetString4(length); + } + else if (c_oSerWorkbookProtection::SaltValue == type) + { + m_oWorkbook.m_oWorkbookProtection->m_oWorkbookSaltValue = m_oBufferedStream.GetString4(length); + } + else if (c_oSerWorkbookProtection::Password == type) + { + m_oWorkbook.m_oWorkbookProtection->m_oPassword = m_oBufferedStream.GetString4(length); + } + else if (c_oSerWorkbookProtection::LockStructure == type) + { + m_oWorkbook.m_oWorkbookProtection->m_oLockStructure.Init(); + m_oWorkbook.m_oWorkbookProtection->m_oLockStructure->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerWorkbookProtection::LockWindows == type) + { + m_oWorkbook.m_oWorkbookProtection->m_oLockWindows.Init(); + m_oWorkbook.m_oWorkbookProtection->m_oLockWindows->FromBool(m_oBufferedStream.GetBool()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadWorkbookPr(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + if (c_oSerWorkbookPrTypes::Date1904 == type) + { + m_oWorkbook.m_oWorkbookPr->m_oDate1904.Init(); + m_oWorkbook.m_oWorkbookPr->m_oDate1904->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerWorkbookPrTypes::DateCompatibility == type) + { + m_oWorkbook.m_oWorkbookPr->m_oDateCompatibility.Init(); + m_oWorkbook.m_oWorkbookPr->m_oDateCompatibility->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerWorkbookPrTypes::HidePivotFieldList == type) + { + m_oWorkbook.m_oWorkbookPr->m_oHidePivotFieldList.Init(); + m_oWorkbook.m_oWorkbookPr->m_oHidePivotFieldList->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerWorkbookPrTypes::ShowPivotChartFilter == type) + { + m_oWorkbook.m_oWorkbookPr->m_oShowPivotChartFilter.Init(); + m_oWorkbook.m_oWorkbookPr->m_oShowPivotChartFilter->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerWorkbookPrTypes::UpdateLinks == type) + { + m_oWorkbook.m_oWorkbookPr->m_oUpdateLinks.Init(); + m_oWorkbook.m_oWorkbookPr->m_oUpdateLinks->SetValueFromByte(m_oBufferedStream.GetUChar()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadBookViews(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + if (c_oSerWorkbookTypes::WorkbookView == type) + { + OOX::Spreadsheet::CWorkbookView* pWorkbookView = new OOX::Spreadsheet::CWorkbookView(); + READ2_DEF_SPREADSHEET(length, res, this->ReadWorkbookView, pWorkbookView); + m_oWorkbook.m_oBookViews->m_arrItems.push_back(pWorkbookView); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadWorkbookView(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CWorkbookView* pWorkbookView = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerWorkbookViewTypes::ActiveTab == type) + { + pWorkbookView->m_oActiveTab.Init(); + pWorkbookView->m_oActiveTab->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSerWorkbookViewTypes::AutoFilterDateGrouping == type) + { + pWorkbookView->m_oAutoFilterDateGrouping.Init(); + pWorkbookView->m_oAutoFilterDateGrouping->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerWorkbookViewTypes::FirstSheet == type) + { + pWorkbookView->m_oActiveTab.Init(); + pWorkbookView->m_oActiveTab->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSerWorkbookViewTypes::Minimized == type) + { + pWorkbookView->m_oMinimized.Init(); + pWorkbookView->m_oMinimized->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerWorkbookViewTypes::ShowHorizontalScroll == type) + { + pWorkbookView->m_oShowHorizontalScroll.Init(); + pWorkbookView->m_oShowHorizontalScroll->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerWorkbookViewTypes::ShowSheetTabs == type) + { + pWorkbookView->m_oShowSheetTabs.Init(); + pWorkbookView->m_oShowSheetTabs->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerWorkbookViewTypes::ShowVerticalScroll == type) + { + pWorkbookView->m_oShowVerticalScroll.Init(); + pWorkbookView->m_oShowVerticalScroll->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerWorkbookViewTypes::TabRatio == type) + { + pWorkbookView->m_oTabRatio.Init(); + pWorkbookView->m_oTabRatio->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSerWorkbookViewTypes::Visibility == type) + { + pWorkbookView->m_oVisibility.Init(); + pWorkbookView->m_oVisibility->SetValueFromByte(m_oBufferedStream.GetUChar()); + } + else if (c_oSerWorkbookViewTypes::WindowHeight == type) + { + pWorkbookView->m_oWindowHeight.Init(); + pWorkbookView->m_oWindowHeight->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSerWorkbookViewTypes::WindowWidth == type) + { + pWorkbookView->m_oWindowWidth.Init(); + pWorkbookView->m_oWindowWidth->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSerWorkbookViewTypes::XWindow == type) + { + pWorkbookView->m_oXWindow.Init(); + pWorkbookView->m_oXWindow->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSerWorkbookViewTypes::YWindow == type) + { + pWorkbookView->m_oYWindow.Init(); + pWorkbookView->m_oYWindow->SetValue(m_oBufferedStream.GetLong()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadExternalReference(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + + OOX::Spreadsheet::CExternalLink *externalLink = static_cast(poResult); + + if (c_oSerWorkbookTypes::ExternalBook == type) + { + externalLink->m_oExternalBook.Init(); + READ1_DEF(length, res, this->ReadExternalBook, externalLink); + } + else if (c_oSerWorkbookTypes::OleLink == type) + { + externalLink->m_oOleLink.Init(); + READ1_DEF(length, res, this->ReadOleLink, externalLink); + } + else if (c_oSerWorkbookTypes::DdeLink == type) + { + externalLink->m_oDdeLink.Init(); + READ1_DEF(length, res, this->ReadDdeLink, externalLink->m_oDdeLink.GetPointer()); + } + else if (c_oSerWorkbookTypes::ExternalFileKey == type) + { + externalLink->m_oFileKey = m_oBufferedStream.GetString4(length); + } + else if (c_oSerWorkbookTypes::ExternalInstanceId == type) + { + externalLink->m_oInstanceId = m_oBufferedStream.GetString4(length); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadExternalReferences(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + if (c_oSerWorkbookTypes::ExternalReference == type) + { + OOX::Spreadsheet::CExternalLink *extLink = new OOX::Spreadsheet::CExternalLink(NULL); + READ1_DEF(length, res, this->ReadExternalReference, extLink); + + smart_ptr oCurFile(extLink); + const OOX::RId oRId = m_oWorkbook.Add(oCurFile); + + OOX::Spreadsheet::CExternalReference* pExternalReference = new OOX::Spreadsheet::CExternalReference(); + + pExternalReference->m_oRid.Init(); + pExternalReference->m_oRid->SetValue(oRId.get()); + + m_oWorkbook.m_oExternalReferences->m_arrItems.push_back(pExternalReference); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadDefinedNames(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + if (c_oSerWorkbookTypes::DefinedName == type) + { + OOX::Spreadsheet::CDefinedName* pDefinedName = new OOX::Spreadsheet::CDefinedName(); + READ1_DEF(length, res, this->ReadDefinedName, pDefinedName); + m_oWorkbook.m_oDefinedNames->m_arrItems.push_back(pDefinedName); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadDefinedName(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CDefinedName* pDefinedName = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerDefinedNameTypes::Name == type) + { + pDefinedName->m_oName = m_oBufferedStream.GetString4(length); + } + else if (c_oSerDefinedNameTypes::Ref == type) + { + pDefinedName->m_oRef = m_oBufferedStream.GetString4(length); + } + else if (c_oSerDefinedNameTypes::LocalSheetId == type) + { + pDefinedName->m_oLocalSheetId.Init(); + pDefinedName->m_oLocalSheetId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSerDefinedNameTypes::Hidden == type) + { + pDefinedName->m_oHidden.Init(); + pDefinedName->m_oHidden->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerDefinedNameTypes::Comment == type) + { + pDefinedName->m_oComment = m_oBufferedStream.GetString4(length); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadCalcPr(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CCalcPr* calcPr = static_cast(poResult); + if (c_oSerCalcPrTypes::CalcId == type) + { + calcPr->m_oCalcId.Init(); + calcPr->m_oCalcId->SetValue(m_oBufferedStream.GetULong()); + } + else if (c_oSerCalcPrTypes::CalcMode == type) + { + calcPr->m_oCalcMode = (SimpleTypes::Spreadsheet::ECalcMode)m_oBufferedStream.GetUChar(); + } + else if (c_oSerCalcPrTypes::FullCalcOnLoad == type) + { + calcPr->m_oFullCalcOnLoad = m_oBufferedStream.GetBool(); + } + else if (c_oSerCalcPrTypes::RefMode == type) + { + calcPr->m_oRefMode = (SimpleTypes::Spreadsheet::ERefMode)m_oBufferedStream.GetUChar(); + } + else if (c_oSerCalcPrTypes::Iterate == type) + { + calcPr->m_oIterate.Init(); + calcPr->m_oIterate->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerCalcPrTypes::IterateCount == type) + { + calcPr->m_oIterateCount.Init(); + calcPr->m_oIterateCount->SetValue(m_oBufferedStream.GetULong()); + } + else if (c_oSerCalcPrTypes::IterateDelta == type) + { + calcPr->m_oIterateDelta.Init(); + calcPr->m_oIterateDelta->SetValue(m_oBufferedStream.GetDoubleReal()); + } + else if (c_oSerCalcPrTypes::FullPrecision == type) + { + calcPr->m_oFullPrecision.Init(); + calcPr->m_oFullPrecision->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerCalcPrTypes::CalcCompleted == type) + { + calcPr->m_oCalcCompleted.Init(); + calcPr->m_oCalcCompleted->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerCalcPrTypes::CalcOnSave == type) + { + calcPr->m_oCalcOnSave.Init(); + calcPr->m_oCalcOnSave->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerCalcPrTypes::ConcurrentCalc == type) + { + calcPr->m_oConcurrentCalc.Init(); + calcPr->m_oConcurrentCalc->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerCalcPrTypes::ConcurrentManualCount == type) + { + calcPr->m_oConcurrentManualCount.Init(); + calcPr->m_oConcurrentManualCount->SetValue(m_oBufferedStream.GetULong()); + } + else if (c_oSerCalcPrTypes::ForceFullCalc == type) + { + calcPr->m_oForceFullCalc.Init(); + calcPr->m_oForceFullCalc->FromBool(m_oBufferedStream.GetBool()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadExternalAlternateUrls(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CExternalLink* extLink = static_cast(poResult); + if (!extLink) return c_oSerConstants::ReadUnknown; + + OOX::Spreadsheet::CExternalBook* pExternalBook = extLink->m_oExternalBook.GetPointer(); + if (!pExternalBook) return c_oSerConstants::ReadUnknown; + + OOX::Spreadsheet::CAlternateUrls* altUrls = pExternalBook->m_oAlternateUrls.GetPointer(); + if (!altUrls) return c_oSerConstants::ReadUnknown; + + int res = c_oSerConstants::ReadOk; + if (c_oSer_ExternalLinkTypes::AbsoluteUrl == type) + { + std::wstring sName(m_oBufferedStream.GetString3(length)); + + OOX::Spreadsheet::ExternalLinkPath* link = new OOX::Spreadsheet::ExternalLinkPath(NULL, OOX::CPath(sName, false)); + smart_ptr oLinkFile(link); + const OOX::RId oRIdLink = extLink->Add(oLinkFile); + + altUrls->m_oAbsoluteUrlRid.Init(); + altUrls->m_oAbsoluteUrlRid->SetValue(oRIdLink.get()); + } + else if (c_oSer_ExternalLinkTypes::RelativeUrl == type) + { + std::wstring sName(m_oBufferedStream.GetString3(length)); + + OOX::Spreadsheet::ExternalLinkPath* link = new OOX::Spreadsheet::ExternalLinkPath(NULL, OOX::CPath(sName, false)); + smart_ptr oLinkFile(link); + const OOX::RId oRIdLink = extLink->Add(oLinkFile); + + altUrls->m_oRelativeUrlRid.Init(); + altUrls->m_oRelativeUrlRid->SetValue(oRIdLink.get()); + } + else if (c_oSer_ExternalLinkTypes::ExternalAlternateUrlsDriveId == type) + { + altUrls->m_oDriveId = m_oBufferedStream.GetString3(length); + } + else if (c_oSer_ExternalLinkTypes::ExternalAlternateUrlsItemId == type) + { + altUrls->m_oItemId = m_oBufferedStream.GetString3(length); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadExternalBook(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CExternalLink* extLink = static_cast(poResult); + OOX::Spreadsheet::CExternalBook* pExternalBook = extLink->m_oExternalBook.GetPointer(); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_ExternalLinkTypes::Id == type) + { + std::wstring sName(m_oBufferedStream.GetString3(length)); + + OOX::Spreadsheet::ExternalLinkPath *link = new OOX::Spreadsheet::ExternalLinkPath(NULL, OOX::CPath(sName, false)); + smart_ptr oLinkFile(link); + const OOX::RId oRIdLink = extLink->Add(oLinkFile); + + pExternalBook->m_oRid.Init(); + pExternalBook->m_oRid->SetValue(oRIdLink.get()); + } + else if (c_oSer_ExternalLinkTypes::SheetNames == type) + { + pExternalBook->m_oSheetNames.Init(); + READ1_DEF(length, res, this->ReadExternalSheetNames, pExternalBook->m_oSheetNames.GetPointer()); + } + else if (c_oSer_ExternalLinkTypes::DefinedNames == type) + { + pExternalBook->m_oDefinedNames.Init(); + READ1_DEF(length, res, this->ReadExternalDefinedNames, pExternalBook->m_oDefinedNames.GetPointer()); + } + else if (c_oSer_ExternalLinkTypes::SheetDataSet == type) + { + pExternalBook->m_oSheetDataSet.Init(); + READ1_DEF(length, res, this->ReadExternalSheetDataSet, pExternalBook->m_oSheetDataSet.GetPointer()); + } + else if (c_oSer_ExternalLinkTypes::AlternateUrls == type) + { + pExternalBook->m_oAlternateUrls.Init(); + READ1_DEF(length, res, this->ReadExternalAlternateUrls, extLink); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadExternalSheetNames(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CExternalSheetNames* pSheetNames = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_ExternalLinkTypes::SheetName == type) + { + ComplexTypes::Spreadsheet::String* pSheetName = new ComplexTypes::Spreadsheet::String(); + pSheetName->m_sVal = m_oBufferedStream.GetString4(length); + pSheetNames->m_arrItems.push_back(pSheetName); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadExternalDefinedNames(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CExternalDefinedNames* pDefinedNames = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_ExternalLinkTypes::DefinedName == type) + { + OOX::Spreadsheet::CExternalDefinedName* pDefinedName = new OOX::Spreadsheet::CExternalDefinedName(); + READ1_DEF(length, res, this->ReadExternalDefinedName, pDefinedName); + pDefinedNames->m_arrItems.push_back(pDefinedName); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadExternalDefinedName(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CExternalDefinedName* pDefinedName = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_ExternalLinkTypes::DefinedNameName == type) + { + pDefinedName->m_oName.Init(); + pDefinedName->m_oName->append(m_oBufferedStream.GetString3(length)); + } + else if (c_oSer_ExternalLinkTypes::DefinedNameRefersTo == type) + { + pDefinedName->m_oRefersTo.Init(); + pDefinedName->m_oRefersTo->append(m_oBufferedStream.GetString3(length)); + } + else if (c_oSer_ExternalLinkTypes::DefinedNameSheetId == type) + { + pDefinedName->m_oSheetId.Init(); + pDefinedName->m_oSheetId->SetValue(m_oBufferedStream.GetULong()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadExternalSheetDataSet(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CExternalSheetDataSet* pSheetDataSet = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_ExternalLinkTypes::SheetData == type) + { + OOX::Spreadsheet::CExternalSheetData* pSheetData = new OOX::Spreadsheet::CExternalSheetData(); + READ1_DEF(length, res, this->ReadExternalSheetData, pSheetData); + pSheetDataSet->m_arrItems.push_back(pSheetData); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadExternalSheetData(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CExternalSheetData* pSheetData = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_ExternalLinkTypes::SheetDataSheetId == type) + { + pSheetData->m_oSheetId.Init(); + pSheetData->m_oSheetId->SetValue(m_oBufferedStream.GetULong()); + } + else if (c_oSer_ExternalLinkTypes::SheetDataRefreshError == type) + { + pSheetData->m_oRefreshError.Init(); + pSheetData->m_oRefreshError->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_ExternalLinkTypes::SheetDataRow == type) + { + OOX::Spreadsheet::CExternalRow* pRow = new OOX::Spreadsheet::CExternalRow(); + READ1_DEF(length, res, this->ReadExternalRow, pRow); + pSheetData->m_arrItems.push_back(pRow); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadExternalRow(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CExternalRow* pRow = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_ExternalLinkTypes::SheetDataRowR == type) + { + pRow->m_oR.Init(); + pRow->m_oR->SetValue(m_oBufferedStream.GetULong()); + } + else if (c_oSer_ExternalLinkTypes::SheetDataRowCell == type) + { + OOX::Spreadsheet::CExternalCell* pCell = new OOX::Spreadsheet::CExternalCell(); + READ1_DEF(length, res, this->ReadExternalCell, pCell); + pRow->m_arrItems.push_back(pCell); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadExternalCell(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CExternalCell* pCell = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_ExternalLinkTypes::SheetDataRowCellRef == type) + { + pCell->m_oRef = m_oBufferedStream.GetString3(length); + } + else if (c_oSer_ExternalLinkTypes::SheetDataRowCellType == type) + { + pCell->m_oType.Init(); + pCell->m_oType->SetValue((SimpleTypes::Spreadsheet::ECellTypeType)m_oBufferedStream.GetUChar()); + } + else if (c_oSer_ExternalLinkTypes::SheetDataRowCellValue == type) + { + pCell->m_oValue.Init(); + pCell->m_oValue->m_sText.append(m_oBufferedStream.GetString3(length)); + } + else if (c_oSer_ExternalLinkTypes::ValueMetadata == type) + { + pCell->m_oValueMetadata = m_oBufferedStream.GetULong(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadOleLink(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CExternalLink* extLink = static_cast(poResult); + OOX::Spreadsheet::COleLink* oleLink = extLink->m_oOleLink.GetPointer(); + int res = c_oSerConstants::ReadOk; + if (c_oSer_OleLinkTypes::Id == type) + { + std::wstring sName(m_oBufferedStream.GetString3(length)); + + OOX::Spreadsheet::ExternalOleObject *link = new OOX::Spreadsheet::ExternalOleObject(NULL, sName); + smart_ptr oLinkFile(link); + const OOX::RId oRIdLink = extLink->Add(oLinkFile); + + oleLink->m_oRid.Init(); + oleLink->m_oRid->SetValue(oRIdLink.get()); + } + else if (c_oSer_OleLinkTypes::ProgId == type) + { + oleLink->m_oProgId.Init(); + oleLink->m_oProgId->append(m_oBufferedStream.GetString3(length)); + } + else if (c_oSer_OleLinkTypes::OleItem == type) + { + if (!oleLink->m_oOleItems.IsInit()) + { + oleLink->m_oOleItems.Init(); + } + OOX::Spreadsheet::COleItem* pOleItem = new OOX::Spreadsheet::COleItem(); + READ1_DEF(length, res, this->ReadOleItem, pOleItem); + oleLink->m_oOleItems->m_arrItems.push_back(pOleItem); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadOleItem(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::COleItem* pOleItem = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_OleLinkTypes::Name == type) + { + pOleItem->m_oName.Init(); + pOleItem->m_oName->append(m_oBufferedStream.GetString3(length)); + } + else if (c_oSer_OleLinkTypes::Icon == type) + { + pOleItem->m_oIcon.Init(); + pOleItem->m_oIcon->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_OleLinkTypes::Advise == type) + { + pOleItem->m_oAdvise.Init(); + pOleItem->m_oAdvise->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_OleLinkTypes::PreferPic == type) + { + pOleItem->m_oPreferPic.Init(); + pOleItem->m_oPreferPic->FromBool(m_oBufferedStream.GetBool()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadDdeLink(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CDdeLink* ddeLink = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_DdeLinkTypes::DdeService == type) + { + ddeLink->m_oDdeService.Init(); + ddeLink->m_oDdeService->append(m_oBufferedStream.GetString3(length)); + } + else if (c_oSer_DdeLinkTypes::DdeTopic == type) + { + ddeLink->m_oDdeTopic.Init(); + ddeLink->m_oDdeTopic->append(m_oBufferedStream.GetString3(length)); + } + else if (c_oSer_DdeLinkTypes::DdeItem == type) + { + if (!ddeLink->m_oDdeItems.IsInit()) + { + ddeLink->m_oDdeItems.Init(); + } + OOX::Spreadsheet::CDdeItem* pDdeItem = new OOX::Spreadsheet::CDdeItem(); + READ1_DEF(length, res, this->ReadDdeItem, pDdeItem); + ddeLink->m_oDdeItems->m_arrItems.push_back(pDdeItem); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadDdeItem(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CDdeItem* pDdeItem = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_DdeLinkTypes::Name == type) + { + pDdeItem->m_oName.Init(); + pDdeItem->m_oName->append(m_oBufferedStream.GetString3(length)); + } + else if (c_oSer_DdeLinkTypes::Ole == type) + { + pDdeItem->m_oOle.Init(); + pDdeItem->m_oOle->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_DdeLinkTypes::Advise == type) + { + pDdeItem->m_oAdvise.Init(); + pDdeItem->m_oAdvise->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_DdeLinkTypes::PreferPic == type) + { + pDdeItem->m_oPreferPic.Init(); + pDdeItem->m_oPreferPic->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_DdeLinkTypes::DdeValues == type) + { + pDdeItem->m_oDdeValues.Init(); + READ1_DEF(length, res, this->ReadDdeValues, pDdeItem->m_oDdeValues.GetPointer()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadDdeValues(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CDdeValues* pDdeValues = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_DdeLinkTypes::DdeValuesRows == type) + { + pDdeValues->m_oRows.Init(); + pDdeValues->m_oRows->SetValue(m_oBufferedStream.GetULong()); + } + else if (c_oSer_DdeLinkTypes::DdeValuesCols == type) + { + pDdeValues->m_oCols.Init(); + pDdeValues->m_oCols->SetValue(m_oBufferedStream.GetULong()); + } + else if (c_oSer_DdeLinkTypes::DdeValue == type) + { + OOX::Spreadsheet::CDdeValue* pDdeValue = new OOX::Spreadsheet::CDdeValue(); + READ1_DEF(length, res, this->ReadDdeValue, pDdeValue); + pDdeValues->m_arrItems.push_back(pDdeValue); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadDdeValue(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CDdeValue* pDdeValue = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_DdeLinkTypes::DdeValueType == type) + { + pDdeValue->m_oType.Init(); + pDdeValue->m_oType->SetValue((SimpleTypes::Spreadsheet::EDdeValueType)m_oBufferedStream.GetUChar()); + } + else if (c_oSer_DdeLinkTypes::DdeValueVal == type) + { + OOX::Spreadsheet::CText* pText = new OOX::Spreadsheet::CText(); + pText->m_sText.append(m_oBufferedStream.GetString3(length)); + pDdeValue->m_arrItems.push_back(pText); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadPivotCaches(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + if (c_oSerWorkbookTypes::PivotCache == type) + { + PivotCachesTemp oPivotCachesTemp; + READ1_DEF(length, res, this->ReadPivotCache, &oPivotCachesTemp); + if (-1 != oPivotCachesTemp.nId && NULL != oPivotCachesTemp.pDefinitionData) + { + OOX::Spreadsheet::CPivotCacheDefinitionFile* pDefinitionFile = new OOX::Spreadsheet::CPivotCacheDefinitionFile(NULL); + if(m_pXlsb) + pDefinitionFile->OOX::File::m_pMainDocument = m_pXlsb; + std::wstring srIdRecords; + if (NULL != oPivotCachesTemp.pRecords) + { + NSCommon::smart_ptr pFileRecords(oPivotCachesTemp.pRecords); + if(m_pXlsb) + pFileRecords->OOX::File::m_pMainDocument = m_pXlsb; + srIdRecords = pDefinitionFile->Add(pFileRecords).ToString(); + } + pDefinitionFile->setData(oPivotCachesTemp.pDefinitionData, oPivotCachesTemp.nDefinitionLength, L""); + + NSCommon::smart_ptr pFile(pDefinitionFile); + OOX::RId rIdDefinition = m_oWorkbook.Add(pFile); + if(!m_pXlsb) + { + m_oWorkbook.m_oPivotCachesXml->append(L"append(std::to_wstring(oPivotCachesTemp.nId)); + m_oWorkbook.m_oPivotCachesXml->append(L"\" r:id=\""); + m_oWorkbook.m_oPivotCachesXml->append(rIdDefinition.ToString()); + m_oWorkbook.m_oPivotCachesXml->append(L"\"/>"); + } + else + { auto bookPivotCache = new OOX::Spreadsheet::CWorkbookPivotCache; + bookPivotCache->m_oCacheId = (_UINT32)oPivotCachesTemp.nId; + bookPivotCache->m_oRid = rIdDefinition.ToString(); + if(!m_oWorkbook.m_oPivotCaches.IsInit()) + m_oWorkbook.m_oPivotCaches.Init(); + m_oWorkbook.m_oPivotCaches->m_arrItems.push_back(bookPivotCache); + } + m_mapPivotCacheDefinitions[oPivotCachesTemp.nId] = pFile; + } + else + { + RELEASEOBJECT(oPivotCachesTemp.pRecords); + } + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadPivotCache(BYTE type, long length, void* poResult) +{ + PivotCachesTemp* pPivotCachesTemp = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_PivotTypes::id == type) + { + pPivotCachesTemp->nId = m_oBufferedStream.GetLong(); + } + else if (c_oSer_PivotTypes::cache == type) + { + pPivotCachesTemp->pDefinitionData = m_oBufferedStream.GetPointer(length); + pPivotCachesTemp->nDefinitionLength = length; + } + else if (c_oSer_PivotTypes::record == type) + { + pPivotCachesTemp->pRecords = new OOX::Spreadsheet::CPivotCacheRecordsFile(NULL); + pPivotCachesTemp->pRecords->setData(m_oBufferedStream.GetPointer(length), length); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadSlicerCaches(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CSlicerCaches* pSlicerCaches = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerWorkbookTypes::SlicerCache == type) + { + OOX::Spreadsheet::CSlicerCacheFile* pSlicerCache = new OOX::Spreadsheet::CSlicerCacheFile(NULL); + if(m_pXlsb) + pSlicerCache->OOX::File::m_pMainDocument = m_pXlsb; + pSlicerCache->m_oSlicerCacheDefinition.Init(); + + m_oBufferedStream.GetUChar();//type + pSlicerCache->m_oSlicerCacheDefinition->fromPPTY(&m_oBufferedStream); + + NSCommon::smart_ptr pSlicerCacheFile(pSlicerCache); + const OOX::RId oRId = m_oWorkbook.Add(pSlicerCacheFile); + + pSlicerCaches->m_oSlicerCache.emplace_back(); + pSlicerCaches->m_oSlicerCache.back().m_oRId.Init(); + pSlicerCaches->m_oSlicerCache.back().m_oRId->SetValue(oRId.get()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadTimelineCaches(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CTimelineCacheRefs* pTimelineCacheRefs = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerWorkbookTypes::TimelineCache == type) + { + OOX::Spreadsheet::CTimelineCacheFile* pTimelineCacheFile = new OOX::Spreadsheet::CTimelineCacheFile(NULL); + pTimelineCacheFile->m_oTimelineCacheDefinition.Init(); + + READ1_DEF(length, res, this->ReadTimelineCache, pTimelineCacheFile->m_oTimelineCacheDefinition.GetPointer()); + + NSCommon::smart_ptr pFile(pTimelineCacheFile); + const OOX::RId oRId = m_oWorkbook.Add(pFile); + + OOX::Spreadsheet::CTimelineCacheRef* pTimelineCacheRef = new OOX::Spreadsheet::CTimelineCacheRef(); + pTimelineCacheRef->m_oRId.Init(); + pTimelineCacheRef->m_oRId->SetValue(oRId.get()); + + pTimelineCacheRefs->m_arrItems.push_back(pTimelineCacheRef); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadTimelineCache(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CTimelineCacheDefinition* pTimelineCache = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_TimelineCache::Name == type) + { + pTimelineCache->m_oName = m_oBufferedStream.GetString3(length); + } + else if (c_oSer_TimelineCache::SourceName == type) + { + pTimelineCache->m_oSourceName = m_oBufferedStream.GetString3(length); + } + else if (c_oSer_TimelineCache::Uid == type) + { + pTimelineCache->m_oUid = m_oBufferedStream.GetString3(length); + } + else if (c_oSer_TimelineCache::PivotTables == type) + { + pTimelineCache->m_oPivotTables.Init(); + READ1_DEF(length, res, this->ReadTimelineCachePivotTables, pTimelineCache->m_oPivotTables.GetPointer()); + } + else if (c_oSer_TimelineCache::State == type) + { + pTimelineCache->m_oState.Init(); + READ1_DEF(length, res, this->ReadTimelineState, pTimelineCache->m_oState.GetPointer()); + } + else if (c_oSer_TimelineCache::PivotFilter == type) + { + pTimelineCache->m_oPivotFilter.Init(); + READ1_DEF(length, res, this->ReadTimelinePivotFilter, pTimelineCache->m_oPivotFilter.GetPointer()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadTimelineCachePivotTables(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CTimelineCachePivotTables* pPivotTables = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + + if (c_oSer_TimelineCache::PivotTable == type) + { + OOX::Spreadsheet::CTimelineCachePivotTable* pPivotTable = new OOX::Spreadsheet::CTimelineCachePivotTable(); + READ2_DEF_SPREADSHEET(length, res, this->ReadTimelineCachePivotTable, pPivotTable); + pPivotTables->m_arrItems.push_back(pPivotTable); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadTimelineState(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CTimelineState* pState = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + + if (c_oSer_TimelineState::Name == type) + { + pState->m_oName = m_oBufferedStream.GetString3(length); + } + else if (c_oSer_TimelineState::FilterState == type) + { + pState->m_oSingleRangeFilterState = m_oBufferedStream.GetBool(); + } + else if (c_oSer_TimelineState::PivotCacheId == type) + { + pState->m_oPivotCacheId = m_oBufferedStream.GetLong(); + } + else if (c_oSer_TimelineState::MinimalRefreshVersion == type) + { + pState->m_oMinimalRefreshVersion = m_oBufferedStream.GetLong(); + } + else if (c_oSer_TimelineState::LastRefreshVersion == type) + { + pState->m_oLastRefreshVersion = m_oBufferedStream.GetLong(); + } + else if (c_oSer_TimelineState::FilterType == type) + { + pState->m_oFilterType = m_oBufferedStream.GetString3(length); + } + else if (c_oSer_TimelineState::Selection == type) + { + pState->m_oSelection.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadTimelineRange, pState->m_oSelection.GetPointer()); + } + else if (c_oSer_TimelineState::Bounds == type) + { + pState->m_oBounds.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadTimelineRange, pState->m_oBounds.GetPointer()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadTimelineRange(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CTimelineRange* pTimelineRange = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + + if (c_oSer_TimelineRange::StartDate == type) + { + pTimelineRange->m_oStartDate = m_oBufferedStream.GetString3(length); + } + else if (c_oSer_TimelineRange::EndDate == type) + { + pTimelineRange->m_oEndDate = m_oBufferedStream.GetString3(length); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadTimelinePivotFilter(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CTimelinePivotFilter* pPivotFilter = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + + if (c_oSer_TimelinePivotFilter::Name == type) + { + pPivotFilter->m_oName = m_oBufferedStream.GetString3(length); + } + else if (c_oSer_TimelinePivotFilter::Description == type) + { + pPivotFilter->m_oDescription = m_oBufferedStream.GetString3(length); + } + else if (c_oSer_TimelinePivotFilter::UseWholeDay == type) + { + pPivotFilter->m_oUseWholeDay = m_oBufferedStream.GetBool(); + } + else if (c_oSer_TimelinePivotFilter::Id == type) + { + pPivotFilter->m_oId = m_oBufferedStream.GetLong(); + } + else if (c_oSer_TimelinePivotFilter::Fld == type) + { + pPivotFilter->m_oFld = m_oBufferedStream.GetLong(); + } + else if (c_oSer_TimelinePivotFilter::AutoFilter == type) + { + pPivotFilter->m_oAutoFilter.Init(); + BinaryTableReader oBinaryTableReader(m_oBufferedStream, NULL); + READ1_DEF(length, res, oBinaryTableReader.ReadAutoFilter, pPivotFilter->m_oAutoFilter.GetPointer()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadTimelineCachePivotTable(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CTimelineCachePivotTable* pPivotTable = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + + if (c_oSer_TimelineCachePivotTable::Name == type) + { + pPivotTable->m_oName = m_oBufferedStream.GetString3(length); + } + else if (c_oSer_TimelineCachePivotTable::TabId == type) + { + pPivotTable->m_oTabId = m_oBufferedStream.GetLong(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +BinaryCommentReader::BinaryCommentReader(NSBinPptxRW::CBinaryFileReader& oBufferedStream, OOX::Spreadsheet::CWorksheet* pCurWorksheet) + : Binary_CommonReader(oBufferedStream), m_pCurWorksheet(pCurWorksheet) +{ +} +int BinaryCommentReader::Read(long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + READ1_DEF(length, res, this->ReadComments, poResult); + return res; +} +int BinaryCommentReader::ReadExternal(long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + READ1_DEF(length, res, this->ReadCommentDatasExternal, poResult); + return res; +} +int BinaryCommentReader::ReadCommentDatasExternal(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + std::vector* pCommentDatas = static_cast*>(poResult); + if ( c_oSer_Comments::CommentData == type ) + { + SerializeCommon::CommentData* oCommentData = new SerializeCommon::CommentData(); + READ1_DEF(length, res, this->ReadCommentData, oCommentData); + pCommentDatas->push_back(oCommentData); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryCommentReader::ReadComments(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + if (c_oSerWorksheetsTypes::Comment == type) + { + OOX::Spreadsheet::CCommentItem* pNewComment = new OOX::Spreadsheet::CCommentItem(); + READ2_DEF_SPREADSHEET(length, res, this->ReadComment, pNewComment); + + if (NULL != m_pCurWorksheet && pNewComment->IsValid()) + { + std::wstring sId = std::to_wstring(pNewComment->m_nRow.get()) + L"-" + std::to_wstring(pNewComment->m_nCol.get()); + m_pCurWorksheet->m_mapComments [sId] = pNewComment; + } + else + RELEASEOBJECT(pNewComment); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryCommentReader::ReadComment(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CCommentItem* pNewComment = static_cast(poResult); + if ( c_oSer_Comments::Row == type ) + pNewComment->m_nRow = m_oBufferedStream.GetLong(); + else if ( c_oSer_Comments::Col == type ) + pNewComment->m_nCol = m_oBufferedStream.GetLong(); + else if ( c_oSer_Comments::CommentDatas == type ) + { + if (!pNewComment->m_sGfxdata.IsInit()) + { + int nStartPos = m_oBufferedStream.GetPos(); + BYTE* pSourceBuffer = m_oBufferedStream.GetPointer(length); + m_oBufferedStream.Seek(nStartPos); + + std::string sSignature("XLS2"); + int nSignatureSize = (int)sSignature.length(); + int nDataLengthSize = sizeof(_INT32); + int nJunkSize = 2; + int nWriteBufferLength = nSignatureSize + nDataLengthSize + length + nJunkSize; + + BYTE* pWriteBuffer = new BYTE[nWriteBufferLength]; + memcpy(pWriteBuffer, sSignature.c_str(), nSignatureSize); + + *((_INT32*)(pWriteBuffer + nSignatureSize)) = (_INT32)length; + memcpy(pWriteBuffer + nSignatureSize + nDataLengthSize, pSourceBuffer, length); + //пишем в конце 0, потому что при редактировании Excel меняет посление байты. + memset(pWriteBuffer + nSignatureSize + nDataLengthSize + length, 0, nJunkSize); + + int nBase64BufferLen = Base64::Base64EncodeGetRequiredLength(nWriteBufferLength, Base64::B64_BASE64_FLAG_NONE); + BYTE* pbBase64Buffer = new BYTE[nBase64BufferLen+64]; + std::wstring sGfxdata; +// if (true == Base64::Base64Encode(pWriteBuffer, nWriteBufferLength, (LPSTR)pbBase64Buffer, &nBase64BufferLen, Base64::B64_BASE64_FLAG_NONE)) + if (true == Base64_1::Base64Encode(pWriteBuffer, nWriteBufferLength, pbBase64Buffer, &nBase64BufferLen)) + { + std::wstring strGfxdata = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(pbBase64Buffer, nBase64BufferLen); + sGfxdata = std::wstring(strGfxdata.c_str()); + //важно иначе при редактировании и сохранении в Excel перетирается + sGfxdata += L"\r\n"; + } + RELEASEARRAYOBJECTS(pbBase64Buffer); + RELEASEARRAYOBJECTS(pWriteBuffer); + + if (!sGfxdata.empty()) + { + pNewComment->m_sGfxdata = sGfxdata; + } + } + READ1_DEF(length, res, this->ReadCommentDatas, pNewComment); + } + else if ( c_oSer_Comments::Left == type ) + pNewComment->m_nLeft = abs(m_oBufferedStream.GetLong()); + else if ( c_oSer_Comments::Top == type ) + pNewComment->m_nTop = abs(m_oBufferedStream.GetLong()); + else if ( c_oSer_Comments::Right == type ) + pNewComment->m_nRight = abs( m_oBufferedStream.GetLong()); + else if ( c_oSer_Comments::Bottom == type ) + pNewComment->m_nBottom = abs(m_oBufferedStream.GetLong()); + else if ( c_oSer_Comments::LeftOffset == type ) + pNewComment->m_nLeftOffset = abs(m_oBufferedStream.GetLong()); + else if ( c_oSer_Comments::TopOffset == type ) + pNewComment->m_nTopOffset = abs(m_oBufferedStream.GetLong()); + else if ( c_oSer_Comments::RightOffset == type ) + pNewComment->m_nRightOffset = abs(m_oBufferedStream.GetLong()); + else if ( c_oSer_Comments::BottomOffset == type ) + pNewComment->m_nBottomOffset = abs(m_oBufferedStream.GetLong()); + else if ( c_oSer_Comments::LeftMM == type ) + pNewComment->m_dLeftMM = m_oBufferedStream.GetDoubleReal(); + else if ( c_oSer_Comments::TopMM == type ) + pNewComment->m_dTopMM = m_oBufferedStream.GetDoubleReal(); + else if ( c_oSer_Comments::WidthMM == type ) + pNewComment->m_dWidthMM = m_oBufferedStream.GetDoubleReal(); + else if ( c_oSer_Comments::HeightMM == type ) + pNewComment->m_dHeightMM = m_oBufferedStream.GetDoubleReal(); + else if ( c_oSer_Comments::MoveWithCells == type ) + pNewComment->m_bMove = m_oBufferedStream.GetBool(); + else if ( c_oSer_Comments::SizeWithCells == type ) + pNewComment->m_bSize = m_oBufferedStream.GetBool(); + else if ( c_oSer_Comments::ThreadedComment == type ) + { + pNewComment->m_pThreadedComment = new OOX::Spreadsheet::CThreadedComment(); + READ1_DEF(length, res, this->ReadThreadedComment, pNewComment->m_pThreadedComment); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryCommentReader::ReadCommentDatas(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CCommentItem* pNewComment = static_cast(poResult); + if ( c_oSer_Comments::CommentData == type ) + { + if (!pNewComment->m_oText.IsInit()) + { + SerializeCommon::CommentData oCommentData; + READ1_DEF(length, res, this->ReadCommentData, &oCommentData); + pNewComment->m_sAuthor = oCommentData.sUserName; + pNewComment->m_oText.Init(); + parseCommentData(&oCommentData, pNewComment->m_oText.get2()); + } + else + res = c_oSerConstants::ReadUnknown; + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryCommentReader::ReadCommentData(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + SerializeCommon::CommentData* pComments = static_cast(poResult); + if ( c_oSer_CommentData::Text == type ) + pComments->sText = m_oBufferedStream.GetString4(length); + else if ( c_oSer_CommentData::Time == type ) + pComments->sTime = m_oBufferedStream.GetString4(length); + else if ( c_oSer_CommentData::OOTime == type ) + pComments->sOOTime = m_oBufferedStream.GetString4(length); + else if ( c_oSer_CommentData::UserId == type ) + pComments->sUserId = m_oBufferedStream.GetString4(length); + else if ( c_oSer_CommentData::UserName == type ) + pComments->sUserName = m_oBufferedStream.GetString4(length); + else if ( c_oSer_CommentData::QuoteText == type ) + pComments->sQuoteText = m_oBufferedStream.GetString4(length); + else if ( c_oSer_CommentData::Guid == type ) + pComments->sGuid = m_oBufferedStream.GetString4(length); + else if ( c_oSer_CommentData::Solved == type ) + { + pComments->bSolved = true; + pComments->Solved = m_oBufferedStream.GetBool(); + } + else if ( c_oSer_CommentData::Document == type ) + { + pComments->bDocument = true; + pComments->Document = m_oBufferedStream.GetBool(); + } + else if ( c_oSer_CommentData::UserData == type ) + { + pComments->sUserData = m_oBufferedStream.GetString4(length); + } + else if ( c_oSer_CommentData::Replies == type ) { + READ1_DEF(length, res, this->ReadCommentReplies, &pComments->aReplies); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryCommentReader::ReadCommentReplies(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + std::vector* pComments = static_cast*>(poResult); + if ( c_oSer_CommentData::Reply == type ) + { + SerializeCommon::CommentData* pCommentData = new SerializeCommon::CommentData(); + READ1_DEF(length, res, this->ReadCommentData, pCommentData); + pComments->push_back(pCommentData); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryCommentReader::ReadThreadedComment(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CThreadedComment* pThreadedComment = static_cast(poResult); + if ( c_oSer_ThreadedComment::dT == type ) + { + pThreadedComment->dT = m_oBufferedStream.GetString3(length); + } + else if ( c_oSer_ThreadedComment::personId == type ) + { + pThreadedComment->personId = m_oBufferedStream.GetString3(length); + } + else if ( c_oSer_ThreadedComment::id == type ) + { + pThreadedComment->id = m_oBufferedStream.GetString3(length); + } + else if ( c_oSer_ThreadedComment::done == type ) + { + pThreadedComment->done = m_oBufferedStream.GetBool(); + } + else if ( c_oSer_ThreadedComment::text == type ) + { + pThreadedComment->m_oText.Init(); + pThreadedComment->m_oText->m_sText = m_oBufferedStream.GetString3(length); + } + else if ( c_oSer_ThreadedComment::mention == type ) + { + OOX::Spreadsheet::CThreadedCommentMention* pMention = new OOX::Spreadsheet::CThreadedCommentMention(); + READ1_DEF(length, res, this->ReadThreadedCommentMention, pMention); + if (!pThreadedComment->m_oMentions.IsInit()) + { + pThreadedComment->m_oMentions.Init(); + } + pThreadedComment->m_oMentions->m_arrItems.push_back(pMention); + } + else if ( c_oSer_ThreadedComment::reply == type ) + { + OOX::Spreadsheet::CThreadedComment* pReply = new OOX::Spreadsheet::CThreadedComment(); + READ1_DEF(length, res, this->ReadThreadedComment, pReply); + pThreadedComment->m_arrReplies.push_back(pReply); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryCommentReader::ReadThreadedCommentMention(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CThreadedCommentMention* pMention = static_cast(poResult); + if ( c_oSer_ThreadedComment::mentionpersonId == type ) + { + pMention->mentionpersonId = m_oBufferedStream.GetString3(length); + } + else if ( c_oSer_ThreadedComment::mentionId == type ) + { + pMention->mentionId = m_oBufferedStream.GetString3(length); + } + else if ( c_oSer_ThreadedComment::startIndex == type ) + { + pMention->startIndex.Init(); + pMention->startIndex->SetValue(m_oBufferedStream.GetULong()); + } + else if ( c_oSer_ThreadedComment::length == type ) + { + pMention->length.Init(); + pMention->length->SetValue(m_oBufferedStream.GetULong()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +void BinaryCommentReader::parseCommentData(SerializeCommon::CommentData* pCommentData, OOX::Spreadsheet::CSi& oSi) +{ + if (NULL != pCommentData && false == pCommentData->sText.empty()) + { + int nLimit = OOX::Spreadsheet::SpreadsheetCommon::MAX_STRING_LEN; + if (pCommentData->sUserName.empty()) + { + nLimit = addCommentRun(oSi, pCommentData->sText, false, nLimit); + } + else + { + nLimit = addCommentRun(oSi, pCommentData->sUserName + _T(":"), true, nLimit); + if (nLimit <= 0) + return; + nLimit = addCommentRun(oSi, _T("\n") + pCommentData->sText, false, nLimit); + } + } +} +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(); + OOX::Spreadsheet::CRPr& pRPr = pRun->m_oRPr.get2(); + if (isBold) + { + pRPr.m_oBold.Init(); + pRPr.m_oBold->m_oVal.FromBool(true); + } + pRPr.m_oRFont.Init(); + pRPr.m_oRFont->m_sVal = L"Tahoma"; + pRPr.m_oSz.Init(); + pRPr.m_oSz->m_oVal.Init(); + pRPr.m_oSz->m_oVal->SetValue(9); + + OOX::Spreadsheet::CText* pText = new OOX::Spreadsheet::CText(); + //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, nullable>& mapPersonList) +{ + int nLimit = OOX::Spreadsheet::SpreadsheetCommon::MAX_STRING_LEN; + if (pThreadedComment->m_oText.IsInit()) + { + 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()) + { + 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; + } + } +} +std::wstring BinaryCommentReader::getThreadedCommentAuthor(nullable>& mapPersonList, nullable& personId, const std::wstring& sDefault) +{ + if (mapPersonList.IsInit() && personId.IsInit()) + { + std::unordered_map::iterator it = mapPersonList->find(personId->ToString()); + if (it != mapPersonList->end()) + { + if (it->second->displayName.IsInit()) + { + return it->second->displayName.get(); + } + } + } + return sDefault; +} + +BinaryWorksheetsTableReader::BinaryWorksheetsTableReader(NSBinPptxRW::CBinaryFileReader& oBufferedStream, OOX::Spreadsheet::CWorkbook& oWorkbook, + OOX::Spreadsheet::CSharedStrings* pSharedStrings, std::vector& arWorksheets, std::map& mapWorksheets, + boost::unordered_map& mapMedia, const std::wstring& sDestinationDir, const std::wstring& sMediaDir, SaveParams& oSaveParams, + NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter, boost::unordered_map>& mapPivotCacheDefinitions) + +: Binary_CommonReader(oBufferedStream), m_oWorkbook(oWorkbook), m_oBcr2(oBufferedStream), m_sMediaDir(sMediaDir), m_oSaveParams(oSaveParams), +m_mapMedia(mapMedia), m_sDestinationDir(sDestinationDir), m_arWorksheets(arWorksheets), m_mapWorksheets(mapWorksheets), m_pSharedStrings(pSharedStrings),m_mapPivotCacheDefinitions(mapPivotCacheDefinitions) +{ + m_pOfficeDrawingConverter = pOfficeDrawingConverter; + m_nNextObjectId = 0xfffff; // в CDrawingConverter своя нумерация .. + m_lObjectIdVML = 1024; +} +int BinaryWorksheetsTableReader::Read() +{ + m_oWorkbook.m_oSheets.Init(); + int res = c_oSerConstants::ReadOk; + READ_TABLE_DEF(res, this->ReadWorksheetsTableContent, this); + return res; +} +int BinaryWorksheetsTableReader::Read2xlsb(OOX::Spreadsheet::CXlsb &xlsb) +{ + m_pXlsb = &xlsb; + int res = c_oSerConstants::ReadOk; + //читаем листы для получения их имен и названий таблиц(используется в формулах) + auto worksheetsPos = m_oBufferedStream.GetPos(); + READ_TABLE_DEF(res, this->ReadWorksheetsCache, this); + m_oWorkbook.m_oSheets->m_arrItems.resize(0); + m_oBufferedStream.Seek(worksheetsPos); + + READ_TABLE_DEF(res, this->ReadWorksheetsTableContent, this); + return res; +} +int BinaryWorksheetsTableReader::ReadWorksheetsTableContent(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + if (c_oSerWorksheetsTypes::Worksheet == type) + { + m_pCurWorksheet.reset( new OOX::Spreadsheet::CWorksheet(NULL) ); + m_pCurSheet.reset(new OOX::Spreadsheet::CSheet()); + m_pCurVmlDrawing.reset(new OOX::CVmlDrawing(NULL, false)); + m_pCurDrawing.reset(new OOX::Spreadsheet::CDrawing(NULL)); + m_pCurOleObjects.reset(new OOX::Spreadsheet::COleObjects()); + + m_lObjectIdVML += 1024; + m_pCurVmlDrawing->m_lObjectIdVML = m_lObjectIdVML; + + boost::unordered_map> mapPos; + READ1_DEF(length, res, this->ReadWorksheetSeekPositions, &mapPos); + m_pCurWorksheet->m_bWriteDirectlyToFile = true; + + smart_ptr oCurWorksheetFile = m_pCurWorksheet.smart_dynamic_cast(); + //for correct file extension + if(m_bWriteToXlsb) + { + oCurWorksheetFile->m_pMainDocument = m_pXlsb; + } + m_oWorkbook.AssignOutputFilename(oCurWorksheetFile); + + std::wstring sWsPath = m_sDestinationDir + FILE_SEPARATOR_STR + _T("xl") + FILE_SEPARATOR_STR + m_pCurWorksheet->DefaultDirectory().GetPath(); + NSDirectory::CreateDirectories(sWsPath); + sWsPath += FILE_SEPARATOR_STR + m_pCurWorksheet->m_sOutputFilename; + if(!m_bWriteToXlsb) + { + NSFile::CStreamWriter oStreamWriter; + oStreamWriter.CreateFileW(sWsPath); + + m_pCurStreamWriter = &oStreamWriter; + res = ReadWorksheet(mapPos, oStreamWriter, poResult); + oStreamWriter.CloseFile(); + } + else + { + auto streamWriter = m_pXlsb->GetFileWriter(sWsPath); + m_pCurStreamWriterBin = streamWriter; + res = ReadWorksheet(mapPos, streamWriter, poResult); + m_pXlsb->WriteSreamCache(streamWriter); + } + if (m_pCurSheet->m_oName.IsInit()) + { + const OOX::RId oRId = m_oWorkbook.Add(oCurWorksheetFile); + m_pCurSheet->m_oRid.Init(); + m_pCurSheet->m_oRid->SetValue(oRId.get()); + + m_arWorksheets.push_back(m_pCurWorksheet.GetPointer()); m_pCurWorksheet.AddRef(); + m_mapWorksheets [m_pCurSheet->m_oName.get()] = m_pCurWorksheet.GetPointer(); //for csv + if(!m_oWorkbook.m_oSheets.IsInit()) + m_oWorkbook.m_oSheets.Init(); + m_oWorkbook.m_oSheets->m_arrItems.push_back(m_pCurSheet.GetPointer()); m_pCurSheet.AddRef(); + } + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadWorksheetsCache(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + if (c_oSerWorksheetsTypes::Worksheet == type) + { + m_pCurSheet.reset(new OOX::Spreadsheet::CSheet()); + boost::unordered_map> mapPos; + READ1_DEF(length, res, this->ReadWorksheetSeekPositions, &mapPos); + ReadSheetCache(mapPos, poResult); + m_pCurSheet.Release(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadWorksheetSeekPositions(BYTE type, long length, void* poResult) +{ + boost::unordered_map>* mapPos = static_cast>*>(poResult); + boost::unordered_map>::iterator pFind = mapPos->find(type); + + if (pFind != mapPos->end()) + { + pFind->second.push_back(m_oBufferedStream.GetPos()); + pFind->second.push_back(length); + } + else + { + std::vector data; + data.push_back(m_oBufferedStream.GetPos()); + data.push_back(length); + (*mapPos)[type] = data; + } + return c_oSerConstants::ReadUnknown; +} +int BinaryWorksheetsTableReader::ReadWorksheet(boost::unordered_map>& mapPos, NSFile::CStreamWriter& oStreamWriter, void* poResult) +{ + m_pCurWorksheet->toXMLStart(oStreamWriter); + LONG nOldPos = m_oBufferedStream.GetPos(); +//------------------------------------------------------------------------------------------------------------- + int res = c_oSerConstants::ReadOk; + boost::unordered_map>::iterator pFind; + LONG nPos; + LONG length; +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::SheetPr); + OOX::Spreadsheet::CSheetPr oSheetPr; + READ1_DEF(length, res, this->ReadSheetPr, &oSheetPr); + SEEK_TO_POS_END(oSheetPr); +//------------------------------------------------------------------------------------------------------------- + m_pCurWorksheet->m_oSheetViews.Init(); + SEEK_TO_POS_START(c_oSerWorksheetsTypes::SheetViews); + READ1_DEF(length, res, this->ReadSheetViews, m_pCurWorksheet->m_oSheetViews.GetPointer()); + SEEK_TO_POS_END2(); + if (m_pCurWorksheet->m_oSheetViews->m_arrItems.empty()) + m_pCurWorksheet->m_oSheetViews->m_arrItems.push_back(new OOX::Spreadsheet::CSheetView()); + OOX::Spreadsheet::CSheetView* pSheetView = m_pCurWorksheet->m_oSheetViews->m_arrItems.front(); + if (false == pSheetView->m_oWorkbookViewId.IsInit()) + { + pSheetView->m_oWorkbookViewId.Init(); + pSheetView->m_oWorkbookViewId->SetValue(0); + } + m_pCurWorksheet->m_oSheetViews->toXML(oStreamWriter); +//------------------------------------------------------------------------------------------------------------- + OOX::Spreadsheet::CSheetFormatPr oSheetFormatPr; + SEEK_TO_POS_START(c_oSerWorksheetsTypes::SheetFormatPr); + READ2_DEF_SPREADSHEET(length, res, this->ReadSheetFormatPr, &oSheetFormatPr); + SEEK_TO_POS_END2(); + if (!oSheetFormatPr.m_oDefaultRowHeight.IsInit()) + { + oSheetFormatPr.m_oDefaultRowHeight = 15.; + } + oSheetFormatPr.toXML(oStreamWriter); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::Cols); + OOX::Spreadsheet::CCols oCols; + READ1_DEF(length, res, this->ReadWorksheetCols, &oCols); + SEEK_TO_POS_END(oCols); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::SheetData) + if (NULL == m_oSaveParams.pCSVWriter) + { + OOX::Spreadsheet::CSheetData oSheetData; + oSheetData.toXMLStart(oStreamWriter); + READ1_DEF(length, res, this->ReadSheetData, NULL); + oSheetData.toXMLEnd(oStreamWriter); + } + else if (m_arWorksheets.size() == m_oWorkbook.GetActiveSheetIndex()) + { + m_oSaveParams.pCSVWriter->WriteSheetStart(m_pCurWorksheet.GetPointer()); + READ1_DEF(length, res, this->ReadSheetData, NULL); + m_oSaveParams.pCSVWriter->WriteSheetEnd(m_pCurWorksheet.GetPointer()); + } + SEEK_TO_POS_END2() + SEEK_TO_POS_ELSE() + OOX::Spreadsheet::CSheetData oSheetData; + oSheetData.toXMLStart(oStreamWriter); + oSheetData.toXMLEnd(oStreamWriter); + SEEK_TO_POS_ELSE_END() +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::Protection); + OOX::Spreadsheet::CSheetProtection oProtection; + READ2_DEF_SPREADSHEET(length, res, this->ReadProtection, &oProtection); + SEEK_TO_POS_END(oProtection); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::ProtectedRanges); + OOX::Spreadsheet::CProtectedRanges oProtectedRanges; + READ1_DEF(length, res, this->ReadProtectedRanges, &oProtectedRanges); + SEEK_TO_POS_END(oProtectedRanges); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::Autofilter); + OOX::Spreadsheet::CAutofilter oAutofilter; + BinaryTableReader oBinaryTableReader(m_oBufferedStream, m_pCurWorksheet.GetPointer()); + READ1_DEF(length, res, oBinaryTableReader.ReadAutoFilter, &oAutofilter); + SEEK_TO_POS_END(oAutofilter); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::SortState); + OOX::Spreadsheet::CSortState oSortState; + BinaryTableReader oBinaryTableReader(m_oBufferedStream, m_pCurWorksheet.GetPointer()); + READ1_DEF(length, res, oBinaryTableReader.ReadSortState, &oSortState); + SEEK_TO_POS_END(oSortState); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::MergeCells); + OOX::Spreadsheet::CMergeCells oMergeCells; + READ1_DEF(length, res, this->ReadMergeCells, &oMergeCells); + oMergeCells.m_oCount.Init(); + oMergeCells.m_oCount->SetValue((unsigned int)oMergeCells.m_arrItems.size()); + SEEK_TO_POS_END(oMergeCells); +//------------------------------------------------------------------------------------------------------------- + OOX::Drawing::COfficeArtExtension* pOfficeArtExtensionCF = new OOX::Drawing::COfficeArtExtension(); + + SEEK_TO_POS_START(c_oSerWorksheetsTypes::ConditionalFormatting); + OOX::Spreadsheet::CConditionalFormatting *pConditionalFormatting = new OOX::Spreadsheet::CConditionalFormatting(); + READ1_DEF(length, res, this->ReadConditionalFormatting, pConditionalFormatting); + + if (pConditionalFormatting->IsExtended()) + { + pOfficeArtExtensionCF->m_arrConditionalFormatting.push_back(pConditionalFormatting); + } + else + { + pConditionalFormatting->toXML(oStreamWriter); + delete pConditionalFormatting; + } + SEEK_TO_POS_END2(); + + if (pOfficeArtExtensionCF->m_arrConditionalFormatting.empty()) + { + delete pOfficeArtExtensionCF; + } + else + { + pOfficeArtExtensionCF->m_sUri = L"{78C0D931-6437-407d-A8EE-F0AAD7539E65}"; + pOfficeArtExtensionCF->m_sAdditionalNamespace = L"xmlns:x14=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/main\""; + + if (m_pCurWorksheet->m_oExtLst.IsInit() == false) + m_pCurWorksheet->m_oExtLst.Init(); + m_pCurWorksheet->m_oExtLst->m_arrExt.push_back(pOfficeArtExtensionCF); + } +//------------------------------------------------------------------------------------------------------------- + OOX::Spreadsheet::CDataValidations oDataValidations; + + SEEK_TO_POS_START(c_oSerWorksheetsTypes::DataValidations); + READ1_DEF(length, res, this->ReadDataValidations, &oDataValidations); + SEEK_TO_POS_END2(); + + OOX::Drawing::COfficeArtExtension* pOfficeArtExtensionDV = new OOX::Drawing::COfficeArtExtension(); + pOfficeArtExtensionDV->m_oDataValidations.Init(); + pOfficeArtExtensionDV->m_oDataValidations->m_oDisablePrompts = oDataValidations.m_oDisablePrompts; + pOfficeArtExtensionDV->m_oDataValidations->m_oXWindow = oDataValidations.m_oXWindow; + pOfficeArtExtensionDV->m_oDataValidations->m_oYWindow = oDataValidations.m_oYWindow; + + for (size_t i = 0; i < oDataValidations.m_arrItems.size(); ++i) + { + if ((oDataValidations.m_arrItems[i]) && (oDataValidations.m_arrItems[i]->IsExtended())) + { + pOfficeArtExtensionDV->m_oDataValidations->m_arrItems.push_back(oDataValidations.m_arrItems[i]); + oDataValidations.m_arrItems[i] = NULL; + } + } + size_t i = 0; + while(!oDataValidations.m_arrItems.empty() && i < oDataValidations.m_arrItems.size()) + { + if (oDataValidations.m_arrItems[i] == NULL) + oDataValidations.m_arrItems.erase(oDataValidations.m_arrItems.begin() + i, oDataValidations.m_arrItems.begin() + i + 1); + else + i++; + } + + pOfficeArtExtensionDV->m_oDataValidations->m_oCount = (int)pOfficeArtExtensionDV->m_oDataValidations->m_arrItems.size(); + oDataValidations.m_oCount = (int)oDataValidations.m_arrItems.size(); + + oDataValidations.toXML(oStreamWriter); + + if (pOfficeArtExtensionDV->m_oDataValidations->m_arrItems.empty()) + { + delete pOfficeArtExtensionDV; + } + else + { + pOfficeArtExtensionDV->m_sUri = L"{CCE6A557-97BC-4b89-ADB6-D9C93CAAB3DF}"; + pOfficeArtExtensionDV->m_sAdditionalNamespace = L"xmlns:x14=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/main\""; + + if (m_pCurWorksheet->m_oExtLst.IsInit() == false) + m_pCurWorksheet->m_oExtLst.Init(); + m_pCurWorksheet->m_oExtLst->m_arrExt.push_back(pOfficeArtExtensionDV); + } +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::Hyperlinks); + OOX::Spreadsheet::CHyperlinks oHyperlinks; + READ1_DEF(length, res, this->ReadHyperlinks, &oHyperlinks); + SEEK_TO_POS_END(oHyperlinks); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::PrintOptions); + OOX::Spreadsheet::CPrintOptions oPrintOptions; + READ2_DEF_SPREADSHEET(length, res, this->ReadPrintOptions, &oPrintOptions); + SEEK_TO_POS_END(oPrintOptions); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::PageMargins); + OOX::Spreadsheet::CPageMargins oPageMargins; + READ2_DEF_SPREADSHEET(length, res, this->ReadPageMargins, &oPageMargins); + SEEK_TO_POS_END(oPageMargins); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::PageSetup); + OOX::Spreadsheet::CPageSetup oPageSetup; + READ2_DEF_SPREADSHEET(length, res, this->ReadPageSetup, &oPageSetup); + SEEK_TO_POS_END(oPageSetup); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::HeaderFooter); + OOX::Spreadsheet::CHeaderFooter oHeaderFooter; + READ1_DEF(length, res, this->ReadHeaderFooter, &oHeaderFooter); + SEEK_TO_POS_END(oHeaderFooter); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::RowBreaks); + OOX::Spreadsheet::CRowColBreaks oRowBreaks; + READ1_DEF(length, res, this->ReadRowColBreaks, &oRowBreaks); + oRowBreaks.toXML2(oStreamWriter, L"rowBreaks"); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::ColBreaks); + OOX::Spreadsheet::CRowColBreaks oColBreaks; + READ1_DEF(length, res, this->ReadRowColBreaks, &oColBreaks); + oColBreaks.toXML2(oStreamWriter, L"colBreaks"); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::CellWatches); + OOX::Spreadsheet::CCellWatches oCellWatches; + READ1_DEF(length, res, this->ReadCellWatches, &oCellWatches); + oCellWatches.toXML(oStreamWriter); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + //important before Drawings + SEEK_TO_POS_START(c_oSerWorksheetsTypes::Comments); + BinaryCommentReader oBinaryCommentReader(m_oBufferedStream, m_pCurWorksheet.GetPointer()); + oBinaryCommentReader.Read(length, poResult); + WriteComments(); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::Drawings); + + m_pOfficeDrawingConverter->SetDstContentRels(); + READ1_DEF(length, res, this->ReadDrawings, m_pCurDrawing.GetPointer()); + + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + OOX::Spreadsheet::CControls oControls; + + SEEK_TO_POS_START(c_oSerWorksheetsTypes::Controls); + READ1_DEF(length, res, this->ReadControls, &oControls); + //SEEK_TO_POS_END(oControls); ниже ... + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + OOX::Spreadsheet::CUserProtectedRanges *pUserProtectedRanges = new OOX::Spreadsheet::CUserProtectedRanges(); + + SEEK_TO_POS_START(c_oSerWorksheetsTypes::UserProtectedRanges); + READ1_DEF(length, res, this->ReadUserProtectedRanges, pUserProtectedRanges); + SEEK_TO_POS_END2(); + + if (false == pUserProtectedRanges->m_arrItems.empty()) + { + if (m_pCurWorksheet->m_oExtLst.IsInit() == false) + m_pCurWorksheet->m_oExtLst.Init(); + + OOX::Drawing::COfficeArtExtension* pOfficeArtExtension = new OOX::Drawing::COfficeArtExtension(); + + pOfficeArtExtension->m_oUserProtectedRanges.reset(pUserProtectedRanges); + pOfficeArtExtension->m_sUri = L"{231B7EB2-2AFC-4442-B178-5FFDF5851E7C}"; + + m_pCurWorksheet->m_oExtLst->m_arrExt.push_back(pOfficeArtExtension); + } + else + { + delete pUserProtectedRanges; + } +//------------------------------------------------------------------------------------------------------------- + OOX::CPath pathDrawingsDir = m_sDestinationDir + FILE_SEPARATOR_STR + _T("xl") + FILE_SEPARATOR_STR + _T("drawings"); + OOX::CPath pathDrawingsRelsDir = pathDrawingsDir.GetPath() + FILE_SEPARATOR_STR + _T("_rels"); + + if (false == m_pCurDrawing->IsEmpty() || false == m_pCurVmlDrawing->IsEmpty()) + { + OOX::CSystemUtility::CreateDirectories(pathDrawingsDir.GetPath()); + OOX::CSystemUtility::CreateDirectories(pathDrawingsRelsDir.GetPath()); + } + + if (false == m_pCurDrawing->IsEmpty()) + { + NSCommon::smart_ptr pFile = m_pCurDrawing.smart_dynamic_cast(); + const OOX::RId oRId = m_pCurWorksheet->Add(pFile); + + OOX::Spreadsheet::CDrawingWorksheet oDrawingWorksheet; + oDrawingWorksheet.m_oId.Init(); + oDrawingWorksheet.m_oId->SetValue(oRId.get()); + oDrawingWorksheet.toXML(oStreamWriter); + + OOX::CPath pathDrawingsRels = pathDrawingsRelsDir.GetPath() + FILE_SEPARATOR_STR + m_pCurDrawing->m_sOutputFilename + _T(".rels"); + m_pOfficeDrawingConverter->SaveDstContentRels(pathDrawingsRels.GetPath()); + } +//------------------------------------------------------------------------------------------------------------- + if (false == m_pCurVmlDrawing->IsEmpty()) + { + NSCommon::smart_ptr pFile = m_pCurVmlDrawing.smart_dynamic_cast(); + const OOX::RId oRId = m_pCurWorksheet->Add(pFile); + OOX::Spreadsheet::CLegacyDrawingWorksheet oLegacyDrawing; + oLegacyDrawing.m_oId.Init(); + oLegacyDrawing.m_oId->SetValue(oRId.get()); + oLegacyDrawing.toXML(oStreamWriter); + } +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::LegacyDrawingHF); + OOX::Spreadsheet::CLegacyDrawingHFWorksheet oLegacyDrawingHF; + READ1_DEF(length, res, this->ReadLegacyDrawingHF, &oLegacyDrawingHF); + SEEK_TO_POS_END(oLegacyDrawingHF); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::Picture); + std::wstring sPicture = m_pOfficeDrawingConverter->m_pReader->m_strFolder + FILE_SEPARATOR_STR + _T("media") + FILE_SEPARATOR_STR + m_oBufferedStream.GetString4(length); + std::vector> additionalFiles; + NSBinPptxRW::_relsGeneratorInfo oRelsGeneratorInfo = m_pOfficeDrawingConverter->m_pReader->m_pRels->WriteImage(sPicture, additionalFiles, L"", L""); + + NSCommon::smart_ptr pImageFileWorksheet(new OOX::Image(NULL, false)); + pImageFileWorksheet->set_filename(oRelsGeneratorInfo.sFilepathImage, false); + smart_ptr pFileWorksheet = pImageFileWorksheet.smart_dynamic_cast(); + OOX::RId oRId = m_pCurWorksheet->Add(pFileWorksheet); + + OOX::Spreadsheet::CPictureWorksheet oPicture; + oPicture.m_oId.Init(); + oPicture.m_oId->SetValue(oRId.get()); + oPicture.toXML(oStreamWriter); + SEEK_TO_POS_END2(); + + if (false == m_pCurOleObjects->m_mapOleObjects.empty()) + { + m_pCurOleObjects->toXML(oStreamWriter); + } + + oControls.toXML(oStreamWriter); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::TableParts); + BinaryTableReader oBinaryTableReader(m_oBufferedStream, m_pCurWorksheet.GetPointer()); + OOX::Spreadsheet::CTableParts oTableParts; + oBinaryTableReader.Read(length, &oTableParts); + oTableParts.m_oCount.Init(); + oTableParts.m_oCount->SetValue((unsigned int)oTableParts.m_arrItems.size()); + SEEK_TO_POS_END(oTableParts); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::QueryTable); + BinaryTableReader oBinaryTableReader(m_oBufferedStream, m_pCurWorksheet.GetPointer()); + smart_ptr pQueryTableFile(new OOX::Spreadsheet::CQueryTableFile(NULL)); + pQueryTableFile->m_oQueryTable.Init(); + + oBinaryTableReader.ReadQueryTable(length, pQueryTableFile->m_oQueryTable.GetPointer()); + + smart_ptr oFile = pQueryTableFile.smart_dynamic_cast(); + m_pCurWorksheet->Add(oFile); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::SparklineGroups); + OOX::Drawing::COfficeArtExtension* pOfficeArtExtension = new OOX::Drawing::COfficeArtExtension(); + pOfficeArtExtension->m_oSparklineGroups.Init(); + + READ1_DEF(length, res, this->ReadSparklineGroups, pOfficeArtExtension->m_oSparklineGroups.GetPointer()); + + pOfficeArtExtension->m_sUri = L"{05C60535-1F16-4fd2-B633-F4F36F0B64E0}"; + pOfficeArtExtension->m_sAdditionalNamespace = L"xmlns:x14=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/main\""; + + if (m_pCurWorksheet->m_oExtLst.IsInit() == false) + m_pCurWorksheet->m_oExtLst.Init(); + m_pCurWorksheet->m_oExtLst->m_arrExt.push_back(pOfficeArtExtension); + + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::Slicers); + OOX::Drawing::COfficeArtExtension* pOfficeArtExtension = new OOX::Drawing::COfficeArtExtension(); + pOfficeArtExtension->m_oSlicerList.Init(); + READ1_DEF(length, res, this->ReadSlicers, pOfficeArtExtension->m_oSlicerList.GetPointer()); + + pOfficeArtExtension->m_sUri = L"{A8765BA9-456A-4dab-B4F3-ACF838C121DE}"; + pOfficeArtExtension->m_sAdditionalNamespace = L"xmlns:x14=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/main\""; + + if (m_pCurWorksheet->m_oExtLst.IsInit() == false) + m_pCurWorksheet->m_oExtLst.Init(); + m_pCurWorksheet->m_oExtLst->m_arrExt.push_back(pOfficeArtExtension); + SEEK_TO_POS_END2(); + + SEEK_TO_POS_START(c_oSerWorksheetsTypes::SlicersExt); + OOX::Drawing::COfficeArtExtension* pOfficeArtExtension = new OOX::Drawing::COfficeArtExtension(); + pOfficeArtExtension->m_oSlicerListExt.Init(); + READ1_DEF(length, res, this->ReadSlicers, pOfficeArtExtension->m_oSlicerListExt.GetPointer()); + + pOfficeArtExtension->m_sUri = L"{3A4CF648-6AED-40f4-86FF-DC5316D8AED3}"; + pOfficeArtExtension->m_sAdditionalNamespace = L"xmlns:x15=\"http://schemas.microsoft.com/office/spreadsheetml/2010/11/main\""; + + if (m_pCurWorksheet->m_oExtLst.IsInit() == false) + m_pCurWorksheet->m_oExtLst.Init(); + m_pCurWorksheet->m_oExtLst->m_arrExt.push_back(pOfficeArtExtension); + SEEK_TO_POS_END2(); + + SEEK_TO_POS_START(c_oSerWorksheetsTypes::TimelinesList); + OOX::Drawing::COfficeArtExtension* pOfficeArtExtension = new OOX::Drawing::COfficeArtExtension(); + pOfficeArtExtension->m_oTimelineRefs.Init(); + READ1_DEF(length, res, this->ReadTimelinesList, pOfficeArtExtension->m_oTimelineRefs.GetPointer()); + + pOfficeArtExtension->m_sUri = L"{7E03D99C-DC04-49d9-9315-930204A7B6E9}"; + pOfficeArtExtension->m_sAdditionalNamespace = L"xmlns:x15=\"http://schemas.microsoft.com/office/spreadsheetml/2010/11/main\""; + + if (m_pCurWorksheet->m_oExtLst.IsInit() == false) + m_pCurWorksheet->m_oExtLst.Init(); + m_pCurWorksheet->m_oExtLst->m_arrExt.push_back(pOfficeArtExtension); + SEEK_TO_POS_END2(); + + if (m_pCurWorksheet->m_oExtLst.IsInit()) + { + oStreamWriter.WriteString(m_pCurWorksheet->m_oExtLst->toXMLWithNS(L"")); + } +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::WorksheetProp); + READ2_DEF_SPREADSHEET(length, res, this->ReadWorksheetProp, poResult); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::PivotTable); + PivotCachesTemp oPivotCachesTemp; + + READ1_DEF(length, res, this->ReadPivotTable, &oPivotCachesTemp); + boost::unordered_map>::const_iterator pair = m_mapPivotCacheDefinitions.find(oPivotCachesTemp.nCacheId); + + if (m_mapPivotCacheDefinitions.end() != pair && NULL != oPivotCachesTemp.pTable) + { + NSCommon::smart_ptr pFileTable(oPivotCachesTemp.pTable); + oPivotCachesTemp.pTable->AddNoWrite(pair->second, L"../pivotCache"); + m_pCurWorksheet->Add(pFileTable); + } + else + { + RELEASEOBJECT(oPivotCachesTemp.pTable); + } + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::NamedSheetView); + smart_ptr pNamedSheetViewFile(new OOX::Spreadsheet::CNamedSheetViewFile(NULL)); + pNamedSheetViewFile->m_oNamedSheetViews.Init(); + pNamedSheetViewFile->m_oNamedSheetViews->fromPPTY(&m_oBufferedStream); + smart_ptr oFile = pNamedSheetViewFile.smart_dynamic_cast(); + m_pCurWorksheet->Add(oFile); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + m_oBufferedStream.Seek(nOldPos); + m_pCurWorksheet->toXMLEnd(oStreamWriter); + return res; +} +int BinaryWorksheetsTableReader::ReadWorksheet(boost::unordered_map>& mapPos, XLS::StreamCacheWriterPtr& oStreamWriter, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + { + auto beginSHeet = oStreamWriter->getNextRecord(XLSB::rt_BeginSheet); + oStreamWriter->storeNextRecord(beginSHeet); + } + boost::unordered_map>::iterator pFind; + LONG nPos; + LONG length; + LONG nOldPos = m_oBufferedStream.GetPos(); + //------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::WorksheetProp); + READ2_DEF_SPREADSHEET(length, res, this->ReadWorksheetProp, poResult); + SEEK_TO_POS_END2(); + //------------------------------------------------------------------------------------------------------------- + m_pCurWorksheet->m_oSheetViews.Init(); + SEEK_TO_POS_START(c_oSerWorksheetsTypes::SheetViews); + READ1_DEF(length, res, this->ReadSheetViews, m_pCurWorksheet->m_oSheetViews.GetPointer()); + SEEK_TO_POS_END2(); + if (m_pCurWorksheet->m_oSheetViews->m_arrItems.empty()) + m_pCurWorksheet->m_oSheetViews->m_arrItems.push_back(new OOX::Spreadsheet::CSheetView()); + OOX::Spreadsheet::CSheetView* pSheetView = m_pCurWorksheet->m_oSheetViews->m_arrItems.front(); + if (false == pSheetView->m_oWorkbookViewId.IsInit()) + { + pSheetView->m_oWorkbookViewId.Init(); + pSheetView->m_oWorkbookViewId->SetValue(0); + } + m_pCurWorksheet->m_oSheetViews->toBin(oStreamWriter); +//------------------------------------------------------------------------------------------------------------- + OOX::Spreadsheet::CSheetFormatPr oSheetFormatPr; + SEEK_TO_POS_START(c_oSerWorksheetsTypes::SheetFormatPr); + READ2_DEF_SPREADSHEET(length, res, this->ReadSheetFormatPr, &oSheetFormatPr); + SEEK_TO_POS_END2(); + if (!oSheetFormatPr.m_oDefaultRowHeight.IsInit()) + { + oSheetFormatPr.m_oDefaultRowHeight = 15.; + } + oSheetFormatPr.toBin(oStreamWriter); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::Cols); + OOX::Spreadsheet::CCols oCols; + READ1_DEF(length, res, this->ReadWorksheetCols, &oCols); + oCols.toBin(oStreamWriter); + SEEK_TO_POS_END2() +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::SheetData) + { + auto begin = m_pCurStreamWriterBin->getNextRecord(XLSB::rt_BeginSheetData); + m_pCurStreamWriterBin->storeNextRecord(begin); + } + READ1_DEF(length, res, this->ReadSheetData, NULL); + m_pCurWorksheet->m_oSheetData->ClearSharedFmlaRefs(); + { + auto end = m_pCurStreamWriterBin->getNextRecord(XLSB::rt_EndSheetData); + m_pCurStreamWriterBin->storeNextRecord(end); + } + SEEK_TO_POS_END2() +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::Protection); + OOX::Spreadsheet::CSheetProtection oProtection; + READ2_DEF_SPREADSHEET(length, res, this->ReadProtection, &oProtection); + oProtection.toBin(oStreamWriter); + SEEK_TO_POS_END2() +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::ProtectedRanges); + OOX::Spreadsheet::CProtectedRanges oProtectedRanges; + READ1_DEF(length, res, this->ReadProtectedRanges, &oProtectedRanges); + oProtectedRanges.toBin(oStreamWriter); + SEEK_TO_POS_END2() +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::Autofilter); + OOX::Spreadsheet::CAutofilter oAutofilter; + BinaryTableReader oBinaryTableReader(m_oBufferedStream, m_pCurWorksheet.GetPointer()); + READ1_DEF(length, res, oBinaryTableReader.ReadAutoFilter, &oAutofilter); + oAutofilter.toBin(oStreamWriter); + SEEK_TO_POS_END2() +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::SortState); + OOX::Spreadsheet::CSortState oSortState; + BinaryTableReader oBinaryTableReader(m_oBufferedStream, m_pCurWorksheet.GetPointer()); + READ1_DEF(length, res, oBinaryTableReader.ReadSortState, &oSortState); + oSortState.toBin(oStreamWriter); + SEEK_TO_POS_END2() +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::MergeCells); + OOX::Spreadsheet::CMergeCells oMergeCells; + READ1_DEF(length, res, this->ReadMergeCells, &oMergeCells); + oMergeCells.m_oCount.Init(); + oMergeCells.m_oCount->SetValue((unsigned int)oMergeCells.m_arrItems.size()); + oMergeCells.toBin(oStreamWriter); + SEEK_TO_POS_END2() +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::ConditionalFormatting); + OOX::Drawing::COfficeArtExtension* pOfficeArtExtensionCF = new OOX::Drawing::COfficeArtExtension(); + OOX::Spreadsheet::CConditionalFormatting *pConditionalFormatting = new OOX::Spreadsheet::CConditionalFormatting(); + READ1_DEF(length, res, this->ReadConditionalFormatting, pConditionalFormatting); + if (pConditionalFormatting->IsExtended()) + { + pOfficeArtExtensionCF->m_arrConditionalFormatting.push_back(pConditionalFormatting); + } + else + { + pConditionalFormatting->toBin(oStreamWriter); + delete pConditionalFormatting; + } + if (pOfficeArtExtensionCF->m_arrConditionalFormatting.empty()) + { + delete pOfficeArtExtensionCF; + } + else + { + pOfficeArtExtensionCF->m_sUri = L"{78C0D931-6437-407d-A8EE-F0AAD7539E65}"; + + if (m_pCurWorksheet->m_oExtLst.IsInit() == false) + m_pCurWorksheet->m_oExtLst.Init(); + m_pCurWorksheet->m_oExtLst->m_arrExt.push_back(pOfficeArtExtensionCF); + } + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::DataValidations); + OOX::Spreadsheet::CDataValidations oDataValidations; + READ1_DEF(length, res, this->ReadDataValidations, &oDataValidations); + oDataValidations.toBin(oStreamWriter); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::Hyperlinks); + OOX::Spreadsheet::CHyperlinks oHyperlinks; + READ1_DEF(length, res, this->ReadHyperlinks, &oHyperlinks); + oHyperlinks.toBin(oStreamWriter); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::PrintOptions); + OOX::Spreadsheet::CPrintOptions oPrintOptions; + READ2_DEF_SPREADSHEET(length, res, this->ReadPrintOptions, &oPrintOptions); + oPrintOptions.toBin(oStreamWriter); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::PageMargins); + OOX::Spreadsheet::CPageMargins oPageMargins; + READ2_DEF_SPREADSHEET(length, res, this->ReadPageMargins, &oPageMargins); + oPageMargins.toBin(oStreamWriter); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::PageSetup); + OOX::Spreadsheet::CPageSetup oPageSetup; + READ2_DEF_SPREADSHEET(length, res, this->ReadPageSetup, &oPageSetup); + oPageSetup.toBin(oStreamWriter); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::HeaderFooter); + OOX::Spreadsheet::CHeaderFooter oHeaderFooter; + READ1_DEF(length, res, this->ReadHeaderFooter, &oHeaderFooter); + oHeaderFooter.toBin(oStreamWriter); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::RowBreaks); + OOX::Spreadsheet::CRowColBreaks oRowBreaks; + READ1_DEF(length, res, this->ReadRowColBreaks, &oRowBreaks); + oRowBreaks.toBinRow(oStreamWriter); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::ColBreaks); + OOX::Spreadsheet::CRowColBreaks oColBreaks; + READ1_DEF(length, res, this->ReadRowColBreaks, &oColBreaks); + oColBreaks.toBinColumn(oStreamWriter); + SEEK_TO_POS_END2(); + +//------------------------------------------------------------------------------------------------------------- + //important before Drawings + SEEK_TO_POS_START(c_oSerWorksheetsTypes::Comments); + BinaryCommentReader oBinaryCommentReader(m_oBufferedStream, m_pCurWorksheet.GetPointer()); + oBinaryCommentReader.Read(length, poResult); + WriteComments(); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::Drawings); + + m_pOfficeDrawingConverter->SetDstContentRels(); + READ1_DEF(length, res, this->ReadDrawings, m_pCurDrawing.GetPointer()); + + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + OOX::Spreadsheet::CControls oControls; + + SEEK_TO_POS_START(c_oSerWorksheetsTypes::Controls); + READ1_DEF(length, res, this->ReadControls, &oControls); + //SEEK_TO_POS_END(oControls); ниже ... + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + OOX::CPath pathDrawingsDir = m_sDestinationDir + FILE_SEPARATOR_STR + _T("xl") + FILE_SEPARATOR_STR + _T("drawings"); + OOX::CPath pathDrawingsRelsDir = pathDrawingsDir.GetPath() + FILE_SEPARATOR_STR + _T("_rels"); + + if (false == m_pCurDrawing->IsEmpty() || false == m_pCurVmlDrawing->IsEmpty()) + { + OOX::CSystemUtility::CreateDirectories(pathDrawingsDir.GetPath()); + OOX::CSystemUtility::CreateDirectories(pathDrawingsRelsDir.GetPath()); + } + + if (false == m_pCurDrawing->IsEmpty()) + { + NSCommon::smart_ptr pFile = m_pCurDrawing.smart_dynamic_cast(); + const OOX::RId oRId = m_pCurWorksheet->Add(pFile); + + OOX::Spreadsheet::CDrawingWorksheet oDrawingWorksheet; + oDrawingWorksheet.m_oId.Init(); + oDrawingWorksheet.m_oId->SetValue(oRId.get()); + oDrawingWorksheet.toBin(oStreamWriter); + + OOX::CPath pathDrawingsRels = pathDrawingsRelsDir.GetPath() + FILE_SEPARATOR_STR + m_pCurDrawing->m_sOutputFilename + _T(".rels"); + m_pOfficeDrawingConverter->SaveDstContentRels(pathDrawingsRels.GetPath()); + } +//------------------------------------------------------------------------------------------------------------- + if (false == m_pCurVmlDrawing->IsEmpty()) + { + NSCommon::smart_ptr pFile = m_pCurVmlDrawing.smart_dynamic_cast(); + const OOX::RId oRId = m_pCurWorksheet->Add(pFile); + OOX::Spreadsheet::CLegacyDrawingWorksheet oLegacyDrawing; + oLegacyDrawing.m_oId.Init(); + oLegacyDrawing.m_oId->SetValue(oRId.get()); + oLegacyDrawing.toBin(oStreamWriter); + } +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::LegacyDrawingHF); + OOX::Spreadsheet::CLegacyDrawingHFWorksheet oLegacyDrawingHF; + READ1_DEF(length, res, this->ReadLegacyDrawingHF, &oLegacyDrawingHF); + oLegacyDrawingHF.toBin(oStreamWriter); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::Picture); + std::wstring sPicture = m_pOfficeDrawingConverter->m_pReader->m_strFolder + FILE_SEPARATOR_STR + _T("media") + FILE_SEPARATOR_STR + m_oBufferedStream.GetString4(length); + std::vector> additionalFiles; + NSBinPptxRW::_relsGeneratorInfo oRelsGeneratorInfo = m_pOfficeDrawingConverter->m_pReader->m_pRels->WriteImage(sPicture, additionalFiles, L"", L""); + + NSCommon::smart_ptr pImageFileWorksheet(new OOX::Image(NULL, false)); + pImageFileWorksheet->set_filename(oRelsGeneratorInfo.sFilepathImage, false); + smart_ptr pFileWorksheet = pImageFileWorksheet.smart_dynamic_cast(); + OOX::RId oRId = m_pCurWorksheet->Add(pFileWorksheet); + + OOX::Spreadsheet::CPictureWorksheet oPicture; + oPicture.m_oId.Init(); + oPicture.m_oId->SetValue(oRId.get()); + oPicture.toBin(oStreamWriter); + SEEK_TO_POS_END2(); + + if (false == m_pCurOleObjects->m_mapOleObjects.empty()) + { + m_pCurOleObjects->toBin(oStreamWriter); + } + + oControls.toBin(oStreamWriter); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::TableParts); + BinaryTableReader oBinaryTableReader(m_oBufferedStream, m_pCurWorksheet.GetPointer()); + OOX::Spreadsheet::CTableParts oTableParts; + oBinaryTableReader.Read(length, &oTableParts); + oTableParts.m_oCount.Init(); + oTableParts.m_oCount->SetValue((unsigned int)oTableParts.m_arrItems.size()); + oTableParts.toBin(oStreamWriter); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::QueryTable); + BinaryTableReader oBinaryTableReader(m_oBufferedStream, m_pCurWorksheet.GetPointer()); + smart_ptr pQueryTableFile(new OOX::Spreadsheet::CQueryTableFile(NULL)); + pQueryTableFile->m_oQueryTable.Init(); + + oBinaryTableReader.ReadQueryTable(length, pQueryTableFile->m_oQueryTable.GetPointer()); + + smart_ptr oFile = pQueryTableFile.smart_dynamic_cast(); + m_pCurWorksheet->Add(oFile); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::SparklineGroups); + OOX::Drawing::COfficeArtExtension* pOfficeArtExtension = new OOX::Drawing::COfficeArtExtension(); + pOfficeArtExtension->m_oSparklineGroups.Init(); + + READ1_DEF(length, res, this->ReadSparklineGroups, pOfficeArtExtension->m_oSparklineGroups.GetPointer()); + + pOfficeArtExtension->m_sUri = L"{05C60535-1F16-4fd2-B633-F4F36F0B64E0}"; + if (m_pCurWorksheet->m_oExtLst.IsInit() == false) + m_pCurWorksheet->m_oExtLst.Init(); + m_pCurWorksheet->m_oExtLst->m_arrExt.push_back(pOfficeArtExtension); + + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + SEEK_TO_POS_START(c_oSerWorksheetsTypes::Slicers); + OOX::Drawing::COfficeArtExtension* pOfficeArtExtension = new OOX::Drawing::COfficeArtExtension(); + pOfficeArtExtension->m_oSlicerList.Init(); + READ1_DEF(length, res, this->ReadSlicers, pOfficeArtExtension->m_oSlicerList.GetPointer()); + + pOfficeArtExtension->m_sUri = L"{A8765BA9-456A-4dab-B4F3-ACF838C121DE}"; + pOfficeArtExtension->m_sAdditionalNamespace = L"xmlns:x14=\"http://schemas.microsoft.com/office/spreadsheetml/2009/9/main\""; + + if (m_pCurWorksheet->m_oExtLst.IsInit() == false) + m_pCurWorksheet->m_oExtLst.Init(); + m_pCurWorksheet->m_oExtLst->m_arrExt.push_back(pOfficeArtExtension); + SEEK_TO_POS_END2(); + + SEEK_TO_POS_START(c_oSerWorksheetsTypes::SlicersExt); + OOX::Drawing::COfficeArtExtension* pOfficeArtExtension = new OOX::Drawing::COfficeArtExtension(); + pOfficeArtExtension->m_oSlicerListExt.Init(); + READ1_DEF(length, res, this->ReadSlicers, pOfficeArtExtension->m_oSlicerListExt.GetPointer()); + + pOfficeArtExtension->m_sUri = L"{3A4CF648-6AED-40f4-86FF-DC5316D8AED3}"; + pOfficeArtExtension->m_sAdditionalNamespace = L"xmlns:x15=\"http://schemas.microsoft.com/office/spreadsheetml/2010/11/main\""; + + if (m_pCurWorksheet->m_oExtLst.IsInit() == false) + m_pCurWorksheet->m_oExtLst.Init(); + m_pCurWorksheet->m_oExtLst->m_arrExt.push_back(pOfficeArtExtension); + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + if (m_pCurWorksheet->m_oExtLst.IsInit()) + { + auto extLst = m_pCurWorksheet->m_oExtLst->toBinWorksheet(); + extLst->write(oStreamWriter, nullptr); + } + SEEK_TO_POS_START(c_oSerWorksheetsTypes::PivotTable); + PivotCachesTemp oPivotCachesTemp; + + READ1_DEF(length, res, this->ReadPivotTable, &oPivotCachesTemp); + boost::unordered_map>::const_iterator pair = m_mapPivotCacheDefinitions.find(oPivotCachesTemp.nCacheId); + + if (m_mapPivotCacheDefinitions.end() != pair && NULL != oPivotCachesTemp.pTable) + { + NSCommon::smart_ptr pFileTable(oPivotCachesTemp.pTable); + if(m_pXlsb) + pFileTable->m_pMainDocument = m_pXlsb; + oPivotCachesTemp.pTable->AddNoWrite(pair->second, L"../pivotCache"); + m_pCurWorksheet->Add(pFileTable); + } + else + { + RELEASEOBJECT(oPivotCachesTemp.pTable); + } + SEEK_TO_POS_END2(); +//------------------------------------------------------------------------------------------------------------- + m_oBufferedStream.Seek(nOldPos); + { + auto endSheet = oStreamWriter->getNextRecord(XLSB::rt_EndSheet); + oStreamWriter->storeNextRecord(endSheet); + } + return res; +} +int BinaryWorksheetsTableReader::ReadSheetCache(boost::unordered_map>& mapPos, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + boost::unordered_map>::iterator pFind; + LONG nPos; + LONG length; + LONG nOldPos = m_oBufferedStream.GetPos(); + SEEK_TO_POS_START(c_oSerWorksheetsTypes::WorksheetProp); + READ2_DEF_SPREADSHEET(length, res, this->ReadWorksheetProp, poResult); + SEEK_TO_POS_END2(); + if(!m_oWorkbook.m_oSheets.IsInit()) + m_oWorkbook.m_oSheets.Init(); + if (m_pCurSheet->m_oName.IsInit()) + { + m_oWorkbook.m_oSheets->AddSheetRef(m_pCurSheet->m_oName.get(), m_oWorkbook.m_oSheets->m_arrItems.size()); + m_oWorkbook.m_oSheets->m_arrItems.push_back(m_pCurSheet.GetPointer()); + } + SEEK_TO_POS_START(c_oSerWorksheetsTypes::TableParts); + BinaryTableReader oBinaryTableReader(m_oBufferedStream, m_pCurWorksheet.GetPointer()); + OOX::Spreadsheet::CTableParts oTableParts; + oBinaryTableReader.ReadTableCache(length, &oTableParts); + SEEK_TO_POS_END2(); + m_oBufferedStream.Seek(nOldPos); + return res; +} +void BinaryWorksheetsTableReader::WriteComments() +{ + if (m_pCurWorksheet->m_mapComments.empty()) return; + + m_pCurVmlDrawing->m_mapComments = &m_pCurWorksheet->m_mapComments; + + boost::unordered_map mapByAuthors; + OOX::Spreadsheet::CComments* pComments = new OOX::Spreadsheet::CComments(NULL); + if(m_pXlsb && m_bWriteToXlsb) + pComments->File::m_pMainDocument = m_pXlsb; + + pComments->m_oCommentList.Init(); + std::vector& aComments = pComments->m_oCommentList->m_arrItems; + + pComments->m_oAuthors.Init(); + + OOX::Spreadsheet::CThreadedComments* pThreadedComments = NULL; + + for (std::map::const_iterator it = m_pCurWorksheet->m_mapComments.begin(); it != m_pCurWorksheet->m_mapComments.end(); ++it) + { + OOX::Spreadsheet::CCommentItem* pCommentItem = it->second; + if (pCommentItem->IsValid()) + { + OOX::Spreadsheet::CComment* pNewComment = new OOX::Spreadsheet::CComment(); + if (pCommentItem->m_nRow.IsInit() && pCommentItem->m_nCol.IsInit()) + { + pNewComment->m_oRef.Init(); + pNewComment->m_oRef->SetValue(OOX::Spreadsheet::CCell::combineRef(pCommentItem->m_nRow.get(), pCommentItem->m_nCol.get())); + } + if (NULL != pCommentItem->m_pThreadedComment) + { + if (NULL == pThreadedComments) + { + pThreadedComments = new OOX::Spreadsheet::CThreadedComments(NULL); + NSCommon::smart_ptr pThreadedCommentsFile(pThreadedComments); + m_pCurWorksheet->Add(pThreadedCommentsFile); + } + OOX::Spreadsheet::CThreadedComment* pThreadedComment = pCommentItem->m_pThreadedComment; + if (pNewComment->m_oRef.IsInit()) + { + pThreadedComment->ref = pNewComment->m_oRef->ToString(); + } + if (!pThreadedComment->id.IsInit()) + { + pThreadedComment->id = L"{" + XmlUtils::GenerateGuid() + L"}"; + } + pNewComment->m_oUid = pThreadedComment->id->ToString(); + pCommentItem->m_sAuthor = L"tc=" + pThreadedComment->id->ToString(); + + pCommentItem->m_oText.Init(); + 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) + { + pThreadedComment->m_arrReplies[i]->parentId = pThreadedComment->id->ToString(); + pThreadedComment->m_arrReplies[i]->ref = pThreadedComment->ref.get(); + if (!pThreadedComment->m_arrReplies[i]->id.IsInit()) + { + pThreadedComment->m_arrReplies[i]->id = L"{" + XmlUtils::GenerateGuid() + L"}"; + } + pThreadedComments->m_arrItems.push_back(pThreadedComment->m_arrReplies[i]); + } + } + + if (pCommentItem->m_sAuthor.IsInit()) + { + const std::wstring& sAuthor = pCommentItem->m_sAuthor.get(); + boost::unordered_map::const_iterator pFind = mapByAuthors.find(sAuthor); + + int nAuthorId; + if (pFind != mapByAuthors.end()) + nAuthorId = (int)pFind->second; + else + { + nAuthorId = (int)mapByAuthors.size(); + + mapByAuthors.insert(std::make_pair(sAuthor, nAuthorId)); + + pComments->m_oAuthors->m_arrItems.push_back(sAuthor); + } + pNewComment->m_oAuthorId.Init(); + pNewComment->m_oAuthorId->SetValue(nAuthorId); + } + pNewComment->m_oText.reset(pCommentItem->m_oText.GetPointerEmptyNullable()); + + aComments.push_back(pNewComment); + } + else if (NULL != pCommentItem->m_pThreadedComment) + { + RELEASEOBJECT(pCommentItem->m_pThreadedComment); + for (size_t i = 0; i < pCommentItem->m_pThreadedComment->m_arrReplies.size(); ++i) + { + RELEASEOBJECT(pCommentItem->m_pThreadedComment->m_arrReplies[i]); + } + } + } + + NSCommon::smart_ptr pCommentsFile(pComments); + m_pCurWorksheet->Add(pCommentsFile); +} +int BinaryWorksheetsTableReader::ReadPivotTable(BYTE type, long length, void* poResult) +{ + PivotCachesTemp* pPivotCachesTemp = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_PivotTypes::cacheId == type) + { + pPivotCachesTemp->nCacheId =m_oBufferedStream.GetLong(); + } + else if (c_oSer_PivotTypes::table == type) + { + OOX::Spreadsheet::CPivotTableFile* pPivotTable = new OOX::Spreadsheet::CPivotTableFile(NULL); + pPivotTable->setData(m_oBufferedStream.GetPointer(length), length); + pPivotCachesTemp->pTable = pPivotTable; + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} + +int BinaryWorksheetsTableReader::ReadWorksheetProp(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + if (c_oSerWorksheetPropTypes::Name == type) + { + m_pCurSheet->m_oName = m_oBufferedStream.GetString4(length); + } + else if (c_oSerWorksheetPropTypes::SheetId == type) + { + m_pCurSheet->m_oSheetId = m_oBufferedStream.GetLong(); + } + else if (c_oSerWorksheetPropTypes::State == type) + { + m_pCurSheet->m_oState = (SimpleTypes::Spreadsheet::EVisibleType)m_oBufferedStream.GetUChar(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadWorksheetCols(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CCols* pCols = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerWorksheetsTypes::Col == type) + { + OOX::Spreadsheet::CCol* pCol = new OOX::Spreadsheet::CCol(); + READ2_DEF_SPREADSHEET(length, res, this->ReadWorksheetCol, pCol); + pCols->m_arrItems.push_back(pCol); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadWorksheetCol(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CCol* pCol = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerWorksheetColTypes::BestFit == type) + { + pCol->m_oBestFit.Init(); + pCol->m_oBestFit->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerWorksheetColTypes::Hidden == type) + { + pCol->m_oHidden.Init(); + pCol->m_oHidden->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerWorksheetColTypes::Max == type) + { + pCol->m_oMax.Init(); + pCol->m_oMax->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSerWorksheetColTypes::Min == type) + { + pCol->m_oMin.Init(); + pCol->m_oMin->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSerWorksheetColTypes::Style == type) + { + pCol->m_oStyle.Init(); + pCol->m_oStyle->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSerWorksheetColTypes::Width == type) + { + pCol->m_oWidth.Init(); + pCol->m_oWidth->SetValue(m_oBufferedStream.GetDoubleReal()); + if (g_nCurFormatVersion < 2) + { + pCol->m_oCustomWidth.Init(); + pCol->m_oCustomWidth->SetValue(SimpleTypes::onoffTrue); + } + } + else if (c_oSerWorksheetColTypes::CustomWidth == type) + { + pCol->m_oCustomWidth.Init(); + pCol->m_oCustomWidth->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerWorksheetColTypes::OutLevel == type) + { + pCol->m_oOutlineLevel.Init(); + pCol->m_oOutlineLevel->SetValue( m_oBufferedStream.GetLong()); + } + else if (c_oSerWorksheetColTypes::Collapsed == type) + { + pCol->m_oCollapsed.Init(); + pCol->m_oCollapsed->FromBool(m_oBufferedStream.GetBool()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadProtectedRanges(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CProtectedRanges* pProtectedRanges = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerWorksheetsTypes::ProtectedRange == type) + { + OOX::Spreadsheet::CProtectedRange* pProtectedRange = new OOX::Spreadsheet::CProtectedRange(); + READ2_DEF_SPREADSHEET(length, res, this->ReadProtectedRange, pProtectedRange); + pProtectedRanges->m_arrItems.push_back(pProtectedRange); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadProtectedRange(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CProtectedRange* pProtectedRange = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + + if (c_oSerProtectedRangeTypes::AlgorithmName == type) + { + pProtectedRange->m_oAlgorithmName.Init(); + pProtectedRange->m_oAlgorithmName->SetValue((SimpleTypes::ECryptAlgoritmName)m_oBufferedStream.GetUChar()); + } + else if (c_oSerProtectedRangeTypes::SpinCount == type) + { + pProtectedRange->m_oSpinCount.Init(); + pProtectedRange->m_oSpinCount->SetValue(m_oBufferedStream.GetULong()); + } + else if (c_oSerProtectedRangeTypes::HashValue == type) + { + pProtectedRange->m_oHashValue = m_oBufferedStream.GetString4(length); + } + else if (c_oSerProtectedRangeTypes::SaltValue == type) + { + pProtectedRange->m_oSaltValue = m_oBufferedStream.GetString4(length); + } + else if (c_oSerProtectedRangeTypes::SqRef == type) + { + pProtectedRange->m_oSqref = m_oBufferedStream.GetString4(length); + } + else if (c_oSerProtectedRangeTypes::Name == type) + { + pProtectedRange->m_oName = m_oBufferedStream.GetString4(length); + } + else if (c_oSerProtectedRangeTypes::SecurityDescriptor == type) + { + pProtectedRange->m_arSecurityDescriptors.push_back(m_oBufferedStream.GetString4(length)); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} + +int BinaryWorksheetsTableReader::ReadSheetViews(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CSheetViews* pSheetViews = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerWorksheetsTypes::SheetView == type) + { + OOX::Spreadsheet::CSheetView* pSheetView = new OOX::Spreadsheet::CSheetView(); + READ1_DEF(length, res, this->ReadSheetView, pSheetView); + pSheetViews->m_arrItems.push_back(pSheetView); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadSheetView(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CSheetView* pSheetView = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_SheetView::ColorId == type) + { + pSheetView->m_oColorId.Init(); + pSheetView->m_oColorId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_SheetView::DefaultGridColor == type) + { + pSheetView->m_oDefaultGridColor.Init(); + pSheetView->m_oDefaultGridColor->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_SheetView::RightToLeft == type) + { + pSheetView->m_oRightToLeft.Init(); + pSheetView->m_oRightToLeft->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_SheetView::ShowFormulas == type) + { + pSheetView->m_oShowFormulas.Init(); + pSheetView->m_oShowFormulas->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_SheetView::ShowGridLines == type) + { + pSheetView->m_oShowGridLines.Init(); + pSheetView->m_oShowGridLines->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_SheetView::ShowOutlineSymbols == type) + { + pSheetView->m_oShowOutlineSymbols.Init(); + pSheetView->m_oShowOutlineSymbols->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_SheetView::ShowRowColHeaders == type) + { + pSheetView->m_oShowRowColHeaders.Init(); + pSheetView->m_oShowRowColHeaders->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_SheetView::ShowRuler == type) + { + pSheetView->m_oShowRuler.Init(); + pSheetView->m_oShowRuler->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_SheetView::ShowWhiteSpace == type) + { + pSheetView->m_oShowWhiteSpace.Init(); + pSheetView->m_oShowWhiteSpace->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_SheetView::ShowZeros == type) + { + pSheetView->m_oShowZeros.Init(); + pSheetView->m_oShowZeros->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_SheetView::TabSelected == type) + { + pSheetView->m_oTabSelected.Init(); + pSheetView->m_oTabSelected->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_SheetView::TopLeftCell == type) + { + pSheetView->m_oTopLeftCell = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_SheetView::View == type) + { + pSheetView->m_oView.Init(); + pSheetView->m_oView->SetValue((SimpleTypes::Spreadsheet::ESheetViewType)m_oBufferedStream.GetUChar()); + } + else if (c_oSer_SheetView::WindowProtection == type) + { + pSheetView->m_oWindowProtection.Init(); + pSheetView->m_oWindowProtection->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_SheetView::WorkbookViewId == type) + { + pSheetView->m_oWorkbookViewId.Init(); + pSheetView->m_oWorkbookViewId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_SheetView::ZoomScale == type) + { + pSheetView->m_oZoomScale.Init(); + pSheetView->m_oZoomScale->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_SheetView::ZoomScaleNormal == type) + { + pSheetView->m_oZoomScaleNormal.Init(); + pSheetView->m_oZoomScaleNormal->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_SheetView::ZoomScalePageLayoutView == type) + { + pSheetView->m_oZoomScalePageLayoutView.Init(); + pSheetView->m_oZoomScalePageLayoutView->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_SheetView::ZoomScaleSheetLayoutView == type) + { + pSheetView->m_oZoomScaleSheetLayoutView.Init(); + pSheetView->m_oZoomScaleSheetLayoutView->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_SheetView::Pane == type) + { + pSheetView->m_oPane.Init(); + READ1_DEF(length, res, this->ReadPane, pSheetView->m_oPane.GetPointer()); + } + else if (c_oSer_SheetView::Selection == type) + { + OOX::Spreadsheet::CSelection* pSelection = new OOX::Spreadsheet::CSelection(); + READ1_DEF(length, res, this->ReadSelection, pSelection); + pSheetView->m_arrItems.push_back(pSelection); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadPane(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CPane* pPane = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_Pane::ActivePane == type) + { + pPane->m_oActivePane.Init(); + pPane->m_oActivePane->SetValue((SimpleTypes::Spreadsheet::EActivePane)m_oBufferedStream.GetUChar()); + } + else if (c_oSer_Pane::State == type) + { + pPane->m_oState.Init(); + std::wstring sVal = m_oBufferedStream.GetString4(length); + pPane->m_oState->FromString(sVal.c_str()); + } + else if (c_oSer_Pane::TopLeftCell == type) + { + pPane->m_oTopLeftCell = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_Pane::XSplit == type) + { + pPane->m_oXSplit.Init(); + pPane->m_oXSplit->SetValue(m_oBufferedStream.GetDoubleReal()); + } + else if (c_oSer_Pane::YSplit == type) + { + pPane->m_oYSplit.Init(); + pPane->m_oYSplit->SetValue(m_oBufferedStream.GetDoubleReal()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadSelection(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CSelection* pSelection = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_Selection::ActiveCell == type) + { + pSelection->m_oActiveCell = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_Selection::ActiveCellId == type) + { + pSelection->m_oActiveCellId.Init(); + pSelection->m_oActiveCellId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_Selection::Sqref == type) + { + pSelection->m_oSqref = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_Selection::Pane == type) + { + pSelection->m_oPane.Init(); + pSelection->m_oPane->SetValue((SimpleTypes::Spreadsheet::EActivePane)m_oBufferedStream.GetUChar()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadSheetPr(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CSheetPr* pSheetPr = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_SheetPr::CodeName == type) + { + pSheetPr->m_oCodeName = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_SheetPr::EnableFormatConditionsCalculation == type) + { + pSheetPr->m_oEnableFormatConditionsCalculation.Init(); + pSheetPr->m_oEnableFormatConditionsCalculation->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSer_SheetPr::FilterMode == type) + { + pSheetPr->m_oFilterMode.Init(); + pSheetPr->m_oFilterMode->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSer_SheetPr::Published == type) + { + pSheetPr->m_oPublished.Init(); + pSheetPr->m_oPublished->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSer_SheetPr::SyncHorizontal == type) + { + pSheetPr->m_oSyncHorizontal.Init(); + pSheetPr->m_oSyncHorizontal->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSer_SheetPr::SyncRef == type) + { + pSheetPr->m_oSyncRef = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_SheetPr::SyncVertical == type) + { + pSheetPr->m_oSyncVertical.Init(); + pSheetPr->m_oSyncVertical->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSer_SheetPr::TransitionEntry == type) + { + pSheetPr->m_oTransitionEntry.Init(); + pSheetPr->m_oTransitionEntry->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSer_SheetPr::TransitionEvaluation == type) + { + pSheetPr->m_oTransitionEvaluation.Init(); + pSheetPr->m_oTransitionEvaluation->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSer_SheetPr::TabColor == type) + { + pSheetPr->m_oTabColor.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadColor, pSheetPr->m_oTabColor.GetPointer()); + } + else if (c_oSer_SheetPr::PageSetUpPr == type) + { + pSheetPr->m_oPageSetUpPr.Init(); + READ1_DEF(length, res, this->ReadPageSetUpPr, pSheetPr->m_oPageSetUpPr.GetPointer()); + } + else if (c_oSer_SheetPr::OutlinePr == type) + { + pSheetPr->m_oOutlinePr.Init(); + READ1_DEF(length, res, this->ReadOutlinePr, pSheetPr->m_oOutlinePr.GetPointer()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadOutlinePr(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::COutlinePr* pOutlinePr = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_SheetPr::ApplyStyles == type) + { + pOutlinePr->m_oApplyStyles.Init(); + pOutlinePr->m_oApplyStyles->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_SheetPr::ShowOutlineSymbols == type) + { + pOutlinePr->m_oShowOutlineSymbols.Init(); + pOutlinePr->m_oShowOutlineSymbols->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_SheetPr::SummaryBelow == type) + { + pOutlinePr->m_oSummaryBelow.Init(); + pOutlinePr->m_oSummaryBelow->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_SheetPr::SummaryRight == type) + { + pOutlinePr->m_oSummaryRight.Init(); + pOutlinePr->m_oSummaryRight->FromBool(m_oBufferedStream.GetBool()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadPageSetUpPr(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CPageSetUpPr* pPageSetUpPr = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_SheetPr::AutoPageBreaks == type) + { + pPageSetUpPr->m_oAutoPageBreaks.Init(); + pPageSetUpPr->m_oAutoPageBreaks->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_SheetPr::FitToPage == type) + { + pPageSetUpPr->m_oFitToPage.Init(); + pPageSetUpPr->m_oFitToPage->FromBool(m_oBufferedStream.GetBool()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadColor(BYTE type, long length, void* poResult) +{ + return m_oBcr2.ReadColor(type, length, poResult); +} +int BinaryWorksheetsTableReader::ReadSheetFormatPr(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CSheetFormatPr* pSheetFormatPr = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerSheetFormatPrTypes::DefaultColWidth == type) + { + pSheetFormatPr->m_oDefaultColWidth = m_oBufferedStream.GetDoubleReal(); + } + else if (c_oSerSheetFormatPrTypes::DefaultRowHeight == type) + { + pSheetFormatPr->m_oDefaultRowHeight = m_oBufferedStream.GetDoubleReal(); + } + else if (c_oSerSheetFormatPrTypes::BaseColWidth == type) + { + pSheetFormatPr->m_oBaseColWidth = m_oBufferedStream.GetLong(); + } + else if (c_oSerSheetFormatPrTypes::CustomHeight == type) + { + pSheetFormatPr->m_oCustomHeight = m_oBufferedStream.GetBool(); + } + else if (c_oSerSheetFormatPrTypes::ZeroHeight == type) + { + pSheetFormatPr->m_oZeroHeight = m_oBufferedStream.GetBool(); + } + else if (c_oSerSheetFormatPrTypes::OutlineLevelCol == type) + { + pSheetFormatPr->m_oOutlineLevelCol = m_oBufferedStream.GetLong(); + } + else if (c_oSerSheetFormatPrTypes::OutlineLevelRow == type) + { + pSheetFormatPr->m_oOutlineLevelRow = m_oBufferedStream.GetLong(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadPageMargins(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CPageMargins* pPageMargins = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_PageMargins::Left == type) + { + pPageMargins->m_oLeft.Init(); + pPageMargins->m_oLeft->FromMm(m_oBufferedStream.GetDoubleReal()); + } + else if (c_oSer_PageMargins::Top == type) + { + pPageMargins->m_oTop.Init(); + pPageMargins->m_oTop->FromMm(m_oBufferedStream.GetDoubleReal()); + } + else if (c_oSer_PageMargins::Right == type) + { + pPageMargins->m_oRight.Init(); + pPageMargins->m_oRight->FromMm(m_oBufferedStream.GetDoubleReal()); + } + else if (c_oSer_PageMargins::Bottom == type) + { + pPageMargins->m_oBottom.Init(); + pPageMargins->m_oBottom->FromMm(m_oBufferedStream.GetDoubleReal()); + } + else if (c_oSer_PageMargins::Header == type) + { + pPageMargins->m_oHeader.Init(); + pPageMargins->m_oHeader->FromMm(m_oBufferedStream.GetDoubleReal()); + } + else if (c_oSer_PageMargins::Footer == type) + { + pPageMargins->m_oFooter.Init(); + pPageMargins->m_oFooter->FromMm(m_oBufferedStream.GetDoubleReal()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadPageSetup(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CPageSetup* pPageSetup = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_PageSetup::BlackAndWhite == type) + { + pPageSetup->m_oBlackAndWhite.Init(); + pPageSetup->m_oBlackAndWhite->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_PageSetup::CellComments == type) + { + pPageSetup->m_oCellComments.Init(); + pPageSetup->m_oCellComments->SetValue((SimpleTypes::Spreadsheet::ECellComments)m_oBufferedStream.GetUChar()); + } + else if (c_oSer_PageSetup::Copies == type) + { + pPageSetup->m_oCopies.Init(); + pPageSetup->m_oCopies->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_PageSetup::Draft == type) + { + pPageSetup->m_oDraft.Init(); + pPageSetup->m_oDraft->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_PageSetup::Errors == type) + { + pPageSetup->m_oErrors.Init(); + pPageSetup->m_oErrors->SetValue((SimpleTypes::Spreadsheet::EPrintError)m_oBufferedStream.GetUChar()); + } + else if (c_oSer_PageSetup::FirstPageNumber == type) + { + pPageSetup->m_oFirstPageNumber.Init(); + pPageSetup->m_oFirstPageNumber->SetValue(m_oBufferedStream.GetULong()); + } + else if (c_oSer_PageSetup::FitToHeight == type) + { + pPageSetup->m_oFitToHeight.Init(); + pPageSetup->m_oFitToHeight->SetValue(m_oBufferedStream.GetULong()); + } + else if (c_oSer_PageSetup::FitToWidth == type) + { + pPageSetup->m_oFitToWidth.Init(); + pPageSetup->m_oFitToWidth->SetValue(m_oBufferedStream.GetULong()); + } + else if (c_oSer_PageSetup::HorizontalDpi == type) + { + pPageSetup->m_oHorizontalDpi.Init(); + pPageSetup->m_oHorizontalDpi->SetValue(m_oBufferedStream.GetULong()); + } + else if (c_oSer_PageSetup::Orientation == type) + { + pPageSetup->m_oOrientation.Init(); + pPageSetup->m_oOrientation->SetValue((SimpleTypes::EPageOrientation)m_oBufferedStream.GetUChar()); + } + else if (c_oSer_PageSetup::PageOrder == type) + { + pPageSetup->m_oPageOrder.Init(); + pPageSetup->m_oPageOrder->SetValue((SimpleTypes::Spreadsheet::EPageOrder)m_oBufferedStream.GetUChar()); + } + else if (c_oSer_PageSetup::PaperHeight == type) + { + pPageSetup->m_oPaperHeight.Init(); + pPageSetup->m_oPaperHeight->SetValue(m_oBufferedStream.GetDoubleReal()); + } + else if (c_oSer_PageSetup::PaperSize == type) + { + pPageSetup->m_oPaperSize.Init(); + pPageSetup->m_oPaperSize->SetValue((SimpleTypes::Spreadsheet::EPageSize)m_oBufferedStream.GetUChar()); + } + else if (c_oSer_PageSetup::PaperWidth == type) + { + pPageSetup->m_oPaperWidth.Init(); + pPageSetup->m_oPaperWidth->SetValue(m_oBufferedStream.GetDoubleReal()); + } + else if (c_oSer_PageSetup::PaperUnits == type) + { + pPageSetup->m_oPaperUnits.Init(); + pPageSetup->m_oPaperUnits->SetValue((SimpleTypes::Spreadsheet::EPageUnits)m_oBufferedStream.GetUChar()); + } + else if (c_oSer_PageSetup::Scale == type) + { + pPageSetup->m_oScale.Init(); + pPageSetup->m_oScale->SetValue(m_oBufferedStream.GetULong()); + } + else if (c_oSer_PageSetup::UseFirstPageNumber == type) + { + pPageSetup->m_oUseFirstPageNumber.Init(); + pPageSetup->m_oUseFirstPageNumber->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_PageSetup::UsePrinterDefaults == type) + { + pPageSetup->m_oUsePrinterDefaults.Init(); + pPageSetup->m_oUsePrinterDefaults->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_PageSetup::VerticalDpi == type) + { + pPageSetup->m_oVerticalDpi.Init(); + pPageSetup->m_oVerticalDpi->SetValue(m_oBufferedStream.GetULong()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadProtection(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CSheetProtection* pProtection = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + + if (c_oSerWorksheetProtection::AlgorithmName == type) + { + pProtection->m_oAlgorithmName.Init(); + pProtection->m_oAlgorithmName->SetValue((SimpleTypes::ECryptAlgoritmName)m_oBufferedStream.GetUChar()); + } + else if (c_oSerWorksheetProtection::SpinCount == type) + { + pProtection->m_oSpinCount.Init(); + pProtection->m_oSpinCount->SetValue(m_oBufferedStream.GetULong()); + } + else if (c_oSerWorksheetProtection::HashValue == type) + { + pProtection->m_oHashValue = m_oBufferedStream.GetString4(length); + } + else if (c_oSerWorksheetProtection::SaltValue == type) + { + pProtection->m_oSaltValue = m_oBufferedStream.GetString4(length); + } + else if (c_oSerWorksheetProtection::Password == type) + { + pProtection->m_oPassword = m_oBufferedStream.GetString4(length); + } + else if (c_oSerWorksheetProtection::AutoFilter == type) + { + pProtection->m_oAutoFilter.Init(); + pProtection->m_oAutoFilter->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerWorksheetProtection::Content == type) + { + pProtection->m_oContent.Init(); + pProtection->m_oContent->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerWorksheetProtection::DeleteColumns == type) + { + pProtection->m_oDeleteColumns.Init(); + pProtection->m_oDeleteColumns->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerWorksheetProtection::DeleteRows == type) + { + pProtection->m_oDeleteRows.Init(); + pProtection->m_oDeleteRows->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerWorksheetProtection::FormatCells == type) + { + pProtection->m_oFormatCells.Init(); + pProtection->m_oFormatCells->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerWorksheetProtection::FormatColumns == type) + { + pProtection->m_oFormatColumns.Init(); + pProtection->m_oFormatColumns->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerWorksheetProtection::FormatRows == type) + { + pProtection->m_oFormatRows.Init(); + pProtection->m_oFormatRows->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerWorksheetProtection::InsertColumns == type) + { + pProtection->m_oInsertColumns.Init(); + pProtection->m_oInsertColumns->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerWorksheetProtection::InsertHyperlinks == type) + { + pProtection->m_oInsertHyperlinks.Init(); + pProtection->m_oInsertHyperlinks->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerWorksheetProtection::InsertRows == type) + { + pProtection->m_oInsertRows.Init(); + pProtection->m_oInsertRows->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerWorksheetProtection::Objects == type) + { + pProtection->m_oObjects.Init(); + pProtection->m_oObjects->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerWorksheetProtection::PivotTables == type) + { + pProtection->m_oPivotTables.Init(); + pProtection->m_oPivotTables->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerWorksheetProtection::Scenarios == type) + { + pProtection->m_oScenarios.Init(); + pProtection->m_oScenarios->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerWorksheetProtection::SelectLockedCells == type) + { + pProtection->m_oSelectLockedCells.Init(); + pProtection->m_oSelectLockedCells->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerWorksheetProtection::SelectUnlockedCell == type) + { + pProtection->m_oSelectUnlockedCells.Init(); + pProtection->m_oSelectUnlockedCells->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerWorksheetProtection::Sheet == type) + { + pProtection->m_oSheet.Init(); + pProtection->m_oSheet->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSerWorksheetProtection::Sort == type) + { + pProtection->m_oSort.Init(); + pProtection->m_oSort->FromBool(m_oBufferedStream.GetBool()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadHeaderFooter(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CHeaderFooter* pHeaderFooter = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_HeaderFooter::AlignWithMargins == type) + { + pHeaderFooter->m_oAlignWithMargins.Init(); + pHeaderFooter->m_oAlignWithMargins->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_HeaderFooter::DifferentFirst == type) + { + pHeaderFooter->m_oDifferentFirst.Init(); + pHeaderFooter->m_oDifferentFirst->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_HeaderFooter::DifferentOddEven == type) + { + pHeaderFooter->m_oDifferentOddEven.Init(); + pHeaderFooter->m_oDifferentOddEven->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_HeaderFooter::ScaleWithDoc == type) + { + pHeaderFooter->m_oScaleWithDoc.Init(); + pHeaderFooter->m_oScaleWithDoc->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_HeaderFooter::EvenFooter == type) + { + pHeaderFooter->m_oEvenFooter.Init(); + pHeaderFooter->m_oEvenFooter->m_sText = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_HeaderFooter::EvenHeader == type) + { + pHeaderFooter->m_oEvenHeader.Init(); + pHeaderFooter->m_oEvenHeader->m_sText = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_HeaderFooter::FirstFooter == type) + { + pHeaderFooter->m_oFirstFooter.Init(); + pHeaderFooter->m_oFirstFooter->m_sText = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_HeaderFooter::FirstHeader == type) + { + pHeaderFooter->m_oFirstHeader.Init(); + pHeaderFooter->m_oFirstHeader->m_sText = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_HeaderFooter::OddFooter == type) + { + pHeaderFooter->m_oOddFooter.Init(); + pHeaderFooter->m_oOddFooter->m_sText = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_HeaderFooter::OddHeader == type) + { + pHeaderFooter->m_oOddHeader.Init(); + pHeaderFooter->m_oOddHeader->m_sText = m_oBufferedStream.GetString4(length); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadCellWatches(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CCellWatches* pCellWatches = static_cast(poResult); + if (c_oSerWorksheetsTypes::CellWatch == type) + { + pCellWatches->m_arrItems.push_back(new OOX::Spreadsheet::CCellWatch()); + READ2_DEF_SPREADSHEET(length, res, this->ReadCellWatch, pCellWatches->m_arrItems.back()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadCellWatch(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CCellWatch* pCellWatch = static_cast(poResult); + if (c_oSerWorksheetsTypes::CellWatchR == type) + { + pCellWatch->m_oR = m_oBufferedStream.GetString4(length); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadRowColBreaks(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CRowColBreaks* pRowColBreaks = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_RowColBreaks::Count == type) + { + pRowColBreaks->m_oCount.Init(); + pRowColBreaks->m_oCount->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_RowColBreaks::ManualBreakCount == type) + { + pRowColBreaks->m_oManualBreakCount.Init(); + pRowColBreaks->m_oManualBreakCount->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_RowColBreaks::Break == type) + { + OOX::Spreadsheet::CBreak* pColBreaks = new OOX::Spreadsheet::CBreak(); + READ1_DEF(length, res, this->ReadBreak, pColBreaks); + pRowColBreaks->m_arrItems.push_back(pColBreaks); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadBreak(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CBreak* pBreak = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_RowColBreaks::Id == type) + { + pBreak->m_oId.Init(); + pBreak->m_oId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_RowColBreaks::Man == type) + { + pBreak->m_oMan.Init(); + pBreak->m_oMan->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_RowColBreaks::Max == type) + { + pBreak->m_oMax.Init(); + pBreak->m_oMax->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_RowColBreaks::Min == type) + { + pBreak->m_oMin.Init(); + pBreak->m_oMin->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_RowColBreaks::Pt == type) + { + pBreak->m_oPt.Init(); + pBreak->m_oPt->FromBool(m_oBufferedStream.GetBool()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadPrintOptions(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CPrintOptions* pPrintOptions = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_PrintOptions::GridLines == type) + { + pPrintOptions->m_oGridLines.Init(); + pPrintOptions->m_oGridLines->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_PrintOptions::Headings == type) + { + pPrintOptions->m_oHeadings.Init(); + pPrintOptions->m_oHeadings->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_PrintOptions::GridLinesSet == type) + { + pPrintOptions->m_oGridLinesSet.Init(); + pPrintOptions->m_oGridLinesSet->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_PrintOptions::HorizontalCentered == type) + { + pPrintOptions->m_oHorizontalCentered.Init(); + pPrintOptions->m_oHorizontalCentered->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_PrintOptions::VerticalCentered == type) + { + pPrintOptions->m_oVerticalCentered.Init(); + pPrintOptions->m_oVerticalCentered->FromBool(m_oBufferedStream.GetBool()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadHyperlinks(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CHyperlinks* pHyperlinks = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerWorksheetsTypes::Hyperlink == type) + { + OOX::Spreadsheet::CHyperlink* pHyperlink = new OOX::Spreadsheet::CHyperlink(); + READ1_DEF(length, res, this->ReadHyperlink, pHyperlink); + pHyperlinks->m_arrItems.push_back(pHyperlink); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadHyperlink(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CHyperlink* pHyperlink = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerHyperlinkTypes::Ref == type) + { + pHyperlink->m_oRef = m_oBufferedStream.GetString4(length); + } + else if (c_oSerHyperlinkTypes::Display == type) + { + pHyperlink->m_oDisplay = m_oBufferedStream.GetString4(length); + } + else if (c_oSerHyperlinkTypes::Hyperlink == type) + { + std::wstring sHyperlink(m_oBufferedStream.GetString3(length)); + const OOX::RId& rId = m_pCurWorksheet->AddHyperlink(sHyperlink); + pHyperlink->m_oRid.Init(); + pHyperlink->m_oRid->SetValue(rId.get()); + } + else if (c_oSerHyperlinkTypes::Location == type) + { + pHyperlink->m_oLocation = m_oBufferedStream.GetString4(length); + } + else if (c_oSerHyperlinkTypes::Tooltip == type) + { + pHyperlink->m_oTooltip = m_oBufferedStream.GetString4(length); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadMergeCells(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMergeCells* pMergeCells = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerWorksheetsTypes::MergeCell == type) + { + OOX::Spreadsheet::CMergeCell* pMergeCell = new OOX::Spreadsheet::CMergeCell(); + pMergeCell->m_oRef = m_oBufferedStream.GetString4(length); + pMergeCells->m_arrItems.push_back(pMergeCell); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadDrawings(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CDrawing* pDrawing = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + + if (c_oSerWorksheetsTypes::Drawing == type) + { + OOX::Spreadsheet::CCellAnchor* pCellAnchor = new OOX::Spreadsheet::CCellAnchor(SimpleTypes::Spreadsheet::CCellAnchorType()); + READ1_DEF(length, res, this->ReadDrawing, pCellAnchor); + + pCellAnchor->m_bShapeOle = false; + pCellAnchor->m_bShapeControl = false; + + bool bAddToDrawing = true; + + if (pCellAnchor->m_oElement.is_init() && pCellAnchor->m_oElement->is()) + { + PPTX::Logic::Pic& oPic = pCellAnchor->m_oElement->as(); + if (oPic.oleObject.IsInit() && oPic.oleObject->m_OleObjectFile.IsInit()) + { + pCellAnchor->m_bShapeOle = oPic.oleObject->isValid(); + if (pCellAnchor->m_bShapeOle) + { + OOX::Spreadsheet::COleObject* pOleObject = new OOX::Spreadsheet::COleObject(); + + if (oPic.oleObject->m_sProgId.IsInit()) pOleObject->m_oProgId = oPic.oleObject->m_sProgId.get(); + if (oPic.oleObject->m_oDrawAspect.IsInit()) + { + std::wstring sDrawAspect; + if (0 == oPic.oleObject->m_oDrawAspect->GetBYTECode()) pOleObject->m_oDvAspect = L"DVASPECT_CONTENT"; + else pOleObject->m_oDvAspect = L"DVASPECT_ICON"; + } + if (oPic.oleObject->m_oUpdateMode.IsInit()) + { + if (0 == oPic.oleObject->m_oUpdateMode->GetBYTECode()) pOleObject->m_oOleUpdate = L"OLEUPDATE_ALWAYS"; + else pOleObject->m_oOleUpdate = L"OLEUPDATE_ONCALL"; + } + pOleObject->m_oObjectPr.Init(); + pOleObject->m_oObjectPr->m_oAnchor.Init(); + + pOleObject->m_oObjectPr->m_oAnchor->m_oSizeWithCells = oPic.oleObject->m_oSizeWithCells; + pOleObject->m_oObjectPr->m_oAnchor->m_oMoveWithCells = oPic.oleObject->m_oMoveWithCells; + + pOleObject->m_OleObjectFile = oPic.oleObject->m_OleObjectFile; + + if (pOleObject->m_OleObjectFile.IsInit()) + { + //generate ClientData + OOX::Vml::CClientData oClientData; + oClientData.m_oObjectType.Init(); + oClientData.m_oObjectType->SetValue(SimpleTypes::Vml::vmlclientdataobjecttypePict); + + oClientData.m_oSizeWithCells = pOleObject->m_oObjectPr->m_oAnchor->m_oSizeWithCells; + oClientData.m_oMoveWithCells = pOleObject->m_oObjectPr->m_oAnchor->m_oMoveWithCells; + + oClientData.m_oAnchor = pCellAnchor->toVmlXML(); + + oPic.m_sClientDataXml = oClientData.toXML(); + + //add VmlDrawing + NSBinPptxRW::CXmlWriter oWriter(XMLWRITER_DOC_TYPE_XLSX); + COOXToVMLGeometry oOOXToVMLRenderer; + + oWriter.m_pOOXToVMLRenderer = &oOOXToVMLRenderer; + oWriter.m_lObjectIdVML = m_pCurVmlDrawing->m_lObjectIdVML; + + NSCommon::smart_ptr oClrMap; + oPic.toXmlWriterVML(&oWriter, m_oSaveParams.pTheme, oClrMap); + + std::wstring strXml = oWriter.GetXmlString(); + + m_pCurVmlDrawing->m_arObjectXml.push_back(strXml); + m_lObjectIdVML = m_pCurVmlDrawing->m_lObjectIdVML = oWriter.m_lObjectIdVML; + + pOleObject->m_oShapeId = *oPic.oleObject->m_sShapeId; + + OOX::CPath pathImageCache = pOleObject->m_OleObjectFile->filename_cache(); + smart_ptr oRIdImg; + + if (pathImageCache.GetPath().empty() == false) + { + //add image rels to VmlDrawing + NSCommon::smart_ptr pImageFileVml(new OOX::Image(NULL, false)); + pImageFileVml->set_filename(pathImageCache, false); + + smart_ptr pFileVml = pImageFileVml.smart_dynamic_cast(); + m_pCurVmlDrawing->Add(*oPic.blipFill.blip->embed, pFileVml); + + //add image rels to Worksheet + NSCommon::smart_ptr pImageFileWorksheet(new OOX::Image(NULL, false)); + + pImageFileWorksheet->set_filename(pathImageCache, false); + + smart_ptr pFileWorksheet = pImageFileWorksheet.smart_dynamic_cast(); + + oRIdImg = new OOX::RId(m_pCurWorksheet->Add(pFileWorksheet)); + } + //add oleObject rels + smart_ptr pFileObject = pOleObject->m_OleObjectFile.smart_dynamic_cast(); + const OOX::RId oRIdBin = m_pCurWorksheet->Add(pFileObject); + + if (!pOleObject->m_oRid.IsInit()) + { + pOleObject->m_oRid.Init(); + } + pOleObject->m_oRid->SetValue(oRIdBin.get()); + //ObjectPr + pOleObject->m_oObjectPr->m_oDefaultSize.Init(); + pOleObject->m_oObjectPr->m_oDefaultSize->FromBool(false); + pOleObject->m_oObjectPr->m_oRid.Init(); + + if (oRIdImg.IsInit()) + pOleObject->m_oObjectPr->m_oRid->SetValue(oRIdImg->get()); + + //SimpleTypes::Spreadsheet::ECellAnchorType eAnchorType = pCellAnchor->m_oAnchorType.GetValue(); + //if (SimpleTypes::Spreadsheet::cellanchorOneCell == eAnchorType) + //{ + // pOleObject->m_oObjectPr->m_oAnchor->m_oMoveWithCells = true; + //} + //else if (SimpleTypes::Spreadsheet::cellanchorTwoCell == eAnchorType) + //{ + // pOleObject->m_oObjectPr->m_oAnchor->m_oSizeWithCells = true; + //} + pOleObject->m_oObjectPr->m_oAnchor->m_oFrom = pCellAnchor->m_oFrom; + pOleObject->m_oObjectPr->m_oAnchor->m_oTo = pCellAnchor->m_oTo; + + m_pCurOleObjects->m_mapOleObjects[pOleObject->m_oShapeId->GetValue()] = pOleObject; + } + else + { + pCellAnchor->m_bShapeOle = false; + delete pOleObject; + } + } + } + } + else if (pCellAnchor->m_oElement.is_init() && pCellAnchor->m_oElement->is()) + { + PPTX::Logic::Shape& oShape = pCellAnchor->m_oElement->as(); + if (oShape.signatureLine.IsInit()) + { + bAddToDrawing = false; + //generate ClientData + OOX::Vml::CClientData oClientData; + oClientData.m_oObjectType.Init(); + oClientData.m_oObjectType->SetValue(SimpleTypes::Vml::vmlclientdataobjecttypePict); + oClientData.m_oSizeWithCells = true; + oClientData.m_oAnchor = pCellAnchor->toVmlXML(); + + oShape.m_sClientDataXml = oClientData.toXML(); + + //add VmlDrawing + NSBinPptxRW::CXmlWriter oWriter(XMLWRITER_DOC_TYPE_XLSX); + COOXToVMLGeometry oOOXToVMLRenderer; + + oWriter.m_pOOXToVMLRenderer = &oOOXToVMLRenderer; + oWriter.m_lObjectIdVML = m_pCurVmlDrawing->m_lObjectIdVML; + + NSCommon::smart_ptr oClrMap; + oShape.toXmlWriterVML(&oWriter, m_oSaveParams.pTheme, oClrMap, false, true); + + std::wstring strXml = oWriter.GetXmlString(); + + m_pCurVmlDrawing->m_arObjectXml.push_back(strXml); + m_lObjectIdVML = m_pCurVmlDrawing->m_lObjectIdVML = oWriter.m_lObjectIdVML; + + if (oShape.spPr.Fill.m_type == PPTX::Logic::UniFill::blipFill) + { + OOX::CPath pathImageCache = oShape.spPr.Fill.as().blip->imageFilepath; + + smart_ptr oRIdImg; + if (pathImageCache.GetPath().empty() == false) + { + //add image rels to VmlDrawing + NSCommon::smart_ptr pImageFileVml(new OOX::Image(NULL, false)); + pImageFileVml->set_filename(pathImageCache, false); + + smart_ptr pFileVml = pImageFileVml.smart_dynamic_cast(); + m_pCurVmlDrawing->Add(*oShape.spPr.Fill.as().blip->embed, pFileVml); + } + } + } + } + if (bAddToDrawing) + { + pDrawing->m_arrItems.push_back(pCellAnchor); + } + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadCellAnchor(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CCellAnchor* pCellAnchor = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + + if (c_oSer_DrawingType::Type == type) + { + pCellAnchor->setAnchorType((SimpleTypes::Spreadsheet::ECellAnchorType)m_oBufferedStream.GetUChar()); + } + else if (c_oSer_DrawingType::EditAs == type) + { + pCellAnchor->m_oEditAs.Init(); + pCellAnchor->m_oEditAs->SetValue((SimpleTypes::Spreadsheet::ECellAnchorType)m_oBufferedStream.GetUChar()); + } + else if (c_oSer_DrawingType::From == type) + { + pCellAnchor->m_oFrom.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadFromTo, pCellAnchor->m_oFrom.GetPointer()); + } + else if (c_oSer_DrawingType::To == type) + { + pCellAnchor->m_oTo.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadFromTo, pCellAnchor->m_oTo.GetPointer()); + } + else if (c_oSer_DrawingType::Pos == type) + { + pCellAnchor->m_oPos.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadPos, pCellAnchor->m_oPos.GetPointer()); + } + else if (c_oSer_DrawingType::Ext == type) + { + pCellAnchor->m_oExt.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadExt, pCellAnchor->m_oExt.GetPointer()); + } + else if (c_oSer_DrawingType::ClientData == type) + { + pCellAnchor->m_oClientData.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadClientData, pCellAnchor->m_oClientData.GetPointer()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadDrawing(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CCellAnchor* pCellAnchor = static_cast(poResult); + + int res = ReadCellAnchor(type, length, poResult); + + if (res != c_oSerConstants::ReadUnknown) return res; + res = c_oSerConstants::ReadOk; + + if (c_oSer_DrawingType::pptxDrawing == type) + { + LONG nOldPos = m_oBufferedStream.GetPos(); + pCellAnchor->m_oElement.Init(); + + BYTE typeRec1 = m_oBufferedStream.GetUChar(); // must be 0; + LONG _e = m_oBufferedStream.GetPos() + m_oBufferedStream.GetLong() + 4; + + m_oBufferedStream.Skip(5); // type record (must be 1) + 4 byte - len record + + pCellAnchor->m_oElement->fromPPTY(&m_oBufferedStream); + + if (!pCellAnchor->m_oElement->is_init()) + { + m_oBufferedStream.Seek(nOldPos); + res = c_oSerConstants::ReadUnknown; + } + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadLegacyDrawingHF(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CLegacyDrawingHFWorksheet* pLegacyDrawingHF = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_LegacyDrawingHF::Drawings == type) + { + m_pOfficeDrawingConverter->SetDstContentRels(); + OOX::CVmlDrawing* pVmlDrawing = new OOX::CVmlDrawing(NULL, false); + pVmlDrawing->m_lObjectIdVML = m_lObjectIdVML; + READ1_DEF(length, res, this->ReadLegacyDrawingHFDrawings, pVmlDrawing); + m_lObjectIdVML = pVmlDrawing->m_lObjectIdVML; + NSCommon::smart_ptr pVmlDrawingFile(pVmlDrawing); + const OOX::RId oRId = m_pCurWorksheet->Add(pVmlDrawingFile); + pLegacyDrawingHF->m_oId.Init(); + pLegacyDrawingHF->m_oId->SetValue(oRId.get()); + + OOX::CPath pathVmlsDir = m_sDestinationDir + FILE_SEPARATOR_STR + _T("xl") + FILE_SEPARATOR_STR + _T("drawings"); + OOX::CSystemUtility::CreateDirectories(pathVmlsDir.GetPath()); + OOX::CPath pathVmlsRelsDir = pathVmlsDir.GetPath() + FILE_SEPARATOR_STR + _T("_rels"); + OOX::CSystemUtility::CreateDirectories(pathVmlsRelsDir.GetPath()); + OOX::CPath pathVmlRels = pathVmlsRelsDir.GetPath() + FILE_SEPARATOR_STR + pVmlDrawingFile->m_sOutputFilename + _T(".rels"); + m_pOfficeDrawingConverter->SaveDstContentRels(pathVmlRels.GetPath()); + } + else if (c_oSer_LegacyDrawingHF::Cfe == type) + { + pLegacyDrawingHF->m_oCfe.Init(); + pLegacyDrawingHF->m_oCfe->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_LegacyDrawingHF::Cff == type) + { + pLegacyDrawingHF->m_oCff.Init(); + pLegacyDrawingHF->m_oCff->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_LegacyDrawingHF::Cfo == type) + { + pLegacyDrawingHF->m_oCfo.Init(); + pLegacyDrawingHF->m_oCfo->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_LegacyDrawingHF::Che == type) + { + pLegacyDrawingHF->m_oChe.Init(); + pLegacyDrawingHF->m_oChe->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_LegacyDrawingHF::Chf == type) + { + pLegacyDrawingHF->m_oChf.Init(); + pLegacyDrawingHF->m_oChf->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_LegacyDrawingHF::Cho == type) + { + pLegacyDrawingHF->m_oCho.Init(); + pLegacyDrawingHF->m_oCho->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_LegacyDrawingHF::Lfe == type) + { + pLegacyDrawingHF->m_oLfe.Init(); + pLegacyDrawingHF->m_oLfe->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_LegacyDrawingHF::Lff == type) + { + pLegacyDrawingHF->m_oLff.Init(); + pLegacyDrawingHF->m_oLff->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_LegacyDrawingHF::Lfo == type) + { + pLegacyDrawingHF->m_oLfo.Init(); + pLegacyDrawingHF->m_oLfo->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_LegacyDrawingHF::Lhe == type) + { + pLegacyDrawingHF->m_oLhe.Init(); + pLegacyDrawingHF->m_oLhe->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_LegacyDrawingHF::Lhf == type) + { + pLegacyDrawingHF->m_oLhf.Init(); + pLegacyDrawingHF->m_oLhf->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_LegacyDrawingHF::Lho == type) + { + pLegacyDrawingHF->m_oLho.Init(); + pLegacyDrawingHF->m_oLho->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_LegacyDrawingHF::Rfe == type) + { + pLegacyDrawingHF->m_oRfe.Init(); + pLegacyDrawingHF->m_oRfe->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_LegacyDrawingHF::Rff == type) + { + pLegacyDrawingHF->m_oRff.Init(); + pLegacyDrawingHF->m_oRff->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_LegacyDrawingHF::Rfo == type) + { + pLegacyDrawingHF->m_oRfo.Init(); + pLegacyDrawingHF->m_oRfo->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_LegacyDrawingHF::Rhe == type) + { + pLegacyDrawingHF->m_oRhe.Init(); + pLegacyDrawingHF->m_oRhe->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_LegacyDrawingHF::Rhf == type) + { + pLegacyDrawingHF->m_oRhf.Init(); + pLegacyDrawingHF->m_oRhf->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_LegacyDrawingHF::Rho == type) + { + pLegacyDrawingHF->m_oRho.Init(); + pLegacyDrawingHF->m_oRho->SetValue(m_oBufferedStream.GetLong()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadLegacyDrawingHFDrawings(BYTE type, long length, void* poResult) +{ + OOX::CVmlDrawing* pVmlDrawing = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_LegacyDrawingHF::Drawing == type) + { + OOX::CVmlDrawing::_vml_shape oVmlShape; + READ1_DEF(length, res, this->ReadLegacyDrawingHFDrawing, &oVmlShape); + + if (NULL != oVmlShape.pElement && !oVmlShape.sXml.empty()) + { + PPTX::Logic::SpTreeElem* pSpTree = static_cast(oVmlShape.pElement); + + NSBinPptxRW::CXmlWriter oWriter(XMLWRITER_DOC_TYPE_XLSX); + COOXToVMLGeometry oOOXToVMLRenderer; + NSCommon::smart_ptr oClrMap; + + oWriter.m_pOOXToVMLRenderer = &oOOXToVMLRenderer; + oWriter.m_lObjectIdVML = pVmlDrawing->m_lObjectIdVML; + oWriter.m_strId = oVmlShape.sXml; + + //oWriter.m_strId = oVmlShape.sXml.c_str(); //?? + + pSpTree->toXmlWriterVML(&oWriter, m_oSaveParams.pTheme, oClrMap); + pVmlDrawing->m_lObjectIdVML = oWriter.m_lObjectIdVML; + pVmlDrawing->m_arObjectXml.push_back(oWriter.GetXmlString()); + } + RELEASEOBJECT(oVmlShape.pElement); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadLegacyDrawingHFDrawing(BYTE type, long length, void* poResult) +{ + OOX::CVmlDrawing::_vml_shape* poVmlShape = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_LegacyDrawingHF::DrawingId == type) + { + poVmlShape->sXml = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_LegacyDrawingHF::DrawingShape == type) + { + PPTX::Logic::SpTreeElem* pSpTree = new PPTX::Logic::SpTreeElem(); + BYTE typeRec1 = m_oBufferedStream.GetUChar(); // must be 0; + LONG _e = m_oBufferedStream.GetPos() + m_oBufferedStream.GetLong() + 4; + m_oBufferedStream.Skip(5); // type record (must be 1) + 4 byte - len recor + pSpTree->fromPPTY(&m_oBufferedStream); + poVmlShape->pElement = pSpTree; + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadFromTo(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CFromTo* pFromTo = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_DrawingFromToType::Col == type) + { + pFromTo->m_oCol.Init(); + pFromTo->m_oCol->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_DrawingFromToType::ColOff == type) + { + double dColOffMm = m_oBufferedStream.GetDoubleReal(); + pFromTo->m_oColOff.Init(); + pFromTo->m_oColOff->FromMm(dColOffMm); + } + else if (c_oSer_DrawingFromToType::Row == type) + { + pFromTo->m_oRow.Init(); + pFromTo->m_oRow->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_DrawingFromToType::RowOff == type) + { + double dRowOffMm = m_oBufferedStream.GetDoubleReal(); + pFromTo->m_oRowOff.Init(); + pFromTo->m_oRowOff->FromMm(dRowOffMm); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadClientData(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CClientData *pClientData = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_DrawingClientDataType::fLocksWithSheet == type) + { + pClientData->fLocksWithSheet = m_oBufferedStream.GetBool(); + } + else if (c_oSer_DrawingClientDataType::fPrintsWithSheet == type) + { + pClientData->fPrintsWithSheet = m_oBufferedStream.GetBool(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadExt(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CExt* pExt = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_DrawingExtType::Cx == type) + { + double dCxMm = m_oBufferedStream.GetDoubleReal(); + pExt->m_oCx.Init(); + pExt->m_oCx->FromMm(dCxMm); + } + else if (c_oSer_DrawingExtType::Cy == type) + { + double dCyMm = m_oBufferedStream.GetDoubleReal(); + pExt->m_oCy.Init(); + pExt->m_oCy->FromMm(dCyMm); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadPos(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CPos* pPos = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_DrawingPosType::X == type) + { + double dXMm = m_oBufferedStream.GetDoubleReal(); + pPos->m_oX.Init(); + pPos->m_oX->FromMm(dXMm); + } + else if (c_oSer_DrawingPosType::Y == type) + { + double dYMm = m_oBufferedStream.GetDoubleReal(); + pPos->m_oY.Init(); + pPos->m_oY->FromMm(dYMm); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadSheetData(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + if (c_oSerWorksheetsTypes::XlsbPos == type) + { + int nOldPos = m_oBufferedStream.GetPos(); + m_oBufferedStream.Seek(m_oBufferedStream.GetULong()); + if(m_pCurStreamWriterBin) + { + auto type = XLSB::rt_BeginSheetData; + while(type!= XLSB::rt_EndSheetData) + { + type = (XLSB::CF_RECORD_TYPE)m_oBufferedStream.XlsbReadRecordType(); + if(type == XLSB::rt_BeginSheetData) + { + m_oBufferedStream.XlsbSkipRecord(); + continue; + } + else if(type == XLSB::rt_EndSheetData) + { + m_oBufferedStream.XlsbSkipRecord(); + break; + } + auto record = m_pCurStreamWriterBin->getNextRecord(type); + auto size = m_oBufferedStream.XlsbReadRecordLength(); + if(size) + { + std::vector tempBuf(size); + m_oBufferedStream.GetArray(tempBuf.data(), size); + record->appendRawDataToStatic(tempBuf.data(), size); + } + m_pCurStreamWriterBin->storeNextRecord(record); + } + + } + else + { + OOX::Spreadsheet::CSheetData oSheetData; + oSheetData.fromXLSB(m_oBufferedStream, m_oBufferedStream.XlsbReadRecordType(), m_oSaveParams.pCSVWriter, *m_pCurStreamWriter); + } + m_oBufferedStream.Seek(nOldPos); + res = c_oSerConstants::ReadUnknown; + } + else if (c_oSerWorksheetsTypes::Row == type) + { + OOX::Spreadsheet::CRow oRow; + READ2_DEF_SPREADSHEET(length, res, this->ReadRow, &oRow); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadRow(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CRow* pRow = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerRowTypes::Row == type) + { + pRow->m_oR.Init(); + pRow->m_oR->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSerRowTypes::Style == type) + { + pRow->m_oS.Init(); + pRow->m_oS->SetValue(m_oBufferedStream.GetLong()); + pRow->m_oCustomFormat.Init(); + pRow->m_oCustomFormat->FromBool(true); + } + else if (c_oSerRowTypes::Height == type) + { + pRow->m_oHt.Init(); + pRow->m_oHt->SetValue(m_oBufferedStream.GetDoubleReal()); + if (g_nCurFormatVersion < 2) + { + pRow->m_oCustomHeight.Init(); + pRow->m_oCustomHeight->SetValue(SimpleTypes::onoffTrue); + } + } + else if (c_oSerRowTypes::Hidden == type) + { + pRow->m_oHidden = m_oBufferedStream.GetBool(); + } + else if (c_oSerRowTypes::CustomHeight == type) + { + pRow->m_oCustomHeight = m_oBufferedStream.GetBool(); + } + else if (c_oSerRowTypes::OutLevel == type) + { + pRow->m_oOutlineLevel.Init(); + pRow->m_oOutlineLevel->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSerRowTypes::Collapsed == type) + { + pRow->m_oCollapsed = m_oBufferedStream.GetBool(); + } + else if (c_oSerRowTypes::Cells == type) + { + if (NULL == m_oSaveParams.pCSVWriter && NULL == m_pCurStreamWriterBin) + { + pRow->toXMLStart(*m_pCurStreamWriter); + READ1_DEF(length, res, this->ReadCells, pRow); + pRow->toXMLEnd(*m_pCurStreamWriter); + } + else if(m_pCurStreamWriterBin != NULL) + { + pRow->WriteAttributes(m_pCurStreamWriterBin); + READ1_DEF(length, res, this->ReadCells, pRow); + } + else + { + m_oSaveParams.pCSVWriter->WriteRowStart(pRow); + READ1_DEF(length, res, this->ReadCells, pRow); + m_oSaveParams.pCSVWriter->WriteRowEnd(pRow); + } + } + + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadCells(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CRow* pRow = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerRowTypes::Cell == type) + { + OOX::Spreadsheet::CCell oCell; + READ1_DEF(length, res, this->ReadCell, &oCell); + +//текст error и формул пишем + if (NULL != m_pSharedStrings && oCell.m_oType.IsInit() && oCell.m_oValue.IsInit()) + { + SimpleTypes::Spreadsheet::ECellTypeType eCellType = oCell.m_oType->GetValue(); + bool bMoveText = false; + if (SimpleTypes::Spreadsheet::celltypeError == eCellType) + bMoveText = true; + else if ((SimpleTypes::Spreadsheet::celltypeSharedString == eCellType && oCell.m_oFormula.IsInit())) + { + bMoveText = true; + oCell.m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeStr); + } + if (bMoveText && SimpleTypes::Spreadsheet::celltypeSharedString == eCellType) + { + int nValue = XmlUtils::GetInteger(oCell.m_oValue->ToString()); + + if (nValue >= 0 && nValue < (int)m_pSharedStrings->m_arrItems.size()) + { + OOX::Spreadsheet::CSi *pSi = m_pSharedStrings->m_arrItems[nValue]; + if (NULL != pSi && !pSi->m_arrItems.empty()) + { + OOX::Spreadsheet::WritingElement* pWe = pSi->m_arrItems.front(); + if (OOX::et_x_t == pWe->getType()) + { + OOX::Spreadsheet::CText* pText = static_cast(pWe); + oCell.m_oValue->m_sText = pText->m_sText; + oCell.m_oValue->m_oSpace = pText->m_oSpace; + } + } + } + } + else if(bMoveText && SimpleTypes::Spreadsheet::celltypeError == eCellType) + { + int nValue = XmlUtils::GetInteger(oCell.m_oValue->ToString()); + std::wstring errText; + switch(nValue) + { + case 0x00: errText = L"#NULL!"; break; + case 0x07: errText = L"#DIV/0!"; break; + case 0x0F: errText = L"#VALUE!"; break; + case 0x17: errText = L"#REF!"; break; + case 0x1D: errText = L"#NAME?"; break; + case 0x24: errText = L"#NUM!"; break; + case 0x2A: errText = L"#N/A"; break; + case 0x2B: errText = L"#GETTING_DATA"; break; + default: + errText = L"#NULL!"; + break; + }; + oCell.m_oValue->m_sText = errText; + } + } + if (NULL == m_oSaveParams.pCSVWriter && m_pCurStreamWriterBin == NULL) + { + oCell.toXML(*m_pCurStreamWriter); + } + else if(m_pCurStreamWriterBin != NULL) + { + if(oCell.m_oRow.IsInit()) + *(oCell.m_oRow) += 1; + oCell.toBin(m_pCurStreamWriterBin); + } + else + { + m_oSaveParams.pCSVWriter->WriteCell(&oCell); + } + } + else + res = c_oSerConstants::ReadUnknown; + + + return res; +} +int BinaryWorksheetsTableReader::ReadCell(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CCell* pCell = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerCellTypes::Ref == type) + { + pCell->setRef(m_oBufferedStream.GetString4(length)); + } + else if (c_oSerCellTypes::RefRowCol == type) + { + int nRow = m_oBufferedStream.GetLong(); + int nCol = m_oBufferedStream.GetLong(); + pCell->setRowCol(nRow - 1, nCol); + } + else if (c_oSerCellTypes::Style == type) + { + pCell->m_oStyle = m_oBufferedStream.GetULong(); + } + else if (c_oSerCellTypes::Type == type) + { + pCell->m_oType = (SimpleTypes::Spreadsheet::ECellTypeType)m_oBufferedStream.GetUChar(); + } + else if (c_oSerCellTypes::Formula == type) + { + pCell->m_oFormula.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadFormula, pCell->m_oFormula.GetPointer()); + } + else if (c_oSerCellTypes::Value == type) + { + double dValue = m_oBufferedStream.GetDoubleReal(); + pCell->m_oValue.Init(); + pCell->m_oValue->m_sText = OOX::Spreadsheet::SpreadsheetCommon::WriteDouble(dValue); + } + else if (c_oSerCellTypes::ValueText == type) + { + pCell->m_oValue.Init(); + pCell->m_oValue->m_sText = m_oBufferedStream.GetString4(length); + } + else if (c_oSerCellTypes::ValueCache == type) + { + pCell->m_oCacheValue = m_oBufferedStream.GetString4(length); + } + else if (c_oSerCellTypes::CellMetadata == type) + { + pCell->m_oCellMetadata = m_oBufferedStream.GetULong(); + } + else if (c_oSerCellTypes::ValueMetadata == type) + { + pCell->m_oValueMetadata = m_oBufferedStream.GetULong(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadControls(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CControls* pControls = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSerControlTypes::Control == type) + { + nullable pControl; pControl.Init(); + + pControl->m_oFormControlPr.Init(); + + pControl->m_oControlPr.Init(); + pControl->m_oControlPr->m_oAnchor.Init(); + + pControl->m_oShapeId = 4096 + m_lObjectIdVML++; + + READ1_DEF(length, res, this->ReadControl, pControl.GetPointer()); + + std::wstring strXml = GetControlVmlShape(pControl.GetPointer()); + + m_pCurVmlDrawing->m_arControlXml.push_back(strXml); + + smart_ptr pCtrlPropFile(new OOX::Spreadsheet::CCtrlPropFile(NULL)); + pCtrlPropFile->m_oFormControlPr = pControl->m_oFormControlPr; + + smart_ptr pFile = pCtrlPropFile.smart_dynamic_cast(); + pControl->m_oRid = new SimpleTypes::CRelationshipId(m_pCurWorksheet->Add(pFile).get()); + + pControls->m_mapControls.insert(std::make_pair(pControl->m_oShapeId->GetValue(), pControl)); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadControl(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CControl* pControl = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + + if (c_oSerControlTypes::ControlAnchor == type) + { + OOX::Spreadsheet::CCellAnchor *pCellAnchor = new OOX::Spreadsheet::CCellAnchor(SimpleTypes::Spreadsheet::CCellAnchorType()); + READ1_DEF(length, res, this->ReadCellAnchor, pCellAnchor); + + pControl->m_oControlPr->m_oAnchor.Init(); + + SimpleTypes::Spreadsheet::ECellAnchorType eAnchorType = pCellAnchor->m_oAnchorType.GetValue(); + if (SimpleTypes::Spreadsheet::cellanchorOneCell == eAnchorType) + { + pControl->m_oControlPr->m_oAnchor->m_oMoveWithCells = true; + } + else if (SimpleTypes::Spreadsheet::cellanchorTwoCell == eAnchorType) + { + pControl->m_oControlPr->m_oAnchor->m_oSizeWithCells = true; + } + pControl->m_oControlPr->m_oAnchor->m_oFrom = pCellAnchor->m_oFrom; + pControl->m_oControlPr->m_oAnchor->m_oTo = pCellAnchor->m_oTo; + + RELEASEOBJECT(pCellAnchor); + } + else if (c_oSerControlTypes::ObjectType == type) + { + pControl->m_oFormControlPr->m_oObjectType = (SimpleTypes::Spreadsheet::EObjectType)m_oBufferedStream.GetUChar(); + } + else if (c_oSerControlTypes::Name == type) + { + pControl->m_oName = m_oBufferedStream.GetString4(length); + } + else if (c_oSerControlTypes::AltText == type) + { + pControl->m_oControlPr->m_oAltText = m_oBufferedStream.GetString4(length); + } + else if (c_oSerControlTypes::AutoFill == type) + { + pControl->m_oControlPr->m_oAutoFill = m_oBufferedStream.GetBool(); + } + else if (c_oSerControlTypes::AutoLine == type) + { + pControl->m_oControlPr->m_oAutoLine = m_oBufferedStream.GetBool(); + } + else if (c_oSerControlTypes::AutoPict == type) + { + pControl->m_oControlPr->m_oAutoPict = m_oBufferedStream.GetBool(); + } + else if (c_oSerControlTypes::DefaultSize == type) + { + pControl->m_oControlPr->m_oDefaultSize = m_oBufferedStream.GetBool(); + } + else if (c_oSerControlTypes::Disabled == type) + { + pControl->m_oControlPr->m_oDisabled = m_oBufferedStream.GetBool(); + } + else if (c_oSerControlTypes::Locked == type) + { + pControl->m_oControlPr->m_oLocked = m_oBufferedStream.GetBool(); + } + else if (c_oSerControlTypes::Macro == type) + { + pControl->m_oControlPr->m_oMacro = m_oBufferedStream.GetString4(length); + } + else if (c_oSerControlTypes::Print == type) + { + pControl->m_oControlPr->m_oPrint = m_oBufferedStream.GetBool(); + } + else if (c_oSerControlTypes::RecalcAlways == type) + { + pControl->m_oControlPr->m_oRecalcAlways = m_oBufferedStream.GetBool(); + } + else if (c_oSerControlTypes::Checked == type) + { + pControl->m_oFormControlPr->m_oChecked = (SimpleTypes::Spreadsheet::EChecked)m_oBufferedStream.GetUChar(); + } + else if (c_oSerControlTypes::Colored == type) + { + pControl->m_oFormControlPr->m_oColored = m_oBufferedStream.GetBool(); + } + else if (c_oSerControlTypes::DropLines == type) + { + pControl->m_oFormControlPr->m_oDropLines = m_oBufferedStream.GetULong(); + } + else if (c_oSerControlTypes::DropStyle == type) + { + pControl->m_oFormControlPr->m_oDropStyle = (SimpleTypes::Spreadsheet::EDropStyle)m_oBufferedStream.GetUChar(); + } + else if (c_oSerControlTypes::Dx == type) + { + pControl->m_oFormControlPr->m_oDx = m_oBufferedStream.GetULong(); + } + else if (c_oSerControlTypes::FirstButton == type) + { + pControl->m_oFormControlPr->m_oFirstButton = m_oBufferedStream.GetBool(); + } + else if (c_oSerControlTypes::FmlaGroup == type) + { + pControl->m_oFormControlPr->m_oFmlaGroup = m_oBufferedStream.GetString4(length); + } + else if (c_oSerControlTypes::FmlaLink == type) + { + pControl->m_oFormControlPr->m_oFmlaLink = m_oBufferedStream.GetString4(length); + } + else if (c_oSerControlTypes::FmlaRange == type) + { + pControl->m_oFormControlPr->m_oFmlaRange = m_oBufferedStream.GetString4(length); + } + else if (c_oSerControlTypes::FmlaTxbx == type) + { + pControl->m_oFormControlPr->m_oFmlaTxbx = m_oBufferedStream.GetString4(length); + } + else if (c_oSerControlTypes::Horiz == type) + { + pControl->m_oFormControlPr->m_oHoriz = m_oBufferedStream.GetBool(); + } + else if (c_oSerControlTypes::Inc == type) + { + pControl->m_oFormControlPr->m_oInc = m_oBufferedStream.GetULong(); + } + else if (c_oSerControlTypes::JustLastX == type) + { + pControl->m_oFormControlPr->m_oJustLastX = m_oBufferedStream.GetBool(); + } + else if (c_oSerControlTypes::LockText == type) + { + pControl->m_oFormControlPr->m_oLockText = m_oBufferedStream.GetBool(); + } + else if (c_oSerControlTypes::Max == type) + { + pControl->m_oFormControlPr->m_oMax = m_oBufferedStream.GetULong(); + } + else if (c_oSerControlTypes::Min == type) + { + pControl->m_oFormControlPr->m_oMin = m_oBufferedStream.GetULong(); + } + else if (c_oSerControlTypes::MultiSel == type) + { + pControl->m_oFormControlPr->m_oMultiSel = m_oBufferedStream.GetString4(length); + } + else if (c_oSerControlTypes::NoThreeD == type) + { + pControl->m_oFormControlPr->m_oNoThreeD = m_oBufferedStream.GetBool(); + } + else if (c_oSerControlTypes::NoThreeD2 == type) + { + pControl->m_oFormControlPr->m_oNoThreeD2 = m_oBufferedStream.GetBool(); + } + else if (c_oSerControlTypes::Page == type) + { + pControl->m_oFormControlPr->m_oPage = m_oBufferedStream.GetULong(); + } + else if (c_oSerControlTypes::Sel == type) + { + pControl->m_oFormControlPr->m_oSel = m_oBufferedStream.GetULong(); + } + else if (c_oSerControlTypes::SelType == type) + { + pControl->m_oFormControlPr->m_oSelType = (SimpleTypes::Spreadsheet::ESelType)m_oBufferedStream.GetUChar(); + } + else if (c_oSerControlTypes::TextHAlign == type) + { + pControl->m_oFormControlPr->m_oTextHAlign = (SimpleTypes::Spreadsheet::EHorizontalAlignment)m_oBufferedStream.GetUChar(); + } + else if (c_oSerControlTypes::TextVAlign == type) + { + pControl->m_oFormControlPr->m_oTextVAlign = (SimpleTypes::Spreadsheet::EVerticalAlignment)m_oBufferedStream.GetUChar(); + } + else if (c_oSerControlTypes::Val == type) + { + pControl->m_oFormControlPr->m_oVal = m_oBufferedStream.GetULong(); + } + else if (c_oSerControlTypes::WidthMin == type) + { + pControl->m_oFormControlPr->m_oWidthMin = m_oBufferedStream.GetULong(); + } + else if (c_oSerControlTypes::EditVal == type) + { + pControl->m_oFormControlPr->m_oEditVal = (SimpleTypes::Spreadsheet::EEditValidation)m_oBufferedStream.GetUChar(); + } + else if (c_oSerControlTypes::MultiLine == type) + { + pControl->m_oFormControlPr->m_oMultiLine = m_oBufferedStream.GetBool(); + } + else if (c_oSerControlTypes::VerticalBar == type) + { + pControl->m_oFormControlPr->m_oVerticalBar = m_oBufferedStream.GetBool(); + } + else if (c_oSerControlTypes::PasswordEdit == type) + { + pControl->m_oFormControlPr->m_oPasswordEdit = m_oBufferedStream.GetBool(); + } + else if (c_oSerControlTypes::Text == type) + { + pControl->m_oFormControlPr->m_oText = m_oBufferedStream.GetString4(length); + } + else if (c_oSerControlTypes::ItemLst == type) + { + pControl->m_oFormControlPr->m_oItemLst.Init(); + READ1_DEF(length, res, this->ReadControlItems, pControl->m_oFormControlPr->m_oItemLst.GetPointer()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadControlItems(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CListItems* pItems = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSerControlTypes::Item == type) + { + nullable pItem; pItem.Init(); + pItem->m_oVal = m_oBufferedStream.GetString4(length); + + pItems->m_arrItems.push_back(pItem); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +std::wstring BinaryWorksheetsTableReader::GetControlVmlShape(void* pC) +{ + OOX::Spreadsheet::CControl* pControl = static_cast(pC); +//generate ClientData + + std::wstring sAnchor; + sAnchor += pControl->m_oControlPr->m_oAnchor->m_oFrom->m_oCol->ToString() + L","; + sAnchor += std::to_wstring(pControl->m_oControlPr->m_oAnchor->m_oFrom->m_oColOff->ToPx()) + L","; + sAnchor += pControl->m_oControlPr->m_oAnchor->m_oFrom->m_oRow->ToString() + L","; + sAnchor += std::to_wstring(pControl->m_oControlPr->m_oAnchor->m_oFrom->m_oRowOff->ToPx()) + L","; + sAnchor += pControl->m_oControlPr->m_oAnchor->m_oTo->m_oCol->ToString() + L","; + sAnchor += std::to_wstring(pControl->m_oControlPr->m_oAnchor->m_oTo->m_oColOff->ToPx()) + L","; + sAnchor += pControl->m_oControlPr->m_oAnchor->m_oTo->m_oRow->ToString() + L","; + sAnchor += std::to_wstring(pControl->m_oControlPr->m_oAnchor->m_oTo->m_oRowOff->ToPx()); + + OOX::Vml::CClientData oClientData; + + oClientData.m_oSizeWithCells = true; + oClientData.m_oAnchor = sAnchor; + + SimpleTypes::Vml::EVmlClientDataObjectType objectType = SimpleTypes::Vml::vmlclientdataobjecttypePict; + + if (pControl->m_oFormControlPr->m_oObjectType.IsInit()) + { + switch(pControl->m_oFormControlPr->m_oObjectType->GetValue()) + { + case SimpleTypes::Spreadsheet::objectButton: objectType = SimpleTypes::Vml::vmlclientdataobjecttypeButton; break; + case SimpleTypes::Spreadsheet::objectCheckBox: objectType = SimpleTypes::Vml::vmlclientdataobjecttypeCheckbox; break; + case SimpleTypes::Spreadsheet::objectDrop: objectType = SimpleTypes::Vml::vmlclientdataobjecttypeDrop; break; + case SimpleTypes::Spreadsheet::objectGBox: objectType = SimpleTypes::Vml::vmlclientdataobjecttypeGBox; break; + case SimpleTypes::Spreadsheet::objectLabel: objectType = SimpleTypes::Vml::vmlclientdataobjecttypeLabel; break; + case SimpleTypes::Spreadsheet::objectList: objectType = SimpleTypes::Vml::vmlclientdataobjecttypeList; break; + case SimpleTypes::Spreadsheet::objectRadio: objectType = SimpleTypes::Vml::vmlclientdataobjecttypeRadio; break; + case SimpleTypes::Spreadsheet::objectScroll: objectType = SimpleTypes::Vml::vmlclientdataobjecttypeScroll; break; + case SimpleTypes::Spreadsheet::objectSpin: objectType = SimpleTypes::Vml::vmlclientdataobjecttypeSpin; break; + case SimpleTypes::Spreadsheet::objectEditBox: objectType = SimpleTypes::Vml::vmlclientdataobjecttypeEdit; break; + case SimpleTypes::Spreadsheet::objectDialog: objectType = SimpleTypes::Vml::vmlclientdataobjecttypeDialog; break; + } + } + oClientData.m_oObjectType.Init(); + oClientData.m_oObjectType->SetValue(objectType); + + if (pControl->m_oFormControlPr->m_oChecked.IsInit()) + oClientData.m_oChecked = pControl->m_oFormControlPr->m_oChecked->ToString(); + + if (pControl->m_oFormControlPr->m_oDropStyle.IsInit()) + oClientData.m_oDropStyle = pControl->m_oFormControlPr->m_oDropStyle->ToVmlString(); + + oClientData.m_oDefaultSize = pControl->m_oControlPr->m_oDefaultSize; + oClientData.m_oAutoLine = pControl->m_oControlPr->m_oAutoLine; + oClientData.m_oAutoPict = pControl->m_oControlPr->m_oAutoPict; + oClientData.m_oCf = pControl->m_oControlPr->m_oCf; + + oClientData.m_oMin = pControl->m_oFormControlPr->m_oMin; + oClientData.m_oMax = pControl->m_oFormControlPr->m_oMax; + oClientData.m_oVal = pControl->m_oFormControlPr->m_oVal; + oClientData.m_oInc = pControl->m_oFormControlPr->m_oInc; + oClientData.m_oDx = pControl->m_oFormControlPr->m_oDx; + oClientData.m_oPage = pControl->m_oFormControlPr->m_oPage; + oClientData.m_oDropLines = pControl->m_oFormControlPr->m_oDropLines; + oClientData.m_oChecked = pControl->m_oFormControlPr->m_oChecked; + oClientData.m_oColored = pControl->m_oFormControlPr->m_oColored; + oClientData.m_oDropStyle = pControl->m_oFormControlPr->m_oDropStyle; + oClientData.m_oFirstButton = pControl->m_oFormControlPr->m_oFirstButton; + oClientData.m_oHoriz = pControl->m_oFormControlPr->m_oHoriz; + oClientData.m_oJustLastX = pControl->m_oFormControlPr->m_oJustLastX; + oClientData.m_oLockText = pControl->m_oFormControlPr->m_oLockText; + oClientData.m_oMultiLine = pControl->m_oFormControlPr->m_oMultiLine; + oClientData.m_oSecretEdit = pControl->m_oFormControlPr->m_oPasswordEdit; + oClientData.m_oTextHAlign = pControl->m_oFormControlPr->m_oTextHAlign; + oClientData.m_oTextVAlign = pControl->m_oFormControlPr->m_oTextVAlign; + oClientData.m_oVal = pControl->m_oFormControlPr->m_oVal; + oClientData.m_oSel = pControl->m_oFormControlPr->m_oSel; + oClientData.m_oSelType = pControl->m_oFormControlPr->m_oSelType; + oClientData.m_oVScroll = pControl->m_oFormControlPr->m_oVerticalBar; + oClientData.m_oWidthMin = pControl->m_oFormControlPr->m_oWidthMin; + oClientData.m_oNoThreeD = pControl->m_oFormControlPr->m_oNoThreeD; + oClientData.m_oNoThreeD2 = pControl->m_oFormControlPr->m_oNoThreeD2; + oClientData.m_oFmlaLink = pControl->m_oFormControlPr->m_oFmlaLink; + oClientData.m_oFmlaRange = pControl->m_oFormControlPr->m_oFmlaRange; + oClientData.m_oFmlaTxbx = pControl->m_oFormControlPr->m_oFmlaTxbx; + oClientData.m_oFmlaGroup = pControl->m_oFormControlPr->m_oFmlaGroup; + + std::wstring result = L"m_oShapeId->GetValue()) + L"\""; + result += L" style='position:absolute' stroked=\"f\" strokecolor=\"windowText [64]\" o:insetmode=\"auto\""; + result += L" filled=\"f\" fillcolor=\"window [65]\""; + + if (objectType == SimpleTypes::Vml::vmlclientdataobjecttypeButton) + { + result += L" o:button=\"t\""; + } + result += L">"; + result += L""; + + result += oClientData.toXML(); + + if (pControl->m_oFormControlPr->m_oText.IsInit()) + { + OOX::Vml::CTextbox oTextbox; + + oTextbox.m_oText = pControl->m_oFormControlPr->m_oText; + result += oTextbox.toXML(); + } + result += L""; + + return result; +} +int BinaryWorksheetsTableReader::ReadFormula(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CFormula* pFormula = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerFormulaTypes::Aca == type) + { + pFormula->m_oAca.Init(); + pFormula->m_oAca->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerFormulaTypes::Bx == type) + { + pFormula->m_oBx.Init(); + pFormula->m_oBx->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerFormulaTypes::Ca == type) + { + pFormula->m_oCa.Init(); + pFormula->m_oCa->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerFormulaTypes::Del1 == type) + { + pFormula->m_oDel1.Init(); + pFormula->m_oDel1->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerFormulaTypes::Del2 == type) + { + pFormula->m_oDel2.Init(); + pFormula->m_oDel2->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerFormulaTypes::Dt2D == type) + { + pFormula->m_oDt2D.Init(); + pFormula->m_oDt2D->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerFormulaTypes::Dtr == type) + { + pFormula->m_oDtr.Init(); + pFormula->m_oDtr->SetValue(false != m_oBufferedStream.GetBool() ? SimpleTypes::onoffTrue : SimpleTypes::onoffFalse); + } + else if (c_oSerFormulaTypes::R1 == type) + { + pFormula->m_oR1.Init(); + pFormula->m_oR1->append(m_oBufferedStream.GetString4(length)); + } + else if (c_oSerFormulaTypes::R2 == type) + { + pFormula->m_oR2.Init(); + pFormula->m_oR2->append(m_oBufferedStream.GetString4(length)); + } + else if (c_oSerFormulaTypes::Ref == type) + { + pFormula->m_oRef.Init(); + pFormula->m_oRef->append(m_oBufferedStream.GetString4(length)); + } + else if (c_oSerFormulaTypes::Si == type) + { + pFormula->m_oSi.Init(); + pFormula->m_oSi->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSerFormulaTypes::T == type) + { + pFormula->m_oT.Init(); + pFormula->m_oT->SetValue((SimpleTypes::Spreadsheet::ECellFormulaType)m_oBufferedStream.GetUChar()); + } + else if (c_oSerFormulaTypes::Text == type) + { + pFormula->m_sText = m_oBufferedStream.GetString4(length); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadUserProtectedRanges(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CUserProtectedRanges *pUserProtectedRanges = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_UserProtectedRange::UserProtectedRange == type) + { + OOX::Spreadsheet::CUserProtectedRange* pUserProtectedRange = new OOX::Spreadsheet::CUserProtectedRange(); + READ1_DEF(length, res, this->ReadUserProtectedRange, pUserProtectedRange); + pUserProtectedRanges->m_arrItems.push_back(pUserProtectedRange); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadUserProtectedRangeDesc(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CUserProtectedRange::_UsersGroupsDesc *desc = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + + if (c_oSer_UserProtectedRangeDesc::Name == type) + { + desc->name = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_UserProtectedRangeDesc::Id == type) + { + desc->id = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_UserProtectedRangeDesc::Type == type) + { + desc->type.Init(); + desc->type->SetValueFromByte(m_oBufferedStream.GetUChar()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadUserProtectedRange(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CUserProtectedRange *pUserProtectedRange = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_UserProtectedRange::Name == type) + { + pUserProtectedRange->m_oName = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_UserProtectedRange::Sqref == type) + { + pUserProtectedRange->m_oSqref = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_UserProtectedRange::Text == type) + { + pUserProtectedRange->m_oText = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_UserProtectedRange::Type == type) + { + pUserProtectedRange->m_oType.Init(); + pUserProtectedRange->m_oType->SetValueFromByte(m_oBufferedStream.GetUChar()); + } + else if (c_oSer_UserProtectedRange::User == type) + { + OOX::Spreadsheet::CUserProtectedRange::_UsersGroupsDesc desc; + READ2_DEF_SPREADSHEET(length, res, this->ReadUserProtectedRangeDesc, &desc); + pUserProtectedRange->m_arUsers.push_back(desc); + } + else if (c_oSer_UserProtectedRange::UsersGroup == type) + { + OOX::Spreadsheet::CUserProtectedRange::_UsersGroupsDesc desc; + READ2_DEF_SPREADSHEET(length, res, this->ReadUserProtectedRangeDesc, &desc); + pUserProtectedRange->m_arUsersGroups.push_back(desc); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadConditionalFormatting(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CConditionalFormatting* pConditionalFormatting = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_ConditionalFormatting::Pivot == type) + { + pConditionalFormatting->m_oPivot.Init(); + pConditionalFormatting->m_oPivot->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_ConditionalFormatting::SqRef == type) + { + pConditionalFormatting->m_oSqRef.Init(); + pConditionalFormatting->m_oSqRef->append(m_oBufferedStream.GetString4(length)); + } + else if (c_oSer_ConditionalFormatting::ConditionalFormattingRule == type) + { + OOX::Spreadsheet::CConditionalFormattingRule* pConditionalFormattingRule = new OOX::Spreadsheet::CConditionalFormattingRule(); + READ1_DEF(length, res, this->ReadConditionalFormattingRule, pConditionalFormattingRule); + pConditionalFormatting->m_arrItems.push_back(pConditionalFormattingRule); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadConditionalFormattingRule(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CConditionalFormattingRule* pConditionalFormattingRule = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_ConditionalFormattingRule::AboveAverage == type) + { + pConditionalFormattingRule->m_oAboveAverage.Init(); + pConditionalFormattingRule->m_oAboveAverage->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_ConditionalFormattingRule::Bottom == type) + { + pConditionalFormattingRule->m_oBottom.Init(); + pConditionalFormattingRule->m_oBottom->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_ConditionalFormattingRule::DxfId == type) + { + pConditionalFormattingRule->m_oDxfId.Init(); + pConditionalFormattingRule->m_oDxfId->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_ConditionalFormattingRule::EqualAverage == type) + { + pConditionalFormattingRule->m_oEqualAverage.Init(); + pConditionalFormattingRule->m_oEqualAverage->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_ConditionalFormattingRule::Operator == type) + { + pConditionalFormattingRule->m_oOperator.Init(); + pConditionalFormattingRule->m_oOperator->SetValue((SimpleTypes::Spreadsheet::ECfOperator)m_oBufferedStream.GetUChar()); + } + else if (c_oSer_ConditionalFormattingRule::Percent == type) + { + pConditionalFormattingRule->m_oPercent.Init(); + pConditionalFormattingRule->m_oPercent->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_ConditionalFormattingRule::Priority == type) + { + pConditionalFormattingRule->m_oPriority.Init(); + pConditionalFormattingRule->m_oPriority->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_ConditionalFormattingRule::Rank == type) + { + pConditionalFormattingRule->m_oRank.Init(); + pConditionalFormattingRule->m_oRank->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_ConditionalFormattingRule::StdDev == type) + { + pConditionalFormattingRule->m_oStdDev.Init(); + pConditionalFormattingRule->m_oStdDev->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_ConditionalFormattingRule::StopIfTrue == type) + { + pConditionalFormattingRule->m_oStopIfTrue.Init(); + pConditionalFormattingRule->m_oStopIfTrue->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_ConditionalFormattingRule::Text == type) + { + pConditionalFormattingRule->m_oText.Init(); + pConditionalFormattingRule->m_oText->append(m_oBufferedStream.GetString4(length)); + } + else if (c_oSer_ConditionalFormattingRule::strTimePeriod == type) + { + pConditionalFormattingRule->m_oTimePeriod = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_ConditionalFormattingRule::TimePeriod == type) + { + pConditionalFormattingRule->m_oTimePeriod.Init(); + pConditionalFormattingRule->m_oTimePeriod->SetValue((SimpleTypes::Spreadsheet::ETimePeriod)m_oBufferedStream.GetUChar()); + } + else if (c_oSer_ConditionalFormattingRule::Type == type) + { + pConditionalFormattingRule->m_oType.Init(); + pConditionalFormattingRule->m_oType->SetValue((SimpleTypes::Spreadsheet::ECfType)m_oBufferedStream.GetUChar()); + } + else if (c_oSer_ConditionalFormattingRule::Dxf == type) + { + OOX::Spreadsheet::CStyles oStyles(NULL); + BinaryStyleTableReader style_reader(m_oBufferedStream, oStyles); + + OOX::Spreadsheet::CDxf* pDxf = new OOX::Spreadsheet::CDxf(); + READ1_DEF(length, res, style_reader.ReadDxf, pDxf); + + pConditionalFormattingRule->m_oDxf = pDxf; + } + else if (c_oSer_ConditionalFormattingRule::ColorScale == type) + { + OOX::Spreadsheet::CColorScale* pColorScale = new OOX::Spreadsheet::CColorScale(); + READ1_DEF(length, res, this->ReadColorScale, pColorScale); + + pConditionalFormattingRule->m_oColorScale = pColorScale; + } + else if (c_oSer_ConditionalFormattingRule::DataBar == type) + { + OOX::Spreadsheet::CDataBar* pDataBar = new OOX::Spreadsheet::CDataBar(); + READ1_DEF(length, res, this->ReadDataBar, pDataBar); + + pConditionalFormattingRule->m_oDataBar = pDataBar; + } + else if (c_oSer_ConditionalFormattingRule::FormulaCF == type) + { + nullable pFormulaCF; pFormulaCF.Init(); + pFormulaCF->m_sText = m_oBufferedStream.GetString4(length); + + pConditionalFormattingRule->m_arrFormula.push_back( pFormulaCF ); + } + else if (c_oSer_ConditionalFormattingRule::IconSet == type) + { + OOX::Spreadsheet::CIconSet* pIconSet = new OOX::Spreadsheet::CIconSet(); + READ1_DEF(length, res, this->ReadIconSet, pIconSet); + + pConditionalFormattingRule->m_oIconSet = pIconSet; + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadColorScale(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CColorScale* pColorScale = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_ConditionalFormattingRuleColorScale::CFVO == type) + { + nullable pCFVO; pCFVO.Init(); + READ1_DEF(length, res, this->ReadCFVO, pCFVO.GetPointer()); + pColorScale->m_arrValues.push_back(pCFVO); + } + else if (c_oSer_ConditionalFormattingRuleColorScale::Color == type) + { + nullable pColor; pColor.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadColor, pColor.GetPointer()); + pColorScale->m_arrColors.push_back(pColor); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadDataBar(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CDataBar* pDataBar = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_ConditionalFormattingDataBar::MaxLength == type) + { + pDataBar->m_oMaxLength.Init(); + pDataBar->m_oMaxLength->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_ConditionalFormattingDataBar::MinLength == type) + { + pDataBar->m_oMinLength.Init(); + pDataBar->m_oMinLength->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_ConditionalFormattingDataBar::ShowValue == type) + { + pDataBar->m_oShowValue.Init(); + pDataBar->m_oShowValue->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_ConditionalFormattingDataBar::GradientEnabled == type) + { + pDataBar->m_oGradient.Init(); + pDataBar->m_oGradient->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_ConditionalFormattingDataBar::NegativeBarColorSameAsPositive == type) + { + pDataBar->m_oNegativeBarColorSameAsPositive.Init(); + pDataBar->m_oNegativeBarColorSameAsPositive->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_ConditionalFormattingDataBar::NegativeBarBorderColorSameAsPositive == type) + { + pDataBar->m_oNegativeBarBorderColorSameAsPositive.Init(); + pDataBar->m_oNegativeBarBorderColorSameAsPositive->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_ConditionalFormattingDataBar::AxisPosition == type) + { + pDataBar->m_oAxisPosition.Init(); + pDataBar->m_oAxisPosition->SetValue((SimpleTypes::Spreadsheet::EDataBarAxisPosition)m_oBufferedStream.GetLong()); + } + else if (c_oSer_ConditionalFormattingDataBar::Direction == type) + { + pDataBar->m_oDirection.Init(); + pDataBar->m_oDirection->SetValue((SimpleTypes::Spreadsheet::EDataBarDirection)m_oBufferedStream.GetLong()); + } + else if (c_oSer_ConditionalFormattingDataBar::Color == type) + { + pDataBar->m_oColor.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadColor, pDataBar->m_oColor.GetPointer()); + } + else if (c_oSer_ConditionalFormattingDataBar::AxisColor == type) + { + pDataBar->m_oAxisColor.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadColor, pDataBar->m_oAxisColor.GetPointer()); + } + else if (c_oSer_ConditionalFormattingDataBar::BorderColor == type) + { + pDataBar->m_oBorderColor.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadColor, pDataBar->m_oBorderColor.GetPointer()); + } + else if (c_oSer_ConditionalFormattingDataBar::NegativeColor == type) + { + pDataBar->m_oNegativeFillColor.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadColor, pDataBar->m_oNegativeFillColor.GetPointer()); + } + else if (c_oSer_ConditionalFormattingDataBar::NegativeBorderColor == type) + { + pDataBar->m_oNegativeBorderColor.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadColor, pDataBar->m_oNegativeBorderColor.GetPointer()); + } + else if (c_oSer_ConditionalFormattingDataBar::CFVO == type) + { + nullable pCFVO; pCFVO.Init(); + READ1_DEF(length, res, this->ReadCFVO, pCFVO.GetPointer()); + pDataBar->m_arrValues.push_back(pCFVO); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadIconSet(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CIconSet* pIconSet = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_ConditionalFormattingIconSet::IconSet == type) + { + pIconSet->m_oIconSet.Init(); + pIconSet->m_oIconSet->SetValue((SimpleTypes::Spreadsheet::EIconSetType)m_oBufferedStream.GetUChar()); + } + else if (c_oSer_ConditionalFormattingIconSet::Percent == type) + { + pIconSet->m_oPercent.Init(); + pIconSet->m_oPercent->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_ConditionalFormattingIconSet::Reverse == type) + { + pIconSet->m_oReverse.Init(); + pIconSet->m_oReverse->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_ConditionalFormattingIconSet::ShowValue == type) + { + pIconSet->m_oShowValue.Init(); + pIconSet->m_oShowValue->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_ConditionalFormattingIconSet::CFVO == type) + { + nullable pCFVO; pCFVO.Init(); + READ1_DEF(length, res, this->ReadCFVO, pCFVO.GetPointer()); + pIconSet->m_arrValues.push_back(pCFVO); + } + else if (c_oSer_ConditionalFormattingIconSet::CFIcon == type) + { + nullable pCFIcon; pCFIcon.Init(); + READ1_DEF(length, res, this->ReadCFIcon, pCFIcon.GetPointer()); + pIconSet->m_arrIconSets.push_back(pCFIcon); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadCFIcon(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CConditionalFormatIconSet* pCFIcon = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_ConditionalFormattingIcon::iconSet == type) + { + pCFIcon->m_oIconSet.Init(); + pCFIcon->m_oIconSet->SetValue((SimpleTypes::Spreadsheet::EIconSetType)m_oBufferedStream.GetLong()); + } + else if (c_oSer_ConditionalFormattingIcon::iconId == type) + { + pCFIcon->m_oIconId.Init(); + pCFIcon->m_oIconId->SetValue(m_oBufferedStream.GetLong()); + } + return res; +} +int BinaryWorksheetsTableReader::ReadCFVO(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CConditionalFormatValueObject* pCFVO = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_ConditionalFormattingValueObject::Gte == type) + { + pCFVO->m_oGte.Init(); + pCFVO->m_oGte->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_ConditionalFormattingValueObject::Type == type) + { + pCFVO->m_oType.Init(); + pCFVO->m_oType->SetValue((SimpleTypes::Spreadsheet::ECfvoType)m_oBufferedStream.GetUChar()); + } + else if (c_oSer_ConditionalFormattingValueObject::Val == type) + { + pCFVO->m_oVal.Init(); + pCFVO->m_oVal = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_ConditionalFormattingValueObject::Formula == type) + { + pCFVO->m_oFormula.Init(); + pCFVO->m_oFormula->m_sText = m_oBufferedStream.GetString4(length); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadSparklineGroups(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CSparklineGroups* pSparklineGroups = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_Sparkline::SparklineGroup == type) + { + OOX::Spreadsheet::CSparklineGroup* pSparklineGroup = new OOX::Spreadsheet::CSparklineGroup(); + READ1_DEF(length, res, this->ReadSparklineGroup, pSparklineGroup); + pSparklineGroups->m_arrItems.push_back(pSparklineGroup); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadSparklineGroup(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CSparklineGroup* pSparklineGroup = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_Sparkline::ManualMax == type) + { + pSparklineGroup->m_oManualMax.Init(); + pSparklineGroup->m_oManualMax->SetValue(m_oBufferedStream.GetDoubleReal()); + } + else if (c_oSer_Sparkline::ManualMin == type) + { + pSparklineGroup->m_oManualMin.Init(); + pSparklineGroup->m_oManualMin->SetValue(m_oBufferedStream.GetDoubleReal()); + } + else if (c_oSer_Sparkline::LineWeight == type) + { + pSparklineGroup->m_oLineWeight.Init(); + pSparklineGroup->m_oLineWeight->SetValue(m_oBufferedStream.GetDoubleReal()); + } + else if (c_oSer_Sparkline::Type == type) + { + pSparklineGroup->m_oType.Init(); + pSparklineGroup->m_oType->SetValue((SimpleTypes::Spreadsheet::ESparklineType)m_oBufferedStream.GetChar()); + } + else if (c_oSer_Sparkline::DateAxis == type) + { + pSparklineGroup->m_oDateAxis.Init(); + pSparklineGroup->m_oDateAxis->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_Sparkline::DisplayEmptyCellsAs == type) + { + pSparklineGroup->m_oDisplayEmptyCellsAs.Init(); + pSparklineGroup->m_oDisplayEmptyCellsAs.get2() = (OOX::Spreadsheet::ST_DispBlanksAs)m_oBufferedStream.GetChar(); + } + else if (c_oSer_Sparkline::Markers == type) + { + pSparklineGroup->m_oMarkers.Init(); + pSparklineGroup->m_oMarkers->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_Sparkline::High == type) + { + pSparklineGroup->m_oHigh.Init(); + pSparklineGroup->m_oHigh->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_Sparkline::Low == type) + { + pSparklineGroup->m_oLow.Init(); + pSparklineGroup->m_oLow->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_Sparkline::First == type) + { + pSparklineGroup->m_oFirst.Init(); + pSparklineGroup->m_oFirst->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_Sparkline::Last == type) + { + pSparklineGroup->m_oLast.Init(); + pSparklineGroup->m_oLast->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_Sparkline::Negative == type) + { + pSparklineGroup->m_oNegative.Init(); + pSparklineGroup->m_oNegative->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_Sparkline::DisplayXAxis == type) + { + pSparklineGroup->m_oDisplayXAxis.Init(); + pSparklineGroup->m_oDisplayXAxis->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_Sparkline::DisplayHidden == type) + { + pSparklineGroup->m_oDisplayHidden.Init(); + pSparklineGroup->m_oDisplayHidden->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_Sparkline::MinAxisType == type) + { + pSparklineGroup->m_oMinAxisType.Init(); + pSparklineGroup->m_oMinAxisType->SetValue((SimpleTypes::Spreadsheet::ESparklineAxisMinMax)m_oBufferedStream.GetChar()); + } + else if (c_oSer_Sparkline::MaxAxisType == type) + { + pSparklineGroup->m_oMaxAxisType.Init(); + pSparklineGroup->m_oMaxAxisType->SetValue((SimpleTypes::Spreadsheet::ESparklineAxisMinMax)m_oBufferedStream.GetChar()); + } + else if (c_oSer_Sparkline::RightToLeft == type) + { + pSparklineGroup->m_oRightToLeft.Init(); + pSparklineGroup->m_oRightToLeft->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_Sparkline::ColorSeries == type) + { + pSparklineGroup->m_oColorSeries.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadColor, pSparklineGroup->m_oColorSeries.GetPointer()); + } + else if (c_oSer_Sparkline::ColorNegative == type) + { + pSparklineGroup->m_oColorNegative.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadColor, pSparklineGroup->m_oColorNegative.GetPointer()); + } + else if (c_oSer_Sparkline::ColorAxis == type) + { + pSparklineGroup->m_oColorAxis.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadColor, pSparklineGroup->m_oColorAxis.GetPointer()); + } + else if (c_oSer_Sparkline::ColorMarkers == type) + { + pSparklineGroup->m_oColorMarkers.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadColor, pSparklineGroup->m_oColorMarkers.GetPointer()); + } + else if (c_oSer_Sparkline::ColorFirst == type) + { + pSparklineGroup->m_oColorFirst.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadColor, pSparklineGroup->m_oColorFirst.GetPointer()); + } + else if (c_oSer_Sparkline::ColorLast == type) + { + pSparklineGroup->m_oColorLast.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadColor, pSparklineGroup->m_oColorLast.GetPointer()); + } + else if (c_oSer_Sparkline::ColorHigh == type) + { + pSparklineGroup->m_oColorHigh.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadColor, pSparklineGroup->m_oColorHigh.GetPointer()); + } + else if (c_oSer_Sparkline::ColorLow == type) + { + pSparklineGroup->m_oColorLow.Init(); + READ2_DEF_SPREADSHEET(length, res, this->ReadColor, pSparklineGroup->m_oColorLow.GetPointer()); + } + else if (c_oSer_Sparkline::Ref == type) + { + pSparklineGroup->m_oRef.Init(); + pSparklineGroup->m_oRef->append(m_oBufferedStream.GetString4(length)); + } + else if (c_oSer_Sparkline::Sparklines == type) + { + pSparklineGroup->m_oSparklines.Init(); + READ1_DEF(length, res, this->ReadSparklines, pSparklineGroup->m_oSparklines.GetPointer()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadDataValidationsContent(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CDataValidations* pDataValidations = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_DataValidation::DataValidation == type) + { + OOX::Spreadsheet::CDataValidation* pDataValidation = new OOX::Spreadsheet::CDataValidation(); + READ2_DEF_SPREADSHEET(length, res, this->ReadDataValidation, pDataValidation); + pDataValidations->m_arrItems.push_back(pDataValidation); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadDataValidations(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CDataValidations* pDataValidations = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_DataValidation::DataValidations == type) + { + READ1_DEF(length, res, this->ReadDataValidationsContent, pDataValidations); + } + else if (c_oSer_DataValidation::DisablePrompts == type) + { + pDataValidations->m_oDisablePrompts.Init(); + pDataValidations->m_oDisablePrompts->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_DataValidation::XWindow == type) + { + if (!pDataValidations->m_oXWindow.IsInit()) + pDataValidations->m_oXWindow.Init(); + pDataValidations->m_oXWindow->SetValue(m_oBufferedStream.GetLong()); + } + else if (c_oSer_DataValidation::YWindow == type) + { + if (!pDataValidations->m_oYWindow.IsInit()) + pDataValidations->m_oYWindow.Init(); + pDataValidations->m_oYWindow->SetValue(m_oBufferedStream.GetLong()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadDataValidation(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CDataValidation* pDataValidation = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_DataValidation::AllowBlank == type) + { + pDataValidation->m_oAllowBlank.Init(); + pDataValidation->m_oAllowBlank->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_DataValidation::Type == type) + { + pDataValidation->m_oType.Init(); + pDataValidation->m_oType->SetValue((SimpleTypes::Spreadsheet::EDataValidationType)m_oBufferedStream.GetChar()); + } + else if (c_oSer_DataValidation::Error == type) + { + pDataValidation->m_oError = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_DataValidation::ErrorTitle == type) + { + pDataValidation->m_oErrorTitle = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_DataValidation::ErrorStyle == type) + { + pDataValidation->m_oErrorStyle.Init(); + pDataValidation->m_oErrorStyle->SetValue((SimpleTypes::Spreadsheet::EDataValidationErrorStyle)m_oBufferedStream.GetChar()); + } + else if (c_oSer_DataValidation::ImeMode == type) + { + pDataValidation->m_oImeMode.Init(); + pDataValidation->m_oImeMode->SetValue((SimpleTypes::Spreadsheet::EDataValidationImeMode)m_oBufferedStream.GetChar()); + } + else if (c_oSer_DataValidation::Operator == type) + { + pDataValidation->m_oOperator.Init(); + pDataValidation->m_oOperator->SetValue((SimpleTypes::Spreadsheet::EDataValidationOperator)m_oBufferedStream.GetChar()); + } + else if (c_oSer_DataValidation::Promt == type) + { + pDataValidation->m_oPrompt = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_DataValidation::PromptTitle == type) + { + pDataValidation->m_oPromptTitle = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_DataValidation::ShowDropDown == type) + { + pDataValidation->m_oShowDropDown.Init(); + pDataValidation->m_oShowDropDown->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_DataValidation::ShowErrorMessage == type) + { + pDataValidation->m_oShowErrorMessage.Init(); + pDataValidation->m_oShowErrorMessage->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_DataValidation::ShowInputMessage == type) + { + pDataValidation->m_oShowInputMessage.Init(); + pDataValidation->m_oShowInputMessage->FromBool(m_oBufferedStream.GetBool()); + } + else if (c_oSer_DataValidation::SqRef == type) + { + pDataValidation->m_oSqRef = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_DataValidation::Formula1 == type) + { + pDataValidation->m_oFormula1.Init(); + pDataValidation->m_oFormula1->m_sText = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_DataValidation::Formula2 == type) + { + pDataValidation->m_oFormula2.Init(); + pDataValidation->m_oFormula2->m_sText = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_DataValidation::List == type) + { + pDataValidation->m_oList = m_oBufferedStream.GetString4(length); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadTimelines(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CTimelines* pTimelines = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerWorksheetsTypes::Timeline == type) + { + OOX::Spreadsheet::CTimeline* pTimeline = new OOX::Spreadsheet::CTimeline(); + READ2_DEF_SPREADSHEET(length, res, this->ReadTimeline, pTimeline); + pTimelines->m_arrItems.push_back(pTimeline); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadTimelinesList(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CTimelineRefs* pTimelineRefs = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerWorksheetsTypes::Timelines == type) + { + OOX::Spreadsheet::CTimelineFile* pTimelineFile = new OOX::Spreadsheet::CTimelineFile(NULL); + pTimelineFile->m_oTimelines.Init(); + + READ1_DEF(length, res, this->ReadTimelines, pTimelineFile->m_oTimelines.GetPointer()); + + NSCommon::smart_ptr pFile(pTimelineFile); + const OOX::RId oRId = m_pCurWorksheet->Add(pFile); + + OOX::Spreadsheet::CTimelineRef* pTimelineRef = new OOX::Spreadsheet::CTimelineRef(); + pTimelineRef->m_oRId.Init(); + pTimelineRef->m_oRId->SetValue(oRId.get()); + + pTimelineRefs->m_arrItems.push_back(pTimelineRef); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadTimeline(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CTimeline* pTimeline = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_Timeline::Name == type) + { + pTimeline->m_oName = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_Timeline::Cache == type) + { + pTimeline->m_oCache = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_Timeline::Caption == type) + { + pTimeline->m_oCaption = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_Timeline::ScrollPosition == type) + { + pTimeline->m_oScrollPosition = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_Timeline::Uid == type) + { + pTimeline->m_oUid = m_oBufferedStream.GetString4(length); + } + else if (c_oSer_Timeline::Level == type) + { + pTimeline->m_oLevel = m_oBufferedStream.GetULong(); + } + else if (c_oSer_Timeline::SelectionLevel == type) + { + pTimeline->m_oSelectionLevel = m_oBufferedStream.GetULong(); + } + else if (c_oSer_Timeline::ShowHeader == type) + { + pTimeline->m_oShowHeader = m_oBufferedStream.GetBool(); + } + else if (c_oSer_Timeline::ShowHorizontalScrollbar == type) + { + pTimeline->m_oShowHorizontalScrollbar = m_oBufferedStream.GetBool(); + } + else if (c_oSer_Timeline::ShowSelectionLabel == type) + { + pTimeline->m_oShowSelectionLabel = m_oBufferedStream.GetBool(); + } + else if (c_oSer_Timeline::ShowTimeLevel == type) + { + pTimeline->m_oShowTimeLevel = m_oBufferedStream.GetBool(); + } + else if (c_oSer_Timeline::Style == type) + { + pTimeline->m_oStyle.Init(); + pTimeline->m_oStyle->SetValueFromByte(m_oBufferedStream.GetUChar()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadSparklines(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CSparklines* pSparklines = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_Sparkline::Sparkline == type) + { + OOX::Spreadsheet::CSparkline* pSparkline = new OOX::Spreadsheet::CSparkline(); + READ1_DEF(length, res, this->ReadSparkline, pSparkline); + pSparklines->m_arrItems.push_back(pSparkline); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadSparkline(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CSparkline* pSparkline = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSer_Sparkline::SparklineRef == type) + { + pSparkline->m_oRef.Init(); + pSparkline->m_oRef->append(m_oBufferedStream.GetString4(length)); + } + else if (c_oSer_Sparkline::SparklineSqRef == type) + { + pSparkline->m_oSqRef.Init(); + pSparkline->m_oSqRef->append(m_oBufferedStream.GetString4(length)); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorksheetsTableReader::ReadSlicers(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CSlicerRefs* pSlicerRefs = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + if (c_oSerWorksheetsTypes::Slicer == type) + { + OOX::Spreadsheet::CSlicerFile* pSlicer = new OOX::Spreadsheet::CSlicerFile(NULL); + if(m_pXlsb && m_bWriteToXlsb) + pSlicer->OOX::File::m_pMainDocument = m_pXlsb; + pSlicer->m_oSlicers.Init(); + + m_oBufferedStream.GetUChar();//type + pSlicer->m_oSlicers->fromPPTY(&m_oBufferedStream); + + NSCommon::smart_ptr pSlicerFile(pSlicer); + const OOX::RId oRId = m_pCurWorksheet->Add(pSlicerFile); + + pSlicerRefs->m_oSlicer.emplace_back(); + pSlicerRefs->m_oSlicer.back().m_oRId.Init(); + pSlicerRefs->m_oSlicer.back().m_oRId->SetValue(oRId.get()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} + +void BinaryWorksheetsTableReader::AddLineBreak(OOX::Spreadsheet::CSi& oSi) +{ + OOX::Spreadsheet::CRun* pRun = new OOX::Spreadsheet::CRun(); + pRun->m_oRPr.Init(); + OOX::Spreadsheet::CRPr& pRPr = pRun->m_oRPr.get2(); + pRPr.m_oRFont.Init(); + pRPr.m_oRFont->m_sVal = L"Tahoma"; + pRPr.m_oSz.Init(); + pRPr.m_oSz->m_oVal.Init(); + pRPr.m_oSz->m_oVal->SetValue(9); + pRPr.m_oBold.Init(); + pRPr.m_oBold->FromBool(true); + + OOX::Spreadsheet::CText* pText = new OOX::Spreadsheet::CText(); + pText->m_sText.append(_T("\n")); + + pRun->m_arrItems.push_back(pText); + oSi.m_arrItems.push_back(pRun); +} + + +BinaryOtherTableReader::BinaryOtherTableReader(NSBinPptxRW::CBinaryFileReader& oBufferedStream, boost::unordered_map& mapMedia, + const std::wstring& sFileInDir, SaveParams& oSaveParams, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter, + const std::wstring& sMediaDir) : + Binary_CommonReader(oBufferedStream), m_mapMedia(mapMedia), m_sFileInDir(sFileInDir), m_oSaveParams(oSaveParams), + m_pOfficeDrawingConverter(pOfficeDrawingConverter),m_sMediaDir(sMediaDir) +{ + m_nCurId = 0; + m_nCurIndex = 1; +} +int BinaryOtherTableReader::Read() +{ + int res = c_oSerConstants::ReadOk; + READ_TABLE_DEF(res, this->ReadOtherTableContent, this); + return res; +} +int BinaryOtherTableReader::ReadOtherTableContent(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + if (c_oSer_OtherType::Media == type) + { + READ1_DEF(length, res, this->ReadMediaContent, poResult); + } + else if (c_oSer_OtherType::Theme == type) + { + m_oSaveParams.pTheme = new PPTX::Theme(NULL); + m_oSaveParams.pTheme->fromPPTY(&m_oBufferedStream); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryOtherTableReader::ReadMediaContent(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + if (c_oSer_OtherType::MediaItem == type) + { + m_nCurId = -1; + m_sCurSrc.clear(); + READ1_DEF(length, res, this->ReadMediaItem, poResult); + if (-1 != m_nCurId && false == m_sCurSrc.empty()) + { + m_mapMedia [m_nCurId] = new ImageObject(m_sCurSrc, m_nCurIndex); + m_nCurIndex++; + } + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryOtherTableReader::ReadMediaItem(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + if (c_oSer_OtherType::MediaSrc == type) + { + std::wstring sImage (m_oBufferedStream.GetString3(length)); + std::wstring sImageSrc; + bool bAddToDelete = false; + NSFile::CFileBinary oFile; + + if (0 == sImage.find(L"data:")) + { + if (oFile.CreateTempFile()) + SerializeCommon::convertBase64ToImage(oFile, sImage); + } + else if (0 == sImage.find(_T("http:")) || 0 == sImage.find(_T("https:")) || 0 == sImage.find(_T("ftp:")) || 0 == sImage.find(_T("www"))) + { + //url + sImageSrc = SerializeCommon::DownloadImage(sImage); + std::wstring sNewTempFile = SerializeCommon::changeExtention(sImageSrc, L"jpg"); + NSFile::CFileBinary::Move(sImageSrc, sNewTempFile); + sImageSrc = sNewTempFile; + bAddToDelete = true; + } + else + { + if (0 == sImage.find(_T("file:///"))) + { + sImageSrc = sImage; + XmlUtils::replace_all( sImageSrc, L"file:///", L""); + } + else + { + //local + sImageSrc = m_sFileInDir + _T("media/") + sImage; + } + } + //Проверяем что файл существует + FILE* pFileNative = oFile.GetFileNative(); + if (NULL != pFileNative) + { + ReadMediaItemSaveFileFILE(pFileNative); + } + else if (NSFile::CFileBinary::Exists(sImageSrc)) + { + CImageFileFormatChecker checker; + if (checker.isImageFile(sImageSrc)) + { + ReadMediaItemSaveFilePath(sImageSrc); + } + if (bAddToDelete) + NSFile::CFileBinary::Remove(sImageSrc); + } + } + else if (c_oSer_OtherType::MediaId == type) + { + m_nCurId = m_oBufferedStream.GetLong(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +std::wstring BinaryOtherTableReader::ReadMediaItemSaveFileGetNewPath(const std::wstring& sTempPath) +{ + if ( !NSDirectory::Exists(m_sMediaDir) ) + OOX::CSystemUtility::CreateDirectories(m_sMediaDir); + std::wstring sNewImageName = L"image" + std::to_wstring(m_nCurIndex); + sNewImageName += OOX::CPath(sTempPath).GetExtention(true); + m_nCurIndex++; + std::wstring sNewImagePath = m_sMediaDir + FILE_SEPARATOR_STR + sNewImageName; + return sNewImagePath; +} +void BinaryOtherTableReader::ReadMediaItemSaveFileFILE(FILE* pFile) +{ + long size = ftell(pFile); + if (size > 0) + { + rewind(pFile); + BYTE* pData = new BYTE[size]; + DWORD dwSizeRead = (DWORD)fread((void*)pData, 1, size, pFile); + if (dwSizeRead > 0) + { + CImageFileFormatChecker checker; + std::wstring sExt = checker.DetectFormatByData(pData, dwSizeRead); + + if (false == sExt.empty()) + { + std::wstring sNewImagePath = ReadMediaItemSaveFileGetNewPath(L"1.jpg"); //todooo add true sExt + NSFile::CFileBinary oFile; + oFile.CreateFileW(sNewImagePath); + oFile.WriteFile(pData, dwSizeRead); + oFile.CloseFile(); + m_sCurSrc = sNewImagePath; + } + } + RELEASEARRAYOBJECTS(pData); + } +} +void BinaryOtherTableReader::ReadMediaItemSaveFilePath(const std::wstring& sTempPath) +{ + std::wstring sNewImagePath = ReadMediaItemSaveFileGetNewPath(sTempPath); + + NSFile::CFileBinary::Copy(sTempPath, sNewImagePath); + m_sCurSrc = sNewImagePath; +} + +//------------------------------------------------------------------------------------------------------------------------------------ +BinaryPersonReader::BinaryPersonReader(NSBinPptxRW::CBinaryFileReader& oBufferedStream, OOX::Spreadsheet::CWorkbook& oWorkbook):Binary_CommonReader(oBufferedStream),m_oWorkbook(oWorkbook) +{ +} +int BinaryPersonReader::Read() +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CPersonList* pPersonList = new OOX::Spreadsheet::CPersonList(NULL); + 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) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CPersonList* pPersonList = static_cast(poResult); + if ( c_oSer_Person::person == type ) + { + OOX::Spreadsheet::CPerson* pPerson = new OOX::Spreadsheet::CPerson(); + READ1_DEF(length, res, this->ReadPerson, pPerson); + pPersonList->m_arrItems.push_back(pPerson); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryPersonReader::ReadPerson(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CPerson* pPerson = static_cast(poResult); + if ( c_oSer_Person::id == type ) + { + pPerson->id = m_oBufferedStream.GetString3(length); + } + else if ( c_oSer_Person::providerId == type ) + { + pPerson->providerId = m_oBufferedStream.GetString3(length); + } + else if ( c_oSer_Person::userId == type ) + { + pPerson->userId = m_oBufferedStream.GetString3(length); + } + else if ( c_oSer_Person::displayName == type ) + { + pPerson->displayName = m_oBufferedStream.GetString3(length); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +//------------------------------------------------------------------------------------------------------------------------------------ +BinaryCustomsReader::BinaryCustomsReader(NSBinPptxRW::CBinaryFileReader& oBufferedStream, OOX::Spreadsheet::CWorkbook* pWorkbook) : Binary_CommonReader(oBufferedStream), m_pWorkbook(pWorkbook) +{ +} +int BinaryCustomsReader::Read() +{ + int res = c_oSerConstants::ReadOk; + READ_TABLE_DEF(res, this->ReadCustom, NULL); + return res; +} +int BinaryCustomsReader::ReadCustom(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + + if (c_oSerCustoms::Custom == type) + { + OOX::CCustomXMLProps *pCustomXmlProps = new OOX::CCustomXMLProps(NULL); + + int res = c_oSerConstants::ReadOk; + READ1_DEF(length, res, this->ReadCustomContent, pCustomXmlProps); + + OOX::CCustomXML *pCustomXml = new OOX::CCustomXML(NULL, false); + pCustomXml->m_sXmlA = pCustomXmlProps->m_oCustomXmlContentA; + + smart_ptr oCustomXmlPropsFile(pCustomXmlProps); + smart_ptr oCustomXmlFile(pCustomXml); + + pCustomXml->Add(oCustomXmlPropsFile); + m_pWorkbook->Add(oCustomXmlFile); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryCustomsReader::ReadCustomContent(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::CCustomXMLProps* pCustomXMLProps = static_cast(poResult); + + if (c_oSerCustoms::Uri == type) + { + if (false == pCustomXMLProps->m_oShemaRefs.IsInit()) + pCustomXMLProps->m_oShemaRefs.Init(); + + pCustomXMLProps->m_oShemaRefs->m_arrItems.push_back(new OOX::CCustomXMLProps::CShemaRef()); + pCustomXMLProps->m_oShemaRefs->m_arrItems.back()->m_sUri = m_oBufferedStream.GetString3(length); + } + else if (c_oSerCustoms::ItemId == type) + { + pCustomXMLProps->m_oItemID.FromString(m_oBufferedStream.GetString3(length)); + } + else if (c_oSerCustoms::Content == type) + { + pCustomXMLProps->m_oCustomXmlContentA = m_oBufferedStream.GetString2A(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMetadata(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMetadata* pMetadata = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_Metadata::MetadataTypes == type) + { + pMetadata->m_oMetadataTypes.Init(); + READ1_DEF(length, res, this->ReadMetadataTypes, pMetadata->m_oMetadataTypes.GetPointer()); + } + else if (c_oSer_Metadata::MetadataStrings == type) + { + pMetadata->m_oMetadataStrings.Init(); + READ1_DEF(length, res, this->ReadMetadataStrings, pMetadata->m_oMetadataStrings.GetPointer()); + } + else if (c_oSer_Metadata::MdxMetadata == type) + { + pMetadata->m_oMdxMetadata.Init(); + READ1_DEF(length, res, this->ReadMdxMetadata, pMetadata->m_oMdxMetadata.GetPointer()); + } + else if (c_oSer_Metadata::CellMetadata == type) + { + pMetadata->m_oCellMetadata.Init(); + READ1_DEF(length, res, this->ReadMetadataBlocks, pMetadata->m_oCellMetadata.GetPointer()); + } + else if (c_oSer_Metadata::ValueMetadata == type) + { + pMetadata->m_oValueMetadata.Init(); + READ1_DEF(length, res, this->ReadMetadataBlocks, pMetadata->m_oValueMetadata.GetPointer()); + } + else if (c_oSer_Metadata::FutureMetadata == type) + { + OOX::Spreadsheet::CFutureMetadata* pFutureMetadata = new OOX::Spreadsheet::CFutureMetadata(); + READ1_DEF(length, res, this->ReadFutureMetadata, pFutureMetadata); + pMetadata->m_arFutureMetadata.push_back(pFutureMetadata); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMetadataTypes(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMetadataTypes* pMetadataTypes = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataType::MetadataType == type) + { + OOX::Spreadsheet::CMetadataType* pMetadataType = new OOX::Spreadsheet::CMetadataType(); + READ1_DEF(length, res, this->ReadMetadataType, pMetadataType); + pMetadataTypes->m_arrItems.push_back(pMetadataType); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMetadataType(BYTE type, long length, void* poResult) +{ + int res = c_oSerConstants::ReadOk; + OOX::Spreadsheet::CMetadataType* pMetadataType = static_cast(poResult); + + if (c_oSer_MetadataType::Name == type) + { + pMetadataType->m_oName = m_oBufferedStream.GetString3(length); + } + else if (c_oSer_MetadataType::MinSupportedVersion == type) + { + pMetadataType->m_oMinSupportedVersion = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataType::GhostRow == type) + { + pMetadataType->m_oGhostRow = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::GhostCol == type) + { + pMetadataType->m_oGhostCol = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::Edit == type) + { + pMetadataType->m_oEdit = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::Delete == type) + { + pMetadataType->m_oDelete = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::Copy == type) + { + pMetadataType->m_oCopy = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::PasteAll == type) + { + pMetadataType->m_oPasteAll = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::PasteFormulas == type) + { + pMetadataType->m_oPasteFormulas = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::PasteValues == type) + { + pMetadataType->m_oPasteValues = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::PasteFormats == type) + { + pMetadataType->m_oPasteFormats = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::PasteComments == type) + { + pMetadataType->m_oPasteComments = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::PasteDataValidation == type) + { + pMetadataType->m_oPasteDataValidation = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::PasteBorders == type) + { + pMetadataType->m_oPasteBorders = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::PasteColWidths == type) + { + pMetadataType->m_oPasteColWidths = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::PasteNumberFormats == type) + { + pMetadataType->m_oPasteNumberFormats = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::Merge == type) + { + pMetadataType->m_oMerge = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::SplitFirst == type) + { + pMetadataType->m_oSplitFirst = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::SplitAll == type) + { + pMetadataType->m_oSplitAll = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::RowColShift == type) + { + pMetadataType->m_oRowColShift = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::ClearAll == type) + { + pMetadataType->m_oClearAll = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::ClearFormats == type) + { + pMetadataType->m_oClearFormats = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::ClearContents == type) + { + pMetadataType->m_oClearContents = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::ClearComments == type) + { + pMetadataType->m_oClearComments = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::Assign == type) + { + pMetadataType->m_oAssign = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::Coerce == type) + { + pMetadataType->m_oCoerce = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataType::CellMeta == type) + { + pMetadataType->m_oCellMeta = m_oBufferedStream.GetBool(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMetadataStrings(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMetadataStrings* pMetadataStrings = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataString::MetadataString == type) + { + OOX::Spreadsheet::CMetadataString* pMetadataString = new OOX::Spreadsheet::CMetadataString(); + pMetadataString->m_oV = m_oBufferedStream.GetString3(length); + pMetadataStrings->m_arrItems.push_back(pMetadataString); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMdxMetadata(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMdxMetadata* pMdxMetadata = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MdxMetadata::Mdx == type) + { + OOX::Spreadsheet::CMdx* pMdx = new OOX::Spreadsheet::CMdx(); + READ1_DEF(length, res, this->ReadMdx, pMdx); + pMdxMetadata->m_arrItems.push_back(pMdx); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMdx(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMdx* pMdx = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MdxMetadata::NameIndex == type) + { + pMdx->m_oN = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MdxMetadata::FunctionTag == type) + { + pMdx->m_oF.Init(); + pMdx->m_oF->SetValueFromByte(m_oBufferedStream.GetUChar()); + } + else if (c_oSer_MdxMetadata::MdxTuple == type) + { + pMdx->m_oMdxTuple.Init(); + READ1_DEF(length, res, this->ReadMdxTuple, pMdx->m_oMdxTuple.GetPointer()); + } + else if (c_oSer_MdxMetadata::MdxSet == type) + { + pMdx->m_oMdxSet.Init(); + READ1_DEF(length, res, this->ReadMdxSet, pMdx->m_oMdxSet.GetPointer()); + } + else if (c_oSer_MdxMetadata::MdxKPI == type) + { + pMdx->m_oCMdxKPI.Init(); + READ1_DEF(length, res, this->ReadMdxKPI, pMdx->m_oCMdxKPI.GetPointer()); + } + else if (c_oSer_MdxMetadata::MdxMemeberProp == type) + { + pMdx->m_oMdxMemeberProp.Init(); + READ1_DEF(length, res, this->ReadMdxMemeberProp, pMdx->m_oMdxMemeberProp.GetPointer()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMetadataBlocks(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMetadataBlocks* pMetadataBlocks = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataBlock::MetadataBlock == type) + { + OOX::Spreadsheet::CMetadataBlock* pMetadataBlock = new OOX::Spreadsheet::CMetadataBlock(); + READ1_DEF(length, res, this->ReadMetadataBlock, pMetadataBlock); + pMetadataBlocks->m_arrItems.push_back(pMetadataBlock); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMetadataBlock(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMetadataBlock* pMetadataBlock = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataBlock::MetadataRecord == type) + { + OOX::Spreadsheet::CMetadataRecord* pMetadataRecord = new OOX::Spreadsheet::CMetadataRecord(); + READ1_DEF(length, res, this->ReadMetadataRecord, pMetadataRecord); + pMetadataBlock->m_arrItems.push_back(pMetadataRecord); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMetadataRecord(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMetadataRecord* pMetadataRecord = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataBlock::MetadataRecordType == type) + { + pMetadataRecord->m_oT = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataBlock::MetadataRecordValue == type) + { + pMetadataRecord->m_oV = m_oBufferedStream.GetULong(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadDynamicArrayProperties(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CDynamicArrayProperties* pDynamicArrayProperties = static_cast(poResult); + int res = c_oSerConstants::ReadOk; + + if (c_oSer_FutureMetadataBlock::DynamicArray == type) + { + pDynamicArrayProperties->m_oFDynamic = m_oBufferedStream.GetBool(); + } + else if (c_oSer_FutureMetadataBlock::CollapsedArray == type) + { + pDynamicArrayProperties->m_oFCollapsed = m_oBufferedStream.GetBool(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMetadataStringIndex(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMetadataStringIndex* pStringIndex = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataStringIndex::StringIsSet == type) + { + pStringIndex->m_oS = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataStringIndex::IndexValue == type) + { + pStringIndex->m_oX = m_oBufferedStream.GetULong(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMdxMemeberProp(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMdxMemeberProp* pMdxMemeberProp = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataMemberProperty::NameIndex == type) + { + pMdxMemeberProp->m_oN = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMemberProperty::Index == type) + { + pMdxMemeberProp->m_oNp = m_oBufferedStream.GetULong(); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMdxKPI(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMdxKPI* pMdxKPI = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataMdxKPI::NameIndex == type) + { + pMdxKPI->m_oN = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMdxKPI::Index == type) + { + pMdxKPI->m_oNp = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMdxKPI::Property == type) + { + pMdxKPI->m_oP.Init(); + pMdxKPI->m_oP->SetValueFromByte(m_oBufferedStream.GetUChar()); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMdxSet(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMdxSet* pMdxSet = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataMdxSet::Count == type) + { + pMdxSet->m_oC = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMdxSet::Index == type) + { + pMdxSet->m_oNs = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMdxSet::SortOrder == type) + { + pMdxSet->m_oO.Init(); + pMdxSet->m_oO->SetValueFromByte(m_oBufferedStream.GetUChar()); + } + else if (c_oSer_MetadataMdxSet::MetadataStringIndex == type) + { + OOX::Spreadsheet::CMetadataStringIndex* pMetadataStringIndex = new OOX::Spreadsheet::CMetadataStringIndex(); + READ1_DEF(length, res, this->ReadMetadataStringIndex, pMetadataStringIndex); + pMdxSet->m_arrItems.push_back(pMetadataStringIndex); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadMdxTuple(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CMdxTuple* pMdxTuple = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_MetadataMdxTuple::IndexCount == type) + { + pMdxTuple->m_oC = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMdxTuple::StringIndex == type) + { + pMdxTuple->m_oSi = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMdxTuple::CultureCurrency == type) + { + pMdxTuple->m_oCt = m_oBufferedStream.GetString3(length); + } + else if (c_oSer_MetadataMdxTuple::NumFmtIndex == type) + { + pMdxTuple->m_oFi = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMdxTuple::BackColor == type) + { + pMdxTuple->m_oBc = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMdxTuple::ForeColor == type) + { + pMdxTuple->m_oFc = m_oBufferedStream.GetULong(); + } + else if (c_oSer_MetadataMdxTuple::Italic == type) + { + pMdxTuple->m_oI = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataMdxTuple::Bold == type) + { + pMdxTuple->m_oB = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataMdxTuple::Underline == type) + { + pMdxTuple->m_oU = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataMdxTuple::Strike == type) + { + pMdxTuple->m_oSt = m_oBufferedStream.GetBool(); + } + else if (c_oSer_MetadataMdxTuple::MetadataStringIndex == type) + { + OOX::Spreadsheet::CMetadataStringIndex* pMetadataStringIndex = new OOX::Spreadsheet::CMetadataStringIndex(); + READ1_DEF(length, res, this->ReadMetadataStringIndex, pMetadataStringIndex); + pMdxTuple->m_arrItems.push_back(pMetadataStringIndex); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadFutureMetadata(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CFutureMetadata* pCFutureMetadata = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + + if (c_oSer_FutureMetadataBlock::Name == type) + { + pCFutureMetadata->m_oName = m_oBufferedStream.GetString3(length); + } + else if (c_oSer_FutureMetadataBlock::FutureMetadataBlock == type) + { + OOX::Spreadsheet::CFutureMetadataBlock* pFutureMetadataBlock = new OOX::Spreadsheet::CFutureMetadataBlock(); + READ1_DEF(length, res, this->ReadFutureMetadataBlock, pFutureMetadataBlock); + pCFutureMetadata->m_arrItems.push_back(pFutureMetadataBlock); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} +int BinaryWorkbookTableReader::ReadFutureMetadataBlock(BYTE type, long length, void* poResult) +{ + OOX::Spreadsheet::CFutureMetadataBlock* pFutureMetadataBlock = static_cast(poResult); + + int res = c_oSerConstants::ReadOk; + if (c_oSer_FutureMetadataBlock::RichValueBlock == type) + { + if (false == pFutureMetadataBlock->m_oExtLst.IsInit()) pFutureMetadataBlock->m_oExtLst.Init(); + + OOX::Drawing::COfficeArtExtension* pExt = new OOX::Drawing::COfficeArtExtension(); + pExt->m_sUri = L"{3e2802c4-a4d2-4d8b-9148-e3be6c30e623}"; + pExt->m_oRichValueBlock.Init(); + pExt->m_oRichValueBlock->m_oI = m_oBufferedStream.GetULong(); + + pFutureMetadataBlock->m_oExtLst->m_arrExt.push_back(pExt); + } + else if (c_oSer_FutureMetadataBlock::DynamicArrayProperties == type) + { + if (false == pFutureMetadataBlock->m_oExtLst.IsInit()) pFutureMetadataBlock->m_oExtLst.Init(); + + OOX::Drawing::COfficeArtExtension* pExt = new OOX::Drawing::COfficeArtExtension(); + pExt->m_sUri = L"{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}"; + pExt->m_oDynamicArrayProperties.Init(); + + READ1_DEF(length, res, this->ReadDynamicArrayProperties, pExt->m_oDynamicArrayProperties.GetPointer()); + pFutureMetadataBlock->m_oExtLst->m_arrExt.push_back(pExt); + } + else + res = c_oSerConstants::ReadUnknown; + return res; +} + +//------------------------------------------------------------------------------------------------------------------------------------ +BinaryFileReader::BinaryFileReader() +{ +} +int BinaryFileReader::Xml2Xlsx(const std::wstring& sSrcFileName, std::wstring sDstPath, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter, const std::wstring& sXMLOptions, bool bMacro) +{ + OOX::Spreadsheet::CXlsxFlat *pXlsxFlat = new OOX::Spreadsheet::CXlsxFlat(); + if (!pXlsxFlat) return AVS_FILEUTILS_ERROR_CONVERT; + + pXlsxFlat->m_strFontDirectory = pOfficeDrawingConverter->m_strFontDirectory; + + pXlsxFlat->read(OOX::CPath(sSrcFileName)); + if (pXlsxFlat->m_arWorksheets.empty()) + { + delete pXlsxFlat; + return AVS_FILEUTILS_ERROR_CONVERT; + } + OOX::Spreadsheet::CXlsx oXlsx; + + oXlsx.m_pStyles = pXlsxFlat->m_pStyles.GetPointerEmptyNullable(); oXlsx.bDeleteStyles = true; + oXlsx.m_pSharedStrings = pXlsxFlat->m_pSharedStrings.GetPointerEmptyNullable(); oXlsx.bDeleteSharedStrings = true; + oXlsx.m_pWorkbook = pXlsxFlat->m_pWorkbook.GetPointerEmptyNullable(); oXlsx.bDeleteWorkbook = true; + + for (size_t i = 0; i < pXlsxFlat->m_arWorksheets.size(); ++i) + { + OOX::Spreadsheet::CWorksheet *sheet = pXlsxFlat->m_arWorksheets[i]; + oXlsx.m_arWorksheets.push_back(sheet); + + if (false == oXlsx.m_pWorkbook->m_oSheets.IsInit()) oXlsx.m_pWorkbook->m_oSheets.Init(); + + while (oXlsx.m_pWorkbook->m_oSheets->m_arrItems.size() <= i) + oXlsx.m_pWorkbook->m_oSheets->m_arrItems.push_back(new OOX::Spreadsheet::CSheet()); + { + std::wstring rId = L"sId" + std::to_wstring(i + 1); + oXlsx.m_pWorkbook->m_oSheets->m_arrItems[i]->m_oRid = new SimpleTypes::CRelationshipId(rId); + + smart_ptr pFile(sheet); + oXlsx.m_pWorkbook->Add(rId, pFile); + } + + if (false == sheet->m_mapComments.empty()) + { + OOX::CVmlDrawing *vmlDrawing = new OOX::CVmlDrawing(NULL, false); + + NSCommon::smart_ptr pVmlDrawingFile(vmlDrawing); + const OOX::RId oRId = sheet->Add(pVmlDrawingFile); + + sheet->m_oLegacyDrawing.Init(); sheet->m_oLegacyDrawing->m_oId.Init(); + sheet->m_oLegacyDrawing->m_oId->SetValue(oRId.get()); + + vmlDrawing->m_mapComments = &sheet->m_mapComments; + + std::map mapByAuthors; + OOX::Spreadsheet::CComments* pComments = new OOX::Spreadsheet::CComments(NULL); + + pComments->m_oCommentList.Init(); + std::vector& aComments = pComments->m_oCommentList->m_arrItems; + + pComments->m_oAuthors.Init(); + + for (std::map::const_iterator it = sheet->m_mapComments.begin(); it != sheet->m_mapComments.end(); ++it) + { + OOX::Spreadsheet::CCommentItem* pCommentItem = it->second; + if (pCommentItem->IsValid()) + { + OOX::Spreadsheet::CComment* pNewComment = new OOX::Spreadsheet::CComment(); + if (pCommentItem->m_nRow.IsInit() && pCommentItem->m_nCol.IsInit()) + { + pNewComment->m_oRef.Init(); + pNewComment->m_oRef->SetValue(OOX::Spreadsheet::CCell::combineRef(pCommentItem->m_nRow.get(), pCommentItem->m_nCol.get())); + } + if (pCommentItem->m_sAuthor.IsInit()) + { + const std::wstring& sAuthor = pCommentItem->m_sAuthor.get(); + std::map::const_iterator pFind = mapByAuthors.find(sAuthor); + + int nAuthorId; + if (pFind != mapByAuthors.end()) + nAuthorId = (int)pFind->second; + else + { + nAuthorId = (int)mapByAuthors.size(); + + mapByAuthors.insert(std::make_pair(sAuthor, nAuthorId)); + + pComments->m_oAuthors->m_arrItems.push_back(sAuthor); + } + pNewComment->m_oAuthorId.Init(); + pNewComment->m_oAuthorId->SetValue(nAuthorId); + } + pNewComment->m_oText.reset(pCommentItem->m_oText.GetPointerEmptyNullable()); + + aComments.push_back(pNewComment); + } + } + NSCommon::smart_ptr pCommentsFile(pComments); + sheet->Add(pCommentsFile); + } + } + oXlsx.bDeleteWorksheets = false; + pXlsxFlat->m_arWorksheets.clear(); + + oXlsx.PrepareToWrite(); + + OOX::CContentTypes oContentTypes; + oXlsx.Write(sDstPath, oContentTypes); +//--------------------- + delete pXlsxFlat; + return 0; +} +int BinaryFileReader::ReadFile(const std::wstring& sSrcFileName, std::wstring sDstPath, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter, const std::wstring& sXMLOptions, bool &bMacro) +{ + bool bResultOk = false; + + NSFile::CFileBinary oFile; + + if (false == oFile.OpenFile(sSrcFileName)) return AVS_FILEUTILS_ERROR_CONVERT; + + DWORD nBase64DataSize = 0; + BYTE* pBase64Data = new BYTE[oFile.GetFileSize()]; + oFile.ReadFile(pBase64Data, oFile.GetFileSize(), nBase64DataSize); + oFile.CloseFile(); + + //проверяем формат + bool bValidFormat = false; + std::wstring sSignature(g_sFormatSignature); + size_t nSigLength = sSignature.length(); + if (nBase64DataSize > nSigLength) + { + std::string sCurSig((char*)pBase64Data, nSigLength); + std::wstring wsCurSig(sCurSig.begin(), sCurSig.end()); + + if (sSignature == wsCurSig) + { + bValidFormat = true; + } + } + if (bValidFormat) + { + //Читаем из файла версию и длину base64 + int nIndex = (int)nSigLength; + int nType = 0; + std::string version = ""; + std::string dst_len = ""; + + while (nIndex < nBase64DataSize) + { + nIndex++; + BYTE _c = pBase64Data[nIndex]; + if (_c == ';') + { + + if (0 == nType) + { + nType = 1; + continue; + } + else + { + nIndex++; + break; + } + } + if (0 == nType) + version += _c; + else + dst_len += _c; + } + int nVersion = g_nFormatVersion; + if (!version.empty()) + { + version = version.substr(1); + g_nCurFormatVersion = nVersion = std::stoi(version.c_str()); + } + bool bIsNoBase64 = nVersion == g_nFormatVersionNoBase64; + + NSBinPptxRW::CBinaryFileReader& oBufferedStream = *pOfficeDrawingConverter->m_pReader; + + int nDataSize = 0; + BYTE* pData = NULL; + if (!bIsNoBase64) + { + nDataSize = atoi(dst_len.c_str()); + pData = new BYTE[nDataSize]; + if (Base64::Base64Decode((const char*)(pBase64Data + nIndex), nBase64DataSize - nIndex, pData, &nDataSize)) + { + oBufferedStream.Init(pData, 0, nDataSize); + } + else + { + RELEASEARRAYOBJECTS(pData); + } + } + else + { + nDataSize = nBase64DataSize; + pData = pBase64Data; + oBufferedStream.Init(pData, 0, nDataSize); + oBufferedStream.Seek(nIndex); + } + + if (NULL != pData) + { + // File Type + std::wstring sDstPathCSV = sDstPath; + BYTE fileType; + UINT nCodePage; + std::wstring sDelimiter; + BYTE saveFileType; + _INT32 Lcid; + + SerializeCommon::ReadFileType(sXMLOptions, fileType, nCodePage, sDelimiter, saveFileType, Lcid); + // Делаем для CSV перебивку пути, иначе создается папка с одинаковым имеем (для rels) и файл не создается. + + if (BinXlsxRW::c_oFileTypes::CSV == fileType) + { + sDstPath = pOfficeDrawingConverter->GetTempPath(); + if (sDstPath.empty()) + sDstPath = NSDirectory::GetTempPath(); + + sDstPath = NSDirectory::CreateDirectoryWithUniqueName(sDstPath); + } + + std::wstring themePath = sDstPath + FILE_SEPARATOR_STR + OOX::Spreadsheet::FileTypes::Workbook.DefaultDirectory().GetPath() + FILE_SEPARATOR_STR + OOX::FileTypes::Theme.DefaultDirectory().GetPath(); + std::wstring drawingsPath = sDstPath + FILE_SEPARATOR_STR + OOX::Spreadsheet::FileTypes::Workbook.DefaultDirectory().GetPath() + FILE_SEPARATOR_STR + OOX::Spreadsheet::FileTypes::Drawings.DefaultDirectory().GetPath(); + std::wstring embeddingsPath = sDstPath + FILE_SEPARATOR_STR + OOX::Spreadsheet::FileTypes::Workbook.DefaultDirectory().GetPath() + FILE_SEPARATOR_STR + OOX::FileTypes::MicrosoftOfficeUnknown.DefaultDirectory().GetPath(); + std::wstring chartsPath = sDstPath + FILE_SEPARATOR_STR + OOX::Spreadsheet::FileTypes::Workbook.DefaultDirectory().GetPath() + FILE_SEPARATOR_STR + OOX::FileTypes::Chart.DefaultDirectory().GetPath(); + + oBufferedStream.m_pRels->m_pManager->SetDstCharts(chartsPath); + + bResultOk = true; + + if (BinXlsxRW::c_oFileTypes::XLSX == fileType) + { + OOX::Spreadsheet::CXlsx oXlsx; + SaveParams oSaveParams(drawingsPath, embeddingsPath, themePath, pOfficeDrawingConverter->GetContentTypes(), NULL, bMacro); + + try + { + ReadMainTable(oXlsx, oBufferedStream, OOX::CPath(sSrcFileName).GetDirectory(), sDstPath, oSaveParams, pOfficeDrawingConverter); + } + catch (...) + { + bResultOk = false; + } + + oXlsx.PrepareToWrite(); + oXlsx.Write(sDstPath, *oSaveParams.pContentTypes); + + bMacro = oSaveParams.bMacroEnabled; + } + else if (BinXlsxRW::c_oFileTypes::XLSB == fileType) + { + OOX::Spreadsheet::CXlsb oXlsb; + oXlsb.m_bWriteToXlsb = true; + + SaveParams oSaveParams(drawingsPath, embeddingsPath, themePath, pOfficeDrawingConverter->GetContentTypes(), NULL, bMacro); + + try + { + ReadMainTable(oXlsb, oBufferedStream, OOX::CPath(sSrcFileName).GetDirectory(), sDstPath, oSaveParams, pOfficeDrawingConverter); + } + catch (...) + { + bResultOk = false; + } + + OOX::CPath oXlPath = OOX::CPath(sDstPath).GetDirectory() / oXlsb.m_pWorkbook->DefaultDirectory(); + oXlsb.WriteWorkbook(oXlPath); + if(oXlsb.m_pStyles) + oXlsb.m_pStyles->OOX::File::m_pMainDocument = &oXlsb; + if(oXlsb.m_pSharedStrings) + oXlsb.m_pSharedStrings->OOX::File::m_pMainDocument = &oXlsb; + oXlsb.PrepareToWrite(); + oXlsb.WriteBin(sDstPath, *oSaveParams.pContentTypes); + + bMacro = oSaveParams.bMacroEnabled; + } + else + { + OOX::Spreadsheet::CXlsx oXlsx; + CSVWriter oCSVWriter; + + oCSVWriter.Init(oXlsx, nCodePage, sDelimiter, Lcid, false); + + bResultOk = oCSVWriter.Start(sDstPathCSV); + if (!bResultOk) return AVS_FILEUTILS_ERROR_CONVERT; + + SaveParams oSaveParams(drawingsPath, embeddingsPath, themePath, pOfficeDrawingConverter->GetContentTypes(), &oCSVWriter, false); + + try + { + ReadMainTable(oXlsx, oBufferedStream, OOX::CPath(sSrcFileName).GetDirectory(), sDstPath, oSaveParams, pOfficeDrawingConverter); + } + catch(...) + { + bResultOk = false; + } + oCSVWriter.End(); + } + } + if (!bIsNoBase64) + { + RELEASEARRAYOBJECTS(pData); + } + + } + RELEASEARRAYOBJECTS(pBase64Data); + + if (bResultOk) return 0; + else return AVS_FILEUTILS_ERROR_CONVERT; +} +int BinaryFileReader::ReadMainTable(OOX::Spreadsheet::CXlsx& oXlsx, NSBinPptxRW::CBinaryFileReader& oBufferedStream, const std::wstring& sFileInDir, const std::wstring& sOutDir, SaveParams& oSaveParams, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter) +{ + oBufferedStream.m_nDocumentType = XMLWRITER_DOC_TYPE_XLSX; + + long res = c_oSerConstants::ReadOk; + //mtLen + res = oBufferedStream.Peek(1) == false ? c_oSerConstants::ErrorStream : c_oSerConstants::ReadOk; + if (c_oSerConstants::ReadOk != res) + return res; + + long nOtherOffset = -1; + std::vector aTypes; + std::vector aOffBits; + long nOtherOffBits = -1; + long nSharedStringsOffBits = -1; + long nWorkbookOffBits = -1; + long nPersonListOffBits = -1; + BYTE mtLen = oBufferedStream.GetUChar(); + + for(int i = 0; i < mtLen; ++i) + { + //mtItem + res = oBufferedStream.Peek(5) == false ? c_oSerConstants::ErrorStream : c_oSerConstants::ReadOk; + if (c_oSerConstants::ReadOk != res) + return res; + + BYTE mtiType = 0; + if (false == oBufferedStream.GetUCharWithResult(&mtiType)) + break; + + long mtiOffBits = oBufferedStream.GetLong(); + if (c_oSerTableTypes::Other == mtiType) + nOtherOffBits = mtiOffBits; + else if (c_oSerTableTypes::SharedStrings == mtiType) + nSharedStringsOffBits = mtiOffBits; + else if (c_oSerTableTypes::Workbook == mtiType) + nWorkbookOffBits = mtiOffBits; + else if (c_oSerTableTypes::PersonList == mtiType) + nPersonListOffBits = mtiOffBits; + else + { + aTypes.push_back(mtiType); + aOffBits.push_back(mtiOffBits); + } + } + OOX::CPath pathMedia = sOutDir + FILE_SEPARATOR_STR + _T("xl") + FILE_SEPARATOR_STR + _T("media"); + std::wstring sMediaDir = pathMedia.GetPath(); + + boost::unordered_map mapMedia; + if (-1 != nOtherOffBits) + { + oBufferedStream.Seek(nOtherOffBits); + res = BinaryOtherTableReader(oBufferedStream, mapMedia, sFileInDir, oSaveParams, pOfficeDrawingConverter, sMediaDir).Read(); + if (c_oSerConstants::ReadOk != res) + return res; + + oXlsx.m_pTheme = oSaveParams.pTheme; + } + if (-1 != nSharedStringsOffBits) + { + oBufferedStream.Seek(nSharedStringsOffBits); + oXlsx.CreateSharedStrings(); + res = BinarySharedStringTableReader(oBufferedStream, *oXlsx.m_pSharedStrings).Read(); + if (c_oSerConstants::ReadOk != res) + return res; + } + oXlsx.CreateWorkbook(); + + boost::unordered_map> m_mapPivotCacheDefinitions; + if (-1 != nWorkbookOffBits) + { + oXlsx.m_pWorkbook->m_bMacroEnabled = oSaveParams.bMacroEnabled; + + oBufferedStream.Seek(nWorkbookOffBits); + auto bookReader = BinaryWorkbookTableReader(oBufferedStream, *oXlsx.m_pWorkbook, m_mapPivotCacheDefinitions, sOutDir, pOfficeDrawingConverter); + OOX::Spreadsheet::CXlsb* xlsb = dynamic_cast(&oXlsx); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + bookReader.m_pXlsb = xlsb; + } + res = bookReader.Read(); + if (c_oSerConstants::ReadOk != res) + return res; + oSaveParams.bMacroEnabled = oXlsx.m_pWorkbook->m_bMacroEnabled; + } + 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) + { + BYTE mtiType = aTypes[i]; + long mtiOffBits = aOffBits[i]; + + oBufferedStream.Seek(mtiOffBits); + switch(mtiType) + { + case c_oSerTableTypes::App: + { + OOX::CApp* pApp = new OOX::CApp(NULL); + pApp->fromPPTY(&oBufferedStream); + pApp->SetRequiredDefaults(); + oXlsx.m_pApp = pApp; + smart_ptr oCurFile(pApp); + oXlsx.Add(oCurFile); + }break; + case c_oSerTableTypes::Core: + { + OOX::CCore* pCore = new OOX::CCore(NULL); + pCore->fromPPTY(&oBufferedStream); + pCore->SetRequiredDefaults(); + oXlsx.m_pCore = pCore; + smart_ptr oCurFile(pCore); + oXlsx.Add(oCurFile); + }break; + case c_oSerTableTypes::CustomProperties: + { + PPTX::CustomProperties* oCustomProperties = new PPTX::CustomProperties(NULL); + oCustomProperties->fromPPTY(&oBufferedStream); + smart_ptr oCurFile(oCustomProperties); + oXlsx.Add(oCurFile); + }break; + case c_oSerTableTypes::Styles: + { + oXlsx.CreateStyles(); + res = BinaryStyleTableReader(oBufferedStream, *oXlsx.m_pStyles).Read(); + }break; + case c_oSerTableTypes::Worksheets: + { + auto sheetreader = BinaryWorksheetsTableReader(oBufferedStream, *oXlsx.m_pWorkbook, oXlsx.m_pSharedStrings, oXlsx.m_arWorksheets, oXlsx.m_mapWorksheets, mapMedia, sOutDir, sMediaDir, oSaveParams, pOfficeDrawingConverter, m_mapPivotCacheDefinitions); + OOX::Spreadsheet::CXlsb* xlsb = dynamic_cast(&oXlsx); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + sheetreader.m_bWriteToXlsb = true; + res = sheetreader.Read2xlsb(*xlsb); + } + else + res = sheetreader.Read(); + }break; + case c_oSerTableTypes::Customs: + { + res = BinaryCustomsReader(oBufferedStream, oXlsx.m_pWorkbook).Read(); + }break; + } + if (c_oSerConstants::ReadOk != res) + return res; + } + for (boost::unordered_map::const_iterator pPair = mapMedia.begin(); pPair != mapMedia.end(); ++pPair) + { + delete pPair->second; + } + mapMedia.clear(); + return res; +} +void BinaryFileReader::initWorkbook(OOX::Spreadsheet::CWorkbook* pWorkbook) +{ + +} + +} + diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.h b/OOXML/Binary/Sheets/Writer/BinaryReaderS.h similarity index 96% rename from OOXML/Binary/Sheets/Writer/BinaryReader.h rename to OOXML/Binary/Sheets/Writer/BinaryReaderS.h index d1551af149..9239105d73 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.h +++ b/OOXML/Binary/Sheets/Writer/BinaryReaderS.h @@ -137,12 +137,16 @@ namespace BinXlsxRW int ReadTableColumns(BYTE type, long length, void* poResult); int ReadTableColumn(BYTE type, long length, void* poResult); int ReadTableStyleInfo(BYTE type, long length, void* poResult); + int ReadTableXmlColumnPr(BYTE type, long length, void* poResult); int ReadQueryTableContent(BYTE type, long length, void* poResult); int ReadQueryTableRefresh(BYTE type, long length, void* poResult); int ReadQueryTableFields(BYTE type, long length, void* poResult); int ReadQueryTableField(BYTE type, long length, void* poResult); int ReadQueryTableDeletedFields(BYTE type, long length, void* poResult); int ReadQueryTableDeletedField(BYTE type, long length, void* poResult); + int ReadTableCache(long length, void* poResult); + int ReadCacheParts(BYTE type,long length, void* poResult); + int ReadCachePart(BYTE type, long length, void* poResult); }; class BinarySharedStringTableReader : public Binary_CommonReader { @@ -276,6 +280,7 @@ namespace BinXlsxRW int ReadMdxMemeberProp(BYTE type, long length, void* poResult); int ReadMetadataStringIndex(BYTE type, long length, void* poResult); int ReadDynamicArrayProperties(BYTE type, long length, void* poResult); + OOX::Spreadsheet::CXlsb* m_pXlsb = NULL; }; class BinaryCommentReader : public Binary_CommonReader { @@ -301,7 +306,9 @@ namespace BinXlsxRW { Binary_CommonReader2 m_oBcr2; NSFile::CStreamWriter* m_pCurStreamWriter; + XLS::StreamCacheWriterPtr m_pCurStreamWriterBin; NSBinPptxRW::CDrawingConverter* m_pOfficeDrawingConverter; + OOX::Spreadsheet::CXlsb* m_pXlsb; OOX::Spreadsheet::CWorkbook& m_oWorkbook; OOX::Spreadsheet::CSharedStrings* m_pSharedStrings; @@ -330,9 +337,13 @@ namespace BinXlsxRW boost::unordered_map& mapMedia, const std::wstring& sDestinationDir, const std::wstring& sMediaDir, SaveParams& oSaveParams, NSBinPptxRW::CDrawingConverter* pOfficeDrawingConverter, boost::unordered_map>& mapPivotCacheDefinitions); int Read(); + int Read2xlsb(OOX::Spreadsheet::CXlsb &xlsb); int ReadWorksheetsTableContent(BYTE type, long length, void* poResult); + int ReadWorksheetsCache(BYTE type, long length, void* poResult); int ReadWorksheetSeekPositions(BYTE type, long length, void* poResult); int ReadWorksheet(boost::unordered_map>& mapPos, NSFile::CStreamWriter& oStreamWriter, void* poResult); + int ReadWorksheet(boost::unordered_map>& mapPos, XLS::StreamCacheWriterPtr& oStreamWriter, void* poResult);//2xlsb + int ReadSheetCache(boost::unordered_map>& mapPos, void* poResult); int ReadPivotTable(BYTE type, long length, void* poResult); int ReadWorksheetProp(BYTE type, long length, void* poResult); int ReadWorksheetCols(BYTE type, long length, void* poResult); @@ -403,6 +414,7 @@ namespace BinXlsxRW void WriteComments(); void AddLineBreak(OOX::Spreadsheet::CSi& oSi); std::wstring GetControlVmlShape(void* pControl); + bool m_bWriteToXlsb = false; }; class BinaryOtherTableReader : public Binary_CommonReader { diff --git a/OOXML/Common/SimpleTypes_Draw.cpp b/OOXML/Common/SimpleTypes_Draw.cpp new file mode 100644 index 0000000000..0a3c914ee2 --- /dev/null +++ b/OOXML/Common/SimpleTypes_Draw.cpp @@ -0,0 +1,146 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "SimpleTypes_Draw.h" + +namespace SimpleTypes +{ +namespace Draw +{ + EForeignType CForeignType::FromString(const std::wstring& sValue) + { + if (L"Bitmap" == sValue) this->m_eValue = typeBitmap; + else if (L"EnhMetaFile" == sValue) this->m_eValue = typeEnhMetaFile; + else if (L"Ink" == sValue) this->m_eValue = typeInk; + else if (L"Object" == sValue) this->m_eValue = typeObject; + else this->m_eValue = typeBitmap; + + return this->m_eValue; + } + std::wstring CForeignType::ToString() const + { + switch (this->m_eValue) + { + case typeBitmap: return L"Bitmap"; + case typeEnhMetaFile: return L"EnhMetaFile"; + case typeInk: return L"Ink"; + case typeObject: return L"Object"; + default: return L"Bitmap"; + + } + } + ECompressionType CCompressionType::FromString(const std::wstring& sValue) + { + if (L"JPEG" == sValue || L"JPG" == sValue) this->m_eValue = typeJPEG; + else if (L"DIB" == sValue) this->m_eValue = typeDIB; + else if (L"PNG" == sValue) this->m_eValue = typePNG; + else if (L"TIFF" == sValue) this->m_eValue = typeTIFF; + else if (L"GIF" == sValue) this->m_eValue = typeGIF; + else this->m_eValue = typeJPEG; + + return this->m_eValue; + } + std::wstring CCompressionType::ToString() const + { + switch (this->m_eValue) + { + case typeJPEG: return L"JPEG"; + case typeDIB: return L"DIB"; + case typePNG: return L"PNG"; + case typeTIFF: return L"TIFF"; + case typeGIF: return L"GIF"; + default: return L"JPEG"; + + } + } + EShapeType CShapeType::FromString(const std::wstring& sValue) + { + if (L"Group" == sValue) this->m_eValue = typeGroup; + else if (L"Guide" == sValue) this->m_eValue = typeGuide; + else if (L"Foreign" == sValue) this->m_eValue = typeForeign; + else this->m_eValue = typeShape; + + return this->m_eValue; + } + std::wstring CShapeType::ToString() const + { + switch (this->m_eValue) + { + case typeGroup: return L"Group"; + case typeGuide: return L"Guide"; + case typeForeign: return L"Foreign"; + default: return L"Shape"; + + } + } + EContainerType CContainerType::FromString(const std::wstring& sValue) + { + if (L"Page" == sValue) this->m_eValue = typeContainerPage; + else if (L"Sheet" == sValue) this->m_eValue = typeContainerSheet; + else if (L"Master" == sValue) this->m_eValue = typeContainerMaster; + else this->m_eValue = typeContainerPage; + + return this->m_eValue; + } + + std::wstring CContainerType::ToString() const + { + switch (this->m_eValue) + { + case typeContainerPage: return L"Page"; + case typeContainerSheet: return L"Sheet"; + case typeContainerMaster: return L"Master"; + default: return L"Page"; + } + } + + EWindowType CWindowType::FromString(const std::wstring& sValue) + { + if (L"Drawing" == sValue) this->m_eValue = EWindowType::typeDrawing; + else if (L"Sheet" == sValue) this->m_eValue = EWindowType::typeSheet; + else if (L"Stencil" == sValue) this->m_eValue = EWindowType::typeStencil; + else this->m_eValue = EWindowType::typeSheet; + + return this->m_eValue; + } + std::wstring CWindowType::ToString() const + { + switch (this->m_eValue) + { + case EWindowType::typeDrawing: return L"Drawing"; + case EWindowType::typeSheet: return L"Sheet"; + case EWindowType::typeStencil: return L"Stencil"; + default: return L"Sheet"; + + } + } +}// Draw +} // SimpleTypes diff --git a/OOXML/Common/SimpleTypes_Draw.h b/OOXML/Common/SimpleTypes_Draw.h new file mode 100644 index 0000000000..67a2e12f90 --- /dev/null +++ b/OOXML/Common/SimpleTypes_Draw.h @@ -0,0 +1,85 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "SimpleTypes_Base.h" + +namespace SimpleTypes +{ +namespace Draw +{ + enum EForeignType + { + typeBitmap = 0, + typeEnhMetaFile = 1, + typeInk = 2, + typeObject = 3 + }; + DEFINE_SIMPLE_TYPE(CForeignType, EForeignType, typeBitmap) + + enum ECompressionType + { + typeJPEG = 0, + typeDIB = 1, + typePNG = 2, + typeTIFF = 3, + typeGIF = 4 + }; + DEFINE_SIMPLE_TYPE(CCompressionType, ECompressionType, typeJPEG) + + enum EShapeType + { + typeGroup = 0, + typeGuide = 1, + typeForeign = 2, + typeShape = 3 + }; + DEFINE_SIMPLE_TYPE(CShapeType, EShapeType, typeShape) + + enum EWindowType + { + typeDrawing = 0, + typeSheet = 1, + typeStencil =2 + }; + DEFINE_SIMPLE_TYPE(CWindowType, EWindowType, typeDrawing) + + enum EContainerType + { + typeContainerPage = 0, + typeContainerSheet = 1, + typeContainerMaster = 2 + }; + DEFINE_SIMPLE_TYPE(CContainerType, EContainerType, typeContainerPage) + +}// Draw +} // SimpleTypes diff --git a/OOXML/Common/SimpleTypes_Spreadsheet.cpp b/OOXML/Common/SimpleTypes_Spreadsheet.cpp index 24d91f3e28..17a58c1293 100644 --- a/OOXML/Common/SimpleTypes_Spreadsheet.cpp +++ b/OOXML/Common/SimpleTypes_Spreadsheet.cpp @@ -589,7 +589,7 @@ namespace SimpleTypes this->m_eValue = underlineDouble; else if(L"doubleAccounting" == sValue) this->m_eValue = underlineDoubleAccounting; - else if(L"none" == sValue) + else if(L"none" == sValue || L"0" == sValue) this->m_eValue = underlineNone; else if(L"single" == sValue) this->m_eValue = underlineSingle; @@ -3415,5 +3415,25 @@ namespace SimpleTypes } return L"edit"; } + EXmlDataType CXmlDataType::FromString(const std::wstring& sValue) + { + if (L"date" == sValue) + this->m_eValue = typeDate; + else if (L"float" == sValue) + this->m_eValue = typeFloat; + else + this->m_eValue = typeString; + return this->m_eValue; + } + std::wstring CXmlDataType::ToString() const + { + switch (this->m_eValue) + { + case typeString: return L"string"; break; + case typeDate: return L"date"; break; + case typeFloat: return L"float"; break; + } + return L"edit"; + } }// Spreadsheet } // SimpleTypes diff --git a/OOXML/Common/SimpleTypes_Spreadsheet.h b/OOXML/Common/SimpleTypes_Spreadsheet.h index 70de28e593..77a18ce49b 100644 --- a/OOXML/Common/SimpleTypes_Spreadsheet.h +++ b/OOXML/Common/SimpleTypes_Spreadsheet.h @@ -1449,5 +1449,12 @@ namespace SimpleTypes }; DEFINE_SIMPLE_TYPE(CUserProtectedRangeType, EUserProtectedRangeType, typeView) + enum EXmlDataType + { + typeString = 0, + typeDate = 1, + typeFloat = 2 //... + }; + DEFINE_SIMPLE_TYPE(CXmlDataType, EXmlDataType, typeString) }// Spreadsheet } // SimpleTypes diff --git a/OOXML/DocxFormat/CustomXml.h b/OOXML/DocxFormat/CustomXml.h index 09819fdb28..a482db61ac 100644 --- a/OOXML/DocxFormat/CustomXml.h +++ b/OOXML/DocxFormat/CustomXml.h @@ -102,10 +102,8 @@ namespace OOX virtual const CPath DefaultDirectory() const; virtual const CPath DefaultFileName() const; - // Attributes SimpleTypes::CGuid m_oItemID; - // Childs nullable m_oShemaRefs; //------------- for write from binary std::wstring m_oCustomXmlContent; diff --git a/OOXML/DocxFormat/Diagram/DiagramData.cpp b/OOXML/DocxFormat/Diagram/DiagramData.cpp index 018e09761e..3e2c67465f 100644 --- a/OOXML/DocxFormat/Diagram/DiagramData.cpp +++ b/OOXML/DocxFormat/Diagram/DiagramData.cpp @@ -40,6 +40,7 @@ #include "../Document.h" #include "../../XlsxFormat/Xlsx.h" +#include "../../VsdxFormat/Vsdx.h" #include "../../PPTXFormat/Logic/SpTree.h" #include "../../Binary/Presentation/BinaryFileReaderWriter.h" @@ -1776,6 +1777,7 @@ namespace OOX { m_bDocument = (NULL != dynamic_cast(pMain)); m_bSpreadsheets = (NULL != dynamic_cast(pMain)); + m_bVisioPages = (NULL != dynamic_cast(pMain)); read( oRootPath, oPath ); } diff --git a/OOXML/DocxFormat/Drawing/DrawingExt.cpp b/OOXML/DocxFormat/Drawing/DrawingExt.cpp index 557d7221e7..0177c8dfb3 100644 --- a/OOXML/DocxFormat/Drawing/DrawingExt.cpp +++ b/OOXML/DocxFormat/Drawing/DrawingExt.cpp @@ -904,8 +904,16 @@ namespace OOX { if(i->m_sUri == L"{78C0D931-6437-407d-A8EE-F0AAD7539E65}") { - auto formatPtr(new XLSB::CONDITIONALFORMATTINGS); - ptr->m_CONDITIONALFORMATTINGS = XLS::BaseObjectPtr{formatPtr}; + XLSB::CONDITIONALFORMATTINGS *formatPtr = NULL; + if(!ptr->m_CONDITIONALFORMATTINGS) + { + formatPtr = new XLSB::CONDITIONALFORMATTINGS; + ptr->m_CONDITIONALFORMATTINGS = XLS::BaseObjectPtr{formatPtr}; + } + else + { + formatPtr = static_cast(ptr->m_CONDITIONALFORMATTINGS.get()); + } for(auto j:i->m_arrConditionalFormatting) { formatPtr->m_arCONDITIONALFORMATTING14.push_back(j->toBin14()); diff --git a/OOXML/DocxFormat/IFileContainer.cpp b/OOXML/DocxFormat/IFileContainer.cpp index 342c58e712..fb069e6fbc 100644 --- a/OOXML/DocxFormat/IFileContainer.cpp +++ b/OOXML/DocxFormat/IFileContainer.cpp @@ -45,6 +45,7 @@ #include "../PPTXFormat/LegacyDiagramText.h" #include "../XlsxFormat/FileFactory_Spreadsheet.h" +#include "../VsdxFormat/FileFactory_Draw.h" namespace OOX { @@ -54,6 +55,7 @@ namespace OOX IFileContainer::IFileContainer(OOX::Document* pMain) : m_pMainDocument(pMain) { + m_bVisioPages = false; m_bSpreadsheets = false; m_lMaxRid = 0; } @@ -101,6 +103,9 @@ namespace OOX if (m_bSpreadsheets) pFile = OOX::Spreadsheet::CreateFile(oRootPath, oPath, oRels.m_arRelations[i], m_pMainDocument); + if (m_bVisioPages) + pFile = OOX::Draw::CreateFile(oRootPath, oPath, oRels.m_arRelations[i], m_pMainDocument); + if (pFile.IsInit() == false || pFile->type() == FileTypes::Unknown) pFile = OOX::CreateFile(oRootPath, oPath, oRels.m_arRelations[i], m_pMainDocument); diff --git a/OOXML/DocxFormat/IFileContainer.h b/OOXML/DocxFormat/IFileContainer.h index 6d92a3df2b..aed99269c6 100644 --- a/OOXML/DocxFormat/IFileContainer.h +++ b/OOXML/DocxFormat/IFileContainer.h @@ -53,7 +53,9 @@ namespace OOX IFileContainer(OOX::Document* pMain); virtual ~IFileContainer(); - bool m_bSpreadsheets; + bool m_bVisioPages = false; + bool m_bSpreadsheets = false; + static boost::unordered_map m_mapEnumeratedGlobal; OOX::Document* m_pMainDocument; smart_ptr m_pCurRels; diff --git a/OOXML/DocxFormat/Media/Media.cpp b/OOXML/DocxFormat/Media/Media.cpp index f6e5638ce1..8c3d095d26 100644 --- a/OOXML/DocxFormat/Media/Media.cpp +++ b/OOXML/DocxFormat/Media/Media.cpp @@ -95,9 +95,6 @@ namespace OOX if (!CSystemUtility::IsFileExist(newFilePath / newFilename)) { - std::wstring ext = filename.GetExtention(); - if (false == ext.empty()) content.AddDefault(ext.substr(1)); - if (false == m_Data.empty()) { NSFile::CFileBinary file; @@ -112,6 +109,8 @@ namespace OOX copy_to(newFilePath); } } + std::wstring ext = filename.GetExtention(); + if (false == ext.empty()) content.AddDefault(ext.substr(1)); } void Media::set_filename(const std::wstring & file_path, bool bExternal) { diff --git a/OOXML/DocxFormat/Media/OleObject.cpp b/OOXML/DocxFormat/Media/OleObject.cpp index 3d5b00c733..40426ea36a 100644 --- a/OOXML/DocxFormat/Media/OleObject.cpp +++ b/OOXML/DocxFormat/Media/OleObject.cpp @@ -31,18 +31,42 @@ */ #include "OleObject.h" +#include "Image.h" namespace OOX { - OleObject::OleObject(OOX::Document *pMain, bool bMsPackage, bool bDocument) : Media (pMain, bDocument) + OleObject::OleObject(OOX::Document *pMain, bool bMsPackage, bool bDocument) : OOX::IFileContainer(pMain), Media (pMain, bDocument) { m_bMsPackage = bMsPackage; } - OleObject::OleObject(OOX::Document *pMain, const OOX::CPath& filename, bool bMsPackage) : Media (pMain) + OleObject::OleObject(OOX::Document *pMain, const OOX::CPath& filename, bool bMsPackage) : OOX::IFileContainer(pMain), Media (pMain) { m_bMsPackage = bMsPackage; read(filename); } + void OleObject::read(const CPath& oFilePath) + { + CPath oRootPath; + read(oRootPath, oFilePath); + } + void OleObject::read(const CPath& oRootPath, const CPath& oFilePath) + { + IFileContainer::Read(oRootPath, oFilePath); + + Media::read(oFilePath); + + smart_ptr pFile = this->Find(OOX::FileTypes::Image); + Image* pImage = dynamic_cast(pFile.GetPointer()); + if (pImage) + { + m_filenameCache = pImage->filename(); + } + } + void OleObject::write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const + { + Media::write(oFilePath, oDirectory, oContent); + IFileContainer::Write(oFilePath, oDirectory, oContent); + } const FileType OleObject::type() const { if (m_bMsPackage) return OOX::FileTypes::MicrosoftOfficeUnknown; diff --git a/OOXML/DocxFormat/Media/OleObject.h b/OOXML/DocxFormat/Media/OleObject.h index 18e5fc8a0d..b953d42f85 100644 --- a/OOXML/DocxFormat/Media/OleObject.h +++ b/OOXML/DocxFormat/Media/OleObject.h @@ -30,15 +30,14 @@ * */ #pragma once -#ifndef OOX_OLE_OBJECT_INCLUDE_H_ -#define OOX_OLE_OBJECT_INCLUDE_H_ +#include "../../DocxFormat/IFileContainer.h" #include "Media.h" #include "../../XlsxFormat/FileTypes_Spreadsheet.h" namespace OOX { - class OleObject : public Media + class OleObject : public OOX::IFileContainer, public Media { public: OleObject(OOX::Document *pMain, bool bMsPackage = false, bool bDocument = true); @@ -49,6 +48,10 @@ namespace OOX virtual const CPath DefaultDirectory() const; virtual const CPath DefaultFileName() const; + virtual void read(const CPath& oFilePath); + virtual void read(const CPath& oRootPath, const CPath& oFilePath); + virtual void write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const; + void set_filename_cache(const std::wstring & file_path); void set_filename_cache(CPath & file_path); void set_MsPackage(bool val); @@ -61,5 +64,3 @@ namespace OOX bool m_bMsPackage; }; } // namespace OOX - -#endif // OOX_OLE_OBJECT_INCLUDE_H_ diff --git a/OOXML/DocxFormat/WritingElement.h b/OOXML/DocxFormat/WritingElement.h index 90aede38a6..ac64eb2faf 100644 --- a/OOXML/DocxFormat/WritingElement.h +++ b/OOXML/DocxFormat/WritingElement.h @@ -188,7 +188,11 @@ namespace OOX {\ Value = Reader.GetText();\ } - +#define WritingElement_ReadAttributesA_Read_ifChar(Reader, AttrName, Value) \ + if ( strcmp(AttrName, wsName) == 0 )\ + {\ + Value = Reader.GetTextA();\ +} #define WritingElement_ReadAttributes_Read_else_if(Reader, AttrName, Value) \ else if ( AttrName == wsName )\ Value = Reader.GetText(); @@ -197,6 +201,10 @@ namespace OOX else if ( strcmp(AttrName, wsName) == 0 )\ Value = Reader.GetText(); +#define WritingElement_ReadAttributesA_Read_else_ifChar(Reader, AttrName, Value) \ + else if ( strcmp(AttrName, wsName) == 0 )\ + Value = Reader.GetTextA(); + #define WritingElement_ReadAttributes_ReadSingle(Reader, AttrName, Value) \ if ( AttrName == wsName )\ {\ @@ -1342,6 +1350,7 @@ namespace OOX et_x_TableColumns, et_x_TableColumn, et_x_TableStyleInfo, + et_x_xmlColumnPr, et_x_AltTextTable, et_x_SortState, et_x_SortCondition, @@ -1542,9 +1551,88 @@ namespace OOX et_x_MdxSet, et_x_MdxMemeberProp, et_x_MdxKPI, - et_x_DynamicArrayProperties, - et_x_RichValueBlock + et_x_RichValueBlock, + et_x_MapInfo, + et_x_Schema, + et_x_Map, + et_x_DataBinding, + et_x_SingleXmlCells, + et_x_SingleXmlCell, + et_x_xmlCellPr, + et_x_xmlPr, + + et_dr_Masters, + et_dr_Pages, + et_dr_DocumentSettings, + et_dr_ColorEntry, + et_dr_Colors, + et_dr_FaceName, + et_dr_FaceNames, + et_dr_StyleSheet, + et_dr_StyleSheets, + et_dr_EventItem, + et_dr_EventList, + et_dr_DocumentSheet, + et_dr_HeaderFooter, + et_dr_Shapes, + et_dr_Shape, + et_dr_Cell, + et_dr_Trigger, + et_dr_Section, + et_dr_Row, + et_dr_Text, + et_dr_text_cp, + et_dr_text_pp, + et_dr_text_tp, + et_dr_text_fld, + et_dr_text_text, + et_dr_ForeignData, + et_dr_Rel, + et_dr_RefBy, + et_dr_Connects, + et_dr_Connect, + et_dr_Page, + et_dr_Master, + et_dr_PageSheet, + et_dr_Icon, + et_dr_DataConnections, + et_dr_DataConnection, + et_dr_DataRecordSets, + et_dr_DataRecordSet, + et_dr_DataColumns, + et_dr_DataColumn, + et_dr_PrimaryKey, + et_dr_RowKeyValue, + et_dr_RowMap, + et_dr_RefreshConflict, + et_dr_AutoLinkComparison, + et_dr_ADOData, + et_dr_Windows, + et_dr_Window, + et_dr_SnapAngles, + et_dr_SnapAngle, + et_dr_PublishSettings, + et_dr_PublishedPage, + et_dr_RefreshableData, + et_dr_Solutions, + et_dr_Solution, + et_dr_Issues, + et_dr_Issue, + et_dr_IssueTarget, + et_dr_RuleInfo, + et_dr_Rule, + et_dr_RuleSet, + et_dr_RuleSets, + et_dr_CRuleFormula, + et_dr_RuleSetFlags, + et_dr_ValidationProperties, + et_dr_Comments, + et_dr_CommentList, + et_dr_AuthorList, + et_dr_CommentEntry, + et_dr_AuthorEntry + }; class File; diff --git a/OOXML/PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.cpp b/OOXML/PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.cpp index 3d46d556a3..3e243830fd 100644 --- a/OOXML/PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.cpp +++ b/OOXML/PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.cpp @@ -5933,7 +5933,59 @@ HRESULT CDrawingConverter::SaveObject(LONG lStart, LONG lLength, const std::wstr oXmlWriter.WriteString(L"\ "); } - oElem.toXmlWriter(&oXmlWriter); + + if (m_pReader->m_nDocumentType == XMLWRITER_DOC_TYPE_DOCX) + { + PPTX::Logic::Xfrm *pXfrm = NULL; + if (oElem.getType() == OOX::et_pic) + { + PPTX::Logic::Pic& s = oElem.as(); + if (s.spPr.xfrm.IsInit() == false) + { + s.spPr.xfrm.Init(); pXfrm = s.spPr.xfrm.GetPointer(); + } + } + else if (oElem.getType() == OOX::et_graphicFrame) + { + PPTX::Logic::GraphicFrame& s = oElem.as(); + if (s.xfrm.IsInit() == false) + { + s.xfrm.Init(); pXfrm = s.xfrm.GetPointer(); + } + } + else if (oElem.getType() == OOX::et_p_ShapeTree) + { + PPTX::Logic::SpTree& s = oElem.as(); + if (s.grpSpPr.xfrm.IsInit() == false) + { + s.grpSpPr.xfrm.Init(); pXfrm = s.grpSpPr.xfrm.GetPointer(); + } + } + else if (oElem.getType() == OOX::et_a_Shape) + { + PPTX::Logic::Shape& s = oElem.as(); + if (s.spPr.xfrm.IsInit() == false) + { + s.spPr.xfrm.Init(); pXfrm = s.spPr.xfrm.GetPointer(); + } + } + else if (oElem.getType() == OOX::et_cxnSp) + { + PPTX::Logic::CxnSp& s = oElem.as(); + if (s.spPr.xfrm.IsInit() == false) + { + s.spPr.xfrm.Init(); pXfrm = s.spPr.xfrm.GetPointer(); + } + } + if (pXfrm) + { + pXfrm->extX = 0; + pXfrm->extY = 0; + pXfrm->offX = 0; + pXfrm->offY = 0; + } + } + oElem.toXmlWriter(&oXmlWriter); if (bAddGraphicData) oXmlWriter.WriteString(L""); diff --git a/OOXML/PPTXFormat/Logic/BgPr.cpp b/OOXML/PPTXFormat/Logic/BgPr.cpp index a7fa605540..f4ada9564e 100644 --- a/OOXML/PPTXFormat/Logic/BgPr.cpp +++ b/OOXML/PPTXFormat/Logic/BgPr.cpp @@ -39,8 +39,34 @@ namespace PPTX void BgPr::fromXML(XmlUtils::CXmlNode& node) { XmlMacroReadAttributeBase(node, L"shadeToTitle", shadeToTitle); - Fill.GetFillFrom(node); - EffectList.GetEffectListFrom(node); + + std::vector oNodes; + if (node.GetNodes(L"*", oNodes)) + { + size_t nCount = oNodes.size(); + for (size_t i = 0; i < nCount; ++i) + { + XmlUtils::CXmlNode& oNode = oNodes[i]; + + std::wstring strName = XmlUtils::GetNameNoNS(oNode.GetName()); + + if (L"blipFill" == strName || + L"gradFill" == strName || + L"grpFill" == strName || + L"noFill" == strName || + L"pattFill" == strName || + L"solidFill" == strName) + { + Fill.fromXML(oNode); + } + else if (L"effectDag" == strName || + L"effectLst" == strName) + { + EffectList.fromXML(oNode); + } + } + } + FillParentPointersForChilds(); } diff --git a/OOXML/PPTXFormat/Logic/CxnSp.cpp b/OOXML/PPTXFormat/Logic/CxnSp.cpp index 4d7f12f28f..788d0e3a62 100644 --- a/OOXML/PPTXFormat/Logic/CxnSp.cpp +++ b/OOXML/PPTXFormat/Logic/CxnSp.cpp @@ -122,7 +122,7 @@ namespace PPTX std::wstring CxnSp::toXML() const { XmlUtils::CAttribute oAttr; - oAttr.Write(L"macro", macro); + oAttr.Write2(L"macro", macro); XmlUtils::CNodeValue oValue; oValue.Write(nvCxnSpPr); @@ -201,5 +201,96 @@ namespace PPTX spPr.Fill.Merge(fill); return BGRA; } + + void CxnSp::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->StartRecord(SPTREE_TYPE_CXNSP); + + pWriter->WriteRecord1(0, nvCxnSpPr); + pWriter->WriteRecord1(1, spPr); + pWriter->WriteRecord2(2, style); + + if (macro.IsInit()) + { + pWriter->StartRecord(SPTREE_TYPE_MACRO); + pWriter->WriteString1(0, *macro); + pWriter->EndRecord(); + } + pWriter->EndRecord(); + } + void CxnSp::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + + while (pReader->GetPos() < _end_rec) + { + BYTE _at = pReader->GetUChar(); + switch (_at) + { + case 0: + { + nvCxnSpPr.fromPPTY(pReader); + }break; + case 1: + { + spPr.fromPPTY(pReader); + }break; + case 2: + { + style = new ShapeStyle(L"p"); + style->fromPPTY(pReader); + }break; + case SPTREE_TYPE_MACRO: + { + pReader->Skip(5); // type + size + macro = pReader->GetString2(); + }break; + default: + { + }break; + } + } + + pReader->Seek(_end_rec); + } + void CxnSp::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_Start(oReader) + WritingElement_ReadAttributes_Read_if(oReader, _T("macro"), macro) + WritingElement_ReadAttributes_End(oReader) + } + void CxnSp::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + std::wstring namespace_ = m_namespace; + + if (pWriter->m_lDocType == XMLWRITER_DOC_TYPE_DOCX || + pWriter->m_lDocType == XMLWRITER_DOC_TYPE_DOCX_GLOSSARY) namespace_ = L"wps"; + else if (pWriter->m_lDocType == XMLWRITER_DOC_TYPE_XLSX) namespace_ = L"xdr"; + else if (pWriter->m_lDocType == XMLWRITER_DOC_TYPE_GRAPHICS) namespace_ = L"a"; + else if (pWriter->m_lDocType == XMLWRITER_DOC_TYPE_CHART_DRAWING) namespace_ = L"cdr"; + else if (pWriter->m_lDocType == XMLWRITER_DOC_TYPE_DIAGRAM) namespace_ = L"dgm"; + else if (pWriter->m_lDocType == XMLWRITER_DOC_TYPE_DSP_DRAWING) namespace_ = L"dsp"; + + pWriter->StartNode(namespace_ + L":cxnSp"); + pWriter->WriteAttribute2(L"macro", macro); + pWriter->EndAttributes(); + + nvCxnSpPr.toXmlWriter(pWriter); + spPr.toXmlWriter(pWriter); + + if (style.is_init()) + { + if (pWriter->m_lDocType == XMLWRITER_DOC_TYPE_DOCX || + pWriter->m_lDocType == XMLWRITER_DOC_TYPE_DOCX_GLOSSARY) style->m_namespace = L"wps"; + else if (pWriter->m_lDocType == XMLWRITER_DOC_TYPE_XLSX) style->m_namespace = L"xdr"; + else if (pWriter->m_lDocType == XMLWRITER_DOC_TYPE_GRAPHICS) style->m_namespace = L"a"; + else if (pWriter->m_lDocType == XMLWRITER_DOC_TYPE_CHART_DRAWING) style->m_namespace = L"cdr"; + else if (pWriter->m_lDocType == XMLWRITER_DOC_TYPE_DIAGRAM) style->m_namespace = L"dgm"; + else if (pWriter->m_lDocType == XMLWRITER_DOC_TYPE_DSP_DRAWING) style->m_namespace = L"dsp"; + + pWriter->Write(style); + } + pWriter->EndNode(namespace_ + L":cxnSp"); + } } // namespace Logic } // namespace PPTX \ No newline at end of file diff --git a/OOXML/PPTXFormat/Logic/CxnSp.h b/OOXML/PPTXFormat/Logic/CxnSp.h index 6eef04c22a..3d0165075c 100644 --- a/OOXML/PPTXFormat/Logic/CxnSp.h +++ b/OOXML/PPTXFormat/Logic/CxnSp.h @@ -67,102 +67,11 @@ namespace PPTX DWORD GetLine(Ln& line)const; DWORD GetFill(UniFill& fill)const; - //void FillLevelUp(); - //void Merge(CxnSp& cxnSp, bool bIsSlidePlaceholder = false); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; - //void SetLevelUpElement( CxnSp* p){m_pLevelUp = p;}; - - virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const - { - pWriter->StartRecord(SPTREE_TYPE_CXNSP); - - pWriter->WriteRecord1(0, nvCxnSpPr); - pWriter->WriteRecord1(1, spPr); - pWriter->WriteRecord2(2, style); - - if (macro.IsInit()) - { - pWriter->StartRecord(SPTREE_TYPE_MACRO); - pWriter->WriteString1(0, *macro); - pWriter->EndRecord(); - } - pWriter->EndRecord(); - } - void ReadAttributes(XmlUtils::CXmlLiteReader& oReader) - { - WritingElement_ReadAttributes_Start(oReader) - WritingElement_ReadAttributes_Read_if(oReader, _T("macro"),macro) - WritingElement_ReadAttributes_End(oReader) - } - virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const - { - std::wstring namespace_ = m_namespace; - - if (pWriter->m_lDocType == XMLWRITER_DOC_TYPE_DOCX || - pWriter->m_lDocType == XMLWRITER_DOC_TYPE_DOCX_GLOSSARY) namespace_ = L"wps"; - else if (pWriter->m_lDocType == XMLWRITER_DOC_TYPE_XLSX) namespace_ = L"xdr"; - else if (pWriter->m_lDocType == XMLWRITER_DOC_TYPE_GRAPHICS) namespace_ = L"a"; - else if (pWriter->m_lDocType == XMLWRITER_DOC_TYPE_CHART_DRAWING) namespace_ = L"cdr"; - else if (pWriter->m_lDocType == XMLWRITER_DOC_TYPE_DIAGRAM) namespace_ = L"dgm"; - else if (pWriter->m_lDocType == XMLWRITER_DOC_TYPE_DSP_DRAWING) namespace_ = L"dsp"; - - pWriter->StartNode(namespace_ + L":cxnSp"); - pWriter->WriteAttribute(L"macro", macro); - pWriter->EndAttributes(); - - nvCxnSpPr.toXmlWriter(pWriter); - spPr.toXmlWriter(pWriter); - - if (style.is_init()) - { - if (pWriter->m_lDocType == XMLWRITER_DOC_TYPE_DOCX || - pWriter->m_lDocType == XMLWRITER_DOC_TYPE_DOCX_GLOSSARY) style->m_namespace = L"wps"; - else if (pWriter->m_lDocType == XMLWRITER_DOC_TYPE_XLSX) style->m_namespace = L"xdr"; - else if (pWriter->m_lDocType == XMLWRITER_DOC_TYPE_GRAPHICS) style->m_namespace = L"a"; - else if (pWriter->m_lDocType == XMLWRITER_DOC_TYPE_CHART_DRAWING) style->m_namespace = L"cdr"; - else if (pWriter->m_lDocType == XMLWRITER_DOC_TYPE_DIAGRAM) style->m_namespace = L"dgm"; - else if (pWriter->m_lDocType == XMLWRITER_DOC_TYPE_DSP_DRAWING) style->m_namespace = L"dsp"; - - pWriter->Write(style); - } - pWriter->EndNode(namespace_ + L":cxnSp"); - } - - virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) - { - LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; - - while (pReader->GetPos() < _end_rec) - { - BYTE _at = pReader->GetUChar(); - switch (_at) - { - case 0: - { - nvCxnSpPr.fromPPTY(pReader); - }break; - case 1: - { - spPr.fromPPTY(pReader); - }break; - case 2: - { - style = new ShapeStyle(L"p"); - style->fromPPTY(pReader); - }break; - case SPTREE_TYPE_MACRO: - { - pReader->Skip(5); // type + size - macro = pReader->GetString2(); - }break; - default: - { - }break; - } - } - - pReader->Seek(_end_rec); - } + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); std::wstring m_namespace; diff --git a/OOXML/PPTXFormat/Logic/EffectLst.cpp b/OOXML/PPTXFormat/Logic/EffectLst.cpp index e54ccad18b..f8f3ed6cd9 100644 --- a/OOXML/PPTXFormat/Logic/EffectLst.cpp +++ b/OOXML/PPTXFormat/Logic/EffectLst.cpp @@ -50,8 +50,6 @@ namespace PPTX } void EffectLst::fromXML(XmlUtils::CXmlLiteReader& oReader) { - ReadAttributes( oReader ); - if ( oReader.IsEmptyNode() ) return; @@ -197,7 +195,19 @@ namespace PPTX pReader->Seek(_end_rec); } + EffectLst& EffectLst::operator=(const EffectLst& oSrc) + { + blur = oSrc.blur; + fillOverlay = oSrc.fillOverlay; + glow = oSrc.glow; + innerShdw = oSrc.innerShdw; + outerShdw = oSrc.outerShdw; + prstShdw = oSrc.prstShdw; + reflection = oSrc.reflection; + softEdge = oSrc.softEdge; + return *this; + } void EffectLst::Merge(EffectLst& effectLst) const { if (blur.IsInit()) diff --git a/OOXML/PPTXFormat/Logic/EffectLst.h b/OOXML/PPTXFormat/Logic/EffectLst.h index d57314d62b..9f99e9ab1d 100644 --- a/OOXML/PPTXFormat/Logic/EffectLst.h +++ b/OOXML/PPTXFormat/Logic/EffectLst.h @@ -30,8 +30,6 @@ * */ #pragma once -#ifndef PPTX_LOGIC_EFFECTLST_INCLUDE_H_ -#define PPTX_LOGIC_EFFECTLST_INCLUDE_H_ #include "./../WrapperWritingElement.h" #include "Effects/Blur.h" @@ -61,10 +59,6 @@ namespace PPTX } virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); - void ReadAttributes(XmlUtils::CXmlLiteReader& oReader) - { - } - virtual void fromXML(XmlUtils::CXmlNode& node); virtual std::wstring toXML() const; @@ -90,5 +84,3 @@ namespace PPTX }; } // namespace Logic } // namespace PPTX - -#endif // PPTX_LOGIC_EFFECTLST_INCLUDE_H_ diff --git a/OOXML/PPTXFormat/Logic/EffectProperties.cpp b/OOXML/PPTXFormat/Logic/EffectProperties.cpp index 6ee1f800f9..f98c554015 100644 --- a/OOXML/PPTXFormat/Logic/EffectProperties.cpp +++ b/OOXML/PPTXFormat/Logic/EffectProperties.cpp @@ -35,6 +35,52 @@ namespace PPTX { namespace Logic { + EffectProperties& EffectProperties::operator=(const EffectProperties& oSrc) + { + parentFile = oSrc.parentFile; + parentElement = oSrc.parentElement; + + List.reset(); + if (oSrc.List.IsInit()) + { + if (oSrc.List.is()) + { + List.reset(new EffectLst()); + List.as() = oSrc.List.as(); + } + else if (oSrc.List.is()) + { + List.reset(new EffectDag()); + List.as() = oSrc.List.as(); + } + } + return *this; + } + OOX::EElementType EffectProperties::getType() const + { + if (List.IsInit()) + return List->getType(); + return OOX::et_Unknown; + } + void EffectProperties::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + std::wstring strName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if (strName == L"effectLst") + { + Logic::EffectLst* pEffectLst = new Logic::EffectLst(); + *pEffectLst = oReader; + List.reset(pEffectLst); + } + else if (strName == L"effectDag") + { + Logic::EffectDag* pEffectDag = new Logic::EffectDag(); + *pEffectDag = oReader; + List.reset(pEffectDag); + } + else + List.reset(); + } void EffectProperties::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) { LONG pos = pReader->GetPos(); @@ -60,6 +106,50 @@ namespace PPTX pReader->SkipRecord(); } } + void EffectProperties::fromXML(XmlUtils::CXmlNode& node) + { + std::wstring strName = XmlUtils::GetNameNoNS(node.GetName()); + + if (L"effectLst" == strName) + { + Logic::EffectLst* pEffectLst = new Logic::EffectLst(); + pEffectLst->fromXML(node); + List.reset(pEffectLst); + } + else if (L"effectDag" == strName) + { + Logic::EffectDag* pEffectDag = new Logic::EffectDag(); + pEffectDag->fromXML(node); + List.reset(pEffectDag); + } + else List.reset(); + } + std::wstring EffectProperties::toXML() const + { + if (!List.IsInit()) + return L""; + return List->toXML(); + } + void EffectProperties::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + if (List.is_init()) + List->toXmlWriter(pWriter); + } + + void EffectProperties::Merge(EffectProperties& effectProperties) const + { + if (List.IsInit() && List.is()) + { + effectProperties.List.reset(new EffectLst()); + List.as().Merge(effectProperties.List.as()); + } + } + + void EffectProperties::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + if (List.is_init()) + List->toPPTY(pWriter); + } } // namespace Logic } // namespace PPTX diff --git a/OOXML/PPTXFormat/Logic/EffectProperties.h b/OOXML/PPTXFormat/Logic/EffectProperties.h index da3c773ad2..6f6ba32a4f 100644 --- a/OOXML/PPTXFormat/Logic/EffectProperties.h +++ b/OOXML/PPTXFormat/Logic/EffectProperties.h @@ -30,8 +30,6 @@ * */ #pragma once -#ifndef PPTX_LOGIC_EFFECTPROPERTIES_INCLUDE_H_ -#define PPTX_LOGIC_EFFECTPROPERTIES_INCLUDE_H_ #include "./../WrapperWritingElement.h" #include "EffectLst.h" @@ -47,39 +45,10 @@ namespace PPTX WritingElement_AdditionMethods(EffectProperties) PPTX_LOGIC_BASE2(EffectProperties) - EffectProperties& operator=(const EffectProperties& oSrc) - { - parentFile = oSrc.parentFile; - parentElement = oSrc.parentElement; + EffectProperties& operator=(const EffectProperties& oSrc); - return *this; - } - - virtual OOX::EElementType getType () const - { - if (List.IsInit()) - return List->getType(); - return OOX::et_Unknown; - } - virtual void fromXML(XmlUtils::CXmlLiteReader& oReader) - { - std::wstring strName = XmlUtils::GetNameNoNS(oReader.GetName()); - - if (strName == _T("effectLst")) - { - Logic::EffectLst* pEffectLst = new Logic::EffectLst(); - *pEffectLst = oReader; - List.reset(pEffectLst); - } - else if(strName == _T("effectDag")) - { - Logic::EffectDag* pEffectDag = new Logic::EffectDag(); - *pEffectDag = oReader; - List.reset(pEffectDag); - } - else - List.reset(); - } + virtual OOX::EElementType getType() const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); virtual bool is_init() const {return (List.IsInit());}; @@ -87,72 +56,15 @@ namespace PPTX template T& as() {return static_cast(*List);} template const T& as() const {return static_cast(*List);} - virtual void fromXML(XmlUtils::CXmlNode& node) - { - std::wstring strName = XmlUtils::GetNameNoNS(node.GetName()); + virtual void fromXML(XmlUtils::CXmlNode& node); - if (strName == _T("effectLst")) - { - Logic::EffectLst* pEffectLst = new Logic::EffectLst(); - *pEffectLst = node; - List.reset(pEffectLst); - } - else if(strName == _T("effectDag")) - { - Logic::EffectDag* pEffectDag = new Logic::EffectDag(); - *pEffectDag = node; - List.reset(pEffectDag); - } - else List.reset(); - } + virtual std::wstring toXML() const; - virtual void GetEffectListFrom(XmlUtils::CXmlNode& element) - { - XmlUtils::CXmlNode oNode = element.ReadNodeNoNS(_T("effectLst")); - if (oNode.IsValid()) - { - Logic::EffectLst* pEffectLst = new Logic::EffectLst(); - *pEffectLst = oNode; - List.reset(pEffectLst); - return; - } - oNode = element.ReadNodeNoNS(_T("effectDag")); - if (oNode.IsValid()) - { - Logic::EffectDag* pEffectDag = new Logic::EffectDag(); - *pEffectDag = oNode; - List.reset(pEffectDag); - } - else List.reset(); - } - - virtual std::wstring toXML() const - { - if (!List.IsInit()) - return _T(""); - return List->toXML(); - } - - virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const - { - if (List.is_init()) - List->toPPTY(pWriter); - } + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); - virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const - { - if (List.is_init()) - List->toXmlWriter(pWriter); - } + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; - void Merge(EffectProperties& effectProperties) const - { - if (List.IsInit() && List.is()) - { - effectProperties.List.reset(new EffectLst()); - List.as().Merge(effectProperties.List.as()); - } - } + void Merge(EffectProperties& effectProperties) const; nullable List; protected: @@ -166,5 +78,3 @@ namespace PPTX }; } // namespace Logic } // namespace PPTX - -#endif // PPTX_LOGIC_EFFECTPROPERTIES_INCLUDE_H diff --git a/OOXML/PPTXFormat/Logic/EffectStyle.cpp b/OOXML/PPTXFormat/Logic/EffectStyle.cpp index b5ff631e44..54955d17f1 100644 --- a/OOXML/PPTXFormat/Logic/EffectStyle.cpp +++ b/OOXML/PPTXFormat/Logic/EffectStyle.cpp @@ -35,15 +35,52 @@ namespace PPTX { namespace Logic { + EffectStyle& EffectStyle::operator=(const EffectStyle& oSrc) + { + parentFile = oSrc.parentFile; + parentElement = oSrc.parentElement; + Effects = oSrc.Effects; + scene3d = oSrc.scene3d; + sp3d = oSrc.sp3d; + return *this; + } void EffectStyle::fromXML(XmlUtils::CXmlNode& node) { - EffectList.GetEffectListFrom(node); - scene3d = node.ReadNode(_T("a:scene3d")); - sp3d = node.ReadNode(_T("a:sp3d")); + std::vector oNodes; + if (node.GetNodes(L"*", oNodes)) + { + size_t nCount = oNodes.size(); + for (size_t i = 0; i < nCount; ++i) + { + XmlUtils::CXmlNode& oNode = oNodes[i]; + std::wstring strName = XmlUtils::GetNameNoNS(oNode.GetName()); + + if (L"scene3d" == strName) + scene3d = oNode; + else if (L"sp3d" == strName) + sp3d = oNode; + else if (L"effectDag" == strName || + L"effectLst" == strName) + { + Effects.fromXML(oNode); + } + } + } FillParentPointersForChilds(); } + void EffectStyle::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"a:effectStyle"); + pWriter->EndAttributes(); + + Effects.toXmlWriter(pWriter); + pWriter->Write(scene3d); + pWriter->Write(sp3d); + + pWriter->EndNode(L"a:effectStyle"); + } void EffectStyle::fromXML(XmlUtils::CXmlLiteReader& oReader) { if ( oReader.IsEmptyNode() ) @@ -58,15 +95,49 @@ namespace PPTX else if (strName == L"a:sp3d") sp3d = oReader; else - EffectList.fromXML(oReader); + Effects.fromXML(oReader); } FillParentPointersForChilds(); } + void EffectStyle::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteRecord1(0, Effects); + pWriter->WriteRecord2(1, scene3d); + pWriter->WriteRecord2(2, sp3d); + } + void EffectStyle::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + while (pReader->GetPos() < _end_rec) + { + BYTE _at = pReader->GetUChar(); + switch (_at) + { + case 0: + { + Effects.fromPPTY(pReader); + }break; + case 1: + { + scene3d = new Logic::Scene3d(); + scene3d->fromPPTY(pReader); + }break; + case 2: + { + sp3d = new Logic::Sp3d(); + sp3d->fromPPTY(pReader); + }break; + default: + break; + } + } + pReader->Seek(_end_rec); + } void EffectStyle::FillParentPointersForChilds() { - EffectList.SetParentPointer(this); + Effects.SetParentPointer(this); if(scene3d.IsInit()) scene3d->SetParentPointer(this); if(sp3d.IsInit()) diff --git a/OOXML/PPTXFormat/Logic/EffectStyle.h b/OOXML/PPTXFormat/Logic/EffectStyle.h index 03b27efd26..1bdae5dbe8 100644 --- a/OOXML/PPTXFormat/Logic/EffectStyle.h +++ b/OOXML/PPTXFormat/Logic/EffectStyle.h @@ -47,16 +47,8 @@ namespace PPTX WritingElement_AdditionMethods(EffectStyle) PPTX_LOGIC_BASE2(EffectStyle) - EffectStyle& operator=(const EffectStyle& oSrc) - { - parentFile = oSrc.parentFile; - parentElement = oSrc.parentElement; + EffectStyle& operator=(const EffectStyle& oSrc); - EffectList = oSrc.EffectList; - scene3d = oSrc.scene3d; - sp3d = oSrc.sp3d; - return *this; - } virtual OOX::EElementType getType() const { return OOX::et_a_effectStyle; @@ -64,20 +56,12 @@ namespace PPTX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); virtual void fromXML(XmlUtils::CXmlNode& node); - virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const - { - pWriter->StartNode(_T("a:effectStyle")); - pWriter->EndAttributes(); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); - EffectList.toXmlWriter(pWriter); - pWriter->Write(scene3d); - pWriter->Write(sp3d); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; - pWriter->EndNode(_T("a:effectStyle")); - } - - public: - EffectProperties EffectList; + EffectProperties Effects; nullable scene3d; nullable sp3d; protected: diff --git a/OOXML/PPTXFormat/Logic/Fills/Blip.cpp b/OOXML/PPTXFormat/Logic/Fills/Blip.cpp index a15bd97f89..aa07c7cfa6 100644 --- a/OOXML/PPTXFormat/Logic/Fills/Blip.cpp +++ b/OOXML/PPTXFormat/Logic/Fills/Blip.cpp @@ -445,8 +445,8 @@ namespace PPTX } if (false == strImagePath.empty()) { - smart_ptr additionalFile; - NSBinPptxRW::_relsGeneratorInfo oRelsGeneratorInfo = pReader->m_pRels->WriteImage(strImagePath, additionalFile, L"", L""); + std::vector> additionalFiles; + NSBinPptxRW::_relsGeneratorInfo oRelsGeneratorInfo = pReader->m_pRels->WriteImage(strImagePath, additionalFiles, L"", L""); if (oRelsGeneratorInfo.nImageRId > 0) { diff --git a/OOXML/PPTXFormat/Logic/Fills/BlipFill.cpp b/OOXML/PPTXFormat/Logic/Fills/BlipFill.cpp index fa2c493172..451bf8186a 100644 --- a/OOXML/PPTXFormat/Logic/Fills/BlipFill.cpp +++ b/OOXML/PPTXFormat/Logic/Fills/BlipFill.cpp @@ -57,7 +57,7 @@ namespace PPTX dpi = oSrc.dpi; rotWithShape = oSrc.rotWithShape; - additionalFile = oSrc.additionalFile; + additionalFiles = oSrc.additionalFiles; oleData = oSrc.oleData; m_namespace = oSrc.m_namespace; @@ -410,7 +410,7 @@ namespace PPTX } } // ------------------- - NSBinPptxRW::_relsGeneratorInfo oRelsGeneratorInfo = pReader->m_pRels->WriteImage(strImagePath, additionalFile, oleData, strOrigBase64); + NSBinPptxRW::_relsGeneratorInfo oRelsGeneratorInfo = pReader->m_pRels->WriteImage(strImagePath, additionalFiles, oleData, strOrigBase64); // ------------------- if (!strTempFile.empty()) { diff --git a/OOXML/PPTXFormat/Logic/Fills/BlipFill.h b/OOXML/PPTXFormat/Logic/Fills/BlipFill.h index 1298fcabc1..5b73c283cc 100644 --- a/OOXML/PPTXFormat/Logic/Fills/BlipFill.h +++ b/OOXML/PPTXFormat/Logic/Fills/BlipFill.h @@ -73,8 +73,8 @@ namespace PPTX nullable_bool rotWithShape; //internal - mutable smart_ptr additionalFile; - std::wstring oleData; + mutable std::vector> additionalFiles; + std::wstring oleData; protected: virtual void FillParentPointersForChilds(); diff --git a/OOXML/PPTXFormat/Logic/GraphicFrame.cpp b/OOXML/PPTXFormat/Logic/GraphicFrame.cpp index d10c74b6b1..96f50151ef 100644 --- a/OOXML/PPTXFormat/Logic/GraphicFrame.cpp +++ b/OOXML/PPTXFormat/Logic/GraphicFrame.cpp @@ -502,7 +502,7 @@ namespace PPTX else if (pWriter->m_lDocType == XMLWRITER_DOC_TYPE_DSP_DRAWING) namespace_ = L"dsp"; pWriter->StartNode(namespace_ + L":graphicFrame"); - pWriter->WriteAttribute(L"macro", macro); + pWriter->WriteAttribute2(L"macro", macro); pWriter->EndAttributes(); toXmlWriter2(pWriter); @@ -795,10 +795,7 @@ namespace PPTX sXml += L"<" + m_namespace + L":graphicFrame"; - sXml += L" macro=\"" + (macro.IsInit() ? *macro : L"") + L"\">"; - - XmlUtils::CAttribute oAttr; - oAttr.Write(L"macro", macro); + sXml += L" macro=\"" + (macro.IsInit() ? XmlUtils::EncodeXmlString(*macro) : L"") + L"\">"; sXml += toXML2(); diff --git a/OOXML/PPTXFormat/Logic/GrpSpPr.cpp b/OOXML/PPTXFormat/Logic/GrpSpPr.cpp index 4066a8e098..e26b0aa218 100644 --- a/OOXML/PPTXFormat/Logic/GrpSpPr.cpp +++ b/OOXML/PPTXFormat/Logic/GrpSpPr.cpp @@ -105,7 +105,7 @@ namespace PPTX void GrpSpPr::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) - WritingElement_ReadAttributes_ReadSingle( oReader, _T("bwMode"), bwMode ) + WritingElement_ReadAttributes_ReadSingle( oReader, L"bwMode", bwMode ) WritingElement_ReadAttributes_End( oReader ) } void GrpSpPr::fromXML(XmlUtils::CXmlNode& node) @@ -115,7 +115,7 @@ namespace PPTX XmlMacroReadAttributeBase(node, L"bwMode", bwMode); std::vector oNodes; - if (node.GetNodes(_T("*"), oNodes)) + if (node.GetNodes(L"*", oNodes)) { size_t count = oNodes.size(); for (size_t i = 0; i < count; ++i) @@ -123,28 +123,39 @@ namespace PPTX XmlUtils::CXmlNode& oNode = oNodes[i]; std::wstring strName = XmlUtils::GetNameNoNS(oNode.GetName()); - if (_T("xfrm") == strName) + if (L"xfrm" == strName) { if (!xfrm.IsInit()) xfrm = oNode; } - else if (_T("scene3d") == strName) + else if (L"blipFill" == strName || + L"gradFill" == strName || + L"grpFill" == strName || + L"noFill" == strName || + L"pattFill" == strName || + L"solidFill" == strName) + { + Fill.fromXML(oNode); + } + else if (L"scene3d" == strName) { if (!scene3d.IsInit()) scene3d = oNode; } + else if (L"effectDag" == strName || + L"effectLst" == strName) + { + EffectList.fromXML(oNode); + } } } - Fill.GetFillFrom(node); - EffectList.GetEffectListFrom(node); - FillParentPointersForChilds(); } std::wstring GrpSpPr::toXML() const { XmlUtils::CAttribute oAttr; - oAttr.WriteLimitNullable(_T("bwMode"), bwMode); + oAttr.WriteLimitNullable(L"bwMode", bwMode); XmlUtils::CNodeValue oValue; oValue.WriteNullable(xfrm); @@ -168,7 +179,7 @@ namespace PPTX pWriter->StartNode(namespace_ + L":grpSpPr"); pWriter->StartAttributes(); - pWriter->WriteAttribute(_T("bwMode"), bwMode); + pWriter->WriteAttribute(L"bwMode", bwMode); pWriter->EndAttributes(); pWriter->Write(xfrm); diff --git a/OOXML/PPTXFormat/Logic/Ln.cpp b/OOXML/PPTXFormat/Logic/Ln.cpp index 3000f4a516..8337165781 100644 --- a/OOXML/PPTXFormat/Logic/Ln.cpp +++ b/OOXML/PPTXFormat/Logic/Ln.cpp @@ -112,8 +112,6 @@ namespace PPTX XmlMacroReadAttributeBase(node, L"cmpd", cmpd); XmlMacroReadAttributeBase(node, L"w", w); - Fill.GetFillFrom(node); - std::vector oNodes; if (node.GetNodes(L"*", oNodes)) { @@ -139,6 +137,20 @@ namespace PPTX { prstDash = oNode; } + else if (L"blipFill" == strName || + L"gradFill" == strName || + L"grpFill" == strName || + L"noFill" == strName || + L"pattFill" == strName || + L"solidFill" == strName) + { + Fill.fromXML(oNode); + } + else if (L"effectDag" == strName || + L"effectLst" == strName) + { + Effects.fromXML(oNode); + } } } diff --git a/OOXML/PPTXFormat/Logic/Pic.cpp b/OOXML/PPTXFormat/Logic/Pic.cpp index c337d76e48..bff40e7383 100644 --- a/OOXML/PPTXFormat/Logic/Pic.cpp +++ b/OOXML/PPTXFormat/Logic/Pic.cpp @@ -35,13 +35,13 @@ #include "../../../MsBinaryFile/XlsFile/Converter/ConvertXls2Xlsx.h" #include "../../../MsBinaryFile/DocFile/Main/DocFormatLib.h" #include "../../Binary/Document/BinWriter/BinEquationWriter.h" -#include "../../Binary/Document/BinWriter/BinWriters.h" -#include "../../Binary/Document/BinReader/Readers.h" +#include "../../Binary/Document/BinWriter/BinaryWriterD.h" +#include "../../Binary/Document/BinReader/BinaryReaderD.h" #include "../../Binary/Document/BinReader/FileWriter.h" #include "../../Binary/Document/DocWrapper/FontProcessor.h" #include "../../Binary/Document/DocWrapper/XlsxSerializer.h" -#include "../../Binary/Sheets/Reader/BinaryWriter.h" -#include "../../Binary/Sheets/Writer/BinaryReader.h" +#include "../../Binary/Sheets/Reader/BinaryWriterS.h" +#include "../../Binary/Sheets/Writer/BinaryReaderS.h" #include "../../Binary/MathEquation/MathEquation.h" #include "SpTree.h" @@ -786,7 +786,7 @@ namespace PPTX std::wstring Pic::toXML() const { XmlUtils::CAttribute oAttr; - oAttr.Write(L"macro", macro); + oAttr.Write2(L"macro", macro); XmlUtils::CNodeValue oValue; oValue.Write(nvPicPr); @@ -857,9 +857,10 @@ namespace PPTX } else if (nvPicPr.nvPr.media.is_init()) { - blipFill.additionalFile = GetMediaLink(pWriter); + blipFill.additionalFiles.emplace_back(); + blipFill.additionalFiles.back() = GetMediaLink(pWriter); - smart_ptr mediaFile = blipFill.additionalFile.smart_dynamic_cast(); + smart_ptr mediaFile = blipFill.additionalFiles.back().smart_dynamic_cast(); if (mediaFile.IsInit() && blipFill.blip.IsInit()) { blipFill.blip->mediaFilepath = mediaFile->filename().GetPath(); @@ -888,9 +889,9 @@ namespace PPTX pWriter->StartRecord(SPTREE_TYPE_PIC); } - if (blipFill.additionalFile.is()) + if (!blipFill.additionalFiles.empty() && blipFill.additionalFiles.back().is()) { - smart_ptr mediaFile = blipFill.additionalFile.smart_dynamic_cast(); + smart_ptr mediaFile = blipFill.additionalFiles.back().smart_dynamic_cast(); pWriter->StartRecord(5); pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); @@ -1009,7 +1010,7 @@ namespace PPTX pWriter->StartAttributes(); pWriter->WriteAttribute(_T("xmlns:pic"), (std::wstring)_T("http://schemas.openxmlformats.org/drawingml/2006/picture")); } - pWriter->WriteAttribute(L"macro", macro); + pWriter->WriteAttribute2(L"macro", macro); pWriter->EndAttributes(); nvPicPr.toXmlWriter(pWriter); @@ -1057,22 +1058,24 @@ namespace PPTX { if (oleObject->m_OleObjectFile.IsInit() == false) oleObject->m_OleObjectFile = new OOX::OleObject(NULL, false, pReader->m_nDocumentType == XMLWRITER_DOC_TYPE_DOCX); - - oleObject->m_OleObjectFile->set_filename_cache (blipFill.blip->oleFilepathImage); + + oleObject->m_OleObjectFile->set_filename_cache(blipFill.blip->oleFilepathImage); if (NSFile::CFileBinary::Exists(oleObject->m_OleObjectFile->filename().GetPath()) == false) { - oleObject->m_OleObjectFile->set_filename (blipFill.blip->oleFilepathBin, false); + oleObject->m_OleObjectFile->set_filename(blipFill.blip->oleFilepathBin, false); } } - - smart_ptr mediaFile = blipFill.additionalFile.smart_dynamic_cast(); - if (mediaFile.IsInit() && blipFill.blip.IsInit()) + for (auto additionalFile : blipFill.additionalFiles) { - if (!mediaFile->IsExternal() && NSFile::CFileBinary::Exists(mediaFile->filename().GetPath()) == false) + smart_ptr mediaFile = additionalFile.smart_dynamic_cast(); + if (mediaFile.IsInit() && blipFill.blip.IsInit()) { - mediaFile->set_filename (blipFill.blip->mediaFilepath, + if (!mediaFile->IsExternal() && NSFile::CFileBinary::Exists(mediaFile->filename().GetPath()) == false) + { + mediaFile->set_filename(blipFill.blip->mediaFilepath, false == NSFile::CFileBinary::Exists(blipFill.blip->mediaFilepath)); + } } } }break; @@ -1093,7 +1096,8 @@ namespace PPTX if (oleObject->m_sData.IsInit()) blipFill.oleData = oleObject->m_sData.get(); - blipFill.additionalFile = oleObject->m_OleObjectFile.smart_dynamic_cast(); + blipFill.additionalFiles.emplace_back(); + blipFill.additionalFiles.back() = oleObject->m_OleObjectFile.smart_dynamic_cast(); }break; case 5: { @@ -1119,7 +1123,7 @@ namespace PPTX else break; } - smart_ptr mediaFile = blipFill.additionalFile.smart_dynamic_cast(); + smart_ptr mediaFile = blipFill.additionalFiles.back().smart_dynamic_cast(); if (mediaFile.IsInit()) { mediaFile->set_filename(strMediaFileMask, isExternal); @@ -1137,73 +1141,78 @@ namespace PPTX } } } - if (blipFill.blip.IsInit() && blipFill.additionalFile.IsInit()) + if (blipFill.blip.IsInit()) { - if (!blipFill.blip->oleRid.empty() && oleObject.IsInit()) + for (auto additionalFile : blipFill.additionalFiles) { - oleObject->m_oId = OOX::RId(blipFill.blip->oleRid); + if (false == additionalFile.IsInit()) continue; - if (oleObject->m_OleObjectFile.IsInit() == false) + if (!blipFill.blip->oleRid.empty() && oleObject.IsInit()) { - oleObject->m_OleObjectFile = new OOX::OleObject(NULL, false, pReader->m_nDocumentType == XMLWRITER_DOC_TYPE_DOCX); - - oleObject->m_OleObjectFile->set_filename (blipFill.blip->oleFilepathBin, false); - oleObject->m_OleObjectFile->set_filename_cache (blipFill.blip->oleFilepathImage); - } - } - if (false == blipFill.blip->mediaRid.empty() && blipFill.additionalFile.IsInit()) - { - smart_ptr mediaFile = blipFill.additionalFile.smart_dynamic_cast(); - bool bExternal = mediaFile->IsExternal(); - - std::wstring strMediaRelsPath; - if (pReader->m_nDocumentType == XMLWRITER_DOC_TYPE_DOCX) strMediaRelsPath = L"media/"; - else strMediaRelsPath = L"../media/"; - - if (bExternal) - { - strMediaRelsPath = mediaFile->filename().GetFilename(); - } - else - { - strMediaRelsPath += mediaFile->filename().GetFilename(); - PPTX::Logic::Ext ext; - - if (blipFill.additionalFile->type() == OOX::FileTypes::Audio || - blipFill.additionalFile->type() == OOX::FileTypes::Video) - { - ext.link_media = OOX::RId(blipFill.blip->mediaRid); - nvPicPr.nvPr.extLst.push_back(ext); - - if (nvPicPr.cNvPr.hlinkClick.IsInit() == false) - nvPicPr.cNvPr.hlinkClick.Init(); + oleObject->m_oId = OOX::RId(blipFill.blip->oleRid); - nvPicPr.cNvPr.hlinkClick->id = L""; - nvPicPr.cNvPr.hlinkClick->action = L"ppaction://media"; - } - else if (blipFill.additionalFile->type() == OOX::FileTypes::SvgBlip) + if (oleObject->m_OleObjectFile.IsInit() == false) { - ext.link_svg = OOX::RId(blipFill.blip->mediaRid); - blipFill.blip->ExtLst.push_back(ext); + oleObject->m_OleObjectFile = new OOX::OleObject(NULL, false, pReader->m_nDocumentType == XMLWRITER_DOC_TYPE_DOCX); + + oleObject->m_OleObjectFile->set_filename(blipFill.blip->oleFilepathBin, false); + oleObject->m_OleObjectFile->set_filename_cache(blipFill.blip->oleFilepathImage); } } + if (false == blipFill.blip->mediaRid.empty() && additionalFile.IsInit()) + { + smart_ptr mediaFile = additionalFile.smart_dynamic_cast(); + bool bExternal = mediaFile->IsExternal(); - unsigned int nRId = 0; - if (blipFill.additionalFile.is()) - { - nvPicPr.nvPr.media.Media = new PPTX::Logic::MediaFile(L"audioFile"); - nRId = pReader->m_pRels->WriteRels(L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/audio", strMediaRelsPath, bExternal ? L"External" : L""); + std::wstring strMediaRelsPath; + if (pReader->m_nDocumentType == XMLWRITER_DOC_TYPE_DOCX) strMediaRelsPath = L"media/"; + else strMediaRelsPath = L"../media/"; - } - if (blipFill.additionalFile.is()) - { - nvPicPr.nvPr.media.Media = new PPTX::Logic::MediaFile(L"videoFile"); - nRId = pReader->m_pRels->WriteRels(L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/video", strMediaRelsPath, bExternal ? L"External" : L""); - } - if (nvPicPr.nvPr.media.Media.IsInit() && nRId > 0) - { - PPTX::Logic::MediaFile& mediaFile = nvPicPr.nvPr.media.Media.as(); - mediaFile.link = OOX::RId((size_t)nRId); + if (bExternal) + { + strMediaRelsPath = mediaFile->filename().GetFilename(); + } + else + { + strMediaRelsPath += mediaFile->filename().GetFilename(); + PPTX::Logic::Ext ext; + + if (additionalFile->type() == OOX::FileTypes::Audio || + additionalFile->type() == OOX::FileTypes::Video) + { + ext.link_media = OOX::RId(blipFill.blip->mediaRid); + nvPicPr.nvPr.extLst.push_back(ext); + + if (nvPicPr.cNvPr.hlinkClick.IsInit() == false) + nvPicPr.cNvPr.hlinkClick.Init(); + + nvPicPr.cNvPr.hlinkClick->id = L""; + nvPicPr.cNvPr.hlinkClick->action = L"ppaction://media"; + } + else if (additionalFile->type() == OOX::FileTypes::SvgBlip) + { + ext.link_svg = OOX::RId(blipFill.blip->mediaRid); + blipFill.blip->ExtLst.push_back(ext); + } + } + + unsigned int nRId = 0; + if (additionalFile.is()) + { + nvPicPr.nvPr.media.Media = new PPTX::Logic::MediaFile(L"audioFile"); + nRId = pReader->m_pRels->WriteRels(L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/audio", strMediaRelsPath, bExternal ? L"External" : L""); + + } + if (additionalFile.is()) + { + nvPicPr.nvPr.media.Media = new PPTX::Logic::MediaFile(L"videoFile"); + nRId = pReader->m_pRels->WriteRels(L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/video", strMediaRelsPath, bExternal ? L"External" : L""); + } + if (nvPicPr.nvPr.media.Media.IsInit() && nRId > 0) + { + PPTX::Logic::MediaFile& mediaFile = nvPicPr.nvPr.media.Media.as(); + mediaFile.link = OOX::RId((size_t)nRId); + } } } } @@ -1800,7 +1809,7 @@ namespace PPTX oDrawingConverter.SetMainDocument(&oDocxSerializer); oDrawingConverter.SetDstPath(sDstEmbeddedTemp + FILE_SEPARATOR_STR + L"word"); - oDrawingConverter.SetSrcPath(pReader->m_strFolder, 1); + oDrawingConverter.SetSrcPath(pReader->m_strFolder, XMLWRITER_DOC_TYPE_DOCX); oDrawingConverter.SetMediaDstPath(sMediaPath); oDrawingConverter.SetEmbedDstPath(sEmbedPath); @@ -1873,7 +1882,7 @@ namespace PPTX oDrawingConverter.m_pReader->Init(pData, 0, length); oDrawingConverter.SetDstPath(sDstEmbeddedTemp + FILE_SEPARATOR_STR + L"xl"); - oDrawingConverter.SetSrcPath(pReader->m_strFolder, 2); + oDrawingConverter.SetSrcPath(pReader->m_strFolder, XMLWRITER_DOC_TYPE_XLSX); oDrawingConverter.SetMediaDstPath(sMediaPath); oDrawingConverter.SetEmbedDstPath(sEmbedPath); diff --git a/OOXML/PPTXFormat/Logic/RunProperties.cpp b/OOXML/PPTXFormat/Logic/RunProperties.cpp index e9aae08466..5d0f772bee 100644 --- a/OOXML/PPTXFormat/Logic/RunProperties.cpp +++ b/OOXML/PPTXFormat/Logic/RunProperties.cpp @@ -367,12 +367,23 @@ namespace PPTX uFillTx = oNode; else if (L"highlight" == strName) highlight = oNode; + else if (L"blipFill" == strName || + L"gradFill" == strName || + L"grpFill" == strName || + L"noFill" == strName || + L"pattFill" == strName || + L"solidFill" == strName) + { + Fill.fromXML(oNode); + } + else if (L"effectDag" == strName || + L"effectLst" == strName) + { + EffectList.fromXML(oNode); + } } } - Fill.GetFillFrom(node); - EffectList.GetEffectListFrom(node); - Normalize(); FillParentPointersForChilds(); diff --git a/OOXML/PPTXFormat/Logic/Runs/MathParaWrapper.cpp b/OOXML/PPTXFormat/Logic/Runs/MathParaWrapper.cpp index a61064154c..7a1876ba1c 100644 --- a/OOXML/PPTXFormat/Logic/Runs/MathParaWrapper.cpp +++ b/OOXML/PPTXFormat/Logic/Runs/MathParaWrapper.cpp @@ -32,7 +32,7 @@ #include "MathParaWrapper.h" #include "../../../DocxFormat/Math/oMathPara.h" -#include "../../../Binary/Document/BinWriter/BinWriters.h" +#include "../../../Binary/Document/BinWriter/BinaryWriterD.h" #include "../../../Binary/Document/BinReader/FileWriter.h" #include "../../DrawingConverter/ASCOfficeDrawingConverter.h" #include "../../../Binary/Presentation/BinaryFileReaderWriter.h" diff --git a/OOXML/PPTXFormat/Logic/Runs/Run.h b/OOXML/PPTXFormat/Logic/Runs/Run.h index 2f42122bb1..ab65121220 100644 --- a/OOXML/PPTXFormat/Logic/Runs/Run.h +++ b/OOXML/PPTXFormat/Logic/Runs/Run.h @@ -30,8 +30,6 @@ * */ #pragma once -#ifndef PPTX_LOGIC_RUN_INCLUDE_H_ -#define PPTX_LOGIC_RUN_INCLUDE_H_ #include "RunBase.h" #include "./../RunProperties.h" @@ -60,7 +58,6 @@ namespace PPTX bool HasText() const; void SetText(const std::wstring& srcText); - public: nullable rPr; private: @@ -71,5 +68,3 @@ namespace PPTX }; } // namespace Logic } // namespace PPTX - -#endif // PPTX_LOGIC_RUN_INCLUDE_H diff --git a/OOXML/PPTXFormat/Logic/Shape.cpp b/OOXML/PPTXFormat/Logic/Shape.cpp index 4183389181..3b154e9489 100644 --- a/OOXML/PPTXFormat/Logic/Shape.cpp +++ b/OOXML/PPTXFormat/Logic/Shape.cpp @@ -218,7 +218,7 @@ namespace PPTX oAttr.Write(L"useBgFill", useBgFill); oAttr.Write(L"modelId", modelId); - oAttr.Write(L"macro", macro); + oAttr.Write2(L"macro", macro); oAttr.Write(L"fLocksText", fLocksText); XmlUtils::CNodeValue oValue; @@ -248,7 +248,7 @@ namespace PPTX pWriter->StartAttributes(); pWriter->WriteAttribute(L"useBgFill", useBgFill); - pWriter->WriteAttribute(L"macro", macro); + pWriter->WriteAttribute2(L"macro", macro); pWriter->WriteAttribute(L"modelId", modelId); pWriter->WriteAttribute(L"fLocksText", fLocksText); pWriter->EndAttributes(); diff --git a/OOXML/PPTXFormat/Logic/SmartArt.cpp b/OOXML/PPTXFormat/Logic/SmartArt.cpp index ca86553690..b7ecdd7863 100644 --- a/OOXML/PPTXFormat/Logic/SmartArt.cpp +++ b/OOXML/PPTXFormat/Logic/SmartArt.cpp @@ -37,11 +37,11 @@ #include "../../PPTXFormat/DrawingConverter/ASCOfficeDrawingConverter.h" -#include "../../Binary/Sheets/Reader/BinaryWriter.h" +#include "../../Binary/Sheets/Reader/BinaryWriterS.h" #include "../../Binary/Document/DocWrapper/XlsxSerializer.h" #include "../../Binary/Document/DocWrapper/FontProcessor.h" -#include "../../Binary/Document/BinWriter/BinWriters.h" +#include "../../Binary/Document/BinWriter/BinaryWriterD.h" #include "../../XlsxFormat/Chart/Chart.h" diff --git a/OOXML/PPTXFormat/Logic/SpPr.cpp b/OOXML/PPTXFormat/Logic/SpPr.cpp index e67a10f515..10d196cc71 100644 --- a/OOXML/PPTXFormat/Logic/SpPr.cpp +++ b/OOXML/PPTXFormat/Logic/SpPr.cpp @@ -126,14 +126,10 @@ namespace PPTX { m_namespace = XmlUtils::GetNamespace(node.GetName()); - Geometry.GetGeometryFrom(node); - Fill.GetFillFrom(node); - EffectList.GetEffectListFrom(node); - XmlMacroReadAttributeBase(node,L"bwMode", bwMode); std::vector oNodes; - if (node.GetNodes(_T("*"), oNodes)) + if (node.GetNodes(L"*", oNodes)) { size_t nCount = oNodes.size(); for (size_t i = 0; i < nCount; ++i) @@ -142,17 +138,35 @@ namespace PPTX std::wstring strName = XmlUtils::GetNameNoNS(oNode.GetName()); - if (_T("xfrm") == strName) + if (L"xfrm" == strName) xfrm = oNode; - else if (_T("ln") == strName) + else if (L"ln" == strName) ln = oNode; - else if (_T("scene3d") == strName) + else if (L"scene3d" == strName) scene3d = oNode; - else if (_T("sp3d") == strName) + else if (L"sp3d" == strName) sp3d = oNode; + else if (L"blipFill" == strName || + L"gradFill" == strName || + L"grpFill" == strName || + L"noFill" == strName || + L"pattFill" == strName || + L"solidFill" == strName) + { + Fill.fromXML(oNode); + } + else if ( L"effectDag" == strName || + L"effectLst" == strName) + { + EffectList.fromXML(oNode); + } + else if (L"prstGeom" == strName || + L"custGeom" == strName) + { + Geometry.fromXML(oNode); + } } } - FillParentPointersForChilds(); } std::wstring SpPr::toXML() const @@ -226,42 +240,35 @@ namespace PPTX case 0: { xfrm = new Logic::Xfrm(); - xfrm->fromPPTY(pReader); - break; - } + xfrm->fromPPTY(pReader); + }break; case 1: { - Geometry.fromPPTY(pReader); - break; - } + Geometry.fromPPTY(pReader); + }break; case 2: { - Fill.fromPPTY(pReader); - break; - } + Fill.fromPPTY(pReader); + }break; case 3: { ln = new Logic::Ln(); - ln->fromPPTY(pReader); - break; - } + ln->fromPPTY(pReader); + }break; case 4: { - EffectList.fromPPTY(pReader); - break; - } + EffectList.fromPPTY(pReader); + }break; case 5: { scene3d = new Logic::Scene3d(); - scene3d->fromPPTY(pReader); - break; - } + scene3d->fromPPTY(pReader); + }break; case 6: { sp3d = new Logic::Sp3d(); - sp3d->fromPPTY(pReader); - break; - } + sp3d->fromPPTY(pReader); + }break; default: break; } @@ -276,7 +283,7 @@ namespace PPTX void SpPr::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) - WritingElement_ReadAttributes_ReadSingle( oReader, _T("bwMode"), bwMode ) + WritingElement_ReadAttributes_ReadSingle( oReader, L"bwMode", bwMode ) WritingElement_ReadAttributes_End( oReader ) } void SpPr::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const @@ -303,7 +310,7 @@ namespace PPTX pWriter->StartNode(name_); pWriter->StartAttributes(); - pWriter->WriteAttribute(_T("bwMode"), bwMode); + pWriter->WriteAttribute(L"bwMode", bwMode); pWriter->EndAttributes(); pWriter->Write(xfrm); @@ -311,7 +318,7 @@ namespace PPTX if ((pWriter->m_lFlag & 0x02) != 0 && !Fill.is_init()) { - pWriter->WriteString(_T("")); + pWriter->WriteString(L""); } Fill.toXmlWriter(pWriter); diff --git a/OOXML/PPTXFormat/Logic/SpTreeElem.cpp b/OOXML/PPTXFormat/Logic/SpTreeElem.cpp index 875eaa859e..a6117dcf6c 100644 --- a/OOXML/PPTXFormat/Logic/SpTreeElem.cpp +++ b/OOXML/PPTXFormat/Logic/SpTreeElem.cpp @@ -616,12 +616,14 @@ namespace PPTX if (_type == SPTREE_TYPE_AUDIO) { OOX::Audio *pAudio = new OOX::Audio(NULL, pReader->m_nDocumentType == XMLWRITER_DOC_TYPE_DOCX); - p->blipFill.additionalFile = smart_ptr(dynamic_cast(pAudio)); + p->blipFill.additionalFiles.emplace_back(); + p->blipFill.additionalFiles.back() = smart_ptr(dynamic_cast(pAudio)); } else if (_type == SPTREE_TYPE_VIDEO) { OOX::Video* pVideo = new OOX::Video(NULL, pReader->m_nDocumentType == XMLWRITER_DOC_TYPE_DOCX); - p->blipFill.additionalFile = smart_ptr(dynamic_cast(pVideo)); + p->blipFill.additionalFiles.emplace_back(); + p->blipFill.additionalFiles.back() = smart_ptr(dynamic_cast(pVideo)); } p->fromPPTY(pReader); diff --git a/OOXML/PPTXFormat/Logic/Table/TableProperties.cpp b/OOXML/PPTXFormat/Logic/Table/TableProperties.cpp index bb393bb332..fc33b17aa6 100644 --- a/OOXML/PPTXFormat/Logic/Table/TableProperties.cpp +++ b/OOXML/PPTXFormat/Logic/Table/TableProperties.cpp @@ -118,13 +118,6 @@ namespace PPTX } void TableProperties::fromXML(XmlUtils::CXmlNode& node) { - Fill.GetFillFrom(node); - Effects.GetEffectListFrom(node); - - XmlUtils::CXmlNode oNode; - if (node.GetNode(_T("a:tableStyleId"), oNode)) - TableStyleId = oNode.GetTextExt(); - XmlMacroReadAttributeBase(node, L"rtl", Rtl); XmlMacroReadAttributeBase(node, L"firstRow", FirstRow); XmlMacroReadAttributeBase(node, L"firstCol", FirstCol); @@ -133,6 +126,36 @@ namespace PPTX XmlMacroReadAttributeBase(node, L"bandRow", BandRow); XmlMacroReadAttributeBase(node, L"bandCol", BandCol); + std::vector oNodes; + if (node.GetNodes(L"*", oNodes)) + { + size_t nCount = oNodes.size(); + for (size_t i = 0; i < nCount; ++i) + { + XmlUtils::CXmlNode& oNode = oNodes[i]; + + std::wstring strName = XmlUtils::GetNameNoNS(oNode.GetName()); + + if (L"tableStyleId" == strName) + { + TableStyleId = oNode.GetTextExt(); + } + else if (L"blipFill" == strName || + L"gradFill" == strName || + L"grpFill" == strName || + L"noFill" == strName || + L"pattFill" == strName || + L"solidFill" == strName) + { + Fill.fromXML(oNode); + } + else if (L"effectDag" == strName || + L"effectLst" == strName) + { + Effects.fromXML(oNode); + } + } + } FillParentPointersForChilds(); } void TableProperties::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const diff --git a/OOXML/PPTXFormat/Logic/TcTxStyle.cpp b/OOXML/PPTXFormat/Logic/TcTxStyle.cpp index 3c8e49498d..c939db12b4 100644 --- a/OOXML/PPTXFormat/Logic/TcTxStyle.cpp +++ b/OOXML/PPTXFormat/Logic/TcTxStyle.cpp @@ -41,24 +41,24 @@ namespace PPTX XmlMacroReadAttributeBase(node, L"i", i); XmlMacroReadAttributeBase(node, L"b", b); - fontRef = node.ReadNodeNoNS(_T("fontRef")); + fontRef = node.ReadNodeNoNS(L"fontRef"); Color.GetColorFrom(node); FillParentPointersForChilds(); } void TcTxStyle::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const { - pWriter->StartNode(_T("a:tcTxStyle")); + pWriter->StartNode(L"a:tcTxStyle"); pWriter->StartAttributes(); - pWriter->WriteAttribute(_T("i"), i); - pWriter->WriteAttribute(_T("b"), b); + pWriter->WriteAttribute(L"i", i); + pWriter->WriteAttribute(L"b", b); pWriter->EndAttributes(); pWriter->Write(fontRef); Color.toXmlWriter(pWriter); - pWriter->EndNode(_T("a:tcTxStyle")); + pWriter->EndNode(L"a:tcTxStyle"); } void TcTxStyle::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const { diff --git a/OOXML/PPTXFormat/Logic/TextSpacing.cpp b/OOXML/PPTXFormat/Logic/TextSpacing.cpp index 43c430994e..26a1ea55cd 100644 --- a/OOXML/PPTXFormat/Logic/TextSpacing.cpp +++ b/OOXML/PPTXFormat/Logic/TextSpacing.cpp @@ -68,17 +68,17 @@ namespace PPTX void TextSpacing::ReadAttributes(XmlUtils::CXmlLiteReader& oReader, nullable_int & val) { WritingElement_ReadAttributes_Start ( oReader ) - WritingElement_ReadAttributes_ReadSingle ( oReader, _T("val"), val) + WritingElement_ReadAttributes_ReadSingle ( oReader, L"val", val) WritingElement_ReadAttributes_End ( oReader ) } void TextSpacing::fromXML(XmlUtils::CXmlNode& node) { m_name = node.GetName(); - XmlUtils::CXmlNode node1 = node.ReadNode(_T("a:spcPct")); + XmlUtils::CXmlNode node1 = node.ReadNode(L"a:spcPct"); XmlMacroReadAttributeBase(node1, L"val", spcPct); - XmlUtils::CXmlNode node2 = node.ReadNode(_T("a:spcPts")); + XmlUtils::CXmlNode node2 = node.ReadNode(L"a:spcPts"); XmlMacroReadAttributeBase(node2, L"val", spcPts); Normalize(); diff --git a/OOXML/PPTXFormat/Logic/UniColor.h b/OOXML/PPTXFormat/Logic/UniColor.h index a7e5e2ef6c..427f090bc0 100644 --- a/OOXML/PPTXFormat/Logic/UniColor.h +++ b/OOXML/PPTXFormat/Logic/UniColor.h @@ -30,8 +30,6 @@ * */ #pragma once -#ifndef PPTX_LOGIC_UNICOLOR_INCLUDE_H_ -#define PPTX_LOGIC_UNICOLOR_INCLUDE_H_ #include "./../WrapperWritingElement.h" #include "Colors/ColorBase.h" @@ -91,5 +89,3 @@ namespace PPTX }; } // namespace Logic } // namespace PPTX - -#endif // PPTX_LOGIC_UNICOLOR_INCLUDE_H diff --git a/OOXML/PPTXFormat/Logic/UniFill.cpp b/OOXML/PPTXFormat/Logic/UniFill.cpp index 38c07f5527..2da1711814 100644 --- a/OOXML/PPTXFormat/Logic/UniFill.cpp +++ b/OOXML/PPTXFormat/Logic/UniFill.cpp @@ -385,7 +385,7 @@ namespace PPTX } // ------------------- - NSBinPptxRW::_relsGeneratorInfo oRelsGeneratorInfo = pReader->m_pRels->WriteImage(strUrl, pFill->additionalFile, pFill->oleData, strOrigBase64); + NSBinPptxRW::_relsGeneratorInfo oRelsGeneratorInfo = pReader->m_pRels->WriteImage(strUrl, pFill->additionalFiles, pFill->oleData, strOrigBase64); // ------------------- if (!strTempFile.empty()) diff --git a/OOXML/PPTXFormat/Theme.cpp b/OOXML/PPTXFormat/Theme.cpp index ebfa2f6df7..aeebe33700 100644 --- a/OOXML/PPTXFormat/Theme.cpp +++ b/OOXML/PPTXFormat/Theme.cpp @@ -114,6 +114,8 @@ namespace PPTX } void Theme::read(XmlUtils::CXmlNode &oNode, FileMap& map) { + extraClrSchemeLst.clear(); + std::wstring strNodeName = XmlUtils::GetNameNoNS(oNode.GetName()); if (_T("themeOverride") == strNodeName) { @@ -146,7 +148,6 @@ namespace PPTX txDef->SetParentFilePointer(this); } - extraClrSchemeLst.clear(); XmlUtils::CXmlNode oNodeList; if (oNode.GetNode(_T("a:extraClrSchemeLst"), oNodeList)) { diff --git a/OOXML/PPTXFormat/Theme.h b/OOXML/PPTXFormat/Theme.h index fb94036dea..49aa50d341 100644 --- a/OOXML/PPTXFormat/Theme.h +++ b/OOXML/PPTXFormat/Theme.h @@ -30,8 +30,6 @@ * */ #pragma once -#ifndef PPTX_THEME_FILE_INCLUDE_H_ -#define PPTX_THEME_FILE_INCLUDE_H_ #include "FileContainer.h" #include "WrapperFile.h" @@ -108,5 +106,3 @@ namespace PPTX Logic::ClrMap const* m_map; }; } // namespace PPTX - -#endif // PPTX_THEME_FILE_INCLUDE_H_ diff --git a/OOXML/PPTXFormat/Theme/ClrScheme.h b/OOXML/PPTXFormat/Theme/ClrScheme.h index eb6f5cdc94..4341b8a07b 100644 --- a/OOXML/PPTXFormat/Theme/ClrScheme.h +++ b/OOXML/PPTXFormat/Theme/ClrScheme.h @@ -30,8 +30,6 @@ * */ #pragma once -#ifndef PPTX_THEME_CLRSCHEME_INCLUDE_H_ -#define PPTX_THEME_CLRSCHEME_INCLUDE_H_ #include "./../WrapperWritingElement.h" #include "./../Logic/UniColor.h" @@ -82,5 +80,3 @@ namespace PPTX }; } // namespace nsTheme } // namespace PPTX - -#endif // PPTX_THEME_CLRSCHEME_INCLUDE_H diff --git a/OOXML/PPTXFormat/Theme/ExtraClrScheme.h b/OOXML/PPTXFormat/Theme/ExtraClrScheme.h index a16173396f..03ee92f16c 100644 --- a/OOXML/PPTXFormat/Theme/ExtraClrScheme.h +++ b/OOXML/PPTXFormat/Theme/ExtraClrScheme.h @@ -48,7 +48,6 @@ namespace PPTX public: PPTX_LOGIC_BASE(ExtraClrScheme) - public: virtual void fromXML(XmlUtils::CXmlNode& node); virtual std::wstring toXML() const; @@ -56,8 +55,7 @@ namespace PPTX virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); - public: - ClrScheme clrScheme; + ClrScheme clrScheme; nullable clrMap; protected: diff --git a/OOXML/PPTXFormat/Theme/FmtScheme.cpp b/OOXML/PPTXFormat/Theme/FmtScheme.cpp index 217dcaac1e..f1909dcad3 100644 --- a/OOXML/PPTXFormat/Theme/FmtScheme.cpp +++ b/OOXML/PPTXFormat/Theme/FmtScheme.cpp @@ -42,7 +42,8 @@ namespace PPTX parentFile = oSrc.parentFile; parentElement = oSrc.parentElement; - name = oSrc.name; + name = oSrc.name; + nameNode = oSrc.nameNode; fillStyleLst = oSrc.fillStyleLst; lnStyleLst = oSrc.lnStyleLst; @@ -53,24 +54,26 @@ namespace PPTX } void FmtScheme::fromXML(XmlUtils::CXmlNode& node) { + nameNode = node.GetName(); + fillStyleLst.clear(); lnStyleLst.clear(); effectStyleLst.clear(); bgFillStyleLst.clear(); - name = node.GetAttribute(_T("name")); + name = node.GetAttribute(L"name"); - XmlUtils::CXmlNode oNode1 = node.ReadNode(_T("a:fillStyleLst")); - XmlMacroLoadArray(oNode1, _T("*"), fillStyleLst, Logic::UniFill); + XmlUtils::CXmlNode oNode1 = node.ReadNode(L"a:fillStyleLst"); + XmlMacroLoadArray(oNode1, L"*", fillStyleLst, Logic::UniFill); - XmlUtils::CXmlNode oNode2 = node.ReadNode(_T("a:lnStyleLst")); - XmlMacroLoadArray(oNode2, _T("a:ln"), lnStyleLst, Logic::Ln); + XmlUtils::CXmlNode oNode2 = node.ReadNode(L"a:lnStyleLst"); + XmlMacroLoadArray(oNode2, L"a:ln", lnStyleLst, Logic::Ln); - XmlUtils::CXmlNode oNode3 = node.ReadNode(_T("a:effectStyleLst")); - XmlMacroLoadArray(oNode3, _T("a:effectStyle"), effectStyleLst, Logic::EffectStyle); + XmlUtils::CXmlNode oNode3 = node.ReadNode(L"a:effectStyleLst"); + XmlMacroLoadArray(oNode3, L"a:effectStyle", effectStyleLst, Logic::EffectStyle); - XmlUtils::CXmlNode oNode4 = node.ReadNode(_T("a:bgFillStyleLst")); - XmlMacroLoadArray(oNode4, _T("*"), bgFillStyleLst, Logic::UniFill); + XmlUtils::CXmlNode oNode4 = node.ReadNode(L"a:bgFillStyleLst"); + XmlMacroLoadArray(oNode4, L"*", bgFillStyleLst, Logic::UniFill); FillWithDefaults(); FillParentPointersForChilds(); @@ -78,38 +81,47 @@ namespace PPTX std::wstring FmtScheme::toXML() const { XmlUtils::CAttribute oAttr; - oAttr.Write(_T("name"), name); + oAttr.Write(L"name", name); + oAttr.m_strValue += xmlns_attr; XmlUtils::CNodeValue oValue; - oValue.WriteArray(_T("a:fillStyleLst"), fillStyleLst); - oValue.WriteArray(_T("a:lnStyleLst"), lnStyleLst); - oValue.WriteArray(_T("a:effectStyleLst"), effectStyleLst); - oValue.WriteArray(_T("a:bgFillStyleLst"), bgFillStyleLst); + oValue.WriteArray(L"a:fillStyleLst", fillStyleLst); + oValue.WriteArray(L"a:lnStyleLst", lnStyleLst); + oValue.WriteArray(L"a:effectStyleLst", effectStyleLst); + oValue.WriteArray(L"a:bgFillStyleLst", bgFillStyleLst); - return XmlUtils::CreateNode(_T("a:fmtScheme"), oAttr, oValue); + return XmlUtils::CreateNode(nameNode, oAttr, oValue); } void FmtScheme::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const { - pWriter->StartNode(_T("a:fmtScheme")); + pWriter->StartNode(nameNode); pWriter->StartAttributes(); - pWriter->WriteAttribute2(_T("name"), name); + pWriter->WriteAttribute2(L"name", name); + pWriter->WriteString(xmlns_attr); pWriter->EndAttributes(); - pWriter->WriteArray(_T("a:fillStyleLst"), fillStyleLst); - pWriter->WriteArray(_T("a:lnStyleLst"), lnStyleLst); - //pWriter->WriteArray(_T("a:effectStyleLst"), effectStyleLst); - // вот такой поуерпоинт (эффекты пока не читаем - а они нужны. даже если и не используются нигде) - pWriter->WriteString(_T("\ + pWriter->WriteArray(L"a:fillStyleLst", fillStyleLst); + pWriter->WriteArray(L"a:lnStyleLst", lnStyleLst); + + if (effectStyleLst.empty()) + { + // вот такой поуерпоинт (эффекты пока не читаем - а они нужны. даже если и не используются нигде) + pWriter->WriteString(L"\ \ \ \ \ -")); +"); + } + else + { + pWriter->WriteArray(L"a:effectStyleLst", effectStyleLst); + } - pWriter->WriteArray(_T("a:bgFillStyleLst"), bgFillStyleLst); + pWriter->WriteArray(L"a:bgFillStyleLst", bgFillStyleLst); - pWriter->EndNode(_T("a:fmtScheme")); + pWriter->EndNode(nameNode); } void FmtScheme::GetLineStyle(int number, Logic::Ln& lnStyle) const { @@ -351,23 +363,17 @@ namespace PPTX } void FmtScheme::FillParentPointersForChilds() { - size_t count = 0; + for (auto elm : fillStyleLst) + elm.SetParentPointer(this); - count = fillStyleLst.size(); - for (size_t i = 0; i < count; ++i) - fillStyleLst[i].SetParentPointer(this); + for (auto elm : lnStyleLst) + elm.SetParentPointer(this); - count = lnStyleLst.size(); - for (size_t i = 0; i < count; ++i) - lnStyleLst[i].SetParentPointer(this); + for (auto elm : effectStyleLst) + elm.SetParentPointer(this); - count = effectStyleLst.size(); - for (size_t i = 0; i < count; ++i) - effectStyleLst[i].SetParentPointer(this); - - count = bgFillStyleLst.size(); - for (size_t i = 0; i < count; ++i) - bgFillStyleLst[i].SetParentPointer(this); + for (auto elm : bgFillStyleLst) + elm.SetParentPointer(this); } } // namespace nsTheme } // namespace PPTX diff --git a/OOXML/PPTXFormat/Theme/FmtScheme.h b/OOXML/PPTXFormat/Theme/FmtScheme.h index 6c3ac3f122..47cfca19c8 100644 --- a/OOXML/PPTXFormat/Theme/FmtScheme.h +++ b/OOXML/PPTXFormat/Theme/FmtScheme.h @@ -30,8 +30,6 @@ * */ #pragma once -#ifndef PPTX_THEME_FMTSCHEME_INCLUDE_H_ -#define PPTX_THEME_FMTSCHEME_INCLUDE_H_ #include "./../WrapperWritingElement.h" #include "./../Logic/UniFill.h" @@ -45,11 +43,10 @@ namespace PPTX class FmtScheme : public WrapperWritingElement { public: - PPTX_LOGIC_BASE(FmtScheme) - + FmtScheme() : nameNode(L"a:fmtScheme") {} + PPTX_LOGIC_BASE_NC(FmtScheme) FmtScheme& operator=(const FmtScheme& oSrc); - public: virtual void fromXML(XmlUtils::CXmlNode& node); virtual std::wstring toXML() const; @@ -63,7 +60,9 @@ namespace PPTX void FillWithDefaults(); - public: + std::wstring nameNode; + std::wstring xmlns_attr; + std::wstring name; std::vector fillStyleLst; std::vector lnStyleLst; @@ -76,4 +75,3 @@ namespace PPTX } // namespace nsTheme } // namespace PPTX -#endif // PPTX_THEME_FMTSCHEME_INCLUDE_H diff --git a/OOXML/PPTXFormat/Theme/FontScheme.h b/OOXML/PPTXFormat/Theme/FontScheme.h index 91127ab86e..728df21646 100644 --- a/OOXML/PPTXFormat/Theme/FontScheme.h +++ b/OOXML/PPTXFormat/Theme/FontScheme.h @@ -30,8 +30,6 @@ * */ #pragma once -#ifndef PPTX_THEME_FONTSCHEME_INCLUDE_H_ -#define PPTX_THEME_FONTSCHEME_INCLUDE_H_ #include "./../WrapperWritingElement.h" #include "./../Logic/FontCollection.h" @@ -62,6 +60,4 @@ namespace PPTX virtual void FillParentPointersForChilds(); }; } // namespace nsTheme -} // namespace PPTX - -#endif // PPTX_THEME_FONTSCHEME_INCLUDE_H +} // namespace PPTX \ No newline at end of file diff --git a/OOXML/PPTXFormat/Theme/ThemeElements.cpp b/OOXML/PPTXFormat/Theme/ThemeElements.cpp index 7ba16fa26f..dda6f11359 100644 --- a/OOXML/PPTXFormat/Theme/ThemeElements.cpp +++ b/OOXML/PPTXFormat/Theme/ThemeElements.cpp @@ -38,9 +38,70 @@ namespace PPTX { void ThemeElements::fromXML(XmlUtils::CXmlNode& node) { - clrScheme = node.ReadNode(_T("a:clrScheme")); - fontScheme = node.ReadNode(_T("a:fontScheme")); - fmtScheme = node.ReadNode(_T("a:fmtScheme")); + std::vector oNodes; + if (node.GetNodes(L"*", oNodes)) + { + for (size_t i = 0; i < oNodes.size(); ++i) + { + XmlUtils::CXmlNode& oNode = oNodes[i]; + + std::wstring strName = XmlUtils::GetNameNoNS(oNode.GetName()); + + if (L"clrScheme" == strName) + clrScheme.fromXML(oNode); + else if (L"fontScheme" == strName) + fontScheme.fromXML(oNode); + else if (L"fmtScheme" == strName) + fmtScheme.fromXML(oNode); + else if (L"extLst" == strName) + { + std::vector nodesExtLst; + if (oNode.GetNodes(L"*", nodesExtLst)) + { + for (auto nodeExt : nodesExtLst) + { + std::wstring uri; + XmlMacroReadAttributeBase(nodeExt, L"uri", uri); + + uri = XmlUtils::GetUpper(uri); + + if (uri == L"{1342405F-259F-4C95-8CDF-A9DCE2D418A2}") + { + fmtConnectorScheme = nodeExt.ReadNodeNoNS(L"fmtConnectorScheme"); + } + else if (uri == L"{D75FF423-9257-4291-A4FE-1B2448832E17}") + { + //themeScheme - schemeID + } + else if (uri == L"{27CD58D4-7086-4B73-B2AB-7AEBE2148A8C}") + { + //fmtSchemeEx - schemeID + } + else if (uri == L"{C6430689-8E98-42EC-ADBF-087148533A3F}") + { + //fmtConnectorSchemeEx - schemeID + } + else if (uri == L"{56243398-1771-4C39-BF73-A5702A9C147F}") + { + fillStyles = nodeExt.ReadNodeNoNS(L"fillStyles"); + } + else if (uri == L"{6CAB99AB-0A78-4BAB-B597-526D62367CB4}") + { + lineStyles = nodeExt.ReadNodeNoNS(L"lineStyles"); + } + else if (uri == L"{EBE24D50-EC5C-4D6F-A1A3-C5F0A18B936A}") + { + fontStylesGroup = nodeExt.ReadNodeNoNS(L"fontStylesGroup"); + } + else if (uri == L"{494CE47F-D151-47DC-95E8-85652EA8A67E}") + { + variationStyleSchemeLst = nodeExt.ReadNodeNoNS(L"variationStyleSchemeLst"); + } + } + } + } + } + } FillParentPointersForChilds(); } @@ -51,24 +112,112 @@ namespace PPTX oValue.Write(fontScheme); oValue.Write(fmtScheme); - return XmlUtils::CreateNode(_T("a:themeElements"), oValue); + if (fmtConnectorScheme.IsInit() || fillStyles.IsInit() || lineStyles.IsInit() || fontStylesGroup.IsInit() || variationStyleSchemeLst.IsInit()) + { + oValue.m_strValue += L""; + + if (fmtConnectorScheme.IsInit()) + { + oValue.m_strValue += L""; + oValue.Write(*fmtConnectorScheme); + oValue.m_strValue += L""; + } + if (fillStyles.IsInit()) + { + oValue.m_strValue += L""; + oValue.Write(*fillStyles); + oValue.m_strValue += L""; + } + if (lineStyles.IsInit()) + { + oValue.m_strValue += L""; + oValue.Write(*lineStyles); + oValue.m_strValue += L""; + } + if (fontStylesGroup.IsInit()) + { + oValue.m_strValue += L""; + oValue.Write(*fontStylesGroup); + oValue.m_strValue += L""; + } + if (variationStyleSchemeLst.IsInit()) + { + oValue.m_strValue += L""; + oValue.Write(*variationStyleSchemeLst); + oValue.m_strValue += L""; + } + oValue.m_strValue += L""; + } + return XmlUtils::CreateNode(L"a:themeElements", oValue); } void ThemeElements::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const { pWriter->WriteRecord1(0, clrScheme); pWriter->WriteRecord1(1, fontScheme); pWriter->WriteRecord1(2, fmtScheme); + pWriter->WriteRecord2(3, fmtConnectorScheme); + pWriter->WriteRecord2(4, fillStyles); + pWriter->WriteRecord2(5, lineStyles); + pWriter->WriteRecord2(6, fontStylesGroup); + pWriter->WriteRecord2(7, variationStyleSchemeLst); } void ThemeElements::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const { - pWriter->StartNode(_T("a:themeElements")); + pWriter->StartNode(L"a:themeElements"); pWriter->EndAttributes(); clrScheme.toXmlWriter(pWriter); fontScheme.toXmlWriter(pWriter); fmtScheme.toXmlWriter(pWriter); - pWriter->EndNode(_T("a:themeElements")); + if (fmtConnectorScheme.IsInit() || fillStyles.IsInit() || lineStyles.IsInit() || fontStylesGroup.IsInit() || variationStyleSchemeLst.IsInit()) + { + pWriter->StartNode(L"a:extLst"); + pWriter->EndAttributes(); + + if (fmtConnectorScheme.IsInit()) + { + pWriter->StartNode(L"a:ext"); + pWriter->WriteAttribute(L"uri", L"{1342405F-259F-4C95-8CDF-A9DCE2D418A2}"); + pWriter->EndAttributes(); + fmtConnectorScheme->toXmlWriter(pWriter); + pWriter->EndNode(L"a:ext"); + } + if (fillStyles.IsInit()) + { + pWriter->StartNode(L"a:ext"); + pWriter->WriteAttribute(L"uri", L"{56243398-1771-4C39-BF73-A5702A9C147F}"); + pWriter->EndAttributes(); + fillStyles->toXmlWriter(pWriter); + pWriter->EndNode(L"a:ext"); + } + if (lineStyles.IsInit()) + { + pWriter->StartNode(L"a:ext"); + pWriter->WriteAttribute(L"uri", L"{6CAB99AB-0A78-4BAB-B597-526D62367CB4}"); + pWriter->EndAttributes(); + lineStyles->toXmlWriter(pWriter); + pWriter->EndNode(L"a:ext"); + } + if (fontStylesGroup.IsInit()) + { + pWriter->StartNode(L"a:ext"); + pWriter->WriteAttribute(L"uri", L"{EBE24D50-EC5C-4D6F-A1A3-C5F0A18B936A}"); + pWriter->EndAttributes(); + fontStylesGroup->toXmlWriter(pWriter); + pWriter->EndNode(L"a:ext"); + } + if (variationStyleSchemeLst.IsInit()) + { + pWriter->StartNode(L"a:ext"); + pWriter->WriteAttribute(L"uri", L"{494CE47F-D151-47DC-95E8-85652EA8A67E}"); + pWriter->EndAttributes(); + variationStyleSchemeLst->toXmlWriter(pWriter); + pWriter->EndNode(L"a:ext"); + } + pWriter->EndNode(L"a:extLst"); + } + pWriter->EndNode(L"a:themeElements"); } void ThemeElements::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) { @@ -81,19 +230,42 @@ namespace PPTX { case 0: { - clrScheme.fromPPTY(pReader); - break; - } + clrScheme.fromPPTY(pReader); + }break; case 1: { - fontScheme.fromPPTY(pReader); - break; - } + fontScheme.fromPPTY(pReader); + }break; case 2: { - fmtScheme.fromPPTY(pReader); - break; - } + fmtScheme.fromPPTY(pReader); + }break; + case 3: + { + fmtConnectorScheme.Init(); fmtConnectorScheme->nameNode = L"vt:fmtConnectorScheme"; + fmtConnectorScheme->xmlns_attr = L" xmlns:vt=\"http://schemas.microsoft.com/office/visio/2012/theme\""; + fmtConnectorScheme->fromPPTY(pReader); + }break; + case 4: + { + fillStyles.Init(); + fillStyles->fromPPTY(pReader); + }break; + case 5: + { + lineStyles.Init(); + lineStyles->fromPPTY(pReader); + }break; + case 6: + { + fontStylesGroup.Init(); + fontStylesGroup->fromPPTY(pReader); + }break; + case 7: + { + variationStyleSchemeLst.Init(); + variationStyleSchemeLst->fromPPTY(pReader); + }break; default: break; } @@ -106,6 +278,12 @@ namespace PPTX clrScheme.SetParentPointer(this); fontScheme.SetParentPointer(this); fmtScheme.SetParentPointer(this); + + if (fmtConnectorScheme.IsInit()) fmtConnectorScheme->SetParentPointer(this); + if (fillStyles.IsInit()) fillStyles->SetParentPointer(this); + if (lineStyles.IsInit()) lineStyles->SetParentPointer(this); + if (fontStylesGroup.IsInit()) fontStylesGroup->SetParentPointer(this); + if (variationStyleSchemeLst.IsInit()) variationStyleSchemeLst->SetParentPointer(this); } } // namespace nsTheme } // namespace PPTX diff --git a/OOXML/PPTXFormat/Theme/ThemeElements.h b/OOXML/PPTXFormat/Theme/ThemeElements.h index d50e0656fc..81dbaa781c 100644 --- a/OOXML/PPTXFormat/Theme/ThemeElements.h +++ b/OOXML/PPTXFormat/Theme/ThemeElements.h @@ -30,14 +30,14 @@ * */ #pragma once -#ifndef PPTX_THEME_THEMEELEMENTS_INCLUDE_H_ -#define PPTX_THEME_THEMEELEMENTS_INCLUDE_H_ #include "./../WrapperWritingElement.h" #include "ClrScheme.h" #include "FontScheme.h" #include "FmtScheme.h" +#include "VisioThemeElements.h" + namespace PPTX { namespace nsTheme @@ -57,11 +57,15 @@ namespace PPTX ClrScheme clrScheme; FontScheme fontScheme; FmtScheme fmtScheme; +//visio ext + nullable fmtConnectorScheme; + nullable fillStyles; + nullable lineStyles; + nullable fontStylesGroup; + nullable variationStyleSchemeLst; protected: virtual void FillParentPointersForChilds(); }; } // namespace nsTheme } // namespace PPTX - -#endif // PPTX_THEME_THEMEELEMENTS_INCLUDE_H diff --git a/OOXML/PPTXFormat/Theme/VisioThemeElements.cpp b/OOXML/PPTXFormat/Theme/VisioThemeElements.cpp new file mode 100644 index 0000000000..468ba69ac8 --- /dev/null +++ b/OOXML/PPTXFormat/Theme/VisioThemeElements.cpp @@ -0,0 +1,1179 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "VisioThemeElements.h" + +namespace PPTX +{ + namespace nsTheme + { + VariationStyleSchemeLst& VariationStyleSchemeLst::operator=(const VariationStyleSchemeLst& oSrc) + { + parentFile = oSrc.parentFile; + parentElement = oSrc.parentElement; + + m_arrItems.clear(); + for (auto elm : oSrc.m_arrItems) + m_arrItems.push_back(elm); + + return *this; + } + void VariationStyleSchemeLst::fromXML(XmlUtils::CXmlNode& node) + { + std::vector oNodes; + if (node.GetNodes(L"*", oNodes)) + { + for (size_t i = 0; i < oNodes.size(); ++i) + { + XmlUtils::CXmlNode& oNode = oNodes[i]; + + std::wstring strName = XmlUtils::GetNameNoNS(oNode.GetName()); + + if (L"variationStyleScheme" == strName) + { + m_arrItems.emplace_back(); + m_arrItems.back().fromXML(oNode); + } + } + } + FillParentPointersForChilds(); + } + std::wstring VariationStyleSchemeLst::toXML() const + { + XmlUtils::CAttribute oAttr; + oAttr.Write(L"xmlns:vt", L"http://schemas.microsoft.com/office/visio/2012/theme"); + + XmlUtils::CNodeValue oValue; + oValue.WriteArray(m_arrItems); + + return XmlUtils::CreateNode(L"vt:variationStyleSchemeLst", oAttr, oValue); + } + void VariationStyleSchemeLst::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + for (auto elm : m_arrItems) + pWriter->WriteRecord1(0, elm); + } + void VariationStyleSchemeLst::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"vt:variationStyleSchemeLst"); + pWriter->WriteAttribute(L"xmlns:vt", L"http://schemas.microsoft.com/office/visio/2012/theme"); + pWriter->EndAttributes(); + + pWriter->WriteArray2(m_arrItems); + + pWriter->EndNode(_T("vt:variationStyleSchemeLst")); + } + void VariationStyleSchemeLst::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + + while (pReader->GetPos() < _end_rec) + { + BYTE _at = pReader->GetUChar(); + switch (_at) + { + case 0: + { + m_arrItems.emplace_back(); + m_arrItems.back().fromPPTY(pReader); + }break; + default: + break; + } + } + + pReader->Seek(_end_rec); + } + void VariationStyleSchemeLst::FillParentPointersForChilds() + { + for (auto elm : m_arrItems) + elm.SetParentPointer(this); + } +//----------------------------------------------------------------------------------------- + FontStyles& FontStyles::operator=(const FontStyles& oSrc) + { + parentFile = oSrc.parentFile; + parentElement = oSrc.parentElement; + + node_name = oSrc.node_name; + + m_arrItems.clear(); + for (auto elm : oSrc.m_arrItems) + m_arrItems.push_back(elm); + + return *this; + } + void FontStyles::fromXML(XmlUtils::CXmlNode& node) + { + node_name = node.GetName(); + + std::vector oNodes; + if (node.GetNodes(L"*", oNodes)) + { + for (size_t i = 0; i < oNodes.size(); ++i) + { + XmlUtils::CXmlNode& oNode = oNodes[i]; + + std::wstring strName = XmlUtils::GetNameNoNS(oNode.GetName()); + + if (L"fontProps" == strName) + { + m_arrItems.emplace_back(); + m_arrItems.back().fromXML(oNode); + } + } + } + FillParentPointersForChilds(); + } + std::wstring FontStyles::toXML() const + { + XmlUtils::CAttribute oAttr; + XmlUtils::CNodeValue oValue; + oValue.WriteArray(m_arrItems); + + return XmlUtils::CreateNode(node_name, oAttr, oValue); + } + void FontStyles::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + for (auto elm : m_arrItems) + pWriter->WriteRecord1(0, elm); + } + void FontStyles::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(node_name); + pWriter->EndAttributes(); + + pWriter->WriteArray2(m_arrItems); + + pWriter->EndNode(node_name); + } + void FontStyles::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + + while (pReader->GetPos() < _end_rec) + { + BYTE _at = pReader->GetUChar(); + switch (_at) + { + case 0: + { + m_arrItems.emplace_back(); + m_arrItems.back().fromPPTY(pReader); + }break; + default: + break; + } + } + + pReader->Seek(_end_rec); + } + void FontStyles::FillParentPointersForChilds() + { + for (auto elm : m_arrItems) + elm.SetParentPointer(this); + } +//----------------------------------------------------------------------------------------- + SchemeLineStyles& SchemeLineStyles::operator=(const SchemeLineStyles& oSrc) + { + parentFile = oSrc.parentFile; + parentElement = oSrc.parentElement; + + node_name = oSrc.node_name; + + m_arrItems.clear(); + for (auto elm : oSrc.m_arrItems) + m_arrItems.push_back(elm); + + return *this; + } + void SchemeLineStyles::fromXML(XmlUtils::CXmlNode& node) + { + node_name = node.GetName(); + + std::vector oNodes; + if (node.GetNodes(L"*", oNodes)) + { + for (size_t i = 0; i < oNodes.size(); ++i) + { + XmlUtils::CXmlNode& oNode = oNodes[i]; + + std::wstring strName = XmlUtils::GetNameNoNS(oNode.GetName()); + + if (L"lineStyle" == strName) + { + m_arrItems.emplace_back(); + m_arrItems.back().fromXML(oNode); + } + } + } + FillParentPointersForChilds(); + } + std::wstring SchemeLineStyles::toXML() const + { + XmlUtils::CAttribute oAttr; + XmlUtils::CNodeValue oValue; + oValue.WriteArray(m_arrItems); + + return XmlUtils::CreateNode(node_name, oAttr, oValue); + } + void SchemeLineStyles::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + for (auto elm : m_arrItems) + pWriter->WriteRecord1(0, elm); + } + void SchemeLineStyles::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(node_name); + pWriter->EndAttributes(); + + pWriter->WriteArray2(m_arrItems); + + pWriter->EndNode(node_name); + } + void SchemeLineStyles::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + + while (pReader->GetPos() < _end_rec) + { + BYTE _at = pReader->GetUChar(); + switch (_at) + { + case 0: + { + m_arrItems.emplace_back(); + m_arrItems.back().fromPPTY(pReader); + }break; + default: + break; + } + } + + pReader->Seek(_end_rec); + } + void SchemeLineStyles::FillParentPointersForChilds() + { + for (auto elm : m_arrItems) + elm.SetParentPointer(this); + } +//----------------------------------------------------------------------------------------- + FillStyles& FillStyles::operator=(const FillStyles& oSrc) + { + parentFile = oSrc.parentFile; + parentElement = oSrc.parentElement; + + m_arrItems.clear(); + for (auto elm : oSrc.m_arrItems) + m_arrItems.push_back(elm); + + return *this; + } + void FillStyles::fromXML(XmlUtils::CXmlNode& node) + { + std::vector oNodes; + if (node.GetNodes(L"*", oNodes)) + { + for (size_t i = 0; i < oNodes.size(); ++i) + { + XmlUtils::CXmlNode& oNode = oNodes[i]; + + std::wstring strName = XmlUtils::GetNameNoNS(oNode.GetName()); + + if (L"fillProps" == strName) + { + m_arrItems.emplace_back(); + m_arrItems.back().fromXML(oNode); + } + } + } + FillParentPointersForChilds(); + } + std::wstring FillStyles::toXML() const + { + XmlUtils::CAttribute oAttr; + oAttr.Write(L"xmlns:vt", L"http://schemas.microsoft.com/office/visio/2012/theme"); + + XmlUtils::CNodeValue oValue; + oValue.WriteArray(m_arrItems); + + return XmlUtils::CreateNode(L"vt:fillStyles", oAttr, oValue); + } + void FillStyles::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + for (auto elm : m_arrItems) + pWriter->WriteRecord1(0, elm); + } + void FillStyles::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"vt:fillStyles"); + pWriter->WriteAttribute(L"xmlns:vt", L"http://schemas.microsoft.com/office/visio/2012/theme"); + pWriter->EndAttributes(); + + pWriter->WriteArray2(m_arrItems); + + pWriter->EndNode(L"vt:fillStyles"); + } + void FillStyles::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + + while (pReader->GetPos() < _end_rec) + { + BYTE _at = pReader->GetUChar(); + switch (_at) + { + case 0: + { + m_arrItems.emplace_back(); + m_arrItems.back().fromPPTY(pReader); + }break; + default: + break; + } + } + pReader->Seek(_end_rec); + } + void FillStyles::FillParentPointersForChilds() + { + for (auto elm : m_arrItems) + elm.SetParentPointer(this); + } +//----------------------------------------------------------------------------------------- + VariationStyleScheme& VariationStyleScheme::operator=(const VariationStyleScheme& oSrc) + { + parentFile = oSrc.parentFile; + parentElement = oSrc.parentElement; + + embellishment = oSrc.embellishment; + + m_arrItems.clear(); + for (auto elm : oSrc.m_arrItems) + m_arrItems.push_back(elm); + + return *this; + } + void VariationStyleScheme::fromXML(XmlUtils::CXmlNode& node) + { + XmlMacroReadAttributeBase(node, L"embellishment", embellishment); + + std::vector oNodes; + if (node.GetNodes(L"*", oNodes)) + { + for (size_t i = 0; i < oNodes.size(); ++i) + { + XmlUtils::CXmlNode& oNode = oNodes[i]; + + std::wstring strName = XmlUtils::GetNameNoNS(oNode.GetName()); + + if (L"varStyle" == strName) + { + m_arrItems.emplace_back(); + m_arrItems.back().fromXML(oNode); + } + } + } + FillParentPointersForChilds(); + } + std::wstring VariationStyleScheme::toXML() const + { + XmlUtils::CAttribute oAttr; + oAttr.Write(L"embellishment", embellishment); + + XmlUtils::CNodeValue oValue; + oValue.WriteArray(m_arrItems); + + return XmlUtils::CreateNode(L"vt:variationStyleScheme", oAttr, oValue); + } + void VariationStyleScheme::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, embellishment); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + for (auto elm : m_arrItems) + pWriter->WriteRecord1(0, elm); + } + void VariationStyleScheme::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"vt:variationStyleScheme"); + pWriter->WriteAttribute2(L"embellishment", embellishment); + pWriter->EndAttributes(); + + pWriter->WriteArray2(m_arrItems); + + pWriter->EndNode(L"vt:variationStyleScheme"); + } + void VariationStyleScheme::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + + switch (_at) + { + case 0: + { + embellishment = pReader->GetULong(); + }break; + default: + break; + } + } + while (pReader->GetPos() < _end_rec) + { + BYTE _at = pReader->GetUChar(); + switch (_at) + { + case 0: + { + m_arrItems.emplace_back(); + m_arrItems.back().fromPPTY(pReader); + }break; + default: + break; + } + } + pReader->Seek(_end_rec); + } + void VariationStyleScheme::FillParentPointersForChilds() + { + for (auto elm : m_arrItems) + elm.SetParentPointer(this); + } +//----------------------------------------------------------------------------------------- + FontStylesGroup& FontStylesGroup::operator=(const FontStylesGroup& oSrc) + { + parentFile = oSrc.parentFile; + parentElement = oSrc.parentElement; + + connectorFontStyles = oSrc.connectorFontStyles; + fontStyles = oSrc.fontStyles; + + return *this; + } + void FontStylesGroup::fromXML(XmlUtils::CXmlNode& node) + { + std::vector oNodes; + if (node.GetNodes(L"*", oNodes)) + { + for (size_t i = 0; i < oNodes.size(); ++i) + { + XmlUtils::CXmlNode& oNode = oNodes[i]; + + std::wstring strName = XmlUtils::GetNameNoNS(oNode.GetName()); + + if (L"connectorFontStyles" == strName) + { + connectorFontStyles.fromXML(oNode); + } + else if (L"fontStyles" == strName) + { + fontStyles.fromXML(oNode); + } + } + } + FillParentPointersForChilds(); + } + std::wstring FontStylesGroup::toXML() const + { + XmlUtils::CAttribute oAttr; + oAttr.Write(L"xmlns:vt", L"http://schemas.microsoft.com/office/visio/2012/theme"); + + XmlUtils::CNodeValue oValue; + oValue.Write(connectorFontStyles); + oValue.Write(fontStyles); + + return XmlUtils::CreateNode(L"vt:fontStylesGroup", oAttr, oValue); + } + void FontStylesGroup::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteRecord1(0, connectorFontStyles); + pWriter->WriteRecord1(1, fontStyles); + } + void FontStylesGroup::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"vt:fontStylesGroup"); + pWriter->WriteAttribute(L"xmlns:vt", L"http://schemas.microsoft.com/office/visio/2012/theme"); + pWriter->EndAttributes(); + + connectorFontStyles.toXmlWriter(pWriter); + fontStyles.toXmlWriter(pWriter); + + pWriter->EndNode(L"vt:fontStylesGroup"); + } + void FontStylesGroup::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + + while (pReader->GetPos() < _end_rec) + { + BYTE _at = pReader->GetUChar(); + switch (_at) + { + case 0: + { + connectorFontStyles.node_name = L"vt:connectorFontStyles"; + connectorFontStyles.fromPPTY(pReader); + }break; + case 1: + { + fontStyles.node_name = L"vt:fontStyles"; + fontStyles.fromPPTY(pReader); + }break; + default: + break; + } + } + + pReader->Seek(_end_rec); + } + void FontStylesGroup::FillParentPointersForChilds() + { + connectorFontStyles.SetParentPointer(this); + fontStyles.SetParentPointer(this); + } +//----------------------------------------------------------------------------------------- + LineStyles& LineStyles::operator=(const LineStyles& oSrc) + { + parentFile = oSrc.parentFile; + parentElement = oSrc.parentElement; + + fmtConnectorSchemeLineStyles = oSrc.fmtConnectorSchemeLineStyles; + fmtSchemeLineStyles = oSrc.fmtSchemeLineStyles; + + return *this; + } + void LineStyles::fromXML(XmlUtils::CXmlNode& node) + { + std::vector oNodes; + if (node.GetNodes(L"*", oNodes)) + { + for (size_t i = 0; i < oNodes.size(); ++i) + { + XmlUtils::CXmlNode& oNode = oNodes[i]; + + std::wstring strName = XmlUtils::GetNameNoNS(oNode.GetName()); + + if (L"fmtConnectorSchemeLineStyles" == strName) + { + fmtConnectorSchemeLineStyles.fromXML(oNode); + } + else if (L"fmtSchemeLineStyles" == strName) + { + fmtSchemeLineStyles.fromXML(oNode); + } + } + } + FillParentPointersForChilds(); + } + std::wstring LineStyles::toXML() const + { + XmlUtils::CAttribute oAttr; + oAttr.Write(L"xmlns:vt", L"http://schemas.microsoft.com/office/visio/2012/theme"); + + XmlUtils::CNodeValue oValue; + oValue.Write(fmtConnectorSchemeLineStyles); + oValue.Write(fmtSchemeLineStyles); + + return XmlUtils::CreateNode(L"vt:lineStyles", oAttr, oValue); + } + void LineStyles::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteRecord1(0, fmtConnectorSchemeLineStyles); + pWriter->WriteRecord1(1, fmtSchemeLineStyles); + } + void LineStyles::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"vt:lineStyles"); + pWriter->WriteAttribute(L"xmlns:vt", L"http://schemas.microsoft.com/office/visio/2012/theme"); + pWriter->EndAttributes(); + + fmtConnectorSchemeLineStyles.toXmlWriter(pWriter); + fmtSchemeLineStyles.toXmlWriter(pWriter); + + pWriter->EndNode(L"vt:lineStyles"); + } + void LineStyles::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + + while (pReader->GetPos() < _end_rec) + { + BYTE _at = pReader->GetUChar(); + switch (_at) + { + case 0: + { + fmtConnectorSchemeLineStyles.node_name = L"vt:fmtConnectorSchemeLineStyles"; + fmtConnectorSchemeLineStyles.fromPPTY(pReader); + }break; + case 1: + { + fmtSchemeLineStyles.node_name = L"vt:fmtSchemeLineStyles"; + fmtSchemeLineStyles.fromPPTY(pReader); + }break; + default: + break; + } + } + + pReader->Seek(_end_rec); + } + void LineStyles::FillParentPointersForChilds() + { + fmtConnectorSchemeLineStyles.SetParentPointer(this); + fmtSchemeLineStyles.SetParentPointer(this); + } +//----------------------------------------------------------------------------------------- + VarStyle& VarStyle::operator=(const VarStyle& oSrc) + { + parentFile = oSrc.parentFile; + parentElement = oSrc.parentElement; + + fillIdx = oSrc.fillIdx; + lineIdx = oSrc.lineIdx; + effectIdx = oSrc.effectIdx; + fontIdx = oSrc.fontIdx; + + return *this; + } + void VarStyle::fromXML(XmlUtils::CXmlNode& node) + { + XmlMacroReadAttributeBase(node, L"fillIdx", fillIdx); + XmlMacroReadAttributeBase(node, L"lineIdx", lineIdx); + XmlMacroReadAttributeBase(node, L"effectIdx", effectIdx); + XmlMacroReadAttributeBase(node, L"fontIdx", fontIdx); + } + std::wstring VarStyle::toXML() const + { + XmlUtils::CAttribute oAttr; + oAttr.Write(L"fillIdx", fillIdx); + oAttr.Write(L"lineIdx", lineIdx); + oAttr.Write(L"effectIdx", effectIdx); + oAttr.Write(L"fontIdx", fontIdx); + + + XmlUtils::CNodeValue oValue; + + return XmlUtils::CreateNode(L"vt:varStyle", oAttr, oValue); + } + void VarStyle::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, fillIdx); + pWriter->WriteUInt2(1, lineIdx); + pWriter->WriteUInt2(2, effectIdx); + pWriter->WriteUInt2(3, fontIdx); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void VarStyle::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"vt:varStyle"); + pWriter->WriteAttribute2(L"fillIdx", fillIdx); + pWriter->WriteAttribute2(L"lineIdx", lineIdx); + pWriter->WriteAttribute2(L"effectIdx", effectIdx); + pWriter->WriteAttribute2(L"fontIdx", fontIdx); + pWriter->EndAttributes(); + + pWriter->EndNode(L"vt:varStyle"); + } + void VarStyle::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + + switch (_at) + { + case 0: + { + fillIdx = pReader->GetULong(); + }break; + case 1: + { + lineIdx = pReader->GetULong(); + }break; + case 2: + { + effectIdx = pReader->GetULong(); + }break; + case 3: + { + fontIdx = pReader->GetULong(); + }break; + default: + break; + } + } + pReader->Seek(_end_rec); + } +//----------------------------------------------------------------------------------------- + FillProps& FillProps::operator=(const FillProps& oSrc) + { + parentFile = oSrc.parentFile; + parentElement = oSrc.parentElement; + + pattern = oSrc.pattern; + return *this; + } + void FillProps::fromXML(XmlUtils::CXmlNode& node) + { + XmlMacroReadAttributeBase(node, L"pattern", pattern); + } + std::wstring FillProps::toXML() const + { + XmlUtils::CAttribute oAttr; + oAttr.Write(L"pattern", pattern); + + XmlUtils::CNodeValue oValue; + + return XmlUtils::CreateNode(L"vt:fillProps", oAttr, oValue); + } + void FillProps::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, pattern); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void FillProps::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"vt:fillProps"); + pWriter->WriteAttribute2(L"pattern", pattern); + pWriter->EndAttributes(); + pWriter->EndNode(L"vt:fillProps"); + } + void FillProps::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + + switch (_at) + { + case 0: + { + pattern = pReader->GetULong(); + }break; + default: + break; + } + } + pReader->Seek(_end_rec); + } +//----------------------------------------------------------------------------------------- + Sketch& Sketch::operator=(const Sketch& oSrc) + { + parentFile = oSrc.parentFile; + parentElement = oSrc.parentElement; + + lnAmp = oSrc.lnAmp; + fillAmp = oSrc.fillAmp; + lnWeight = oSrc.lnWeight; + numPts = oSrc.numPts; + + return *this; + } + void Sketch::fromXML(XmlUtils::CXmlNode& node) + { + XmlMacroReadAttributeBase(node, L"lnAmp", lnAmp); + XmlMacroReadAttributeBase(node, L"fillAmp", fillAmp); + XmlMacroReadAttributeBase(node, L"lnWeight", lnWeight); + XmlMacroReadAttributeBase(node, L"numPts", numPts); + } + std::wstring Sketch::toXML() const + { + XmlUtils::CAttribute oAttr; + oAttr.Write(L"lnAmp", lnAmp); + oAttr.Write(L"fillAmp", fillAmp); + oAttr.Write(L"lnWeight", lnWeight); + oAttr.Write(L"numPts", numPts); + + XmlUtils::CNodeValue oValue; + + return XmlUtils::CreateNode(L"vt:sketch", oAttr, oValue); + } + void Sketch::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, lnAmp); + pWriter->WriteUInt2(1, fillAmp); + pWriter->WriteUInt2(2, lnWeight); + pWriter->WriteUInt2(3, numPts); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void Sketch::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"vt:sketch"); + pWriter->WriteAttribute2(L"lnAmp", lnAmp); + pWriter->WriteAttribute2(L"fillAmp", fillAmp); + pWriter->WriteAttribute2(L"lnWeight", lnWeight); + pWriter->WriteAttribute2(L"numPts", numPts); + pWriter->EndAttributes(); + + pWriter->EndNode(L"vt:sketch"); + } + void Sketch::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + + switch (_at) + { + case 0: + { + lnAmp = pReader->GetULong(); + }break; + case 1: + { + fillAmp = pReader->GetULong(); + }break; + case 2: + { + lnWeight = pReader->GetULong(); + }break; + case 3: + { + numPts = pReader->GetULong(); + }break; + default: + break; + } + } + pReader->Seek(_end_rec); + } +//----------------------------------------------------------------------------------------- + FontProps& FontProps::operator=(const FontProps& oSrc) + { + parentFile = oSrc.parentFile; + parentElement = oSrc.parentElement; + + style = oSrc.style; + color = oSrc.color; + + return *this; + } + void FontProps::fromXML(XmlUtils::CXmlNode& node) + { + XmlMacroReadAttributeBase(node, L"style", style); + + std::vector oNodes; + if (node.GetNodes(L"*", oNodes)) + { + for (size_t i = 0; i < oNodes.size(); ++i) + { + XmlUtils::CXmlNode& oNode = oNodes[i]; + + std::wstring strName = XmlUtils::GetNameNoNS(oNode.GetName()); + + if (L"color" == strName) + { + color.GetColorFrom(oNode); + } + } + } + } + std::wstring FontProps::toXML() const + { + XmlUtils::CAttribute oAttr; + oAttr.Write(L"style", style); + + XmlUtils::CNodeValue oValue; + oValue.Write(L"vt:color", color); + + return XmlUtils::CreateNode(L"vt:fontProps", oAttr, oValue); + } + void FontProps::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, style); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + pWriter->WriteRecord1(0, color); + } + void FontProps::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"vt:fontProps"); + pWriter->WriteAttribute2(L"style", style); + pWriter->EndAttributes(); + + if (color.is_init()) + { + pWriter->WriteString(L""); + color.toXmlWriter(pWriter); + pWriter->WriteString(L""); + } + + pWriter->EndNode(L"vt:fontProps"); + } + void FontProps::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + + switch (_at) + { + case 0: + { + style = pReader->GetULong(); + }break; + default: + break; + } + } + while (pReader->GetPos() < _end_rec) + { + BYTE _at = pReader->GetUChar(); + switch (_at) + { + case 0: + { + color.fromPPTY(pReader); + }break; + default: + break; + } + } + pReader->Seek(_end_rec); + } +//----------------------------------------------------------------------------------------- + LineEx& LineEx::operator=(const LineEx& oSrc) + { + parentFile = oSrc.parentFile; + parentElement = oSrc.parentElement; + + rndg = oSrc.rndg; + start = oSrc.start; + startSize = oSrc.startSize; + end = oSrc.end; + endSize = oSrc.endSize; + + return *this; + } + void LineEx::fromXML(XmlUtils::CXmlNode& node) + { + XmlMacroReadAttributeBase(node, L"rndg", rndg); + XmlMacroReadAttributeBase(node, L"start", start); + XmlMacroReadAttributeBase(node, L"startSize", startSize); + XmlMacroReadAttributeBase(node, L"end", end); + XmlMacroReadAttributeBase(node, L"endSize", endSize); + } + std::wstring LineEx::toXML() const + { + XmlUtils::CAttribute oAttr; + oAttr.Write(L"rndg", rndg); + oAttr.Write(L"start", start); + oAttr.Write(L"startSize", startSize); + oAttr.Write(L"end", end); + oAttr.Write(L"endSize", endSize); + + XmlUtils::CNodeValue oValue; + + return XmlUtils::CreateNode(L"vt:lineEx", oAttr, oValue); + } + void LineEx::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, rndg); + pWriter->WriteUInt2(1, start); + pWriter->WriteUInt2(2, startSize); + pWriter->WriteUInt2(3, end); + pWriter->WriteUInt2(4, endSize); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void LineEx::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"vt:lineEx"); + pWriter->WriteAttribute2(L"rndg", rndg); + pWriter->WriteAttribute2(L"start", start); + pWriter->WriteAttribute2(L"startSize", startSize); + pWriter->WriteAttribute2(L"end", end); + pWriter->WriteAttribute2(L"endSize", endSize); + pWriter->EndAttributes(); + pWriter->EndNode(L"vt:lineEx"); + } + void LineEx::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + + switch (_at) + { + case 0: + { + rndg = pReader->GetULong(); + }break; + case 1: + { + start = pReader->GetULong(); + }break; + case 2: + { + startSize = pReader->GetULong(); + }break; + case 3: + { + end = pReader->GetULong(); + }break; + case 4: + { + endSize = pReader->GetULong(); + }break; + default: + break; + } + } + pReader->Seek(_end_rec); + } +//----------------------------------------------------------------------------------------- + LineStyle& LineStyle::operator=(const LineStyle& oSrc) + { + parentFile = oSrc.parentFile; + parentElement = oSrc.parentElement; + + lineEx = oSrc.lineEx; + sketch = oSrc.sketch; + + return *this; + } + void LineStyle::fromXML(XmlUtils::CXmlNode& node) + { + std::vector oNodes; + if (node.GetNodes(L"*", oNodes)) + { + for (size_t i = 0; i < oNodes.size(); ++i) + { + XmlUtils::CXmlNode& oNode = oNodes[i]; + + std::wstring strName = XmlUtils::GetNameNoNS(oNode.GetName()); + + if (L"lineEx" == strName) + { + lineEx.fromXML(oNode); + } + else if (L"sketch" == strName) + { + sketch = oNode; + } + } + } + FillParentPointersForChilds(); + } + std::wstring LineStyle::toXML() const + { + XmlUtils::CAttribute oAttr; + + XmlUtils::CNodeValue oValue; + oValue.Write(lineEx); + oValue.WriteNullable(sketch); + + return XmlUtils::CreateNode(L"vt:lineStyle", oAttr, oValue); + } + void LineStyle::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteRecord1(0, lineEx); + pWriter->WriteRecord2(1, sketch); + } + void LineStyle::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"vt:lineStyle"); + pWriter->EndAttributes(); + + lineEx.toXmlWriter(pWriter); + pWriter->Write(sketch); + + pWriter->EndNode(L"vt:lineStyle"); + } + void LineStyle::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + + while (pReader->GetPos() < _end_rec) + { + BYTE _at = pReader->GetUChar(); + switch (_at) + { + case 0: + { + lineEx.fromPPTY(pReader); + }break; + case 1: + { + sketch.Init(); + sketch->fromPPTY(pReader); + }break; + default: + break; + } + } + pReader->Seek(_end_rec); + } + void LineStyle::FillParentPointersForChilds() + { + lineEx.SetParentPointer(this); + if (sketch.IsInit()) sketch->SetParentPointer(this); + } + } // namespace nsTheme +} // namespace PPTX diff --git a/OOXML/PPTXFormat/Theme/VisioThemeElements.h b/OOXML/PPTXFormat/Theme/VisioThemeElements.h new file mode 100644 index 0000000000..1892924803 --- /dev/null +++ b/OOXML/PPTXFormat/Theme/VisioThemeElements.h @@ -0,0 +1,289 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "./../WrapperWritingElement.h" +#include "../Logic/UniColor.h" + +namespace PPTX +{ + namespace nsTheme + { + class LineEx : public WrapperWritingElement + { + public: + PPTX_LOGIC_BASE(LineEx) + LineEx& operator=(const LineEx& oSrc); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + + nullable_uint rndg; + nullable_uint start; + nullable_uint startSize; + nullable_uint end; + nullable_uint endSize; + }; + class Sketch : public WrapperWritingElement + { + public: + PPTX_LOGIC_BASE(Sketch) + Sketch& operator=(const Sketch& oSrc); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + + nullable_uint lnAmp; //PositiveFixedPercentage + nullable_uint fillAmp; + nullable_uint lnWeight; //PositiveCoordinate + nullable_uint numPts; + }; + class LineStyle : public WrapperWritingElement + { + public: + PPTX_LOGIC_BASE(LineStyle) + LineStyle& operator=(const LineStyle& oSrc); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + + LineEx lineEx; + nullable sketch; + protected: + virtual void FillParentPointersForChilds(); + }; + class SchemeLineStyles : public WrapperWritingElement + { + public: + PPTX_LOGIC_BASE(SchemeLineStyles) + SchemeLineStyles& operator=(const SchemeLineStyles& oSrc); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + + std::wstring node_name; + std::vector m_arrItems; + + protected: + virtual void FillParentPointersForChilds(); + }; + class LineStyles : public WrapperWritingElement + { + public: + PPTX_LOGIC_BASE(LineStyles) + LineStyles& operator=(const LineStyles& oSrc); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + + SchemeLineStyles fmtConnectorSchemeLineStyles; + SchemeLineStyles fmtSchemeLineStyles; + + protected: + virtual void FillParentPointersForChilds(); + }; + class FillProps : public WrapperWritingElement + { + public: + PPTX_LOGIC_BASE(FillProps) + FillProps& operator=(const FillProps& oSrc); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + + nullable_uint pattern; + //extLst + }; + class FillStyles : public WrapperWritingElement + { + public: + PPTX_LOGIC_BASE(FillStyles) + FillStyles& operator=(const FillStyles& oSrc); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + + std::vector m_arrItems; //min 3 ??? + protected: + virtual void FillParentPointersForChilds(); + }; + class FontProps : public WrapperWritingElement + { + public: + PPTX_LOGIC_BASE(FontProps) + FontProps& operator=(const FontProps& oSrc); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + + nullable_uint style; + Logic::UniColor color; + //extLst + }; + class FontStyles : public WrapperWritingElement + { + public: + PPTX_LOGIC_BASE(FontStyles) + FontStyles& operator=(const FontStyles& oSrc); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + + std::wstring node_name; + std::vector m_arrItems; //min 3 + protected: + virtual void FillParentPointersForChilds(); + }; + class FontStylesGroup : public WrapperWritingElement + { + public: + PPTX_LOGIC_BASE(FontStylesGroup) + FontStylesGroup& operator=(const FontStylesGroup& oSrc); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + + FontStyles connectorFontStyles; + FontStyles fontStyles; + + protected: + virtual void FillParentPointersForChilds(); + }; + class VarStyle : public WrapperWritingElement + { + public: + PPTX_LOGIC_BASE(VarStyle) + VarStyle& operator=(const VarStyle& oSrc); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + + nullable_uint fillIdx; + nullable_uint lineIdx; + nullable_uint effectIdx; + nullable_uint fontIdx; + //extLst + }; + class VariationStyleScheme : public WrapperWritingElement + { + public: + PPTX_LOGIC_BASE(VariationStyleScheme) + VariationStyleScheme& operator=(const VariationStyleScheme& oSrc); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + + nullable_uint embellishment; + std::vector m_arrItems; //min 4 + protected: + virtual void FillParentPointersForChilds(); + }; + class VariationStyleSchemeLst : public WrapperWritingElement + { + public: + PPTX_LOGIC_BASE(VariationStyleSchemeLst) + VariationStyleSchemeLst& operator=(const VariationStyleSchemeLst& oSrc); + + virtual void fromXML(XmlUtils::CXmlNode& node); + virtual std::wstring toXML() const; + + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + + std::vector m_arrItems; //min 4 + protected: + virtual void FillParentPointersForChilds(); + }; + } // namespace nsTheme +} // namespace PPTX diff --git a/OOXML/Projects/Linux/BinDocument/BinDocument.pro b/OOXML/Projects/Linux/BinDocument/BinDocument.pro index d49218d6d2..71eb49dd1d 100644 --- a/OOXML/Projects/Linux/BinDocument/BinDocument.pro +++ b/OOXML/Projects/Linux/BinDocument/BinDocument.pro @@ -35,16 +35,19 @@ SOURCES += \ ../../../Binary/Document/DocWrapper/FontProcessor.cpp \ ../../../Binary/Document/DocWrapper/XlsxSerializer.cpp \ ../../../Binary/Document/DocWrapper/ChartSerializer.cpp \ - ../../../Binary/Document/BinWriter/BinWriters.cpp \ + ../../../Binary/Document/DocWrapper/VsdxSerializer.cpp \ + ../../../Binary/Document/BinWriter/BinaryWriterD.cpp \ ../../../Binary/Sheets/Common/Common.cpp \ ../../../Binary/Sheets/Reader/ChartFromToBinary.cpp \ ../../../Binary/Sheets/Reader/CommonWriter.cpp \ ../../../Binary/Sheets/Reader/CSVReader.cpp \ - ../../../Binary/Sheets/Reader/BinaryWriter.cpp \ - ../../../Binary/Sheets/Writer/BinaryReader.cpp \ + ../../../Binary/Sheets/Reader/BinaryWriterS.cpp \ + ../../../Binary/Sheets/Writer/BinaryReaderS.cpp \ ../../../Binary/Sheets/Writer/CSVWriter.cpp \ - ../../../Binary/Document/BinReader/ReaderClasses.cpp \ - ../../../Binary/Document/BinReader/Readers.cpp \ + ../../../Binary/Draw/BinaryWriterV.cpp \ + ../../../Binary/Draw/BinaryReaderV.cpp \ + ../../../Binary/Document/BinReader/ReaderClasses.cpp \ + ../../../Binary/Document/BinReader/BinaryReaderD.cpp \ ../../../Binary/Document/BinReader/CustomXmlWriter.cpp \ ../../../Binary/Document/BinReader/FileWriter.cpp \ ../../../Binary/Document/BinReader/ChartWriter.cpp \ @@ -76,7 +79,8 @@ HEADERS += \ ../../../Binary/Document/DocWrapper/DocxSerializer.h \ ../../../Binary/Document/DocWrapper/FontProcessor.h \ ../../../Binary/Document/DocWrapper/XlsxSerializer.h \ - ../../../Binary/Document/BinReader/ChartWriter.h \ + ../../../Binary/Document/DocWrapper/VsdxSerializer.h \ + ../../../Binary/Document/BinReader/ChartWriter.h \ ../../../Binary/Document/BinReader/CommentsWriter.h \ ../../../Binary/Document/BinReader/DocumentRelsWriter.h \ ../../../Binary/Document/BinReader/DocumentWriter.h \ @@ -86,22 +90,25 @@ HEADERS += \ ../../../Binary/Document/BinReader/MediaWriter.h \ ../../../Binary/Document/BinReader/NumberingWriter.h \ ../../../Binary/Document/BinReader/ReaderClasses.h \ - ../../../Binary/Document/BinReader/Readers.h \ + ../../../Binary/Document/BinReader/BinaryReaderD.h \ ../../../Binary/Document/BinReader/SettingWriter.h \ ../../../Binary/Document/BinReader/StylesWriter.h \ ../../../Binary/Document/BinWriter/BinEquationWriter.h \ ../../../Binary/Document/BinWriter/BinReaderWriterDefines.h \ - ../../../Binary/Document/BinWriter/BinWriters.h \ + ../../../Binary/Document/BinWriter/BinaryWriterD.h \ ../../../Binary/Sheets/Common/BinReaderWriterDefines.h \ ../../../Binary/Sheets/Common/Common.h \ - ../../../Binary/Sheets/Reader/BinaryWriter.h \ + ../../../Binary/Sheets/Reader/BinaryWriterS.h \ ../../../Binary/Sheets/Reader/ChartFromToBinary.h \ ../../../Binary/Sheets/Reader/CommonWriter.h \ ../../../Binary/Sheets/Reader/CSVReader.h \ ../../../Binary/Sheets/Writer/BinaryCommonReader.h \ - ../../../Binary/Sheets/Writer/BinaryReader.h \ + ../../../Binary/Sheets/Writer/BinaryReaderS.h \ ../../../Binary/Sheets/Writer/CSVWriter.h \ - ../../../Binary/Document/BinReader/webSettingsWriter.h \ + ../../../Binary/Draw/BinaryReaderV.h \ + ../../../Binary/Draw/BinaryWriterV.h \ + ../../../Binary/Draw/BinReaderWriterDefines.h \ + ../../../Binary/Document/BinReader/webSettingsWriter.h \ ../../../../Common/FileDownloader/FileDownloader.h \ ../../../Binary/Document/BinReader/DefaultThemeWriter.h \ ../../../Binary/Document/DocWrapper/ChartWriter.h \ diff --git a/OOXML/Projects/Linux/DocxFormatLib/DocxFormatLib.pro b/OOXML/Projects/Linux/DocxFormatLib/DocxFormatLib.pro index ed6fb5632f..cc1f191263 100644 --- a/OOXML/Projects/Linux/DocxFormatLib/DocxFormatLib.pro +++ b/OOXML/Projects/Linux/DocxFormatLib/DocxFormatLib.pro @@ -141,7 +141,8 @@ SOURCES += \ ../../../Common/SimpleTypes_Shared.cpp \ ../../../Common/SimpleTypes_Spreadsheet.cpp \ ../../../Common/SimpleTypes_Vml.cpp \ - ../../../Common/ComplexTypes.cpp \ + ../../../Common/SimpleTypes_Draw.cpp \ + ../../../Common/ComplexTypes.cpp \ ../../../SystemUtility/SystemUtility.cpp \ ../../../SystemUtility/FileUtils.cpp \ ../../../XML/XmlSimple.cpp \ @@ -177,7 +178,8 @@ SOURCES += \ ../../../XlsxFormat/Workbook/ExternalReferences.cpp \ ../../../XlsxFormat/Workbook/Sheets.cpp \ ../../../XlsxFormat/Workbook/WorkbookPr.cpp \ - ../../../XlsxFormat/Comments/XlsxComments.cpp \ + ../../../XlsxFormat/Workbook/CustomsXml.cpp \ + ../../../XlsxFormat/Comments/XlsxComments.cpp \ ../../../XlsxFormat/Comments/ThreadedComments.cpp \ ../../../XlsxFormat/Drawing/CellAnchor.cpp \ ../../../XlsxFormat/Drawing/XlsxDrawing.cpp \ @@ -187,8 +189,16 @@ SOURCES += \ ../../../XlsxFormat/ExternalLinks/ExternalLinks.cpp \ ../../../XlsxFormat/Workbook/Metadata.cpp \ ../../../XlsxFormat/RichData/RdRichValue.cpp \ - ../../../XlsxFormat/Ole/OleObjects.cpp -} + ../../../XlsxFormat/Ole/OleObjects.cpp \ + ../../../VsdxFormat/Vsdx.cpp \ + ../../../VsdxFormat/VisioPages.cpp \ + ../../../VsdxFormat/VisioDocument.cpp \ + ../../../VsdxFormat/VisioConnections.cpp \ + ../../../VsdxFormat/VisioOthers.cpp \ + ../../../VsdxFormat/Shapes.cpp \ + ../../../VsdxFormat/FileFactory_Draw.cpp \ + ../../../VsdxFormat/FileTypes_Draw.cpp + } SOURCES += \ @@ -212,7 +222,8 @@ HEADERS += \ ../../../Common/SimpleTypes_Shared.h \ ../../../Common/SimpleTypes_Vml.h \ ../../../Common/SimpleTypes_Word.h \ - ../../../Common/Size.h \ + ../../../Common/SimpleTypes_Draw.h \ + ../../../Common/Size.h \ ../../../Common/Unit.h \ ../../../Common/Wrap.h \ ../../../Common/ZIndex.h \ @@ -334,7 +345,8 @@ HEADERS += \ ../../../XlsxFormat/Workbook/Workbook.h \ ../../../XlsxFormat/Workbook/WorkbookPr.h \ ../../../XlsxFormat/Workbook/ExternalReferences.h \ - ../../../XlsxFormat/Worksheets/Cols.h \ + ../../../XlsxFormat/Workbook/CustomsXml.h \ + ../../../XlsxFormat/Worksheets/Cols.h \ ../../../XlsxFormat/Worksheets/ConditionalFormatting.h \ ../../../XlsxFormat/Worksheets/DataValidation.h \ ../../../XlsxFormat/Worksheets/Hyperlinks.h \ @@ -383,4 +395,12 @@ HEADERS += \ ../../../XlsxFormat/NamedSheetViews/NamedSheetViews.h \ ../../../XlsxFormat/Workbook/Metadata.h \ ../../../XlsxFormat/RichData/RdRichValue.h \ + ../../../VsdxFormat/Vsdx.h \ + ../../../VsdxFormat/VisioPages.h \ + ../../../VsdxFormat/VisioDocument.h \ + ../../../VsdxFormat/VisioConnections.h \ + ../../../VsdxFormat/VisioOthers.h \ + ../../../VsdxFormat/Shapes.h \ + ../../../VsdxFormat/FileFactory_Draw.h \ + ../../../VsdxFormat/FileTypes_Draw.h \ docx_format.h diff --git a/OOXML/Projects/Linux/DocxFormatLib/common_format.cpp b/OOXML/Projects/Linux/DocxFormatLib/common_format.cpp index ef4e605092..c49eb02a59 100644 --- a/OOXML/Projects/Linux/DocxFormatLib/common_format.cpp +++ b/OOXML/Projects/Linux/DocxFormatLib/common_format.cpp @@ -38,6 +38,7 @@ #include "../../../Common/SimpleTypes_Shared.cpp" #include "../../../Common/SimpleTypes_Spreadsheet.cpp" #include "../../../Common/SimpleTypes_Vml.cpp" +#include "../../../Common/SimpleTypes_Draw.cpp" #include "../../../Common/ComplexTypes.cpp" #include "../../../SystemUtility/SystemUtility.cpp" diff --git a/OOXML/Projects/Linux/DocxFormatLib/docx_format_logic.cpp b/OOXML/Projects/Linux/DocxFormatLib/docx_format_logic.cpp index b77dd39088..1224f15341 100644 --- a/OOXML/Projects/Linux/DocxFormatLib/docx_format_logic.cpp +++ b/OOXML/Projects/Linux/DocxFormatLib/docx_format_logic.cpp @@ -31,6 +31,7 @@ */ #include "common_format.cpp" #include "xlsx_format_logic.cpp" +#include "vsdx_format_logic.cpp" #include "../../../DocxFormat/Logic/AlternateContent.cpp" #include "../../../DocxFormat/Logic/Annotations.cpp" diff --git a/OOXML/Projects/Linux/DocxFormatLib/vsdx_format_logic.cpp b/OOXML/Projects/Linux/DocxFormatLib/vsdx_format_logic.cpp new file mode 100644 index 0000000000..d18d8d3111 --- /dev/null +++ b/OOXML/Projects/Linux/DocxFormatLib/vsdx_format_logic.cpp @@ -0,0 +1,40 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +#include "../../../VsdxFormat/Vsdx.cpp" +#include "../../../VsdxFormat/VisioPages.cpp" +#include "../../../VsdxFormat/VisioDocument.cpp" +#include "../../../VsdxFormat/VisioConnections.cpp" +#include "../../../VsdxFormat/VisioOthers.cpp" +#include "../../../VsdxFormat/Shapes.cpp" +#include "../../../VsdxFormat/FileFactory_Draw.cpp" +#include "../../../VsdxFormat/FileTypes_Draw.cpp" diff --git a/OOXML/Projects/Linux/DocxFormatLib/xlsx_format_logic.cpp b/OOXML/Projects/Linux/DocxFormatLib/xlsx_format_logic.cpp index aa764e8635..b8b2abbe0f 100644 --- a/OOXML/Projects/Linux/DocxFormatLib/xlsx_format_logic.cpp +++ b/OOXML/Projects/Linux/DocxFormatLib/xlsx_format_logic.cpp @@ -82,6 +82,7 @@ #include "../../../XlsxFormat/Workbook/ExternalReferences.cpp" #include "../../../XlsxFormat/Workbook/Sheets.cpp" #include "../../../XlsxFormat/Workbook/WorkbookPr.cpp" +#include "../../../XlsxFormat/Workbook/CustomsXml.cpp" #include "../../../XlsxFormat/Comments/XlsxComments.cpp" #include "../../../XlsxFormat/Comments/ThreadedComments.cpp" #include "../../../XlsxFormat/Drawing/CellAnchor.cpp" diff --git a/OOXML/Projects/Linux/PPTXFormatLib/PPTXFormatLib.pro b/OOXML/Projects/Linux/PPTXFormatLib/PPTXFormatLib.pro index ba9ac8966e..182a0505f2 100644 --- a/OOXML/Projects/Linux/PPTXFormatLib/PPTXFormatLib.pro +++ b/OOXML/Projects/Linux/PPTXFormatLib/PPTXFormatLib.pro @@ -105,7 +105,8 @@ SOURCES += \ ../../../PPTXFormat/Theme/FmtScheme.cpp \ ../../../PPTXFormat/Theme/FontScheme.cpp \ ../../../PPTXFormat/Theme/ThemeElements.cpp \ - \ + ../../../PPTXFormat/Theme/VisioThemeElements.cpp \ + \ ../../../PPTXFormat/ShowPr/PresentationPr.cpp \ ../../../PPTXFormat/ShowPr/Present.cpp \ ../../../PPTXFormat/ShowPr/Kiosk.cpp \ @@ -166,6 +167,7 @@ HEADERS += \ ../../../PPTXFormat/Theme/FmtScheme.h \ ../../../PPTXFormat/Theme/FontScheme.h \ ../../../PPTXFormat/Theme/ThemeElements.h \ + ../../../PPTXFormat/Theme/VisioThemeElements.h \ \ ../../../PPTXFormat/ViewProps/CSldViewPr.h \ ../../../PPTXFormat/ViewProps/CViewPr.h \ diff --git a/OOXML/Projects/Windows/BinaryFormatLib/BinaryFormatLib.vcxproj b/OOXML/Projects/Windows/BinaryFormatLib/BinaryFormatLib.vcxproj index 02672f264e..976c5683e0 100644 --- a/OOXML/Projects/Windows/BinaryFormatLib/BinaryFormatLib.vcxproj +++ b/OOXML/Projects/Windows/BinaryFormatLib/BinaryFormatLib.vcxproj @@ -31,20 +31,23 @@ - + - + + + + - + @@ -60,7 +63,7 @@ - + @@ -76,16 +79,20 @@ - + - + + + + + @@ -95,7 +102,7 @@ - + @@ -111,7 +118,7 @@ - + diff --git a/OOXML/Projects/Windows/BinaryFormatLib/BinaryFormatLib.vcxproj.filters b/OOXML/Projects/Windows/BinaryFormatLib/BinaryFormatLib.vcxproj.filters index 11ffe5c302..e9b87ab6db 100644 --- a/OOXML/Projects/Windows/BinaryFormatLib/BinaryFormatLib.vcxproj.filters +++ b/OOXML/Projects/Windows/BinaryFormatLib/BinaryFormatLib.vcxproj.filters @@ -31,18 +31,12 @@ {3bf431c7-ab39-40bb-a5ce-dbc6008ae5e5} + + {63d19e50-d1a5-4bc3-802f-062b7213a8a6} + - - Document - - - Document - - - Document - - + Document\Writer @@ -54,10 +48,10 @@ Document\Reader - + Document\Reader - + Sheets\Writer @@ -111,12 +105,9 @@ Document\Reader - + Sheets\Reader - - Document - Document\Writer @@ -162,24 +153,26 @@ Sheets\Reader\CellFormat + + + + + + + Draw + + + Draw + - - Document - - - Document - - - Document - Document\Writer Document\Writer - + Document\Writer @@ -218,7 +211,7 @@ Document\Reader - + Document\Reader @@ -230,7 +223,7 @@ Document\Reader - + Sheets\Writer @@ -242,7 +235,7 @@ Sheets\Reader - + Sheets\Reader @@ -311,5 +304,18 @@ Sheets\Reader\CellFormat + + + + + + Draw + + + Draw + + + Draw + \ No newline at end of file diff --git a/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj b/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj index 4dc49f0162..a097e79f1f 100644 --- a/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj +++ b/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj @@ -242,6 +242,7 @@ + @@ -327,6 +328,14 @@ + + + + + + + + @@ -384,6 +393,7 @@ + @@ -412,6 +422,7 @@ + @@ -493,6 +504,14 @@ + + + + + + + + @@ -545,6 +564,7 @@ + diff --git a/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj.filters b/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj.filters index 8b9170151f..af6da32519 100644 --- a/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj.filters +++ b/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj.filters @@ -88,6 +88,9 @@ {db25162b-705e-4c13-b6c5-f7c018c6f39a} + + {ca654de5-6ef9-42b5-8833-8832f0d9de31} + @@ -553,6 +556,36 @@ XlsxFormat\Pivots + + VsdxFormat + + + VsdxFormat + + + VsdxFormat + + + VsdxFormat + + + VsdxFormat + + + Common + + + VsdxFormat + + + VsdxFormat + + + VsdxFormat + + + XlsxFormat\Workbook + @@ -975,5 +1008,35 @@ XlsxFormat\Pivots + + VsdxFormat + + + VsdxFormat + + + VsdxFormat + + + VsdxFormat + + + VsdxFormat + + + Common + + + VsdxFormat + + + VsdxFormat + + + VsdxFormat + + + XlsxFormat\Workbook + \ No newline at end of file diff --git a/OOXML/Projects/Windows/PPTXFormatLib/PPTXFormat.vcxproj b/OOXML/Projects/Windows/PPTXFormatLib/PPTXFormat.vcxproj index 2f78d02f24..bfed147632 100644 --- a/OOXML/Projects/Windows/PPTXFormatLib/PPTXFormat.vcxproj +++ b/OOXML/Projects/Windows/PPTXFormatLib/PPTXFormat.vcxproj @@ -648,6 +648,7 @@ + @@ -1278,6 +1279,7 @@ + diff --git a/OOXML/Projects/Windows/PPTXFormatLib/PPTXFormat.vcxproj.filters b/OOXML/Projects/Windows/PPTXFormatLib/PPTXFormat.vcxproj.filters index d4eebdf5fb..2e2a4ba88d 100644 --- a/OOXML/Projects/Windows/PPTXFormatLib/PPTXFormat.vcxproj.filters +++ b/OOXML/Projects/Windows/PPTXFormatLib/PPTXFormat.vcxproj.filters @@ -21,7 +21,6 @@ - @@ -1895,6 +1894,10 @@ Binary + + + Theme + @@ -1942,7 +1945,6 @@ - @@ -3728,6 +3730,10 @@ Binary + + + Theme + diff --git a/OOXML/VsdxFormat/FileFactory_Draw.cpp b/OOXML/VsdxFormat/FileFactory_Draw.cpp new file mode 100644 index 0000000000..0685978287 --- /dev/null +++ b/OOXML/VsdxFormat/FileFactory_Draw.cpp @@ -0,0 +1,141 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "FileTypes_Draw.h" +#include "Vsdx.h" +#include "VisioDocument.h" +#include "VisioConnections.h" +#include "VisioPages.h" +#include "VisioOthers.h" + //#include "Comments.h" +#include "../DocxFormat/Rels.h" + +#ifdef CreateFile +#undef CreateFile +#endif + +namespace OOX +{ + namespace Draw + { + smart_ptr CreateFile(const OOX::CPath& oRootPath, const OOX::CPath& oPath, const OOX::Rels::CRelationShip& oRelation, OOX::Document *pMain) + { + OOX::CPath oRelationFilename = oRelation.Filename(); + CPath oFileName; + + if (oRelation.IsExternal()) + { + oFileName = oRelationFilename; + } + else + { + if (oRelationFilename.GetIsRoot() && oRootPath.GetPath().length() > 0) + oFileName = oRootPath / oRelationFilename; + else + oFileName = oPath / oRelationFilename; + } + if ( oRelation.Type() == FileTypes::Document || oRelation.Type() == FileTypes::DocumentMacro) + return smart_ptr(new CDocumentFile( pMain, oRootPath, oFileName )); + else if (oRelation.Type() == FileTypes::Pages) + return smart_ptr(new CPagesFile(pMain, oRootPath, oFileName)); + else if (oRelation.Type() == FileTypes::Masters) + return smart_ptr(new CMastersFile(pMain, oRootPath, oFileName)); + else if (oRelation.Type() == FileTypes::Page) + return smart_ptr(new CPageFile(pMain, oRootPath, oFileName)); + else if (oRelation.Type() == FileTypes::Master) + return smart_ptr(new CMasterFile(pMain, oRootPath, oFileName)); + else if (oRelation.Type() == FileTypes::Recordsets) + return smart_ptr(new CRecordsetsFile(pMain, oRootPath, oFileName)); + else if (oRelation.Type() == FileTypes::Recordset) + return smart_ptr(new CRecordsetFile(pMain, oRootPath, oFileName)); + else if (oRelation.Type() == FileTypes::Connections) + return smart_ptr(new CConnectionsFile(pMain, oRootPath, oFileName)); + else if (oRelation.Type() == FileTypes::Windows) + return smart_ptr(new CWindowsFile(pMain, oRootPath, oFileName)); + else if (oRelation.Type() == FileTypes::Validation) + return smart_ptr(new CValidationFile(pMain, oRootPath, oFileName)); + else if (oRelation.Type() == FileTypes::Comments) + return smart_ptr(new CCommentsFile(pMain, oRootPath, oFileName)); + else if (oRelation.Type() == FileTypes::Solutions) + return smart_ptr(new CSolutionsFile(pMain, oRootPath, oFileName)); + else if (oRelation.Type() == FileTypes::Solution) + return smart_ptr(new CSolutionFile(pMain, oRootPath, oFileName)); + + return smart_ptr( new UnknowTypeFile(pMain) ); + } + smart_ptr CreateFile(const OOX::CPath& oRootPath, const OOX::CPath& oPath, OOX::Rels::CRelationShip* pRelation, OOX::Document *pMain) + { + if (pRelation == NULL) return smart_ptr( new UnknowTypeFile(pMain) ); + + OOX::CPath oRelationFilename = pRelation->Filename(); + CPath oFileName; + + if (pRelation->IsExternal()) + { + oFileName = oRelationFilename; + } + else + { + if (oRelationFilename.GetIsRoot() && oRootPath.GetPath().length() > 0) + oFileName = oRootPath / oRelationFilename; + else + oFileName = oPath / oRelationFilename; + } + if ( pRelation->Type() == FileTypes::Document || pRelation->Type() == FileTypes::DocumentMacro) + return smart_ptr(new CDocumentFile( pMain, oRootPath, oFileName )); + else if (pRelation->Type() == FileTypes::Pages) + return smart_ptr(new CPagesFile(pMain, oRootPath, oFileName)); + else if (pRelation->Type() == FileTypes::Masters) + return smart_ptr(new CMastersFile(pMain, oRootPath, oFileName)); + else if (pRelation->Type() == FileTypes::Page) + return smart_ptr(new CPageFile(pMain, oRootPath, oFileName)); + else if (pRelation->Type() == FileTypes::Master) + return smart_ptr(new CMasterFile(pMain, oRootPath, oFileName)); + else if (pRelation->Type() == FileTypes::Comments) + return smart_ptr(new CCommentsFile(pMain, oRootPath, oFileName)); + else if (pRelation->Type() == FileTypes::Connections) + return smart_ptr(new CConnectionsFile(pMain, oRootPath, oFileName)); + else if (pRelation->Type() == FileTypes::Windows) + return smart_ptr(new CWindowsFile(pMain, oRootPath, oFileName)); + else if (pRelation->Type() == FileTypes::Validation) + return smart_ptr(new CValidationFile(pMain, oRootPath, oFileName)); + else if (pRelation->Type() == FileTypes::Recordsets) + return smart_ptr(new CRecordsetsFile(pMain, oRootPath, oFileName)); + else if (pRelation->Type() == FileTypes::Recordset) + return smart_ptr(new CRecordsetFile(pMain, oRootPath, oFileName)); + else if (pRelation->Type() == FileTypes::Solutions) + return smart_ptr(new CSolutionsFile(pMain, oRootPath, oFileName)); + else if (pRelation->Type() == FileTypes::Solution) + return smart_ptr(new CSolutionFile(pMain, oRootPath, oFileName)); + return smart_ptr( new UnknowTypeFile(pMain) ); + } + } +} // namespace OOX diff --git a/OOXML/VsdxFormat/FileFactory_Draw.h b/OOXML/VsdxFormat/FileFactory_Draw.h new file mode 100644 index 0000000000..28f8811dbd --- /dev/null +++ b/OOXML/VsdxFormat/FileFactory_Draw.h @@ -0,0 +1,53 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../Base/SmartPtr.h" +#include "../SystemUtility/SystemUtility.h" + +namespace OOX +{ + class File; + namespace Rels + { + class CRelationShip; + } +} + +namespace OOX +{ + namespace Draw + { + NSCommon::smart_ptr CreateFile(const OOX::CPath& oRootPath, const CPath& oPath, const OOX::Rels::CRelationShip& oRelation, OOX::Document *pMain); + NSCommon::smart_ptr CreateFile(const OOX::CPath& oRootPath, const OOX::CPath& oPath, OOX::Rels::CRelationShip* pRelation, OOX::Document *pMain); + } +} // namespace OOX diff --git a/OOXML/VsdxFormat/FileTypes_Draw.cpp b/OOXML/VsdxFormat/FileTypes_Draw.cpp new file mode 100644 index 0000000000..80f98237d8 --- /dev/null +++ b/OOXML/VsdxFormat/FileTypes_Draw.cpp @@ -0,0 +1,103 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "./FileTypes_Draw.h" + +namespace OOX +{ + namespace Draw + { + namespace FileTypes + { + const FileType Document (L"visio", L"document.xml", + L"application/vnd.ms-visio.drawing.main+xml", + L"http://schemas.microsoft.com/visio/2010/relationships/document"); + + const FileType DocumentMacro (L"visio", L"document.xml", + L"application/vnd.ms-visio.drawing.macroEnabled.main+xml", + L"http://schemas.microsoft.com/visio/2010/relationships/document"); + + const FileType Windows (L"", L"windows.xml", + L"application/vnd.ms-visio.windows+xml", + L"http://schemas.microsoft.com/visio/2010/relationships/windows"); + + const FileType Validation (L"", L"validation.xml", + L"application/vnd.ms-visio.validation+xml", + L"http://schemas.microsoft.com/visio/2010/relationships/validation"); + + const FileType Comments (L"", L"comments.xml", + L"application/vnd.ms-visio.comments+xml", + L"http://schemas.microsoft.com/visio/2010/relationships/comments"); + + const FileType Connections (L"data", L"connections.xml", + L"application/vnd.ms-visio.connections+xml", + L"http://schemas.microsoft.com/visio/2010/relationships/connections"); + + const FileType Pages (L"pages", L"pages.xml", + L"application/vnd.ms-visio.pages+xml", + L"http://schemas.microsoft.com/visio/2010/relationships/pages"); + + + const FileType Masters (L"masters", L"masters.xml", + L"application/vnd.ms-visio.masters+xml", + L"http://schemas.microsoft.com/visio/2010/relationships/masters"); + + + const FileType Recordsets (L"data", L"recordsets.xml", + L"application/vnd.ms-visio.recordsets+xml", + L"http://schemas.microsoft.com/visio/2010/relationships/recordsets"); + + const FileType Solutions (L"solutions", L"solutions.xml", + L"application/vnd.ms-visio.solutions+xml", + L"http://schemas.microsoft.com/visio/2010/relationships/solutions"); + + const FileType Page (L"", L"page.xml", + L"application/vnd.ms-visio.page+xml", + L"http://schemas.microsoft.com/visio/2010/relationships/page", + L"pages/page", true); + + const FileType Master (L"", L"master.xml", + L"application/vnd.ms-visio.master+xml", + L"http://schemas.microsoft.com/visio/2010/relationships/master", + L"masters/master", true); + + const FileType Recordset (L"", L"recordset.xml", + L"application/vnd.ms-visio.recordset+xml", + L"http://schemas.microsoft.com/visio/2010/relationships/recordset", + L"data/recordset", true); + + const FileType Solution (L"", L"solution.xml", + L"application/vnd.ms-visio.solution+xml", + L"http://schemas.microsoft.com/visio/2010/relationships/solution", + L"solutions/solution", true); + } // namespace FileTypes + } +} // namespace OOX diff --git a/OOXML/VsdxFormat/FileTypes_Draw.h b/OOXML/VsdxFormat/FileTypes_Draw.h new file mode 100644 index 0000000000..7b9fa0add7 --- /dev/null +++ b/OOXML/VsdxFormat/FileTypes_Draw.h @@ -0,0 +1,70 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once +#include "../DocxFormat/FileType.h" + +namespace OOX +{ + namespace Draw + { + namespace FileTypes + { + extern const FileType Document; + + extern const FileType DocumentMacro; + + extern const FileType Windows; + + extern const FileType Validation; + + extern const FileType Pages; + + extern const FileType Masters; + + extern const FileType Master; + + extern const FileType Page; + + extern const FileType Comments; + + extern const FileType Connections; + + extern const FileType Recordsets; + + extern const FileType Recordset; + + extern const FileType Solutions; + + extern const FileType Solution; + } // namespace FileTypes + } +} // namespace OOX diff --git a/OOXML/VsdxFormat/Shapes.cpp b/OOXML/VsdxFormat/Shapes.cpp new file mode 100644 index 0000000000..d3a9099198 --- /dev/null +++ b/OOXML/VsdxFormat/Shapes.cpp @@ -0,0 +1,1725 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "Shapes.h" + +#include "../../DesktopEditor/common/SystemUtils.h" +#include "../../DesktopEditor/common/Directory.h" +#include "../../DesktopEditor/raster/ImageFileFormatChecker.h" +#include "../../DesktopEditor/graphics/pro/Image.h" + +#include "../Binary/Presentation/BinaryFileReaderWriter.h" +#include "../Binary/Presentation/XmlWriter.h" +#include "../Binary/Presentation/imagemanager.h" +#include "../DocxFormat/Media/OleObject.h" +#include "../DocxFormat/Media/Image.h" + +#include "../../Common/OfficeFileFormatChecker.h" + +namespace OOX +{ + namespace Draw + { + EElementType CRel::getType() const + { + return et_dr_Rel; + } + void CRel::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "id", Rid) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CRel::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + } + void CRel::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"Rel"); + pWriter->StartAttributes(); + if (Rid.IsInit()) + pWriter->WriteAttribute2(L"r:id", Rid->ToString()); + pWriter->EndAttributes(); + pWriter->WriteNodeEnd(L"Rel"); + } + EElementType CIcon::getType() const + { + return et_dr_Icon; + } + void CIcon::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + content = oReader.GetText2(); + } + void CIcon::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteString1(0, content); + } + void CIcon::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + + content = pReader->GetString2(); + + pReader->Seek(_end_rec); + } + void CIcon::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"Icon"); + pWriter->EndAttributes(); + pWriter->WriteString(content); + pWriter->WriteNodeEnd(L"Icon"); + } + EElementType CForeignData::getType() const + { + return et_dr_ForeignData; + } + void CForeignData::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "ForeignType", ForeignType) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "CompressionType", CompressionType) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "CompressionLevel", CompressionLevel) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ObjectType", ObjectType) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ShowAsIcon", ShowAsIcon) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ObjectWidth", ObjectWidth) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ObjectHeight", ObjectHeight) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ExtentX", ExtentX) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ExtentY", ExtentY) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + nullable CompressionType; + nullable_double CompressionLevel; + void CForeignData::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + if (L"Rel" == sName) + { + Rel = oReader; + } + } + } + void CForeignData::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + if (ForeignType.IsInit()) pWriter->WriteByte1(0, ForeignType->GetValue()); + pWriter->WriteUInt2(1, ObjectType); + pWriter->WriteBool2(2, ShowAsIcon); + pWriter->WriteDoubleReal2(3, ObjectWidth); + pWriter->WriteDoubleReal2(4, ObjectHeight); + pWriter->WriteDoubleReal2(5, ExtentX); + pWriter->WriteDoubleReal2(6, ExtentY); + if (CompressionType.IsInit()) pWriter->WriteByte1(7, CompressionType->GetValue()); + pWriter->WriteDoubleReal2(8, CompressionLevel); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + if (Rel.IsInit() && Rel->Rid.IsInit()) + { + CPath out = pWriter->m_strMainFolder + FILE_SEPARATOR_STR + L"media"; + + smart_ptr pFile = pWriter->GetRels()->Find(Rel->Rid->GetValue()); + OOX::OleObject* pOleObject = dynamic_cast(pFile.GetPointer()); + + CPath image_path; + if (pOleObject) + { + image_path = pOleObject->filename_cache(); + CPath ole = pOleObject->filename(); + + //todooo check correct path inside container + NSFile::CFileBinary::Copy(ole.GetPath(), out.GetPath() + FILE_SEPARATOR_STR + ole.GetFilename()); + + pWriter->StartRecord(2); + pWriter->WriteString(ole.GetFilename()); + pWriter->EndRecord(); + } + else + { + OOX::Media* pMedia = dynamic_cast(pFile.GetPointer()); + if (pMedia) + { + image_path = pMedia->filename(); + } + } + if (false == image_path.GetPath().empty()) + { + //todooo check correct path inside container + NSFile::CFileBinary::Copy(image_path.GetPath(), out.GetPath() + FILE_SEPARATOR_STR + image_path.GetFilename()); + + pWriter->StartRecord(1); + pWriter->WriteString(image_path.GetFilename()); + pWriter->EndRecord(); + + CImageFileFormatChecker checker; + if (checker.isImageFile(image_path.GetPath())) + { + if (checker.eFileType == _CXIMAGE_FORMAT_WMF || checker.eFileType == _CXIMAGE_FORMAT_EMF) + { + MetaFile::IMetaFile* pMetafile = MetaFile::Create(pWriter->m_pCommon->m_pMediaManager->m_pFontManager->GetApplication()); + + if (pMetafile->LoadFromFile(image_path.GetPath().c_str())) + { + // пробуем сохранить в svg напрямую из метафайлов + std::wstring sInternalSvg = pMetafile->ConvertToSvg(ObjectWidth.get_value_or(0), ObjectHeight.get_value_or(0)); + + if (!sInternalSvg.empty()) + { + NSFile::CFileBinary::SaveToFile(out.GetPath() + FILE_SEPARATOR_STR + image_path.GetFilename() + L".svg", sInternalSvg); + } + else + {// не смогли сконвертировать в svg - пробуем в png + + std::wstring strSaveItem = out.GetPath() + FILE_SEPARATOR_STR + image_path.GetFilename() + L".png"; + pMetafile->ConvertToRaster(strSaveItem.c_str(), 4 /*CXIMAGE_FORMAT_PNG*/, 0, 0); + } + } + RELEASEOBJECT(pMetafile); + } + } + } + } + } + void CForeignData::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + std::wstring media_filename, ole_filename; + + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + ForeignType.Init(); + ForeignType->SetValueFromByte(pReader->GetUChar()); + }break; + case 1: + { + ObjectType = pReader->GetULong(); + }break; + case 2: + { + ShowAsIcon = pReader->GetBool(); + }break; + case 3: + { + ObjectWidth = pReader->GetDoubleReal(); + }break; + case 4: + { + ObjectHeight = pReader->GetDoubleReal(); + }break; + case 5: + { + ExtentX = pReader->GetDoubleReal(); + }break; + case 6: + { + ExtentY = pReader->GetDoubleReal(); + }break; + case 7: + { + CompressionType.Init(); + CompressionType->SetValueFromByte(pReader->GetUChar()); + }break; + case 8: + { + CompressionLevel = pReader->GetDoubleReal(); + }break; + } + } + while (pReader->GetPos() < _end_rec) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 1: + { + pReader->Skip(4); + media_filename = pReader->GetString2(); + }break; + case 2: + { + pReader->Skip(4); + ole_filename = pReader->GetString2(); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(_end_rec); + + if (ole_filename.empty() == false) + { + std::wstring srcMedia = pReader->m_strFolder + FILE_SEPARATOR_STR + L"media" + FILE_SEPARATOR_STR; + + NSFile::CFileBinary::Copy(srcMedia + ole_filename, pReader->m_pRels->m_pManager->GetDstEmbed() + FILE_SEPARATOR_STR + ole_filename); + NSFile::CFileBinary::Copy(srcMedia + media_filename, pReader->m_pRels->m_pManager->GetDstMedia() + FILE_SEPARATOR_STR + media_filename); + + OleObject* pOle = new OleObject(NULL, false, false); + pOle->set_filename(pReader->m_pRels->m_pManager->GetDstEmbed() + FILE_SEPARATOR_STR + ole_filename, false); + pOle->set_filename_cache(pReader->m_pRels->m_pManager->GetDstMedia() + FILE_SEPARATOR_STR + media_filename); + + COfficeFileFormatChecker checker; + if (checker.isOOXFormatFile(pOle->filename().GetPath())) + { + pOle->set_MsPackage(true); + } + + smart_ptr oFile(pOle); + + Rel.Init(); Rel->Rid.Init(); + Rel->Rid->SetValue(pReader->GetRels()->Add(oFile).get()); + + if (media_filename.empty() == false) + { + Image* pImage = new Image(NULL, false); + pImage->set_filename(pReader->m_pRels->m_pManager->GetDstMedia() + FILE_SEPARATOR_STR + media_filename, false); + + smart_ptr oFileCache(pImage); + pOle->Add(oFileCache); + } + } + else + { + std::wstring srcMedia = pReader->m_strFolder + FILE_SEPARATOR_STR + L"media" + FILE_SEPARATOR_STR; + + NSFile::CFileBinary::Copy(srcMedia + media_filename, pReader->m_pRels->m_pManager->GetDstMedia() + FILE_SEPARATOR_STR + media_filename); + + Image* pImage = new Image(NULL, false); + pImage->set_filename(pReader->m_pRels->m_pManager->GetDstMedia() + FILE_SEPARATOR_STR + media_filename, false); + + smart_ptr oFile(pImage); + Rel.Init(); Rel->Rid.Init(); + Rel->Rid->SetValue(pReader->GetRels()->Add(oFile).get()); + } + } + void CForeignData::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"ForeignData"); + pWriter->StartAttributes(); + if (ForeignType.IsInit()) pWriter->WriteAttribute(L"ForeignType", ForeignType->ToString()); + if (CompressionType.IsInit()) pWriter->WriteAttribute(L"CompressionType", CompressionType->ToString()); + pWriter->WriteAttribute(L"CompressionLevel", CompressionLevel); + pWriter->WriteAttribute2(L"ObjectType", ObjectType); + pWriter->WriteAttribute(L"ShowAsIcon", ShowAsIcon); + pWriter->WriteAttribute(L"ObjectWidth", ObjectWidth); + pWriter->WriteAttribute(L"ObjectHeight", ObjectHeight); + pWriter->WriteAttribute(L"ExtentX", ExtentX); + pWriter->WriteAttribute(L"ExtentY", ExtentY); + pWriter->EndAttributes(); + + if (Rel.IsInit()) + Rel->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"ForeignData"); + } + EElementType CText::getType() const + { + return et_dr_Text; + } + void CText::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + } + void CText::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + + int nDepth = oReader.GetDepth(); + XmlUtils::XmlNodeType eNodeType = XmlUtils::XmlNodeType_EndElement; + + while (oReader.Read(eNodeType) && oReader.GetDepth() >= nDepth && XmlUtils::XmlNodeType_EndElement != eNodeType) + { + if (eNodeType == XmlUtils::XmlNodeType_Text + || eNodeType == XmlUtils::XmlNodeType_Whitespace + || eNodeType == XmlUtils::XmlNodeType_SIGNIFICANT_WHITESPACE + || eNodeType == XmlUtils::XmlNodeType_CDATA) + { + const char* pValue = oReader.GetTextChar(); + + if ('\0' != pValue[0]) + { + CText_text* pText = new CText_text(); + NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)pValue, (LONG)strlen(pValue), pText->content); + m_arrItems.push_back(pText); + } + } + else if (eNodeType == XmlUtils::XmlNodeType_Element) + { + std::wstring sName = oReader.GetName(); + + WritingElement* pItem = NULL; + if (L"cp" == sName) + { + pItem = new CText_cp(); + } + else if (L"pp" == sName) + { + pItem = new CText_pp(); + } + else if (L"tp" == sName) + { + pItem = new CText_tp(); + } + else if (L"fld" == sName) + { + pItem = new CText_fld(); + } + if (pItem) + { + pItem->fromXML(oReader); + m_arrItems.push_back(pItem); + } + } + } + } + void CText::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + int type = 0xff; + switch (m_arrItems[i]->getType()) + { + case et_dr_text_cp: type = 0; break; + case et_dr_text_pp: type = 1; break; + case et_dr_text_tp: type = 2; break; + case et_dr_text_fld: type = 3; break; + case et_dr_text_text: type = 4; break; + } + if (type != 0xff) + pWriter->WriteRecord2(type, dynamic_cast(m_arrItems[i])); + } + } + void CText::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + while (pReader->GetPos() < _end_rec) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + m_arrItems.push_back(new CText_cp()); + m_arrItems.back()->fromPPTY(pReader); + }break; + case 1: + { + m_arrItems.push_back(new CText_pp()); + m_arrItems.back()->fromPPTY(pReader); + }break; + case 2: + { + m_arrItems.push_back(new CText_tp()); + m_arrItems.back()->fromPPTY(pReader); + }break; + case 3: + { + m_arrItems.push_back(new CText_fld()); + m_arrItems.back()->fromPPTY(pReader); + }break; + case 4: + { + m_arrItems.push_back(new CText_text()); + m_arrItems.back()->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CText::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"Text"); + pWriter->StartAttributes(); + pWriter->EndAttributes(); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + m_arrItems[i]->toXmlWriter(pWriter); + } + + pWriter->WriteNodeEnd(L"Text"); + } + EElementType CText_text::getType() const + { + return et_dr_text_text; + } + void CText_text::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteString1(0, content); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CText_text::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + content = pReader->GetString2(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CText_text::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->WriteStringXML(content); + } + EElementType CText_fld::getType() const + { + return et_dr_text_fld; + } + void CText_fld::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "IX", IX) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CText_fld::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + + content = oReader.GetText2(); + } + void CText_fld::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, IX); + pWriter->WriteString1(1, content); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CText_fld::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + IX = pReader->GetULong(); + }break; + case 1: + { + content = pReader->GetString2(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CText_fld::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"fld"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"IX", IX); + pWriter->EndAttributes(); + + pWriter->WriteStringXML(content); + + pWriter->WriteNodeEnd(L"fld"); + } + EElementType CText_tp::getType() const + { + return et_dr_text_tp; + } + void CText_tp::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "IX", IX) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CText_tp::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + } + void CText_tp::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, IX); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CText_tp::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + IX = pReader->GetULong(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CText_tp::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"tp"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"IX", IX); + pWriter->EndAttributes(); + pWriter->WriteNodeEnd(L"tp"); + } + EElementType CText_pp::getType() const + { + return et_dr_text_pp; + } + void CText_pp::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "IX", IX) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CText_pp::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + } + void CText_pp::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, IX); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CText_pp::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + IX = pReader->GetULong(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CText_pp::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"pp"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"IX", IX); + pWriter->EndAttributes(); + pWriter->WriteNodeEnd(L"pp"); + } + EElementType CText_cp::getType() const + { + return et_dr_text_cp; + } + void CText_cp::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "IX", IX) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CText_cp::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + } + void CText_cp::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, IX); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CText_cp::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + IX = pReader->GetULong(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CText_cp::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"cp"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"IX", IX); + pWriter->EndAttributes(); + pWriter->WriteNodeEnd(L"cp"); + } + EElementType CRow::getType() const + { + return et_dr_Row; + } + void CRow::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "IX", IX) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Del", Del) + WritingElement_ReadAttributesA_Read_else_ifChar(oReader, "N", N) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "LocalName", LocalName) + WritingElement_ReadAttributesA_Read_else_ifChar(oReader, "T", T) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CRow::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + WritingElement* pItem = NULL; + if (L"Cell" == sName) + { + pItem = new CCell(); + } + else if (L"Trigger" == sName) + { + pItem = new CTrigger(); + } + if (pItem) + { + pItem->fromXML(oReader); + m_arrItems.push_back(pItem); + } + } + } + void CRow::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, IX); + pWriter->WriteString2(1, N); + pWriter->WriteString2(2, LocalName); + pWriter->WriteString2(3, T); + pWriter->WriteBool2(4, Del); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + int type = 0xff; //todooo predefine type for ??? + switch (m_arrItems[i]->getType()) + { + case et_dr_Cell: type = 0; break; + case et_dr_Trigger: type = 1; break; + } + if (type != 0xff) + pWriter->WriteRecord2(type, dynamic_cast(m_arrItems[i])); + } + } + void CRow::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + IX = pReader->GetULong(); + }break; + case 1: + { + N = pReader->GetString2A(); + }break; + case 2: + { + LocalName = pReader->GetString2(); + }break; + case 3: + { + T = pReader->GetString2A(); + }break; + case 4: + { + Del = pReader->GetBool(); + }break; + } + } + while (pReader->GetPos() < _end_rec) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + m_arrItems.push_back(new CCell()); + m_arrItems.back()->fromPPTY(pReader); + }break; + case 1: + { + m_arrItems.push_back(new CTrigger()); + m_arrItems.back()->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CRow::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"Row"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"N", N); + pWriter->WriteAttribute2(L"LocalName", LocalName); + pWriter->WriteAttribute2(L"T", T); + pWriter->WriteAttribute2(L"IX", IX); + pWriter->WriteAttribute(L"Del", Del); + pWriter->EndAttributes(); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"Row"); + } + EElementType CSection::getType() const + { + return et_dr_Section; + } + void CSection::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "IX", IX) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Del", Del) + WritingElement_ReadAttributesA_Read_else_ifChar(oReader, "N", N) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CSection::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + WritingElement* pItem = NULL; + if (L"Cell" == sName) + { + pItem = new CCell(); + } + else if (L"Trigger" == sName) + { + pItem = new CTrigger(); + } + else if (L"Row" == sName) + { + pItem = new CRow(); + } + if (pItem) + { + pItem->fromXML(oReader); + m_arrItems.push_back(pItem); + } + } + } + void CSection::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, IX); + pWriter->WriteString2(1, N); + pWriter->WriteBool2(2, Del); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + int type = 0xff; //todooo predefine type for ??? + switch (m_arrItems[i]->getType()) + { + case et_dr_Cell: type = 0; break; + case et_dr_Trigger: type = 1; break; + case et_dr_Row: type = 6; break; + } + if (type != 0xff) + pWriter->WriteRecord2(type, dynamic_cast(m_arrItems[i])); + } + } + void CSection::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + IX = pReader->GetULong(); + }break; + case 1: + { + N = pReader->GetString2A(); + }break; + case 2: + { + Del = pReader->GetBool(); + }break; + } + } + while (pReader->GetPos() < _end_rec) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + m_arrItems.push_back(new CCell()); + m_arrItems.back()->fromPPTY(pReader); + }break; + case 1: + { + m_arrItems.push_back(new CTrigger()); + m_arrItems.back()->fromPPTY(pReader); + }break; + case 6: + { + m_arrItems.push_back(new CRow()); + m_arrItems.back()->fromPPTY(pReader); + }break; + + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CSection::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"Section"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"N", N); + pWriter->WriteAttribute2(L"IX", IX); + pWriter->WriteAttribute(L"Del", Del); + pWriter->EndAttributes(); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"Section"); + } + EElementType CRefBy::getType() const + { + return et_dr_RefBy; + } + void CRefBy::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "ID", ID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "T", T) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CRefBy::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + } + void CRefBy::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, ID); + pWriter->WriteString2(1, T); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CRefBy::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + ID = pReader->GetULong(); + }break; + case 1: + { + T = pReader->GetString2(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CRefBy::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"RefBy"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"T", T); + pWriter->WriteAttribute2(L"ID", ID); + pWriter->EndAttributes(); + pWriter->WriteNodeEnd(L"RefBy"); + } + EElementType CCell::getType() const + { + return et_dr_Cell; + } + void CCell::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributesA_Read_ifChar(oReader, "N", N) + WritingElement_ReadAttributesA_Read_else_ifChar(oReader, "U", U) + WritingElement_ReadAttributesA_Read_else_ifChar(oReader, "E", E) + WritingElement_ReadAttributesA_Read_else_ifChar(oReader, "F", F) + WritingElement_ReadAttributesA_Read_else_ifChar(oReader, "V", V) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CCell::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + + int nDepth = oReader.GetDepth(); + XmlUtils::XmlNodeType eNodeType = XmlUtils::XmlNodeType_EndElement; + + while (oReader.Read(eNodeType) && oReader.GetDepth() >= nDepth && XmlUtils::XmlNodeType_EndElement != eNodeType) + { + if (eNodeType == XmlUtils::XmlNodeType_Text + || eNodeType == XmlUtils::XmlNodeType_Whitespace + || eNodeType == XmlUtils::XmlNodeType_SIGNIFICANT_WHITESPACE + || eNodeType == XmlUtils::XmlNodeType_CDATA) + { + const char* pValue = oReader.GetTextChar(); + + if ('\0' != pValue[0]) + { + std::wstring val; + NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)pValue, (LONG)strlen(pValue), val); + content += val; + } + } + else if (eNodeType == XmlUtils::XmlNodeType_Element) + { + std::wstring sName = oReader.GetName(); + + if (L"RefBy" == sName) + { + RefBy = oReader; + } + } + } + } + void CCell::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteString2(0, N); + pWriter->WriteString2(1, U); + pWriter->WriteString2(2, E); + pWriter->WriteString2(3, F); + pWriter->WriteString2(4, V); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + pWriter->WriteRecord2(0, RefBy); + + if (false == content.empty()) + { + pWriter->StartRecord(1); + pWriter->WriteString(content); + pWriter->EndRecord(); + } + } + void CCell::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + N = pReader->GetString2A(); + }break; + case 1: + { + U = pReader->GetString2A(); + }break; + case 2: + { + E = pReader->GetString2A(); + }break; + case 3: + { + F = pReader->GetString2A(); + }break; + case 4: + { + V = pReader->GetString2A(); + }break; + } + } + while (pReader->GetPos() < _end_rec) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + RefBy.Init(); + RefBy->fromPPTY(pReader); + }break; + case 1: + { + content = pReader->GetString2(); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CCell::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"Cell"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"N", N); + pWriter->WriteAttributeUtf8(L"V", V); + pWriter->WriteAttribute2(L"U", U); + pWriter->WriteAttribute2(L"E", E); + pWriter->WriteAttributeUtf8(L"F", F); + pWriter->EndAttributes(); + + if (RefBy.IsInit()) + RefBy->toXmlWriter(pWriter); + + if (false == content.empty()) + { + pWriter->WriteStringXML(content); + } + + pWriter->WriteNodeEnd(L"Cell"); + } + EElementType CTrigger::getType() const + { + return et_dr_Trigger; + } + void CTrigger::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributesA_Read_ifChar(oReader, "N", N) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CTrigger::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + if (L"RefBy" == sName) + { + RefBy = oReader; + } + } + } + void CTrigger::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteString2(0, N); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + pWriter->WriteRecord2(0, RefBy); + } + void CTrigger::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + N = pReader->GetString2A(); + }break; + } + } + while (pReader->GetPos() < _end_rec) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + RefBy.Init(); + RefBy->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CTrigger::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"Trigger"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"N", N); + + pWriter->EndAttributes(); + + if (RefBy.IsInit()) + RefBy->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"Trigger"); + } + EElementType CShape::getType() const + { + return et_dr_Shape; + } + void CShape::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "ID", ID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "OriginalID", OriginalID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Type", Type) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Del", Del) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "MasterShape", MasterShape) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "NameU", NameU) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "UniqueID", UniqueID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Name", Name) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "IsCustomName", IsCustomName) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "IsCustomNameU", IsCustomNameU) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Master", Master) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "LineStyle", LineStyle) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "FillStyle", FillStyle) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "TextStyle", TextStyle) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CShape::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + WritingElement* pItem = NULL; + if (L"Cell" == sName) + { + pItem = new CCell(); + } + else if (L"Trigger" == sName) + { + pItem = new CTrigger(); + } + else if (L"Section" == sName) + { + pItem = new CSection(); + } + else if (L"Text" == sName) + { + pItem = new CText(); + } + else if (L"ForeignData" == sName) + { + pItem = new CForeignData(); + } + else if (L"Shapes" == sName) + { + pItem = new CShapes(); + } + if (pItem) + { + pItem->fromXML(oReader); + m_arrItems.push_back(pItem); + } + } + } + void CShape::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, ID); + if (Type.IsInit()) pWriter->WriteByte1(1, Type->GetValue()); + pWriter->WriteUInt2(2, OriginalID); + pWriter->WriteBool2(3, Del); + pWriter->WriteUInt2(4, MasterShape); + pWriter->WriteString2(5, UniqueID); + pWriter->WriteString2(6, NameU); + pWriter->WriteString2(7, Name); + pWriter->WriteBool2(8, IsCustomName); + pWriter->WriteBool2(9, IsCustomNameU); + pWriter->WriteUInt2(10, Master); + pWriter->WriteUInt2(11, LineStyle); + pWriter->WriteUInt2(12, FillStyle); + pWriter->WriteUInt2(13, TextStyle); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + int type = 0xff; //todooo predefine type for ??? + switch (m_arrItems[i]->getType()) + { + case et_dr_Cell: type = 0; break; + case et_dr_Trigger: type = 1; break; + case et_dr_Section: type = 2; break; + case et_dr_Text: type = 3; break; + case et_dr_ForeignData: type = 4; break; + case et_dr_Shapes: type = 5; break; + } + if (type != 0xff) + pWriter->WriteRecord2(type, dynamic_cast(m_arrItems[i])); + } + } + void CShape::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + ID = pReader->GetULong(); + }break; + case 1: + { + Type.Init(); Type->SetValueFromByte(pReader->GetUChar()); + }break; + case 2: + { + OriginalID = pReader->GetULong(); + }break; + case 3: + { + Del = pReader->GetBool(); + }break; + case 4: + { + MasterShape = pReader->GetULong(); + }break; + case 5: + { + UniqueID = pReader->GetString2(); + }break; + case 6: + { + NameU = pReader->GetString2(); + }break; + case 7: + { + Name = pReader->GetString2(); + }break; + case 8: + { + IsCustomName = pReader->GetBool(); + }break; + case 9: + { + IsCustomNameU = pReader->GetBool(); + }break; + case 10: + { + Master = pReader->GetULong(); + }break; + case 11: + { + LineStyle = pReader->GetULong(); + }break; + case 12: + { + FillStyle = pReader->GetULong(); + }break; + case 13: + { + TextStyle = pReader->GetULong(); + }break; + } + } + while (pReader->GetPos() < _end_rec) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + m_arrItems.push_back(new CCell()); + m_arrItems.back()->fromPPTY(pReader); + }break; + case 1: + { + m_arrItems.push_back(new CTrigger()); + m_arrItems.back()->fromPPTY(pReader); + }break; + case 2: + { + m_arrItems.push_back(new CSection()); + m_arrItems.back()->fromPPTY(pReader); + }break; + case 3: + { + m_arrItems.push_back(new CText()); + m_arrItems.back()->fromPPTY(pReader); + }break; + case 4: + { + m_arrItems.push_back(new CForeignData()); + m_arrItems.back()->fromPPTY(pReader); + }break; + case 5: + { + m_arrItems.push_back(new CShapes()); + m_arrItems.back()->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CShape::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"Shape"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"ID", ID); + pWriter->WriteAttribute2(L"OriginalID", OriginalID); + if (Type.IsInit()) pWriter->WriteAttribute2(L"Type", Type->ToString()); + pWriter->WriteAttribute(L"Del", Del); + pWriter->WriteAttribute2(L"MasterShape", MasterShape); + pWriter->WriteAttribute2(L"UniqueID", UniqueID); + pWriter->WriteAttribute2(L"NameU", NameU); + pWriter->WriteAttribute2(L"Name", Name); + pWriter->WriteAttribute(L"IsCustomName", IsCustomName); + pWriter->WriteAttribute(L"IsCustomNameU", IsCustomNameU); + pWriter->WriteAttribute2(L"Master", Master); + pWriter->WriteAttribute2(L"LineStyle", LineStyle); + pWriter->WriteAttribute2(L"FillStyle", FillStyle); + pWriter->WriteAttribute2(L"TextStyle", TextStyle); + pWriter->EndAttributes(); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"Shape"); + } + EElementType CShapes::getType() const + { + return et_dr_Shapes; + } + void CShapes::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + if (L"Shape" == sName) + { + CShape* pItem = new CShape(); + *pItem = oReader; + + if (pItem) + m_arrItems.push_back(pItem); + } + } + } + void CShapes::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + m_arrItems.push_back(new CShape()); + m_arrItems.back()->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + } + void CShapes::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + for (size_t i = 0; i < m_arrItems.size(); ++i) + pWriter->WriteRecord2(0, dynamic_cast(m_arrItems[i])); + } + void CShapes::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"Shapes"); + pWriter->EndAttributes(); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"Shapes"); + } + EElementType CConnect::getType() const + { + return et_dr_Connect; + } + void CConnect::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "FromSheet", FromSheet) + WritingElement_ReadAttributesA_Read_else_ifChar(oReader, "FromCell", FromCell) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "FromPart", FromPart) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ToSheet", ToSheet) + WritingElement_ReadAttributesA_Read_else_ifChar(oReader, "ToCell", ToCell) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ToPart", ToPart) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CConnect::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + } + void CConnect::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, FromSheet); + pWriter->WriteString2(1, FromCell); + pWriter->WriteInt2(2, FromPart); + pWriter->WriteUInt2(3, ToSheet); + pWriter->WriteString2(4, ToCell); + pWriter->WriteInt2(5, ToPart); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CConnect::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + FromSheet = pReader->GetULong(); + }break; + case 1: + { + FromCell = pReader->GetString2A(); + }break; + case 2: + { + FromPart = pReader->GetLong(); + }break; + case 3: + { + ToSheet = pReader->GetULong(); + }break; + case 4: + { + ToCell = pReader->GetString2A(); + }break; + case 5: + { + ToPart = pReader->GetLong(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CConnect::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"Connect"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"FromSheet", FromSheet); + pWriter->WriteAttribute2(L"FromCell", FromCell); + pWriter->WriteAttribute(L"FromPart", FromPart); + pWriter->WriteAttribute2(L"ToSheet", ToSheet); + pWriter->WriteAttribute2(L"ToCell", ToCell); + pWriter->WriteAttribute(L"ToPart", ToPart); + pWriter->EndAttributes(); + pWriter->WriteNodeEnd(L"Connect"); + } + void CConnects::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + if (L"Connect" == sName) + { + CConnect* pItem = new CConnect(); + *pItem = oReader; + + if (pItem) + m_arrItems.push_back(pItem); + } + } + } + EElementType CConnects::getType() const + { + return et_dr_Connects; + } + void CConnects::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + m_arrItems.push_back(new CConnect()); + m_arrItems.back()->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + } + void CConnects::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + for (size_t i = 0; i < m_arrItems.size(); ++i) + pWriter->WriteRecord2(0, dynamic_cast(m_arrItems[i])); + } + void CConnects::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"Connects"); + pWriter->EndAttributes(); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"Connects"); + } + } +} // namespace OOX diff --git a/OOXML/VsdxFormat/Shapes.h b/OOXML/VsdxFormat/Shapes.h new file mode 100644 index 0000000000..070d8c209e --- /dev/null +++ b/OOXML/VsdxFormat/Shapes.h @@ -0,0 +1,493 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../Base/Nullable.h" + +#include "FileTypes_Draw.h" +#include "../DocxFormat/IFileContainer.h" +#include "../Common/SimpleTypes_Draw.h" +#include "../Common/SimpleTypes_Shared.h" + +namespace OOX +{ + class CRelationShip; + + namespace Draw + { + class CRel : public WritingElement + { + public: + WritingElement_AdditionMethods(CRel) + CRel() {} + virtual ~CRel() {} + + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + public: + nullable Rid; + }; + class CIcon : public WritingElement + { + public: + WritingElement_AdditionMethods(CIcon) + CIcon() {} + virtual ~CIcon() {} + + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + std::wstring content; + }; + class CForeignData : public WritingElement + { + public: + WritingElement_AdditionMethods(CForeignData) + CForeignData() {} + virtual ~CForeignData() {} + + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + public: + nullable ForeignType; + nullable CompressionType; + nullable_double CompressionLevel; + nullable_uint ObjectType; + nullable_bool ShowAsIcon; + nullable_double ObjectWidth; + nullable_double ObjectHeight; + nullable_double ExtentX; + nullable_double ExtentY; + + nullable Rel; + }; + class CText_cp: public WritingElement + { + public: + WritingElement_AdditionMethods(CText_cp) + CText_cp() {} + virtual ~CText_cp() {} + + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + public: + nullable_uint IX; + }; + class CText_pp : public WritingElement + { + public: + WritingElement_AdditionMethods(CText_pp) + CText_pp() {} + virtual ~CText_pp() {} + + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + public: + nullable_uint IX; + }; + class CText_tp : public WritingElement + { + public: + WritingElement_AdditionMethods(CText_tp) + CText_tp() {} + virtual ~CText_tp() {} + + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + public: + nullable_uint IX; + }; + class CText_fld : public WritingElement + { + public: + WritingElement_AdditionMethods(CText_fld) + CText_fld() {} + virtual ~CText_fld() {} + + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + public: + nullable_uint IX; + std::wstring content; + }; + class CText_text : public WritingElement + { + public: + WritingElement_AdditionMethods(CText_text) + CText_text() {} + virtual ~CText_text() {} + + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader) {} + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + std::wstring content; + }; + class CText : public WritingElementWithChilds<> + { + public: + WritingElement_AdditionMethods(CText) + CText() {} + virtual ~CText() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + }; + class CRow : public WritingElementWithChilds<> + { + public: + WritingElement_AdditionMethods(CRow) + CRow() {} + virtual ~CRow() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_astring N; + nullable_string LocalName; + nullable_uint IX; + nullable_astring T; // todooo GeometryRowTypes + nullable_bool Del; + }; + class CSection : public WritingElementWithChilds<> + { + public: + WritingElement_AdditionMethods(CSection) + CSection() {} + virtual ~CSection() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_astring N; + nullable_bool Del; + nullable_uint IX; + }; + class CRefBy : public WritingElement + { + public: + WritingElement_AdditionMethods(CRefBy) + + CRefBy() {} + virtual ~CRefBy() {} + + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + public: + nullable_uint ID; + nullable_string T; + }; + class CCell : public WritingElement + { + public: + WritingElement_AdditionMethods(CCell) + + CCell() {} + virtual ~CCell() {} + + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + public: + nullable_astring N; + nullable_astring U; //todooo type + nullable_astring E; //todooo err + nullable_astring F; + nullable_astring V; + + nullable RefBy; + + std::wstring content; + }; + class CTrigger : public WritingElement + { + public: + WritingElement_AdditionMethods(CTrigger) + + CTrigger() {} + virtual ~CTrigger() {} + + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + public: + nullable_astring N; + + nullable RefBy; + }; + class CShape : public WritingElementWithChilds<> + { + public: + WritingElement_AdditionMethods(CShape) + CShape() {} + virtual ~CShape() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_uint ID; + nullable_uint OriginalID; + nullable_bool Del; + nullable_uint MasterShape; + nullable_string UniqueID; + nullable_string Name; + nullable_string NameU; + nullable_bool IsCustomName; + nullable_bool IsCustomNameU; + nullable_uint Master; + nullable Type; + nullable_uint LineStyle; + nullable_uint FillStyle; + nullable_uint TextStyle; + }; + class CShapes : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CShapes) + CShapes() {} + virtual ~CShapes() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader) {} + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + }; + class CConnect : public WritingElement + { + public: + WritingElement_AdditionMethods(CConnect) + CConnect() {} + virtual ~CConnect() {} + + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + public: + nullable_uint FromSheet; + nullable_astring FromCell; + nullable_int FromPart; + nullable_uint ToSheet; + nullable_astring ToCell; + nullable_int ToPart; + }; + class CConnects : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CConnects) + CConnects() {} + virtual ~CConnects() {} + + virtual std::wstring toXML() const { return L""; } + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + }; + } //Draw +} // namespace OOX diff --git a/OOXML/VsdxFormat/VisioConnections.cpp b/OOXML/VsdxFormat/VisioConnections.cpp new file mode 100644 index 0000000000..152e3d0345 --- /dev/null +++ b/OOXML/VsdxFormat/VisioConnections.cpp @@ -0,0 +1,1438 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "VisioConnections.h" +#include "Shapes.h" +#include "../../DesktopEditor/common/SystemUtils.h" +#include "../Binary/Presentation/BinaryFileReaderWriter.h" +#include "../Binary/Presentation/XmlWriter.h" + +namespace OOX +{ +namespace Draw +{ + OOX::Draw::CConnectionsFile::CConnectionsFile(OOX::Document* pMain) : OOX::File(pMain) + { + } + OOX::Draw::CConnectionsFile::CConnectionsFile(OOX::Document* pMain, const CPath& uri) : OOX::File(pMain) + { + read(uri.GetDirectory(), uri); + } + OOX::Draw::CConnectionsFile::CConnectionsFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::File(pMain) + { + read(oRootPath, oPath); + } + OOX::Draw::CConnectionsFile::~CConnectionsFile() + { + } + void OOX::Draw::CConnectionsFile::read(const CPath& oFilePath) + { + CPath oRootPath; + read(oRootPath, oFilePath); + } + void OOX::Draw::CConnectionsFile::read(const CPath& oRootPath, const CPath& oFilePath) + { + XmlUtils::CXmlLiteReader oReader; + + if (!oReader.FromFile(oFilePath.GetPath())) + return; + + if (!oReader.ReadNextNode()) + return; + + m_strFilename = oFilePath.GetPath(); + + DataConnections = oReader; + } + void OOX::Draw::CConnectionsFile::write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const + { + NSBinPptxRW::CXmlWriter oXmlWriter; + oXmlWriter.WriteString((L"")); + + oXmlWriter.m_lDocType = XMLWRITER_DOC_TYPE_VSDX; + toXmlWriter(&oXmlWriter); + + NSFile::CFileBinary::SaveToFile(oFilePath.GetPath(), oXmlWriter.GetXmlString()); + + oContent.Registration(type().OverrideType(), oDirectory, oFilePath.GetFilename()); + } + const OOX::FileType OOX::Draw::CConnectionsFile::type() const + { + return FileTypes::Connections; + } + const OOX::CPath OOX::Draw::CConnectionsFile::DefaultDirectory() const + { + return type().DefaultDirectory(); + } + const OOX::CPath OOX::Draw::CConnectionsFile::DefaultFileName() const + { + return type().DefaultFileName(); + } + void OOX::Draw::CConnectionsFile::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + + switch (_rec) + { + case 0: + { + DataConnections.Init(); + DataConnections->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + } + void OOX::Draw::CConnectionsFile::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteRecord2(0, DataConnections); + } + void OOX::Draw::CConnectionsFile::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + if (DataConnections.IsInit()) + DataConnections->toXmlWriter(pWriter); + } +//----------------------------------------------------------------------------------------------------------------------------- + OOX::Draw::CRecordsetFile::CRecordsetFile(OOX::Document* pMain) : OOX::File(pMain) + { + } + OOX::Draw::CRecordsetFile::CRecordsetFile(OOX::Document* pMain, const CPath& uri) : OOX::File(pMain) + { + read(uri.GetDirectory(), uri); + } + OOX::Draw::CRecordsetFile::CRecordsetFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::File(pMain) + { + read(oRootPath, oPath); + } + OOX::Draw::CRecordsetFile::~CRecordsetFile() + { + } + void OOX::Draw::CRecordsetFile::read(const CPath& oFilePath) + { + CPath oRootPath; + read(oRootPath, oFilePath); + } + void OOX::Draw::CRecordsetFile::read(const CPath& oRootPath, const CPath& oFilePath) + { + NSFile::CFileBinary::ReadAllTextUtf8A(oFilePath.GetPath(), m_sXmlA); + } + void OOX::Draw::CRecordsetFile::write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const + { + NSFile::CFileBinary oFile; + if (true == oFile.CreateFileW(oFilePath.GetPath())) + { + if (false == m_sXmlA.empty()) + oFile.WriteFile((BYTE*)m_sXmlA.c_str(), m_sXmlA.length()); + oFile.CloseFile(); + } + oContent.Registration(type().OverrideType(), oDirectory, oFilePath.GetFilename()); + } + const OOX::FileType OOX::Draw::CRecordsetFile::type() const + { + return FileTypes::Recordset; + } + const OOX::CPath OOX::Draw::CRecordsetFile::DefaultDirectory() const + { + return type().DefaultDirectory(); + } + const OOX::CPath OOX::Draw::CRecordsetFile::DefaultFileName() const + { + return type().DefaultFileName(); + } + void OOX::Draw::CRecordsetFile::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + + switch (_rec) + { + case 0: + { + pReader->Skip(4); // len + m_sXmlA = pReader->GetString2A(); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + } + void OOX::Draw::CRecordsetFile::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) + { + pWriter->StartRecord(0); + pWriter->WriteStringA(m_sXmlA); + pWriter->EndRecord(); + } +//----------------------------------------------------------------------------------------------------------------------------- + OOX::Draw::CRecordsetsFile::CRecordsetsFile(OOX::Document* pMain) : OOX::IFileContainer(pMain), OOX::File(pMain) + { + m_bVisioPages = true; + } + OOX::Draw::CRecordsetsFile::CRecordsetsFile(OOX::Document* pMain, const CPath& uri) : OOX::IFileContainer(pMain), OOX::File(pMain) + { + m_bVisioPages = true; + read(uri.GetDirectory(), uri); + } + OOX::Draw::CRecordsetsFile::CRecordsetsFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::IFileContainer(pMain), OOX::File(pMain) + { + m_bVisioPages = true; + + read(oRootPath, oPath); + } + OOX::Draw::CRecordsetsFile::~CRecordsetsFile() + { + } + void OOX::Draw::CRecordsetsFile::read(const CPath& oFilePath) + { + CPath oRootPath; + read(oRootPath, oFilePath); + } + void OOX::Draw::CRecordsetsFile::read(const CPath& oRootPath, const CPath& oFilePath) + { + IFileContainer::Read(oRootPath, oFilePath); + + XmlUtils::CXmlLiteReader oReader; + + if (!oReader.FromFile(oFilePath.GetPath())) + return; + + if (!oReader.ReadNextNode()) + return; + + m_strFilename = oFilePath.GetPath(); + + DataRecordSets = oReader; + } + void OOX::Draw::CRecordsetsFile::write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const + { + NSBinPptxRW::CXmlWriter oXmlWriter; + oXmlWriter.WriteString((L"")); + + oXmlWriter.m_lDocType = XMLWRITER_DOC_TYPE_VSDX; + toXmlWriter(&oXmlWriter); + + NSFile::CFileBinary::SaveToFile(oFilePath.GetPath(), oXmlWriter.GetXmlString()); + + oContent.Registration(type().OverrideType(), oDirectory, oFilePath.GetFilename()); + IFileContainer::Write(oFilePath, oDirectory, oContent); + } + const OOX::FileType OOX::Draw::CRecordsetsFile::type() const + { + return FileTypes::Recordsets; + } + const OOX::CPath OOX::Draw::CRecordsetsFile::DefaultDirectory() const + { + return type().DefaultDirectory(); + } + const OOX::CPath OOX::Draw::CRecordsetsFile::DefaultFileName() const + { + return type().DefaultFileName(); + } + void OOX::Draw::CRecordsetsFile::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + smart_ptr rels_old = pReader->GetRels(); + pReader->SetRels(dynamic_cast((CRecordsetsFile*)this)); + + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + + switch (_rec) + { + case 0: + { + DataRecordSets.Init(); + DataRecordSets->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + pReader->SetRels(rels_old); + } + void OOX::Draw::CRecordsetsFile::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + smart_ptr rels_old = pWriter->GetRels(); + pWriter->SetRels(dynamic_cast((CRecordsetsFile*)this)); + + pWriter->WriteRecord2(0, DataRecordSets); + + pWriter->SetRels(rels_old); + } + void OOX::Draw::CRecordsetsFile::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + if (DataRecordSets.IsInit()) + DataRecordSets->toXmlWriter(pWriter); + } +//----------------------------------------------------------------------------------------------------------------------------- + EElementType CDataConnection::getType() const + { + return et_dr_DataConnection; + } + void CDataConnection::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "ID", ID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "FileName", FileName) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ConnectionString", ConnectionString) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Command", Command) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "FriendlyName", FriendlyName) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Timeout", Timeout) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "AlwaysUseConnectionFile", AlwaysUseConnectionFile) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CDataConnection::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + } + void CDataConnection::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, ID); + pWriter->WriteString2(1, FileName); + pWriter->WriteString2(2, ConnectionString); + pWriter->WriteString2(3, Command); + pWriter->WriteString2(4, FriendlyName); + pWriter->WriteUInt2(5, Timeout); + pWriter->WriteBool2(6, AlwaysUseConnectionFile); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CDataConnection::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + ID = pReader->GetULong(); + }break; + case 1: + { + FileName = pReader->GetString2(); + }break; + case 2: + { + ConnectionString = pReader->GetString2(); + }break; + case 3: + { + Command = pReader->GetString2(); + }break; + case 4: + { + FriendlyName = pReader->GetString2(); + }break; + case 5: + { + Timeout = pReader->GetULong(); + }break; + case 6: + { + AlwaysUseConnectionFile = pReader->GetBool(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CDataConnection::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"DataConnection"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"ID", ID); + pWriter->WriteAttribute2(L"FileName", FileName); + pWriter->WriteAttribute2(L"ConnectionString", ConnectionString); + pWriter->WriteAttribute2(L"Command", Command); + pWriter->WriteAttribute2(L"FriendlyName", FriendlyName); + pWriter->WriteAttribute2(L"Timeout", Timeout); + pWriter->WriteAttribute(L"AlwaysUseConnectionFile", AlwaysUseConnectionFile); + pWriter->EndAttributes(); + + pWriter->WriteNodeEnd(L"DataConnection"); + } +//----------------------------------------------------------------------------------------------------------------------------- + void CDataConnections::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + if (L"DataConnection" == sName) + { + CDataConnection* pItem = new CDataConnection(); + *pItem = oReader; + + if (pItem) + m_arrItems.push_back(pItem); + } + } + } + void CDataConnections::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "NextID", NextID) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + EElementType CDataConnections::getType() const + { + return et_dr_DataConnections; + } + void CDataConnections::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + NextID = pReader->GetULong(); + }break; + } + } + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + m_arrItems.push_back(new CDataConnection()); + m_arrItems.back()->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + } + void CDataConnections::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, NextID); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + pWriter->WriteRecord2(0, dynamic_cast(m_arrItems[i])); + } + void CDataConnections::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"DataConnections"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"xmlns", L"http://schemas.microsoft.com/office/visio/2012/main"); + pWriter->WriteAttribute2(L"xmlns:r", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships"); + pWriter->WriteAttribute2(L"xml:space", L"preserve"); + pWriter->WriteAttribute2(L"NextID", NextID); + pWriter->EndAttributes(); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"DataConnections"); + } +//----------------------------------------------------------------------------------------------------------------------------- + EElementType CDataRecordSet::getType() const + { + return et_dr_DataRecordSet; + } + void CDataRecordSet::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "ID", ID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ConnectionID", ConnectionID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Options", Options) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Command", Command) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "TimeRefreshed", TimeRefreshed) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "NextRowID", NextRowID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Name", Name) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "RowOrder", RowOrder) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "RefreshOverwriteAll", RefreshOverwriteAll) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "RefreshNoReconciliationUI", RefreshNoReconciliationUI) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "RefreshInterval", RefreshInterval) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ReplaceLinks", ReplaceLinks) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Checksum", Checksum) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CDataRecordSet::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + const char* sName = XmlUtils::GetNameNoNS(oReader.GetNameChar()); + + WritingElement* pItem = NULL; + if (strcmp("DataColumns", sName) == 0) //1 + { + DataColumns = oReader; + } + else if (strcmp("Rel", sName) == 0) //1 + { + Rel = oReader; + } + else if (strcmp("PrimaryKey", sName) == 0) //unbounded + { + pItem = new CPrimaryKey(); + } + else if (strcmp("RowMap", sName) == 0) //unbounded + { + pItem = new CRowMap(); + } + else if (strcmp("RefreshConflict", sName) == 0) //unbounded + { + pItem = new CRefreshConflict(); + } + else if (strcmp("AutoLinkComparison", sName) == 0) //unbounded + { + pItem = new CAutoLinkComparison(); + } + else if (strcmp("ADOData", sName) == 0) //unbounded ??? + { + } + if (pItem) + { + pItem->fromXML(oReader); + m_arrItems.push_back(pItem); + } + } + } + void CDataRecordSet::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, ID); + pWriter->WriteUInt2(1, ConnectionID); + pWriter->WriteString2(2, Command); + pWriter->WriteUInt2(3, Options); + pWriter->WriteString2(4, TimeRefreshed); + pWriter->WriteUInt2(5, NextRowID); + pWriter->WriteString2(6, Name); + pWriter->WriteBool2(7, RowOrder); + pWriter->WriteBool2(8, RefreshOverwriteAll); + pWriter->WriteBool2(9, RefreshNoReconciliationUI); + pWriter->WriteUInt2(10, RefreshInterval); + pWriter->WriteUInt2(11, ReplaceLinks); + pWriter->WriteUInt2(12, Checksum); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + pWriter->WriteRecord2(0, DataColumns); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + int type = 0xff; //todooo predefine type for ??? + switch (m_arrItems[i]->getType()) + { + case et_dr_PrimaryKey: type = 1; break; + case et_dr_RowMap: type = 2; break; + case et_dr_RefreshConflict: type = 3; break; + case et_dr_AutoLinkComparison: type = 4; break; + } + if (type != 0xff) + pWriter->WriteRecord2(type, dynamic_cast(m_arrItems[i])); + } + if (Rel.IsInit() && Rel->Rid.IsInit()) + { + smart_ptr pFile = pWriter->GetRels()->Find(Rel->Rid->GetValue()); + CRecordsetFile* pRecordset = dynamic_cast(pFile.GetPointer()); + if (pRecordset) + { + pWriter->StartRecord(5); + pRecordset->toPPTY(pWriter); + pWriter->EndRecord(); + } + } + } + void CDataRecordSet::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + ID = pReader->GetULong(); + }break; + case 1: + { + ConnectionID = pReader->GetULong(); + }break; + case 2: + { + Command = pReader->GetString2(); + }break; + case 3: + { + Options = pReader->GetULong(); + }break; + case 4: + { + TimeRefreshed = pReader->GetString2(); + }break; + case 5: + { + NextRowID = pReader->GetULong(); + }break; + case 6: + { + Name = pReader->GetString2(); + }break; + case 7: + { + RowOrder = pReader->GetBool(); + }break; + case 8: + { + RefreshOverwriteAll = pReader->GetBool(); + }break; + case 9: + { + RefreshNoReconciliationUI = pReader->GetBool(); + }break; + case 10: + { + RefreshInterval = pReader->GetULong(); + }break; + case 11: + { + ReplaceLinks = pReader->GetULong(); + }break; + case 12: + { + Checksum = pReader->GetULong(); + }break; + } + } + while (pReader->GetPos() < _end_rec) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + DataColumns.Init(); + DataColumns->fromPPTY(pReader); + }break; + case 1: + { + m_arrItems.push_back(new CPrimaryKey()); + m_arrItems.back()->fromPPTY(pReader); + }break; + case 2: + { + m_arrItems.push_back(new CRowMap()); + m_arrItems.back()->fromPPTY(pReader); + }break; + case 3: + { + m_arrItems.push_back(new CRefreshConflict()); + m_arrItems.back()->fromPPTY(pReader); + }break; + case 4: + { + m_arrItems.push_back(new CAutoLinkComparison()); + m_arrItems.back()->fromPPTY(pReader); + }break; + case 5: + { + CRecordsetFile* pRecordset = new CRecordsetFile(NULL); + pRecordset->fromPPTY(pReader); + smart_ptr oFile(pRecordset); + + Rel.Init(); Rel->Rid.Init(); + Rel->Rid->SetValue(pReader->GetRels()->Add(oFile).get()); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CDataRecordSet::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"DataRecordSet"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"ID", ID); + pWriter->WriteAttribute2(L"ConnectionID", ConnectionID); + pWriter->WriteAttribute2(L"Command", Command); + pWriter->WriteAttribute2(L"Options", Options); + pWriter->WriteAttribute2(L"TimeRefreshed", TimeRefreshed); + pWriter->WriteAttribute2(L"NextRowID", NextRowID); + pWriter->WriteAttribute2(L"Name", Name); + pWriter->WriteAttribute(L"RowOrder", RowOrder); + pWriter->WriteAttribute(L"RefreshOverwriteAll", RefreshOverwriteAll); + pWriter->WriteAttribute(L"RefreshNoReconciliationUI", RefreshNoReconciliationUI); + pWriter->WriteAttribute2(L"RefreshInterval", RefreshInterval); + pWriter->WriteAttribute2(L"ReplaceLinks", ReplaceLinks); + pWriter->WriteAttribute2(L"Checksum", Checksum); + pWriter->EndAttributes(); + + if (Rel.IsInit()) + Rel->toXmlWriter(pWriter); + + if (DataColumns.IsInit()) + DataColumns->toXmlWriter(pWriter); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"DataRecordSet"); + } +//----------------------------------------------------------------------------------------------------------- + EElementType CDataRecordSets::getType() const + { + return et_dr_DataRecordSets; + } + void CDataRecordSets::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + if (L"DataRecordSet" == sName) + { + CDataRecordSet* pItem = new CDataRecordSet(); + *pItem = oReader; + + if (pItem) + m_arrItems.push_back(pItem); + } + } + } + void CDataRecordSets::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "NextID", NextID) + WritingElement_ReadAttributes_Read_ifChar(oReader, "ActiveRecordsetID", ActiveRecordsetID) + WritingElement_ReadAttributes_Read_ifChar(oReader, "DataWindowOrder", DataWindowOrder) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CDataRecordSets::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + NextID = pReader->GetULong(); + }break; + case 1: + { + ActiveRecordsetID = pReader->GetULong(); + }break; + case 2: + { + DataWindowOrder = pReader->GetString2(); + }break; + } + } + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + m_arrItems.push_back(new CDataRecordSet()); + m_arrItems.back()->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + } + void CDataRecordSets::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, NextID); + pWriter->WriteUInt2(1, ActiveRecordsetID); + pWriter->WriteString2(2, DataWindowOrder); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + pWriter->WriteRecord2(0, dynamic_cast(m_arrItems[i])); + } + void CDataRecordSets::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"DataRecordSets"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"xmlns", L"http://schemas.microsoft.com/office/visio/2012/main"); + pWriter->WriteAttribute2(L"xmlns:r", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships"); + pWriter->WriteAttribute2(L"xml:space", L"preserve"); + pWriter->WriteAttribute2(L"NextID", NextID); + pWriter->WriteAttribute2(L"ActiveRecordsetID", ActiveRecordsetID); + pWriter->WriteAttribute2(L"DataWindowOrder", DataWindowOrder); + pWriter->EndAttributes(); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"DataRecordSets"); + } +//----------------------------------------------------------------------------------------------------------------------------- + EElementType CDataColumn::getType() const + { + return et_dr_DataColumn; + } + void CDataColumn::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "ColumnNameID", ColumnNameID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Name", Name) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Label", Label) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "OrigLabel", OrigLabel) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "LangID", LangID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Calendar", Calendar) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "DataType", DataType) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "UnitType", UnitType) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Currency", Currency) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Degree", Degree) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "DisplayWidth", DisplayWidth) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "DisplayOrder", DisplayOrder) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Mapped", Mapped) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Hyperlink", Hyperlink) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CDataColumn::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + } + void CDataColumn::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteString2(0, ColumnNameID); + pWriter->WriteString2(1, Name); + pWriter->WriteString2(2, Label); + pWriter->WriteString2(3, OrigLabel); + pWriter->WriteString2(4, LangID); + pWriter->WriteUInt2(5, Calendar); + pWriter->WriteUInt2(6, DataType); + pWriter->WriteString2(7, UnitType); + pWriter->WriteUInt2(8, Currency); + pWriter->WriteUInt2(9, Degree); + pWriter->WriteUInt2(10, DisplayWidth); + pWriter->WriteUInt2(11, DisplayOrder); + pWriter->WriteBool2(12, Mapped); + pWriter->WriteBool2(13, Hyperlink); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CDataColumn::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + ColumnNameID = pReader->GetString2(); + }break; + case 1: + { + Name = pReader->GetString2(); + }break; + case 2: + { + Label = pReader->GetString2(); + }break; + case 3: + { + OrigLabel = pReader->GetString2(); + }break; + case 4: + { + LangID = pReader->GetString2(); + }break; + case 5: + { + Calendar = pReader->GetULong(); + }break; + case 6: + { + DataType = pReader->GetULong(); + }break; + case 7: + { + UnitType = pReader->GetString2(); + }break; + case 8: + { + Currency = pReader->GetULong(); + }break; + case 9: + { + Degree = pReader->GetULong(); + }break; + case 10: + { + DisplayWidth = pReader->GetULong(); + }break; + case 11: + { + DisplayOrder = pReader->GetULong(); + }break; + case 12: + { + Mapped = pReader->GetBool(); + }break; + case 13: + { + Hyperlink = pReader->GetBool(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CDataColumn::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"DataColumn"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"ColumnNameID", ColumnNameID); + pWriter->WriteAttribute2(L"Name", Name); + pWriter->WriteAttribute2(L"Label", Label); + pWriter->WriteAttribute2(L"OrigLabel", OrigLabel); + pWriter->WriteAttribute2(L"LangID", LangID); + pWriter->WriteAttribute2(L"Calendar", Calendar); + pWriter->WriteAttribute2(L"DataType", DataType); + pWriter->WriteAttribute2(L"UnitType", UnitType); + pWriter->WriteAttribute2(L"Currency", Currency); + pWriter->WriteAttribute2(L"Degree", Degree); + pWriter->WriteAttribute2(L"DisplayWidth", DisplayWidth); + pWriter->WriteAttribute2(L"DisplayOrder", DisplayOrder); + pWriter->WriteAttribute(L"Mapped", Mapped); + pWriter->WriteAttribute(L"Hyperlink", Hyperlink); + pWriter->EndAttributes(); + + pWriter->WriteNodeEnd(L"DataColumn"); + } +//----------------------------------------------------------------------------------------------------------------------------- + void CDataColumns::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + if (L"DataColumn" == sName) + { + CDataColumn* pItem = new CDataColumn(); + *pItem = oReader; + + if (pItem) + m_arrItems.push_back(pItem); + } + } + } + void CDataColumns::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "SortColumn", SortColumn) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "SortAsc", SortAsc) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + EElementType CDataColumns::getType() const + { + return et_dr_DataColumns; + } + void CDataColumns::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + SortColumn = pReader->GetString2(); + }break; + case 1: + { + SortAsc = pReader->GetBool(); + }break; + } + } + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + m_arrItems.push_back(new CDataColumn()); + m_arrItems.back()->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + } + void CDataColumns::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteString2(0, SortColumn); + pWriter->WriteBool2(1, SortAsc); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + pWriter->WriteRecord2(0, dynamic_cast(m_arrItems[i])); + } + void CDataColumns::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"DataColumns"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"SortColumn", SortColumn); + pWriter->WriteAttribute(L"SortAsc", SortAsc); + pWriter->EndAttributes(); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"DataColumns"); + } +//----------------------------------------------------------------------------------------------------------------------------- + EElementType CRowKeyValue::getType() const + { + return et_dr_RowKeyValue; + } + void CRowKeyValue::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "RowID", RowID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Value", Value) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CRowKeyValue::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + } + void CRowKeyValue::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, RowID); + pWriter->WriteString2(1, Value); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CRowKeyValue::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + RowID = pReader->GetULong(); + }break; + case 1: + { + Value = pReader->GetString2(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CRowKeyValue::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"RowKeyValue"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"RowID", RowID); + pWriter->WriteAttribute2(L"Value", Value); + pWriter->EndAttributes(); + pWriter->WriteNodeEnd(L"RowKeyValue"); + } +//----------------------------------------------------------------------------------------------------------------------------- + void CPrimaryKey::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + if (L"RowKeyValue" == sName) + { + CRowKeyValue* pItem = new CRowKeyValue(); + *pItem = oReader; + + if (pItem) + m_arrItems.push_back(pItem); + } + } + } + void CPrimaryKey::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "ColumnNameID", ColumnNameID) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + EElementType CPrimaryKey::getType() const + { + return et_dr_PrimaryKey; + } + void CPrimaryKey::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + ColumnNameID = pReader->GetString2(); + }break; + } + } + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + m_arrItems.push_back(new CRowKeyValue()); + m_arrItems.back()->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + } + void CPrimaryKey::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteString2(0, ColumnNameID); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + pWriter->WriteRecord2(0, dynamic_cast(m_arrItems[i])); + } + void CPrimaryKey::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"PrimaryKey"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"ColumnNameID", ColumnNameID); + pWriter->EndAttributes(); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"PrimaryKey"); + } + EElementType CRowMap::getType() const + { + return et_dr_RowMap; + } + void CRowMap::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "RowID", RowID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "PageID", PageID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ShapeID", ShapeID) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CRowMap::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + } + void CRowMap::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, RowID); + pWriter->WriteUInt2(1, PageID); + pWriter->WriteUInt2(2, ShapeID); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CRowMap::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + RowID = pReader->GetULong(); + }break; + case 1: + { + PageID = pReader->GetULong(); + }break; + case 2: + { + ShapeID = pReader->GetULong(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CRowMap::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"RowMap"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"RowID", RowID); + pWriter->WriteAttribute2(L"PageID", PageID); + pWriter->WriteAttribute2(L"ShapeID", ShapeID); + pWriter->EndAttributes(); + pWriter->WriteNodeEnd(L"RowMap"); + } + EElementType CRefreshConflict::getType() const + { + return et_dr_RefreshConflict; + } + void CRefreshConflict::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "RowID", RowID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "PageID", PageID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ShapeID", ShapeID) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CRefreshConflict::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + } + void CRefreshConflict::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, RowID); + pWriter->WriteUInt2(1, PageID); + pWriter->WriteUInt2(2, ShapeID); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CRefreshConflict::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + RowID = pReader->GetULong(); + }break; + case 1: + { + PageID = pReader->GetULong(); + }break; + case 2: + { + ShapeID = pReader->GetULong(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CRefreshConflict::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"RefreshConflict"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"RowID", RowID); + pWriter->WriteAttribute2(L"PageID", PageID); + pWriter->WriteAttribute2(L"ShapeID", ShapeID); + pWriter->EndAttributes(); + pWriter->WriteNodeEnd(L"RefreshConflict"); + } + EElementType CAutoLinkComparison::getType() const + { + return et_dr_AutoLinkComparison; + } + void CAutoLinkComparison::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "ColumnName", ColumnName) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ContextType", ContextType) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ContextTypeLabel", ContextTypeLabel) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CAutoLinkComparison::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + } + void CAutoLinkComparison::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteString2(0, ColumnName); + pWriter->WriteUInt2(1, ContextType); + pWriter->WriteString2(2, ContextTypeLabel); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CAutoLinkComparison::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + ColumnName = pReader->GetString2(); + }break; + case 1: + { + ContextType = pReader->GetULong(); + }break; + case 2: + { + ContextTypeLabel = pReader->GetString2(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CAutoLinkComparison::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"AutoLinkComparison"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"ColumnName", ColumnName); + pWriter->WriteAttribute2(L"ContextType", ContextType); + pWriter->WriteAttribute2(L"ContextTypeLabel", ContextTypeLabel); + pWriter->EndAttributes(); + pWriter->WriteNodeEnd(L"AutoLinkComparison"); + } +} +} // namespace OOX diff --git a/OOXML/VsdxFormat/VisioConnections.h b/OOXML/VsdxFormat/VisioConnections.h new file mode 100644 index 0000000000..d3183e1062 --- /dev/null +++ b/OOXML/VsdxFormat/VisioConnections.h @@ -0,0 +1,405 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../Base/Nullable.h" + +#include "FileTypes_Draw.h" +#include "../DocxFormat/IFileContainer.h" + +namespace OOX +{ + namespace Draw + { + class CRel; + + class CAutoLinkComparison : public WritingElement + { + public: + WritingElement_AdditionMethods(CAutoLinkComparison) + CAutoLinkComparison() {} + virtual ~CAutoLinkComparison() {} + + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + public: + nullable_string ColumnName; + nullable_uint ContextType; + nullable_string ContextTypeLabel; + }; + class CRefreshConflict : public WritingElement + { + public: + WritingElement_AdditionMethods(CRefreshConflict) + CRefreshConflict() {} + virtual ~CRefreshConflict() {} + + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + public: + nullable_uint RowID; + nullable_uint PageID; + nullable_uint ShapeID; + }; + class CRowMap : public WritingElement + { + public: + WritingElement_AdditionMethods(CRowMap) + CRowMap() {} + virtual ~CRowMap() {} + + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + public: + nullable_uint RowID; + nullable_uint PageID; + nullable_uint ShapeID; + }; + class CRowKeyValue : public WritingElement + { + public: + WritingElement_AdditionMethods(CRowKeyValue) + CRowKeyValue() {} + virtual ~CRowKeyValue() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_uint RowID; + nullable_string Value; + }; + class CPrimaryKey : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CPrimaryKey) + CPrimaryKey() {} + virtual ~CPrimaryKey() {} + + virtual std::wstring toXML() const { return L""; } + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + + nullable_string ColumnNameID; + }; + class CDataConnection : public WritingElement + { + public: + WritingElement_AdditionMethods(CDataConnection) + CDataConnection() {} + virtual ~CDataConnection() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_uint ID; + nullable_string FileName; + nullable_string ConnectionString; + nullable_string Command; + nullable_string FriendlyName; + nullable_uint Timeout; + nullable_bool AlwaysUseConnectionFile; + }; + class CDataConnections : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CDataConnections) + CDataConnections() {} + virtual ~CDataConnections() {} + + virtual std::wstring toXML() const { return L""; } + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + + nullable_uint NextID; + }; + class CDataColumn : public WritingElement + { + public: + WritingElement_AdditionMethods(CDataColumn) + CDataColumn() {} + virtual ~CDataColumn() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_string ColumnNameID; + nullable_string Name; + nullable_string Label; + nullable_string OrigLabel; + nullable_string LangID; + nullable_uint Calendar; + nullable_uint DataType; + nullable_string UnitType; + nullable_uint Currency; + nullable_uint Degree; + nullable_uint DisplayWidth; + nullable_uint DisplayOrder; + nullable_bool Mapped; + nullable_bool Hyperlink; + }; + class CDataColumns : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CDataColumns) + CDataColumns() {} + virtual ~CDataColumns() {} + + virtual std::wstring toXML() const { return L""; } + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + + nullable_string SortColumn; + nullable_bool SortAsc; + }; + class CDataRecordSet : public WritingElementWithChilds<> + { + public: + WritingElement_AdditionMethods(CDataRecordSet) + CDataRecordSet() {} + virtual ~CDataRecordSet() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_uint ID; + nullable_uint ConnectionID; + nullable_string Command; + nullable_uint Options; + nullable_string TimeRefreshed; + nullable_uint NextRowID; + nullable_string Name; + nullable_bool RowOrder; + nullable_bool RefreshOverwriteAll; + nullable_bool RefreshNoReconciliationUI; + nullable_uint RefreshInterval; + nullable_uint ReplaceLinks; + nullable_uint Checksum; + + nullable DataColumns; + nullable Rel; + }; + class CDataRecordSets : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CDataRecordSets) + CDataRecordSets() {} + virtual ~CDataRecordSets() {} + + virtual std::wstring toXML() const { return L""; } + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + + nullable_uint NextID; + nullable_uint ActiveRecordsetID; + nullable_string DataWindowOrder; + }; +//------------------------------------------------------------------------------------------------------------------------------ + class CConnectionsFile : public OOX::File + { + public: + CConnectionsFile(OOX::Document* pMain); + CConnectionsFile(OOX::Document* pMain, const CPath& uri); + CConnectionsFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); + virtual ~CConnectionsFile(); + + virtual void read(const CPath& oFilePath); + virtual void read(const CPath& oRootPath, const CPath& oFilePath); + virtual void write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const; + + virtual const OOX::FileType type() const; + + virtual const CPath DefaultDirectory() const; + virtual const CPath DefaultFileName() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + std::wstring m_strFilename; + + nullable DataConnections; + }; + class CRecordsetsFile : public OOX::IFileContainer, public OOX::File + { + public: + CRecordsetsFile(OOX::Document* pMain); + CRecordsetsFile(OOX::Document* pMain, const CPath& uri); + CRecordsetsFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); + virtual ~CRecordsetsFile(); + + virtual void read(const CPath& oFilePath); + virtual void read(const CPath& oRootPath, const CPath& oFilePath); + virtual void write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const; + + virtual const OOX::FileType type() const; + + virtual const CPath DefaultDirectory() const; + virtual const CPath DefaultFileName() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + std::wstring m_strFilename; + + nullable DataRecordSets; + }; + class CRecordsetFile : public OOX::File + { + public: + CRecordsetFile(OOX::Document* pMain); + CRecordsetFile(OOX::Document* pMain, const CPath& uri); + CRecordsetFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); + virtual ~CRecordsetFile(); + + virtual void read(const CPath& oFilePath); + virtual void read(const CPath& oRootPath, const CPath& oFilePath); + virtual void write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const; + + virtual const OOX::FileType type() const; + + virtual const CPath DefaultDirectory() const; + virtual const CPath DefaultFileName() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter); + + std::wstring m_strFilename; + + std::string m_sXmlA; + }; + } //Draw +} // namespace OOX diff --git a/OOXML/VsdxFormat/VisioDocument.cpp b/OOXML/VsdxFormat/VisioDocument.cpp new file mode 100644 index 0000000000..c21785dd67 --- /dev/null +++ b/OOXML/VsdxFormat/VisioDocument.cpp @@ -0,0 +1,2366 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "VisioDocument.h" +#include "VisioPages.h" +#include "VisioConnections.h" +#include "VisioOthers.h" +#include "Shapes.h" +#include "../PPTXFormat/Theme.h" +#include "../../DesktopEditor/common/SystemUtils.h" +#include "../Binary/Presentation/BinaryFileReaderWriter.h" +#include "../Binary/Presentation/XmlWriter.h" + +namespace OOX +{ +namespace Draw +{ + EElementType CPublishedPage::getType() const + { + return et_dr_PublishedPage; + } + void CPublishedPage::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "ID", ID) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CPublishedPage::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + } + void CPublishedPage::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, ID); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CPublishedPage::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + ID = pReader->GetULong(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CPublishedPage::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"PublishedPage"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"ID", ID); + pWriter->EndAttributes(); + pWriter->WriteNodeEnd(L"PublishedPage"); + } + EElementType CRefreshableData::getType() const + { + return et_dr_RefreshableData; + } + void CRefreshableData::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "ID", ID) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CRefreshableData::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + } + void CRefreshableData::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, ID); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CRefreshableData::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + ID = pReader->GetULong(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CRefreshableData::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"RefreshableData"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"ID", ID); + pWriter->EndAttributes(); + pWriter->WriteNodeEnd(L"RefreshableData"); + } + EElementType CPublishSettings::getType() const + { + return et_dr_PublishSettings; + } + void CPublishSettings::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + WritingElement* pItem = NULL; + if (L"PublishedPage" == sName) + { + pItem = new CPublishedPage(); + } + else if (L"RefreshableData" == sName) + { + pItem = new CRefreshableData(); + } + if (pItem) + { + pItem->fromXML(oReader); + m_arrItems.push_back(pItem); + } + } + } + void CPublishSettings::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + int type = 0xff; //todooo predefine type for ??? + switch (m_arrItems[i]->getType()) + { + case et_dr_PublishedPage: type = 0; break; + case et_dr_RefreshableData: type = 1; break; + } + if (type != 0xff) + pWriter->WriteRecord2(type, dynamic_cast(m_arrItems[i])); + } + } + void CPublishSettings::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + while (pReader->GetPos() < _end_rec) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + m_arrItems.push_back(new CPublishedPage()); + m_arrItems.back()->fromPPTY(pReader); + }break; + case 1: + { + m_arrItems.push_back(new CRefreshableData()); + m_arrItems.back()->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CPublishSettings::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"PublishSettings"); + pWriter->EndAttributes(); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"PublishSettings"); + } +//---------------------------------------------------------------------------------------------------------------- + EElementType CHeaderFooter::getType() const + { + return et_dr_HeaderFooter; + } + void CHeaderFooter::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "HeaderMargin", HeaderMargin) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "FooterMargin", FooterMargin) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "HeaderLeft", HeaderLeft) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "HeaderCenter", HeaderCenter) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "HeaderRight", HeaderRight) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "FooterLeft", FooterLeft) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "FooterCenter", FooterCenter) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "FooterRight", FooterRight) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CHeaderFooter::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + } + void CHeaderFooter::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteString2(0, HeaderMargin); + pWriter->WriteString2(1, FooterMargin); + pWriter->WriteString2(2, HeaderLeft); + pWriter->WriteString2(3, HeaderCenter); + pWriter->WriteString2(4, HeaderRight); + pWriter->WriteString2(5, FooterLeft); + pWriter->WriteString2(6, FooterCenter); + pWriter->WriteString2(7, FooterRight); + pWriter->WriteString2(8, HeaderFooterColor); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CHeaderFooter::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + HeaderMargin = pReader->GetString2(); + }break; + case 1: + { + FooterMargin = pReader->GetString2(); + }break; + case 2: + { + HeaderLeft = pReader->GetString2(); + }break; + case 3: + { + HeaderCenter = pReader->GetString2(); + }break; + case 4: + { + HeaderRight = pReader->GetString2(); + }break; + case 5: + { + FooterLeft = pReader->GetString2(); + }break; + case 6: + { + FooterCenter = pReader->GetString2(); + }break; + case 7: + { + FooterRight = pReader->GetString2(); + }break; + case 8: + { + HeaderFooterColor = pReader->GetString2(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CHeaderFooter::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"HeaderFooter"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"HeaderMargin", HeaderMargin); + pWriter->WriteAttribute2(L"FooterMargin", FooterMargin); + pWriter->WriteAttribute2(L"HeaderLeft", HeaderLeft); + pWriter->WriteAttribute2(L"HeaderCenter", HeaderCenter); + pWriter->WriteAttribute2(L"HeaderRight", HeaderRight); + pWriter->WriteAttribute2(L"FooterLeft", FooterLeft); + pWriter->WriteAttribute2(L"FooterCenter", FooterCenter); + pWriter->WriteAttribute2(L"FooterRight", FooterRight); + pWriter->WriteAttribute2(L"HeaderFooterColor", HeaderFooterColor); + pWriter->EndAttributes(); +// todooo color, font + pWriter->WriteNodeEnd(L"HeaderFooter"); + } + EElementType CDocumentSheet::getType() const + { + return et_dr_DocumentSheet; + } + void CDocumentSheet::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "UniqueID", UniqueID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "NameU", NameU) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Name", Name) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "IsCustomName", IsCustomName) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "IsCustomNameU", IsCustomNameU) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "LineStyle", LineStyle) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "FillStyle", FillStyle) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "TextStyle", TextStyle) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CDocumentSheet::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + WritingElement* pItem = NULL; + if (L"Cell" == sName) + { + pItem = new CCell(); + } + else if (L"Trigger" == sName) + { + pItem = new CTrigger(); + } + else if (L"Section" == sName) + { + pItem = new CSection(); + } + if (pItem) + { + pItem->fromXML(oReader); + m_arrItems.push_back(pItem); + } + } + } + void CDocumentSheet::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteString2(0, UniqueID); + pWriter->WriteString2(1, NameU); + pWriter->WriteString2(2, Name); + pWriter->WriteBool2(3, IsCustomName); + pWriter->WriteBool2(4, IsCustomNameU); + pWriter->WriteUInt2(5, LineStyle); + pWriter->WriteUInt2(6, FillStyle); + pWriter->WriteUInt2(7, TextStyle); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + int type = 0xff; //todooo predefine type for ??? + switch (m_arrItems[i]->getType()) + { + case et_dr_Cell: type = 0; break; + case et_dr_Trigger: type = 1; break; + case et_dr_Section: type = 2; break; + } + if (type != 0xff) + pWriter->WriteRecord2(type, dynamic_cast(m_arrItems[i])); + } + } + void CDocumentSheet::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + UniqueID = pReader->GetString2(); + }break; + case 1: + { + NameU = pReader->GetString2(); + }break; + case 2: + { + Name = pReader->GetString2(); + }break; + case 3: + { + IsCustomName = pReader->GetBool(); + }break; + case 4: + { + IsCustomNameU = pReader->GetBool(); + }break; + case 5: + { + LineStyle = pReader->GetULong(); + }break; + case 6: + { + FillStyle = pReader->GetULong(); + }break; + case 7: + { + TextStyle = pReader->GetULong(); + }break; + } + } + while (pReader->GetPos() < _end_rec) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + m_arrItems.push_back(new CCell()); + m_arrItems.back()->fromPPTY(pReader); + }break; + case 1: + { + m_arrItems.push_back(new CTrigger()); + m_arrItems.back()->fromPPTY(pReader); + }break; + case 2: + { + m_arrItems.push_back(new CSection()); + m_arrItems.back()->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CDocumentSheet::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"DocumentSheet"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"NameU", NameU); + pWriter->WriteAttribute2(L"Name", Name); + pWriter->WriteAttribute(L"IsCustomName", IsCustomName); + pWriter->WriteAttribute(L"IsCustomNameU", IsCustomNameU); + pWriter->WriteAttribute2(L"UniqueID", UniqueID); + pWriter->WriteAttribute2(L"LineStyle", LineStyle); + pWriter->WriteAttribute2(L"FillStyle", FillStyle); + pWriter->WriteAttribute2(L"TextStyle", TextStyle); + pWriter->EndAttributes(); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"DocumentSheet"); + } + EElementType CEventItem::getType() const + { + return et_dr_EventItem; + } + void CEventItem::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "ID", ID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Action", Action) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "EventCode", EventCode) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Enabled", Enabled) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Target", Target) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "TargetArgs", TargetArgs) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CEventItem::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + } + void CEventItem::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, ID); + pWriter->WriteUInt2(1, Action); + pWriter->WriteUInt2(2, EventCode); + pWriter->WriteBool2(3, Enabled); + pWriter->WriteString2(4, Target); + pWriter->WriteString2(5, TargetArgs); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CEventItem::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + ID = pReader->GetULong(); + }break; + case 1: + { + Action = pReader->GetULong(); + }break; + case 2: + { + EventCode = pReader->GetULong(); + }break; + case 3: + { + Enabled = pReader->GetBool(); + }break; + case 4: + { + Target = pReader->GetString2(); + }break; + case 5: + { + TargetArgs = pReader->GetString2(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CEventItem::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"EventItem"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"ID", ID); + pWriter->WriteAttribute2(L"Action", Action); + pWriter->WriteAttribute2(L"EventCode", EventCode); + pWriter->WriteAttribute(L"Enabled", Enabled); + pWriter->WriteAttribute2(L"Target", Target); + pWriter->WriteAttribute2(L"TargetArgs", TargetArgs); + pWriter->EndAttributes(); + pWriter->WriteNodeEnd(L"EventItem"); + } + void CEventList::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + if (L"EventItem" == sName) + { + CEventItem* pItem = new CEventItem(); + *pItem = oReader; + + if (pItem) + m_arrItems.push_back(pItem); + } + } + } + EElementType CEventList::getType() const + { + return et_dr_EventList; + } + void CEventList::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + m_arrItems.push_back(new CEventItem()); + m_arrItems.back()->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + } + void CEventList::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + for (size_t i = 0; i < m_arrItems.size(); ++i) + pWriter->WriteRecord2(0, dynamic_cast(m_arrItems[i])); + } + void CEventList::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"EventList"); + pWriter->EndAttributes(); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"EventList"); + } + EElementType CStyleSheet::getType() const + { + return et_dr_StyleSheet; + } + void CStyleSheet::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "ID", ID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "NameU", NameU) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Name", Name) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "IsCustomName", IsCustomName) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "IsCustomNameU", IsCustomNameU) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "LineStyle", LineStyle) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "FillStyle", FillStyle) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "TextStyle", TextStyle) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CStyleSheet::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + WritingElement* pItem = NULL; + if (L"Cell" == sName) + { + pItem = new CCell(); + } + else if (L"Trigger" == sName) + { + pItem = new CTrigger(); + } + else if (L"Section" == sName) + { + pItem = new CSection(); + } + if (pItem) + { + pItem->fromXML(oReader); + m_arrItems.push_back(pItem); + } + } + } + void CStyleSheet::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, ID); + pWriter->WriteString2(1, NameU); + pWriter->WriteString2(2, Name); + pWriter->WriteBool2(3, IsCustomName); + pWriter->WriteBool2(4, IsCustomNameU); + pWriter->WriteUInt2(5, LineStyle); + pWriter->WriteUInt2(6, FillStyle); + pWriter->WriteUInt2(7, TextStyle); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + int type = 0xff; //todooo predefine type for ??? + switch (m_arrItems[i]->getType()) + { + case et_dr_Cell: type = 0; break; + case et_dr_Trigger: type = 1; break; + case et_dr_Section: type = 2; break; + } + if (type != 0xff) + pWriter->WriteRecord2(type, dynamic_cast(m_arrItems[i])); + } + } + void CStyleSheet::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + ID = pReader->GetULong(); + }break; + case 1: + { + NameU = pReader->GetString2(); + }break; + case 2: + { + Name = pReader->GetString2(); + }break; + case 3: + { + IsCustomName = pReader->GetBool(); + }break; + case 4: + { + IsCustomNameU = pReader->GetBool(); + }break; + case 5: + { + LineStyle = pReader->GetULong(); + }break; + case 6: + { + FillStyle = pReader->GetULong(); + }break; + case 7: + { + TextStyle = pReader->GetULong(); + }break; + } + } + while (pReader->GetPos() < _end_rec) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + m_arrItems.push_back(new CCell()); + m_arrItems.back()->fromPPTY(pReader); + }break; + case 1: + { + m_arrItems.push_back(new CTrigger()); + m_arrItems.back()->fromPPTY(pReader); + }break; + case 2: + { + m_arrItems.push_back(new CSection()); + m_arrItems.back()->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CStyleSheet::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"StyleSheet"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"ID", ID); + pWriter->WriteAttribute2(L"NameU", NameU); + pWriter->WriteAttribute2(L"Name", Name); + pWriter->WriteAttribute(L"IsCustomName", IsCustomName); + pWriter->WriteAttribute(L"IsCustomNameU", IsCustomNameU); + pWriter->WriteAttribute2(L"LineStyle", LineStyle); + pWriter->WriteAttribute2(L"FillStyle", FillStyle); + pWriter->WriteAttribute2(L"TextStyle", TextStyle); + pWriter->EndAttributes(); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"StyleSheet"); + } + void CStyleSheets::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + if (L"StyleSheet" == sName) + { + CStyleSheet* pItem = new CStyleSheet(); + *pItem = oReader; + + if (pItem) + m_arrItems.push_back(pItem); + } + } + } + EElementType CStyleSheets::getType() const + { + return et_dr_StyleSheets; + } + void CStyleSheets::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + m_arrItems.push_back(new CStyleSheet()); + m_arrItems.back()->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + } + void CStyleSheets::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + for (size_t i = 0; i < m_arrItems.size(); ++i) + pWriter->WriteRecord2(0, dynamic_cast(m_arrItems[i])); + } + void CStyleSheets::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"StyleSheets"); + pWriter->EndAttributes(); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"StyleSheets"); + } + EElementType CColorEntry::getType() const + { + return et_dr_ColorEntry; + } + void CColorEntry::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "IX", IX) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "RGB", RGB) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CColorEntry::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + } + void CColorEntry::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, IX); + pWriter->WriteString2(1, RGB); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CColorEntry::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + IX = pReader->GetULong(); + }break; + case 1: + { + RGB = pReader->GetString2(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CColorEntry::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"ColorEntry"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"IX", IX); + pWriter->WriteAttribute2(L"RGB", RGB); + pWriter->EndAttributes(); + pWriter->WriteNodeEnd(L"ColorEntry"); + } + void CColors::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + if (L"ColorEntry" == sName) + { + CColorEntry* pItem = new CColorEntry(); + *pItem = oReader; + + if (pItem) + m_arrItems.push_back(pItem); + } + } + } + EElementType CColors::getType() const + { + return et_dr_Colors; + } + void CColors::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + m_arrItems.push_back(new CColorEntry()); + m_arrItems.back()->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + } + void CColors::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + for (size_t i = 0; i < m_arrItems.size(); ++i) + pWriter->WriteRecord2(0, dynamic_cast(m_arrItems[i])); + } + void CColors::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"Colors"); + pWriter->EndAttributes(); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"Colors"); + } + EElementType CFaceName::getType() const + { + return et_dr_FaceName; + } + void CFaceName::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "NameU", NameU) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "UnicodeRanges", UnicodeRanges) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "CharSets", CharSets) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Panos", Panos) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Panose", Panose) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Flags", Flags) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CFaceName::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + } + void CFaceName::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteString2(0, NameU); + pWriter->WriteString2(1, UnicodeRanges); + pWriter->WriteString2(2, CharSets); + pWriter->WriteString2(3, Panos); + pWriter->WriteString2(4, Panose); + pWriter->WriteUInt2(5, Flags); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CFaceName::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + NameU = pReader->GetString2(); + }break; + + case 1: + { + UnicodeRanges = pReader->GetString2(); + }break; + case 2: + { + CharSets = pReader->GetString2(); + }break; + case 3: + { + Panos = pReader->GetString2(); + }break; + case 4: + { + Panose = pReader->GetString2(); + }break; + + case 5: + { + Flags = pReader->GetULong(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CFaceName::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"FaceName"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"NameU", NameU); + pWriter->WriteAttribute2(L"UnicodeRanges", UnicodeRanges); + pWriter->WriteAttribute2(L"CharSets", CharSets); + pWriter->WriteAttribute2(L"Panos", Panos); + pWriter->WriteAttribute2(L"Panose", Panose); + pWriter->WriteAttribute2(L"Flags", Flags); + pWriter->EndAttributes(); + pWriter->WriteNodeEnd(L"FaceName"); + } + void CFaceNames::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + if (L"FaceName" == sName) + { + CFaceName* pItem = new CFaceName(); + *pItem = oReader; + + if (pItem) + m_arrItems.push_back(pItem); + } + } + } + EElementType CFaceNames::getType() const + { + return et_dr_FaceNames; + } + void CFaceNames::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + m_arrItems.push_back(new CFaceName()); + m_arrItems.back()->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + } + void CFaceNames::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + for (size_t i = 0; i < m_arrItems.size(); ++i) + pWriter->WriteRecord2(0, dynamic_cast(m_arrItems[i])); + } + void CFaceNames::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"FaceNames"); + pWriter->EndAttributes(); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"FaceNames"); + } +//----------------------------------------------------------------------------------------------------------------------------- + EElementType CDocumentSettings::getType() const + { + return et_dr_DocumentSettings; + } + void CDocumentSettings::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "TopPage", TopPage) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "DefaultTextStyle", DefaultTextStyle) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "DefaultLineStyle", DefaultLineStyle) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "DefaultFillStyle", DefaultFillStyle) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "DefaultGuideStyle", DefaultGuideStyle) + WritingElement_ReadAttributes_EndChar_No_NS( oReader ) + } + void CDocumentSettings::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + const char* sName = XmlUtils::GetNameNoNS(oReader.GetNameChar()); + if (strcmp("GlueSettings", sName) == 0) + { + GlueSettings = oReader.GetText(); + } + else if (strcmp("SnapSettings", sName) == 0) + { + SnapSettings = oReader.GetText(); + } + else if (strcmp("SnapExtensions", sName) == 0) + { + SnapExtensions = oReader.GetText(); + } + else if (strcmp("SnapAngles", sName) == 0) + { + SnapAngles = oReader.GetText(); + } + else if (strcmp("DynamicGridEnabled", sName) == 0) + { + DynamicGridEnabled = oReader.GetText(); + } + else if (strcmp("ProtectStyles", sName) == 0) + { + ProtectStyles = oReader.GetText(); + } + else if (strcmp("ProtectShapes", sName) == 0) + { + ProtectShapes = oReader.GetText(); + } + else if (strcmp("ProtectBkgnds", sName) == 0) + { + ProtectBkgnds = oReader.GetText(); + } + else if (strcmp("ProtectMasters", sName) == 0) + { + ProtectMasters = oReader.GetText(); + } + else if (strcmp("CustomMenusFile", sName) == 0) + { + CustomMenusFile = oReader.GetText(); + } + else if (strcmp("CustomToolbarsFile", sName) == 0) + { + CustomToolbarsFile = oReader.GetText(); + } + else if (strcmp("AttachedToolbars", sName) == 0) + { + AttachedToolbars = oReader.GetText(); + } + } + } + void CDocumentSettings::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, TopPage); + pWriter->WriteUInt2(1, DefaultTextStyle); + pWriter->WriteUInt2(2, DefaultLineStyle); + pWriter->WriteUInt2(3, DefaultFillStyle); + pWriter->WriteUInt2(4, DefaultGuideStyle); + pWriter->WriteInt2(5, GlueSettings); + pWriter->WriteInt2(6, SnapSettings); + pWriter->WriteInt2(7, SnapExtensions); + pWriter->WriteInt2(8, SnapAngles); + pWriter->WriteBool2(9, DynamicGridEnabled); + pWriter->WriteBool2(10, ProtectStyles); + pWriter->WriteBool2(11, ProtectShapes); + pWriter->WriteBool2(12, ProtectBkgnds); + pWriter->WriteBool2(13, ProtectMasters); + pWriter->WriteString2(14, CustomMenusFile); + pWriter->WriteString2(15, CustomToolbarsFile); + pWriter->WriteString2(16, AttachedToolbars); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CDocumentSettings::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + TopPage = pReader->GetULong(); + }break; + case 1: + { + DefaultTextStyle = pReader->GetULong(); + }break; + case 2: + { + DefaultLineStyle = pReader->GetULong(); + }break; + case 3: + { + DefaultFillStyle = pReader->GetULong(); + }break; + case 4: + { + DefaultGuideStyle = pReader->GetULong(); + }break; + case 5: + { + GlueSettings = pReader->GetLong(); + }break; + case 6: + { + SnapSettings = pReader->GetLong(); + }break; + case 7: + { + SnapExtensions = pReader->GetLong(); + }break; + case 8: + { + SnapAngles = pReader->GetLong(); + }break; + case 9: + { + DynamicGridEnabled = pReader->GetBool(); + }break; + case 10: + { + ProtectStyles = pReader->GetBool(); + }break; + case 11: + { + ProtectShapes = pReader->GetBool(); + }break; + case 12: + { + ProtectBkgnds = pReader->GetBool(); + }break; + case 13: + { + ProtectMasters = pReader->GetBool(); + }break; + case 14: + { + CustomMenusFile = pReader->GetString2(); + }break; + case 15: + { + CustomToolbarsFile = pReader->GetString2(); + }break; + case 16: + { + AttachedToolbars = pReader->GetString2(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CDocumentSettings::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"DocumentSettings"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"TopPage", TopPage); + pWriter->WriteAttribute2(L"DefaultTextStyle", DefaultTextStyle); + pWriter->WriteAttribute2(L"DefaultLineStyle", DefaultLineStyle); + pWriter->WriteAttribute2(L"DefaultFillStyle", DefaultFillStyle); + pWriter->WriteAttribute2(L"DefaultGuideStyle", DefaultGuideStyle); + pWriter->EndAttributes(); + //todooo + pWriter->WriteNodeEnd(L"DocumentSettings"); + } +//----------------------------------------------------------------------------------------------------------------------------- + OOX::Draw::CDocumentFile::CDocumentFile(OOX::Document* pMain) : OOX::IFileContainer(pMain), OOX::File(pMain) + { + m_bMacroEnabled = false; + m_bVisioPages = true; + } + OOX::Draw::CDocumentFile::CDocumentFile(OOX::Document* pMain, const CPath& uri) : OOX::IFileContainer(pMain), OOX::File(pMain) + { + m_bMacroEnabled = false; + m_bVisioPages = true; + + read(uri.GetDirectory(), uri); + } + OOX::Draw::CDocumentFile::CDocumentFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::IFileContainer(pMain), OOX::File(pMain) + { + m_bMacroEnabled = false; + m_bVisioPages = true; + + read(oRootPath, oPath); + } + OOX::Draw::CDocumentFile::~CDocumentFile() + { + } + void OOX::Draw::CDocumentFile::read(const CPath& oFilePath) + { + CPath oRootPath; + read(oRootPath, oFilePath); + } + void OOX::Draw::CDocumentFile::read(const CPath& oRootPath, const CPath& oFilePath) + { + IFileContainer::Read(oRootPath, oFilePath); + + smart_ptr pFile = this->Find(OOX::FileTypes::VbaProject); + if (pFile.IsInit()) + { + m_bMacroEnabled = true; + + } + XmlUtils::CXmlLiteReader oReader; + + if (!oReader.FromFile(oFilePath.GetPath())) + return; + + if (!oReader.ReadNextNode()) + return; + + m_strFilename = oFilePath.GetPath(); + + std::wstring sName = oReader.GetName(); + if (L"VisioDocument" == sName && !oReader.IsEmptyNode()) + { + int nDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nDepth)) + { + sName = oReader.GetName(); + + if (L"DocumentSettings" == sName) + { + DocumentSettings = oReader; + } + else if (L"Colors" == sName) + { + Colors = oReader; + } + else if (L"FaceNames" == sName) + { + FaceNames = oReader; + } + else if (L"StyleSheets" == sName) + { + StyleSheets = oReader; + } + else if (L"DocumentSheet" == sName) + { + DocumentSheet = oReader; + } + else if (L"EventList" == sName) + { + EventList = oReader; + } + else if (L"HeaderFooter" == sName) + { + HeaderFooter = oReader; + } + } + } + } + void OOX::Draw::CDocumentFile::write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const + { + NSBinPptxRW::CXmlWriter oXmlWriter; + oXmlWriter.WriteString((L"")); + + oXmlWriter.m_lDocType = XMLWRITER_DOC_TYPE_VSDX; + toXmlWriter(&oXmlWriter); + + NSFile::CFileBinary::SaveToFile(oFilePath.GetPath(), oXmlWriter.GetXmlString()); + + oContent.Registration(type().OverrideType(), oDirectory, oFilePath.GetFilename()); + IFileContainer::Write(oFilePath, oDirectory, oContent); + } + const OOX::FileType OOX::Draw::CDocumentFile::type() const + { + if (m_bMacroEnabled) return OOX::Draw::FileTypes::DocumentMacro; + else return OOX::Draw::FileTypes::Document; + } + const OOX::CPath OOX::Draw::CDocumentFile::DefaultDirectory() const + { + return type().DefaultDirectory(); + } + const OOX::CPath OOX::Draw::CDocumentFile::DefaultFileName() const + { + return type().DefaultFileName(); + } + void OOX::Draw::CDocumentFile::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + pReader->Skip(1); // type + + smart_ptr rels_old = pReader->GetRels(); + pReader->SetRels(dynamic_cast((CDocumentFile*)this)); + + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + + switch (_rec) + { + case 0: + { + DocumentSettings.Init(); + DocumentSettings->fromPPTY(pReader); + }break; + case 1: + { + Colors.Init(); + Colors->fromPPTY(pReader); + }break; + case 2: + { + FaceNames.Init(); + FaceNames->fromPPTY(pReader); + }break; + case 3: + { + StyleSheets.Init(); + StyleSheets->fromPPTY(pReader); + }break; + case 4: + { + DocumentSheet.Init(); + DocumentSheet->fromPPTY(pReader); + }break; + case 5: + { + EventList.Init(); + EventList->fromPPTY(pReader); + }break; + case 6: + { + HeaderFooter.Init(); + HeaderFooter->fromPPTY(pReader); + }break; + case 7: + { + CMastersFile* pMaster = new CMastersFile(((OOX::File*)this)->m_pMainDocument); + pMaster->fromPPTY(pReader); + smart_ptr oFile(pMaster); + + pReader->GetRels()->Add(oFile); + }break; + case 8: + { + CPagesFile* pPage = new CPagesFile(((OOX::File*)this)->m_pMainDocument); + pPage->fromPPTY(pReader); + smart_ptr oFile(pPage); + + pReader->GetRels()->Add(oFile); + }break; + case 9: + { + CConnectionsFile* pConnections = new CConnectionsFile(((OOX::File*)this)->m_pMainDocument); + pConnections->fromPPTY(pReader); + smart_ptr oFile(pConnections); + + pReader->GetRels()->Add(oFile); + }break; + case 10: + { + CRecordsetsFile* pRecordsets = new CRecordsetsFile(((OOX::File*)this)->m_pMainDocument); + pRecordsets->fromPPTY(pReader); + smart_ptr oFile(pRecordsets); + + pReader->GetRels()->Add(oFile); + }break; + case 11: + { + CSolutionsFile* pSolutions = new CSolutionsFile(((OOX::File*)this)->m_pMainDocument); + pSolutions->fromPPTY(pReader); + smart_ptr oFile(pSolutions); + + pReader->GetRels()->Add(oFile); + }break; + case 12: + { + CValidationFile* pValidation = new CValidationFile(((OOX::File*)this)->m_pMainDocument); + pValidation->fromPPTY(pReader); + smart_ptr oFile(pValidation); + + pReader->GetRels()->Add(oFile); + }break; + case 13: + { + CCommentsFile* pComments = new CCommentsFile(((OOX::File*)this)->m_pMainDocument); + pComments->fromPPTY(pReader); + smart_ptr oFile(pComments); + + pReader->GetRels()->Add(oFile); + }break; + case 14: + { + CWindowsFile* pWindows = new CWindowsFile(((OOX::File*)this)->m_pMainDocument); + pWindows->fromPPTY(pReader); + smart_ptr oFile(pWindows); + + pReader->GetRels()->Add(oFile); + }break; + case 15: + { + pReader->Skip(4); // len + + PPTX::Theme* pTheme = new PPTX::Theme(((OOX::File*)this)->m_pMainDocument); + pTheme->fromPPTY(pReader); + smart_ptr oFile(pTheme); + + pReader->GetRels()->Add(oFile); + }break; + case 16: + { + if (m_bMacroEnabled) + { + OOX::VbaProject* pVbaProject = new OOX::VbaProject(((OOX::File*)this)->m_pMainDocument); + pVbaProject->fromPPTY(pReader); + smart_ptr oFile(pVbaProject); + + pReader->GetRels()->Add(oFile); + } + else + { + pReader->SkipRecord(); + } + }break; + case 17: + { + _INT32 _len = pReader->GetRecordSize(); + + BYTE* pData = pReader->GetPointer(_len); + OOX::CPath oJsaProject = OOX::FileTypes::JsaProject.DefaultFileName(); + std::wstring filePath = pReader->m_strFolder + FILE_SEPARATOR_STR + _T("visio") + FILE_SEPARATOR_STR + oJsaProject.GetPath(); + + NSFile::CFileBinary oBinaryFile; + oBinaryFile.CreateFileW(filePath); + oBinaryFile.WriteFile(pData, _len); + oBinaryFile.CloseFile(); + + smart_ptr oFileJsaProject(new OOX::JsaProject(NULL)); + smart_ptr oFile = oFileJsaProject.smart_dynamic_cast(); + pReader->GetRels()->Add(oFile); + + pReader->m_pRels->m_pManager->m_pContentTypes->AddDefault(oJsaProject.GetExtention(false)); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + pReader->SetRels(rels_old); + } + void OOX::Draw::CDocumentFile::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->StartRecord(0); + + pWriter->WriteRecord2(0, DocumentSettings); + pWriter->WriteRecord2(1, Colors); + pWriter->WriteRecord2(2, FaceNames); + pWriter->WriteRecord2(3, StyleSheets); + pWriter->WriteRecord2(4, DocumentSheet); + pWriter->WriteRecord2(5, EventList); + pWriter->WriteRecord2(6, HeaderFooter); + + smart_ptr pFile = this->Find(OOX::Draw::FileTypes::Masters); + CMastersFile* pMasters= dynamic_cast(pFile.GetPointer()); + if (pMasters) + { + pWriter->StartRecord(7); + pMasters->toPPTY(pWriter); + pWriter->EndRecord(); + } + + pFile = this->Find(OOX::Draw::FileTypes::Pages); + CPagesFile* pPages = dynamic_cast(pFile.GetPointer()); + if (pPages) + { + pWriter->StartRecord(8); + pPages->toPPTY(pWriter); + pWriter->EndRecord(); + } + + pFile = this->Find(OOX::Draw::FileTypes::Connections); + CConnectionsFile* pConnections = dynamic_cast(pFile.GetPointer()); + if (pConnections) + { + pWriter->StartRecord(9); + pConnections->toPPTY(pWriter); + pWriter->EndRecord(); + } + + pFile = this->Find(OOX::Draw::FileTypes::Recordsets); + CRecordsetsFile* pRecordsets = dynamic_cast(pFile.GetPointer()); + if (pRecordsets) + { + pWriter->StartRecord(10); + pRecordsets->toPPTY(pWriter); + pWriter->EndRecord(); + } + + pFile = this->Find(OOX::Draw::FileTypes::Solutions); + CSolutionsFile* pSolutions = dynamic_cast(pFile.GetPointer()); + if (pSolutions) + { + pWriter->StartRecord(11); + pSolutions->toPPTY(pWriter); + pWriter->EndRecord(); + } + + pFile = this->Find(OOX::Draw::FileTypes::Validation); + CValidationFile* pValidation = dynamic_cast(pFile.GetPointer()); + if (pValidation) + { + pWriter->StartRecord(12); + pValidation->toPPTY(pWriter); + pWriter->EndRecord(); + } + + pFile = this->Find(OOX::Draw::FileTypes::Comments); + CCommentsFile* pComments = dynamic_cast(pFile.GetPointer()); + if (pComments) + { + pWriter->StartRecord(13); + pComments->toPPTY(pWriter); + pWriter->EndRecord(); + } + + pFile = this->Find(OOX::Draw::FileTypes::Windows); + CWindowsFile* pWindows = dynamic_cast(pFile.GetPointer()); + if (pPages) + { + pWriter->StartRecord(14); + pWindows->toPPTY(pWriter); + pWriter->EndRecord(); + } + std::vector>& container = ((OOX::IFileContainer*)(this))->GetContainer(); + for (size_t k = 0; k < container.size(); ++k) + { + if (OOX::FileTypes::Theme == container[k]->type()) + { + PPTX::Theme* pTheme = dynamic_cast(container[k].GetPointer()); + + pWriter->StartRecord(15); + pTheme->toPPTY(pWriter); + pWriter->EndRecord(); + } + } + pFile = this->Find(OOX::FileTypes::VbaProject); + OOX::VbaProject *pVbaProject = dynamic_cast(pFile.GetPointer()); + if (pVbaProject) + { + pWriter->StartRecord(16); + pVbaProject->toPPTY(pWriter); + pWriter->EndRecord(); + } + pFile = this->Find(OOX::FileTypes::JsaProject); + OOX::JsaProject* pJsaProject = dynamic_cast(pFile.GetPointer()); + if (pJsaProject) + { + if (pJsaProject->IsExist() && !pJsaProject->IsExternal()) + { + std::wstring pathJsa = pJsaProject->filename().GetPath(); + if (std::wstring::npos != pathJsa.find(pWriter->m_strMainFolder)) + { + BYTE* pData = NULL; + DWORD nBytesCount; + if (NSFile::CFileBinary::ReadAllBytes(pJsaProject->filename().GetPath(), &pData, nBytesCount)) + { + pWriter->StartRecord(17); + pWriter->WriteBYTEArray(pData, nBytesCount); + pWriter->EndRecord(); + + RELEASEARRAYOBJECTS(pData); + } + } + } + if (pJsaProject->IsExternal()) + { + //pWriter->StartRecord(18); + //m_oBcw.m_oStream.WriteStringW3(pJsaProject->filename().GetPath()); + //pWriter->EndRecord(); + } + } + pWriter->EndRecord(); + } + void CDocumentFile::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"VisioDocument"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"xmlns", L"http://schemas.microsoft.com/office/visio/2012/main"); + pWriter->WriteAttribute2(L"xmlns:r", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships"); + pWriter->WriteAttribute2(L"xml:space", L"preserve"); + pWriter->EndAttributes(); + + if (DocumentSettings.IsInit()) + DocumentSettings->toXmlWriter(pWriter); + if (Colors.IsInit()) + Colors->toXmlWriter(pWriter); + if (FaceNames.IsInit()) + FaceNames->toXmlWriter(pWriter); + if (StyleSheets.IsInit()) + StyleSheets->toXmlWriter(pWriter); + if (DocumentSheet.IsInit()) + DocumentSheet->toXmlWriter(pWriter); + if (EventList.IsInit()) + EventList->toXmlWriter(pWriter); + if (HeaderFooter.IsInit()) + HeaderFooter->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"VisioDocument"); + } + //----------------------------------------------------------------------------------------------------------------------------- + EElementType CSnapAngle::getType() const + { + return et_dr_SnapAngle; + } + void CSnapAngle::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + + content = oReader.GetText2(); + } + void CSnapAngle::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteDoubleReal2(0, content); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CSnapAngle::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + content = pReader->GetDoubleReal(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CSnapAngle::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->WriteNodeValue(L"SnapAngle", content); + } +//----------------------------------------------------------------------------------------------------------------------------- + void CSnapAngles::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + if (L"SnapAngle" == sName) + { + CSnapAngle* pItem = new CSnapAngle(); + *pItem = oReader; + + if (pItem) + m_arrItems.push_back(pItem); + } + } + } + EElementType CSnapAngles::getType() const + { + return et_dr_SnapAngles; + } + void CSnapAngles::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + m_arrItems.push_back(new CSnapAngle()); + m_arrItems.back()->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + } + void CSnapAngles::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + for (size_t i = 0; i < m_arrItems.size(); ++i) + pWriter->WriteRecord2(0, dynamic_cast(m_arrItems[i])); + } + void CSnapAngles::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"SnapAngles"); + pWriter->EndAttributes(); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"SnapAngles"); + } +//----------------------------------------------------------------------------------------------------------------------------- + EElementType CWindow::getType() const + { + return et_dr_Window; + } + void CWindow::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "ID", ID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "WindowType", WindowType) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "WindowState", WindowState) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "WindowLeft", WindowLeft) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "WindowTop", WindowTop) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "WindowWidth", WindowWidth) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "WindowHeight", WindowHeight) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ContainerType", ContainerType) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Container", Container) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Page", Page) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Sheet", Sheet) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ViewScale", ViewScale) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ViewCenterX", ViewCenterX) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ViewCenterY", ViewCenterY) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Document", Document) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ParentWindow", ParentWindow) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ReadOnly", ReadOnly) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CWindow::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + if (L"ShowRulers" == sName) + { + ShowRulers = oReader.GetText2(); + } + else if (L"ShowGrid" == sName) + { + ShowGrid = oReader.GetText2(); + } + else if (L"ShowPageBreaks" == sName) + { + ShowPageBreaks = oReader.GetText2(); + } + else if (L"GlueSettings" == sName) + { + GlueSettings = oReader.GetText2(); + } + else if (L"ShowGuides" == sName) + { + ShowGuides = oReader.GetText2(); + } + else if (L"ShowConnectionPoints" == sName) + { + ShowConnectionPoints = oReader.GetText2(); + } + else if (L"SnapSettings" == sName) + { + SnapSettings = oReader.GetText2(); + } + else if (L"SnapExtensions" == sName) + { + SnapExtensions = oReader.GetText2(); + } + else if (L"SnapAngles" == sName) + { + SnapAngles = oReader; + } + else if (L"DynamicGridEnabled" == sName) + { + DynamicGridEnabled = oReader.GetText2(); + } + else if (L"TabSplitterPos" == sName) + { + TabSplitterPos = oReader.GetText2(); + } + else if (L"StencilGroup" == sName) + { + StencilGroup = oReader.GetText2(); + } + else if (L"StencilGroupPos" == sName) + { + StencilGroupPos = oReader.GetText2(); + } + } + + } + void CWindow::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, ID); + if (WindowType.IsInit()) pWriter->WriteByte1(1, WindowType->GetValue()); + pWriter->WriteUInt2(2, WindowState); + pWriter->WriteInt2(3, WindowLeft); + pWriter->WriteInt2(4, WindowTop); + pWriter->WriteUInt2(5, WindowWidth); + pWriter->WriteUInt2(6, WindowHeight); + if (ContainerType.IsInit()) pWriter->WriteByte1(7, ContainerType->GetValue()); + pWriter->WriteUInt2(8, Container); + pWriter->WriteUInt2(9, Page); + pWriter->WriteUInt2(10, Sheet); + pWriter->WriteDoubleReal2(11, ViewScale); + pWriter->WriteDoubleReal2(12, ViewCenterX); + pWriter->WriteDoubleReal2(13, ViewCenterY); + pWriter->WriteString2(14, Document); + pWriter->WriteUInt2(15, ParentWindow); + pWriter->WriteBool2(16, ReadOnly); + pWriter->WriteBool2(17, ShowRulers); + pWriter->WriteBool2(18, ShowGrid); + pWriter->WriteBool2(19, ShowPageBreaks); + pWriter->WriteBool2(20, ShowGuides); + pWriter->WriteBool2(21, ShowConnectionPoints); + pWriter->WriteUInt2(22, GlueSettings); + pWriter->WriteUInt2(23, SnapSettings); + pWriter->WriteUInt2(24, SnapExtensions); + pWriter->WriteBool2(26, DynamicGridEnabled); + pWriter->WriteDoubleReal2(27, TabSplitterPos); + pWriter->WriteUInt2(28, StencilGroup); + pWriter->WriteUInt2(29, StencilGroupPos); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + pWriter->WriteRecord2(0, SnapAngles); + } + + void CWindow::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + ID = pReader->GetULong(); + }break; + case 1: + { + WindowType.Init(); WindowType->SetValueFromByte(pReader->GetUChar()); + }break; + case 2: + { + WindowState = pReader->GetULong(); + }break; + case 3: + { + WindowLeft = pReader->GetLong(); + }break; + case 4: + { + WindowTop = pReader->GetLong(); + }break; + case 5: + { + WindowWidth = pReader->GetULong(); + }break; + case 6: + { + WindowHeight = pReader->GetULong(); + }break; + case 7: + { + ContainerType.Init(); ContainerType->SetValueFromByte(pReader->GetUChar()); + }break; + case 8: + { + Container = pReader->GetULong(); + }break; + case 9: + { + Page = pReader->GetULong(); + }break; + case 10: + { + Sheet = pReader->GetULong(); + }break; + case 11: + { + ViewScale = pReader->GetDoubleReal(); + }break; + case 12: + { + ViewCenterX = pReader->GetDoubleReal(); + }break; + case 13: + { + ViewCenterY = pReader->GetDoubleReal(); + }break; + case 14: + { + Document = pReader->GetString2(); + }break; + case 15: + { + ParentWindow = pReader->GetULong(); + }break; + case 16: + { + ReadOnly = pReader->GetBool(); + }break; + case 17: + { + ShowRulers = pReader->GetBool(); + }break; + case 18: + { + ShowGrid = pReader->GetBool(); + }break; + case 19: + { + ShowPageBreaks = pReader->GetBool(); + }break; + case 20: + { + ShowGuides = pReader->GetBool(); + }break; + case 21: + { + ShowConnectionPoints = pReader->GetBool(); + }break; + case 22: + { + GlueSettings = pReader->GetULong(); + }break; + case 23: + { + SnapSettings = pReader->GetULong(); + }break; + case 24: + { + SnapExtensions = pReader->GetULong(); + }break; + case 26: + { + DynamicGridEnabled = pReader->GetBool(); + }break; + case 27: + { + TabSplitterPos = pReader->GetDoubleReal(); + }break; + case 28: + { + StencilGroup = pReader->GetULong(); + }break; + case 29: + { + StencilGroupPos = pReader->GetULong(); + }break; + } + } + while (pReader->GetPos() < _end_rec) + { + BYTE _rec = pReader->GetUChar(); + + switch (_rec) + { + case 0: + { + SnapAngles.Init(); + SnapAngles->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CWindow::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"Window"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"ID", ID); + if (WindowType.IsInit()) + pWriter->WriteAttribute2(L"WindowType", WindowType->ToString()); + pWriter->WriteAttribute2(L"WindowState", WindowState); + pWriter->WriteAttribute(L"WindowLeft", WindowLeft); + pWriter->WriteAttribute(L"WindowTop", WindowTop); + pWriter->WriteAttribute2(L"WindowWidth", WindowWidth); + pWriter->WriteAttribute2(L"WindowHeight", WindowHeight); + if (ContainerType.IsInit()) + pWriter->WriteAttribute2(L"ContainerType", ContainerType->ToString()); + pWriter->WriteAttribute2(L"Container", Container); + pWriter->WriteAttribute2(L"Page", Page); + pWriter->WriteAttribute2(L"Sheet", Sheet); + pWriter->WriteAttribute(L"ViewScale", ViewScale); + pWriter->WriteAttribute(L"ViewCenterX", ViewCenterX); + pWriter->WriteAttribute(L"ViewCenterY", ViewCenterY); + pWriter->WriteAttribute2(L"Document", Document); + pWriter->WriteAttribute2(L"ParentWindow", ParentWindow); + pWriter->WriteAttribute(L"ReadOnly", ReadOnly); + pWriter->EndAttributes(); + + pWriter->WriteNodeValue(L"ShowRulers", ShowRulers); + pWriter->WriteNodeValue(L"ShowGrid", ShowGrid); + pWriter->WriteNodeValue(L"ShowPageBreaks", ShowPageBreaks); + pWriter->WriteNodeValue(L"ShowGuides", ShowGuides); + pWriter->WriteNodeValue(L"ShowConnectionPoints", ShowConnectionPoints); + pWriter->WriteNodeValue(L"GlueSettings", GlueSettings); + pWriter->WriteNodeValue(L"SnapSettings", SnapSettings); + pWriter->WriteNodeValue(L"SnapExtensions", SnapExtensions); + pWriter->WriteNodeValue(L"DynamicGridEnabled", DynamicGridEnabled); + pWriter->WriteNodeValue(L"TabSplitterPos", TabSplitterPos); + pWriter->WriteNodeValue(L"StencilGroup", StencilGroup); + pWriter->WriteNodeValue(L"StencilGroupPos", StencilGroupPos); + + if (SnapAngles.IsInit()) + SnapAngles->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"Window"); + } +//----------------------------------------------------------------------------------------------------------------------------- + void CWindows::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + if (L"Window" == sName) + { + CWindow* pItem = new CWindow(); + *pItem = oReader; + + if (pItem) + m_arrItems.push_back(pItem); + } + } + } + void CWindows::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "ClientWidth", ClientWidth) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ClientHeight", ClientHeight) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + EElementType CWindows::getType() const + { + return et_dr_Windows; + } + void CWindows::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + ClientWidth = pReader->GetULong(); + }break; + case 1: + { + ClientHeight = pReader->GetULong(); + }break; + } + } + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + m_arrItems.push_back(new CWindow()); + m_arrItems.back()->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + } + void CWindows::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, ClientWidth); + pWriter->WriteUInt2(1, ClientHeight); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + pWriter->WriteRecord2(0, dynamic_cast(m_arrItems[i])); + } + void CWindows::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"Windows"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"xmlns", L"http://schemas.microsoft.com/office/visio/2012/main"); + pWriter->WriteAttribute2(L"xmlns:r", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships"); + pWriter->WriteAttribute2(L"xml:space", L"preserve"); + pWriter->WriteAttribute2(L"ClientWidth", ClientWidth); + pWriter->WriteAttribute2(L"ClientHeight", ClientHeight); + pWriter->EndAttributes(); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"Windows"); + } +//----------------------------------------------------------------------------------------------------------------------------- + OOX::Draw::CWindowsFile::CWindowsFile(OOX::Document* pMain) : OOX::File(pMain) + { + } + OOX::Draw::CWindowsFile::CWindowsFile(OOX::Document* pMain, const CPath& uri) : OOX::File(pMain) + { + read(uri.GetDirectory(), uri); + } + OOX::Draw::CWindowsFile::CWindowsFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::File(pMain) + { + read(oRootPath, oPath); + } + OOX::Draw::CWindowsFile::~CWindowsFile() + { + } + void OOX::Draw::CWindowsFile::read(const CPath& oFilePath) + { + CPath oRootPath; + read(oRootPath, oFilePath); + } + void OOX::Draw::CWindowsFile::read(const CPath& oRootPath, const CPath& oFilePath) + { + XmlUtils::CXmlLiteReader oReader; + + if (!oReader.FromFile(oFilePath.GetPath())) + return; + + if (!oReader.ReadNextNode()) + return; + + m_strFilename = oFilePath.GetPath(); + + Windows = oReader; + } + void OOX::Draw::CWindowsFile::write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const + { + NSBinPptxRW::CXmlWriter oXmlWriter; + oXmlWriter.WriteString((L"")); + + oXmlWriter.m_lDocType = XMLWRITER_DOC_TYPE_VSDX; + toXmlWriter(&oXmlWriter); + + NSFile::CFileBinary::SaveToFile(oFilePath.GetPath(), oXmlWriter.GetXmlString()); + + oContent.Registration(type().OverrideType(), oDirectory, oFilePath.GetFilename()); + } + const OOX::FileType OOX::Draw::CWindowsFile::type() const + { + return FileTypes::Windows; + } + const OOX::CPath OOX::Draw::CWindowsFile::DefaultDirectory() const + { + return type().DefaultDirectory(); + } + const OOX::CPath OOX::Draw::CWindowsFile::DefaultFileName() const + { + return type().DefaultFileName(); + } + void OOX::Draw::CWindowsFile::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + + switch (_rec) + { + case 0: + { + Windows.Init(); + Windows->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + } + void OOX::Draw::CWindowsFile::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteRecord2(0, Windows); + } + void OOX::Draw::CWindowsFile::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + if (Windows.IsInit()) + Windows->toXmlWriter(pWriter); + } +} +} // namespace OOX diff --git a/OOXML/VsdxFormat/VisioDocument.h b/OOXML/VsdxFormat/VisioDocument.h new file mode 100644 index 0000000000..e977d3a8af --- /dev/null +++ b/OOXML/VsdxFormat/VisioDocument.h @@ -0,0 +1,574 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../Base/Nullable.h" + +#include "FileTypes_Draw.h" +#include "../DocxFormat/IFileContainer.h" +#include "../Common/SimpleTypes_Draw.h" + +namespace OOX +{ + namespace Draw + { + class CPublishedPage : public WritingElement + { + public: + WritingElement_AdditionMethods(CPublishedPage) + + CPublishedPage() {} + virtual ~CPublishedPage() {} + + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + public: + nullable_uint ID; + }; + class CRefreshableData : public WritingElement + { + public: + WritingElement_AdditionMethods(CRefreshableData) + + CRefreshableData() {} + virtual ~CRefreshableData() {} + + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + public: + nullable_uint ID; + }; + class CPublishSettings : public WritingElementWithChilds<> + { + public: + WritingElement_AdditionMethods(CPublishSettings) + CPublishSettings() {} + virtual ~CPublishSettings() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + }; + class CDocumentSettings : public WritingElement + { + public: + WritingElement_AdditionMethods(CDocumentSettings) + CDocumentSettings(){} + virtual ~CDocumentSettings(){} + + virtual void fromXML(XmlUtils::CXmlNode& node){} + virtual std::wstring toXML() const{return L"";} + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_uint TopPage; + nullable_uint DefaultTextStyle; + nullable_uint DefaultLineStyle; + nullable_uint DefaultFillStyle; + nullable_uint DefaultGuideStyle; + + nullable_int GlueSettings; + nullable_int SnapSettings; + nullable_int SnapExtensions; + nullable_int SnapAngles; + nullable_bool DynamicGridEnabled; + nullable_bool ProtectStyles; + nullable_bool ProtectShapes; + nullable_bool ProtectBkgnds; + nullable_bool ProtectMasters; + nullable_string CustomMenusFile; + nullable_string CustomToolbarsFile; + nullable_string AttachedToolbars; //base64 + }; + class CColorEntry : public WritingElement + { + public: + WritingElement_AdditionMethods(CColorEntry) + + CColorEntry() {} + virtual ~CColorEntry() {} + + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + public: + nullable_uint IX; + nullable_string RGB; + }; + class CColors : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CColors) + + CColors() {} + virtual ~CColors() {} + + virtual std::wstring toXML() const { return L""; } + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + }; + class CFaceName : public WritingElement + { + public: + WritingElement_AdditionMethods(CFaceName) + + CFaceName() {} + virtual ~CFaceName() {} + + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + public: + nullable_string NameU; + nullable_string UnicodeRanges; + nullable_string CharSets; + nullable_string Panos; + nullable_string Panose; + nullable_uint Flags; + }; + class CFaceNames : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CFaceNames) + + CFaceNames() {} + virtual ~CFaceNames() {} + + virtual std::wstring toXML() const { return L""; } + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + }; + class CStyleSheet : public WritingElementWithChilds<> + { + public: + WritingElement_AdditionMethods(CStyleSheet) + CStyleSheet() {} + virtual ~CStyleSheet() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_uint ID; + nullable_string NameU; + nullable_string Name; + nullable_bool IsCustomName; + nullable_bool IsCustomNameU; + nullable_uint LineStyle; + nullable_uint FillStyle; + nullable_uint TextStyle; + }; + class CStyleSheets : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CStyleSheets) + + CStyleSheets() {} + virtual ~CStyleSheets() {} + + virtual std::wstring toXML() const { return L""; } + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + }; + class CDocumentSheet : public WritingElementWithChilds<> + { + public: + WritingElement_AdditionMethods(CDocumentSheet) + CDocumentSheet() {} + virtual ~CDocumentSheet() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_string Name; + nullable_string NameU; + nullable_bool IsCustomName; + nullable_bool IsCustomNameU; + nullable_string UniqueID; + nullable_uint LineStyle; + nullable_uint FillStyle; + nullable_uint TextStyle; + }; + class CEventItem : public WritingElement + { + public: + WritingElement_AdditionMethods(CEventItem) + + CEventItem() {} + virtual ~CEventItem() {} + + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + public: + nullable_uint ID; + nullable_uint Action; + nullable_uint EventCode; + nullable_bool Enabled; + nullable_string Target; + nullable_string TargetArgs; + }; + class CEventList : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CEventList) + CEventList() {} + virtual ~CEventList() {} + + virtual std::wstring toXML() const { return L""; } + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + }; + class CHeaderFooter : public WritingElement + { + public: + WritingElement_AdditionMethods(CHeaderFooter) + CHeaderFooter() {} + virtual ~CHeaderFooter() {} + + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + public: + nullable_string HeaderMargin; + nullable_string FooterMargin; + nullable_string HeaderLeft; + nullable_string HeaderCenter; + nullable_string HeaderRight; + nullable_string FooterLeft; + nullable_string FooterCenter; + nullable_string FooterRight; + + //nullable HeaderFooterFont; + nullable_string HeaderFooterColor; + + }; + class CSnapAngle : public WritingElement + { + public: + WritingElement_AdditionMethods(CSnapAngle) + + CSnapAngle() {} + virtual ~CSnapAngle() {} + + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + public: + nullable_double content; + }; + class CSnapAngles : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CSnapAngles) + CSnapAngles() {} + virtual ~CSnapAngles() {} + + virtual std::wstring toXML() const { return L""; } + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + }; + class CWindow : public WritingElement + { + public: + WritingElement_AdditionMethods(CWindow) + CWindow() {} + virtual ~CWindow() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_uint ID; + nullable WindowType; + nullable_uint WindowState; + nullable_int WindowLeft; + nullable_int WindowTop; + nullable_uint WindowWidth; + nullable_uint WindowHeight; + nullable ContainerType; + nullable_uint Container; + nullable_uint Page; + nullable_uint Sheet; + nullable_double ViewScale; + nullable_double ViewCenterX; + nullable_double ViewCenterY; + nullable_string Document; + nullable_uint ParentWindow; + nullable_bool ReadOnly; + + nullable_bool ShowRulers; + nullable_bool ShowGrid; + nullable_bool ShowPageBreaks; + nullable_bool ShowGuides; + nullable_bool ShowConnectionPoints; + nullable_uint GlueSettings; + nullable_uint SnapSettings; + nullable_uint SnapExtensions; + nullable_bool DynamicGridEnabled; + nullable_double TabSplitterPos; + nullable_uint StencilGroup; + nullable_uint StencilGroupPos; + + nullable SnapAngles; + }; + class CWindows : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CWindows) + CWindows() {} + virtual ~CWindows() {} + + virtual std::wstring toXML() const { return L""; } + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + + nullable_uint ClientWidth; + nullable_uint ClientHeight; + }; + class CDocumentFile : public OOX::IFileContainer, public OOX::File + { + public: + CDocumentFile(OOX::Document* pMain); + CDocumentFile(OOX::Document* pMain, const CPath& uri); + CDocumentFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); + virtual ~CDocumentFile(); + + virtual void read(const CPath& oFilePath); + virtual void read(const CPath& oRootPath, const CPath& oFilePath); + virtual void write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const; + + virtual const OOX::FileType type() const; + + virtual const CPath DefaultDirectory() const; + virtual const CPath DefaultFileName() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + std::wstring m_strFilename; + bool m_bMacroEnabled; + + nullable DocumentSettings; + nullable Colors; + nullable FaceNames; + nullable StyleSheets; + nullable DocumentSheet; + nullable EventList; + nullable HeaderFooter; + nullable PublishSettings; + }; + class CWindowsFile : public OOX::File + { + public: + CWindowsFile(OOX::Document* pMain); + CWindowsFile(OOX::Document* pMain, const CPath& uri); + CWindowsFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); + virtual ~CWindowsFile(); + + virtual void read(const CPath& oFilePath); + virtual void read(const CPath& oRootPath, const CPath& oFilePath); + virtual void write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const; + + virtual const OOX::FileType type() const; + + virtual const CPath DefaultDirectory() const; + virtual const CPath DefaultFileName() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + std::wstring m_strFilename; + + nullable Windows; + }; + + + } //Draw +} // namespace OOX diff --git a/OOXML/VsdxFormat/VisioOthers.cpp b/OOXML/VsdxFormat/VisioOthers.cpp new file mode 100644 index 0000000000..844fac6da0 --- /dev/null +++ b/OOXML/VsdxFormat/VisioOthers.cpp @@ -0,0 +1,1768 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "VisioOthers.h" +#include "Shapes.h" +#include "../../DesktopEditor/common/SystemUtils.h" +#include "../Binary/Presentation/BinaryFileReaderWriter.h" +#include "../Binary/Presentation/XmlWriter.h" + +namespace OOX +{ +namespace Draw +{ + CSolutionFile::CSolutionFile(OOX::Document* pMain) : OOX::File(pMain) + { + } + CSolutionFile::CSolutionFile(OOX::Document* pMain, const CPath& uri) : OOX::File(pMain) + { + read(uri.GetDirectory(), uri); + } + CSolutionFile::CSolutionFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::File(pMain) + { + read(oRootPath, oPath); + } + CSolutionFile::~CSolutionFile() + { + } + void CSolutionFile::read(const CPath& oFilePath) + { + CPath oRootPath; + read(oRootPath, oFilePath); + } + void CSolutionFile::read(const CPath& oRootPath, const CPath& oFilePath) + { + NSFile::CFileBinary::ReadAllTextUtf8A(oFilePath.GetPath(), m_sXmlA); + } + void CSolutionFile::write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const + { + NSFile::CFileBinary oFile; + if (true == oFile.CreateFileW(oFilePath.GetPath())) + { + if (false == m_sXmlA.empty()) + oFile.WriteFile((BYTE*)m_sXmlA.c_str(), m_sXmlA.length()); + oFile.CloseFile(); + } + oContent.Registration(type().OverrideType(), oDirectory, oFilePath.GetFilename()); + } + const OOX::FileType CSolutionFile::type() const + { + return FileTypes::Solution; + } + const OOX::CPath CSolutionFile::DefaultDirectory() const + { + return type().DefaultDirectory(); + } + const OOX::CPath CSolutionFile::DefaultFileName() const + { + return type().DefaultFileName(); + } + void CSolutionFile::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + + switch (_rec) + { + case 0: + { + pReader->Skip(4); // len + m_sXmlA = pReader->GetString2A(); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + } + void CSolutionFile::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) + { + pWriter->StartRecord(0); + pWriter->WriteStringA(m_sXmlA); + pWriter->EndRecord(); + } +//----------------------------------------------------------------------------------------------------------------------------- + CSolutionsFile::CSolutionsFile(OOX::Document* pMain) : OOX::IFileContainer(pMain), OOX::File(pMain) + { + m_bVisioPages = true; + } + CSolutionsFile::CSolutionsFile(OOX::Document* pMain, const CPath& uri) : OOX::IFileContainer(pMain), OOX::File(pMain) + { + m_bVisioPages = true; + read(uri.GetDirectory(), uri); + } + CSolutionsFile::CSolutionsFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::IFileContainer(pMain), OOX::File(pMain) + { + m_bVisioPages = true; + + read(oRootPath, oPath); + } + CSolutionsFile::~CSolutionsFile() + { + } + void CSolutionsFile::read(const CPath& oFilePath) + { + CPath oRootPath; + read(oRootPath, oFilePath); + } + void CSolutionsFile::read(const CPath& oRootPath, const CPath& oFilePath) + { + IFileContainer::Read(oRootPath, oFilePath); + + XmlUtils::CXmlLiteReader oReader; + + if (!oReader.FromFile(oFilePath.GetPath())) + return; + + if (!oReader.ReadNextNode()) + return; + + m_strFilename = oFilePath.GetPath(); + + Solutions = oReader; + } + void CSolutionsFile::write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const + { + NSBinPptxRW::CXmlWriter oXmlWriter; + oXmlWriter.WriteString((L"")); + + oXmlWriter.m_lDocType = XMLWRITER_DOC_TYPE_VSDX; + toXmlWriter(&oXmlWriter); + + NSFile::CFileBinary::SaveToFile(oFilePath.GetPath(), oXmlWriter.GetXmlString()); + + oContent.Registration(type().OverrideType(), oDirectory, oFilePath.GetFilename()); + IFileContainer::Write(oFilePath, oDirectory, oContent); + } + const OOX::FileType CSolutionsFile::type() const + { + return FileTypes::Solutions; + } + const OOX::CPath CSolutionsFile::DefaultDirectory() const + { + return type().DefaultDirectory(); + } + const OOX::CPath CSolutionsFile::DefaultFileName() const + { + return type().DefaultFileName(); + } + void CSolutionsFile::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + smart_ptr rels_old = pReader->GetRels(); + pReader->SetRels(dynamic_cast((CSolutionsFile*)this)); + + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + + switch (_rec) + { + case 0: + { + Solutions.Init(); + Solutions->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + pReader->SetRels(rels_old); + } + void CSolutionsFile::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + smart_ptr rels_old = pWriter->GetRels(); + pWriter->SetRels(dynamic_cast((CSolutionsFile*)this)); + + pWriter->WriteRecord2(0, Solutions); + + pWriter->SetRels(rels_old); + } + void CSolutionsFile::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + if (Solutions.IsInit()) + Solutions->toXmlWriter(pWriter); + } +//----------------------------------------------------------------------------------------------------------------------------- + EElementType CSolution::getType() const + { + return et_dr_Solution; + } + void CSolution::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "Name", Name) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CSolution::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + const char* sName = XmlUtils::GetNameNoNS(oReader.GetNameChar()); + if (strcmp("Rel", sName) == 0) + { + Rel = oReader; + } + } + } + void CSolution::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteString2(0, Name); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + if (Rel.IsInit() && Rel->Rid.IsInit()) + { + smart_ptr pFile = pWriter->GetRels()->Find(Rel->Rid->GetValue()); + CSolutionFile* pSolution = dynamic_cast(pFile.GetPointer()); + if (pSolution) + { + pWriter->StartRecord(0); + pSolution->toPPTY(pWriter); + pWriter->EndRecord(); + } + } + } + void CSolution::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + Name = pReader->GetString2(); + }break; + } + } + while (pReader->GetPos() < _end_rec) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + CSolutionFile* pSolution = new CSolutionFile(NULL); + pSolution->fromPPTY(pReader); + smart_ptr oFile(pSolution); + + Rel.Init(); Rel->Rid.Init(); + Rel->Rid->SetValue(pReader->GetRels()->Add(oFile).get()); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CSolution::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"Solution"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"Name", Name); + pWriter->EndAttributes(); + + if (Rel.IsInit()) + Rel->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"Solution"); + } +//----------------------------------------------------------------------------------------------------------------------------- + void CSolutions::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + if (L"Solution" == sName) + { + CSolution* pItem = new CSolution(); + *pItem = oReader; + + if (pItem) + m_arrItems.push_back(pItem); + } + } + } + EElementType CSolutions::getType() const + { + return et_dr_Solutions; + } + void CSolutions::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + m_arrItems.push_back(new CSolution()); + m_arrItems.back()->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + } + void CSolutions::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + for (size_t i = 0; i < m_arrItems.size(); ++i) + pWriter->WriteRecord2(0, dynamic_cast(m_arrItems[i])); + } + void CSolutions::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"Solutions"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"xmlns", L"http://schemas.microsoft.com/office/visio/2012/main"); + pWriter->WriteAttribute2(L"xmlns:r", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships"); + pWriter->WriteAttribute2(L"xml:space", L"preserve"); + pWriter->EndAttributes(); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"Solutions"); + } +//----------------------------------------------------------------------------------------------------------------------------------------- + CValidationFile::CValidationFile(OOX::Document* pMain) : OOX::File(pMain) + { + } + CValidationFile::CValidationFile(OOX::Document* pMain, const CPath& uri) : OOX::File(pMain) + { + read(uri.GetDirectory(), uri); + } + CValidationFile::CValidationFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::File(pMain) + { + read(oRootPath, oPath); + } + CValidationFile::~CValidationFile() + { + } + void CValidationFile::read(const CPath& oFilePath) + { + CPath oRootPath; + read(oRootPath, oFilePath); + } + void CValidationFile::read(const CPath& oRootPath, const CPath& oFilePath) + { + XmlUtils::CXmlLiteReader oReader; + + if (!oReader.FromFile(oFilePath.GetPath())) + return; + + if (!oReader.ReadNextNode()) + return; + + m_strFilename = oFilePath.GetPath(); + + std::wstring sName = oReader.GetName(); + if (L"Validation" == sName && !oReader.IsEmptyNode()) + { + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + if (L"ValidationProperties" == sName) + { + ValidationProperties = oReader; + } + else if (L"RuleSets" == sName) + { + RuleSets = oReader; + } + else if (L"Issues" == sName) + { + Issues = oReader; + } + } + } + } + void CValidationFile::write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const + { + NSBinPptxRW::CXmlWriter oXmlWriter; + oXmlWriter.WriteString((L"")); + + oXmlWriter.m_lDocType = XMLWRITER_DOC_TYPE_VSDX; + toXmlWriter(&oXmlWriter); + + NSFile::CFileBinary::SaveToFile(oFilePath.GetPath(), oXmlWriter.GetXmlString()); + + oContent.Registration(type().OverrideType(), oDirectory, oFilePath.GetFilename()); + } + void CValidationFile::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"Validation"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"xmlns", L"http://schemas.microsoft.com/office/visio/2012/main"); + pWriter->WriteAttribute2(L"xmlns:r", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships"); + pWriter->WriteAttribute2(L"xml:space", L"preserve"); + pWriter->EndAttributes(); + + if (ValidationProperties.IsInit()) + ValidationProperties->toXmlWriter(pWriter); + + if (RuleSets.IsInit()) + RuleSets->toXmlWriter(pWriter); + + if (Issues.IsInit()) + Issues->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"Validation"); + } + const OOX::FileType CValidationFile::type() const + { + return FileTypes::Validation; + } + const OOX::CPath CValidationFile::DefaultDirectory() const + { + return type().DefaultDirectory(); + } + const OOX::CPath CValidationFile::DefaultFileName() const + { + return type().DefaultFileName(); + } + void CValidationFile::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + + while (pReader->GetPos() < _end_rec) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + ValidationProperties.Init(); + ValidationProperties->fromPPTY(pReader); + }break; + case 1: + { + RuleSets.Init(); + RuleSets->fromPPTY(pReader); + }break; + case 2: + { + Issues.Init(); + Issues->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CValidationFile::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) + { + pWriter->WriteRecord2(0, ValidationProperties); + pWriter->WriteRecord2(1, RuleSets); + pWriter->WriteRecord2(2, Issues); + + + } +//----------------------------------------------------------------------------------------------------------------------------- + EElementType CIssue::getType() const + { + return et_dr_Issue; + } + void CIssue::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "ID", ID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Ignored", Ignored) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CIssue::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + if (L"IssueTarget" == sName) + { + IssueTarget = oReader; + } + else if (L"RuleInfo" == sName) + { + RuleInfo = oReader; + } + } + } + void CIssue::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, ID); + pWriter->WriteBool2(1, Ignored); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + pWriter->WriteRecord2(0, IssueTarget); + pWriter->WriteRecord2(1, RuleInfo); + } + void CIssue::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + ID = pReader->GetULong(); + }break; + case 1: + { + Ignored = pReader->GetBool(); + }break; + } + } + while (pReader->GetPos() < _end_rec) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + IssueTarget.Init(); + IssueTarget->fromPPTY(pReader); + }break; + case 1: + { + RuleInfo.Init(); + RuleInfo->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CIssue::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"Issue"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"ID", ID); + pWriter->WriteAttribute(L"Ignored", Ignored); + pWriter->EndAttributes(); + + if (IssueTarget.IsInit()) + IssueTarget->toXmlWriter(pWriter); + + if (RuleInfo.IsInit()) + RuleInfo->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"Issue"); + } + EElementType CIssues::getType() const + { + return et_dr_Issues; + } + void CIssues::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + if (L"Issue" == sName) + { + CIssue* pItem = new CIssue(); + *pItem = oReader; + + if (pItem) + m_arrItems.push_back(pItem); + } + } + } + void CIssues::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + m_arrItems.push_back(new CIssue()); + m_arrItems.back()->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + } + void CIssues::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + for (size_t i = 0; i < m_arrItems.size(); ++i) + pWriter->WriteRecord2(0, dynamic_cast(m_arrItems[i])); + } + void CIssues::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"Issues"); + pWriter->EndAttributes(); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"Issues"); + } +//----------------------------------------------------------------------------------------------------------------------------- + EElementType CRule::getType() const + { + return et_dr_Rule; + } + void CRule::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "ID", ID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Category", Category) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "NameU", NameU) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Description", Description) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Ignored", Ignored) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "RuleTarget", RuleTarget) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CRule::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + if (L"RuleFilter" == sName) + { + RuleFilter = oReader; + } + else if(L"RuleTest" == sName) + { + RuleTest = oReader; + } + } + } + void CRule::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, ID); + pWriter->WriteString2(1, Category); + pWriter->WriteString2(2, NameU); + pWriter->WriteBool2(3, Ignored); + pWriter->WriteString2(4, Description); + pWriter->WriteInt2(5, RuleTarget); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + pWriter->WriteRecord2(0, RuleFilter); + pWriter->WriteRecord2(1, RuleTest); + } + void CRule::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + ID = pReader->GetULong(); + }break; + case 1: + { + Category = pReader->GetString2(); + }break; + case 2: + { + NameU = pReader->GetString2(); + }break; + case 3: + { + Ignored = pReader->GetBool(); + }break; + case 4: + { + Description = pReader->GetString2(); + }break; + case 5: + { + RuleTarget = pReader->GetLong(); + }break; + } + } + while (pReader->GetPos() < _end_rec) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + RuleFilter.Init(); + RuleFilter->node_name = L"RuleFilter"; + RuleFilter->fromPPTY(pReader); + }break; + case 1: + { + RuleTest.Init(); + RuleFilter->node_name = L"RuleTest"; + RuleTest->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CRule::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"Rule"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"ID", ID); + pWriter->WriteAttribute2(L"Category", Category); + pWriter->WriteAttribute2(L"NameU", NameU); + pWriter->WriteAttribute2(L"Description", Description); + pWriter->WriteAttribute(L"Ignored", Ignored); + pWriter->WriteAttribute(L"RuleTarget", RuleTarget); + pWriter->EndAttributes(); + + if (RuleFilter.IsInit()) + RuleFilter->toXmlWriter(pWriter); + + if (RuleTest.IsInit()) + RuleTest->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"Rule"); + } +//----------------------------------------------------------------------------------------------------------------------------- + EElementType CRuleSet::getType() const + { + return et_dr_RuleSet; + } + void CRuleSet::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "ID", ID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "NameU", NameU) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Name", Name) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Description", Description) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Enabled", Enabled) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CRuleSet::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + if (L"RuleSetFlags" == sName) + { + RuleSetFlags = oReader; + } + else if (L"Rule" == sName) + { + CRule* pItem = new CRule(); + + if (pItem) + { + pItem->fromXML(oReader); + m_arrItems.push_back(pItem); + } + } + } + } + void CRuleSet::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, ID); + pWriter->WriteString2(1, NameU); + pWriter->WriteString2(2, Name); + pWriter->WriteString2(3, Description); + pWriter->WriteBool2(4, Enabled); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + pWriter->WriteRecord2(0, RuleSetFlags); + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + pWriter->WriteRecord2(1, dynamic_cast(m_arrItems[i])); + } + } + void CRuleSet::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + ID = pReader->GetULong(); + }break; + case 1: + { + NameU = pReader->GetString2(); + }break; + case 2: + { + Name = pReader->GetString2(); + }break; + case 3: + { + Description = pReader->GetString2(); + }break; + case 8: + { + Enabled = pReader->GetBool(); + }break; + } + } + while (pReader->GetPos() < _end_rec) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + RuleSetFlags.Init(); + RuleSetFlags->fromPPTY(pReader); + }break; + case 1: + { + m_arrItems.push_back(new CRule()); + m_arrItems.back()->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CRuleSet::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"RuleSet"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"ID", ID); + pWriter->WriteAttribute2(L"NameU", NameU); + pWriter->WriteAttribute2(L"Name", Name); + pWriter->WriteAttribute2(L"Description", Description); + pWriter->WriteAttribute(L"Enabled", Enabled); + pWriter->EndAttributes(); + + if (RuleSetFlags.IsInit()) + RuleSetFlags->toXmlWriter(pWriter); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"RuleSet"); + } + EElementType CRuleSets::getType() const + { + return et_dr_RuleSets; + } + void CRuleSets::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + if (L"RuleSet" == sName) + { + CRuleSet* pItem = new CRuleSet(); + *pItem = oReader; + + if (pItem) + m_arrItems.push_back(pItem); + } + } + } + void CRuleSets::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + m_arrItems.push_back(new CRuleSet()); + m_arrItems.back()->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + } + void CRuleSets::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + for (size_t i = 0; i < m_arrItems.size(); ++i) + pWriter->WriteRecord2(0, dynamic_cast(m_arrItems[i])); + } + void CRuleSets::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"RuleSets"); + pWriter->EndAttributes(); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"RuleSets"); + } + EElementType CValidationProperties::getType() const + { + return et_dr_ValidationProperties; + } + void CValidationProperties::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "ShowIgnored", ShowIgnored) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "LastValidated", LastValidated) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CValidationProperties::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + } + void CValidationProperties::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteBool2(0, ShowIgnored); + pWriter->WriteString2(1, LastValidated); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CValidationProperties::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + ShowIgnored = pReader->GetBool(); + }break; + case 1: + { + LastValidated = pReader->GetString2(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CValidationProperties::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"ValidationProperties"); + pWriter->StartAttributes(); + pWriter->WriteAttribute(L"ShowIgnored", ShowIgnored); + pWriter->WriteAttribute2(L"LastValidated", LastValidated); + pWriter->EndAttributes(); + pWriter->WriteNodeEnd(L"ValidationProperties"); + } + EElementType CIssueTarget::getType() const + { + return et_dr_IssueTarget; + } + void CIssueTarget::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "PageID", PageID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ShapeID", ShapeID) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CIssueTarget::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + } + void CIssueTarget::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, PageID); + pWriter->WriteUInt2(1, ShapeID); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CIssueTarget::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + PageID = pReader->GetULong(); + }break; + case 1: + { + ShapeID = pReader->GetULong(); + }break; + + } + } + pReader->Seek(_end_rec); + } + void CIssueTarget::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"IssueTarget"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"PageID", PageID); + pWriter->WriteAttribute2(L"ShapeID", ShapeID); + pWriter->EndAttributes(); + pWriter->WriteNodeEnd(L"IssueTarget"); + } + EElementType CRuleInfo::getType() const + { + return et_dr_RuleInfo; + } + void CRuleInfo::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "RuleID", RuleID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "RuleSetID", RuleSetID) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CRuleInfo::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + } + void CRuleInfo::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, RuleID); + pWriter->WriteUInt2(1, RuleSetID); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CRuleInfo::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + RuleID = pReader->GetULong(); + }break; + case 1: + { + RuleSetID = pReader->GetULong(); + }break; + + } + } + pReader->Seek(_end_rec); + } + void CRuleInfo::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"RuleInfo"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"RuleID", RuleID); + pWriter->WriteAttribute2(L"RuleSetID", RuleSetID); + pWriter->EndAttributes(); + pWriter->WriteNodeEnd(L"RuleInfo"); + } + EElementType CRuleFormula::getType() const + { + return et_dr_CRuleFormula; + } + void CRuleFormula::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "Formula", Formula) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CRuleFormula::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + } + void CRuleFormula::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteString2(0, Formula); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CRuleFormula::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + Formula = pReader->GetString2(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CRuleFormula::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) + { + if (node_name.empty()) node_name = L"RuleFilter"; + pWriter->StartNode(node_name); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"Formula", Formula); + pWriter->EndAttributes(); + pWriter->WriteNodeEnd(node_name); + } + EElementType CRuleSetFlags::getType() const + { + return et_dr_RuleSetFlags; + } + void CRuleSetFlags::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "Hidden", Hidden) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CRuleSetFlags::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + } + void CRuleSetFlags::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteBool2(0, Hidden); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CRuleSetFlags::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + Hidden = pReader->GetBool(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CRuleSetFlags::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"RuleSetFlags"); + pWriter->StartAttributes(); + pWriter->WriteAttribute(L"Hidden", Hidden); + pWriter->EndAttributes(); + pWriter->WriteNodeEnd(L"RuleSetFlags"); + } +//----------------------------------------------------------------------------------------------------------------------------- + CCommentsFile::CCommentsFile(OOX::Document* pMain) : OOX::File(pMain) + { + } + CCommentsFile::CCommentsFile(OOX::Document* pMain, const CPath& uri) : OOX::File(pMain) + { + read(uri.GetDirectory(), uri); + } + CCommentsFile::CCommentsFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::File(pMain) + { + read(oRootPath, oPath); + } + CCommentsFile::~CCommentsFile() + { + } + void CCommentsFile::read(const CPath& oFilePath) + { + CPath oRootPath; + read(oRootPath, oFilePath); + } + void CCommentsFile::read(const CPath& oRootPath, const CPath& oFilePath) + { + XmlUtils::CXmlLiteReader oReader; + + if (!oReader.FromFile(oFilePath.GetPath())) + return; + + if (!oReader.ReadNextNode()) + return; + + m_strFilename = oFilePath.GetPath(); + + Comments = oReader; + } + void CCommentsFile::write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const + { + NSBinPptxRW::CXmlWriter oXmlWriter; + oXmlWriter.WriteString((L"")); + + oXmlWriter.m_lDocType = XMLWRITER_DOC_TYPE_VSDX; + + if (Comments.IsInit()) + Comments->toXmlWriter(&oXmlWriter); + + NSFile::CFileBinary::SaveToFile(oFilePath.GetPath(), oXmlWriter.GetXmlString()); + + oContent.Registration(type().OverrideType(), oDirectory, oFilePath.GetFilename()); + } + const OOX::FileType CCommentsFile::type() const + { + return FileTypes::Comments; + } + const OOX::CPath CCommentsFile::DefaultDirectory() const + { + return type().DefaultDirectory(); + } + const OOX::CPath CCommentsFile::DefaultFileName() const + { + return type().DefaultFileName(); + } + void CCommentsFile::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + + switch (_rec) + { + case 0: + { + Comments.Init(); + Comments->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + } + void CCommentsFile::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + smart_ptr rels_old = pWriter->GetRels(); + pWriter->SetRels(dynamic_cast((CSolutionsFile*)this)); + + pWriter->WriteRecord2(0, Comments); + + pWriter->SetRels(rels_old); + } + void CCommentsFile::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + if (Comments.IsInit()) + Comments->toXmlWriter(pWriter); + } +//-------------------------------------------------------------------------------------------------------------- + EElementType CComments::getType() const + { + return et_dr_Comments; + } + void CComments::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "ShowCommentTags", ShowCommentTags) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CComments::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + const char* sName = XmlUtils::GetNameNoNS(oReader.GetNameChar()); + if (strcmp("AuthorList", sName) == 0) + { + AuthorList = oReader; + } + else if (strcmp("CommentList", sName) == 0) + { + CommentList = oReader; + } + } + } + void CComments::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteBool2(0, ShowCommentTags); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + pWriter->WriteRecord2(0, AuthorList); + pWriter->WriteRecord2(1, CommentList); + } + void CComments::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + ShowCommentTags = pReader->GetBool(); + }break; + } + } + while (pReader->GetPos() < _end_rec) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + AuthorList.Init(); + AuthorList->fromPPTY(pReader); + }break; + case 1: + { + CommentList.Init(); + CommentList->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CComments::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"Comments"); + pWriter->StartAttributes(); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"xmlns", L"http://schemas.microsoft.com/office/visio/2012/main"); + pWriter->WriteAttribute2(L"xmlns:r", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships"); + pWriter->WriteAttribute2(L"xml:space", L"preserve"); + pWriter->WriteAttribute(L"ShowCommentTags", ShowCommentTags); + pWriter->EndAttributes(); + + if (AuthorList.IsInit()) + AuthorList->toXmlWriter(pWriter); + + if (CommentList.IsInit()) + CommentList->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"Comments"); + } +//----------------------------------------------------------------------------------------------------------------- + EElementType CCommentList::getType() const + { + return et_dr_CommentList; + } + void CCommentList::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + if (L"CommentEntry" == sName) + { + CCommentEntry* pItem = new CCommentEntry(); + *pItem = oReader; + + if (pItem) + m_arrItems.push_back(pItem); + } + } + } + void CCommentList::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + m_arrItems.push_back(new CCommentEntry()); + m_arrItems.back()->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + } + void CCommentList::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + for (size_t i = 0; i < m_arrItems.size(); ++i) + pWriter->WriteRecord2(0, dynamic_cast(m_arrItems[i])); + } + void CCommentList::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"CommentList"); + pWriter->EndAttributes(); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"CommentList"); + } +//----------------------------------------------------------------------------------------------------------------------------- + EElementType CAuthorList::getType() const + { + return et_dr_AuthorList; + } + void CAuthorList::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + if (L"AuthorEntry" == sName) + { + CAuthorEntry* pItem = new CAuthorEntry(); + *pItem = oReader; + + if (pItem) + m_arrItems.push_back(pItem); + } + } + } + void CAuthorList::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + m_arrItems.push_back(new CAuthorEntry()); + m_arrItems.back()->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + } + void CAuthorList::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + for (size_t i = 0; i < m_arrItems.size(); ++i) + pWriter->WriteRecord2(0, dynamic_cast(m_arrItems[i])); + } + void CAuthorList::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"AuthorList"); + pWriter->EndAttributes(); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"AuthorList"); + } +//----------------------------------------------------------------------------------------------------------------------------- + EElementType CCommentEntry::getType() const + { + return et_dr_CommentEntry; + } + void CCommentEntry::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "AuthorID", AuthorID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "PageID", PageID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ShapeID", ShapeID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Date", Date) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "EditDate", EditDate) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Done", Done) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "CommentID", CommentID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "AutoCommentType", AutoCommentType) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CCommentEntry::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + content = oReader.GetText2(); + } + void CCommentEntry::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, AuthorID); + pWriter->WriteUInt2(1, PageID); + pWriter->WriteUInt2(2, ShapeID); + pWriter->WriteString2(3, Date); + pWriter->WriteString2(4, EditDate); + pWriter->WriteUInt2(5, CommentID); + pWriter->WriteUInt2(6, AutoCommentType); + pWriter->WriteString1(7, content); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CCommentEntry::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + AuthorID = pReader->GetULong(); + }break; + case 1: + { + PageID = pReader->GetULong(); + }break; + case 2: + { + ShapeID = pReader->GetULong(); + }break; + case 3: + { + Date = pReader->GetString2(); + }break; + case 4: + { + EditDate = pReader->GetString2(); + }break; + case 5: + { + CommentID = pReader->GetULong(); + }break; + case 6: + { + AutoCommentType = pReader->GetULong(); + }break; + case 7: + { + content = pReader->GetString2(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CCommentEntry::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"CommentEntry"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"AuthorID", AuthorID); + pWriter->WriteAttribute2(L"PageID", PageID); + pWriter->WriteAttribute2(L"ShapeID", ShapeID); + pWriter->WriteAttribute2(L"Date", Date); + pWriter->WriteAttribute2(L"EditDate", EditDate); + pWriter->WriteAttribute2(L"CommentID", CommentID); + pWriter->WriteAttribute2(L"AutoCommentType", AutoCommentType); + pWriter->EndAttributes(); + pWriter->WriteStringXML(content); + pWriter->WriteNodeEnd(L"CommentEntry"); + } +//----------------------------------------------------------------------------------------------------------------------------- + EElementType CAuthorEntry::getType() const + { + return et_dr_AuthorEntry; + } + void CAuthorEntry::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "ID", ID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Name", Name) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Initials", Initials) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ResolutionID", ResolutionID) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CAuthorEntry::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + } + void CAuthorEntry::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, ID); + pWriter->WriteString2(1, Name); + pWriter->WriteString2(2, Initials); + pWriter->WriteString2(3, ResolutionID); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CAuthorEntry::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + ID = pReader->GetULong(); + }break; + case 1: + { + Name = pReader->GetString2(); + }break; + case 2: + { + Initials = pReader->GetString2(); + }break; + case 3: + { + ResolutionID = pReader->GetString2(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CAuthorEntry::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"AuthorEntry"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"ID", ID); + pWriter->WriteAttribute2(L"Name", Name); + pWriter->WriteAttribute2(L"Initials", Initials); + pWriter->WriteAttribute2(L"ResolutionID", ResolutionID); + pWriter->EndAttributes(); + pWriter->WriteNodeEnd(L"AuthorEntry"); + } + +//----------------------------------------------------------------------------------------------------------------------------- +} +} // namespace OOX diff --git a/OOXML/VsdxFormat/VisioOthers.h b/OOXML/VsdxFormat/VisioOthers.h new file mode 100644 index 0000000000..6967b74d41 --- /dev/null +++ b/OOXML/VsdxFormat/VisioOthers.h @@ -0,0 +1,525 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../Base/Nullable.h" + +#include "FileTypes_Draw.h" +#include "../DocxFormat/IFileContainer.h" + +namespace OOX +{ + namespace Draw + { + class CRel; + + class CSolution : public WritingElement + { + public: + WritingElement_AdditionMethods(CSolution) + CSolution() {} + virtual ~CSolution() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_string Name; + nullable Rel; + }; + class CSolutions : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CSolutions) + CSolutions() {} + virtual ~CSolutions() {} + + virtual std::wstring toXML() const { return L""; } + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + }; +//------------------------------------------------------------------------------------------------------------------------------ + class CSolutionsFile : public OOX::IFileContainer, public OOX::File + { + public: + CSolutionsFile(OOX::Document* pMain); + CSolutionsFile(OOX::Document* pMain, const CPath& uri); + CSolutionsFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); + virtual ~CSolutionsFile(); + + virtual void read(const CPath& oFilePath); + virtual void read(const CPath& oRootPath, const CPath& oFilePath); + virtual void write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const; + + virtual const OOX::FileType type() const; + + virtual const CPath DefaultDirectory() const; + virtual const CPath DefaultFileName() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + std::wstring m_strFilename; + + nullable Solutions; + }; + class CSolutionFile : public OOX::File + { + public: + CSolutionFile(OOX::Document* pMain); + CSolutionFile(OOX::Document* pMain, const CPath& uri); + CSolutionFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); + virtual ~CSolutionFile(); + + virtual void read(const CPath& oFilePath); + virtual void read(const CPath& oRootPath, const CPath& oFilePath); + virtual void write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const; + + virtual const OOX::FileType type() const; + + virtual const CPath DefaultDirectory() const; + virtual const CPath DefaultFileName() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter); + + std::wstring m_strFilename; + + std::string m_sXmlA; + }; +//--------------------------------------------------------------------------------------------------------------------------------- + class CAuthorEntry : public WritingElement + { + public: + WritingElement_AdditionMethods(CAuthorEntry) + CAuthorEntry() {} + virtual ~CAuthorEntry() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_uint ID; + nullable_string Name; + nullable_string Initials; + nullable_string ResolutionID; + }; + class CAuthorList : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CAuthorList) + CAuthorList() {} + virtual ~CAuthorList() {} + + virtual std::wstring toXML() const { return L""; } + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + }; + class CCommentEntry : public WritingElement + { + public: + WritingElement_AdditionMethods(CCommentEntry) + CCommentEntry() {} + virtual ~CCommentEntry() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_uint AuthorID; + nullable_uint PageID; + nullable_uint ShapeID; + nullable_string Date; + nullable_string EditDate; + nullable_bool Done; + nullable_uint CommentID; + nullable_uint AutoCommentType; + + std::wstring content; + }; + class CCommentList : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CCommentList) + CCommentList() {} + virtual ~CCommentList() {} + + virtual std::wstring toXML() const { return L""; } + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + }; + class CComments : public WritingElement + { + public: + WritingElement_AdditionMethods(CComments) + CComments() {} + virtual ~CComments() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_bool ShowCommentTags; + + nullable AuthorList; + nullable CommentList; + }; + class CCommentsFile : public OOX::File + { + public: + CCommentsFile(OOX::Document* pMain); + CCommentsFile(OOX::Document* pMain, const CPath& uri); + CCommentsFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); + virtual ~CCommentsFile(); + + virtual void read(const CPath& oFilePath); + virtual void read(const CPath& oRootPath, const CPath& oFilePath); + virtual void write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const; + + virtual const OOX::FileType type() const; + + virtual const CPath DefaultDirectory() const; + virtual const CPath DefaultFileName() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + std::wstring m_strFilename; + + nullable Comments; + }; +//--------------------------------------------------------------------------------------------------------------------------------- + class CValidationProperties : public WritingElement + { + public: + WritingElement_AdditionMethods(CValidationProperties) + CValidationProperties() {} + virtual ~CValidationProperties() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_string LastValidated; + nullable_bool ShowIgnored; + }; + class CRuleSetFlags : public WritingElement + { + public: + WritingElement_AdditionMethods(CRuleSetFlags) + CRuleSetFlags() {} + virtual ~CRuleSetFlags() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_bool Hidden; + }; + class CRuleFormula : public WritingElement + { + public: + WritingElement_AdditionMethods(CRuleFormula) + CRuleFormula() {} + virtual ~CRuleFormula() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter); + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_string Formula; + std::wstring node_name; + }; + class CRule : public WritingElement + { + public: + WritingElement_AdditionMethods(CRule) + CRule() {} + virtual ~CRule() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_uint ID; + nullable_string Category; + nullable_string NameU; + nullable_bool Ignored; + nullable_string Description; + nullable_int RuleTarget; + + nullable RuleFilter; + nullable RuleTest; + }; + class CRuleSet : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CRuleSet) + CRuleSet() {} + virtual ~CRuleSet() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_uint ID; + nullable_string Name; + nullable_string NameU; + nullable_bool Enabled; + nullable_string Description; + + nullable RuleSetFlags; + }; + class CRuleSets : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CRuleSets) + CRuleSets() {} + virtual ~CRuleSets() {} + + virtual std::wstring toXML() const { return L""; } + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + }; + class CIssueTarget : public WritingElement + { + public: + WritingElement_AdditionMethods(CIssueTarget) + CIssueTarget() {} + virtual ~CIssueTarget() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_uint PageID; + nullable_uint ShapeID; + }; + class CRuleInfo : public WritingElement + { + public: + WritingElement_AdditionMethods(CRuleInfo) + CRuleInfo() {} + virtual ~CRuleInfo() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_uint RuleID; + nullable_uint RuleSetID; + }; + class CIssue : public WritingElement + { + public: + WritingElement_AdditionMethods(CIssue) + CIssue() {} + virtual ~CIssue() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_uint ID; + nullable_bool Ignored; + + nullable IssueTarget; + nullable RuleInfo; + }; + class CIssues : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CIssues) + CIssues() {} + virtual ~CIssues() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + }; + class CValidationFile : public OOX::File + { + public: + CValidationFile(OOX::Document* pMain); + CValidationFile(OOX::Document* pMain, const CPath& uri); + CValidationFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); + virtual ~CValidationFile(); + + virtual void read(const CPath& oFilePath); + virtual void read(const CPath& oRootPath, const CPath& oFilePath); + virtual void write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const; + + virtual const OOX::FileType type() const; + + virtual const CPath DefaultDirectory() const; + virtual const CPath DefaultFileName() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + std::wstring m_strFilename; + + nullable ValidationProperties; + nullable RuleSets; + nullable Issues; + }; + } //Draw +} // namespace OOX diff --git a/OOXML/VsdxFormat/VisioPages.cpp b/OOXML/VsdxFormat/VisioPages.cpp new file mode 100644 index 0000000000..934d525192 --- /dev/null +++ b/OOXML/VsdxFormat/VisioPages.cpp @@ -0,0 +1,1314 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "Vsdx.h" +#include "VisioPages.h" +#include "Shapes.h" +#include "../../DesktopEditor/common/SystemUtils.h" +#include "../Binary/Presentation/BinaryFileReaderWriter.h" +#include "../Binary/Presentation/XmlWriter.h" + +namespace OOX +{ +namespace Draw +{ + //----------------------------------------------------------------------------------------------------------------------------- + CMasterFile::CMasterFile(OOX::Document* pMain) : OOX::IFileContainer(pMain), OOX::File(pMain) + { + m_bVisioPages = true; + } + CMasterFile::CMasterFile(OOX::Document* pMain, const CPath& uri) : OOX::IFileContainer(pMain), OOX::File(pMain) + { + m_bVisioPages = true; + + read(uri.GetDirectory(), uri); + } + CMasterFile::CMasterFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::IFileContainer(pMain), OOX::File(pMain) + { + m_bVisioPages = true; + + read(oRootPath, oPath); + } + CMasterFile::~CMasterFile() + { + } + void CMasterFile::read(const CPath& oFilePath) + { + CPath oRootPath; + read(oRootPath, oFilePath); + } + void CMasterFile::read(const CPath& oRootPath, const CPath& oFilePath) + { + IFileContainer::Read(oRootPath, oFilePath); + + XmlUtils::CXmlLiteReader oReader; + + if (!oReader.FromFile(oFilePath.GetPath())) + return; + + if (!oReader.ReadNextNode()) + return; + + m_strFilename = oFilePath.GetPath(); + + std::wstring sName = oReader.GetName(); + if (L"MasterContents" == sName && !oReader.IsEmptyNode()) + { + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + if (L"Shapes" == sName) + { + Shapes = oReader; + } + else if (L"Connects" == sName) + { + Connects = oReader; + } + } + } + } + void CMasterFile::write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const + { + NSBinPptxRW::CXmlWriter oXmlWriter; + oXmlWriter.WriteString((L"")); + + oXmlWriter.m_lDocType = XMLWRITER_DOC_TYPE_VSDX; + toXmlWriter(&oXmlWriter); + + NSFile::CFileBinary::SaveToFile(oFilePath.GetPath(), oXmlWriter.GetXmlString()); + + oContent.Registration(type().OverrideType(), oDirectory, oFilePath.GetFilename()); + IFileContainer::Write(oFilePath, oDirectory, oContent); + } + const OOX::FileType CMasterFile::type() const + { + return FileTypes::Master; + } + const OOX::CPath CMasterFile::DefaultDirectory() const + { + return type().DefaultDirectory(); + } + const OOX::CPath CMasterFile::DefaultFileName() const + { + return type().DefaultFileName(); + } + void CMasterFile::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + smart_ptr rels_old = pReader->GetRels(); + pReader->SetRels(dynamic_cast((CMasterFile*)this)); + + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + + switch (_rec) + { + case 0: + { + Shapes.Init(); + Shapes->fromPPTY(pReader); + }break; + case 1: + { + Connects.Init(); + Connects->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + pReader->SetRels(rels_old); + } + void CMasterFile::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + smart_ptr rels_old = pWriter->GetRels(); + pWriter->SetRels(dynamic_cast((CPageFile*)this)); + + pWriter->WriteRecord2(0, Shapes); + pWriter->WriteRecord2(1, Connects); + + pWriter->SetRels(rels_old); + } + void CMasterFile::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"MasterContents"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"xmlns", L"http://schemas.microsoft.com/office/visio/2012/main"); + pWriter->WriteAttribute2(L"xmlns:r", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships"); + pWriter->WriteAttribute2(L"xml:space", L"preserve"); + pWriter->EndAttributes(); + + if (Shapes.IsInit()) + Shapes->toXmlWriter(pWriter); + + if (Connects.IsInit()) + Connects->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"MasterContents"); + } +//----------------------------------------------------------------------------------------------------------------------------- + CPageFile::CPageFile(OOX::Document* pMain) : OOX::IFileContainer(pMain), OOX::File(pMain) + { + m_bVisioPages = true; + } + CPageFile::CPageFile(OOX::Document* pMain, const CPath& uri) : OOX::IFileContainer(pMain), OOX::File(pMain) + { + m_bVisioPages = true; + read(uri.GetDirectory(), uri); + } + CPageFile::CPageFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::IFileContainer(pMain), OOX::File(pMain) + { + m_bVisioPages = true; + read(oRootPath, oPath); + } + CPageFile::~CPageFile() + { + } + void CPageFile::read(const CPath& oFilePath) + { + CPath oRootPath; + read(oRootPath, oFilePath); + } + void CPageFile::read(const CPath& oRootPath, const CPath& oFilePath) + { + IFileContainer::Read(oRootPath, oFilePath); + + XmlUtils::CXmlLiteReader oReader; + + if (!oReader.FromFile(oFilePath.GetPath())) + return; + + if (!oReader.ReadNextNode()) + return; + + m_strFilename = oFilePath.GetPath(); + + std::wstring sName = oReader.GetName(); + if (L"PageContents" == sName && !oReader.IsEmptyNode()) + { + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + if (L"Shapes" == sName) + { + Shapes = oReader; + } + else if (L"Connects" == sName) + { + Connects = oReader; + } + } + } + } + void CPageFile::write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const + { + NSBinPptxRW::CXmlWriter oXmlWriter; + oXmlWriter.WriteString((L"")); + + oXmlWriter.m_lDocType = XMLWRITER_DOC_TYPE_VSDX; + toXmlWriter(&oXmlWriter); + + NSFile::CFileBinary::SaveToFile(oFilePath.GetPath(), oXmlWriter.GetXmlString()); + + oContent.Registration(type().OverrideType(), oDirectory, oFilePath.GetFilename()); + IFileContainer::Write(oFilePath, oDirectory, oContent); + } + const OOX::FileType CPageFile::type() const + { + return FileTypes::Page; + } + const OOX::CPath CPageFile::DefaultDirectory() const + { + return type().DefaultDirectory(); + } + const OOX::CPath CPageFile::DefaultFileName() const + { + return type().DefaultFileName(); + } + void CPageFile::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + std::vector> arMasterRels; + std::vector arPagesRels; + + smart_ptr rels_old = pReader->GetRels(); + pReader->SetRels(dynamic_cast((CPageFile*)this)); + + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + + switch (_rec) + { + case 0: + { + Shapes.Init(); + Shapes->fromPPTY(pReader); + + }break; + case 1: + { + Connects.Init(); + Connects->fromPPTY(pReader); + }break; + case 2: + { + nullable_uint ID; + nullable_string UniqueID; + + LONG _end_rec_2 = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + ID = pReader->GetULong(); + }break; + case 1: + { + UniqueID = pReader->GetString2(); + }break; + } + } + pReader->Seek(_end_rec_2); + arMasterRels.push_back(std::make_pair(ID, UniqueID)); + }break; + case 3: + { + nullable_uint ID; + + LONG _end_rec_2 = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + ID = pReader->GetULong(); + }break; + } + } + pReader->Seek(_end_rec_2); + arPagesRels.push_back(ID); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + pReader->SetRels(rels_old); +//------------------------------------------------------------------------------------------- + OOX::Draw::CVsdx* pVsdx = dynamic_cast(((OOX::File*)this)->m_pMainDocument); + for (auto r : arMasterRels) + { + if (r.first.IsInit()) + { + std::map>::iterator pFind = pVsdx->mapMastersByID.find(*r.first); + if (pFind != pVsdx->mapMastersByID.end()) + { + AddNoWrite(pFind->second, L"../masters"); + } + } + else if (r.second.IsInit()) + { + //std::map>::iteratorpFind = map2.find(*r.first); + //if (pFind != map.end()) + //{ + // this->AddNoWrite(pFind->second, L"../masters"); + //} + } + } + for (auto r : arPagesRels) + { + if (r.IsInit()) + { + std::map>::iterator pFind = pVsdx->mapPagesByID.find(*r); + if (pFind != pVsdx->mapPagesByID.end()) + { + AddNoWrite(pFind->second, L""); + } + } + } + } + void CPageFile::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + smart_ptr rels_old = pWriter->GetRels(); + pWriter->SetRels(dynamic_cast((CPageFile*)this)); + + pWriter->WriteRecord2(0, Shapes); + pWriter->WriteRecord2(1, Connects); + + pWriter->SetRels(rels_old); +//------------------------------------------------------------------------------------------------------- + for (auto r : m_arContainer) + { + if (r->type() == OOX::Draw::FileTypes::Master) + { + smart_ptr master = r.smart_dynamic_cast(); + pWriter->StartRecord(2); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, master->ID); + pWriter->WriteString2(1, master->UniqueID); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + pWriter->EndRecord(); + } + else if (r->type() == OOX::Draw::FileTypes::Page) + { + smart_ptr page = r.smart_dynamic_cast(); + pWriter->StartRecord(3); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, page->ID); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + pWriter->EndRecord(); + } + } + } + void CPageFile::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"PageContents"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"xmlns", L"http://schemas.microsoft.com/office/visio/2012/main"); + pWriter->WriteAttribute2(L"xmlns:r", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships"); + pWriter->WriteAttribute2(L"xml:space", L"preserve"); + pWriter->EndAttributes(); + + if (Shapes.IsInit()) + Shapes->toXmlWriter(pWriter); + + if (Connects.IsInit()) + Connects->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"PageContents"); + } + CMastersFile::CMastersFile(OOX::Document* pMain) : OOX::IFileContainer(pMain), OOX::File(pMain) + { + m_bVisioPages = true; + } + CMastersFile::CMastersFile(OOX::Document* pMain, const CPath& uri) : OOX::IFileContainer(pMain), OOX::File(pMain) + { + m_bVisioPages = true; + read(uri.GetDirectory(), uri); + } + CMastersFile::CMastersFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::IFileContainer(pMain), OOX::File(pMain) + { + m_bVisioPages = true; + + read(oRootPath, oPath); + } + CMastersFile::~CMastersFile() + { + } + void CMastersFile::read(const CPath& oFilePath) + { + CPath oRootPath; + read(oRootPath, oFilePath); + } + void CMastersFile::read(const CPath& oRootPath, const CPath& oFilePath) + { + IFileContainer::Read(oRootPath, oFilePath); + + XmlUtils::CXmlLiteReader oReader; + + if (!oReader.FromFile(oFilePath.GetPath())) + return; + + if (!oReader.ReadNextNode()) + return; + + m_strFilename = oFilePath.GetPath(); + + fromXML(oReader); + } + OOX::EElementType CMastersFile::getType() const + { + return et_dr_Masters; + } + void CMastersFile::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + if (L"Master" == sName) + { + CMaster* pItem = new CMaster(); + if (pItem) + { + *pItem = oReader; + m_arrItems.push_back(pItem); + + if (pItem->Rel.IsInit()) + { + smart_ptr pFile = this->Find(pItem->Rel->Rid->GetValue()); + CMasterFile* pMasterContent = dynamic_cast(pFile.GetPointer()); + if (pMasterContent) + { + pMasterContent->ID = pItem->ID; + pMasterContent->UniqueID = pItem->UniqueID; + } + } + } + } + } + } + void CMastersFile::write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const + { + NSBinPptxRW::CXmlWriter oXmlWriter; + oXmlWriter.WriteString((L"")); + + oXmlWriter.m_lDocType = XMLWRITER_DOC_TYPE_VSDX; + toXmlWriter(&oXmlWriter); + + NSFile::CFileBinary::SaveToFile(oFilePath.GetPath(), oXmlWriter.GetXmlString()); + + oContent.Registration(type().OverrideType(), oDirectory, oFilePath.GetFilename()); + IFileContainer::Write(oFilePath, oDirectory, oContent); + } + const OOX::FileType CMastersFile::type() const + { + return FileTypes::Masters; + } + const OOX::CPath CMastersFile::DefaultDirectory() const + { + return type().DefaultDirectory(); + } + const OOX::CPath CMastersFile::DefaultFileName() const + { + return type().DefaultFileName(); + } + void CMastersFile::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + smart_ptr rels_old = pReader->GetRels(); + pReader->SetRels(dynamic_cast((CMastersFile*)this)); + + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + + switch (_rec) + { + case 0: + { + m_arrItems.push_back(new CMaster(((OOX::File*)this)->m_pMainDocument)); + m_arrItems.back()->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + pReader->SetRels(rels_old); + } + void CMastersFile::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + smart_ptr rels_old = pWriter->GetRels(); + pWriter->SetRels(dynamic_cast((CPageFile*)this)); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + pWriter->WriteRecord2(0, dynamic_cast(m_arrItems[i])); + + pWriter->SetRels(rels_old); + } + void CMastersFile::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"Masters"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"xmlns", L"http://schemas.microsoft.com/office/visio/2012/main"); + pWriter->WriteAttribute2(L"xmlns:r", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships"); + pWriter->WriteAttribute2(L"xml:space", L"preserve"); + pWriter->EndAttributes(); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"Masters"); + } +//----------------------------------------------------------------------------------------------------------------------------- + CPagesFile::CPagesFile(OOX::Document* pMain) : OOX::IFileContainer(pMain), OOX::File(pMain) + { + m_bVisioPages = true; + } + CPagesFile::CPagesFile(OOX::Document* pMain, const CPath& uri) : OOX::IFileContainer(pMain), OOX::File(pMain) + { + m_bVisioPages = true; + read(uri.GetDirectory(), uri); + } + CPagesFile::CPagesFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::IFileContainer(pMain), OOX::File(pMain) + { + m_bVisioPages = true; + read(oRootPath, oPath); + } + CPagesFile::~CPagesFile() + { + } + void CPagesFile::read(const CPath& oFilePath) + { + CPath oRootPath; + read(oRootPath, oFilePath); + } + void CPagesFile::read(const CPath& oRootPath, const CPath& oFilePath) + { + IFileContainer::Read(oRootPath, oFilePath); + + XmlUtils::CXmlLiteReader oReader; + + if (!oReader.FromFile(oFilePath.GetPath())) + return; + + if (!oReader.ReadNextNode()) + return; + + m_strFilename = oFilePath.GetPath(); + + fromXML(oReader); + } + OOX::EElementType CPagesFile::getType() const + { + return et_dr_Pages; + } + void CPagesFile::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + if (L"Page" == sName) + { + CPage* pItem = new CPage(); + + if (pItem) + { + *pItem = oReader; + m_arrItems.push_back(pItem); + + if (pItem->Rel.IsInit()) + { + smart_ptr pFile = this->Find(pItem->Rel->Rid->GetValue()); + CPageFile* pPageContent = dynamic_cast(pFile.GetPointer()); + if (pPageContent) + { + pPageContent->ID = pItem->ID; + } + } + } + } + } + } + void CPagesFile::write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const + { + NSBinPptxRW::CXmlWriter oXmlWriter; + oXmlWriter.WriteString((L"")); + + oXmlWriter.m_lDocType = XMLWRITER_DOC_TYPE_VSDX; + toXmlWriter(&oXmlWriter); + + NSFile::CFileBinary::SaveToFile(oFilePath.GetPath(), oXmlWriter.GetXmlString()); + + oContent.Registration(type().OverrideType(), oDirectory, oFilePath.GetFilename()); + IFileContainer::Write(oFilePath, oDirectory, oContent); + } + const OOX::FileType CPagesFile::type() const + { + return FileTypes::Pages; + } + const OOX::CPath CPagesFile::DefaultDirectory() const + { + return type().DefaultDirectory(); + } + const OOX::CPath CPagesFile::DefaultFileName() const + { + return type().DefaultFileName(); + } + void CPagesFile::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + smart_ptr rels_old = pReader->GetRels(); + pReader->SetRels(dynamic_cast((CPagesFile*)this)); + + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + + switch (_rec) + { + case 0: + { + m_arrItems.push_back(new CPage(((OOX::File*)this)->m_pMainDocument)); + m_arrItems.back()->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + pReader->SetRels(rels_old); + } + void CPagesFile::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + smart_ptr rels_old = pWriter->GetRels(); + pWriter->SetRels(dynamic_cast((CPageFile*)this)); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + pWriter->WriteRecord2(0, dynamic_cast(m_arrItems[i])); + + pWriter->SetRels(rels_old); + } + void CPagesFile::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"Pages"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"xmlns", L"http://schemas.microsoft.com/office/visio/2012/main"); + pWriter->WriteAttribute2(L"xmlns:r", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships"); + pWriter->WriteAttribute2(L"xml:space", L"preserve"); + pWriter->EndAttributes(); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"Pages"); + } +//-------------------------------------------------------------------------------------------------------------- + CPage::CPage(OOX::Document* pMain) : WritingElement(pMain) + { + } + CPage::~CPage() + { + } + EElementType CPage::getType() const + { + return et_dr_Page; + } + void CPage::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "ID", ID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Name", Name) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "NameU", NameU) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "IsCustomName", IsCustomName) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "IsCustomNameU", IsCustomNameU) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Background", Background) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "BackPage", BackPage) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ViewScale", ViewScale) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ViewCenterX", ViewCenterX) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ViewCenterY", ViewCenterY) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ReviewerID", ReviewerID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "AssociatedPage", AssociatedPage) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CPage::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + const char* sName = XmlUtils::GetNameNoNS(oReader.GetNameChar()); + if (strcmp("PageSheet", sName) == 0) + { + PageSheet = oReader; + } + else if (strcmp("Rel", sName) == 0) + { + Rel = oReader; + } + } + } + void CPage::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, ID); + pWriter->WriteString2(1, Name); + pWriter->WriteString2(2, NameU); + pWriter->WriteBool2(3, IsCustomName); + pWriter->WriteBool2(4, IsCustomNameU); + pWriter->WriteBool2(5, Background); + pWriter->WriteUInt2(6, BackPage); + pWriter->WriteDoubleReal2(7, ViewScale); + pWriter->WriteDoubleReal2(8, ViewCenterX); + pWriter->WriteDoubleReal2(9, ViewCenterY); + pWriter->WriteUInt2(10, ReviewerID); + pWriter->WriteUInt2(11, AssociatedPage); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + pWriter->WriteRecord2(0, PageSheet); + + if (Rel.IsInit() && Rel->Rid.IsInit()) + { + smart_ptr pFile = pWriter->GetRels()->Find(Rel->Rid->GetValue()); + CPageFile* pPage = dynamic_cast(pFile.GetPointer()); + if (pPage) + { + pWriter->StartRecord(1); + pPage->toPPTY(pWriter); + pWriter->EndRecord(); + } + } + } + void CPage::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + ID = pReader->GetULong(); + }break; + case 1: + { + Name = pReader->GetString2(); + }break; + case 2: + { + NameU = pReader->GetString2(); + }break; + case 3: + { + IsCustomName = pReader->GetBool(); + }break; + case 4: + { + IsCustomNameU = pReader->GetBool(); + }break; + case 5: + { + Background = pReader->GetBool(); + }break; + case 6: + { + BackPage = pReader->GetULong(); + }break; + case 7: + { + ViewScale = pReader->GetDoubleReal(); + }break; + case 8: + { + ViewCenterX = pReader->GetDoubleReal(); + }break; + case 9: + { + ViewCenterY = pReader->GetDoubleReal(); + }break; + case 10: + { + ReviewerID = pReader->GetULong(); + }break; + case 11: + { + AssociatedPage = pReader->GetULong(); + }break; + } + } + while (pReader->GetPos() < _end_rec) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + PageSheet.Init(); + PageSheet->fromPPTY(pReader); + }break; + case 1: + { + CPageFile* pPage = new CPageFile(m_pMainDocument); + pPage->fromPPTY(pReader); + smart_ptr oFile(pPage); + + Rel.Init(); Rel->Rid.Init(); + Rel->Rid->SetValue(pReader->GetRels()->Add(oFile).get()); + + pPage->ID = ID; + + OOX::Draw::CVsdx* pVsdx = dynamic_cast(m_pMainDocument); + pVsdx->mapPagesByID.insert(std::make_pair(*ID, oFile)); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CPage::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"Page"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"ID", ID); + pWriter->WriteAttribute2(L"NameU", NameU); + pWriter->WriteAttribute(L"IsCustomNameU", IsCustomNameU); + pWriter->WriteAttribute2(L"Name", Name); + pWriter->WriteAttribute(L"IsCustomName", IsCustomName); + pWriter->WriteAttribute(L"Background", Background); + pWriter->WriteAttribute2(L"BackPage", BackPage); + pWriter->WriteAttribute(L"ViewScale", ViewScale); + pWriter->WriteAttribute(L"ViewCenterX", ViewCenterX); + pWriter->WriteAttribute(L"ViewCenterY", ViewCenterY); + pWriter->WriteAttribute2(L"ReviewerID", ReviewerID); + pWriter->WriteAttribute2(L"AssociatedPage", AssociatedPage); + pWriter->EndAttributes(); + + if (PageSheet.IsInit()) + PageSheet->toXmlWriter(pWriter); + + if (Rel.IsInit()) + Rel->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"Page"); + } +//----------------------------------------------------------------------------------------------------------------- + CMaster::CMaster(OOX::Document* pMain) : WritingElement(pMain) + { + + } + CMaster::~CMaster() + { + } + EElementType CMaster::getType() const + { + return et_dr_Master; + } + void CMaster::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "ID", ID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Name", Name) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "NameU", NameU) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "BaseID", BaseID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "UniqueID", UniqueID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "MatchByName", MatchByName) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "IsCustomName", IsCustomName) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "IsCustomNameU", IsCustomNameU) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "IconSize", IconSize) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "PatternFlags", PatternFlags) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Prompt", Prompt) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Hidden", Hidden) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "IconUpdate", IconUpdate) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "AlignName", AlignName) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "MasterType", MasterType) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CMaster::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + + int nCurDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nCurDepth)) + { + const char* sName = XmlUtils::GetNameNoNS(oReader.GetNameChar()); + if (strcmp("PageSheet", sName) == 0) + { + PageSheet = oReader; + } + else if (strcmp("Icon", sName) == 0) + { + Icon = oReader; + } + else if (strcmp("Rel", sName) == 0) + { + Rel = oReader; + } + } + } + void CMaster::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, ID); + pWriter->WriteString2(1, Name); + pWriter->WriteString2(2, NameU); + pWriter->WriteString2(3, BaseID); + pWriter->WriteString2(4, UniqueID); + pWriter->WriteBool2(5, MatchByName); + pWriter->WriteBool2(6, IsCustomName); + pWriter->WriteBool2(7, IsCustomNameU); + pWriter->WriteUInt2(8, IconSize); + pWriter->WriteUInt2(9, PatternFlags); + pWriter->WriteString2(10, Prompt); + pWriter->WriteBool2(11, Hidden); + pWriter->WriteBool2(12, IconUpdate); + pWriter->WriteUInt2(13, AlignName); + pWriter->WriteUInt2(14, MasterType); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + pWriter->WriteRecord2(0, PageSheet); + + if (Icon.IsInit()) + { + pWriter->StartRecord(1); + pWriter->WriteString(Icon->content); + pWriter->EndRecord(); + } + if (Rel.IsInit() && Rel->Rid.IsInit()) + { + smart_ptr pFile = pWriter->GetRels()->Find(Rel->Rid->GetValue()); + CMasterFile* pMaster = dynamic_cast(pFile.GetPointer()); + if (pMaster) + { + pWriter->StartRecord(2); + pMaster->toPPTY(pWriter); + pWriter->EndRecord(); + } + } + } + void CMaster::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + ID = pReader->GetULong(); + }break; + case 1: + { + Name = pReader->GetString2(); + }break; + case 2: + { + NameU = pReader->GetString2(); + }break; + case 3: + { + BaseID = pReader->GetString2(); + }break; + case 4: + { + UniqueID = pReader->GetString2(); + }break; + case 5: + { + MatchByName = pReader->GetBool(); + }break; + case 6: + { + IsCustomName = pReader->GetBool(); + }break; + case 7: + { + IsCustomNameU = pReader->GetBool(); + }break; + case 8: + { + IconSize = pReader->GetULong(); + }break; + case 9: + { + PatternFlags = pReader->GetULong(); + }break; + case 10: + { + Prompt = pReader->GetString2(); + }break; + case 11: + { + Hidden = pReader->GetBool(); + }break; + case 12: + { + IconUpdate = pReader->GetBool(); + }break; + case 13: + { + AlignName = pReader->GetULong(); + }break; + case 14: + { + MasterType = pReader->GetULong(); + }break; + } + } + while (pReader->GetPos() < _end_rec) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + PageSheet.Init(); + PageSheet->fromPPTY(pReader); + }break; + case 1: + { + Icon.Init(); + Icon->fromPPTY(pReader); + }break; + case 2: + { + CMasterFile* pMaster = new CMasterFile(m_pMainDocument); + pMaster->fromPPTY(pReader); + smart_ptr oFile(pMaster); + + Rel.Init(); Rel->Rid.Init(); + Rel->Rid->SetValue(pReader->GetRels()->Add(oFile).get()); + + pMaster->ID = ID; + pMaster->UniqueID = UniqueID; + + OOX::Draw::CVsdx* pVsdx = dynamic_cast(m_pMainDocument); + + pVsdx->mapMastersByID.insert(std::make_pair(*ID, oFile)); + //pVsdx->mapMastersByUniqueID.insert(*UniqueID, oFile) + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CMaster::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"Master"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"ID", ID); + pWriter->WriteAttribute2(L"NameU", NameU); + pWriter->WriteAttribute(L"IsCustomNameU", IsCustomNameU); + pWriter->WriteAttribute2(L"Name", Name); + pWriter->WriteAttribute(L"IsCustomName", IsCustomName); + pWriter->WriteAttribute2(L"Prompt", Prompt); + pWriter->WriteAttribute2(L"IconSize", IconSize); + pWriter->WriteAttribute2(L"AlignName", AlignName); + pWriter->WriteAttribute(L"MatchByName", MatchByName); + pWriter->WriteAttribute(L"IconUpdate", IconUpdate); + pWriter->WriteAttribute2(L"UniqueID", UniqueID); + pWriter->WriteAttribute2(L"BaseID", BaseID); + pWriter->WriteAttribute2(L"PatternFlags", PatternFlags); + pWriter->WriteAttribute(L"Hidden", Hidden); + pWriter->WriteAttribute2(L"MasterType", MasterType); + pWriter->EndAttributes(); + + if (PageSheet.IsInit()) + PageSheet->toXmlWriter(pWriter); + + if (Icon.IsInit()) + Icon->toXmlWriter(pWriter); + + if (Rel.IsInit()) + Rel->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"Master"); + } + EElementType CPageSheet::getType() const + { + return et_dr_PageSheet; + } + void CPageSheet::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "UniqueID", UniqueID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "LineStyle", LineStyle) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "FillStyle", FillStyle) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "TextStyle", TextStyle) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CPageSheet::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + WritingElement* pItem = NULL; + if (L"Cell" == sName) + { + pItem = new CCell(); + } + else if (L"Trigger" == sName) + { + pItem = new CTrigger(); + } + else if (L"Section" == sName) + { + pItem = new CSection(); + } + if (pItem) + { + pItem->fromXML(oReader); + m_arrItems.push_back(pItem); + } + } + } + void CPageSheet::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteString2(0, UniqueID); + pWriter->WriteUInt2(1, LineStyle); + pWriter->WriteUInt2(2, FillStyle); + pWriter->WriteUInt2(3, TextStyle); + + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + int type = 0xff; //todooo predefine type for ??? + switch (m_arrItems[i]->getType()) + { + case et_dr_Cell: type = 0; break; + case et_dr_Trigger: type = 1; break; + case et_dr_Section: type = 2; break; + } + if (type != 0xff) + pWriter->WriteRecord2(type, dynamic_cast(m_arrItems[i])); + } + } + void CPageSheet::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + UniqueID = pReader->GetString2(); + }break; + case 1: + { + LineStyle = pReader->GetULong(); + }break; + case 2: + { + FillStyle = pReader->GetULong(); + }break; + case 3: + { + TextStyle = pReader->GetULong(); + }break; + } + } + while (pReader->GetPos() < _end_rec) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + m_arrItems.push_back(new CCell()); + m_arrItems.back()->fromPPTY(pReader); + }break; + case 1: + { + m_arrItems.push_back(new CTrigger()); + m_arrItems.back()->fromPPTY(pReader); + }break; + case 2: + { + m_arrItems.push_back(new CSection()); + m_arrItems.back()->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CPageSheet::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"PageSheet"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"LineStyle", LineStyle); + pWriter->WriteAttribute2(L"FillStyle", FillStyle); + pWriter->WriteAttribute2(L"TextStyle", TextStyle); + pWriter->WriteAttribute2(L"UniqueID", UniqueID); + pWriter->EndAttributes(); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"PageSheet"); + } +} +} // namespace OOX diff --git a/OOXML/VsdxFormat/VisioPages.h b/OOXML/VsdxFormat/VisioPages.h new file mode 100644 index 0000000000..9765fd0edf --- /dev/null +++ b/OOXML/VsdxFormat/VisioPages.h @@ -0,0 +1,266 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../Base/Nullable.h" + +#include "FileTypes_Draw.h" +#include "../DocxFormat/IFileContainer.h" + +namespace OOX +{ + namespace Draw + { + class CConnects; + class CShapes; + class CRel; + class CIcon; + + class CPageFile : public OOX::IFileContainer, public OOX::File + { + public: + CPageFile(OOX::Document* pMain); + CPageFile(OOX::Document* pMain, const CPath& uri); + CPageFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); + virtual ~CPageFile(); + + virtual void read(const CPath& oFilePath); + virtual void read(const CPath& oRootPath, const CPath& oFilePath); + virtual void write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const; + + virtual const OOX::FileType type() const; + + virtual const CPath DefaultDirectory() const; + virtual const CPath DefaultFileName() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + std::wstring m_strFilename; + + nullable Shapes; + nullable Connects; +// from pages + nullable_uint ID; + }; + class CMasterFile : public OOX::IFileContainer, public OOX::File + { + public: + CMasterFile(OOX::Document* pMain); + CMasterFile(OOX::Document* pMain, const CPath& uri); + CMasterFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); + virtual ~CMasterFile(); + + virtual void read(const CPath& oFilePath); + virtual void read(const CPath& oRootPath, const CPath& oFilePath); + virtual void write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const; + + virtual const OOX::FileType type() const; + + virtual const CPath DefaultDirectory() const; + virtual const CPath DefaultFileName() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + std::wstring m_strFilename; + + nullable Shapes; + nullable Connects; +// from masters + nullable_uint ID; + nullable_string UniqueID; + }; + //--------------------------------------------------------------------------------------------------------------------------------- + class CPageSheet : public WritingElementWithChilds<> + { + public: + WritingElement_AdditionMethods(CPageSheet) + CPageSheet() {} + virtual ~CPageSheet() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_string UniqueID; + nullable_uint LineStyle; + nullable_uint FillStyle; + nullable_uint TextStyle; + }; + class CPage : public WritingElement + { + public: + WritingElement_AdditionMethods(CPage) + CPage(OOX::Document* pMain = NULL); + virtual ~CPage(); + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_uint ID; + nullable_string Name; + nullable_string NameU; + nullable_bool IsCustomName; + nullable_bool IsCustomNameU; + nullable_bool Background; + nullable_uint BackPage; + nullable_double ViewScale; + nullable_double ViewCenterX; + nullable_double ViewCenterY; + nullable_uint ReviewerID; + nullable_uint AssociatedPage; + + nullable PageSheet; + nullable Rel; + }; + class CMaster : public WritingElement + { + public: + WritingElement_AdditionMethods(CMaster) + CMaster(OOX::Document* pMain = NULL); + virtual ~CMaster(); + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_uint ID; + nullable_string Name; + nullable_string BaseID; + nullable_string UniqueID; + nullable_bool MatchByName; + nullable_string NameU; + nullable_bool IsCustomName; + nullable_bool IsCustomNameU; + nullable_uint IconSize; + nullable_uint PatternFlags; + nullable_string Prompt; + nullable_bool Hidden; + nullable_bool IconUpdate; + nullable_uint AlignName; + nullable_uint MasterType; + + nullable PageSheet; + nullable Rel; + nullable Icon; + }; + class CPagesFile : public OOX::IFileContainer, public OOX::File, public WritingElementWithChilds + { + public: + CPagesFile(OOX::Document* pMain); + CPagesFile(OOX::Document* pMain, const CPath& uri); + CPagesFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); + virtual ~CPagesFile(); + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + virtual EElementType getType() const; + + virtual void read(const CPath& oFilePath); + virtual void read(const CPath& oRootPath, const CPath& oFilePath); + virtual void write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const; + + virtual const OOX::FileType type() const; + + virtual const CPath DefaultDirectory() const; + virtual const CPath DefaultFileName() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + + std::wstring m_strFilename; + }; + class CMastersFile : public OOX::IFileContainer, public OOX::File, public WritingElementWithChilds + { + public: + CMastersFile(OOX::Document* pMain); + CMastersFile(OOX::Document* pMain, const CPath& uri); + CMastersFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); + virtual ~CMastersFile(); + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + virtual EElementType getType() const; + + virtual void read(const CPath& oFilePath); + virtual void read(const CPath& oRootPath, const CPath& oFilePath); + virtual void write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const; + + virtual const OOX::FileType type() const; + + virtual const CPath DefaultDirectory() const; + virtual const CPath DefaultFileName() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + + std::wstring m_strFilename; + }; + + } //Draw +} // namespace OOX diff --git a/OOXML/VsdxFormat/Vsdx.cpp b/OOXML/VsdxFormat/Vsdx.cpp new file mode 100644 index 0000000000..47c54c97fe --- /dev/null +++ b/OOXML/VsdxFormat/Vsdx.cpp @@ -0,0 +1,80 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "Vsdx.h" + +#include "../DocxFormat/App.h" +#include "../DocxFormat/Core.h" + +#include "FileTypes_Draw.h" + +#include "../../DesktopEditor/common/SystemUtils.h" + +#include "VisioDocument.h" +#include "VisioConnections.h" +#include "Shapes.h" + + +OOX::Draw::CVsdx::CVsdx() : OOX::IFileContainer(dynamic_cast(this)) +{ +} +OOX::Draw::CVsdx::CVsdx(const CPath& oFilePath) : OOX::IFileContainer(dynamic_cast(this)) +{ + m_bVisioPages = true; + Read( oFilePath ); +} +OOX::Draw::CVsdx::~CVsdx() +{ + +} +bool OOX::Draw::CVsdx::Read(const CPath& oFilePath) +{ + m_sDocumentPath = oFilePath.GetPath(); + + OOX::CRels oRels(oFilePath / FILE_SEPARATOR_STR); + IFileContainer::Read(oRels, oFilePath, oFilePath); + + m_pDocument = Find(FileTypes::Document).smart_dynamic_cast(); + m_pApp = Find(OOX::FileTypes::App).smart_dynamic_cast(); + m_pCore = Find(OOX::FileTypes::Core).smart_dynamic_cast(); + return true; +} +bool OOX::Draw::CVsdx::Write(const CPath& oDirPath, OOX::CContentTypes &oContentTypes) +{ + //CPath oVisioPath = oDirPath / m_pWorkbook->DefaultDirectory(); + //WriteWorkbook(oVisioPath); + + IFileContainer::Write(oDirPath / L"" , OOX::CPath(_T("")), oContentTypes); + + oContentTypes.Write(oDirPath); + return true; +} +//----------------------------------------------------------------------------------------------------------------------------- diff --git a/OOXML/VsdxFormat/Vsdx.h b/OOXML/VsdxFormat/Vsdx.h new file mode 100644 index 0000000000..f61ce7de01 --- /dev/null +++ b/OOXML/VsdxFormat/Vsdx.h @@ -0,0 +1,67 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../DocxFormat/IFileContainer.h" +#include "../../DesktopEditor/common/Directory.h" + +namespace OOX +{ + class CApp; + class CCore; + + namespace Draw + { + class CDocumentFile; + + class CVsdx : public OOX::Document, public OOX::IFileContainer + { + public: + CVsdx(); + CVsdx(const CPath& oFilePath); + virtual ~CVsdx(); + + bool Read(const CPath& oFilePath); + bool Write(const CPath& oDirPath, OOX::CContentTypes &oContentTypes); + + smart_ptr m_pDocument; + + smart_ptr m_pApp; + smart_ptr m_pCore; + + std::map> mapMastersByID; + std::map> mapPagesByID; + }; + + } //Draw +} // OOX + diff --git a/OOXML/XML/XmlSimple.cpp b/OOXML/XML/XmlSimple.cpp index c438728105..73884201d6 100644 --- a/OOXML/XML/XmlSimple.cpp +++ b/OOXML/XML/XmlSimple.cpp @@ -93,6 +93,12 @@ namespace XmlUtils return; m_strValue += (L" ") + strName + L"=\"" + *value + L"\""; } + void CAttribute::Write2(const std::wstring& strName, const nullable_string& value) + { + if (!value.IsInit()) + return; + m_strValue += (L" ") + strName + L"=\"" + XmlUtils::EncodeXmlString(*value) + L"\""; + } void CAttribute::Write(const std::wstring& strName, const nullable_bool& value) { if (!value.IsInit()) diff --git a/OOXML/XML/XmlSimple.h b/OOXML/XML/XmlSimple.h index 3eea02b2f9..674ec9797a 100644 --- a/OOXML/XML/XmlSimple.h +++ b/OOXML/XML/XmlSimple.h @@ -76,8 +76,7 @@ namespace XmlUtils return; Write(strName, value->get()); } - - public: + void Write(const std::wstring& strName, const nullable_int& value); void Write(const std::wstring& strName, const nullable_uint& value); void Write(const std::wstring& strName, const nullable_sizet& value); @@ -85,8 +84,8 @@ namespace XmlUtils void Write(const std::wstring& strName, const nullable_string& value); void Write(const std::wstring& strName, const nullable_bool& value); void Write2(const std::wstring& strName, const nullable_bool& value); + void Write2(const std::wstring& strName, const nullable_string& value); - public: CAttribute(const CAttribute& oSrc); CAttribute& operator=(const CAttribute& oSrc); }; @@ -96,7 +95,6 @@ namespace XmlUtils public: std::wstring m_strValue; - public: CNodeValue(); template diff --git a/OOXML/XlsbFormat/Biff12_records/BeginDatabar14.h b/OOXML/XlsbFormat/Biff12_records/BeginDatabar14.h index b56dfa12e4..e7826498bd 100644 --- a/OOXML/XlsbFormat/Biff12_records/BeginDatabar14.h +++ b/OOXML/XlsbFormat/Biff12_records/BeginDatabar14.h @@ -56,7 +56,7 @@ namespace XLSB FRTBlank FRTheader; BYTE bLenMin = 0; BYTE bLenMax = 100; - XLS::Boolean fShowValue = 0; + XLS::Boolean fShowValue = 1; BYTE bDirection = 0; BYTE bAxisPosType = 0; diff --git a/OOXML/XlsbFormat/Biff12_structures/FRTProductVersion.h b/OOXML/XlsbFormat/Biff12_structures/FRTProductVersion.h index d15e7035c1..2e3615ae11 100644 --- a/OOXML/XlsbFormat/Biff12_structures/FRTProductVersion.h +++ b/OOXML/XlsbFormat/Biff12_structures/FRTProductVersion.h @@ -1,4 +1,4 @@ -/* +/* * (c) Copyright Ascensio System SIA 2010-2021 * * This program is a free software product. You can redistribute it and/or @@ -52,8 +52,8 @@ namespace XLSB void load(XLS::CFRecord& record) override; void save(XLS::CFRecord& record) override; - _UINT16 version; - _UINT16 product; + _UINT16 version = 0; + _UINT16 product = 0; }; typedef boost::shared_ptr FRTProductVersionPtr; diff --git a/OOXML/XlsxFormat/FileFactory_Spreadsheet.cpp b/OOXML/XlsxFormat/FileFactory_Spreadsheet.cpp index 8b692b6291..89475757ba 100644 --- a/OOXML/XlsxFormat/FileFactory_Spreadsheet.cpp +++ b/OOXML/XlsxFormat/FileFactory_Spreadsheet.cpp @@ -46,6 +46,7 @@ #include "Worksheets/Worksheet.h" #include "CalcChain/CalcChain.h" #include "WorkbookComments.h" +#include "Workbook/CustomsXml.h" #include "Comments/ThreadedComments.h" #include "Comments/Comments.h" #include "Controls/Controls.h" @@ -83,8 +84,8 @@ namespace OOX { smart_ptr CreateFile(const OOX::CPath& oRootPath, const OOX::CPath& oPath, const OOX::Rels::CRelationShip& oRelation, OOX::Document *pMain) { - OOX::CPath oRelationFilename = oRelation.Filename(); - CPath oFileName; + OOX::CPath oRelationFilename = oRelation.Filename(); + CPath oFileName; if (oRelation.IsExternal()) { @@ -114,6 +115,8 @@ namespace OOX return smart_ptr(new CWorksheet( pMain, oRootPath, oFileName, oRelation.rId().ToString(), true )); else if ( oRelation.Type() == FileTypes::Table ) return smart_ptr(new CTableFile( pMain, oRootPath, oFileName )); + else if (oRelation.Type() == FileTypes::TableSingleCells) + return smart_ptr(new CTableSingleCellsFile(pMain, oRootPath, oFileName)); else if ( oRelation.Type() == FileTypes::QueryTable ) return smart_ptr(new CQueryTableFile( pMain, oRootPath, oFileName )); else if ( oRelation.Type() == FileTypes::PivotTable ) @@ -140,7 +143,9 @@ namespace OOX return smart_ptr(new CExternalLink( pMain, oRootPath, oFileName, oRelation.rId().ToString() )); else if ( oRelation.Type() == FileTypes::Connections ) return smart_ptr(new CConnectionsFile( pMain, oRootPath, oFileName )); - + else if (oRelation.Type() == FileTypes::XmlMaps) + return smart_ptr(new CXmlMapsFile(pMain, oRootPath, oFileName)); + else if ( oRelation.Type() == OOX::FileTypes::Chart ) return smart_ptr(new CChartFile( pMain, oRootPath, oFileName )); else if ( oRelation.Type() == OOX::FileTypes::ChartEx ) @@ -251,6 +256,8 @@ namespace OOX return smart_ptr(new CWorksheet( pMain, oRootPath, oFileName, pRelation->rId().ToString(), true )); else if ( pRelation->Type() == FileTypes::Table ) return smart_ptr(new CTableFile( pMain, oRootPath, oFileName )); + else if (pRelation->Type() == FileTypes::TableSingleCells) + return smart_ptr(new CTableSingleCellsFile(pMain, oRootPath, oFileName)); else if ( pRelation->Type() == FileTypes::QueryTable ) return smart_ptr(new CQueryTableFile( pMain, oRootPath, oFileName )); else if ( pRelation->Type() == FileTypes::PivotTable ) @@ -331,8 +338,10 @@ namespace OOX return smart_ptr(new CRdRichValueFile(pMain, oRootPath, oFileName)); else if (pRelation->Type() == FileTypes::RdRichValueTypes) return smart_ptr(new CRdRichValueTypesFile(pMain, oRootPath, oFileName)); + else if (pRelation->Type() == FileTypes::XmlMaps) + return smart_ptr(new CXmlMapsFile(pMain, oRootPath, oFileName)); return smart_ptr( new UnknowTypeFile(pMain) ); } - } + } } // namespace OOX diff --git a/OOXML/XlsxFormat/FileFactory_Spreadsheet.h b/OOXML/XlsxFormat/FileFactory_Spreadsheet.h index bde2487631..b99d6746d2 100644 --- a/OOXML/XlsxFormat/FileFactory_Spreadsheet.h +++ b/OOXML/XlsxFormat/FileFactory_Spreadsheet.h @@ -30,8 +30,6 @@ * */ #pragma once -#ifndef OOX_XLSXFILE_FACTORY_INCLUDE_H_ -#define OOX_XLSXFILE_FACTORY_INCLUDE_H_ #include "../Base/SmartPtr.h" #include "../SystemUtility/SystemUtility.h" @@ -53,5 +51,3 @@ namespace OOX NSCommon::smart_ptr CreateFile(const OOX::CPath& oRootPath, const OOX::CPath& oPath, OOX::Rels::CRelationShip* pRelation, OOX::Document *pMain); } } // namespace OOX - -#endif // OOX_XLSXFILE_FACTORY_INCLUDE_H_ diff --git a/OOXML/XlsxFormat/FileTypes_Spreadsheet.cpp b/OOXML/XlsxFormat/FileTypes_Spreadsheet.cpp index e5c88368de..4bdcf456da 100644 --- a/OOXML/XlsxFormat/FileTypes_Spreadsheet.cpp +++ b/OOXML/XlsxFormat/FileTypes_Spreadsheet.cpp @@ -86,6 +86,11 @@ namespace OOX L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/table", L"tables/table", true, true); + const FileType TableSingleCells (L"../tables", L"tableSingleCells.xml", + L"application/vnd.openxmlformats-officedocument.spreadsheetml.tableSingleCells+xml", + L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/tableSingleCells", + L"tables/tableSingleCells", true, true); + const FileType QueryTable (L"../queryTables", L"queryTable.xml", L"application/vnd.openxmlformats-officedocument.spreadsheetml.queryTable+xml", L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/queryTable", @@ -172,10 +177,14 @@ namespace OOX L"application/vnd.ms-excel.rdrichvaluestructure+xml", L"http://schemas.microsoft.com/office/2017/06/relationships/rdRichValueStructure"); - const FileType RdRichValueTypes (L"richData", L"rdRichValueTypes..xml", + const FileType RdRichValueTypes (L"richData", L"rdRichValueTypes.xml", L"application/vnd.ms-excel.rdrichvaluetypes+xml", L"http://schemas.microsoft.com/office/2017/06/relationships/rdRichValueTypes"); + const FileType XmlMaps (L"", L"xmlMaps.xml", + L"application/xml", + L"http://schemas.openxmlformats.org/officeDocument/2006/relationships/xmlMaps"); + const FileType SpreadsheetFlat (L"", L"", L"", L""); } // namespace FileTypes diff --git a/OOXML/XlsxFormat/FileTypes_Spreadsheet.h b/OOXML/XlsxFormat/FileTypes_Spreadsheet.h index 0204c80566..3f71d38ed8 100644 --- a/OOXML/XlsxFormat/FileTypes_Spreadsheet.h +++ b/OOXML/XlsxFormat/FileTypes_Spreadsheet.h @@ -60,6 +60,8 @@ namespace OOX extern const FileType Table; + extern const FileType TableSingleCells; + extern const FileType QueryTable; extern const FileType Connections; @@ -100,6 +102,8 @@ namespace OOX extern const FileType RdRichValueStructure; extern const FileType RdRichValueTypes; + + extern const FileType XmlMaps; } // namespace FileTypes } } // namespace OOX diff --git a/OOXML/XlsxFormat/NamedSheetViews/NamedSheetViews.cpp b/OOXML/XlsxFormat/NamedSheetViews/NamedSheetViews.cpp index 7949bbde33..10ba2ef1ed 100644 --- a/OOXML/XlsxFormat/NamedSheetViews/NamedSheetViews.cpp +++ b/OOXML/XlsxFormat/NamedSheetViews/NamedSheetViews.cpp @@ -32,8 +32,8 @@ #include "NamedSheetViews.h" #include "../Styles/dxf.h" -#include "../../Binary/Sheets/Reader/BinaryWriter.h" -#include "../../Binary/Sheets/Writer/BinaryReader.h" +#include "../../Binary/Sheets/Reader/BinaryWriterS.h" +#include "../../Binary/Sheets/Writer/BinaryReaderS.h" #include "../../Common/SimpleTypes_Spreadsheet.h" #include "../Styles/Colors.h" diff --git a/OOXML/XlsxFormat/Pivot/PivotCacheChildOther.cpp b/OOXML/XlsxFormat/Pivot/PivotCacheChildOther.cpp index 76690fe90e..7f01ca3d8c 100644 --- a/OOXML/XlsxFormat/Pivot/PivotCacheChildOther.cpp +++ b/OOXML/XlsxFormat/Pivot/PivotCacheChildOther.cpp @@ -1,4 +1,4 @@ -/* +/* * (c) Copyright Ascensio System SIA 2010-2024 * * This program is a free software product. You can redistribute it and/or @@ -38,10 +38,15 @@ #include "../../XlsbFormat/Biff12_unions/MG.h" #include "../../XlsbFormat/Biff12_unions/MGMAPS.h" #include "../../XlsbFormat/Biff12_unions/MAP.h" +#include "../../XlsbFormat/Biff12_unions/PCDCALCITEMS.h" +#include "../../XlsbFormat/Biff12_unions/PCDCALCITEM.h" #include "../../XlsbFormat/Biff12_records/BeginDim.h" #include "../../XlsbFormat/Biff12_records/BeginMG.h" #include "../../XlsbFormat/Biff12_records/BeginMap.h" +#include "../../XlsbFormat/Biff12_records/BeginPCDCalcItems.h" +#include "../../XlsbFormat/Biff12_records/BeginPCDCalcItem.h" + namespace OOX { @@ -364,5 +369,137 @@ XLS::BaseObjectPtr CMeasureDimensionMap::toBin() return objectPtr; } +void CCalculatedItems::fromXML(XmlUtils::CXmlLiteReader& oReader) +{ + WritingElement_ReadAttributes_Start( oReader ) + WritingElement_ReadAttributes_Read_if ( oReader, L"count", m_oCount ) + WritingElement_ReadAttributes_End( oReader ) + + auto nCurDepth = oReader.GetDepth(); + while( oReader.ReadNextSiblingNode( nCurDepth ) ) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + + if ( L"calculatedItem" == sName ) + { + CCalculatedItem* pCalcItem = new CCalculatedItem(); + *pCalcItem = oReader; + m_arrItems.push_back(pCalcItem); + } + } +} + +void CCalculatedItems::toXML(NSStringUtils::CStringBuilder& writer) const +{ + writer.WriteString(L""); + else + { + writer.WriteString(L"/>"); + return; + } + + for ( size_t i = 0; i < m_arrItems.size(); ++i) + { + if ( m_arrItems[i] ) + { + m_arrItems[i]->toXML(writer); + } + } + writer.WriteString(L""); +} + +void CCalculatedItems::fromBin(XLS::BaseObjectPtr& obj) +{ + auto ptr = static_cast(obj.get()); + if(!ptr) + return; + m_oCount = (_UINT32)ptr->m_arPCDCALCITEM.size(); + for(auto i:ptr->m_arPCDCALCITEM) + m_arrItems.push_back(new CCalculatedItem(i)); +} + +XLS::BaseObjectPtr CCalculatedItems::toBin() +{ + auto ptr(new XLSB::PCDCALCITEMS); + XLS::BaseObjectPtr objectPtr(ptr); + for(auto i : m_arrItems) + ptr->m_arPCDCALCITEM.push_back(i->toBin()); + + return objectPtr; +} + + +void CCalculatedItem::fromXML(XmlUtils::CXmlLiteReader& oReader) +{ + ReadAttributes( oReader ); + int nCurDepth = oReader.GetDepth(); + while( oReader.ReadNextSiblingNode( nCurDepth ) ) + { + std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); + if ( L"pivotArea" == sName ) + m_oPivotArea = oReader; + else if (L"extLst" == sName) + m_oExtLst = oReader; + } +} + +void CCalculatedItem::toXML(NSStringUtils::CStringBuilder& writer) const +{ + writer.WriteString(L""); + return; + } + writer.WriteString(L">"); + if(m_oPivotArea.IsInit()) + m_oPivotArea->toXML(writer); + if(m_oExtLst.IsInit()) + writer.WriteString(m_oExtLst->toXMLWithNS(_T(""))); + writer.WriteString(L""); +} + +void CCalculatedItem::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) +{ + WritingElement_ReadAttributes_Start( oReader ) + WritingElement_ReadAttributes_Read_if ( oReader, L"field", m_oField ) + WritingElement_ReadAttributes_Read_else_if ( oReader, L"formula", m_oFormula ) + WritingElement_ReadAttributes_End( oReader ) +} + +XLS::BaseObjectPtr CCalculatedItem::toBin() +{ + auto ptr(new XLSB::PCDCALCITEM); + auto ptr1(new XLSB::BeginPCDCalcItem); + ptr->m_BrtBeginPCDCalcItem = XLS::BaseObjectPtr{ptr1}; + XLS::BaseObjectPtr objectPtr(ptr); + + if(m_oFormula.IsInit()) + ptr1->fmla = m_oFormula.get(); + + if(m_oPivotArea.IsInit()) + ptr->m_PIVOTRULE = m_oPivotArea->toBin(); + return objectPtr; +} + +void CCalculatedItem::fromBin(XLS::BaseObjectPtr& obj) +{ + auto ptr = static_cast(obj.get()); + auto ptr1 = static_cast(ptr->m_BrtBeginPCDCalcItem.get()); + + m_oFormula = ptr1->fmla.getAssembledFormula(); + + if(ptr->m_PIVOTRULE != nullptr) + { + m_oPivotArea = ptr->m_PIVOTRULE; + } + +} + } } diff --git a/OOXML/XlsxFormat/Pivot/PivotCacheChildOther.h b/OOXML/XlsxFormat/Pivot/PivotCacheChildOther.h index 6cc92e4d5e..bee891b89e 100644 --- a/OOXML/XlsxFormat/Pivot/PivotCacheChildOther.h +++ b/OOXML/XlsxFormat/Pivot/PivotCacheChildOther.h @@ -1,4 +1,4 @@ -/* +/* * (c) Copyright Ascensio System SIA 2010-2024 * * This program is a free software product. You can redistribute it and/or @@ -37,6 +37,7 @@ #include "../FileTypes_Spreadsheet.h" #include "../../Common/ComplexTypes.h" +#include "PivotTable.h" namespace OOX { @@ -192,5 +193,56 @@ public: nullable_int m_oCount; }; +class CCalculatedItem : public WritingElement +{ +public: + WritingElement_AdditionMethods(CCalculatedItem) + WritingElement_XlsbConstructors(CCalculatedItem) + CCalculatedItem(){} + virtual ~CCalculatedItem() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) + { + } + virtual std::wstring toXML() const + { + return _T(""); + } + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); + + nullable m_oPivotArea; + nullable_uint m_oField; + nullable_string m_oFormula; + nullable m_oExtLst; +}; + +class CCalculatedItems: public WritingElementWithChilds +{ +public: + WritingElement_AdditionMethods(CCalculatedItems) + WritingElement_XlsbConstructors(CCalculatedItems) + CCalculatedItems(){} + virtual ~CCalculatedItems() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) + { + } + virtual std::wstring toXML() const + { + return _T(""); + } + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + void fromBin(XLS::BaseObjectPtr& obj); + XLS::BaseObjectPtr toBin(); + + nullable_int m_oCount; +}; + } } diff --git a/OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h b/OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h index 444b2e9494..625422b2db 100644 --- a/OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h +++ b/OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h @@ -600,6 +600,7 @@ namespace OOX nullable m_oDimensions; nullable m_oMeasureGroups; nullable m_oMaps; + nullable m_oCalculatedItems; //calculatedItems (Calculated Items) §18.10.1.9 //calculatedMembers (Calculated Members) §18.10.1.11 @@ -684,6 +685,7 @@ namespace OOX nullable m_oPivotCashDefinition; private: CPath m_oReadPath; + std::wstring prepareData() const; BYTE *m_pData; long m_nDataLength; diff --git a/OOXML/XlsxFormat/Pivot/PivotTable.h b/OOXML/XlsxFormat/Pivot/PivotTable.h index 887163400b..5aa27cd243 100644 --- a/OOXML/XlsxFormat/Pivot/PivotTable.h +++ b/OOXML/XlsxFormat/Pivot/PivotTable.h @@ -1066,6 +1066,7 @@ namespace OOX long m_nDataLength; CPath m_oReadPath; + std::wstring prepareData() const; void ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { } diff --git a/OOXML/XlsxFormat/Pivot/Pivots.cpp b/OOXML/XlsxFormat/Pivot/Pivots.cpp index b484f94540..6c40d35ac7 100644 --- a/OOXML/XlsxFormat/Pivot/Pivots.cpp +++ b/OOXML/XlsxFormat/Pivot/Pivots.cpp @@ -210,7 +210,28 @@ namespace Spreadsheet } XLS::BaseObjectPtr CPivotTableFile::WriteBin() const { - return m_oPivotTableDefinition->toBin(); + if(m_oPivotTableDefinition.IsInit()) + return m_oPivotTableDefinition->toBin(); + else if(m_nDataLength && m_pData) + { + CPivotTableDefinition tableDef; + { + XmlUtils::CXmlLiteReader reader; + { + auto wstringData = prepareData(); + reader.FromString(wstringData); + } + reader.ReadNextNode(); + tableDef.fromXML(reader); + } + return tableDef.toBin(); + + } + else + { + auto ptr = new XLSB::PivotTableStream(); + return XLS::BaseObjectPtr{ptr}; + } } void CPivotTableFile::read(const CPath& oRootPath, const CPath& oPath) @@ -237,7 +258,7 @@ namespace Spreadsheet void CPivotTableFile::write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const { CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); - if ((xlsb) && (xlsb->m_bWriteToXlsb) && m_oPivotTableDefinition.IsInit()) + if ((xlsb) && (xlsb->m_bWriteToXlsb)) { XLS::BaseObjectPtr object = WriteBin(); xlsb->WriteBin(oPath, object.get()); @@ -265,15 +286,21 @@ namespace Spreadsheet oContent.Registration( type().OverrideType(), oDirectory, oPath.GetFilename() ); IFileContainer::Write( oPath, oDirectory, oContent ); } - const OOX::FileType CPivotTableFile::type() const - { - CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); - if ((xlsb) && (xlsb->m_bWriteToXlsb)) - { - return OOX::SpreadsheetBin::FileTypes::PivotTableBin; - } - return OOX::Spreadsheet::FileTypes::PivotTable; - } + const OOX::FileType CPivotTableFile::type() const + { + CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { + return OOX::SpreadsheetBin::FileTypes::PivotTableBin; + } + return OOX::Spreadsheet::FileTypes::PivotTable; + } + std::wstring CPivotTableFile::prepareData() const + { + std::string stringData(reinterpret_cast(m_pData), m_nDataLength); + std::wstring_convert> converter; + return converter.from_bytes(stringData); + } //------------------------------------ void CPivotTableDefinition::toXML(NSStringUtils::CStringBuilder& writer) const { @@ -3734,6 +3761,26 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" auto pivotCacheDefStream = m_oPivotCashDefinition->toBin(); return pivotCacheDefStream; } + else if(m_nDataLength && m_pData) + { + CPivotCacheDefinition cacheDef; + { + XmlUtils::CXmlLiteReader reader; + { + auto wstringData = prepareData(); + reader.FromString(wstringData); + } + reader.ReadNextNode(); + cacheDef.fromXML(reader); + } + return cacheDef.toBin(); + + } + else + { + auto ptr = new XLSB::PivotCacheDefStream(); + return XLS::BaseObjectPtr{ptr}; + } } void CPivotCacheDefinitionFile::read(const CPath& oRootPath, const CPath& oPath) { @@ -3764,8 +3811,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" bIsWritten = true; CXlsb* xlsb = dynamic_cast(File::m_pMainDocument); - if ((xlsb) && (xlsb->m_bWriteToXlsb) && m_oPivotCashDefinition.IsInit()) - { + if ((xlsb) && (xlsb->m_bWriteToXlsb)) + { XLS::BaseObjectPtr object = WriteBin(); xlsb->WriteBin(oPath, object.get()); } @@ -3801,6 +3848,12 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } return OOX::Spreadsheet::FileTypes::PivotCacheDefinition; } + std::wstring CPivotCacheDefinitionFile::prepareData() const + { + std::string stringData(reinterpret_cast(m_pData), m_nDataLength); + std::wstring_convert> converter; + return converter.from_bytes(stringData); + } //------------------------------------ void CPivotCacheDefinition::toXML(NSStringUtils::CStringBuilder& writer) const { @@ -3836,6 +3889,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" m_oCacheFields->toXML(writer); if(m_oHierarchies.IsInit()) m_oHierarchies->toXML(writer); + if(m_oCalculatedItems.IsInit()) + m_oCalculatedItems->toXML(writer); if(m_oDimensions.IsInit()) m_oDimensions->toXML(writer); if(m_oMeasureGroups.IsInit()) @@ -3864,10 +3919,11 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if (L"cacheFields" == sName) m_oCacheFields = oReader; else if (L"cacheSource" == sName) m_oCacheSource = oReader; else if (L"cacheHierarchies" == sName) m_oHierarchies = oReader; + else if (L"calculatedItems" == sName) m_oCalculatedItems = oReader; else if (L"dimensions" == sName) m_oDimensions = oReader; else if (L"maps" == sName) m_oMaps = oReader; else if (L"measureGroups" == sName) m_oMeasureGroups = oReader; - else if (L"extLst" == sName) m_oExtLst = oReader; + else if (L"extLst" == sName) m_oExtLst = oReader; } } XLS::BaseObjectPtr CPivotCacheDefinition::toBin() @@ -3881,6 +3937,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" ptr->m_PCDSOURCE = m_oCacheSource->toBin(); if(m_oHierarchies.IsInit()) ptr->m_PCDHIERARCHIES = m_oHierarchies->toBin(); + if(m_oCalculatedItems.IsInit()) + ptr->m_PCDCALCITEMS = m_oCalculatedItems->toBin(); if(m_oDimensions.IsInit()) ptr->m_DIMS = m_oDimensions->toBin(); if(m_oMeasureGroups.IsInit()) @@ -3994,6 +4052,9 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(ptr->m_PCDHIERARCHIES != nullptr) m_oHierarchies = ptr->m_PCDHIERARCHIES; + if(ptr->m_PCDCALCITEMS != nullptr) + m_oCalculatedItems = ptr->m_PCDCALCITEMS; + if(ptr->m_DIMS != nullptr) m_oDimensions = ptr->m_DIMS; diff --git a/OOXML/XlsxFormat/SharedStrings/Si.cpp b/OOXML/XlsxFormat/SharedStrings/Si.cpp index e3335860a2..c27e54d38b 100644 --- a/OOXML/XlsxFormat/SharedStrings/Si.cpp +++ b/OOXML/XlsxFormat/SharedStrings/Si.cpp @@ -157,7 +157,8 @@ namespace OOX run.ich = ptr->str.value().size(); ptr->str = ptr->str.value() + crunPtr->toBin(ind); run.ifnt = ind; - ptr->rgsStrRun.push_back(run); + if(run.ich != 0 || run.ifnt != 0) + ptr->rgsStrRun.push_back(run); continue; } auto phonPtr = static_cast(m_arrItems[i]); diff --git a/OOXML/XlsxFormat/Styles/CellStyles.cpp b/OOXML/XlsxFormat/Styles/CellStyles.cpp index 4563abeac8..39d6a4fbbb 100644 --- a/OOXML/XlsxFormat/Styles/CellStyles.cpp +++ b/OOXML/XlsxFormat/Styles/CellStyles.cpp @@ -1,4 +1,4 @@ -/* +/* * (c) Copyright Ascensio System SIA 2010-2023 * * This program is a free software product. You can redistribute it and/or @@ -93,7 +93,7 @@ namespace OOX ptr->fHidden = m_oHidden->GetValue(); else ptr->fHidden = false; - if (m_oILevel.IsInit()) + if (m_oILevel.IsInit() && m_oILevel->GetValue() >= 0 && m_oILevel->GetValue() <= 6) ptr->iLevel = m_oILevel->GetValue(); else ptr->iLevel = 0; diff --git a/OOXML/XlsxFormat/Table/Connections.cpp b/OOXML/XlsxFormat/Table/Connections.cpp index 8a4d9ca565..4c01f56f27 100644 --- a/OOXML/XlsxFormat/Table/Connections.cpp +++ b/OOXML/XlsxFormat/Table/Connections.cpp @@ -1,4 +1,4 @@ -/* +/* * (c) Copyright Ascensio System SIA 2010-2023 * * This program is a free software product. You can redistribute it and/or @@ -36,6 +36,7 @@ #include "../../XlsbFormat/ConnectionsStream.h" #include "../../XlsbFormat/Biff12_unions/EXTCONNECTIONS.h" #include "../../XlsbFormat/Biff12_unions/EXTCONNECTION.h" +#include "../../XlsbFormat/Biff12_unions/FRTEXTCONNECTIONS.h" #include "../../XlsbFormat/Biff12_records/BeginExtConnection.h" #include "../../XlsbFormat/Biff12_unions/ECDBPROPS.h" #include "../../XlsbFormat/Biff12_records/BeginECDbProps.h" @@ -1060,115 +1061,101 @@ namespace OOX XLS::BaseObjectPtr CConnection::toBin() { XLS::BaseObjectPtr objectPtr; - if(m_oRangePr.IsInit()) - { - auto ptr(new XLSB::EXTCONN15); - objectPtr = XLS::BaseObjectPtr{ptr}; - auto ptr1(new XLSB::BeginExtConn15); - ptr1->fAutoDelete = false; - ptr1->fExcludeFromRefreshAll = false; - ptr1->fSandbox = false; - ptr1->fUsedByAddin = false; - if(m_oId.IsInit()) - ptr1->irstId = m_oId->GetValue(); - else - ptr1->irstId = false; - ptr->m_BrtBeginExtConn15 = XLS::BaseObjectPtr{ptr1}; - ptr->m_source = m_oRangePr->toBin(); - } - else - { - auto ptr(new XLSB::EXTCONNECTION); - objectPtr = XLS::BaseObjectPtr{ptr}; - auto ptr1(new XLSB::BeginExtConnection); - ptr->m_BrtBeginExtConnection = XLS::BaseObjectPtr{ptr1}; + auto ptr(new XLSB::EXTCONNECTION); + objectPtr = XLS::BaseObjectPtr{ptr}; + auto ptr1(new XLSB::BeginExtConnection); + ptr->m_BrtBeginExtConnection = XLS::BaseObjectPtr{ptr1}; - if(m_oType.IsInit()) - ptr1->idbtype = m_oType.get(); - else - ptr1->idbtype = 0; - if(m_oName.IsInit()) - ptr1->stConnName = m_oName.get(); - else - ptr1->stConnName = L""; + if(m_oType.IsInit()) + ptr1->idbtype = m_oType.get(); + else + ptr1->idbtype = 0; + if(m_oName.IsInit()) + ptr1->stConnName = m_oName.get(); + else + ptr1->stConnName = L""; - if(m_oId.IsInit()) - ptr1->dwConnID = m_oId->GetValue(); - if(m_oCredentials.IsInit()) - ptr1->iCredMethod = m_oCredentials->GetValue(); + if(m_oId.IsInit()) + ptr1->dwConnID = m_oId->GetValue(); + if(m_oCredentials.IsInit()) + ptr1->iCredMethod = m_oCredentials->GetValue(); - if(m_oBackground.IsInit()) - ptr1->fBackgroundQuery = m_oBackground.get(); - if(m_oDeleted.IsInit()) - ptr1->fDeleted = m_oDeleted.get(); + if(m_oBackground.IsInit()) + ptr1->fBackgroundQuery = m_oBackground.get(); + if(m_oDeleted.IsInit()) + ptr1->fDeleted = m_oDeleted.get(); - if(m_oDescription.IsInit()) - { - ptr1->stConnDesc = m_oDescription.get(); - ptr1->fLoadConnectionDesc = true; - } - if(m_oInterval.IsInit()) - ptr1->wInterval = m_oInterval.get(); + if(m_oDescription.IsInit()) + { + ptr1->stConnDesc = m_oDescription.get(); + ptr1->fLoadConnectionDesc = true; + } + if(m_oInterval.IsInit()) + ptr1->wInterval = m_oInterval.get(); - if(m_oKeepAlive.IsInit()) - ptr1->fMaintain = m_oKeepAlive.get(); + if(m_oKeepAlive.IsInit()) + ptr1->fMaintain = m_oKeepAlive.get(); - if(m_oMinRefreshableVersion.IsInit()) - ptr1->bVerRefreshableMin = m_oMinRefreshableVersion.get(); - else if(m_oRefreshedVersion.IsInit()) - ptr1->bVerRefreshableMin = m_oRefreshedVersion.get(); - else - ptr1->bVerRefreshableMin = 0; + if(m_oMinRefreshableVersion.IsInit()) + ptr1->bVerRefreshableMin = m_oMinRefreshableVersion.get(); + else if(m_oRefreshedVersion.IsInit()) + ptr1->bVerRefreshableMin = m_oRefreshedVersion.get(); + else + ptr1->bVerRefreshableMin = 0; - if(m_oNew.IsInit()) - ptr1->fNewQuery = m_oNew.get(); + if(m_oNew.IsInit()) + ptr1->fNewQuery = m_oNew.get(); - if(m_oOdcFile.IsInit()) - { - ptr1->stConnectionFile = m_oOdcFile.get(); - ptr1->fLoadSourceConnectionFile = true; - } - if(m_oOnlyUseConnectionFile.IsInit()) - ptr1->fAlwaysUseConnectionFile = m_oOnlyUseConnectionFile.get(); + if(m_oOdcFile.IsInit()) + { + ptr1->stConnectionFile = m_oOdcFile.get(); + ptr1->fLoadSourceConnectionFile = true; + } + if(m_oOnlyUseConnectionFile.IsInit()) + ptr1->fAlwaysUseConnectionFile = m_oOnlyUseConnectionFile.get(); - if(m_oReconnectionMethod.IsInit()) - ptr1->irecontype = m_oReconnectionMethod.get(); + if(m_oReconnectionMethod.IsInit()) + ptr1->irecontype = m_oReconnectionMethod.get(); - if(m_oRefreshedVersion.IsInit()) - ptr1->bVerRefreshed = m_oRefreshedVersion.get(); - if(m_oRefreshOnLoad.IsInit()) - ptr1->fRefreshOnLoad = m_oRefreshOnLoad.get(); + if(m_oRefreshedVersion.IsInit()) + ptr1->bVerRefreshed = m_oRefreshedVersion.get(); + if(m_oRefreshOnLoad.IsInit()) + ptr1->fRefreshOnLoad = m_oRefreshOnLoad.get(); - if(m_oSaveData.IsInit()) - ptr1->fSaveData = m_oSaveData.get(); + if(m_oSaveData.IsInit()) + ptr1->fSaveData = m_oSaveData.get(); - if(m_oSavePassword.IsInit()) - ptr1->pc = m_oSavePassword.get(); + if(m_oSavePassword.IsInit()) + ptr1->pc = m_oSavePassword.get(); - if(m_oSingleSignOnId.IsInit()) - { - ptr1->stSso = m_oSingleSignOnId.get(); - ptr1->fLoadSSOApplicationID = true; - } - if(m_oSourceFile.IsInit()) - { - ptr1->stDataFile = m_oSourceFile.get(); - ptr1->fLoadSourceDataFile = true; - } - - if(m_oDbPr.IsInit()) - ptr->m_ECDBPROPS = m_oDbPr->toBin(); - if(m_oOlapPr.IsInit()) - ptr->m_ECOLAPPROPS = m_oOlapPr->toBin(); - if(m_oTextPr.IsInit()) - ptr->m_ECTXTWIZ = m_oTextPr->toBin(); - if(m_oWebPr.IsInit()) - ptr->m_ECWEBPROPS = m_oWebPr->toBin(); - if(m_oExtLst.IsInit()) - ptr->m_FRTEXTCONNECTIONS = m_oExtLst->toBinConnections(); - } + if(m_oSingleSignOnId.IsInit()) + { + ptr1->stSso = m_oSingleSignOnId.get(); + ptr1->fLoadSSOApplicationID = true; + } + if(m_oSourceFile.IsInit()) + { + ptr1->stDataFile = m_oSourceFile.get(); + ptr1->fLoadSourceDataFile = true; + } + if(m_oDbPr.IsInit()) + ptr->m_ECDBPROPS = m_oDbPr->toBin(); + if(m_oOlapPr.IsInit()) + ptr->m_ECOLAPPROPS = m_oOlapPr->toBin(); + if(m_oTextPr.IsInit()) + ptr->m_ECTXTWIZ = m_oTextPr->toBin(); + if(m_oWebPr.IsInit()) + ptr->m_ECWEBPROPS = m_oWebPr->toBin(); + if(m_oExtLst.IsInit()) + ptr->m_FRTEXTCONNECTIONS = m_oExtLst->toBinConnections(); + else if(m_oRangePr.IsInit()) + { + auto frtPrt(new XLSB::FRTEXTCONNECTIONS); + ptr->m_FRTEXTCONNECTIONS = XLS::BaseObjectPtr{frtPrt}; + frtPrt->m_EXTCONN15 = toBin15(); + } return objectPtr; } EElementType CConnection::getType() const diff --git a/OOXML/XlsxFormat/Table/Table.h b/OOXML/XlsxFormat/Table/Table.h index 58bfc18f29..a64d5b461a 100644 --- a/OOXML/XlsxFormat/Table/Table.h +++ b/OOXML/XlsxFormat/Table/Table.h @@ -41,6 +41,7 @@ namespace SimpleTypes { class CTableType; class CTotalsRowFunction; + class CXmlDataType; } } @@ -124,26 +125,46 @@ namespace OOX public: nullable m_oName; - nullable m_oShowColumnStripes; - nullable m_oShowFirstColumn; - nullable m_oShowLastColumn; - nullable m_oShowRowStripes; + nullable m_oShowColumnStripes; + nullable m_oShowFirstColumn; + nullable m_oShowLastColumn; + nullable m_oShowRowStripes; }; + class CXmlColumnPr : public WritingElement + { + public: + WritingElement_AdditionMethods(CXmlColumnPr) + CXmlColumnPr() {} + virtual ~CXmlColumnPr() {} + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + virtual void toXML(NSStringUtils::CStringBuilder& writer) const; + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_uint mapId; + nullable_string xpath; + nullable_bool denormalized; + nullable xmlDataType; + + //ext + }; class CTableColumn : public WritingElement { public: WritingElement_AdditionMethods(CTableColumn) WritingElement_XlsbConstructors(CTableColumn) - CTableColumn() - { - } - virtual ~CTableColumn() - { - } - virtual void fromXML(XmlUtils::CXmlNode& node) - { - } + CTableColumn() {} + virtual ~CTableColumn() {} + virtual void fromXML(XmlUtils::CXmlNode& node) {} virtual std::wstring toXML() const { return _T(""); @@ -162,24 +183,24 @@ namespace OOX void ReadAttributes(XLS::BaseObjectPtr& obj); public: - nullable_string m_oDataCellStyle; - nullable m_oDataDxfId; - nullable_string m_oHeaderRowCellStyle; - nullable m_oHeaderRowDxfId; - nullable m_oId; - nullable_string m_oName; - nullable m_oQueryTableFieldId; - nullable_string m_oTotalsRowCellStyle; - nullable m_oTotalsRowDxfId; - nullable m_oTotalsRowFunction; - nullable_string m_oTotalsRowLabel; - nullable_string m_oUniqueName; - nullable_string m_oUid; + nullable_string m_oDataCellStyle; + nullable m_oDataDxfId; + nullable_string m_oHeaderRowCellStyle; + nullable m_oHeaderRowDxfId; + nullable m_oId; + nullable_string m_oName; + nullable m_oQueryTableFieldId; + nullable_string m_oTotalsRowCellStyle; + nullable m_oTotalsRowDxfId; + nullable m_oTotalsRowFunction; + nullable_string m_oTotalsRowLabel; + nullable_string m_oUniqueName; + nullable_string m_oUid; - nullable_string m_oTotalsRowFormula; - nullable_string m_oCalculatedColumnFormula; - //xmlColumnPr; - //ext + nullable_string m_oTotalsRowFormula; + nullable_string m_oCalculatedColumnFormula; + nullable m_oXmlColumnPr; + //ext }; class CTableColumns : public WritingElementWithChilds @@ -397,16 +418,129 @@ namespace OOX { return m_oReadPath; } - - nullable m_oTable; - + nullable m_oTable; private: - CPath m_oReadPath; - - void ReadAttributes(XmlUtils::CXmlLiteReader& oReader) - { - } + CPath m_oReadPath; }; +//--------------------------------------------------------------------------------------------------------------------------------- + class CXmlPr : public WritingElement + { + public: + WritingElement_AdditionMethods(CXmlPr) + CXmlPr() {} + virtual ~CXmlPr() {} + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + virtual void toXML(NSStringUtils::CStringBuilder& writer) const {} + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_uint mapId; + nullable_string xpath; + nullable xmlDataType; + + //ext + }; + class CXmlCellPr : public WritingElement + { + public: + WritingElement_AdditionMethods(CXmlCellPr) + CXmlCellPr() {} + virtual ~CXmlCellPr() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + virtual void toXML(NSStringUtils::CStringBuilder& writer) const {} + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_uint id; + nullable_string uniqueName; + + nullable xmlPr; + //ext + }; + class CSingleXmlCell : public WritingElement + { + public: + WritingElement_AdditionMethods(CSingleXmlCell) + CSingleXmlCell() {} + virtual ~CSingleXmlCell() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + virtual void toXML(NSStringUtils::CStringBuilder& writer) const {} + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_uint connectionId; + nullable_uint id; + nullable_string r; //ref + + nullable xmlCellPr; + //ext + }; + class CSingleXmlCells : public WritingElementWithChilds + { + public: + WritingElement_AdditionMethods(CSingleXmlCells) + CSingleXmlCells() {} + virtual ~CSingleXmlCells() {} + + virtual void toXML(NSStringUtils::CStringBuilder& writer) const {} + virtual std::wstring toXML() const { return L""; } + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + virtual EElementType getType() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + }; + class CTableSingleCellsFile : public OOX::File + { + public: + CTableSingleCellsFile(OOX::Document* pMain); + CTableSingleCellsFile(OOX::Document* pMain, const CPath& uri); + CTableSingleCellsFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); + virtual ~CTableSingleCellsFile(); + + virtual void read(const CPath& oFilePath); + virtual void read(const CPath& oRootPath, const CPath& oFilePath); + virtual void write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const; + + virtual const OOX::FileType type() const; + + virtual const CPath DefaultDirectory() const; + virtual const CPath DefaultFileName() const; + + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + + nullable singleXmlCells; + }; } //Spreadsheet } // namespace OOX diff --git a/OOXML/XlsxFormat/Table/Tables.cpp b/OOXML/XlsxFormat/Table/Tables.cpp index f6f3afab2d..ea97a2801e 100644 --- a/OOXML/XlsxFormat/Table/Tables.cpp +++ b/OOXML/XlsxFormat/Table/Tables.cpp @@ -203,7 +203,91 @@ namespace Spreadsheet WritingElement_ReadAttributes_End( oReader ) } + //----------------------------------------------------------------------------------------------------------------------------- + EElementType CXmlColumnPr::getType() const + { + return et_x_xmlColumnPr; + } + void CXmlColumnPr::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "mapId", mapId) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "xpath", xpath) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "xmlDataType", xmlDataType) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "denormalized", denormalized) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CXmlColumnPr::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + } + void CXmlColumnPr::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, mapId); + pWriter->WriteString2(1, xpath); + if (xmlDataType.IsInit()) + pWriter->WriteByte1(2, xmlDataType->GetValue()); + pWriter->WriteBool2(1, denormalized); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CXmlColumnPr::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + mapId = pReader->GetULong(); + }break; + case 1: + { + xpath = pReader->GetString2(); + }break; + case 2: + { + xmlDataType.Init(); + xmlDataType->SetValueFromByte(pReader->GetUChar()); + }break; + case 3: + { + denormalized = pReader->GetBool(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CXmlColumnPr::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"xmlColumnPr"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"mapId", mapId); + pWriter->WriteAttribute2(L"xpath", xpath); + if (xmlDataType.IsInit()) pWriter->WriteAttribute(L"xmlDataType", xmlDataType->ToString()); + pWriter->WriteAttribute(L"denormalized", denormalized); + pWriter->EndAttributes(); + + pWriter->WriteNodeEnd(L"xmlColumnPr"); + } + void CXmlColumnPr::toXML(NSStringUtils::CStringBuilder& writer) const + { + writer.WriteString(L"ToString()); + WritingStringNullableAttrBool2(L"denormalized", denormalized); + writer.WriteString(L"/>"); + } + void CTableColumn::toXML(NSStringUtils::CStringBuilder& writer) const { std::wstring sRoot; @@ -221,15 +305,20 @@ namespace Spreadsheet WritingStringNullableAttrInt(L"headerRowDxfId", m_oHeaderRowDxfId, m_oHeaderRowDxfId->GetValue()); WritingStringNullableAttrString(L"totalsRowCellStyle", m_oTotalsRowCellStyle, *m_oTotalsRowCellStyle); WritingStringNullableAttrInt(L"totalsRowDxfId", m_oTotalsRowDxfId, m_oTotalsRowDxfId->GetValue()); - if(m_oTotalsRowFormula.IsInit() || m_oCalculatedColumnFormula.IsInit()) + + if (m_oTotalsRowFormula.IsInit() || m_oCalculatedColumnFormula.IsInit() || m_oXmlColumnPr.IsInit()) { writer.WriteString(L">"); - if(m_oCalculatedColumnFormula.IsInit()) + if (m_oXmlColumnPr.IsInit()) + { + m_oXmlColumnPr->toXML(writer); + } + if (m_oCalculatedColumnFormula.IsInit()) { WritingStringValEncodeXmlString(L"calculatedColumnFormula", m_oCalculatedColumnFormula.get()); } - if(m_oTotalsRowFormula.IsInit()) + if (m_oTotalsRowFormula.IsInit()) { WritingStringValEncodeXmlString(L"totalsRowFormula", m_oTotalsRowFormula.get()); } @@ -253,10 +342,12 @@ namespace Spreadsheet { std::wstring sName = XmlUtils::GetNameNoNS(oReader.GetName()); - if ( (L"totalsRowFormula") == sName ) + if (L"totalsRowFormula" == sName) m_oTotalsRowFormula = oReader.GetText3(); - else if ( (L"calculatedColumnFormula") == sName ) + else if (L"calculatedColumnFormula" == sName) m_oCalculatedColumnFormula = oReader.GetText3(); + else if (L"xmlColumnPr" == sName) + m_oXmlColumnPr = oReader; } } void CTableColumn::fromBin(XLS::BaseObjectPtr& obj) @@ -1896,6 +1987,410 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } return OOX::Spreadsheet::FileTypes::QueryTable; } +//----------------------------------------------------------------------------------------------------------------------------- + EElementType CXmlPr::getType() const + { + return et_x_xmlPr; + } + void CXmlPr::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "mapId", mapId) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "xpath", xpath) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "xmlDataType", xmlDataType) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CXmlPr::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + } + void CXmlPr::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, mapId); + pWriter->WriteString2(1, xpath); + if (xmlDataType.IsInit()) + pWriter->WriteByte1(2, xmlDataType->GetValue()); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CXmlPr::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + mapId = pReader->GetULong(); + }break; + case 1: + { + xpath = pReader->GetString2(); + }break; + case 2: + { + xmlDataType.Init(); + xmlDataType->SetValueFromByte(pReader->GetUChar()); + }break; + } + } + pReader->Seek(_end_rec); + } + void CXmlPr::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"xmlPr"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"mapId", mapId); + pWriter->WriteAttribute2(L"xpath", xpath); + if (xmlDataType.IsInit()) pWriter->WriteAttribute(L"xmlDataType", xmlDataType->ToString()); + pWriter->EndAttributes(); + + pWriter->WriteNodeEnd(L"xmlPr"); + } +//----------------------------------------------------------------------------------------------------------------------------- + EElementType CXmlCellPr::getType() const + { + return et_x_xmlCellPr; + } + void CXmlCellPr::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "uniqueName", uniqueName) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "id", id) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CXmlCellPr::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetNameNoNS(); + + if (L"xmlPr" == sName) + { + xmlPr = oReader; + } + } + } + void CXmlCellPr::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteString2(0, uniqueName); + pWriter->WriteUInt2(1, id); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + pWriter->WriteRecord2(0, xmlPr); + } + void CXmlCellPr::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + uniqueName = pReader->GetString2(); + }break; + case 1: + { + id = pReader->GetULong(); + }break; + } + } + while (pReader->GetPos() < _end_rec) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + xmlPr.Init(); + xmlPr->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CXmlCellPr::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"xmlCellPr"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"id", id); + pWriter->WriteAttribute2(L"uniqueName", uniqueName); + pWriter->EndAttributes(); + + if (xmlPr.IsInit()) + xmlPr->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"xmlCellPr"); + } +//----------------------------------------------------------------------------------------------------------------------------- + EElementType CSingleXmlCell::getType() const + { + return et_x_SingleXmlCell; + } + void CSingleXmlCell::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "connectionId", connectionId) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "id", id) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "r", r) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CSingleXmlCell::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + + if (oReader.IsEmptyNode()) + return; + + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetNameNoNS(); + + if (L"xmlCellPr" == sName) + { + xmlCellPr = oReader; + } + } + } + void CSingleXmlCell::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, connectionId); + pWriter->WriteUInt2(1, id); + pWriter->WriteString2(2, r); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + pWriter->WriteRecord2(0, xmlCellPr); + } + void CSingleXmlCell::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + connectionId = pReader->GetULong(); + }break; + case 1: + { + id = pReader->GetULong(); + }break; + case 2: + { + r = pReader->GetString2(); + }break; + } + } + while (pReader->GetPos() < _end_rec) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + xmlCellPr.Init(); + xmlCellPr->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CSingleXmlCell::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"singleXmlCell"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"id", id); + pWriter->WriteAttribute2(L"r", r); + pWriter->WriteAttribute2(L"connectionId", connectionId); + pWriter->EndAttributes(); + + if (xmlCellPr.IsInit()) + xmlCellPr->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"singleXmlCell"); + } +//----------------------------------------------------------------------------------------------------------------------------- + void CSingleXmlCells::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + if (oReader.IsEmptyNode()) + return; + + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetNameNoNS(); + + if (L"singleXmlCell" == sName) + { + CSingleXmlCell* pItem = new CSingleXmlCell(); + *pItem = oReader; + + if (pItem) + m_arrItems.push_back(pItem); + } + } + } + EElementType CSingleXmlCells::getType() const + { + return et_x_SingleXmlCells; + } + void CSingleXmlCells::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + m_arrItems.push_back(new CSingleXmlCell()); + m_arrItems.back()->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + } + void CSingleXmlCells::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + for (size_t i = 0; i < m_arrItems.size(); ++i) + pWriter->WriteRecord2(0, dynamic_cast(m_arrItems[i])); + } + void CSingleXmlCells::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"singleXmlCells"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"xmlns", L"http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + pWriter->EndAttributes(); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"singleXmlCells"); + } +//----------------------------------------------------------------------------------------------------------------------------- + CTableSingleCellsFile::CTableSingleCellsFile(OOX::Document* pMain) : OOX::File(pMain) + { + } + CTableSingleCellsFile::CTableSingleCellsFile(OOX::Document* pMain, const CPath& uri) : OOX::File(pMain) + { + read(uri.GetDirectory(), uri); + } + CTableSingleCellsFile::CTableSingleCellsFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::File(pMain) + { + read(oRootPath, oPath); + } + CTableSingleCellsFile::~CTableSingleCellsFile() + { + } + void CTableSingleCellsFile::read(const CPath& oFilePath) + { + CPath oRootPath; + read(oRootPath, oFilePath); + } + void CTableSingleCellsFile::read(const CPath& oRootPath, const CPath& oFilePath) + { + XmlUtils::CXmlLiteReader oReader; + + if (!oReader.FromFile(oFilePath.GetPath())) + return; + + if (!oReader.ReadNextNode()) + return; + + singleXmlCells = oReader; + } + void CTableSingleCellsFile::write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const + { + NSBinPptxRW::CXmlWriter oXmlWriter; + oXmlWriter.WriteString((L"")); + + oXmlWriter.m_lDocType = XMLWRITER_DOC_TYPE_XLSX; + + if (singleXmlCells.IsInit()) + singleXmlCells->toXmlWriter(&oXmlWriter); + + NSFile::CFileBinary::SaveToFile(oFilePath.GetPath(), oXmlWriter.GetXmlString()); + + oContent.Registration(type().OverrideType(), oDirectory, oFilePath.GetFilename()); + } + const OOX::FileType CTableSingleCellsFile::type() const + { + return FileTypes::TableSingleCells; + } + const OOX::CPath CTableSingleCellsFile::DefaultDirectory() const + { + return type().DefaultDirectory(); + } + const OOX::CPath CTableSingleCellsFile::DefaultFileName() const + { + return type().DefaultFileName(); + } + void CTableSingleCellsFile::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + + switch (_rec) + { + case 0: + { + singleXmlCells.Init(); + singleXmlCells->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + } + void CTableSingleCellsFile::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteRecord2(0, singleXmlCells); + } } //Spreadsheet } // namespace OOX diff --git a/OOXML/XlsxFormat/Workbook/CustomsXml.cpp b/OOXML/XlsxFormat/Workbook/CustomsXml.cpp new file mode 100644 index 0000000000..e90a857e99 --- /dev/null +++ b/OOXML/XlsxFormat/Workbook/CustomsXml.cpp @@ -0,0 +1,561 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#include "CustomsXml.h" + +#include "../FileTypes_Spreadsheet.h" + +#include "../../../DesktopEditor/common/SystemUtils.h" +#include "../../Binary/Presentation/BinaryFileReaderWriter.h" +#include "../../Binary/Presentation/XmlWriter.h" + +namespace OOX +{ +namespace Spreadsheet +{ + CXmlMapsFile::CXmlMapsFile(OOX::Document* pMain) : OOX::File(pMain) + { + } + CXmlMapsFile::CXmlMapsFile(OOX::Document* pMain, const CPath& uri) : OOX::File(pMain) + { + read(uri.GetDirectory(), uri); + } + CXmlMapsFile::CXmlMapsFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::File(pMain) + { + read(oRootPath, oPath); + } + CXmlMapsFile::~CXmlMapsFile() + { + } + void CXmlMapsFile::read(const CPath& oFilePath) + { + CPath oRootPath; + read(oRootPath, oFilePath); + } + void CXmlMapsFile::read(const CPath& oRootPath, const CPath& oFilePath) + { + XmlUtils::CXmlLiteReader oReader; + + if (!oReader.FromFile(oFilePath.GetPath())) + return; + + if (!oReader.ReadNextNode()) + return; + + m_MapInfo = oReader; + } + void CXmlMapsFile::write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const + { + NSBinPptxRW::CXmlWriter oXmlWriter; + oXmlWriter.WriteString((L"")); + + oXmlWriter.m_lDocType = XMLWRITER_DOC_TYPE_XLSX; + + if (m_MapInfo.IsInit()) + m_MapInfo->toXmlWriter(&oXmlWriter); + + NSFile::CFileBinary::SaveToFile(oFilePath.GetPath(), oXmlWriter.GetXmlString()); + + oContent.Registration(type().OverrideType(), oDirectory, oFilePath.GetFilename()); + } + const OOX::FileType CXmlMapsFile::type() const + { + return FileTypes::XmlMaps; + } + const OOX::CPath CXmlMapsFile::DefaultDirectory() const + { + return type().DefaultDirectory(); + } + const OOX::CPath CXmlMapsFile::DefaultFileName() const + { + return type().DefaultFileName(); + } + void CXmlMapsFile::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + + switch (_rec) + { + case 0: + { + m_MapInfo.Init(); + m_MapInfo->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); + } + void CXmlMapsFile::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) + { + smart_ptr rels_old = pWriter->GetRels(); + pWriter->SetRels(dynamic_cast((CMapInfo*)this)); + + pWriter->WriteRecord2(0, m_MapInfo); + + pWriter->SetRels(rels_old); + } +//-------------------------------------------------------------------------------------------------------------- + EElementType CMapInfo::getType() const + { + return et_x_MapInfo; + } + void CMapInfo::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "SelectionNamespaces", SelectionNamespaces) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CMapInfo::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetNameNoNS(); + + OOX::Spreadsheet::WritingElement* pItem = NULL; + if (L"Schema" == sName) + { + pItem = new OOX::Spreadsheet::CSchema(); + } + else if (L"Map" == sName) + { + pItem = new OOX::Spreadsheet::CMap(); + } + if (pItem) + { + pItem->fromXML(oReader); + m_arrItems.push_back(pItem); + } + } + } + void CMapInfo::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteString2(0, SelectionNamespaces); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + { + int type = 0xff; //todooo predefine type for ??? + switch (m_arrItems[i]->getType()) + { + case et_x_Schema: type = 0; break; + case et_x_Map: type = 1; break; + } + if (type != 0xff) + pWriter->WriteRecord2(type, dynamic_cast(m_arrItems[i])); + } + } + void CMapInfo::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + SelectionNamespaces = pReader->GetString2(); + }break; + } + } + while (pReader->GetPos() < _end_rec) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + m_arrItems.push_back(new CSchema()); + m_arrItems.back()->fromPPTY(pReader); + }break; + case 1: + { + m_arrItems.push_back(new CMap()); + m_arrItems.back()->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CMapInfo::toXmlWriter(NSBinPptxRW::CXmlWriter * pWriter) const + { + pWriter->StartNode(L"MapInfo"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"xmlns", L"http://schemas.openxmlformats.org/spreadsheetml/2006/main"); + pWriter->WriteAttribute2(L"SelectionNamespaces", SelectionNamespaces); + pWriter->EndAttributes(); + + for (size_t i = 0; i < m_arrItems.size(); ++i) + m_arrItems[i]->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"MapInfo"); + } + EElementType CMap::getType() const + { + return et_x_Map; + } + void CMap::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "ID", ID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Name", Name) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "RootElement", RootElement) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "SchemaID", SchemaID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ShowImportExportValidationErrors", ShowImportExportValidationErrors) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "AutoFit", AutoFit) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Append", Append) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "PreserveSortAFLayout", PreserveSortAFLayout) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "PreserveFormat", PreserveFormat) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CMap::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + + int nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + std::wstring sName = oReader.GetName(); + + if (L"DataBinding" == sName) + { + DataBinding = oReader; + } + } + } + void CMap::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, ID); + pWriter->WriteString2(1, Name); + pWriter->WriteString2(2, RootElement); + pWriter->WriteString2(3, SchemaID); + pWriter->WriteBool2(4, ShowImportExportValidationErrors); + pWriter->WriteBool2(5, AutoFit); + pWriter->WriteBool2(6, Append); + pWriter->WriteBool2(7, PreserveSortAFLayout); + pWriter->WriteBool2(8, PreserveFormat); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + + pWriter->WriteRecord2(0, DataBinding); + } + void CMap::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + ID = pReader->GetULong(); + }break; + case 1: + { + Name = pReader->GetString2(); + }break; + case 2: + { + RootElement = pReader->GetString2(); + }break; + case 3: + { + SchemaID = pReader->GetString2(); + }break; + case 4: + { + ShowImportExportValidationErrors = pReader->GetBool(); + }break; + case 5: + { + AutoFit = pReader->GetBool(); + }break; + case 6: + { + Append = pReader->GetBool(); + }break; + case 7: + { + PreserveSortAFLayout = pReader->GetBool(); + }break; + case 8: + { + PreserveFormat = pReader->GetBool(); + }break; + } + } + while (pReader->GetPos() < _end_rec) + { + BYTE _rec = pReader->GetUChar(); + switch (_rec) + { + case 0: + { + DataBinding.Init(); + DataBinding->fromPPTY(pReader); + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CMap::toXmlWriter(NSBinPptxRW::CXmlWriter * pWriter) const + { + pWriter->StartNode(L"Map"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"ID", ID); + pWriter->WriteAttribute2(L"RootElement", RootElement); + pWriter->WriteAttribute2(L"Name", Name); + pWriter->WriteAttribute2(L"SchemaID", SchemaID); + pWriter->WriteAttribute(L"ShowImportExportValidationErrors", ShowImportExportValidationErrors); + pWriter->WriteAttribute(L"AutoFit", AutoFit); + pWriter->WriteAttribute(L"Append", Append); + pWriter->WriteAttribute(L"PreserveSortAFLayout", PreserveSortAFLayout); + pWriter->WriteAttribute(L"PreserveFormat", PreserveFormat); + pWriter->EndAttributes(); + + if (DataBinding.IsInit()) + DataBinding->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"Map"); + } + EElementType CDataBinding::getType() const + { + return et_x_Map; + } + void CDataBinding::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "ConnectionID", ConnectionID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "DataBindingName", DataBindingName) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "FileBindingName", FileBindingName) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "SchemaID", SchemaID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "FileBinding", FileBinding) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "DataBindingLoadMode", DataBindingLoadMode) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CDataBinding::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + + content = oReader.GetInnerXml(); + } + void CDataBinding::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteUInt2(0, ConnectionID); + pWriter->WriteString2(1, DataBindingName); + pWriter->WriteString2(2, FileBindingName); + pWriter->WriteString2(3, SchemaID); + pWriter->WriteBool2(4, FileBinding); + pWriter->WriteUInt2(5, DataBindingLoadMode); + pWriter->WriteString2(6, content); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CDataBinding::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + ConnectionID = pReader->GetULong(); + }break; + case 1: + { + DataBindingName = pReader->GetString2(); + }break; + case 2: + { + FileBindingName = pReader->GetString2(); + }break; + case 3: + { + SchemaID = pReader->GetString2(); + }break; + case 4: + { + FileBinding = pReader->GetBool(); + }break; + case 5: + { + DataBindingLoadMode = pReader->GetULong(); + }break; + case 6: + { + content = pReader->GetString2(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CDataBinding::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"DataBinding"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"ConnectionID", ConnectionID); + pWriter->WriteAttribute2(L"DataBindingName", DataBindingName); + pWriter->WriteAttribute2(L"FileBindingName", FileBindingName); + pWriter->WriteAttribute2(L"SchemaID", SchemaID); + pWriter->WriteAttribute(L"FileBinding", FileBinding); + pWriter->WriteAttribute2(L"DataBindingLoadMode", DataBindingLoadMode); + pWriter->EndAttributes(); + + if (content.is_init()) + { + pWriter->WriteString(*content); + } + pWriter->WriteNodeEnd(L"DataBinding"); + } + EElementType CSchema::getType() const + { + return et_x_Schema; + } + void CSchema::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_Read_ifChar(oReader, "ID", ID) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "SchemaRef", SchemaRef) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Namespace", Namespace) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "SchemaLanguage", SchemaLanguage) + WritingElement_ReadAttributes_EndChar_No_NS(oReader) + } + void CSchema::fromXML(XmlUtils::CXmlLiteReader& oReader) + { + ReadAttributes(oReader); + if (oReader.IsEmptyNode()) + return; + + content = oReader.GetInnerXml(); + } + void CSchema::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + pWriter->WriteString2(0, ID); + pWriter->WriteString2(1, SchemaRef); + pWriter->WriteString2(2, Namespace); + pWriter->WriteString2(3, SchemaLanguage); + pWriter->WriteString2(4, content); + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CSchema::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + { + LONG _end_rec = pReader->GetPos() + pReader->GetRecordSize() + 4; + pReader->Skip(1); // start attributes + while (true) + { + BYTE _at = pReader->GetUChar_TypeNode(); + if (_at == NSBinPptxRW::g_nodeAttributeEnd) + break; + switch (_at) + { + case 0: + { + ID = pReader->GetString2(); + }break; + case 1: + { + SchemaRef = pReader->GetString2(); + }break; + case 2: + { + Namespace = pReader->GetString2(); + }break; + case 3: + { + SchemaLanguage = pReader->GetString2(); + }break; + case 4: + { + content = pReader->GetString2(); + }break; + } + } + pReader->Seek(_end_rec); + } + void CSchema::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"Schema"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"ID", ID); + pWriter->WriteAttribute2(L"SchemaRef", SchemaRef); + pWriter->WriteAttribute2(L"Namespace", Namespace); + pWriter->WriteAttribute2(L"SchemaLanguage", SchemaLanguage); + pWriter->EndAttributes(); + + if (content.is_init()) + { + pWriter->WriteString(*content); + } + + pWriter->WriteNodeEnd(L"Schema"); + } +} +} // namespace OOX + diff --git a/OOXML/XlsxFormat/Workbook/CustomsXml.h b/OOXML/XlsxFormat/Workbook/CustomsXml.h new file mode 100644 index 0000000000..b077a1014d --- /dev/null +++ b/OOXML/XlsxFormat/Workbook/CustomsXml.h @@ -0,0 +1,179 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../Table/Autofilter.h" +#include "../../DocxFormat/IFileContainer.h" +#include "../../Common/SimpleTypes_Spreadsheet.h" + +namespace OOX +{ + namespace Spreadsheet + { + class CMapInfo : public OOX::Spreadsheet::WritingElementWithChilds<> + { + public: + WritingElement_AdditionMethods(CMapInfo) + CMapInfo() {} + virtual ~CMapInfo() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + virtual void toXML(NSStringUtils::CStringBuilder& writer) const {} + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + + virtual EElementType getType() const; + + nullable_string SelectionNamespaces; + private: + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + }; +//------------------------------------------------------------------------------------------------------------------------ + class CXmlMapsFile : public OOX::File + { + public: + CXmlMapsFile(OOX::Document* pMain); + CXmlMapsFile(OOX::Document* pMain, const CPath& uri); + CXmlMapsFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); + virtual ~CXmlMapsFile(); + + virtual void read(const CPath& oPath); + virtual void read(const CPath& oRootPath, const CPath& oPath); + + virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; + virtual const OOX::FileType type() const; + + virtual const CPath DefaultDirectory() const; + virtual const CPath DefaultFileName() const; + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter); + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + + const CPath& GetReadPath(); + + nullable m_MapInfo; + private: + CPath m_oReadPath; + }; + class CDataBinding : public OOX::Spreadsheet::WritingElement + { + public: + WritingElement_AdditionMethods(CDataBinding) + CDataBinding() {} + virtual ~CDataBinding() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + virtual void toXML(NSStringUtils::CStringBuilder& writer) const {} + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter); + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_uint ConnectionID; + nullable_string DataBindingName; + nullable_string FileBindingName; + nullable_string SchemaID; + nullable_bool FileBinding; + nullable_uint DataBindingLoadMode; + nullable_string content; + }; + class CMap : public OOX::Spreadsheet::WritingElement + { + public: + WritingElement_AdditionMethods(CMap) + CMap() {} + virtual ~CMap() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + virtual void toXML(NSStringUtils::CStringBuilder& writer) const {} + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_uint ID; + nullable_string Name; + nullable_string RootElement; + nullable_string SchemaID; + nullable_bool ShowImportExportValidationErrors; + nullable_bool AutoFit; + nullable_bool Append; + nullable_bool PreserveSortAFLayout; + nullable_bool PreserveFormat; + + nullable DataBinding; + }; + class CSchema : public OOX::Spreadsheet::WritingElement + { + public: + WritingElement_AdditionMethods(CSchema) + CSchema() {} + virtual ~CSchema() {} + + virtual void fromXML(XmlUtils::CXmlNode& node) {} + virtual std::wstring toXML() const { return L""; } + virtual void toXML(NSStringUtils::CStringBuilder& writer) const {} + + virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); + virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; + + void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); + + virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; + virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); + virtual EElementType getType() const; + + nullable_string ID; + nullable_string SchemaRef; + nullable_string Namespace; + nullable_string SchemaLanguage; + nullable_string content; + }; + } //Spreadsheet +} // namespace OOX diff --git a/OOXML/XlsxFormat/Workbook/Sheets.h b/OOXML/XlsxFormat/Workbook/Sheets.h index fcb5b5af0a..e0978d5264 100644 --- a/OOXML/XlsxFormat/Workbook/Sheets.h +++ b/OOXML/XlsxFormat/Workbook/Sheets.h @@ -98,9 +98,8 @@ namespace OOX void fromBin(std::vector& obj); std::vector toBin(); virtual EElementType getType () const; - + static void AddSheetRef(const std::wstring& link, const _INT32& sheetIndex); private: - void AddSheetRef(const std::wstring& link, const _INT32& sheetIndex); void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); }; diff --git a/OOXML/XlsxFormat/Workbook/Workbook.cpp b/OOXML/XlsxFormat/Workbook/Workbook.cpp index 38179fbd5e..e02ba8919d 100644 --- a/OOXML/XlsxFormat/Workbook/Workbook.cpp +++ b/OOXML/XlsxFormat/Workbook/Workbook.cpp @@ -427,8 +427,18 @@ namespace OOX workBookStream->m_FRTWORKBOOK = m_oExtLst->toBinWorkBook(); if (m_oFileSharing.IsInit()) - workBookStream->m_BrtFileSharing = m_oFileSharing->toBin(); - + { + auto sharingVector = m_oFileSharing->toBin(); + if(sharingVector.size() == 2) + { + workBookStream->m_BrtFileSharingIso = sharingVector.at(0); + workBookStream->m_BrtFileSharing = sharingVector.at(1); + } + else if(sharingVector.size() == 1) + { + workBookStream->m_BrtFileSharing = sharingVector.at(0); + } + } return workBookStream; } void CWorkbook::read(const CPath& oPath) diff --git a/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp b/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp index 0b71a56d26..729b85fdad 100644 --- a/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp +++ b/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp @@ -1,4 +1,4 @@ -/* +/* * (c) Copyright Ascensio System SIA 2010-2023 * * This program is a free software product. You can redistribute it and/or @@ -428,13 +428,13 @@ namespace OOX if (!oReader.IsEmptyNode()) oReader.ReadTillEnd(); } - XLS::BaseObjectPtr CFileSharing::toBin() + std::vector CFileSharing::toBin() { - XLS::BaseObjectPtr objectPtr; + std::vector objectVector; if(m_oSpinCount.IsInit() || m_oAlgorithmName.IsInit() || m_oHashValue.IsInit()) { auto ptr(new XLSB::FileSharingIso); - objectPtr = XLS::BaseObjectPtr{ptr}; + XLS::BaseObjectPtr objectPtr = XLS::BaseObjectPtr{ptr}; if (m_oReadOnlyRecommended.IsInit()) ptr->fReadOnlyRec = m_oReadOnlyRecommended.get(); @@ -472,12 +472,18 @@ namespace OOX bytes1, len1); } ptr->ipdPasswordData.rgbSalt.cbLength = len1; + auto ptr1(new XLSB::FileSharing); + ptr1->wResPass = L""; + ptr1->fReadOnlyRec = ptr->fReadOnlyRec; + ptr1->stUserName = ptr->stUserName; + objectVector.push_back(objectPtr); + objectVector.push_back(XLS::BaseObjectPtr{ptr1}); } else { auto ptr(new XLSB::FileSharing); - objectPtr = XLS::BaseObjectPtr{ptr}; + XLS::BaseObjectPtr objectPtr = XLS::BaseObjectPtr{ptr}; if (m_oReadOnlyRecommended.IsInit()) ptr->fReadOnlyRec = m_oReadOnlyRecommended.get(); else @@ -490,8 +496,9 @@ namespace OOX ptr->wResPass = m_oPassword.get(); else ptr->wResPass = L""; + objectVector.push_back(objectPtr); } - return objectPtr; + return objectVector; } void CFileSharing::fromBin(XLS::BaseObjectPtr& obj) { diff --git a/OOXML/XlsxFormat/Workbook/WorkbookPr.h b/OOXML/XlsxFormat/Workbook/WorkbookPr.h index 3f32c987bf..77de4016ec 100644 --- a/OOXML/XlsxFormat/Workbook/WorkbookPr.h +++ b/OOXML/XlsxFormat/Workbook/WorkbookPr.h @@ -148,7 +148,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); - XLS::BaseObjectPtr toBin(); + std::vector toBin(); virtual EElementType getType() const; void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); diff --git a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp index 51e76b6b90..54a7654c09 100644 --- a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp +++ b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp @@ -317,21 +317,24 @@ void CConditionalFormatValueObject::toBin(XLS::StreamCacheWriterPtr& writer, con cfvo.fGTE = m_oGte->GetValue(); else cfvo.fGTE = true; - if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Number) + + auto valType = m_oType->GetValue(); + if (valType == SimpleTypes::Spreadsheet::ECfvoType::Number) cfvo.iType = XLSB::CFVOtype::CFVONUM; - else if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Minimum) + else if (valType == SimpleTypes::Spreadsheet::ECfvoType::Minimum || valType == SimpleTypes::Spreadsheet::ECfvoType::autoMin) cfvo.iType = XLSB::CFVOtype::CFVOMIN; - else if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Maximum) + else if (valType == SimpleTypes::Spreadsheet::ECfvoType::Maximum || valType == SimpleTypes::Spreadsheet::ECfvoType::autoMax) cfvo.iType = XLSB::CFVOtype::CFVOMAX; - else if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Percent) + else if (valType == SimpleTypes::Spreadsheet::ECfvoType::Percent) cfvo.iType = XLSB::CFVOtype::CFVOPERCENT; - else if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Percentile) + else if (valType == SimpleTypes::Spreadsheet::ECfvoType::Percentile) cfvo.iType = XLSB::CFVOtype::CFVOPERCENTILE; - else if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Formula) + else if (valType == SimpleTypes::Spreadsheet::ECfvoType::Formula) cfvo.iType = XLSB::CFVOtype::CFVOFMLA; else cfvo.iType = XLSB::CFVOtype::CFVONUM; - + if(valType == SimpleTypes::Spreadsheet::ECfvoType::Formula && !(m_oVal.IsInit()) && m_oFormula.IsInit()) + m_oVal = m_oFormula->m_sText; if(m_oVal.IsInit() && cfvo.iType != XLSB::CFVOtype::CFVOFMLA) try { @@ -394,6 +397,10 @@ XLS::BaseObjectPtr CConditionalFormatValueObject::toBin14(bool isIcon) ptr1->iType = XLSB::CFVOtype::CFVOPERCENTILE; else if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::Formula) ptr1->iType = XLSB::CFVOtype::CFVOFMLA; + else if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::autoMin) + ptr1->iType = XLSB::CFVOType14::CFVOAUTOMIN_14; + else if (m_oType == SimpleTypes::Spreadsheet::ECfvoType::autoMax) + ptr1->iType = XLSB::CFVOType14::CFVOAUTOMAX_14; else ptr1->iType = XLSB::CFVOtype::CFVONUM; @@ -401,19 +408,17 @@ XLS::BaseObjectPtr CConditionalFormatValueObject::toBin14(bool isIcon) ptr1->numParam.data.value = 0; else if(ptr1->iType.get_type() == XLSB::CFVOtype::CFVOMAX) ptr1->numParam.data.value = 0; - + if(static_cast<_UINT32>(ptr1->iType) == XLSB::CFVOtype::CFVOFMLA && !(m_oVal.IsInit()) && m_oFormula.IsInit() && !m_oFormula->m_sText.empty()) + m_oVal = m_oFormula->m_sText; if(static_cast<_UINT32>(ptr1->iType) == XLSB::CFVOtype::CFVOFMLA && m_oVal.IsInit()) { XLSB::FRTFormula tempFmla; tempFmla.formula = m_oVal.get(); - ptr1->FRTheader.rgFormulas.array.push_back(tempFmla); - ptr1->FRTheader.fFormula = true; - ptr1->cbFmla = 1; - } - else if (static_cast<_UINT32>(ptr1->iType) == XLSB::CFVOtype::CFVOFMLA && m_oFormula.IsInit() && !m_oFormula->m_sText.empty()) - { - XLSB::FRTFormula tempFmla; - tempFmla.formula = m_oFormula->m_sText; + auto lastValType = GETBITS(tempFmla.formula.rgce.sequence.rbegin()->get()->ptg_id.get(),5,6); + if(lastValType == 1 || lastValType == 3) + { + SETBITS(tempFmla.formula.rgce.sequence.rbegin()->get()->ptg_id.get(),5,6,2); + } ptr1->FRTheader.rgFormulas.array.push_back(tempFmla); ptr1->FRTheader.fFormula = true; ptr1->cbFmla = 1; @@ -2414,8 +2419,6 @@ void CConditionalFormattingRule::toBin(XLS::StreamCacheWriterPtr& writer, const beginExt->guid = m_oExtId.get(); auto ruleBegin(new XLSB::FRTBegin); - ruleBegin->productVersion.product = 0; - ruleBegin->productVersion.version = 0; ext.m_BrtFRTBegin = XLS::BaseObjectPtr{ruleBegin}; ext.write(writer, nullptr); } @@ -2942,46 +2945,17 @@ XLS::BaseObjectPtr CConditionalFormattingRule::WriteAttributes14(const XLS::Cel XLSB::FRTFormula tempFmla; tempFmla.formula.set_base_ref(cellRef); tempFmla.formula = i->m_sText; + auto lastValType = GETBITS(tempFmla.formula.rgce.sequence.rbegin()->get()->ptg_id.get(),5,6); + if(lastValType == 1 || lastValType == 3) + { + SETBITS(tempFmla.formula.rgce.sequence.rbegin()->get()->ptg_id.get(),5,6,2); + } ptr->FRTheader.rgFormulas.array.push_back(tempFmla); } } if(!ptr->FRTheader.rgFormulas.array.empty()) ptr->FRTheader.fFormula = true; - - if(m_oType == SimpleTypes::Spreadsheet::ECfType::colorScale || m_oType == SimpleTypes::Spreadsheet::ECfType::dataBar - || m_oType == SimpleTypes::Spreadsheet::ECfType::iconSet) - ptr->cbFmla3 = 1; - else - ptr->cbFmla1 = 1; - if(m_arrFormula.size() > 1) - ptr->cbFmla2 = 1; - } - - if(!m_arrFormula.empty() && !m_arrFormula.front()->m_sText.empty()) - { - ptr->cbFmla1 = 1; - } - else - { - ptr->cbFmla1 = 0; - } - if(!m_arrFormula.empty() && !m_arrFormula.front()->m_sText.empty()) - { - ptr->cbFmla2 = 1; - } - else - { - ptr->cbFmla2 = 0; - } - if(!m_arrFormula.empty() && !m_arrFormula.front()->m_sText.empty()) - { - ptr->cbFmla3 = 1; - } - else - { - ptr->cbFmla3 = 0; - } - + } ptr->iType = XLSB::CFType::CF_TYPE_EXPRIS; ptr->iParam =0; ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_EXPR; @@ -3146,6 +3120,23 @@ XLS::BaseObjectPtr CConditionalFormattingRule::WriteAttributes14(const XLS::Cel ptr->iParam = 1; ptr->iTemplate = XLSB::CFTemp::CF_TEMPLATE_FILTER; } + + if(!ptr->FRTheader.rgFormulas.array.empty()) + { + if(ptr->iType != XLSB::CFType::CF_TYPE_GRADIENT && ptr->iType != XLSB::CFType::CF_TYPE_DATABAR + && ptr->iType != XLSB::CFType::CF_TYPE_MULTISTATE) + { + ptr->cbFmla1 = 1; + ptr->cbFmla3 = 0; + } + else + { + ptr->cbFmla1 = 0; + ptr->cbFmla3 = 1; + } + if(m_arrFormula.size() > 1 && ptr->cbFmla1) + ptr->cbFmla2 = 1; + } return objPtr; } @@ -3869,7 +3860,11 @@ void CConditionalFormatting::toBin(XLS::StreamCacheWriterPtr& writer) writer->storeNextRecord(begin); } for(auto i: m_arrItems) + { + if(m_bIsExtended) + i->m_oExtId = L"{" + XmlUtils::GenerateGuid() + L"}"; i->toBin(writer, formatingfirstCell); + } { auto end = writer->getNextRecord(XLSB::rt_EndConditionalFormatting); writer->storeNextRecord(end); diff --git a/OOXML/XlsxFormat/Worksheets/DataValidation.cpp b/OOXML/XlsxFormat/Worksheets/DataValidation.cpp index 2843d01620..899d2fa027 100644 --- a/OOXML/XlsxFormat/Worksheets/DataValidation.cpp +++ b/OOXML/XlsxFormat/Worksheets/DataValidation.cpp @@ -407,9 +407,9 @@ xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\">"); *record << flags; } { - XLSB::UncheckedRfX ref; + XLSB::UncheckedSqRfX ref; if(m_oSqRef.IsInit()) - ref = m_oSqRef.get(); + ref.strValue = m_oSqRef.get(); *record << ref; } { diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index a0f84fefce..3284a969a7 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -1130,7 +1130,7 @@ namespace OOX } namespace SharedFormulasRef { - std::unique_ptr> sharedRefsLocations; + std::unique_ptr> sharedRefsLocations; std::unique_ptr>> ArrayRefsLocations; } void CFormula::fromBin(XLS::StreamCacheReaderPtr& reader, XLS::CFRecordPtr& record) @@ -1157,9 +1157,10 @@ namespace OOX rowRef = static_cast(BinFmla.rgce.sequence.begin()->get())->rowXlsb; ColumnRef = static_cast(BinFmla.rgcb.getPtgs().back().get())->col; if(!SharedFormulasRef::sharedRefsLocations) - SharedFormulasRef::sharedRefsLocations = std::unique_ptr>(new std::vector); - SharedFormulasRef::sharedRefsLocations->push_back(XLS::CellRef(rowRef, ColumnRef, true, true)); - m_oSi = (unsigned int)SharedFormulasRef::sharedRefsLocations->size() - 1; + SharedFormulasRef::sharedRefsLocations = std::unique_ptr>(new std::map<_UINT32, XLS::CellRef>); + m_oSi = (unsigned int)SharedFormulasRef::sharedRefsLocations->size(); + SharedFormulasRef::sharedRefsLocations->emplace(m_oSi->GetValue(), XLS::CellRef(rowRef, ColumnRef, true, true)); + } } auto fmlaRecord = reader->getNextRecord(XLSB::rt_ShrFmla); @@ -1204,12 +1205,12 @@ namespace OOX auto ColumnPart = static_cast(BinFmla.rgcb.getPtgs().back().get()); if(!SharedFormulasRef::sharedRefsLocations) return; - for(auto i = 0; i size(); i++) + for(const auto& location : *SharedFormulasRef::sharedRefsLocations) { - if(SharedFormulasRef::sharedRefsLocations->at(i).row == rowPart->rowXlsb && - SharedFormulasRef::sharedRefsLocations->at(i).column == ColumnPart->col) + if(location.second.row == rowPart->rowXlsb && + location.second.column == ColumnPart->col) { - m_oSi = i; + m_oSi = location.first; m_oT = SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeShared; } } @@ -1894,7 +1895,7 @@ namespace OOX int nCol = 0; getRowCol(nRow, nCol); xlsx->m_nLastReadCol = nCol > xlsx->m_nLastReadCol ? nCol : xlsx->m_nLastReadCol + 1; - setRowCol(xlsx->m_nLastReadRow, xlsx->m_nLastReadCol); + setRowCol(xlsx->m_nLastReadRow, xlsx->m_nLastReadCol); } void CCell::AfterRead() { @@ -2691,7 +2692,7 @@ namespace OOX void CCell::toBin(XLS::StreamCacheWriterPtr& writer) { XLS::CellRef CellReference; - XLS::CellRef* SharedFmlaRef; + XLS::CellRef* SharedFmlaRef = NULL; if((!m_oRow.IsInit() || !m_oCol.IsInit())) { if(m_oRef.IsInit()) @@ -2708,7 +2709,7 @@ namespace OOX } else { - CellReference.row = m_oRow.get() - 1; + CellReference.row = m_oRow.get() -1; CellReference.column = m_oCol.get(); } if(SharedFormulasRef::ArrayRefsLocations && SharedFormulasRef::ArrayRefsLocations->size()) @@ -2912,6 +2913,8 @@ namespace OOX XLSB::XLWideString str; if(m_oValue.IsInit()) str = m_oValue->m_sText; + else + str = L""; *CellRecord << str; } else @@ -2924,7 +2927,7 @@ namespace OOX case SimpleTypes::Spreadsheet::celltypeInlineStr: case SimpleTypes::Spreadsheet::celltypeStr: { - if(m_oValue.IsInit() || m_oRichText.IsInit()) + if(m_oValue.IsInit() || m_oRichText.IsInit() || m_oFormula.IsInit()) { if(!m_oFormula.IsInit()) CellRecord = writer->getNextRecord(XLSB::rt_CellSt); @@ -2934,8 +2937,10 @@ namespace OOX XLSB::XLWideString str; if(m_oValue.IsInit()) str = m_oValue->m_sText; - else + else if(m_oRichText.IsInit()) str = m_oRichText->ToString(); + else + str = L""; *CellRecord << str; } else @@ -2956,15 +2961,19 @@ namespace OOX else if(m_oFormula->m_oT.get() == SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeShared) { if(!SharedFormulasRef::sharedRefsLocations) - SharedFormulasRef::sharedRefsLocations = std::unique_ptr>(new std::vector); + SharedFormulasRef::sharedRefsLocations = std::unique_ptr>(new std::map<_UINT32, XLS::CellRef>); if(!m_oFormula->m_sText.empty()) { ExtraRecord = writer->getNextRecord(XLSB::rt_ShrFmla); - SharedFormulasRef::sharedRefsLocations->push_back(CellReference); + if(!m_oFormula->m_oSi.IsInit()) + m_oFormula->m_oSi = (_UINT32)SharedFormulasRef::sharedRefsLocations->size(); + SharedFormulasRef::sharedRefsLocations->emplace(m_oFormula->m_oSi->GetValue(), CellReference); + SharedFmlaRef = &CellReference; } - if(m_oFormula->m_oSi.IsInit() && m_oFormula->m_oSi->GetValue() < SharedFormulasRef::sharedRefsLocations->size()) + if(m_oFormula->m_oSi.IsInit() && SharedFormulasRef::sharedRefsLocations->find(m_oFormula->m_oSi->GetValue()) != SharedFormulasRef::sharedRefsLocations->end()) { - SharedFmlaRef = &SharedFormulasRef::sharedRefsLocations->at(m_oFormula->m_oSi->GetValue()); + if(m_oFormula->m_sText.empty()) + SharedFmlaRef = &SharedFormulasRef::sharedRefsLocations->at(m_oFormula->m_oSi->GetValue()); XLS::CellParsedFormula BinFmla(false); //пишем флаги для формулы @@ -3507,7 +3516,7 @@ namespace OOX if (parseRefA(m_oRef->c_str(), nRow, nCol)) { bRes = true; - //nRow--; + //nRow--; nCol--; } } @@ -4360,7 +4369,7 @@ namespace OOX } bool CRow::compressCell(CCell* pCell) { - if(!pCell->m_oValue.IsInit() && !m_arrItems.empty()) + if(!pCell->m_oValue.IsInit() && !pCell->m_oFormula.IsInit() && !m_arrItems.empty()) { auto prevCell = m_arrItems.back(); if(!prevCell->m_oRepeated.IsInit()) @@ -4587,6 +4596,13 @@ namespace OOX } m_mapStyleMerges2003.clear(); } + void CSheetData::ClearSharedFmlaRefs() + { + if(SharedFormulasRef::sharedRefsLocations) + SharedFormulasRef::sharedRefsLocations.reset(); + if(SharedFormulasRef::ArrayRefsLocations) + SharedFormulasRef::ArrayRefsLocations.reset(); + } void CSheetData::fromXLSB (NSBinPptxRW::CBinaryFileReader& oStream, _UINT16 nType, CSVWriter* pCSVWriter, NSFile::CStreamWriter& oStreamWriter) { oStream.XlsbSkipRecord();//XLSB::rt_BeginSheetData @@ -4723,8 +4739,7 @@ namespace OOX else delete pRow; } - if(SharedFormulasRef::sharedRefsLocations) - SharedFormulasRef::sharedRefsLocations.reset(); + ClearSharedFmlaRefs(); } XLS::BaseObjectPtr CSheetData::toBin() { @@ -4781,10 +4796,7 @@ namespace OOX } it = m_arrItems.erase(it); } - if(SharedFormulasRef::sharedRefsLocations) - SharedFormulasRef::sharedRefsLocations.reset(); - if(SharedFormulasRef::ArrayRefsLocations) - SharedFormulasRef::ArrayRefsLocations.reset(); + ClearSharedFmlaRefs(); { auto record = writer->getNextRecord(XLSB::rt_EndSheetData); writer->storeNextRecord(record); diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.h b/OOXML/XlsxFormat/Worksheets/SheetData.h index cb03de47c3..c01066637f 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.h +++ b/OOXML/XlsxFormat/Worksheets/SheetData.h @@ -310,6 +310,7 @@ namespace OOX void fromBin(XLS::StreamCacheReaderPtr& reader); XLS::BaseObjectPtr toBin(sharedFormula &sharedFormulas); void toBin(XLS::StreamCacheWriterPtr& writer); + void WriteAttributes(XLS::StreamCacheWriterPtr& writer); virtual EElementType getType () const; @@ -317,7 +318,6 @@ namespace OOX void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); void ReadAttributes(XLS::CFRecordPtr& oReader); void ReadAttributes(XLS::BaseObjectPtr& obj); - void WriteAttributes(XLS::StreamCacheWriterPtr& writer); void CheckIndex(); bool compressCell(CCell* pCell); @@ -367,6 +367,7 @@ namespace OOX std::map> m_mapStyleMerges2003; // map(row, map(col, style)) void StyleFromMapStyleMerges2003(std::map &mapStyleMerges); void AfterRead(); + void ClearSharedFmlaRefs(); private: void fromXLSBToXmlCell (CCell& pCell, CSVWriter* pCSVWriter, NSFile::CStreamWriter& oStreamWriter); diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 2a01c9e9d5..4573f24d60 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -40,7 +40,7 @@ #include "../../XlsbFormat/Biff12_records/BeginHeaderFooter.h" #include "../../XlsbFormat/Biff12_records/SheetProtectionIso.h" #include "../../XlsbFormat/Biff12_records/SheetProtection.h" -#include "../../XlsbFormat/Biff12_records/LegacyDrawingHF.h" +#include "../../XlsbFormat/Biff12_records/LegacyDrawingHF.h" #include "../../XlsbFormat/Biff12_records/Margins.h" #include "../../XlsbFormat/Biff12_records/PrintOptions.h" #include "../../XlsbFormat/Biff12_records/WsProp.h" @@ -1472,9 +1472,9 @@ namespace OOX BYTE flags = 0; if(m_oState.IsInit()) { - if(m_oState == SimpleTypes::Spreadsheet::EPaneState::panestateFrozenSplit) + if(m_oState == SimpleTypes::Spreadsheet::EPaneState::panestateFrozen) SETBIT(flags, 0, 1) - else if(m_oState == SimpleTypes::Spreadsheet::EPaneState::panestateFrozen) + else if(m_oState == SimpleTypes::Spreadsheet::EPaneState::panestateFrozenSplit) SETBIT(flags, 1, 1) } *record << flags; @@ -2812,32 +2812,47 @@ namespace OOX if(m_oOddHeader.IsInit()) dataString = m_oOddHeader->m_sText; else - dataString = L""; + dataString.setSize(0xFFFFFFFF); *begin << dataString; + } + { + XLSB::XLNullableWideString dataString; if(m_oOddFooter.IsInit()) dataString = m_oOddFooter->m_sText; else - dataString = L""; + dataString.setSize(0xFFFFFFFF); *begin << dataString; + } + { + XLSB::XLNullableWideString dataString; if(m_oEvenHeader.IsInit()) dataString = m_oEvenHeader->m_sText; else - dataString = L""; + dataString.setSize(0xFFFFFFFF); *begin << dataString; + } + { + XLSB::XLNullableWideString dataString; if(m_oEvenFooter.IsInit()) dataString = m_oEvenFooter->m_sText; else - dataString = L""; - *begin << dataString; + dataString.setSize(0xFFFFFFFF); + *begin << dataString; + } + { + XLSB::XLNullableWideString dataString; if(m_oFirstHeader.IsInit()) dataString = m_oFirstHeader->m_sText; else - dataString = L""; + dataString.setSize(0xFFFFFFFF); *begin << dataString; + } + { + XLSB::XLNullableWideString dataString; if(m_oFirstFooter.IsInit()) dataString = m_oFirstFooter->m_sText; else - dataString = L""; + dataString.setSize(0xFFFFFFFF); *begin << dataString; } writer->storeNextRecord(begin); @@ -3615,7 +3630,7 @@ namespace OOX void CSheetProtection::toBin(XLS::StreamCacheWriterPtr& writer) { XLS::CFRecordPtr record; - unsigned char *flagBuf; + unsigned char *flagBuf = NULL; if(m_oSpinCount.IsInit() || m_oHashValue.IsInit() || m_oSaltValue.IsInit()) { record = writer->getNextRecord(XLSB::rt_SheetProtectionIso); diff --git a/OdfFile/Reader/Converter/SMCustomShape2OOXML/SMCustomShape2OOXML.pri b/OdfFile/Reader/Converter/SMCustomShape2OOXML/SMCustomShape2OOXML.pri new file mode 100644 index 0000000000..d9fb024867 --- /dev/null +++ b/OdfFile/Reader/Converter/SMCustomShape2OOXML/SMCustomShape2OOXML.pri @@ -0,0 +1,15 @@ +CORE_ROOT_DIR = $$PWD/../../../.. +PWD_ROOT_DIR = $$PWD + +include($$CORE_ROOT_DIR/Common/base.pri) +include($$CORE_ROOT_DIR/Common/3dParty/icu/icu.pri) +include($$CORE_ROOT_DIR/Common/3dParty/boost/boost.pri) +ADD_DEPENDENCY(UnicodeConverter, kernel) + +HEADERS += \ + $$PWD/smcustomshapepars.h + +SOURCES += \ + $$PWD/smcustomshapepars.cpp + + diff --git a/OdfFile/Reader/Converter/SMCustomShape2OOXML/TestSMCustomShape/TestSMCustomShape.pro b/OdfFile/Reader/Converter/SMCustomShape2OOXML/TestSMCustomShape/TestSMCustomShape.pro new file mode 100644 index 0000000000..f39c1dd0b6 --- /dev/null +++ b/OdfFile/Reader/Converter/SMCustomShape2OOXML/TestSMCustomShape/TestSMCustomShape.pro @@ -0,0 +1,18 @@ +QT -= core gui + +TARGET = test +CONFIG += console +CONFIG -= app_bundle +TEMPLATE = app + +CORE_ROOT_DIR = $$PWD/../../../../.. +PWD_ROOT_DIR = $$PWD + +include($$CORE_ROOT_DIR/OdfFile/Reader/Converter/SMCustomShape2OOXML/SMCustomShape2OOXML.pri) +include($$CORE_ROOT_DIR/Common/3dParty/googletest/googletest.pri) + + + +SOURCES += main.cpp + +DESTDIR = $$PWD/build diff --git a/OdfFile/Reader/Converter/SMCustomShape2OOXML/TestSMCustomShape/main.cpp b/OdfFile/Reader/Converter/SMCustomShape2OOXML/TestSMCustomShape/main.cpp new file mode 100644 index 0000000000..512442b1fc --- /dev/null +++ b/OdfFile/Reader/Converter/SMCustomShape2OOXML/TestSMCustomShape/main.cpp @@ -0,0 +1,163 @@ +#include "gtest/gtest.h" +#include "../smcustomshapepars.h" + +TEST(SMCustomShapeTest,Number) +{ + std::wstring wsString =L"45"; + StarMathCustomShape::SMCustomShapePars oPars; + StarMathCustomShape::SMCustomShapeConversion oConvers; + oPars.StartParsSMCustomShape(wsString); + oConvers.StartConversion(oPars.GetVector(),L"gd35"); + std::wstring wsXmlString = L""; + EXPECT_EQ(oConvers.GetStringXml(),wsXmlString); +} +TEST(SMCustomShapeTest,Plus) +{ + std::wstring wsString =L"left+?f2"; + StarMathCustomShape::SMCustomShapePars oPars; + StarMathCustomShape::SMCustomShapeConversion oConvers; + oPars.StartParsSMCustomShape(wsString); + oConvers.StartConversion(oPars.GetVector(),L"gd35"); + std::wstring wsXmlString = L""; + EXPECT_EQ(oConvers.GetStringXml(),wsXmlString); +} +TEST(SMCustomShapeTest,Minus) +{ + std::wstring wsString =L"bottom-?f2 "; + StarMathCustomShape::SMCustomShapePars oPars; + StarMathCustomShape::SMCustomShapeConversion oConvers; + oPars.StartParsSMCustomShape(wsString); + oConvers.StartConversion(oPars.GetVector(),L"gd35"); + std::wstring wsXmlString = L""; + EXPECT_EQ(oConvers.GetStringXml(),wsXmlString); +} +TEST(SMCustomShapeTest,Multi) +{ + std::wstring wsString =L"?f1 *3163/7636"; + StarMathCustomShape::SMCustomShapePars oPars; + StarMathCustomShape::SMCustomShapeConversion oConvers; + oPars.StartParsSMCustomShape(wsString); + oConvers.StartConversion(oPars.GetVector(),L"gd35"); + std::wstring wsXmlString = L""; + EXPECT_EQ(oConvers.GetStringXml(),wsXmlString); +} +TEST(SMCustomShapeTest,Divide) +{ + std::wstring wsString =L"10800/cos(pi/8)"; + StarMathCustomShape::SMCustomShapePars oPars; + StarMathCustomShape::SMCustomShapeConversion oConvers; + oPars.StartParsSMCustomShape(wsString); + oConvers.StartConversion(oPars.GetVector(),L"gd35"); + std::wstring wsXmlString = L""; + EXPECT_EQ(oConvers.GetStringXml(),wsXmlString); +} +TEST(SMCustomShapeTest,Sqrt) +{ + std::wstring wsString =L"*sqrt(2)/2"; + StarMathCustomShape::SMCustomShapePars oPars; + StarMathCustomShape::SMCustomShapeConversion oConvers; + oPars.StartParsSMCustomShape(wsString); + oConvers.StartConversion(oPars.GetVector(),L"gd35"); + std::wstring wsXmlString = L""; + EXPECT_EQ(oConvers.GetStringXml(),wsXmlString); +} +TEST(SMCustomShapeTest,DoubleBracket) +{ + std::wstring wsString =L"$0 *sin(?f0 *(pi/180))"; + StarMathCustomShape::SMCustomShapePars oPars; + StarMathCustomShape::SMCustomShapeConversion oConvers; + oPars.StartParsSMCustomShape(wsString); + oConvers.StartConversion(oPars.GetVector(),L"gd35"); + std::wstring wsXmlString = L""; + EXPECT_EQ(oConvers.GetStringXml(),wsXmlString); +} +TEST(SMCustomShapeTest,Min) +{ + std::wstring wsString =L"min(?f36+25,?f37/2)"; + StarMathCustomShape::SMCustomShapePars oPars; + StarMathCustomShape::SMCustomShapeConversion oConvers; + oPars.StartParsSMCustomShape(wsString); + oConvers.StartConversion(oPars.GetVector(),L"gd35"); + std::wstring wsXmlString = L""; + EXPECT_EQ(oConvers.GetStringXml(),wsXmlString); +} +TEST(SMCustomShapeTest,Max) +{ + std::wstring wsString =L"max(?f36,2)"; + StarMathCustomShape::SMCustomShapePars oPars; + StarMathCustomShape::SMCustomShapeConversion oConvers; + oPars.StartParsSMCustomShape(wsString); + oConvers.StartConversion(oPars.GetVector(),L"gd35"); + std::wstring wsXmlString = L""; + EXPECT_EQ(oConvers.GetStringXml(),wsXmlString); +} +TEST(SMCustomShapeTest,Abs) +{ + std::wstring wsString =L"abs(?f2+?f3)"; + StarMathCustomShape::SMCustomShapePars oPars; + StarMathCustomShape::SMCustomShapeConversion oConvers; + oPars.StartParsSMCustomShape(wsString); + oConvers.StartConversion(oPars.GetVector(),L"gd35"); + std::wstring wsXmlString = L""; + EXPECT_EQ(oConvers.GetStringXml(),wsXmlString); +} +TEST(SMCustomShapeTest,Sin) +{ + std::wstring wsString =L"sin(26500)"; + StarMathCustomShape::SMCustomShapePars oPars; + StarMathCustomShape::SMCustomShapeConversion oConvers; + oPars.StartParsSMCustomShape(wsString); + oConvers.StartConversion(oPars.GetVector(),L"gd35"); + std::wstring wsXmlString = L""; + EXPECT_EQ(oConvers.GetStringXml(),wsXmlString); +} +TEST(SMCustomShapeTest,Cos) +{ + std::wstring wsString =L"cos(45/?f40)"; + StarMathCustomShape::SMCustomShapePars oPars; + StarMathCustomShape::SMCustomShapeConversion oConvers; + oPars.StartParsSMCustomShape(wsString); + oConvers.StartConversion(oPars.GetVector(),L"gd35"); + std::wstring wsXmlString = L""; + EXPECT_EQ(oConvers.GetStringXml(),wsXmlString); +} +TEST(SMCustomShapeTest,IF) +{ + std::wstring wsString =L"if(2+?f1,26500/sqrt(2),min(?f35,?f37))"; + StarMathCustomShape::SMCustomShapePars oPars; + StarMathCustomShape::SMCustomShapeConversion oConvers; + oPars.StartParsSMCustomShape(wsString); + oConvers.StartConversion(oPars.GetVector(),L"gd35"); + std::wstring wsXmlString = L""; + EXPECT_EQ(oConvers.GetStringXml(),wsXmlString); +} +TEST(SMCustomShapeTest,Tan) +{ + std::wstring wsString =L"tan(?f40*?f41)"; + StarMathCustomShape::SMCustomShapePars oPars; + StarMathCustomShape::SMCustomShapeConversion oConvers; + oPars.StartParsSMCustomShape(wsString); + oConvers.StartConversion(oPars.GetVector(),L"gd35"); + std::wstring wsXmlString = L""; + EXPECT_EQ(oConvers.GetStringXml(),wsXmlString); +} +TEST(SMCustomShapeTest,ComplexEquation) +{ + std::wstring wsString =L"sqrt(?f36 * ?f36 + ?f39 * ?f39 + 0 * 0)"; + StarMathCustomShape::SMCustomShapePars oPars; + StarMathCustomShape::SMCustomShapeConversion oConvers; + oPars.StartParsSMCustomShape(wsString); + oConvers.StartConversion(oPars.GetVector(),L"gd35"); + std::wstring wsXmlString = L""; + EXPECT_EQ(oConvers.GetStringXml(),wsXmlString); +} +TEST(SMCustomShapeTest,Atan) +{ + std::wstring wsString =L"atan(25/5)"; + StarMathCustomShape::SMCustomShapePars oPars; + StarMathCustomShape::SMCustomShapeConversion oConvers; + oPars.StartParsSMCustomShape(wsString); + oConvers.StartConversion(oPars.GetVector(),L"gd35"); + std::wstring wsXmlString = L""; + EXPECT_EQ(oConvers.GetStringXml(),wsXmlString); +} diff --git a/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.cpp b/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.cpp new file mode 100644 index 0000000000..adb91e402e --- /dev/null +++ b/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.cpp @@ -0,0 +1,769 @@ +#include "smcustomshapepars.h" + +namespace StarMathCustomShape +{ + SMCustomShapePars::SMCustomShapePars() + {} + SMCustomShapePars::~SMCustomShapePars() + { + for(CElement* pElement:m_arVecElements) + delete pElement; + } + void SMCustomShapePars::StartParsSMCustomShape(std::wstring &wsStarMath) + { + CSMReader* pReader = new CSMReader(wsStarMath); + SMCustomShapePars::ParsString(pReader,m_arVecElements); + return; + } + CElement* SMCustomShapePars::ParseElement(CSMReader* pReader) + { + CElement* pElement(nullptr); + if(!pReader->GetElement().empty()) + pElement = CElement::CreateElement(pReader->GetElement()); + else + pElement = pReader->ReadingElement(); + if(pElement != nullptr) + pElement->Parse(pReader); + return pElement; + } + void SMCustomShapePars::ParsString(CSMReader* pReader, std::vector& arVec) + { + while(!pReader->CheckIteratorPosition()) + { + CElement* pElement = SMCustomShapePars::ParseElement(pReader); + if(pElement != nullptr) + { + if(pElement->GetBaseType() == TypeElement::ArithmeticOperation && !arVec.empty()) + { + CElementArithmeticOperations* pSign = static_cast(pElement); + pSign->SetFirstValue(arVec.back()); + arVec.pop_back(); + } + arVec.push_back(pElement); + } + } + if(!pReader->GetElement().empty()) + { + CElement* pElement = SMCustomShapePars::ParseElement(pReader); + if(pElement != nullptr) + { + if(pElement->GetBaseType() == TypeElement::ArithmeticOperation && !arVec.empty()) + { + CElementArithmeticOperations* pSign = static_cast(pElement); + pSign->SetFirstValue(arVec.back()); + arVec.pop_back(); + } + arVec.push_back(pElement); + } + } + } + std::vector& SMCustomShapePars::GetVector() + { + return m_arVecElements; + } +//class CElemnt + CElement::CElement():m_wsNameFormula(L"") + {} + CElement::~CElement() + {} + CElement *CElement::CreateElement(const std::wstring& wsElement) + { + if(CElementNumber::CheckNumber(wsElement)) + return new CElementNumber(wsElement); + else if(CElementArithmeticOperations::CheckArithmeticOperators(wsElement)) + return new CElementArithmeticOperations(wsElement); + else if(wsElement == L"(") + return new CElementBracket(); + else if(wsElement == L",") + return new CElementComma(); + TypeElement enType = CElementFunction::TypeCheckingByFunction(wsElement); + if(enType != TypeElement::empty) + return new CElementFunction(enType); + if(!wsElement.empty()) + return new CElementNumber(wsElement); + return nullptr; + } + void CElement::SetBaseType(const TypeElement& enType) + { + m_enBaseType = enType; + } + TypeElement CElement::GetBaseType() + { + return m_enBaseType; + } + void CElement::SetNameFormula(const std::wstring& wsNameFormula) + { + m_wsNameFormula = wsNameFormula; + } + std::wstring CElement::GetNameFormula() + { + return m_wsNameFormula; + } +//class CElementNumber + CElementNumber::CElementNumber():m_wsNumber(L"") + {} + CElementNumber::CElementNumber(const std::wstring& wsName):m_wsNumber(wsName) + { + SetBaseType(TypeElement::NumberOrName); + } + CElementNumber::~CElementNumber() + {} + void CElementNumber::Parse(CSMReader *pReader) + { + if(!pReader->GetElement().empty()) + pReader->ClearElement(); + } + bool CElementNumber::CheckNumber(const std::wstring& wsNumber) + { + if(wsNumber.empty()) + return false; + if(wsNumber.size() > 2 && wsNumber[0] == L'?' && wsNumber[1] == L'f') + return true; + for(unsigned int i = 0;i < wsNumber.size();i++) + { + if(!iswdigit(wsNumber[i])) + return false; + } + return true; + } + void CElementNumber::ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter, const std::wstring &wsName) + { + if(m_wsNumber[0] == L'?' && m_wsNumber[1] == L'f') + m_wsNumber.replace(0,2,L"gd"); + pXmlWriter->WriteString(m_wsNumber + L" "); + } + std::wstring CElementNumber::GetString() + { + if(m_wsNumber[0] == L'?' && m_wsNumber[1] == L'f') + m_wsNumber.replace(0,2,L"gd"); + return m_wsNumber; + } +//CElementArithmeticOperations + CElementArithmeticOperations::CElementArithmeticOperations():m_enTypeSign(TypeElement::empty),m_pSecondSign(nullptr),m_pFirstValue(nullptr),m_pSecondValue(nullptr),m_uiNumberFormula(1) + {} + CElementArithmeticOperations::CElementArithmeticOperations(const std::wstring& wsSign):m_enTypeSign(TypeElement::empty),m_pSecondSign(nullptr),m_pFirstValue(nullptr),m_pSecondValue(nullptr),m_uiNumberFormula(1) + { + m_enTypeSign = CElementArithmeticOperations::SetTypeSign(wsSign); + SetBaseType(TypeElement::ArithmeticOperation); + } + CElementArithmeticOperations::~CElementArithmeticOperations() + { + delete m_pFirstValue; + delete m_pSecondValue; + delete m_pSecondSign; + } + void CElementArithmeticOperations::Parse(CSMReader *pReader) + { + if(!pReader->GetElement().empty()) + pReader->ClearElement(); + CElement* pElement = SMCustomShapePars::ParseElement(pReader); + if(pElement == nullptr) + return; + pReader->ReadingNextElement(); + if(pElement->GetBaseType() != TypeElement::ArithmeticOperation && pElement->GetBaseType() != TypeElement::comma && !ComparingPriorities(pReader->GetElement()))//утечка данных, если тип ариф знаки + { + m_pSecondValue = pElement; + pElement = nullptr; + } + else if(ComparingPriorities(pReader->GetElement())) + { + CElement* pTempElement = SMCustomShapePars::ParseElement(pReader); + if(pTempElement->GetBaseType() == TypeElement::ArithmeticOperation) + { + CElementArithmeticOperations* pTempArithOp = dynamic_cast(pTempElement); + pTempArithOp->SetFirstValue(pElement); + m_pSecondValue = pTempArithOp; + } + else + m_pSecondValue = pTempElement; + } + if(!pReader->GetDoubleSign()&& !pReader->GetElement().empty() && ComparisonSign(pReader->GetElement())) + { + pReader->SetDoubleSign(true); + CElement* pSecondSign = SMCustomShapePars::ParseElement(pReader); + if(pSecondSign != nullptr) + m_pSecondSign = pSecondSign; + pReader->SetDoubleSign(false); + } + if(pElement != nullptr) + { + if(m_pFirstValue == nullptr) + m_pFirstValue = pElement; + else if(m_pSecondValue == nullptr) + m_pSecondValue = pElement; + } + } + void CElementArithmeticOperations::ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter, const std::wstring &wsName) + { + if(wsName != L"") + SetNameFormula(wsName); + if(m_pSecondSign != nullptr) + { + CElementArithmeticOperations* pTemp = dynamic_cast(m_pSecondSign); + std::wstring wsNameValueSecondSign(L""),wsNameFirstValue(L""),wsNameSecondValue(L""); + if(pTemp->GetSecondValue() != nullptr) + wsNameValueSecondSign = ConversionValueSign(pXmlWriter,pTemp->GetSecondValue()); + if(m_pFirstValue != nullptr) + wsNameFirstValue = ConversionValueSign(pXmlWriter,m_pFirstValue); + if(m_pSecondValue != nullptr) + wsNameSecondValue = ConversionValueSign(pXmlWriter,m_pSecondValue); + pXmlWriter->WriteNodeBegin(L"a:gd",true); + if(!GetNameFormula().empty()) + pXmlWriter->WriteAttribute(L"name",GetNameFormula()); + else + pXmlWriter->WriteAttribute(L"name",L"Unknown"); + pXmlWriter->WriteString(L" fmla=\""); + SignRecording(pXmlWriter,m_enTypeSign); + SignRecording(pXmlWriter,pTemp->GetTypeSign()); + pXmlWriter->WriteString(L" "); + RecordingTheValuesSign(pXmlWriter,wsNameFirstValue,wsNameSecondValue); + if(!wsNameValueSecondSign.empty()) + pXmlWriter->WriteString(wsNameValueSecondSign + L" "); + else if(pTemp->GetSecondValue() != nullptr) + pTemp->GetSecondValue()->ConversionOOXml(pXmlWriter); + pXmlWriter->WriteString(L"\""); + pXmlWriter->WriteNodeEnd(L"",true,true); + } + else + { + bool bPlusMultiplication(false),bMinusDivision(false); + std::wstring wsNameFirstValue(L""), wsNameSecondValue(L""); + if(m_pFirstValue != nullptr) + wsNameFirstValue = ConversionValueSign(pXmlWriter,m_pFirstValue); + if(m_pSecondValue != nullptr) + wsNameSecondValue = ConversionValueSign(pXmlWriter,m_pSecondValue); + pXmlWriter->WriteNodeBegin(L"a:gd",true); + if(!GetNameFormula().empty()) + pXmlWriter->WriteAttribute(L"name",GetNameFormula()); + else + pXmlWriter->WriteAttribute(L"name",L"Unknown"); + pXmlWriter->WriteString(L" fmla=\""); + switch(m_enTypeSign) { + case TypeElement::multiplication: + case TypeElement::plus: + { + SignRecording(pXmlWriter,m_enTypeSign); + pXmlWriter->WriteString(L"/"); + bPlusMultiplication = true; + break; + } + case TypeElement::division: + case TypeElement::minus: + { + pXmlWriter->WriteString(L"+"); + SignRecording(pXmlWriter,m_enTypeSign); + bMinusDivision = true; + break; + } + default: + break; + } + pXmlWriter->WriteString(L" "); + if(bPlusMultiplication) + { + RecordingTheValuesSign(pXmlWriter,wsNameFirstValue,wsNameSecondValue); + pXmlWriter->WriteString(L"1 "); + } + else if(bMinusDivision) + { + pXmlWriter->WriteString(L"0 "); + RecordingTheValuesSign(pXmlWriter,wsNameFirstValue,wsNameSecondValue); + } + pXmlWriter->WriteString(L"\""); + pXmlWriter->WriteNodeEnd(L"",true,true); + } + } + bool CElementArithmeticOperations::CheckArithmeticOperators(const std::wstring& wsElement) + { + if(wsElement.empty()) + return false; + if(wsElement.size() == 1) + { + switch (wsElement[0]) + { + case L'+': + case L'-': + case L'*': + case L'/': + return true; + default: + return false; + } + } + else + return false; + } + //Нет сравнения + и / + bool CElementArithmeticOperations::ComparisonSign(const std::wstring& wsSign) + { + return((m_enTypeSign == TypeElement::multiplication && wsSign == L"/") || (m_enTypeSign == TypeElement::plus && wsSign == L"-")); + } + bool CElementArithmeticOperations::ComparingPriorities(const std::wstring& wsSign) + { + return ((m_enTypeSign == TypeElement::plus || m_enTypeSign == TypeElement::minus) && (wsSign == L"/" || wsSign == L"*")); + } + void CElementArithmeticOperations::SetFirstValue(CElement* pElement) + { + m_pFirstValue = pElement; + } + TypeElement CElementArithmeticOperations::SetTypeSign(const std::wstring& wsSign) + { + if(wsSign.size() > 1) + return TypeElement::empty; + switch (wsSign[0]) { + case '+': + return TypeElement::plus; + case '-': + return TypeElement::minus; + case '/': + return TypeElement::division; + case '*': + return TypeElement::multiplication; + default: + return TypeElement::empty; + } + } + TypeElement CElementArithmeticOperations::GetTypeSign() + { + return m_enTypeSign; + } + void CElementArithmeticOperations::SignRecording(XmlUtils::CXmlWriter* pXmlWriter, const TypeElement& enTypeSign) + { + switch (enTypeSign) { + case TypeElement::multiplication: + pXmlWriter->WriteString(L"*"); + break; + case TypeElement::plus: + pXmlWriter->WriteString(L"+"); + break; + case TypeElement::minus: + pXmlWriter->WriteString(L"-"); + break; + case TypeElement::division: + pXmlWriter->WriteString(L"/"); + break; + default: + break; + } + } + CElement* CElementArithmeticOperations::GetSecondValue() + { + return m_pSecondValue; + } + std::wstring CElementArithmeticOperations::ConversionValueSign(XmlUtils::CXmlWriter *pXmlWriter, CElement* pElement) + { + if(pElement->GetBaseType() != TypeElement::NumberOrName) + { + std::wstring wsTempName = GetNameFormula() + L"." + std::to_wstring(m_uiNumberFormula); + m_uiNumberFormula++; + pElement->ConversionOOXml(pXmlWriter,wsTempName); + return pElement->GetNameFormula(); + } + else + return L""; + } + void CElementArithmeticOperations::RecordingTheValuesSign(XmlUtils::CXmlWriter *pXmlWriter, const std::wstring &wsNameFirst, const std::wstring &wsNameSecond) + { + if(!wsNameFirst.empty()) + pXmlWriter->WriteString(wsNameFirst + L" "); + else if(m_pFirstValue != nullptr) + m_pFirstValue->ConversionOOXml(pXmlWriter); + else + pXmlWriter->WriteString(L"1 "); + if(!wsNameSecond.empty()) + pXmlWriter->WriteString(wsNameSecond + L" "); + else if(m_pSecondValue != nullptr) + m_pSecondValue->ConversionOOXml(pXmlWriter); + else + pXmlWriter->WriteString(L"1 "); + } +//CSMReader + CSMReader::CSMReader(std::wstring& wsStarMath):m_wsElement(L""),m_pElement(nullptr),m_bDoubleSign(false) + { + m_itStart = wsStarMath.begin(); + m_itEnd = wsStarMath.end(); + } + CSMReader::~CSMReader() + { + delete m_pElement; + } + std::wstring CSMReader::GetElement(std::wstring::iterator& itStart,std::wstring::iterator& itEnd) + { + std::wstring wsOneElement{L""}; + for(;itStart != itEnd;itStart++) + { + if(iswspace(*itStart)) + { + if(!wsOneElement.empty()) + return wsOneElement; + else + continue; + } + else if(!wsOneElement.empty() && (L'+' == *itStart || L'-' == *itStart || L'*' == *itStart || L'/' == *itStart || L',' == *itStart || L'(' == *itStart || L')' == *itStart)) + return wsOneElement; + else if(wsOneElement.empty() && (L'+' == *itStart || L'-' == *itStart || L'*' == *itStart || L'/' == *itStart || L',' == *itStart || L'(' == *itStart || L')' == *itStart)) + { + wsOneElement.push_back(*itStart); + itStart++; + return wsOneElement; + } + else + wsOneElement.push_back(*itStart); + } + if(!wsOneElement.empty()) + return wsOneElement; + else + return L""; + } + CElement *CSMReader::ReadingElement() + { + std::wstring wsElement = GetElement(m_itStart,m_itEnd); + return CElement::CreateElement(wsElement); + } + bool CSMReader::ReadingNextElement() + { + if(!m_wsElement.empty()) + return true; + m_wsElement = GetElement(m_itStart,m_itEnd); + if(!m_wsElement.empty()) + return true; + else + return false; + } + bool CSMReader::CheckIteratorPosition() + { + if(m_itStart == m_itEnd) + return true; + else + return false; + } + std::wstring CSMReader::GetElement() + { + return m_wsElement; + } + void CSMReader::ClearElement() + { + m_wsElement.clear(); + } + void CSMReader::FindingTheEndOfTheBrackets() + { + std::wstring::iterator itStartTemp = m_itStart; + unsigned int uiOpenBracket{0}; + for(;m_itStart !=m_itEnd;m_itStart++) + { + if(*m_itStart == L')' && uiOpenBracket == 0) + { + // m_itEndForBrecket = m_itEnd; + m_stEndBrecket.push(m_itEnd); + m_itEnd = m_itStart; + m_itStart = itStartTemp; + return; + } + else if(*m_itStart == L')' && uiOpenBracket != 0) + { + // m_stEndBrecket.push(m_itStart); + uiOpenBracket--; + } + else if(*m_itStart == L'(') + uiOpenBracket++; + } + } + void CSMReader::RemovingTheParenthesisIterator() + { + if(!m_stEndBrecket.empty()) + { + m_itEnd = m_stEndBrecket.top(); + m_stEndBrecket.pop(); + } + m_wsElement = GetElement(m_itStart,m_itEnd); + m_wsElement.clear(); + } + void CSMReader::SetDoubleSign(const bool& bDoubleSign) + { + m_bDoubleSign = bDoubleSign; + } + bool CSMReader::GetDoubleSign() + { + return m_bDoubleSign; + } +//CElementBracket + CElementBracket::CElementBracket() + { + SetBaseType(TypeElement::Bracket); + } + CElementBracket::~CElementBracket() + { + for(CElement* pElement:m_arElements) + delete pElement; + } + void CElementBracket::Parse(CSMReader* pReader) + { + pReader->FindingTheEndOfTheBrackets(); + SMCustomShapePars::ParsString(pReader,m_arElements); + pReader->RemovingTheParenthesisIterator(); + } + void CElementBracket::ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter, const std::wstring &wsName) + { + if(!wsName.empty()) + SetNameFormula(wsName); + for(CElement* pElement:m_arElements) + { + if(pElement != nullptr) + pElement->ConversionOOXml(pXmlWriter,wsName); + } + + } + std::vector CElementBracket::GetVector() + { + return m_arElements; + } +//CElementFunction + CElementFunction::CElementFunction():m_enTypeFunction(TypeElement::empty),m_pValue(nullptr),m_uiNumberFormula(1) + { + SetBaseType(TypeElement::Function); + } + CElementFunction::CElementFunction(const TypeElement& enType):m_pValue(nullptr),m_uiNumberFormula(1) + { + SetBaseType(TypeElement::Function); + m_enTypeFunction = enType; + } + CElementFunction::~CElementFunction() + {} + TypeElement CElementFunction::TypeCheckingByFunction(const std::wstring& wsFunction) + { + if(wsFunction == L"sqrt") + return TypeElement::sqrt; + else if(wsFunction == L"sin") + return TypeElement::sin; + else if(wsFunction == L"cos") + return TypeElement::cos; + else if(wsFunction == L"abs") + return TypeElement::abs; + else if(wsFunction == L"if") + return TypeElement::If; + else if(wsFunction == L"tan") + return TypeElement::tan; + else if(wsFunction == L"min") + return TypeElement::min; + else if(wsFunction == L"max") + return TypeElement::max; + // else if(wsFunction == L"atan2") + // return TypeElement::atan2; + else if(wsFunction == L"atan") + return TypeElement::atan; + else + return TypeElement::empty; + } + void CElementFunction::Parse(CSMReader* pReader) + { + pReader->ClearElement(); + m_pValue = SMCustomShapePars::ParseElement(pReader); + } + void CElementFunction::ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter, const std::wstring &wsName) + { + if(m_pValue == nullptr) + return; + if(!wsName.empty()) + SetNameFormula(wsName); + else + SetNameFormula(L"Function"); + switch (m_enTypeFunction) { + case TypeElement::If: + { + std::wstring wsFormula = L"?: "; + if(m_pValue->GetBaseType() == TypeElement::Bracket) + { + CElementBracket* pBracket = dynamic_cast(m_pValue); + std::vector arVector = pBracket->GetVector(); + for(unsigned int i = 0; i < arVector.size(); i++) + { + if(arVector[i]->GetBaseType() == TypeElement::comma) + { + if(i - 1 >= 0) + { + ConversionElement(pXmlWriter,arVector[i - 1],wsFormula); + } + else + wsFormula += L"1 "; + } + else if(i + 1 == arVector.size() && arVector[i]->GetBaseType() != TypeElement::comma) + ConversionElement(pXmlWriter,arVector[i],wsFormula); + } + } + SMCustomShapeConversion::WritingFormulaXml(pXmlWriter,GetNameFormula(),wsFormula); + break; + } + case TypeElement::abs: + case TypeElement::sqrt: + { + std::wstring wsFormula; + if(m_enTypeFunction == TypeElement::abs) + wsFormula = L"abs "; + else + wsFormula = L"sqrt "; + if(m_pValue->GetBaseType() == TypeElement::Bracket) + { + CElementBracket* pBracket = dynamic_cast(m_pValue); + std::vector arValues = pBracket->GetVector(); + ConversionElement(pXmlWriter,arValues[0],wsFormula); + } + else + ConversionElement(pXmlWriter,m_pValue,wsFormula); + SMCustomShapeConversion::WritingFormulaXml(pXmlWriter,GetNameFormula(),wsFormula); + break; + } + case TypeElement::min: + case TypeElement::max: + { + std::wstring wsFormula; + if(m_enTypeFunction == TypeElement::max) + wsFormula = L"max "; + else + wsFormula = L"min "; + if(m_pValue->GetBaseType() == TypeElement::Bracket) + { + CElementBracket* pBracket = dynamic_cast(m_pValue); + std::vector pElements = pBracket->GetVector(); + for(unsigned int i = 0; i < pElements.size();i++) + { + if(pElements[i]->GetBaseType() == TypeElement::comma) + { + if(i - 1 >= 0) + ConversionElement(pXmlWriter,pElements[i-1],wsFormula); + if(i + 1 <= pElements.size() && pElements[i+1]->GetBaseType() != TypeElement::comma) + ConversionElement(pXmlWriter,pElements[i+1],wsFormula); + i = pElements.size(); + } + } + SMCustomShapeConversion::WritingFormulaXml(pXmlWriter,GetNameFormula(),wsFormula); + } + break; + } + case TypeElement::sin: + case TypeElement::cos: + case TypeElement::atan: + case TypeElement::tan: + { + std::wstring wsFormula; + if(m_enTypeFunction == TypeElement::sin) + wsFormula = L"sin 1 "; + else if(m_enTypeFunction == TypeElement::cos) + wsFormula = L"cos 1 "; + else if(m_enTypeFunction == TypeElement::tan) + wsFormula = L"tan 1 "; + else + wsFormula = L"at2 1 "; + ConvertBracketsForTrigonometry(pXmlWriter,wsFormula); + SMCustomShapeConversion::WritingFormulaXml(pXmlWriter,GetNameFormula(),wsFormula); + break; + } + default: + break; + } + } + void CElementFunction::ConversionElement(XmlUtils::CXmlWriter* pXmlWriter, CElement *pElement, std::wstring &wsFormula) + { + if(pElement == nullptr) + return; + if(pElement->GetBaseType() == TypeElement::NumberOrName) + { + CElementNumber* pTempElement = dynamic_cast(pElement); + wsFormula += pTempElement->GetString() + L" "; + } + else + { + std::wstring wsNewNameFormula = GetNameFormula() + L"." + std::to_wstring(m_uiNumberFormula); + m_uiNumberFormula++; + pElement->ConversionOOXml(pXmlWriter,wsNewNameFormula); + wsFormula += pElement->GetNameFormula() + L" "; + } + } + void CElementFunction::ConvertBracketsForTrigonometry(XmlUtils::CXmlWriter* pXmlWriter, std::wstring& wsFormula) + { + if(m_pValue->GetBaseType() == TypeElement::Bracket) + { + CElementBracket* pBracket = dynamic_cast(m_pValue); + std::vector arVec = pBracket->GetVector(); + if(arVec[0] != nullptr && arVec[0]->GetBaseType() != TypeElement::comma) + ConversionElement(pXmlWriter,arVec[0],wsFormula); + } + else if(m_pValue->GetBaseType() != TypeElement::comma) + ConversionElement(pXmlWriter,m_pValue,wsFormula); + else + wsFormula += L"1 "; + } +//CElementComma + CElementComma::CElementComma() + {SetBaseType(TypeElement::comma);} + CElementComma::~CElementComma() + {} + void CElementComma::Parse(CSMReader* pReader) + { + if(!pReader->GetElement().empty()) + pReader->ClearElement(); + } + void CElementComma::ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter, const std::wstring &wsName) + {} +//SMCustomShapeConversion + SMCustomShapeConversion::SMCustomShapeConversion():m_pXmlWriter(nullptr) + {} + SMCustomShapeConversion::~SMCustomShapeConversion() + { + delete m_pXmlWriter; + } + void SMCustomShapeConversion::StartConversion(std::vector& arElements, const std::wstring& wsFormulaName) + { + if(arElements.empty()) + return; + m_pXmlWriter = new XmlUtils::CXmlWriter; + if(arElements.size() == 1 && arElements[0]->GetBaseType() == TypeElement::NumberOrName) + { + m_pXmlWriter->WriteNodeBegin(L"a:gd",true); + if(!wsFormulaName.empty()) + m_pXmlWriter->WriteAttribute(L"name",wsFormulaName); + else + m_pXmlWriter->WriteAttribute(L"name",L"Text"); + m_pXmlWriter->WriteString(L" fmla=\"val "); + arElements[0]->ConversionOOXml(m_pXmlWriter,wsFormulaName); + m_pXmlWriter->WriteString(L"\""); + m_pXmlWriter->WriteNodeEnd(L"",true,true); + } + else + { + for(CElement* pElement:arElements) + { + if(pElement != nullptr) + pElement->ConversionOOXml(m_pXmlWriter,wsFormulaName); + } + } + + } + std::wstring SMCustomShapeConversion::GetStringXml() + { + return m_pXmlWriter->GetXmlString(); + } + void SMCustomShapeConversion::WritingFormulaXml(XmlUtils::CXmlWriter* pXmlWriter,const std::wstring& wsNameFormula,const std::wstring& wsFormula) + { + pXmlWriter->WriteNodeBegin(L"a:gd",true); + pXmlWriter->WriteAttribute(L"name",wsNameFormula); + pXmlWriter->WriteAttribute(L"fmla",wsFormula); + pXmlWriter->WriteNodeEnd(L"",true,true); + } + std::wstring SMCustomShapeConversion::ParsFormulaName(const std::wstring& wsFormulaName, std::wstring &wsName) + { + if(wsFormulaName.empty()) + return L""; + std::wstring wsTempNumber; + for(wchar_t wcElement: wsFormulaName) + { + if(iswdigit(wcElement) && (L'-' == wcElement || L'.' == wcElement)) + wsTempNumber += wcElement; + else + wsName += wcElement; + } + if(!wsTempNumber.empty()) + return wsTempNumber; + else + return L""; + } +} diff --git a/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.h b/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.h new file mode 100644 index 0000000000..35b1663884 --- /dev/null +++ b/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.h @@ -0,0 +1,177 @@ +#ifndef SMCUSTOMSHAPEPARS_H +#define SMCUSTOMSHAPEPARS_H +#include +#include +#include +#include +#include +#include +#include "../../../../DesktopEditor/xml/include/xmlwriter.h" + +namespace StarMathCustomShape +{ + class CElement; + enum class TypeElement + { + //name class + NumberOrName, + ArithmeticOperation, + Function, + Bracket, + //arithmetic sign + plus, + minus, + division, + multiplication, + //function + sqrt, + abs, + sin, + cos, + tan, + min, + max, + If, + atan, + atan2, + empty, + comma, + }; + class CSMReader + { + public: + CSMReader(std::wstring& wsStarMath); + ~CSMReader(); + std::wstring GetElement(std::wstring::iterator& itStart,std::wstring::iterator& itEnd); + CElement* ReadingElement(); + bool ReadingNextElement(); + bool CheckIteratorPosition(); + std::wstring GetElement(); + void ClearElement(); + void FindingTheEndOfTheBrackets(); + void RemovingTheParenthesisIterator(); + void SetDoubleSign(const bool& bDoubleSign); + bool GetDoubleSign(); + private: + std::wstring::iterator m_itStart; + std::wstring::iterator m_itEnd,m_itEndForBrecket; + std::stack m_stEndBrecket; + std::wstring m_wsElement; + CElement* m_pElement; + bool m_bDoubleSign; + }; + class SMCustomShapePars + { + public: + SMCustomShapePars(); + ~SMCustomShapePars(); + void StartParsSMCustomShape(std::wstring& wsStarMath); + static CElement* ParseElement(CSMReader* pReader); + static void ParsString(CSMReader* pReader, std::vector& arVec); + std::vector& GetVector(); + private: + std::vector m_arVecElements; + }; + class SMCustomShapeConversion + { + public: + SMCustomShapeConversion(); + ~SMCustomShapeConversion(); + void StartConversion(std::vector& arElements, const std::wstring& wsFormulaName = L""); + std::wstring GetStringXml(); + static void WritingFormulaXml(XmlUtils::CXmlWriter* pXmlWriter,const std::wstring& wsNameFormula,const std::wstring& wsFormula); + static std::wstring ParsFormulaName(const std::wstring& wsFormulaName, std::wstring& wsName); + private: + XmlUtils::CXmlWriter* m_pXmlWriter; + }; + class CElement + { + public: + CElement(); + virtual ~CElement(); + virtual void Parse(CSMReader* pReader) = 0; + virtual void ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter,const std::wstring& wsName = L"") = 0; + static CElement* CreateElement(const std::wstring& wsElement); + void SetBaseType(const TypeElement& enType); + TypeElement GetBaseType(); + void SetNameFormula(const std::wstring& wsName); + std::wstring GetNameFormula(); + private: + TypeElement m_enBaseType; + std::wstring m_wsNameFormula; + }; + class CElementNumber:public CElement + { + public: + CElementNumber(); + CElementNumber(const std::wstring& wsName); + virtual ~CElementNumber(); + void Parse(CSMReader* pReader) override; + void ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter,const std::wstring& wsName = L"") override; + static bool CheckNumber(const std::wstring& wsNumber); + std::wstring GetString(); + private: + std::wstring m_wsNumber; + }; + class CElementArithmeticOperations:public CElement + { + public: + CElementArithmeticOperations(); + CElementArithmeticOperations(const std::wstring& wsSign); + virtual ~CElementArithmeticOperations(); + void Parse(CSMReader* pReader) override; + void ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter, const std::wstring& wsName = L"") override; + static bool CheckArithmeticOperators(const std::wstring& wsElement); + bool ComparisonSign(const std::wstring& wsSign); + bool ComparingPriorities(const std::wstring& wsSign); + void SetFirstValue(CElement* pElement); + static TypeElement SetTypeSign(const std::wstring& wsSign); + TypeElement GetTypeSign(); + void SignRecording(XmlUtils::CXmlWriter* pXmlWriter, const TypeElement &enTypeSign); + CElement* GetSecondValue(); + std::wstring ConversionValueSign(XmlUtils::CXmlWriter* pXmlWriter, CElement* pElement); + void RecordingTheValuesSign(XmlUtils::CXmlWriter* pXmlWriter,const std::wstring& wsNameFirst, const std::wstring& wsNameSecond); + private: + TypeElement m_enTypeSign; + CElement* m_pSecondSign; + CElement* m_pFirstValue; + CElement* m_pSecondValue; + unsigned int m_uiNumberFormula; + }; + class CElementBracket: public CElement + { + public: + CElementBracket(); + virtual ~CElementBracket(); + void Parse(CSMReader* pReader) override; + void ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter,const std::wstring& wsName = L"") override; + std::vector GetVector(); + private: + std::vector m_arElements; + }; + class CElementFunction: public CElement + { + public: + CElementFunction(); + CElementFunction(const TypeElement& enType); + virtual ~CElementFunction(); + void Parse(CSMReader* pReader) override; + void ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter, const std::wstring& wsName = L"") override; + void ConversionElement(XmlUtils::CXmlWriter* pXmlWriter,CElement* pElement, std::wstring& wsFormula); + static TypeElement TypeCheckingByFunction(const std::wstring& wsFunction); + void ConvertBracketsForTrigonometry(XmlUtils::CXmlWriter *pXmlWriter, std::wstring &wsFormula); + private: + TypeElement m_enTypeFunction; + CElement* m_pValue; + unsigned int m_uiNumberFormula; + }; + class CElementComma: public CElement + { + public: + CElementComma(); + virtual ~CElementComma(); + void Parse(CSMReader* pReader) override; + void ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter, const std::wstring& wsName = L"") override; + }; +} +#endif // SMCUSTOMSHAPEPARS_H diff --git a/OdfFile/Writer/Converter/ConvertDrawing.cpp b/OdfFile/Writer/Converter/ConvertDrawing.cpp index 749dc50b57..369dc7fcbd 100644 --- a/OdfFile/Writer/Converter/ConvertDrawing.cpp +++ b/OdfFile/Writer/Converter/ConvertDrawing.cpp @@ -1307,15 +1307,15 @@ void OoxConverter::convert(PPTX::Logic::EffectStyle *oox_effects, DWORD ARGB) { if (!oox_effects) return; - if (oox_effects->EffectList.is_init()) + if (oox_effects->Effects.is_init()) { - if (oox_effects->EffectList.is()) + if (oox_effects->Effects.is()) { - convert(dynamic_cast(oox_effects->EffectList.List.GetPointer()), ARGB); + convert(dynamic_cast(oox_effects->Effects.List.GetPointer()), ARGB); } - else if(oox_effects->EffectList.is()) + else if(oox_effects->Effects.is()) { - convert(dynamic_cast(oox_effects->EffectList.List.GetPointer()), ARGB); + convert(dynamic_cast(oox_effects->Effects.List.GetPointer()), ARGB); } } if (oox_effects->scene3d.IsInit()) diff --git a/OdfFile/Writer/Converter/Converter.cpp b/OdfFile/Writer/Converter/Converter.cpp index 1fbd0119f2..e4c2ee5e56 100644 --- a/OdfFile/Writer/Converter/Converter.cpp +++ b/OdfFile/Writer/Converter/Converter.cpp @@ -931,7 +931,7 @@ std::wstring OoxConverter::find_link_by (smart_ptr & oFile, int type, if (pOleObject) { ref = pOleObject->filename().GetPath(); - bExternal = pOleObject->IsExternal(); + bExternal = dynamic_cast(pOleObject)->IsExternal(); } } return ref; diff --git a/OdfFile/Writer/Converter/MathConverter.cpp b/OdfFile/Writer/Converter/MathConverter.cpp index 5cd2841a19..646bedb8b8 100644 --- a/OdfFile/Writer/Converter/MathConverter.cpp +++ b/OdfFile/Writer/Converter/MathConverter.cpp @@ -199,11 +199,6 @@ namespace Oox2Odf } bool bStart = odf_context()->start_math(base_font_size, base_font_color); - for (size_t i = 0; i < oox_math->m_arrItems.size(); ++i) - { - convert(oox_math->m_arrItems[i]); - } - if (bStart) { StarMath::COOXml2Odf starMathConverter; @@ -212,20 +207,23 @@ namespace Oox2Odf std::wstring annotation_text = starMathConverter.GetAnnotation(); - if (false == annotation_text.empty()) + if (annotation_text.empty()) { - CREATE_MATH_TAG(L"annotation"); - typedef odf_writer::math_annotation* T; - T tmp = dynamic_cast(elm.get()); - if (tmp) + for (size_t i = 0; i < oox_math->m_arrItems.size(); ++i) { - tmp->encoding_ = L"StarMath 5.0"; + convert(oox_math->m_arrItems[i]); } - elm->add_text(annotation_text); - - OPEN_MATH_TAG(elm); CLOSE_MATH_TAG; } + else + { + std::wstring content = starMathConverter.GetOdf(); + odf_context()->math_context()->add_content(content); + + odf_context()->math_context()->symbol_counter = 30; // starMathConverter. ??? + odf_context()->math_context()->lvl_max = 20; // starMathConverter. ??? + odf_context()->math_context()->lvl_min = 0; // starMathConverter. ??? + } odf_context()->end_math(); } @@ -286,10 +284,6 @@ namespace Oox2Odf } bool bStart = odf_context()->start_math(base_font_size, base_font_color); - for (size_t i = 0; i < oox_math_para->m_arrItems.size(); ++i) - { - convert(oox_math_para->m_arrItems[i]); - } if (bStart) { StarMath::COOXml2Odf starMathConverter; @@ -298,20 +292,24 @@ namespace Oox2Odf std::wstring annotation_text = starMathConverter.GetAnnotation(); - if (false == annotation_text.empty()) + if (annotation_text.empty()) { - CREATE_MATH_TAG(L"annotation"); - typedef odf_writer::math_annotation* T; - T tmp = dynamic_cast(elm.get()); - if (tmp) + for (size_t i = 0; i < oox_math_para->m_arrItems.size(); ++i) { - tmp->encoding_ = L"StarMath 5.0"; + convert(oox_math_para->m_arrItems[i]); } - elm->add_text(annotation_text); - - OPEN_MATH_TAG(elm); CLOSE_MATH_TAG; } + else + { + std::wstring content = starMathConverter.GetOdf(); + odf_context()->math_context()->add_content(content); + + odf_context()->math_context()->symbol_counter = 30; // starMathConverter. ? ? ? ? + odf_context()->math_context()->lvl_max = 20; // starMathConverter. ? ? ? ? + odf_context()->math_context()->lvl_min = 0; // starMathConverter. ? ? ? ? + } + odf_context()->end_math(); } } diff --git a/OdfFile/Writer/Format/math_elements.cpp b/OdfFile/Writer/Format/math_elements.cpp index 2de345d48d..c07a73a0a3 100644 --- a/OdfFile/Writer/Format/math_elements.cpp +++ b/OdfFile/Writer/Format/math_elements.cpp @@ -71,13 +71,23 @@ void office_math::add_child_element(const office_element_ptr & child_element) void office_math::serialize(std::wostream & _Wostream) { - CP_XML_WRITER(_Wostream) + if (false == content_.empty()) { - CP_XML_NODE_SIMPLE_NONS() - { - CP_XML_ATTR(L"xmlns", L"http://www.w3.org/1998/Math/MathML"); - - semantics_->serialize(CP_XML_STREAM()); + _Wostream << content_; + } + else + { + CP_XML_WRITER(_Wostream) + { + CP_XML_NODE_SIMPLE_NONS() + { + CP_XML_ATTR(L"xmlns", L"http://www.w3.org/1998/Math/MathML"); + + if (semantics_) + { + semantics_->serialize(CP_XML_STREAM()); + } + } } } } diff --git a/OdfFile/Writer/Format/math_elements.h b/OdfFile/Writer/Format/math_elements.h index 04158a0928..042ae7d19a 100644 --- a/OdfFile/Writer/Format/math_elements.h +++ b/OdfFile/Writer/Format/math_elements.h @@ -75,12 +75,13 @@ public: static const wchar_t * name; static const ElementType type = typeMath; - friend class odf_document; virtual void create_child_element(const std::wstring & Ns, const std::wstring & Name); virtual void add_child_element(const office_element_ptr & child_element); + + std::wstring content_; private: virtual void serialize(std::wostream & _Wostream); diff --git a/OdfFile/Writer/Format/odf_conversion_context.cpp b/OdfFile/Writer/Format/odf_conversion_context.cpp index f393e1472a..22dd960b6f 100644 --- a/OdfFile/Writer/Format/odf_conversion_context.cpp +++ b/OdfFile/Writer/Format/odf_conversion_context.cpp @@ -420,7 +420,7 @@ void odf_conversion_context::end_math() _CP_OPT(double)height = convert_symbol_width(1.76 * h, true); if (false == math_context_.in_text_box_) - drawing_context()->set_size(width, height); // раскомиттить по завершению + drawing_context()->set_size(width, height); drawing_context()->end_object(!math_context_.in_text_box_); diff --git a/OdfFile/Writer/Format/odf_math_context.cpp b/OdfFile/Writer/Format/odf_math_context.cpp index b94a9bf192..ac920dc089 100644 --- a/OdfFile/Writer/Format/odf_math_context.cpp +++ b/OdfFile/Writer/Format/odf_math_context.cpp @@ -134,12 +134,10 @@ namespace odf_writer lvl_down_counter = -1; lvl_max = 1; lvl_min = -1; - //debug_stream.open(debug_fileName); } odf_math_context::~odf_math_context() { - //debug_stream.close(); } void odf_math_context::set_styles_context(odf_style_context_ptr style_context) @@ -172,14 +170,21 @@ namespace odf_writer size_t level = impl_->current_level_.size(); - odf_math_level_state level_state = { NULL, NULL, root }; + odf_math_level_state level_state = { NULL, NULL, root }; odf_element_state state(root, L"", office_element_ptr(), level); impl_->current_level_.push_back(level_state); impl_->current_math_state_.elements_.push_back(state); style_flag = true; } + void odf_math_context::end_math() + { + if (impl_->current_math_state_.elements_.empty()) return; + end_element(); + + impl_->clear_current(); + } bool odf_math_context::start_element(office_element_ptr & elm) { if (!elm) @@ -198,19 +203,18 @@ namespace odf_writer void odf_math_context::end_element() { + if (impl_->current_level_.empty()) return; + impl_->current_level_.pop_back(); } bool odf_math_context::isEmpty() { return impl_->current_level_.empty(); } - void odf_math_context::end_math() + void odf_math_context::add_content(const std::wstring& content) { - if (impl_->current_math_state_.elements_.empty()) return; - - end_element(); - - impl_->clear_current(); + if (!impl_->root_element_) return; + impl_->root_element_->content_ = content; } } } \ No newline at end of file diff --git a/OdfFile/Writer/Format/odf_math_context.h b/OdfFile/Writer/Format/odf_math_context.h index 89b1c77f56..fd569d801e 100644 --- a/OdfFile/Writer/Format/odf_math_context.h +++ b/OdfFile/Writer/Format/odf_math_context.h @@ -106,9 +106,11 @@ namespace cpdoccore { odf_text_context* text_context(); void start_math(office_element_ptr& root); + void end_math(); - bool start_element(office_element_ptr& elm); // office_math_element TODO + void add_content(const std::wstring& content); + bool start_element(office_element_ptr& elm); void end_element(); std::vector> brackets; @@ -132,10 +134,6 @@ namespace cpdoccore { std::set mo; std::map diak_symbols; - void end_math(); - - std::wofstream debug_stream; - std::string debug_fileName = "debugLog.txt"; bool isEmpty(); std::vector tagFlag; diff --git a/OfficeUtils/src/zlib-1.2.11/zutil.h b/OfficeUtils/src/zlib-1.2.11/zutil.h index af57e47231..888a132ac3 100644 --- a/OfficeUtils/src/zlib-1.2.11/zutil.h +++ b/OfficeUtils/src/zlib-1.2.11/zutil.h @@ -131,6 +131,7 @@ extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ #endif #if defined(MACOS) || defined(TARGET_OS_MAC) +#include # define OS_CODE 7 # ifndef Z_SOLO # if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os diff --git a/PdfFile/OnlineOfficeBinToPdf.cpp b/PdfFile/OnlineOfficeBinToPdf.cpp index b9bf950496..29d1a2380e 100644 --- a/PdfFile/OnlineOfficeBinToPdf.cpp +++ b/PdfFile/OnlineOfficeBinToPdf.cpp @@ -146,11 +146,12 @@ namespace NSOnlineOfficeBinToPdf enum class AddCommandType { - EditPage = 0, // ранее Annotation + EditPage = 0, AddPage = 1, RemovePage = 2, WidgetInfo = 3, MovePage = 4, + MergePages = 5, Undefined = 255 }; @@ -175,7 +176,7 @@ namespace NSOnlineOfficeBinToPdf int nLen = oReader.ReadInt(); AddCommandType CommandType = (AddCommandType)oReader.ReadByte(); int nPageNum = 0; - if (CommandType != AddCommandType::WidgetInfo) + if (CommandType != AddCommandType::WidgetInfo && CommandType != AddCommandType::MergePages) nPageNum = oReader.ReadInt(); if (nPageNum < 0) @@ -185,7 +186,8 @@ namespace NSOnlineOfficeBinToPdf { case AddCommandType::EditPage: { - pPdf->EditPage(nPageNum); + if (!pPdf->EditPage(nPageNum)) + return false; NSOnlineOfficeBinToPdf::ConvertBufferToRenderer(oReader.GetCurrentBuffer(), (LONG)(nLen - 9) , &oCorrector); oReader.Skip(nLen - 9); @@ -210,6 +212,25 @@ namespace NSOnlineOfficeBinToPdf pPdf->DeletePage(nPageNum); break; } + case AddCommandType::MergePages: + { + std::wstring wsPath = NSFile::CFileBinary::CreateTempFileWithUniqueName(pPdf->GetTempDirectory(), L"PDF"); + int nLength = oReader.ReadInt(); + BYTE* pFile = oReader.GetCurrentBuffer(); + oReader.Skip(nLength); + if (!wsPath.empty()) + { + NSFile::CFileBinary oFile; + if (oFile.CreateFileW(wsPath)) + oFile.WriteFile(pFile, nLength); + oFile.CloseFile(); + } + + int nMaxID = oReader.ReadInt(); + std::wstring wsPrefix = oReader.ReadString(); + pPdf->MergePages(wsPath, nMaxID, wsPrefix); + break; + } case AddCommandType::WidgetInfo: { NSOnlineOfficeBinToPdf::ConvertBufferToRenderer(oReader.GetCurrentBuffer(), (LONG)(nLen - 5) , &oCorrector); diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 055d309137..12022ecf12 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -34,17 +34,22 @@ #include "../DesktopEditor/common/Path.h" #include "SrcReader/Adaptors.h" +#include "SrcReader/PdfAnnot.h" #include "lib/xpdf/PDFDoc.h" #include "lib/xpdf/AcroForm.h" #include "lib/xpdf/TextString.h" #include "lib/xpdf/Lexer.h" #include "lib/xpdf/Parser.h" +#include "lib/xpdf/Outline.h" +#include "lib/xpdf/Link.h" #include "SrcWriter/Catalog.h" #include "SrcWriter/EncryptDictionary.h" #include "SrcWriter/Info.h" #include "SrcWriter/ResourcesDictionary.h" #include "SrcWriter/Streams.h" +#include "SrcWriter/Destination.h" +#include "SrcWriter/Outline.h" #define AddToObject(oVal)\ {\ @@ -54,14 +59,14 @@ ((PdfWriter::CArrayObject*)pObj)->Add(oVal);\ } -void DictToCDictObject(Object* obj, PdfWriter::CObjectBase* pObj, bool bBinary, const std::string& sKey, bool bUnicode = false) +void DictToCDictObject(Object* obj, PdfWriter::CObjectBase* pObj, const std::string& sKey) { Object oTemp; switch (obj->getType()) { case objBool: { - bool b = obj->getBool(); + bool b = obj->getBool() == gTrue; AddToObject(b) break; } @@ -77,21 +82,20 @@ void DictToCDictObject(Object* obj, PdfWriter::CObjectBase* pObj, bool bBinary, } case objString: { - if (bBinary) + GString* str = obj->getString(); + if (str->isBinary()) { - GString* str = obj->getString(); int nLength = str->getLength(); BYTE* arrId = new BYTE[nLength]; for (int nIndex = 0; nIndex < nLength; ++nIndex) arrId[nIndex] = str->getChar(nIndex); - AddToObject(new PdfWriter::CBinaryObject(arrId, nLength)); - RELEASEARRAYOBJECTS(arrId); + AddToObject(new PdfWriter::CBinaryObject(arrId, nLength, false)); } else { - TextString* s = new TextString(obj->getString()); + TextString* s = new TextString(str); std::string sValue = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); - AddToObject(new PdfWriter::CStringObject(sValue.c_str(), bUnicode)) + AddToObject(new PdfWriter::CStringObject(sValue.c_str(), !s->isPDFDocEncoding())) delete s; } break; @@ -113,7 +117,7 @@ void DictToCDictObject(Object* obj, PdfWriter::CObjectBase* pObj, bool bBinary, for (int nIndex = 0; nIndex < obj->arrayGetLength(); ++nIndex) { obj->arrayGetNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pArray, bBinary, "", bUnicode); + DictToCDictObject(&oTemp, pArray, ""); oTemp.free(); } break; @@ -126,7 +130,7 @@ void DictToCDictObject(Object* obj, PdfWriter::CObjectBase* pObj, bool bBinary, { char* chKey = obj->dictGetKey(nIndex); obj->dictGetValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pDict, bBinary, chKey, bUnicode); + DictToCDictObject(&oTemp, pDict, chKey); oTemp.free(); } break; @@ -150,11 +154,360 @@ void DictToCDictObject(Object* obj, PdfWriter::CObjectBase* pObj, bool bBinary, break; } } -PdfWriter::CDictObject* GetWidgetParent(PDFDoc* pdfDoc, PdfWriter::CDocument* pDoc, Object* pParentRef) +bool SplitSkipDict(Object* obj, CObjectsManager* pManager, int nStartRefID) +{ + Object oTemp, oTemp2; + if (obj->dictLookup("Type", &oTemp)->isName("Page")) + { + oTemp.free(); + return true; + } + else if (oTemp.isName("Annot") && obj->dictLookupNF("P", &oTemp2)->isRef()) + { + PdfWriter::CObjectBase* pObj = pManager->GetObj(oTemp2.getRefNum() + nStartRefID); + if (!pObj) + { + oTemp.free(); oTemp2.free(); + return true; + } + } + oTemp.free(); oTemp2.free(); + + if (obj->dictLookup("S", &oTemp)->isName("GoTo")) + { + oTemp.free(); + if (obj->dictLookup("D", &oTemp)->isArray() && oTemp.arrayGetLength() > 1 && oTemp.arrayGetNF(0, &oTemp2)->isRef()) + { + PdfWriter::CObjectBase* pObj = pManager->GetObj(oTemp2.getRefNum() + nStartRefID); + if (!pObj) + { + oTemp.free(); oTemp2.free(); + return true; + } + } + oTemp2.free(); + } + oTemp.free(); + + return false; +} +PdfWriter::CAnnotation* CreateAnnot(Object* oAnnot, Object* oType, PdfWriter::CXref* pXref) +{ + PdfWriter::CAnnotation* pAnnot = NULL; + if (oType->isName("Text")) + pAnnot = new PdfWriter::CTextAnnotation(pXref); + else if (oType->isName("Ink")) + pAnnot = new PdfWriter::CInkAnnotation(pXref); + else if (oType->isName("Line")) + pAnnot = new PdfWriter::CLineAnnotation(pXref); + else if (oType->isName("Highlight") || oType->isName("Underline") || oType->isName("Squiggly") || oType->isName("StrikeOut")) + pAnnot = new PdfWriter::CTextMarkupAnnotation(pXref); + else if (oType->isName("Square") || oType->isName("Circle")) + pAnnot = new PdfWriter::CSquareCircleAnnotation(pXref); + else if (oType->isName("Polygon") || oType->isName("PolyLine")) + pAnnot = new PdfWriter::CPolygonLineAnnotation(pXref); + else if (oType->isName("FreeText")) + pAnnot = new PdfWriter::CFreeTextAnnotation(pXref); + else if (oType->isName("Caret")) + pAnnot = new PdfWriter::CCaretAnnotation(pXref); + else if (oType->isName("Stamp")) + pAnnot = new PdfWriter::CStampAnnotation(pXref); + else if (oType->isName("Popup")) + pAnnot = new PdfWriter::CPopupAnnotation(pXref); + else if (oType->isName("Widget")) + { + char* sName = NULL; + Object oFT; + if (oAnnot->dictLookup("FT", &oFT)->isName()) + sName = oFT.getName(); + + if (!sName) + { + Object oParent, oParent2; + oAnnot->dictLookup("Parent", &oParent); + while (oParent.isDict()) + { + if (oParent.dictLookup("FT", &oFT)->isName()) + { + sName = oFT.getName(); + break; + } + oFT.free(); + oParent.dictLookup("Parent", &oParent2); + oParent.free(); + oParent = oParent2; + } + oParent.free(); + } + + if (!sName) + { + oFT.free(); + return new PdfWriter::CWidgetAnnotation(pXref, PdfWriter::EAnnotType::AnnotWidget); + } + if (strcmp("Btn", sName) == 0) + { + bool bPushButton = false; + oFT.free(); + int nFf = 0; + if (oAnnot->dictLookup("Ff", &oFT)->isInt()) + nFf = oFT.getInt(); + if (!nFf) + { + Object oParent, oParent2; + oAnnot->dictLookup("Parent", &oParent); + while (oParent.isDict()) + { + if (oParent.dictLookup("Ff", &oFT)->isInt()) + { + nFf = oFT.getInt(); + break; + } + oFT.free(); + oParent.dictLookup("Parent", &oParent2); + oParent.free(); + oParent = oParent2; + } + oParent.free(); + } + + bPushButton = (bool)((nFf >> 16) & 1); + if (bPushButton) + pAnnot = new PdfWriter::CPushButtonWidget(pXref); + else + pAnnot = new PdfWriter::CCheckBoxWidget(pXref); + } + else if (strcmp("Tx", sName) == 0) + pAnnot = new PdfWriter::CTextWidget(pXref); + else if (strcmp("Ch", sName) == 0) + pAnnot = new PdfWriter::CChoiceWidget(pXref); + else if (strcmp("Sig", sName) == 0) + pAnnot = new PdfWriter::CSignatureWidget(pXref); + else + pAnnot = new PdfWriter::CWidgetAnnotation(pXref, PdfWriter::EAnnotType::AnnotWidget); + oFT.free(); + } + return pAnnot; +} +PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CDocument* pDoc, XRef* xref, CObjectsManager* pManager, int nStartRefID, int nAddObjToXRef = 0) +{ + PdfWriter::CObjectBase* pBase = NULL; + Object oTemp; + switch (obj->getType()) + { + case objBool: + { + pBase = new PdfWriter::CBoolObject(obj->getBool() == gTrue); + break; + } + case objInt: + { + pBase = new PdfWriter::CNumberObject(obj->getInt()); + break; + } + case objReal: + { + pBase = new PdfWriter::CRealObject(obj->getReal()); + break; + } + case objString: + { + GString* str = obj->getString(); + if (str->isBinary()) + { + int nLength = str->getLength(); + BYTE* arrId = new BYTE[nLength]; + for (int nIndex = 0; nIndex < nLength; ++nIndex) + arrId[nIndex] = str->getChar(nIndex); + pBase = new PdfWriter::CBinaryObject(arrId, nLength, false); + } + else + { + TextString* s = new TextString(str); + std::string sValue = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); + pBase = new PdfWriter::CStringObject(sValue.c_str(), !s->isPDFDocEncoding()); + delete s; + } + break; + } + case objName: + { + pBase = new PdfWriter::CNameObject(obj->getName()); + break; + } + case objNull: + { + pBase = new PdfWriter::CNullObject(); + break; + } + case objArray: + { + PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject(); + if (nAddObjToXRef > 0) + { + pDoc->AddObject(pArray); + pManager->AddObj(nAddObjToXRef + nStartRefID, pArray); + nAddObjToXRef = 0; + } + for (int nIndex = 0; nIndex < obj->arrayGetLength(); ++nIndex) + { + obj->arrayGetNF(nIndex, &oTemp); + pBase = DictToCDictObject2(&oTemp, pDoc, xref, pManager, nStartRefID); + pArray->Add(pBase); + oTemp.free(); + } + pBase = pArray; + break; + } + case objDict: + { + if (SplitSkipDict(obj, pManager, nStartRefID)) + return NULL; + + Object oType, oSubtype; + PdfWriter::CDictObject* pDict = NULL; + if (obj->dictLookup("Type", &oType)->isName("Annot") && obj->dictLookup("Subtype", &oSubtype)->isName()) + { + PdfWriter::CAnnotation* pAnnot = CreateAnnot(obj, &oSubtype, NULL); + if (pAnnot) + { + pDoc->AddAnnotation(nAddObjToXRef + nStartRefID, pAnnot); + pDict = pAnnot; + } + } + oType.free(); oSubtype.free(); + + if (!pDict) + pDict = new PdfWriter::CDictObject(); + if (nAddObjToXRef > 0) + { + pDoc->AddObject(pDict); + pManager->AddObj(nAddObjToXRef + nStartRefID, pDict); + nAddObjToXRef = 0; + } + for (int nIndex = 0; nIndex < obj->dictGetLength(); ++nIndex) + { + char* chKey = obj->dictGetKey(nIndex); + obj->dictGetValNF(nIndex, &oTemp); + pBase = DictToCDictObject2(&oTemp, pDoc, xref, pManager, nStartRefID); + pDict->Add(chKey, pBase); + oTemp.free(); + } + pBase = pDict; + break; + } + case objRef: + { + int nObjNum = obj->getRefNum(); + PdfWriter::CObjectBase* pObj = pManager->GetObj(nObjNum + nStartRefID); + if (pObj) + { + pManager->IncRefCount(nObjNum + nStartRefID); + return pObj; + } + + obj->fetch(xref, &oTemp); + pBase = DictToCDictObject2(&oTemp, pDoc, xref, pManager, nStartRefID, nObjNum); + oTemp.free(); + break; + } + case objNone: + { + pBase = new PdfWriter::CNameObject("None"); + break; + } + case objStream: + { + PdfWriter::CDictObject* pDict = new PdfWriter::CDictObject(); + if (nAddObjToXRef > 0) + { + pDoc->AddObject(pDict); + pManager->AddObj(nAddObjToXRef + nStartRefID, pDict); + nAddObjToXRef = 0; + } + + Dict* pODict = obj->streamGetDict(); + int nLength = 0; + for (int nIndex = 0; nIndex < pODict->getLength(); ++nIndex) + { + char* chKey = pODict->getKey(nIndex); + if (strcmp("Length", chKey) == 0) + { + pODict->getVal(nIndex, &oTemp); + nLength = oTemp.getNum(); + oTemp.free(); + } + pODict->getValNF(nIndex, &oTemp); + pBase = DictToCDictObject2(&oTemp, pDoc, xref, pManager, nStartRefID); + pDict->Add(chKey, pBase); + oTemp.free(); + } + pBase = pDict; + + PdfWriter::CStream* pStream = new PdfWriter::CMemoryStream(nLength); + pDict->SetStream(pStream); + Stream* pOStream = obj->getStream()->getUndecodedStream(); + pOStream->reset(); + int nChar = pOStream->getChar(); + while (nChar != EOF) + { + pStream->WriteChar(nChar); + nChar = pOStream->getChar(); + } + break; + } + case objCmd: + case objError: + case objEOF: + break; + } + if (nAddObjToXRef > 0) + { + pDoc->AddObject(pBase); + pManager->AddObj(nAddObjToXRef + nStartRefID, pBase); + } + + return pBase; +} +void AddWidgetParent(PdfWriter::CDocument* pDoc, CObjectsManager* pManager, PdfWriter::CObjectBase* pObj) +{ + if (pObj->GetType() != PdfWriter::object_type_DICT) + return; + PdfWriter::CDictObject* pDict = dynamic_cast(pObj); + if (!pDict) + return; + + int nID = pManager->FindObj(pObj); + if (nID < 0) + return; + + if (pDict->GetDictType() == PdfWriter::dict_type_UNKNOWN) + { + if (pDoc->GetParent(nID)) + return; + pDoc->AddParent(nID, pDict); + } + + PdfWriter::CObjectBase* pObjParent = pDict->Get("Parent"); + if (pObjParent && pObjParent->GetType() == PdfWriter::object_type_DICT) + AddWidgetParent(pDoc, pManager, pObjParent); + + if (pDict->GetDictType() != PdfWriter::dict_type_UNKNOWN) + return; + + PdfWriter::CObjectBase* pObjKids = pDict->Get("Kids"); + if (!pObjKids || pObjKids->GetType() != PdfWriter::object_type_ARRAY) + return; + + PdfWriter::CArrayObject* pKids = (PdfWriter::CArrayObject*)pObjKids; + for (int i = 0; i < pKids->GetCount(); ++i) + AddWidgetParent(pDoc, pManager, pKids->Get(i)); +} +PdfWriter::CDictObject* GetWidgetParent(PDFDoc* pdfDoc, PdfWriter::CDocument* pDoc, Object* pParentRef, int nStartRefID) { if (!pParentRef || !pParentRef->isRef() || !pdfDoc) return NULL; - PdfWriter::CDictObject* pParent = pDoc->GetParent(pParentRef->getRefNum()); + PdfWriter::CDictObject* pParent = pDoc->GetParent(pParentRef->getRefNum() + nStartRefID); if (pParent) return pParent; @@ -165,10 +518,14 @@ PdfWriter::CDictObject* GetWidgetParent(PDFDoc* pdfDoc, PdfWriter::CDocument* pD return pParent; } - PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, pParentRef->getRefNum()); + PdfWriter::CXref* pXref = NULL; pParent = new PdfWriter::CDictObject(); - pXref->Add(pParent, pParentRef->getRefGen()); - if (!pDoc->EditParent(pXref, pParent, pParentRef->getRefNum())) + if (nStartRefID == 0) + { + pXref = new PdfWriter::CXref(pDoc, pParentRef->getRefNum()); + pXref->Add(pParent, pParentRef->getRefGen()); + } + if (!pDoc->EditParent(pXref, pParent, pParentRef->getRefNum() + nStartRefID)) { RELEASEOBJECT(pXref); oParent.free(); @@ -182,7 +539,7 @@ PdfWriter::CDictObject* GetWidgetParent(PDFDoc* pdfDoc, PdfWriter::CDocument* pD { Object oParentRef; oParent.dictGetValNF(i, &oParentRef); - PdfWriter::CDictObject* pParent2 = GetWidgetParent(pdfDoc, pDoc, &oParentRef); + PdfWriter::CDictObject* pParent2 = GetWidgetParent(pdfDoc, pDoc, &oParentRef, nStartRefID); if (pParent2) { pParent->Add("Parent", pParent2); @@ -193,7 +550,7 @@ PdfWriter::CDictObject* GetWidgetParent(PDFDoc* pdfDoc, PdfWriter::CDocument* pD } Object oTemp; oParent.dictGetValNF(i, &oTemp); - DictToCDictObject(&oTemp, pParent, false, chKey); + DictToCDictObject(&oTemp, pParent, chKey); oTemp.free(); } @@ -204,7 +561,7 @@ HRESULT _ChangePassword(const std::wstring& wsPath, const std::wstring& wsPasswo { if (!_pReader || !_pWriter) return S_FALSE; - PDFDoc* pPDFDocument = _pReader->GetPDFDocument(); + PDFDoc* pPDFDocument = _pReader->GetPDFDocument(0); if (!pPDFDocument) return S_FALSE; XRef* xref = pPDFDocument->getXRef(); @@ -285,7 +642,7 @@ HRESULT _ChangePassword(const std::wstring& wsPath, const std::wstring& wsPasswo { Object oT; oTemp.arrayGetNF(nIndex, &oT); - DictToCDictObject(&oT, pObj, false, ""); + DictToCDictObject(&oT, pObj, ""); oT.free(); } break; @@ -299,7 +656,7 @@ HRESULT _ChangePassword(const std::wstring& wsPath, const std::wstring& wsPasswo Object oT; char* chKey = oTemp.dictGetKey(nIndex); oTemp.dictGetValNF(nIndex, &oT); - DictToCDictObject(&oT, pObj, false, chKey); + DictToCDictObject(&oT, pObj, chKey); oT.free(); } break; @@ -338,7 +695,7 @@ HRESULT _ChangePassword(const std::wstring& wsPath, const std::wstring& wsPasswo continue; } pDict->getValNF(nIndex, &oT); - DictToCDictObject(&oT, pObj, false, chKey); + DictToCDictObject(&oT, pObj, chKey); oT.free(); } @@ -372,7 +729,7 @@ HRESULT _ChangePassword(const std::wstring& wsPath, const std::wstring& wsPasswo if (strcmp("Root", chKey) == 0 || strcmp("Info", chKey) == 0) { trailerDict->dictGetValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pTrailer, true, chKey); + DictToCDictObject(&oTemp, pTrailer, chKey); } oTemp.free(); } @@ -449,76 +806,178 @@ void GetCTM(XRef* pXref, Object* oPage, double* dCTM) oContents.free(); } -CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPassword, CPdfReader* _pReader, const std::wstring& _wsDstFile, CPdfWriter* _pWriter) +void CObjectsManager::AddObj(int nID, PdfWriter::CObjectBase* pObj) { - wsSrcFile = _wsSrcFile; - wsPassword = _wsPassword; - pReader = _pReader; - pWriter = _pWriter; - m_nEditPage = -1; - nError = 0; + if (m_mUniqueRef.find(nID) == m_mUniqueRef.end()) + m_mUniqueRef[nID] = { pObj, 1 }; +} +PdfWriter::CObjectBase* CObjectsManager::GetObj(int nID) +{ + if (m_mUniqueRef.find(nID) != m_mUniqueRef.end()) + return m_mUniqueRef[nID].pObj; + return NULL; +} +bool CObjectsManager::IncRefCount(int nID) +{ + if (m_mUniqueRef.find(nID) != m_mUniqueRef.end()) + { + m_mUniqueRef[nID].nRefCount++; + return true; + } + return false; +} +bool CObjectsManager::DecRefCount(int nID) +{ + if (m_mUniqueRef.find(nID) != m_mUniqueRef.end()) + { + if (m_mUniqueRef[nID].pObj->IsHidden()) + return false; + m_mUniqueRef[nID].pObj->SetHidden(); + return true; + } + return false; +} +int CObjectsManager::FindObj(PdfWriter::CObjectBase* pObj) +{ + std::map::iterator it = std::find_if(m_mUniqueRef.begin(), m_mUniqueRef.end(), [pObj](const std::pair& t){ return t.second.pObj == pObj; }); + if (it != m_mUniqueRef.end()) + return it->first; + return -1; +} +void CObjectsManager::DeleteObjTree(Object* obj, XRef* xref, int nStartRefID) +{ + Object oTemp; + switch (obj->getType()) + { + case objBool: + case objInt: + case objReal: + case objString: + case objName: + case objNull: + case objNone: + case objCmd: + case objError: + case objEOF: + break; + case objArray: + { + for (int nIndex = 0; nIndex < obj->arrayGetLength(); ++nIndex) + { + obj->arrayGetNF(nIndex, &oTemp); + DeleteObjTree(&oTemp, xref, nStartRefID); + oTemp.free(); + } + break; + } + case objDict: + { + if (SplitSkipDict(obj, this, nStartRefID)) + return; + for (int nIndex = 0; nIndex < obj->dictGetLength(); ++nIndex) + { + obj->dictGetValNF(nIndex, &oTemp); + DeleteObjTree(&oTemp, xref, nStartRefID); + oTemp.free(); + } + break; + } + case objRef: + { + int nObjNum = obj->getRefNum(); + PdfWriter::CObjectBase* pObj = GetObj(nObjNum + nStartRefID); + if (pObj && DecRefCount(nObjNum + nStartRefID)) + return; - PDFDoc* pPDFDocument = pReader->GetPDFDocument(); + obj->fetch(xref, &oTemp); + DeleteObjTree(&oTemp, xref, nStartRefID); + oTemp.free(); + break; + } + case objStream: + { + Dict* pODict = obj->streamGetDict(); + for (int nIndex = 0; nIndex < pODict->getLength(); ++nIndex) + { + pODict->getValNF(nIndex, &oTemp); + DeleteObjTree(&oTemp, xref, nStartRefID); + oTemp.free(); + } + break; + } + } +} + +CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPassword, const std::wstring& _wsDstFile, CPdfReader* _pReader, CPdfWriter* _pWriter) +{ + m_wsSrcFile = _wsSrcFile; + m_wsDstFile = _wsDstFile; + m_wsPassword = _wsPassword; + m_pReader = _pReader; + m_pWriter = _pWriter; + m_nEditPage = -1; + m_nError = 0; + m_nMode = Mode::Unknown; + + PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(0); if (!pPDFDocument) { - nError = 1; + m_nError = 1; return; } - // Если результат редактирования будет сохранен в тот же файл, что открыт для чтения, то файл необходимо сделать редактируемым - std::string sPathUtf8New = U_TO_UTF8(_wsDstFile); - std::string sPathUtf8Old = U_TO_UTF8(wsSrcFile); + XRef* xref = pPDFDocument->getXRef(); + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); + if (!xref || !pDoc) + { + m_nError = 1; + return; + } +} +bool CPdfEditor::IncrementalUpdates() +{ + if (m_nMode != Mode::Unknown) + return true; + + m_nMode = Mode::WriteAppend; + PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(0); + XRef* xref = pPDFDocument->getXRef(); + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); + + std::string sPathUtf8New = U_TO_UTF8(m_wsDstFile); + std::string sPathUtf8Old = U_TO_UTF8(m_wsSrcFile); if (sPathUtf8Old == sPathUtf8New || NSSystemPath::NormalizePath(sPathUtf8Old) == NSSystemPath::NormalizePath(sPathUtf8New)) { - GString* owner_pswd = NSStrings::CreateString(wsPassword); - GString* user_pswd = NSStrings::CreateString(wsPassword); + GString* owner_pswd = NSStrings::CreateString(m_wsPassword); + GString* user_pswd = NSStrings::CreateString(m_wsPassword); GBool bRes = pPDFDocument->makeWritable(true, owner_pswd, user_pswd); delete owner_pswd; delete user_pswd; if (!bRes) - { - nError = 2; // Не удалось проверить файл для записи - return; - } + return false; } else { - if (!NSFile::CFileBinary::Copy(wsSrcFile, _wsDstFile)) - { - nError = 2; - return; - } + if (!NSFile::CFileBinary::Copy(m_wsSrcFile, m_wsDstFile)) + return false; NSFile::CFileBinary oFile; - if (!oFile.OpenFile(_wsDstFile, true)) - { - nError = 2; - return; - } + if (!oFile.OpenFile(m_wsDstFile, true)) + return false; oFile.CloseFile(); } - XRef* xref = pPDFDocument->getXRef(); - PdfWriter::CDocument* pDoc = pWriter->GetDocument(); - if (!xref || !pDoc) - { - nError = 1; - return; - } - // Получение каталога и дерева страниц из reader Object catDict, catRefObj, pagesRefObj; if (!xref->getCatalog(&catDict)->isDict() || !catDict.dictLookupNF("Pages", &pagesRefObj)) { pagesRefObj.free(); catDict.free(); - nError = 3; // Не удалось получить каталог и дерево страниц - return; + return false; } Object* trailer = xref->getTrailerDict(); if (!trailer || !trailer->isDict() || !trailer->dictLookupNF("Root", &catRefObj)->isRef()) { pagesRefObj.free(); catDict.free(); catRefObj.free(); - nError = 3; // Не удалось получить каталог и дерево страниц - return; + return false; } Ref catRef = catRefObj.getRef(); catRefObj.free(); @@ -528,15 +987,13 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa if (!pXref) { pagesRefObj.free(); catDict.free(); - nError = 1; - return; + return false; } PdfWriter::CCatalog* pCatalog = new PdfWriter::CCatalog(); if (!pCatalog) { pagesRefObj.free(); catDict.free(); RELEASEOBJECT(pXref); - nError = 1; - return; + return false; } pXref->Add(pCatalog, catRef.gen); PdfWriter::CResourcesDict* pDR = NULL; @@ -578,7 +1035,7 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa Object oTemp; char* chKey2 = oTemp2.dictGetKey(nIndex2); oTemp2.dictGetVal(nIndex2, &oTemp); - DictToCDictObject(&oTemp, pDR, false, chKey2); + DictToCDictObject(&oTemp, pDR, chKey2); oTemp.free(); } oTemp2.free(); @@ -588,7 +1045,7 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa } else oAcroForm.dictGetValNF(nIndex, &oTemp2); - DictToCDictObject(&oTemp2, pAcroForm, false, chKey); + DictToCDictObject(&oTemp2, pAcroForm, chKey); oTemp2.free(); } @@ -601,7 +1058,7 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa } else catDict.dictGetValNF(nIndex, &oAcroForm); - DictToCDictObject(&oAcroForm, pCatalog, false, chKey); + DictToCDictObject(&oAcroForm, pCatalog, chKey); oAcroForm.free(); } catDict.free(); @@ -659,7 +1116,7 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa Object oTemp; char* chKey = encrypt.dictGetKey(nIndex); encrypt.dictGetValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pEncryptDict, true, chKey); + DictToCDictObject(&oTemp, pEncryptDict, chKey); oTemp.free(); } } @@ -670,7 +1127,7 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa encrypt.free(); if (pTrailerDict->dictLookup("ID", &ID) && ID.isArray() && ID.arrayGet(0, &ID1) && ID1.isString()) - DictToCDictObject(&ID1, pEncryptDict, true, "ID"); + DictToCDictObject(&ID1, pEncryptDict, "ID"); ID.free(); ID1.free(); xref->onEncrypted(); @@ -678,20 +1135,19 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa pEncryptDict->SetRef(0, 0); pEncryptDict->Fix(); - pEncryptDict->SetPasswords(wsPassword, wsPassword); + pEncryptDict->SetPasswords(m_wsPassword, m_wsPassword); if (!pEncryptDict->UpdateKey(nCryptAlgorithm)) { pagesRefObj.free(); RELEASEOBJECT(pXref); RELEASEOBJECT(pDRXref); - nError = 4; // Ошибка шифрования файла - return; + return false; } } } // Применение редактирования для writer - bool bRes = pDoc->EditPdf(_wsDstFile, xref->getLastXRefPos(), xref->getNumObjects() + 1, pXref, pCatalog, pEncryptDict, nFormField); + bool bRes = pDoc->EditPdf(xref->getLastXRefPos(), xref->getNumObjects() + 1, pXref, pCatalog, pEncryptDict, nFormField); if (bRes) { // Воспроизведение дерева страниц во writer @@ -701,18 +1157,22 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa bRes = pDoc->EditResources(pDRXref, pDR); } pagesRefObj.free(); - if (!bRes) - nError = 5; // Ошибка применения редактирования + return bRes; } void CPdfEditor::Close() { - PDFDoc* pPDFDocument = pReader->GetPDFDocument(); - PdfWriter::CDocument* pDoc = pWriter->GetDocument(); - if (!pPDFDocument || !pDoc) + if (m_wsDstFile.empty()) + return; + + if (m_nMode != Mode::WriteAppend) + { + m_pWriter->SaveToFile(m_wsDstFile); return; + } + + PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(0); + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); XRef* xref = pPDFDocument->getXRef(); - if (!xref) - return; // Добавляем первый элемент в таблицу xref // он должен иметь вид 0000000000 65535 f @@ -731,7 +1191,7 @@ void CPdfEditor::Close() Object oTemp; char* chKey = trailerDict->dictGetKey(nIndex); trailerDict->dictGetValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pTrailer, true, chKey); + DictToCDictObject(&oTemp, pTrailer, chKey); oTemp.free(); } } @@ -764,49 +1224,48 @@ void CPdfEditor::Close() Object oTemp; char* chKey = info.dictGetKey(nIndex); info.dictGetValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pInfoDict, true, chKey); + DictToCDictObject(&oTemp, pInfoDict, chKey); oTemp.free(); } pInfoDict->SetTime(PdfWriter::InfoModaDate); } info.free(); - if (!pWriter->EditClose() || !pDoc->AddToFile(pXref, pTrailer, pInfoXref, pInfoDict)) + if (!m_pWriter->EditClose() || !pDoc->AddToFile(m_wsDstFile, pXref, pTrailer, pInfoXref, pInfoDict)) { RELEASEOBJECT(pXref); return; } - std::wstring wsPath = pDoc->GetEditPdfPath(); - std::string sPathUtf8New = U_TO_UTF8(wsPath); - std::string sPathUtf8Old = U_TO_UTF8(wsSrcFile); + std::string sPathUtf8New = U_TO_UTF8(m_wsDstFile); + std::string sPathUtf8Old = U_TO_UTF8(m_wsSrcFile); if (sPathUtf8Old == sPathUtf8New || NSSystemPath::NormalizePath(sPathUtf8Old) == NSSystemPath::NormalizePath(sPathUtf8New)) { - GString* owner_pswd = NSStrings::CreateString(wsPassword); - GString* user_pswd = NSStrings::CreateString(wsPassword); + GString* owner_pswd = NSStrings::CreateString(m_wsPassword); + GString* user_pswd = NSStrings::CreateString(m_wsPassword); pPDFDocument->makeWritable(false, owner_pswd, user_pswd); delete owner_pswd; delete user_pswd; NSFile::CFileBinary oFile; - if (oFile.OpenFile(wsSrcFile)) + if (oFile.OpenFile(m_wsSrcFile)) { - pReader->ChangeLength(oFile.GetFileSize()); + m_pReader->ChangeLength(oFile.GetFileSize()); oFile.CloseFile(); } } - pReader = NULL; - pWriter = NULL; + m_pReader = NULL; + m_pWriter = NULL; m_nEditPage = -1; } int CPdfEditor::GetError() { - return nError; + return m_nError; } void CPdfEditor::GetPageTree(XRef* xref, Object* pPagesRefObj, PdfWriter::CPageTree* pPageParent) { - PdfWriter::CDocument* pDoc = pWriter->GetDocument(); + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); if (!pPagesRefObj || !xref || !pDoc) return; @@ -851,7 +1310,7 @@ void CPdfEditor::GetPageTree(XRef* xref, Object* pPagesRefObj, PdfWriter::CPageT oTemp.dictGetVal(nIndex, &oRes); else oTemp.dictGetValNF(nIndex, &oRes); - DictToCDictObject(&oRes, pDict, false, chKey2); + DictToCDictObject(&oRes, pDict, chKey2); oRes.free(); } @@ -871,7 +1330,7 @@ void CPdfEditor::GetPageTree(XRef* xref, Object* pPagesRefObj, PdfWriter::CPageT } else pagesObj.dictGetValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pPageT, false, chKey); + DictToCDictObject(&oTemp, pPageT, chKey); oTemp.free(); } pDoc->CreatePageTree(pXref, pPageT); @@ -895,22 +1354,29 @@ void CPdfEditor::GetPageTree(XRef* xref, Object* pPagesRefObj, PdfWriter::CPageT } kidsArrObj.free(); } -bool CPdfEditor::EditPage(int nPageIndex, bool bSet, bool bActualPos) +bool CPdfEditor::EditPage(int _nPageIndex, bool bSet, bool bActualPos) { - PDFDoc* pPDFDocument = pReader->GetPDFDocument(); - PdfWriter::CDocument* pDoc = pWriter->GetDocument(); + if (m_nMode != Mode::WriteAppend && !IncrementalUpdates()) + return false; + + PDFDoc* pPDFDocument = NULL; + int nPageIndex = m_pReader->GetPageIndex(_nPageIndex, &pPDFDocument); + if (nPageIndex < 0 || !pPDFDocument) + return NULL; + + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); if (!pPDFDocument || !pDoc) return false; PdfWriter::CPage* pEditPage = NULL; - pEditPage = bActualPos ? pDoc->GetPage(nPageIndex) : pDoc->GetEditPage(nPageIndex); + pEditPage = bActualPos ? pDoc->GetPage(nPageIndex) : pDoc->GetEditPage(_nPageIndex); if (pEditPage) { if (bSet) { pDoc->SetCurPage(pEditPage); - pWriter->EditPage(pEditPage); - m_nEditPage = nPageIndex; + m_pWriter->EditPage(pEditPage); + m_nEditPage = _nPageIndex; } return true; } @@ -919,13 +1385,13 @@ bool CPdfEditor::EditPage(int nPageIndex, bool bSet, bool bActualPos) Catalog* pCatalog = pPDFDocument->getCatalog(); if (!xref || !pCatalog) return false; - std::pair pPageRef = pDoc->GetPageRef(nPageIndex); - if (pPageRef.first == 0) + Ref* pPageRef = pPDFDocument->getCatalog()->getPageRef(nPageIndex); + if (!pPageRef || pPageRef->num == 0) return false; // Получение объекта страницы Object pageRefObj, pageObj; - pageRefObj.initRef(pPageRef.first, pPageRef.second); + pageRefObj.initRef(pPageRef->num, pPageRef->gen); if (!pageRefObj.fetch(xref, &pageObj) || !pageObj.isDict()) { pageObj.free(); @@ -935,7 +1401,7 @@ bool CPdfEditor::EditPage(int nPageIndex, bool bSet, bool bActualPos) pageRefObj.free(); // Воспроизведение словаря страницы из reader для writer - PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, pPageRef.first); + PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, pPageRef->num); if (!pXref) { pageObj.free(); @@ -948,7 +1414,7 @@ bool CPdfEditor::EditPage(int nPageIndex, bool bSet, bool bActualPos) RELEASEOBJECT(pXref); return false; } - pXref->Add(pPage, pPageRef.second); + pXref->Add(pPage, pPageRef->gen); for (int nIndex = 0; nIndex < pageObj.dictGetLength(); ++nIndex) { Object oTemp; @@ -967,7 +1433,7 @@ bool CPdfEditor::EditPage(int nPageIndex, bool bSet, bool bActualPos) oTemp.dictGetVal(nIndex, &oRes); else oTemp.dictGetValNF(nIndex, &oRes); - DictToCDictObject(&oRes, pDict, false, chKey2); + DictToCDictObject(&oRes, pDict, chKey2); oRes.free(); } @@ -990,7 +1456,7 @@ bool CPdfEditor::EditPage(int nPageIndex, bool bSet, bool bActualPos) { Object oAnnot; oTemp.arrayGetNF(nIndex, &oAnnot); - DictToCDictObject(&oAnnot, pArray, false, ""); + DictToCDictObject(&oAnnot, pArray, ""); oAnnot.free(); } oTemp.free(); @@ -1006,7 +1472,7 @@ bool CPdfEditor::EditPage(int nPageIndex, bool bSet, bool bActualPos) { if (pageObj.dictGetVal(nIndex, &oTemp)->isArray()) { - DictToCDictObject(&oTemp, pPage, true, chKey); + DictToCDictObject(&oTemp, pPage, chKey); oTemp.free(); continue; } @@ -1022,7 +1488,7 @@ bool CPdfEditor::EditPage(int nPageIndex, bool bSet, bool bActualPos) } else pageObj.dictGetValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pPage, true, chKey); + DictToCDictObject(&oTemp, pPage, chKey); oTemp.free(); } pPage->Fix(); @@ -1031,12 +1497,12 @@ bool CPdfEditor::EditPage(int nPageIndex, bool bSet, bool bActualPos) pageObj.free(); // Применение редактирования страницы для writer - if (pDoc->EditPage(pXref, pPage, nPageIndex)) + if (pDoc->EditPage(pXref, pPage, _nPageIndex)) { if (bSet) { - pWriter->EditPage(pPage); - m_nEditPage = nPageIndex; + m_pWriter->EditPage(pPage); + m_nEditPage = _nPageIndex; } pPage->StartTransform(dCTM[0], dCTM[1], dCTM[2], dCTM[3], dCTM[4], dCTM[5]); pPage->SetStrokeColor(0, 0, 0); @@ -1053,51 +1519,647 @@ bool CPdfEditor::EditPage(int nPageIndex, bool bSet, bool bActualPos) RELEASEOBJECT(pXref); return false; } +bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFDoc* _pDoc, int nStartRefID) +{ + if (m_nMode == Mode::WriteNew) + return false; + if (m_nMode == Mode::Unknown) + m_nMode = Mode::WriteNew; + PDFDoc* pPDFDocument = _pDoc; + XRef* xref = pPDFDocument->getXRef(); + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); + int nPagesBefore = m_pReader->GetNumPages() - pPDFDocument->getNumPages(); + + if (unLength == 0) + unLength = pPDFDocument->getNumPages(); + + // Страницы должны быть созданы заранее для ссылки на них + Catalog* pCatalog = pPDFDocument->getCatalog(); + for (unsigned int i = 0; i < unLength; ++i) + { + Ref* pPageRef = pCatalog->getPageRef((arrPageIndex ? arrPageIndex[i] : i) + 1); + if (pPageRef->num == 0) + return false; + + PdfWriter::CPage* pPage = new PdfWriter::CPage(pDoc); + pDoc->AddObject(pPage); + pDoc->AddPage(pDoc->GetPagesCount(), pPage); + pDoc->AddEditPage(pPage, nPagesBefore + i); + + // Получение объекта страницы + Object pageRefObj, pageObj; + pageRefObj.initRef(pPageRef->num, pPageRef->gen); + if (!pageRefObj.fetch(xref, &pageObj)->isDict()) + { + pageObj.free(); pageRefObj.free(); + return false; + } + m_mObjManager.AddObj(pPageRef->num + nStartRefID, pPage); + pageObj.free(); pageRefObj.free(); + } + + for (unsigned int i = 0; i < unLength; ++i) + { + Ref* pPageRef = pCatalog->getPageRef((arrPageIndex ? arrPageIndex[i] : i) + 1); + if (pPageRef->num == 0) + return false; + + // Получение объекта страницы + PdfWriter::CPage* pPage = (PdfWriter::CPage*)m_mObjManager.GetObj(pPageRef->num + nStartRefID); + Object pageRefObj, pageObj; + pageRefObj.initRef(pPageRef->num, pPageRef->gen); + if (!pageRefObj.fetch(xref, &pageObj)->isDict()) + { + pageObj.free(); + pageRefObj.free(); + return false; + } + pageRefObj.free(); + + // Копирование страницы со всеми ресурсами из reader для writer + for (int nIndex = 0; nIndex < pageObj.dictGetLength(); ++nIndex) + { + Object oTemp; + char* chKey = pageObj.dictGetKey(nIndex); + if (strcmp("Resources", chKey) == 0) + { + Ref oResourcesRef = { -1, -1 }; + if (pageObj.dictGetValNF(nIndex, &oTemp)->isRef()) + oResourcesRef = oTemp.getRef(); + oTemp.free(); + + PdfWriter::CObjectBase* pObj = oResourcesRef.num > 0 ? m_mObjManager.GetObj(oResourcesRef.num + nStartRefID) : NULL; + if (pObj) + { + pPage->Add(chKey, pObj); + m_mObjManager.IncRefCount(oResourcesRef.num + nStartRefID); + continue; + } + + if (pageObj.dictGetVal(nIndex, &oTemp)->isDict()) + { + PdfWriter::CResourcesDict* pDict = pDoc->CreateResourcesDict(oResourcesRef.num < 0, false); + if (oResourcesRef.num > 0) + m_mObjManager.AddObj(oResourcesRef.num + nStartRefID, pDict); + pPage->Add(chKey, pDict); + for (int nIndex = 0; nIndex < oTemp.dictGetLength(); ++nIndex) + { + Object oRes; + char* chKey2 = oTemp.dictGetKey(nIndex); + oTemp.dictGetValNF(nIndex, &oRes); + PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oRes, pDoc, xref, &m_mObjManager, nStartRefID); + pDict->Add(chKey2, pBase); + oRes.free(); + } + + oTemp.free(); + continue; + } + else + { + oTemp.free(); + pageObj.dictGetValNF(nIndex, &oTemp); + } + } + else if (strcmp("Parent", chKey) == 0) // TODO может ли родитель страницы обладать важными для неё полями + { + oTemp.free(); + continue; + } + else + pageObj.dictGetValNF(nIndex, &oTemp); + PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp, pDoc, xref, &m_mObjManager, nStartRefID); + pPage->Add(chKey, pBase); + if (strcmp("Contents", chKey) == 0) + { + if (pBase->GetType() == PdfWriter::object_type_ARRAY) + { + PdfWriter::CArrayObject* pArr = (PdfWriter::CArrayObject*)pBase; + for (int j = 0; j < pArr->GetCount(); ++j) + { + pBase = pArr->Get(j); + if (pBase->GetType() == PdfWriter::object_type_DICT) + { + PdfWriter::CDictObject* pDict = (PdfWriter::CDictObject*)pBase; + if (pDict->Get("Filter")) + pDict->SetFilter(STREAM_FILTER_ALREADY_DECODE); + } + } + } + else if (pBase->GetType() == PdfWriter::object_type_DICT) + { + PdfWriter::CDictObject* pDict = (PdfWriter::CDictObject*)pBase; + if (pDict->Get("Filter")) + pDict->SetFilter(STREAM_FILTER_ALREADY_DECODE); + } + + } + oTemp.free(); + } + pPage->Fix(); + if (m_nMode == Mode::WriteAppend) + { + pDoc->FixEditPage(pPage); + + double dCTM[6] = { 1, 0, 0, 1, 0, 0 }; + GetCTM(xref, &pageObj, dCTM); + pPage->StartTransform(dCTM[0], dCTM[1], dCTM[2], dCTM[3], dCTM[4], dCTM[5]); + pPage->SetStrokeColor(0, 0, 0); + pPage->SetFillColor(0, 0, 0); + pPage->SetExtGrState(pDoc->GetExtGState(255, 255)); + pPage->BeginText(); + pPage->SetCharSpace(0); + pPage->SetTextRenderingMode(PdfWriter::textrenderingmode_Fill); + pPage->SetHorizontalScalling(100); + pPage->EndText(); + } + else + m_pWriter->SetNeedAddHelvetica(false); // TODO дописывает шрифт для адекватного редактирования Adobe pdf без текст. Убрать при реализации map шрифтов + pageObj.free(); + } + + Object oCatalog; + if (!xref->getCatalog(&oCatalog)->isDict()) + { + oCatalog.free(); + return false; + } + + Object oAcroForm; + if (oCatalog.dictLookupNF("AcroForm", &oAcroForm)->isRef() || oAcroForm.isDict()) + { + PdfWriter::CDictObject* pAcroForm = pDoc->GetAcroForm(); + if (!pAcroForm) + { + pAcroForm = new PdfWriter::CDictObject(); + if (oAcroForm.isRef()) + pDoc->AddObject(pAcroForm); + pDoc->SetAcroForm(pAcroForm); + } + else + pAcroForm->Remove("NeedAppearances"); + + if (oAcroForm.isRef()) + { + oAcroForm.free(); + if (!oCatalog.dictLookup("AcroForm", &oAcroForm)->isDict()) + { + oAcroForm.free(); oCatalog.free(); + return false; + } + } + + for (int nIndex = 0; nIndex < oAcroForm.dictGetLength(); ++nIndex) + { + Object oTemp; + char* chKey = oAcroForm.dictGetKey(nIndex); + if (strcmp("Fields", chKey) == 0) + { + Ref oFieldsRef = { -1, -1 }; + if (oAcroForm.dictGetValNF(nIndex, &oTemp)->isRef()) + oFieldsRef = oTemp.getRef(); + oTemp.free(); + + PdfWriter::CArrayObject* pFields = dynamic_cast(pAcroForm->Get("Fields")); + if (!pFields) + { + PdfWriter::CObjectBase* pObj = oFieldsRef.num > 0 ? m_mObjManager.GetObj(oFieldsRef.num + nStartRefID) : NULL; + if (pObj) + { + pAcroForm->Add(chKey, pObj); + m_mObjManager.IncRefCount(oFieldsRef.num + nStartRefID); + continue; + } + } + + // TODO нужна проверка полных имён + // Если имя совпадает, то: переименование с удалением действий или преобразование типа + // Если другие поля - тип, флаг и т.д. совпадает, то выносим общее в общего родителя + // Иначе переименовываем, action обрубаем + + if (oAcroForm.dictGetVal(nIndex, &oTemp)->isArray()) + { + if (!pFields) + { + pFields = new PdfWriter::CArrayObject(); + if (oFieldsRef.num > 0) + { + pDoc->AddObject(pFields); + m_mObjManager.AddObj(oFieldsRef.num + nStartRefID, pFields); + } + pAcroForm->Add(chKey, pFields); + } + + for (int nIndex = 0; nIndex < oTemp.arrayGetLength(); ++nIndex) + { + Object oRes; + PdfWriter::CObjectBase* pObj = NULL; + if (oTemp.arrayGetNF(nIndex, &oRes)->isRef()) + pObj = m_mObjManager.GetObj(oRes.getRefNum() + nStartRefID); + if (pObj) + { + pFields->Add(pObj); + m_mObjManager.IncRefCount(oRes.getRefNum() + nStartRefID); + AddWidgetParent(pDoc, &m_mObjManager, pObj); + oRes.free(); + continue; + } + oRes.free(); + } + oTemp.free(); + continue; + } + else if (!pFields) + { + oTemp.free(); + oAcroForm.dictGetValNF(nIndex, &oTemp); + } + else + { + oTemp.free(); + continue; + } + } + else if (strcmp("SigFlags", chKey) == 0 || strcmp("XFA", chKey) == 0 || (strcmp("DA", chKey) == 0 && pAcroForm->Get("DA")) || strcmp("NeedAppearances", chKey) == 0) + { // Нельзя гарантировать их выполнение + oTemp.free(); + continue; + } + else if (strcmp("DR", chKey) == 0) + { // Добавляем только уникальные ключи + PdfWriter::CDictObject* pDR = dynamic_cast(pAcroForm->Get("DR")); + if (!pDR) + { + pDR = new PdfWriter::CDictObject(); + pDoc->AddObject(pDR); + pAcroForm->Add(chKey, pDR); + } + + PdfWriter::CArrayObject* pProcset = new PdfWriter::CArrayObject(); + pDR->Add("ProcSet", pProcset); + pProcset->Add(new PdfWriter::CNameObject("PDF")); + pProcset->Add(new PdfWriter::CNameObject("Text")); + pProcset->Add(new PdfWriter::CNameObject("ImageB")); + pProcset->Add(new PdfWriter::CNameObject("ImageC")); + pProcset->Add(new PdfWriter::CNameObject("ImageI")); + + if (oAcroForm.dictGetVal(nIndex, &oTemp)->isDict()) + { + Object oTemp2; + for (int nIndex2 = 0; nIndex2 < oTemp.dictGetLength(); ++nIndex2) + { + char* chKey2 = oTemp.dictGetKey(nIndex2); + if (strcmp("ProcSet", chKey2) == 0 || !oTemp.dictGetVal(nIndex2, &oTemp2)->isDict()) + { + oTemp2.free(); + continue; + } + PdfWriter::CDictObject* pDict = dynamic_cast(pDR->Get(chKey2)); + if (!pDict) + { + Object oTempRef; + if (oTemp.dictGetValNF(nIndex2, &oTempRef)->isRef()) + { + PdfWriter::CObjectBase* pObj = m_mObjManager.GetObj(oTempRef.getRefNum() + nStartRefID); + if (pObj) + { + pDR->Add(chKey2, pObj); + m_mObjManager.IncRefCount(oTempRef.getRefNum() + nStartRefID); + oTemp2.free(); oTempRef.free(); + continue; + } + } + PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp2, pDoc, xref, &m_mObjManager, nStartRefID); + if (oTempRef.isRef()) + pDoc->AddObject(pBase); + pDR->Add(chKey2, pBase); + oTemp2.free(); oTempRef.free(); + continue; + } + else + { + for (int nIndex3 = 0; nIndex3 < oTemp2.dictGetLength(); ++nIndex3) + { + char* chKey3 = oTemp2.dictGetKey(nIndex3); + if (pDict->Get(chKey3)) + continue; + Object oTempRef; + if (oTemp2.dictGetValNF(nIndex3, &oTempRef)->isRef()) + { + PdfWriter::CObjectBase* pObj = m_mObjManager.GetObj(oTempRef.getRefNum() + nStartRefID); + if (pObj) + { + pDict->Add(chKey3, pObj); + m_mObjManager.IncRefCount(oTempRef.getRefNum() + nStartRefID); + oTemp2.free(); oTempRef.free(); + continue; + } + } + PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp2, pDoc, xref, &m_mObjManager, nStartRefID); + if (oTempRef.isRef()) + pDoc->AddObject(pBase); + pDict->Add(chKey3, pBase); + oTemp2.free(); oTempRef.free(); + continue; + } + } + } + oTemp2.free(); oTemp.free(); + continue; + } + else + { + oTemp.free(); + oAcroForm.dictGetValNF(nIndex, &oTemp); + } + } + else + oAcroForm.dictGetValNF(nIndex, &oTemp); + PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp, pDoc, xref, &m_mObjManager, nStartRefID); + pAcroForm->Add(chKey, pBase); + oTemp.free(); + } + } + oAcroForm.free(); oCatalog.free(); + + return true; +} +BYTE* CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength) +{ + if (m_nMode != Mode::Unknown) + return NULL; + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); + if (!pDoc) + return NULL; + + int nTotalPages = 0; + int nPDFIndex = 0; + std::map> mFileToPages; + PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(nPDFIndex); + int nPages = pPDFDocument->getNumPages(); + for (unsigned int i = 0; i < unLength; ++i) + { + if (arrPageIndex[i] < nTotalPages + nPages) + mFileToPages[nPDFIndex].push_back(arrPageIndex[i] - nTotalPages); + else + { + pPDFDocument = m_pReader->GetPDFDocument(++nPDFIndex); + if (!pPDFDocument) + break; + nTotalPages += nPages; + nPages = pPDFDocument->getNumPages(); + --i; + } + } + + for (const std::pair>& it : mFileToPages) + { + pPDFDocument = m_pReader->GetPDFDocument(it.first); + if (!SplitPages(it.second.data(), it.second.size(), pPDFDocument, m_pReader->GetStartRefID(pPDFDocument))) + return NULL; + } + + BYTE* pRes = NULL; + int nLength = 0; + if (m_pWriter->SaveToMemory(&pRes, &nLength) == 0) + { + NSWasm::CData oRes; + oRes.SkipLen(); + + oRes.Write(pRes, nLength); + RELEASEARRAYOBJECTS(pRes); + + oRes.WriteLen(); + BYTE* bRes = oRes.GetBuffer(); + oRes.ClearWithoutAttack(); + return bRes; + } + RELEASEARRAYOBJECTS(pRes); + return NULL; +} +void CreateOutlines(PDFDoc* pdfDoc, PdfWriter::CDocument* pDoc, OutlineItem* pOutlineItem, PdfWriter::COutline* pParent) +{ + std::string sTitle = NSStringExt::CConverter::GetUtf8FromUTF32(pOutlineItem->getTitle(), pOutlineItem->getTitleLength()); + PdfWriter::COutline* pOutline = pDoc->CreateOutline(pParent, sTitle.c_str()); + + PdfWriter::CDestination* pDest = NULL; + LinkAction* pLinkAction = pOutlineItem->getAction(); + if (pLinkAction && pLinkAction->getKind() == actionGoTo) + { + GString* str = ((LinkGoTo*)pLinkAction)->getNamedDest(); + LinkDest* pLinkDest = str ? pdfDoc->findDest(str) : ((LinkGoTo*)pLinkAction)->getDest(); + if (pLinkDest) + { + int pg; + if (pLinkDest->isPageRef()) + { + Ref pageRef = pLinkDest->getPageRef(); + pg = pdfDoc->findPage(pageRef.num, pageRef.gen); + } + else + pg = pLinkDest->getPageNum(); + if (pg == 0) + pg = 1; + + Ref* pPageRef = pdfDoc->getCatalog()->getPageRef(pg); + PdfWriter::CObjectBase* pPageD = pDoc->GetEditPage(--pg); + if (!pPageD && pPageRef->num > 0) + { + PdfWriter::CObjectBase* pBase = new PdfWriter::CObjectBase(); + pBase->SetRef(pPageRef->num, pPageRef->gen); + pPageD = new PdfWriter::CProxyObject(pBase, true); + } + pDest = pDoc->CreateDestination(pPageD, true); + + switch (pLinkDest->getKind()) + { + case destXYZ: + { + pDest->SetXYZ(pLinkDest->getLeft(), pLinkDest->getTop(), pLinkDest->getZoom()); + break; + } + case destFit: + { + pDest->SetFit(); + break; + } + case destFitH: + { + pDest->SetFitH(pLinkDest->getTop()); + break; + } + case destFitV: + { + pDest->SetFitV(pLinkDest->getLeft()); + break; + } + case destFitR: + { + pDest->SetFitR(pLinkDest->getLeft(), pLinkDest->getBottom(), pLinkDest->getRight(), pLinkDest->getTop()); + break; + } + case destFitB: + { + pDest->SetFitB(); + break; + } + case destFitBH: + { + pDest->SetFitBH(pLinkDest->getTop()); + break; + } + case destFitBV: + { + pDest->SetFitBV(pLinkDest->getLeft()); + break; + } + } + } + if (str) + RELEASEOBJECT(pLinkDest); + } + if (pDest) + pOutline->SetDestination(pDest); + + pOutlineItem->open(); + GList* pList = pOutlineItem->getKids(); + if (!pList) + { + pOutlineItem->close(); + return; + } + for (int i = 0, num = pList->getLength(); i < num; i++) + { + OutlineItem* pOutlineItemKid = (OutlineItem*)pList->get(i); + if (pOutlineItemKid) + CreateOutlines(pdfDoc, pDoc, pOutlineItemKid, pOutline); + } + pOutlineItem->close(); +} +bool CPdfEditor::MergePages(const std::wstring& wsPath, const std::wstring& wsPrefixForm) +{ + if (m_nMode != Mode::WriteAppend && !IncrementalUpdates()) + return false; + PDFDoc* pDocument = m_pReader->GetLastPDFDocument(); + int nStartRefID = m_pReader->GetStartRefID(pDocument); + bool bRes = SplitPages(NULL, 0, pDocument, nStartRefID); + if (!bRes) + return false; + + Outline* pOutlineAdd = pDocument->getOutline(); + GList* pListAdd = NULL; + if (pOutlineAdd) + pListAdd = pOutlineAdd->getItems(); + if (!pListAdd) + return bRes; + + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); + PDFDoc* pDocumentFirst = m_pReader->GetPDFDocument(0); + Outline* pOutlineOld = pDocumentFirst->getOutline(); + GList* pListOld = NULL; + if (pOutlineOld) + pListOld = pOutlineOld->getItems(); + if (!pDoc->GetOutlines() && pListOld) + { + for (int i = 0, num = pListOld->getLength(); i < num; i++) + { + OutlineItem* pOutlineItem = (OutlineItem*)pListOld->get(i); + if (pOutlineItem) + CreateOutlines(pDocumentFirst, pDoc, pOutlineItem, NULL); + } + } + + std::wstring wsFileName = NSFile::GetFileName(wsPath); + std::string sFileName = U_TO_UTF8(wsFileName); + PdfWriter::COutline* pOutline = pDoc->CreateOutline(NULL, sFileName.c_str()); + for (int i = 0, num = pListAdd->getLength(); i < num; i++) + { + OutlineItem* pOutlineItem = (OutlineItem*)pListAdd->get(i); + if (pOutlineItem) + CreateOutlines(pDocumentFirst, pDoc, pOutlineItem, pOutline); + } + + return bRes; +} bool CPdfEditor::DeletePage(int nPageIndex) { - return pWriter->GetDocument()->DeletePage(nPageIndex); + if (m_nMode != Mode::WriteAppend && !IncrementalUpdates()) + return false; + + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); + PdfWriter::CPage* pPage = pDoc->GetPage(nPageIndex); + int nObjID = m_mObjManager.FindObj(pPage); + if (nObjID > 0) + { + PDFDoc* pPDFDocument = NULL; + int nStartRefID = 0; + int nRefID = m_pReader->FindRefNum(nObjID, &pPDFDocument, &nStartRefID); + if (nRefID > 0) + { + XRefEntry* pEntry = pPDFDocument->getXRef()->getEntry(nRefID); + Object oRef; + oRef.initRef(nRefID, pEntry->gen); + m_mObjManager.DeleteObjTree(&oRef, pPDFDocument->getXRef(), nStartRefID); + } + pPage->SetHidden(); + } + + return pDoc->DeletePage(nPageIndex); } bool CPdfEditor::AddPage(int nPageIndex) { + if (m_nMode == Mode::Unknown) + return false; + // Применение добавления страницы для writer - if (!pWriter->AddPage(nPageIndex)) + if (!m_pWriter->AddPage(nPageIndex)) return false; // По умолчанию выставляются размеры первой страницы, в дальнейшем размеры можно изменить double dPageDpiX, dPageDpiY; double dWidth, dHeight; - pReader->GetPageInfo(0, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); + m_pReader->GetPageInfo(0, &dWidth, &dHeight, &dPageDpiX, &dPageDpiY); dWidth *= 25.4 / dPageDpiX; dHeight *= 25.4 / dPageDpiY; - pWriter->put_Width(dWidth); - pWriter->put_Height(dHeight); + m_pWriter->put_Width(dWidth); + m_pWriter->put_Height(dHeight); return true; } bool CPdfEditor::MovePage(int nPageIndex, int nPos) { - if (EditPage(nPageIndex, true, true)) + if (EditPage(nPageIndex)) { m_nEditPage = nPos; - return pWriter->GetDocument()->MovePage(nPageIndex, nPos); + return m_pWriter->GetDocument()->MovePage(nPageIndex, nPos); } return false; } -bool CPdfEditor::EditAnnot(int nPageIndex, int nID) +bool CPdfEditor::EditAnnot(int _nPageIndex, int nID) { - PDFDoc* pPDFDocument = pReader->GetPDFDocument(); - PdfWriter::CDocument* pDoc = pWriter->GetDocument(); - if (!pPDFDocument || !pDoc) + PdfWriter::CObjectBase* pObj = m_mObjManager.GetObj(nID); + if (pObj) + return true; + + PDFDoc* pPDFDocument = NULL; + PdfReader::CPdfFontList* pFontList = NULL; + int nStartRefID = 0; + int nPageIndex = m_pReader->GetPageIndex(_nPageIndex, &pPDFDocument, &pFontList, &nStartRefID); + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); + if (nPageIndex < 0 || !pPDFDocument || !pDoc) return false; + if (pDoc->GetAnnot(nID)) + return true; + XRef* xref = pPDFDocument->getXRef(); - std::pair pPageRef = pDoc->GetPageRef(nPageIndex); - if (!xref || pPageRef.first == 0) + Ref* pPageRef = pPDFDocument->getCatalog()->getPageRef(nPageIndex); + if (!xref || !pPageRef || pPageRef->num == 0) return false; // Получение объекта аннотации Object pageRefObj, pageObj, oAnnots; - pageRefObj.initRef(pPageRef.first, pPageRef.second); + pageRefObj.initRef(pPageRef->num, pPageRef->gen); if (!pageRefObj.fetch(xref, &pageObj)->isDict() || !pageObj.dictLookup("Annots", &oAnnots)->isArray()) { pageRefObj.free(); pageObj.free(); oAnnots.free(); @@ -1108,7 +2170,7 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID) Object oAnnotRef, oAnnot, oType; for (int i = 0; i < oAnnots.arrayGetLength(); ++i) { - if (oAnnots.arrayGetNF(i, &oAnnotRef)->isRef() && oAnnotRef.getRefNum() == nID) + if (oAnnots.arrayGetNF(i, &oAnnotRef)->isRef() && oAnnotRef.getRefNum() + nStartRefID == nID) break; oAnnotRef.free(); } @@ -1119,14 +2181,8 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID) return false; } - PdfWriter::CPage* pEditPage = pDoc->GetEditPage(nPageIndex); - if (!pEditPage) - { - pEditPage = pDoc->GetCurPage(); - EditPage(nPageIndex); - pDoc->SetCurPage(pEditPage); - pWriter->EditPage(pEditPage); - } + if (!pDoc->GetEditPage(_nPageIndex)) + EditPage(_nPageIndex, false); // Воспроизведение словаря аннотации из reader для writer PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, oAnnotRef.getRefNum()); @@ -1152,7 +2208,7 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID) pAnnot = new PdfWriter::CPolygonLineAnnotation(pXref); else if (oType.isName("FreeText")) { - std::map mapFont = pReader->GetAnnotFonts(&oAnnotRef); + std::map mapFont = PdfReader::CAnnotFonts::GetAnnotFont(pPDFDocument, m_pReader->GetFontManager(), pFontList, &oAnnotRef); m_mFonts.insert(mapFont.begin(), mapFont.end()); pAnnot = new PdfWriter::CFreeTextAnnotation(pXref); } @@ -1218,10 +2274,11 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID) } bPushButton = (bool)((nFf >> 16) & 1); + bool bRadiobutton = (bool)((nFf >> 15) & 1); if (bPushButton) pAnnot = new PdfWriter::CPushButtonWidget(pXref); else - pAnnot = new PdfWriter::CCheckBoxWidget(pXref); + pAnnot = new PdfWriter::CCheckBoxWidget(pXref, bRadiobutton ? PdfWriter::WidgetRadiobutton : PdfWriter::WidgetCheckbox); } else if (strcmp("Tx", sName) == 0) pAnnot = new PdfWriter::CTextWidget(pXref); @@ -1245,14 +2302,13 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID) for (int nIndex = 0; nIndex < oAnnot.dictGetLength(); ++nIndex) { - bool bUnicode = false; char* chKey = oAnnot.dictGetKey(nIndex); if (!strcmp("Popup", chKey)) { Object oPopupRef; - if (oAnnot.dictGetValNF(nIndex, &oPopupRef)->isRef() && EditAnnot(nPageIndex, oPopupRef.getRefNum())) + if (oAnnot.dictGetValNF(nIndex, &oPopupRef)->isRef() && EditAnnot(nPageIndex, oPopupRef.getRefNum() + nStartRefID)) { - PdfWriter::CAnnotation* pPopup = pDoc->GetAnnot(oPopupRef.getRefNum()); + PdfWriter::CAnnotation* pPopup = pDoc->GetAnnot(oPopupRef.getRefNum() + nStartRefID); if (pPopup) { pAnnot->Add("Popup", pPopup); @@ -1265,7 +2321,7 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID) { Object oParentRef; oAnnot.dictGetValNF(nIndex, &oParentRef); - PdfWriter::CDictObject* pParent = GetWidgetParent(pPDFDocument, pDoc, &oParentRef); + PdfWriter::CDictObject* pParent = GetWidgetParent(pPDFDocument, pDoc, &oParentRef, nStartRefID); if (!pParent) { @@ -1291,12 +2347,33 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID) } } oParentRef.free(); + continue; + } + else if (!strcmp("AP", chKey) && pAnnot->GetAnnotationType() == PdfWriter::AnnotWidget) + { + PdfWriter::EWidgetType nType = ((PdfWriter::CWidgetAnnotation*)pAnnot)->GetWidgetType(); + if (nType == PdfWriter::WidgetRadiobutton || nType == PdfWriter::WidgetCheckbox) + { + PdfWriter::CCheckBoxWidget* pCAnnot = dynamic_cast(pAnnot); + + Object oAP, oN; + if (oAnnot.dictGetVal(nIndex, &oAP)->isDict() && oAP.dictLookup("N", &oN)->isDict()) + { + for (int j = 0, nNormLength = oN.dictGetLength(); j < nNormLength; ++j) + { + std::string sNormName(oN.dictGetKey(j)); + if (sNormName != "Off") + { + pCAnnot->SetAP_N_Yes(UTF8_TO_U(sNormName)); + break; + } + } + } + } } - else if (!strcmp("Opt", chKey)) - bUnicode = true; Object oTemp; oAnnot.dictGetValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pAnnot, false, chKey, bUnicode); + DictToCDictObject(&oTemp, pAnnot, chKey); oTemp.free(); } @@ -1321,7 +2398,7 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID) { char* chKey = pODict->getKey(nIndex); pODict->getValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pAPN, false, chKey); + DictToCDictObject(&oTemp, pAPN, chKey); oTemp.free(); } int nLength = 0; @@ -1347,16 +2424,35 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID) } bool CPdfEditor::DeleteAnnot(int nID, Object* oAnnots) { - PDFDoc* pPDFDocument = pReader->GetPDFDocument(); - PdfWriter::CDocument* pDoc = pWriter->GetDocument(); - if (!pPDFDocument || !pDoc) + PdfWriter::CObjectBase* pObj = m_mObjManager.GetObj(nID); + if (pObj) + { + PDFDoc* pPDFDocument = NULL; + int nStartRefID = 0; + int nRefID = m_pReader->FindRefNum(nID, &pPDFDocument, &nStartRefID); + if (nRefID > 0) + { + XRefEntry* pEntry = pPDFDocument->getXRef()->getEntry(nRefID); + Object oRef; + oRef.initRef(nRefID, pEntry->gen); + m_mObjManager.DeleteObjTree(&oRef, pPDFDocument->getXRef(), nStartRefID); + } + pObj->SetHidden(); + return true; + } + + PDFDoc* pPDFDocument = NULL; + int nPageIndex = m_pReader->GetPageIndex(m_nEditPage, &pPDFDocument); + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); + if (nPageIndex < 0 || !pPDFDocument || !pDoc) return false; XRef* xref = pPDFDocument->getXRef(); bool bClear = false; if (!oAnnots) { - std::pair pPageRef = pDoc->GetPageRef(m_nEditPage); + PdfWriter::CPage* pPage = pDoc->GetCurPage(); + std::pair pPageRef = { pPage->GetObjId(), pPage->GetObjId() }; if (pPageRef.first == 0) return false; @@ -1381,14 +2477,176 @@ bool CPdfEditor::DeleteAnnot(int nID, Object* oAnnots) Object oAnnotRef, oAnnot; if (oAnnots->arrayGetNF(i, &oAnnotRef)->isRef() && oAnnotRef.getRefNum() == nID) { - bRes = pDoc->DeleteAnnot(oAnnotRef.getRefNum(), oAnnotRef.getRefGen()); + bool bNeed = false; if (oAnnotRef.fetch(xref, &oAnnot)->isDict()) { - Object oPopupRef; - if (oAnnot.dictLookupNF("Popup", &oPopupRef)->isRef()) - pDoc->DeleteAnnot(oPopupRef.getRefNum(), oPopupRef.getRefGen()); - oPopupRef.free(); + Object oType; + if (oAnnot.dictLookup("Subtype", &oType)->isName("Widget")) + { + char* sName = NULL; + Object oFT; + if (oAnnot.dictLookup("FT", &oFT)->isName()) + sName = oFT.getName(); + + if (!sName) + { + Object oParent, oParent2; + oAnnot.dictLookup("Parent", &oParent); + while (oParent.isDict()) + { + if (oParent.dictLookup("FT", &oFT)->isName()) + { + sName = oFT.getName(); + break; + } + oFT.free(); + oParent.dictLookup("Parent", &oParent2); + oParent.free(); + oParent = oParent2; + } + oParent.free(); + } + + if (sName && strcmp("Btn", sName) == 0) + { + bool bPushButton = false; + oFT.free(); + int nFf = 0; + if (oAnnot.dictLookup("Ff", &oFT)->isInt()) + nFf = oFT.getInt(); + if (!nFf) + { + Object oParent, oParent2; + oAnnot.dictLookup("Parent", &oParent); + while (oParent.isDict()) + { + if (oParent.dictLookup("Ff", &oFT)->isInt()) + { + nFf = oFT.getInt(); + break; + } + oFT.free(); + oParent.dictLookup("Parent", &oParent2); + oParent.free(); + oParent = oParent2; + } + oParent.free(); + } + + bPushButton = (bool)((nFf >> 16) & 1); + bool bRadiosInUnison = (bool)(nFf & (1 << 25)); + if (!bPushButton) + { + oFT.free(); + bNeed = oAnnot.dictLookup("Opt", &oFT)->isArray() == gTrue; + if (!bNeed) + { + Object oParent, oParent2; + oAnnot.dictLookup("Parent", &oParent); + while (oParent.isDict()) + { + if (oParent.dictLookup("Opt", &oFT)->isArray()) + { + bNeed = true; + break; + } + oFT.free(); + oParent.dictLookup("Parent", &oParent2); + oParent.free(); + oParent = oParent2; + } + oParent.free(); + } + if (bNeed && EditAnnot(m_nEditPage, nID)) + { + PdfWriter::CAnnotation* pAnnot = pDoc->GetAnnot(nID); + if (pAnnot) + { + pAnnot->SetHidden(); + + PdfWriter::CObjectBase* pObj = pAnnot->Get("Parent"); + PdfWriter::CDictObject* pParent = NULL; + if (pObj && pObj->GetType() == PdfWriter::object_type_DICT) + pParent = (PdfWriter::CDictObject*)pObj; + PdfWriter::CArrayObject* pOpt = NULL, *pKids = NULL; + if (pParent) + { + pObj = pParent->Get("Kids"); + if (pObj && pObj->GetType() == PdfWriter::object_type_ARRAY) + pKids = (PdfWriter::CArrayObject*)pObj; + pObj = pParent->Get("Opt"); + if (pObj && pObj->GetType() == PdfWriter::object_type_ARRAY) + pOpt = (PdfWriter::CArrayObject*)pObj; + } + std::map mNameAP_N_Yes; + if (pKids && pOpt && pKids->GetCount() == pOpt->GetCount()) + { + for (int i = 0; i < pKids->GetCount(); ++i) + { + pObj = pKids->Get(i); + if (pObj == pAnnot) + { + pKids->Remove(i); + pOpt->Remove(i); + --i; + } + else + { + pObj = pOpt->Get(i); + if (pObj->GetType() == PdfWriter::object_type_ARRAY && ((PdfWriter::CArrayObject*)pObj)->GetCount() > 0) + pObj = ((PdfWriter::CArrayObject*)pObj)->Get(0); + std::wstring sNameOpt; + if (pObj->GetType() == PdfWriter::object_type_STRING) + { + PdfWriter::CStringObject* pStr = (PdfWriter::CStringObject*)pObj; + sNameOpt = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)pStr->GetString(), pStr->GetLength()); + if (mNameAP_N_Yes.find(sNameOpt) == mNameAP_N_Yes.end()) + mNameAP_N_Yes[sNameOpt] = std::to_wstring(i); + } + pObj = pKids->Get(i); + Object oAnnot, oSubtype, oPageRef; + if (xref->fetch(pObj->GetObjId(), pObj->GetGenNo(), &oAnnot)->isDict("Annot") && oAnnot.dictLookup("Subtype", &oSubtype)->isName("Widget") && + oAnnot.dictLookupNF("P", &oPageRef)->isRef()) + { + int nPage = pPDFDocument->findPage(oPageRef.getRefNum(), oPageRef.getRefGen()) - 1; + PdfWriter::CCheckBoxWidget* pKidAnnot = NULL; + int nObjId = pObj->GetObjId(); + if (nPage >= 0 && EditAnnot(nPage, nObjId)) + pKidAnnot = dynamic_cast(pDoc->GetAnnot(nObjId)); + if (pKidAnnot && !sNameOpt.empty()) + pKidAnnot->RenameAP_N_Yes((bRadiosInUnison || pKidAnnot->GetWidgetType() == PdfWriter::WidgetCheckbox) ? mNameAP_N_Yes[sNameOpt] : std::to_wstring(i)); + } + oAnnot.free(); oSubtype.free(); oPageRef.free(); + } + } + } + + Object oPopupRef; + if (oAnnot.dictLookupNF("Popup", &oPopupRef)->isRef()) + { + pAnnot = pDoc->GetAnnot(oPopupRef.getRefNum()); + if (pAnnot) + pAnnot->SetHidden(); + } + oPopupRef.free(); + } + } + } + } + oFT.free(); + } + oType.free(); + + if (!bNeed) + { + Object oPopupRef; + if (oAnnot.dictLookupNF("Popup", &oPopupRef)->isRef()) + pDoc->DeleteAnnot(oPopupRef.getRefNum(), oPopupRef.getRefGen()); + oPopupRef.free(); + } } + if (!bNeed) + bRes = pDoc->DeleteAnnot(oAnnotRef.getRefNum(), oAnnotRef.getRefGen()); } else if (oAnnots->arrayGet(i, &oAnnot)->isDict()) { @@ -1410,9 +2668,11 @@ bool CPdfEditor::DeleteAnnot(int nID, Object* oAnnots) } bool CPdfEditor::EditWidgets(IAdvancedCommand* pCommand) { + if (m_nMode != Mode::WriteAppend && !IncrementalUpdates()) + return false; + CWidgetsInfo* pFieldInfo = (CWidgetsInfo*)pCommand; - PDFDoc* pPDFDocument = pReader->GetPDFDocument(); - PdfWriter::CDocument* pDoc = pWriter->GetDocument(); + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); std::vector arrParents = pFieldInfo->GetParents(); for (CWidgetsInfo::CParent* pParent : arrParents) @@ -1421,10 +2681,16 @@ bool CPdfEditor::EditWidgets(IAdvancedCommand* pCommand) if (pDParent) continue; + PDFDoc* pPDFDocument = NULL; + int nStartRefID = 0; + int nRefID = m_pReader->FindRefNum(pParent->nID, &pPDFDocument, &nStartRefID); + if (nRefID < 0) + continue; + + XRefEntry* pEntry = pPDFDocument->getXRef()->getEntry(nRefID); Object oParentRef; - // TODO узнать gen родителя - oParentRef.initRef(pParent->nID, 0); - GetWidgetParent(pPDFDocument, pDoc, &oParentRef); + oParentRef.initRef(nRefID, pEntry->gen); + GetWidgetParent(pPDFDocument, pDoc, &oParentRef, nStartRefID); // TODO перевыставить детей oParentRef.free(); } @@ -1432,11 +2698,11 @@ bool CPdfEditor::EditWidgets(IAdvancedCommand* pCommand) } int CPdfEditor::GetPagesCount() { - return pWriter->GetDocument()->GetPagesCount(); + return m_pWriter->GetDocument()->GetPagesCount(); } void CPdfEditor::GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) { - PdfWriter::CPage* pPage = pWriter->GetDocument()->GetPage(nPageIndex); + PdfWriter::CPage* pPage = m_pWriter->GetDocument()->GetPage(nPageIndex); if (!pPage) return; @@ -1457,7 +2723,7 @@ void CPdfEditor::GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, } int CPdfEditor::GetRotate(int nPageIndex) { - PdfWriter::CPage* pPage = pWriter->GetDocument()->GetPage(nPageIndex); + PdfWriter::CPage* pPage = m_pWriter->GetDocument()->GetPage(nPageIndex); if (!pPage) return 0; return pPage->GetRotate(); @@ -1468,10 +2734,14 @@ bool CPdfEditor::IsEditPage() } void CPdfEditor::ClearPage() { - PDFDoc* pPDFDocument = pReader->GetPDFDocument(); + PDFDoc* pPDFDocument = NULL; + int nPageIndex = m_pReader->GetPageIndex(m_nEditPage, &pPDFDocument); + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); + if (nPageIndex < 0 || !pPDFDocument || !pDoc) + return; XRef* xref = pPDFDocument->getXRef(); - PdfWriter::CDocument* pDoc = pWriter->GetDocument(); - std::pair pPageRef = pDoc->GetPageRef(m_nEditPage); + PdfWriter::CPage* pPage = pDoc->GetCurPage(); + std::pair pPageRef = { pPage->GetObjId(), pPage->GetObjId() }; // Получение объекта страницы Object pageRefObj, pageObj; @@ -1504,21 +2774,21 @@ void CPdfEditor::ClearPage() } void CPdfEditor::AddShapeXML(const std::string& sXML) { - return pWriter->GetDocument()->AddShapeXML(sXML); + return m_pWriter->GetDocument()->AddShapeXML(sXML); } void CPdfEditor::EndMarkedContent() { - pWriter->GetDocument()->EndShapeXML(); + m_pWriter->GetDocument()->EndShapeXML(); } bool CPdfEditor::IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bItalic, std::wstring& wsFontPath) { - std::map::iterator it = m_mFonts.find(wsFontName); + std::map::const_iterator it = m_mFonts.find(wsFontName); if (it != m_mFonts.end()) wsFontPath = it->second; if (wsFontPath.empty()) { - std::map mFonts = pReader->GetFonts(); - std::map::iterator it2 = mFonts.find(wsFontName); + const std::map& mFonts = m_pReader->GetFonts(); + std::map::const_iterator it2 = mFonts.find(wsFontName); if (it2 != mFonts.end()) wsFontPath = it2->second; } diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h index c41b5bcd9f..937697e15d 100644 --- a/PdfFile/PdfEditor.h +++ b/PdfFile/PdfEditor.h @@ -37,10 +37,43 @@ HRESULT _ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword, CPdfReader* _pReader, CPdfWriter* _pWriter); +struct CObjectInfo +{ + PdfWriter::CObjectBase* pObj; + int nRefCount; + + CObjectInfo() { pObj = NULL; nRefCount = 0; } + CObjectInfo(PdfWriter::CObjectBase* _pObj, int _nRefCount) : pObj(_pObj), nRefCount(_nRefCount) {} +}; + +class CObjectsManager +{ +public: + void AddObj(int nID, PdfWriter::CObjectBase* pObj); + PdfWriter::CObjectBase* GetObj(int nID); + bool IncRefCount(int nID); + bool DecRefCount(int nID); + int FindObj(PdfWriter::CObjectBase* pObj); + void DeleteObjTree(Object* obj, XRef* xref, int nStartRefID); + +private: + std::map m_mUniqueRef; // map уникальных объектов +}; + class CPdfEditor { public: - CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPassword, CPdfReader* _pReader, const std::wstring& _wsDstFile, CPdfWriter* _pWriter); + enum class Mode + { + Unknown, + ReadOnly, + WriteNew, + WriteAppend + }; + + CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPassword, const std::wstring& _wsDstFile, CPdfReader* _pReader, CPdfWriter* _pWriter); + + bool IncrementalUpdates(); int GetError(); void Close(); @@ -60,17 +93,26 @@ public: void EndMarkedContent(); bool IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bItalic, std::wstring& wsFontPath); + BYTE* SplitPages(const int* arrPageIndex, unsigned int unLength); + bool MergePages(const std::wstring& wsPath, const std::wstring& wsPrefixForm); + private: void GetPageTree(XRef* xref, Object* pPagesRefObj, PdfWriter::CPageTree* pPageParent = NULL); + bool SplitPages(const int* arrPageIndex, unsigned int unLength, PDFDoc* _pDoc, int nStartRefID); - std::wstring wsSrcFile; - std::wstring wsPassword; + std::wstring m_wsSrcFile; + std::wstring m_wsDstFile; + std::wstring m_wsPassword; std::map m_mFonts; + CObjectsManager m_mObjManager; - CPdfReader* pReader; - CPdfWriter* pWriter; + CPdfReader* m_pReader; + CPdfWriter* m_pWriter; - int nError; + int m_nError; + // 0 - Дозапись. pReader и pWriter работают с одним файлом + // 1 - Split. pReader и pWriter работают с разными файлами + Mode m_nMode; int m_nEditPage; }; diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index ec96d91007..b63f38e503 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -32,38 +32,14 @@ #include "PdfFile.h" #include "PdfWriter.h" #include "PdfReader.h" +#include "PdfEditor.h" #include "../DesktopEditor/common/File.h" #include "../DesktopEditor/graphics/commands/DocInfo.h" -#include "lib/xpdf/PDFDoc.h" #include "Resources/BaseFonts.h" -#ifndef BUILDING_WASM_MODULE -#include "PdfEditor.h" #include "OnlineOfficeBinToPdf.h" #include "SrcWriter/Document.h" -#else -class CPdfEditor -{ -public: - int GetError() { return 0; } - void Close() {} - bool EditPage(int nPageIndex, bool bSet = true) { return false; } - bool DeletePage(int nPageIndex) { return false; } - bool AddPage(int nPageIndex) { return false; } - bool EditAnnot(int nPageIndex, int nID) { return false; } - bool DeleteAnnot(int nID, Object* oAnnots = NULL) { return false; } - bool EditWidgets(IAdvancedCommand* pCommand) { return false; } - int GetPagesCount() { return 0; } - void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) {} - int GetRotate(int nPageIndex) { return 0; } - bool IsEditPage() { return false; } - void ClearPage() {} - void AddShapeXML(const std::string& sXML) {} - void EndMarkedContent() {} - bool IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bItalic, std::wstring& wsFontPath) { return false; } -}; -#endif // BUILDING_WASM_MODULE class CPdfFile_Private { @@ -126,24 +102,18 @@ void CPdfFile::RotatePage(int nRotate) { if (!m_pInternal->pWriter) return; - // Применение поворота страницы для writer m_pInternal->pWriter->PageRotate(nRotate); } -#ifndef BUILDING_WASM_MODULE bool CPdfFile::EditPdf(const std::wstring& wsDstFile) { - if (wsDstFile.empty()) + if (wsDstFile.empty() || !m_pInternal->pReader) return false; - if (!m_pInternal->pReader) - return false; - - // Создание writer для редактирования RELEASEOBJECT(m_pInternal->pWriter); m_pInternal->pWriter = new CPdfWriter(m_pInternal->pAppFonts, false, this); RELEASEOBJECT(m_pInternal->pEditor); - m_pInternal->pEditor = new CPdfEditor(m_pInternal->wsSrcFile, m_pInternal->wsPassword, m_pInternal->pReader, wsDstFile, m_pInternal->pWriter); + m_pInternal->pEditor = new CPdfEditor(m_pInternal->wsSrcFile, m_pInternal->wsPassword, wsDstFile, m_pInternal->pReader, m_pInternal->pWriter); return m_pInternal->pEditor->GetError() == 0; } bool CPdfFile::EditPage(int nPageIndex) @@ -164,6 +134,14 @@ bool CPdfFile::AddPage(int nPageIndex) return false; return m_pInternal->pEditor->AddPage(nPageIndex); } +bool CPdfFile::MergePages(const std::wstring& wsPath, int nMaxID, const std::wstring& wsPrefixForm) +{ + if (!m_pInternal->pEditor) + return false; + if (m_pInternal->pReader->MergePages(wsPath, L"", nMaxID)) + return m_pInternal->pEditor->MergePages(wsPath, wsPrefixForm); + return false; +} bool CPdfFile::MovePage(int nPageIndex, int nPos) { if (!m_pInternal->pEditor) @@ -176,7 +154,6 @@ HRESULT CPdfFile::ChangePassword(const std::wstring& wsPath, const std::wstring& m_pInternal->pWriter = new CPdfWriter(m_pInternal->pAppFonts, false, this, false); return _ChangePassword(wsPath, wsPassword, m_pInternal->pReader, m_pInternal->pWriter); } -#endif // BUILDING_WASM_MODULE // ------------------------------------------------------------------------ @@ -194,28 +171,23 @@ bool CPdfFile::IsNeedCMap() } void CPdfFile::SetCMapMemory(BYTE* pData, DWORD nSizeData) { - if (!m_pInternal->pReader) - return; - m_pInternal->pReader->SetCMapMemory(pData, nSizeData); + if (m_pInternal->pReader) + m_pInternal->pReader->SetCMapMemory(pData, nSizeData); } void CPdfFile::SetCMapFolder(const std::wstring& sFolder) { - if (!m_pInternal->pReader) - return; - m_pInternal->pReader->SetCMapFolder(sFolder); + if (m_pInternal->pReader) + m_pInternal->pReader->SetCMapFolder(sFolder); } void CPdfFile::SetCMapFile(const std::wstring& sFile) { - if (!m_pInternal->pReader) - return; - m_pInternal->pReader->SetCMapFile(sFile); + if (m_pInternal->pReader) + m_pInternal->pReader->SetCMapFile(sFile); } void CPdfFile::ToXml(const std::wstring& sFile, bool bSaveStreams) { - if (!m_pInternal->pReader) - return; - - m_pInternal->pReader->ToXml(sFile, bSaveStreams); + if (m_pInternal->pReader) + m_pInternal->pReader->ToXml(sFile, bSaveStreams); } bool CPdfFile::GetMetaData(const std::wstring& sFile, const std::wstring& sMetaName, BYTE** pMetaData, DWORD& nMetaLength) @@ -320,7 +292,7 @@ bool CPdfFile::LoadFromMemory(BYTE* data, DWORD length, const std::wstring& opti m_pInternal->pReader = new CPdfReader(m_pInternal->pAppFonts); if (!m_pInternal->pReader) return false; - m_pInternal->wsSrcFile = L""; + m_pInternal->wsSrcFile.clear(); m_pInternal->wsPassword = owner_password; return m_pInternal->pReader->LoadFromMemory(m_pInternal->pAppFonts, data, length, owner_password, user_password) && (m_pInternal->pReader->GetError() == 0); } @@ -346,15 +318,13 @@ int CPdfFile::GetPagesCount() { if (!m_pInternal->pReader) return 0; - PDFDoc* pPdfDoc = m_pInternal->pReader->GetPDFDocument(); - int nPages = pPdfDoc ? pPdfDoc->getNumPages() : 0; if (m_pInternal->pEditor) { int nWPages = m_pInternal->pEditor->GetPagesCount(); if (nWPages > 0) - nPages = nWPages; + return nWPages; } - return nPages; + return m_pInternal->pReader->GetNumPages(); } void CPdfFile::GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) { @@ -365,6 +335,12 @@ void CPdfFile::GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, do else m_pInternal->pReader->GetPageInfo(nPageIndex, pdWidth, pdHeight, pdDpiX, pdDpiY); } +bool CPdfFile::MergePages(BYTE* data, DWORD length, int nMaxID, const std::string& sPrefixForm) +{ + if (!m_pInternal->pReader) + return false; + return m_pInternal->pReader->MergePages(data, length, L"", nMaxID, sPrefixForm) && (m_pInternal->pReader->GetError() == 0); +} int CPdfFile::GetRotate(int nPageIndex) { if (!m_pInternal->pReader) @@ -447,6 +423,22 @@ BYTE* CPdfFile::GetAnnots(int nPageIndex) return NULL; return m_pInternal->pReader->GetAnnots(nPageIndex); } +BYTE* CPdfFile::SplitPages(const int* arrPageIndex, unsigned int unLength) +{ + if (!m_pInternal->pReader) + return NULL; + RELEASEOBJECT(m_pInternal->pWriter); + m_pInternal->pWriter = new CPdfWriter(m_pInternal->pAppFonts, false, this); + + RELEASEOBJECT(m_pInternal->pEditor); + m_pInternal->pEditor = new CPdfEditor(m_pInternal->wsSrcFile, m_pInternal->wsPassword, L"", m_pInternal->pReader, m_pInternal->pWriter); + + BYTE* pRes = m_pInternal->pEditor->SplitPages(arrPageIndex, unLength); + + RELEASEOBJECT(m_pInternal->pWriter); + RELEASEOBJECT(m_pInternal->pEditor); + return pRes; +} BYTE* CPdfFile::VerifySign(const std::wstring& sFile, ICertificate* pCertificate, int nWidget) { if (!m_pInternal->pReader) @@ -487,44 +479,35 @@ int CPdfFile::SaveToFile(const std::wstring& wsPath) } void CPdfFile::SetPassword(const std::wstring& wsPassword) { - if (!m_pInternal->pWriter) - return; - m_pInternal->pWriter->SetPassword(wsPassword); + if (m_pInternal->pWriter) + m_pInternal->pWriter->SetPassword(wsPassword); } void CPdfFile::SetDocumentID(const std::wstring& wsDocumentID) { - if (!m_pInternal->pWriter) - return; - m_pInternal->pWriter->SetDocumentID(wsDocumentID); + if (m_pInternal->pWriter) + m_pInternal->pWriter->SetDocumentID(wsDocumentID); } void CPdfFile::AddMetaData(const std::wstring& sMetaName, BYTE* pMetaData, DWORD nMetaLength) { - if (!m_pInternal->pWriter) - return; - m_pInternal->pWriter->AddMetaData(sMetaName, pMetaData, nMetaLength); + if (m_pInternal->pWriter) + m_pInternal->pWriter->AddMetaData(sMetaName, pMetaData, nMetaLength); } HRESULT CPdfFile::OnlineWordToPdf(const std::wstring& wsSrcFile, const std::wstring& wsDstFile, CConvertFromBinParams* pParams) { -#ifndef BUILDING_WASM_MODULE if (!m_pInternal->pWriter || !NSOnlineOfficeBinToPdf::ConvertBinToPdf(this, wsSrcFile, wsDstFile, false, pParams)) return S_FALSE; -#endif return S_OK; } HRESULT CPdfFile::OnlineWordToPdfFromBinary(const std::wstring& wsSrcFile, const std::wstring& wsDstFile, CConvertFromBinParams* pParams) { -#ifndef BUILDING_WASM_MODULE if (!m_pInternal->pWriter || !NSOnlineOfficeBinToPdf::ConvertBinToPdf(this, wsSrcFile, wsDstFile, true, pParams)) return S_FALSE; -#endif return S_OK; } HRESULT CPdfFile::AddToPdfFromBinary(BYTE* pBuffer, unsigned int nLen, CConvertFromBinParams* pParams) { -#ifndef BUILDING_WASM_MODULE if (!m_pInternal->pEditor || !NSOnlineOfficeBinToPdf::AddBinToPdf(this, pBuffer, nLen, pParams)) return S_FALSE; -#endif return S_OK; } HRESULT CPdfFile::DrawImageWith1bppMask(IGrObject* pImage, NSImages::CPixJbig2* pMaskBuffer, const unsigned int& unMaskWidth, const unsigned int& unMaskHeight, const double& dX, const double& dY, const double& dW, const double& dH) @@ -861,28 +844,24 @@ HRESULT CPdfFile::get_BrushTextureImage(Aggplus::CImage** pImage) { if (!m_pInternal->pWriter) return S_FALSE; - return m_pInternal->pWriter->get_BrushTextureImage(pImage); } HRESULT CPdfFile::put_BrushTextureImage(Aggplus::CImage* pImage) { if (!m_pInternal->pWriter) return S_FALSE; - return m_pInternal->pWriter->put_BrushTextureImage(pImage); } HRESULT CPdfFile::get_BrushTransform(Aggplus::CMatrix& oMatrix) { if (!m_pInternal->pWriter) return S_FALSE; - return m_pInternal->pWriter->get_BrushTransform(oMatrix); } HRESULT CPdfFile::put_BrushTransform(const Aggplus::CMatrix& oMatrix) { if (!m_pInternal->pWriter) return S_FALSE; - return m_pInternal->pWriter->put_BrushTransform(oMatrix); } @@ -1258,7 +1237,15 @@ HRESULT CPdfFile::AdvancedCommand(IAdvancedCommand* command) { CAnnotFieldInfo* pCommand = (CAnnotFieldInfo*)command; if (m_pInternal->pEditor && m_pInternal->pEditor->IsEditPage()) + { m_pInternal->pEditor->EditAnnot(pCommand->GetPage(), pCommand->GetID()); + if (pCommand->IsStamp()) + { + int nFlags = pCommand->GetMarkupAnnotPr()->GetFlag(); + if (nFlags & (1 << 15)) + m_pInternal->pEditor->EditAnnot(pCommand->GetPage(), pCommand->GetCopyAP()); + } + } return m_pInternal->pWriter->AddAnnotField(m_pInternal->pAppFonts, pCommand); } case IAdvancedCommand::AdvancedCommandType::DeleteAnnot: diff --git a/PdfFile/PdfFile.h b/PdfFile/PdfFile.h index d055c338c6..8187bfdbea 100644 --- a/PdfFile/PdfFile.h +++ b/PdfFile/PdfFile.h @@ -90,16 +90,15 @@ public: virtual void Close(); // --- EDIT --- -#ifndef BUILDING_WASM_MODULE // Переходит в режим редактирования. Pdf уже должен быть открыт на чтение - LoadFromFile/LoadFromMemory bool EditPdf(const std::wstring& wsDstFile = L""); // Манипуляции со страницами возможны в режиме редактирования - bool EditPage (int nPageIndex); - bool DeletePage (int nPageIndex); - bool AddPage (int nPageIndex); - bool MovePage (int nPageIndex, int nPos); + bool EditPage (int nPageIndex); + bool DeletePage(int nPageIndex); + bool AddPage (int nPageIndex); + bool MovePage (int nPageIndex, int nPos); + bool MergePages(const std::wstring& wsPath, int nMaxID = 0, const std::wstring& wsPrefixForm = L""); HRESULT ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword = L""); -#endif // --- READER --- @@ -126,13 +125,16 @@ public: virtual std::wstring GetInfo(); virtual BYTE* GetStructure(); virtual BYTE* GetLinks(int nPageIndex); + bool ValidMetaData(); + bool MergePages(BYTE* data, DWORD length, int nMaxID = 0, const std::string& sPrefixForm = ""); int GetRotate(int nPageIndex); int GetMaxRefID(); BYTE* GetWidgets(); BYTE* GetAnnotEmbeddedFonts(); BYTE* GetAnnotStandardFonts(); BYTE* GetAnnots (int nPageIndex = -1); + BYTE* SplitPages (const int* arrPageIndex, unsigned int unLength); BYTE* VerifySign (const std::wstring& sFile, ICertificate* pCertificate, int nWidget = -1); BYTE* GetAPWidget (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget = -1, const char* sView = NULL, const char* sBView = NULL); BYTE* GetAPAnnots (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nAnnot = -1, const char* sView = NULL); diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index ba49925cb3..3ba5a28968 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -44,7 +44,6 @@ #include "Resources/BaseFonts.h" #include "lib/xpdf/PDFDoc.h" -#include "lib/xpdf/PDFCore.h" #include "lib/xpdf/GlobalParams.h" #include "lib/xpdf/ErrorCodes.h" #include "lib/xpdf/TextString.h" @@ -56,57 +55,15 @@ #include "lib/xpdf/AcroForm.h" #include "lib/goo/GList.h" -#include - -CPdfReader::CPdfReader(NSFonts::IApplicationFonts* pAppFonts) +NSFonts::IFontManager* InitFontManager(NSFonts::IApplicationFonts* pAppFonts) { - m_pPDFDocument = NULL; - m_nFileLength = 0; - - globalParams = new GlobalParamsAdaptor(NULL); -#ifndef _DEBUG - globalParams->setErrQuiet(gTrue); -#endif - - m_pFontList = new PdfReader::CPdfFontList(); - - // Создаем менеджер шрифтов с собственным кэшем - m_pFontManager = pAppFonts->GenerateFontManager(); + NSFonts::IFontManager* m_pFontManager = pAppFonts->GenerateFontManager(); NSFonts::IFontsCache* pMeasurerCache = NSFonts::NSFontCache::Create(); pMeasurerCache->SetStreams(pAppFonts->GetStreams()); m_pFontManager->SetOwnerCache(pMeasurerCache); pMeasurerCache->SetCacheSize(1); - ((GlobalParamsAdaptor*)globalParams)->SetFontManager(m_pFontManager); -#ifndef BUILDING_WASM_MODULE - globalParams->setupBaseFonts(NULL); - SetCMapFile(NSFile::GetProcessDirectory() + L"/cmap.bin"); -#else - globalParams->setDrawFormFields(gFalse); - globalParams->setDrawAnnotations(gFalse); - SetCMapMemory(NULL, 0); -#endif - - m_eError = errNone; + return m_pFontManager; } -CPdfReader::~CPdfReader() -{ - if (m_pFontList) - { - m_pFontList->Clear(); - delete m_pFontList; - } - - if (!m_wsTempFolder.empty()) - { - NSDirectory::DeleteDirectory(m_wsTempFolder); - m_wsTempFolder = L""; - } - - RELEASEOBJECT(m_pPDFDocument); - RELEASEOBJECT(globalParams); - RELEASEINTERFACE(m_pFontManager); -} - bool scanFonts(Dict *pResources, const std::vector& arrCMap, int nDepth, std::vector& arrUniqueResources) { if (nDepth > 5) @@ -238,109 +195,167 @@ bool scanAPfonts(Object* oAnnot, const std::vector& arrCMap, std::v oAP.free(); return bRes; } + +CPdfReaderContext::~CPdfReaderContext() +{ + if (m_pFontList) + { + m_pFontList->Clear(); + RELEASEOBJECT(m_pFontList) + } + RELEASEOBJECT(m_pDocument); +} + +CPdfReader::CPdfReader(NSFonts::IApplicationFonts* pAppFonts) +{ + m_nFileLength = 0; + + globalParams = new GlobalParamsAdaptor(NULL); +#ifndef _DEBUG + globalParams->setErrQuiet(gTrue); +#endif + + // Создаем менеджер шрифтов с собственным кэшем + m_pFontManager = InitFontManager(pAppFonts); +#ifndef BUILDING_WASM_MODULE + globalParams->setupBaseFonts(NULL); + SetCMapFile(NSFile::GetProcessDirectory() + L"/cmap.bin"); +#else + globalParams->setDrawFormFields(gFalse); + globalParams->setDrawAnnotations(gFalse); + SetCMapMemory(NULL, 0); +#endif + + m_eError = errNone; +} +CPdfReader::~CPdfReader() +{ + Clear(); + + if (!m_wsTempFolder.empty()) + NSDirectory::DeleteDirectory(m_wsTempFolder); + + RELEASEOBJECT(globalParams); + RELEASEINTERFACE(m_pFontManager); +} +void CPdfReader::Clear() +{ + for (CPdfReaderContext* pPDFContext : m_vPDFContext) + delete pPDFContext; + m_vPDFContext.clear(); +} + bool CPdfReader::IsNeedCMap() { - std::vector arrCMap = {"GB-EUC-H", "GB-EUC-V", "GB-H", "GB-V", "GBpc-EUC-H", "GBpc-EUC-V", "GBK-EUC-H", - "GBK-EUC-V", "GBKp-EUC-H", "GBKp-EUC-V", "GBK2K-H", "GBK2K-V", "GBT-H", "GBT-V", "GBTpc-EUC-H", "GBTpc-EUC-V", - "UniGB-UCS2-H", "UniGB-UCS2-V", "UniGB-UTF8-H", "UniGB-UTF8-V", "UniGB-UTF16-H", "UniGB-UTF16-V", "UniGB-UTF32-H", - "UniGB-UTF32-V", "B5pc-H", "B5pc-V", "B5-H", "B5-V", "HKscs-B5-H", "HKscs-B5-V", "HKdla-B5-H", "HKdla-B5-V", - "HKdlb-B5-H", "HKdlb-B5-V", "HKgccs-B5-H", "HKgccs-B5-V", "HKm314-B5-H", "HKm314-B5-V", "HKm471-B5-H", - "HKm471-B5-V", "ETen-B5-H", "ETen-B5-V", "ETenms-B5-H", "ETenms-B5-V", "ETHK-B5-H", "ETHK-B5-V", "CNS-EUC-H", - "CNS-EUC-V", "CNS1-H", "CNS1-V", "CNS2-H", "CNS2-V", "UniCNS-UCS2-H", "UniCNS-UCS2-V", "UniCNS-UTF8-H", - "UniCNS-UTF8-V", "UniCNS-UTF16-H", "UniCNS-UTF16-V", "UniCNS-UTF32-H", "UniCNS-UTF32-V", "78-EUC-H", "78-EUC-V", - "78-H", "78-V", "78-RKSJ-H", "78-RKSJ-V", "78ms-RKSJ-H", "78ms-RKSJ-V","83pv-RKSJ-H", "90ms-RKSJ-H", "90ms-RKSJ-V", - "90msp-RKSJ-H", "90msp-RKSJ-V", "90pv-RKSJ-H", "90pv-RKSJ-V", "Add-H", "Add-V", "Add-RKSJ-H", "Add-RKSJ-V", - "EUC-H", "EUC-V", "Ext-RKSJ-H", "Ext-RKSJ-V", "H", "V", "NWP-H", "NWP-V", "RKSJ-H", "RKSJ-V", "UniJIS-UCS2-H", - "UniJIS-UCS2-V", "UniJIS-UCS2-HW-H", "UniJIS-UCS2-HW-V", "UniJIS-UTF8-H", "UniJIS-UTF8-V", "UniJIS-UTF16-H", - "UniJIS-UTF16-V", "UniJIS-UTF32-H", "UniJIS-UTF32-V", "UniJIS2004-UTF8-H", "UniJIS2004-UTF8-V", "UniJIS2004-UTF16-H", - "UniJIS2004-UTF16-V", "UniJIS2004-UTF32-H", "UniJIS2004-UTF32-V", "UniJISPro-UCS2-V", "UniJISPro-UCS2-HW-V", - "UniJISPro-UTF8-V", "UniJISX0213-UTF32-H", "UniJISX0213-UTF32-V", "UniJISX02132004-UTF32-H", "UniJISX02132004-UTF32-V", - "WP-Symbol", "Hankaku", "Hiragana", "Katakana", "Roman", "KSC-EUC-H", "KSC-EUC-V", "KSC-H", "KSC-V", "KSC-Johab-H", - "KSC-Johab-V", "KSCms-UHC-H", "KSCms-UHC-V", "KSCms-UHC-HW-H", "KSCms-UHC-HW-V", "KSCpc-EUC-H", "KSCpc-EUC-V", - "UniKS-UCS2-H", "UniKS-UCS2-V", "UniKS-UTF8-H", "UniKS-UTF8-V", "UniKS-UTF16-H", "UniKS-UTF16-V", "UniKS-UTF32-H", - "UniKS-UTF32-V", "UniAKR-UTF8-H", "UniAKR-UTF16-H", "UniAKR-UTF32-H"}; - - if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) + if (!((GlobalParamsAdaptor*)globalParams)->IsNeedCMap()) return false; + if (m_vPDFContext.empty()) + return false; + + std::vector arrCMap = {"GB-EUC-H", "GB-EUC-V", "GB-H", "GB-V", "GBpc-EUC-H", "GBpc-EUC-V", "GBK-EUC-H", +"GBK-EUC-V", "GBKp-EUC-H", "GBKp-EUC-V", "GBK2K-H", "GBK2K-V", "GBT-H", "GBT-V", "GBTpc-EUC-H", "GBTpc-EUC-V", +"UniGB-UCS2-H", "UniGB-UCS2-V", "UniGB-UTF8-H", "UniGB-UTF8-V", "UniGB-UTF16-H", "UniGB-UTF16-V", "UniGB-UTF32-H", +"UniGB-UTF32-V", "B5pc-H", "B5pc-V", "B5-H", "B5-V", "HKscs-B5-H", "HKscs-B5-V", "HKdla-B5-H", "HKdla-B5-V", +"HKdlb-B5-H", "HKdlb-B5-V", "HKgccs-B5-H", "HKgccs-B5-V", "HKm314-B5-H", "HKm314-B5-V", "HKm471-B5-H", +"HKm471-B5-V", "ETen-B5-H", "ETen-B5-V", "ETenms-B5-H", "ETenms-B5-V", "ETHK-B5-H", "ETHK-B5-V", "CNS-EUC-H", +"CNS-EUC-V", "CNS1-H", "CNS1-V", "CNS2-H", "CNS2-V", "UniCNS-UCS2-H", "UniCNS-UCS2-V", "UniCNS-UTF8-H", +"UniCNS-UTF8-V", "UniCNS-UTF16-H", "UniCNS-UTF16-V", "UniCNS-UTF32-H", "UniCNS-UTF32-V", "78-EUC-H", "78-EUC-V", +"78-H", "78-V", "78-RKSJ-H", "78-RKSJ-V", "78ms-RKSJ-H", "78ms-RKSJ-V","83pv-RKSJ-H", "90ms-RKSJ-H", "90ms-RKSJ-V", +"90msp-RKSJ-H", "90msp-RKSJ-V", "90pv-RKSJ-H", "90pv-RKSJ-V", "Add-H", "Add-V", "Add-RKSJ-H", "Add-RKSJ-V", +"EUC-H", "EUC-V", "Ext-RKSJ-H", "Ext-RKSJ-V", "H", "V", "NWP-H", "NWP-V", "RKSJ-H", "RKSJ-V", "UniJIS-UCS2-H", +"UniJIS-UCS2-V", "UniJIS-UCS2-HW-H", "UniJIS-UCS2-HW-V", "UniJIS-UTF8-H", "UniJIS-UTF8-V", "UniJIS-UTF16-H", +"UniJIS-UTF16-V", "UniJIS-UTF32-H", "UniJIS-UTF32-V", "UniJIS2004-UTF8-H", "UniJIS2004-UTF8-V", "UniJIS2004-UTF16-H", +"UniJIS2004-UTF16-V", "UniJIS2004-UTF32-H", "UniJIS2004-UTF32-V", "UniJISPro-UCS2-V", "UniJISPro-UCS2-HW-V", +"UniJISPro-UTF8-V", "UniJISX0213-UTF32-H", "UniJISX0213-UTF32-V", "UniJISX02132004-UTF32-H", "UniJISX02132004-UTF32-V", +"WP-Symbol", "Hankaku", "Hiragana", "Katakana", "Roman", "KSC-EUC-H", "KSC-EUC-V", "KSC-H", "KSC-V", "KSC-Johab-H", +"KSC-Johab-V", "KSCms-UHC-H", "KSCms-UHC-V", "KSCms-UHC-HW-H", "KSCms-UHC-HW-V", "KSCpc-EUC-H", "KSCpc-EUC-V", +"UniKS-UCS2-H", "UniKS-UCS2-V", "UniKS-UTF8-H", "UniKS-UTF8-V", "UniKS-UTF16-H", "UniKS-UTF16-V", "UniKS-UTF32-H", +"UniKS-UTF32-V", "UniAKR-UTF8-H", "UniAKR-UTF16-H", "UniAKR-UTF32-H"}; std::vector arrUniqueResources; - for (int nPage = 1, nLastPage = m_pPDFDocument->getNumPages(); nPage <= nLastPage; ++nPage) + for (CPdfReaderContext* pPDFContext : m_vPDFContext) { - Page* pPage = m_pPDFDocument->getCatalog()->getPage(nPage); - Dict* pResources = pPage->getResourceDict(); - if (pResources && scanFonts(pResources, arrCMap, 0, arrUniqueResources)) - return true; - - Object oAnnots; - if (!pPage->getAnnots(&oAnnots)->isArray()) - { - oAnnots.free(); + PDFDoc* pDoc = pPDFContext->m_pDocument; + if (!pDoc || !pDoc->getCatalog()) continue; - } - for (int i = 0, nNum = oAnnots.arrayGetLength(); i < nNum; ++i) + + for (int nPage = 1, nLastPage = pDoc->getNumPages(); nPage <= nLastPage; ++nPage) { - Object oAnnot; - if (!oAnnots.arrayGet(i, &oAnnot)->isDict()) + Page* pPage = pDoc->getCatalog()->getPage(nPage); + Dict* pResources = pPage->getResourceDict(); + if (pResources && scanFonts(pResources, arrCMap, 0, arrUniqueResources)) + return true; + + Object oAnnots; + if (!pPage->getAnnots(&oAnnots)->isArray()) { - oAnnot.free(); + oAnnots.free(); continue; } - - Object oDR; - if (oAnnot.dictLookup("DR", &oDR)->isDict() && scanFonts(oDR.getDict(), arrCMap, 0, arrUniqueResources)) + for (int i = 0, nNum = oAnnots.arrayGetLength(); i < nNum; ++i) { - oDR.free(); oAnnot.free(); oAnnots.free(); - return true; - } - oDR.free(); + Object oAnnot; + if (!oAnnots.arrayGet(i, &oAnnot)->isDict()) + { + oAnnot.free(); + continue; + } - if (scanAPfonts(&oAnnot, arrCMap, arrUniqueResources)) - { - oAnnot.free(); oAnnots.free(); - return true; + Object oDR; + if (oAnnot.dictLookup("DR", &oDR)->isDict() && scanFonts(oDR.getDict(), arrCMap, 0, arrUniqueResources)) + { + oDR.free(); oAnnot.free(); oAnnots.free(); + return true; + } + oDR.free(); + + if (scanAPfonts(&oAnnot, arrCMap, arrUniqueResources)) + { + oAnnot.free(); oAnnots.free(); + return true; + } + oAnnot.free(); } - oAnnot.free(); + oAnnots.free(); } - oAnnots.free(); - } - AcroForm* pAcroForms = m_pPDFDocument->getCatalog()->getForm(); - if (!pAcroForms) - return false; - Object oDR; - Object* oAcroForm = pAcroForms->getAcroFormObj(); - if (oAcroForm->dictLookup("DR", &oDR)->isDict() && scanFonts(oDR.getDict(), arrCMap, 0, arrUniqueResources)) - { - oDR.free(); - return true; - } - oDR.free(); - - for (int i = 0, nNum = pAcroForms->getNumFields(); i < nNum; ++i) - { - AcroFormField* pField = pAcroForms->getField(i); - - if (pField->getResources(&oDR)->isDict() && scanFonts(oDR.getDict(), arrCMap, 0, arrUniqueResources)) + AcroForm* pAcroForms = pDoc->getCatalog()->getForm(); + if (!pAcroForms) + continue; + Object oDR; + Object* oAcroForm = pAcroForms->getAcroFormObj(); + if (oAcroForm->dictLookup("DR", &oDR)->isDict() && scanFonts(oDR.getDict(), arrCMap, 0, arrUniqueResources)) { oDR.free(); return true; } oDR.free(); - Object oWidgetRef, oWidget; - pField->getFieldRef(&oWidgetRef); - oWidgetRef.fetch(m_pPDFDocument->getXRef(), &oWidget); - oWidgetRef.free(); - - if (scanAPfonts(&oWidget, arrCMap, arrUniqueResources)) + for (int i = 0, nNum = pAcroForms->getNumFields(); i < nNum; ++i) { + AcroFormField* pField = pAcroForms->getField(i); + + if (pField->getResources(&oDR)->isDict() && scanFonts(oDR.getDict(), arrCMap, 0, arrUniqueResources)) + { + oDR.free(); + return true; + } + oDR.free(); + + Object oWidgetRef, oWidget; + pField->getFieldRef(&oWidgetRef); + oWidgetRef.fetch(pDoc->getXRef(), &oWidget); + oWidgetRef.free(); + + if (scanAPfonts(&oWidget, arrCMap, arrUniqueResources)) + { + oWidget.free(); + return true; + } oWidget.free(); - return true; } - oWidget.free(); } - return false; } void CPdfReader::SetCMapMemory(BYTE* pData, DWORD nSizeData) @@ -355,97 +370,39 @@ void CPdfReader::SetCMapFile(const std::wstring& sFile) { ((GlobalParamsAdaptor*)globalParams)->SetCMapFile(sFile); } + bool CPdfReader::LoadFromFile(NSFonts::IApplicationFonts* pAppFonts, const std::wstring& wsSrcPath, const std::wstring& wsOwnerPassword, const std::wstring& wsUserPassword) { + Clear(); RELEASEINTERFACE(m_pFontManager); - m_pFontManager = pAppFonts->GenerateFontManager(); - NSFonts::IFontsCache* pMeasurerCache = NSFonts::NSFontCache::Create(); - pMeasurerCache->SetStreams(pAppFonts->GetStreams()); - m_pFontManager->SetOwnerCache(pMeasurerCache); - pMeasurerCache->SetCacheSize(1); - ((GlobalParamsAdaptor*)globalParams)->SetFontManager(m_pFontManager); - - RELEASEOBJECT(m_pPDFDocument); + m_pFontManager = InitFontManager(pAppFonts); if (m_wsTempFolder == L"") SetTempDirectory(NSDirectory::GetTempPath()); m_eError = errNone; - GString* owner_pswd = NSStrings::CreateString(wsOwnerPassword); - GString* user_pswd = NSStrings::CreateString(wsUserPassword); - - // конвертим путь в utf8 - под виндой они сконвертят в юникод, а на остальных - так и надо - std::string sPathUtf8 = U_TO_UTF8(wsSrcPath); - m_pPDFDocument = new PDFDoc((char*)sPathUtf8.c_str(), owner_pswd, user_pswd); - - delete owner_pswd; - delete user_pswd; - NSFile::CFileBinary oFile; if (oFile.OpenFile(wsSrcPath)) { m_nFileLength = oFile.GetFileSize(); oFile.CloseFile(); } - - m_eError = m_pPDFDocument ? m_pPDFDocument->getErrorCode() : errMemory; - - if (!m_pPDFDocument || !m_pPDFDocument->isOk()) - { - RELEASEOBJECT(m_pPDFDocument); - return false; - } - - m_pFontList->Clear(); - - std::map mFonts = PdfReader::CAnnotFonts::GetAllFonts(m_pPDFDocument, m_pFontManager, m_pFontList); - m_mFonts.insert(mFonts.begin(), mFonts.end()); - - return true; + return MergePages(wsSrcPath, wsOwnerPassword); } -bool CPdfReader::LoadFromMemory(NSFonts::IApplicationFonts* pAppFonts, BYTE* data, DWORD length, const std::wstring& owner_password, const std::wstring& user_password) +bool CPdfReader::LoadFromMemory(NSFonts::IApplicationFonts* pAppFonts, BYTE* data, DWORD length, const std::wstring& wsOwnerPassword, const std::wstring& wsUserPassword) { + Clear(); RELEASEINTERFACE(m_pFontManager); - m_pFontManager = pAppFonts->GenerateFontManager(); - NSFonts::IFontsCache* pMeasurerCache = NSFonts::NSFontCache::Create(); - pMeasurerCache->SetStreams(pAppFonts->GetStreams()); - m_pFontManager->SetOwnerCache(pMeasurerCache); - pMeasurerCache->SetCacheSize(1); - ((GlobalParamsAdaptor*)globalParams)->SetFontManager(m_pFontManager); + m_pFontManager = InitFontManager(pAppFonts); - RELEASEOBJECT(m_pPDFDocument); m_eError = errNone; - GString* owner_pswd = NSStrings::CreateString(owner_password); - GString* user_pswd = NSStrings::CreateString(user_password); - - Object obj; - obj.initNull(); - // будет освобожден в деструкторе PDFDoc - BaseStream *str = new MemStream((char*)data, 0, length, &obj); - m_pPDFDocument = new PDFDoc(str, owner_pswd, user_pswd); m_nFileLength = length; - delete owner_pswd; - delete user_pswd; - - m_eError = m_pPDFDocument ? m_pPDFDocument->getErrorCode() : errMemory; - - if (!m_pPDFDocument || !m_pPDFDocument->isOk()) - { - RELEASEOBJECT(m_pPDFDocument); - return false; - } - - m_pFontList->Clear(); - - std::map mFonts = PdfReader::CAnnotFonts::GetAllFonts(m_pPDFDocument, m_pFontManager, m_pFontList); - m_mFonts.insert(mFonts.begin(), mFonts.end()); - - return true; + return MergePages(data, length, wsOwnerPassword); } void CPdfReader::Close() { - RELEASEOBJECT(m_pPDFDocument); + Clear(); m_mFonts.clear(); } void CPdfReader::SetParams(COfficeDrawingPageParams* pParams) @@ -458,37 +415,97 @@ void CPdfReader::SetParams(COfficeDrawingPageParams* pParams) globalParams->setDrawAnnotations(bDraw); } +int CPdfReader::GetStartRefID(PDFDoc* _pDoc) +{ + for (CPdfReaderContext* pPDFContext : m_vPDFContext) + { + if (!pPDFContext || !pPDFContext->m_pDocument) + continue; + PDFDoc* pDoc = pPDFContext->m_pDocument; + if (_pDoc == pDoc) + return pPDFContext->m_nStartID; + } + return -1; +} +int CPdfReader::FindRefNum(int nObjID, PDFDoc** _pDoc, int* _nStartRefID) +{ + for (CPdfReaderContext* pPDFContext : m_vPDFContext) + { + if (!pPDFContext || !pPDFContext->m_pDocument) + continue; + PDFDoc* pDoc = pPDFContext->m_pDocument; + if (nObjID < pPDFContext->m_nStartID + pDoc->getXRef()->getNumObjects()) + { + if (_pDoc) + *_pDoc = pDoc; + if (_nStartRefID) + *_nStartRefID = pPDFContext->m_nStartID; + return nObjID - pPDFContext->m_nStartID; + } + } + return -1; +} +int CPdfReader::GetPageIndex(int nAbsPageIndex, PDFDoc** _pDoc, PdfReader::CPdfFontList** pFontList, int* nStartRefID) +{ + int nTotalPages = 0; + for (CPdfReaderContext* pPDFContext : m_vPDFContext) + { + if (!pPDFContext || !pPDFContext->m_pDocument) + continue; + PDFDoc* pDoc = pPDFContext->m_pDocument; + + int nPages = pDoc->getNumPages(); + if (nAbsPageIndex < nTotalPages + nPages) + { + if (_pDoc) + *_pDoc = pDoc; + if (pFontList) + *pFontList = pPDFContext->m_pFontList; + if (nStartRefID) + *nStartRefID = pPDFContext->m_nStartID; + return nAbsPageIndex - nTotalPages + 1; + } + nTotalPages += nPages; + } + return -1; +} int CPdfReader::GetError() { - if (!m_pPDFDocument) + if (m_vPDFContext.empty()) return m_eError; - if (m_pPDFDocument->isOk()) - return 0; + for (CPdfReaderContext* pPDFContext : m_vPDFContext) + { + PDFDoc* pDoc = pPDFContext->m_pDocument; + if (!pDoc) + return m_eError; - return m_pPDFDocument->getErrorCode(); + if (pDoc->isOk() == gFalse) + return pDoc->getErrorCode(); + } + return 0; } void CPdfReader::GetPageInfo(int _nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY) { - int nPageIndex = _nPageIndex + 1; - - if (!m_pPDFDocument) + PDFDoc* pDoc = NULL; + int nPageIndex = GetPageIndex(_nPageIndex, &pDoc); + if (nPageIndex < 0 || !pDoc) return; #ifdef BUILDING_WASM_MODULE - *pdWidth = m_pPDFDocument->getPageCropWidth(nPageIndex); - *pdHeight = m_pPDFDocument->getPageCropHeight(nPageIndex); + *pdWidth = pDoc->getPageCropWidth(nPageIndex); + *pdHeight = pDoc->getPageCropHeight(nPageIndex); #else - int nRotate = m_pPDFDocument->getPageRotate(nPageIndex); + int nRotate = pDoc->getPageRotate(nPageIndex); if (nRotate % 180 == 0) { - *pdWidth = m_pPDFDocument->getPageCropWidth(nPageIndex); - *pdHeight = m_pPDFDocument->getPageCropHeight(nPageIndex); + *pdWidth = pDoc->getPageCropWidth(nPageIndex); + *pdHeight = pDoc->getPageCropHeight(nPageIndex); } else { - *pdHeight = m_pPDFDocument->getPageCropWidth(nPageIndex); - *pdWidth = m_pPDFDocument->getPageCropHeight(nPageIndex); + *pdHeight = pDoc->getPageCropWidth(nPageIndex); + *pdWidth = pDoc->getPageCropHeight(nPageIndex); } #endif @@ -497,29 +514,46 @@ void CPdfReader::GetPageInfo(int _nPageIndex, double* pdWidth, double* pdHeight, } int CPdfReader::GetRotate(int _nPageIndex) { - if (!m_pPDFDocument) + PDFDoc* pDoc = NULL; + int nPageIndex = GetPageIndex(_nPageIndex, &pDoc); + if (nPageIndex < 0 || !pDoc) return 0; - return m_pPDFDocument->getPageRotate(_nPageIndex + 1); + return pDoc->getPageRotate(nPageIndex); } int CPdfReader::GetMaxRefID() { - if (!m_pPDFDocument) - return 0; - return m_pPDFDocument->getXRef()->getNumObjects(); + if (!m_vPDFContext.empty()) + return m_vPDFContext.back()->m_nStartID + m_vPDFContext.back()->m_pDocument->getXRef()->getNumObjects(); + return 0; +} +int CPdfReader::GetNumPages() +{ + int nNumPages = 0; + for (CPdfReaderContext* pPDFContext : m_vPDFContext) + { + if (!pPDFContext || !pPDFContext->m_pDocument) + continue; + nNumPages += pPDFContext->m_pDocument->getNumPages(); + } + return nNumPages; } bool CPdfReader::ValidMetaData() { - if (!m_pPDFDocument) + if (m_vPDFContext.empty() || m_vPDFContext.size() != 1) return false; - XRef* xref = m_pPDFDocument->getXRef(); - Object oMeta, oType, oID; - if (!xref->fetch(1, 0, &oMeta)->isStream() || !oMeta.streamGetDict()->lookup("Type", &oType)->isName("MetaOForm") || !oMeta.streamGetDict()->lookup("ID", &oID)->isString()) + CPdfReaderContext* pPDFContext = m_vPDFContext.front(); + if (!pPDFContext || !pPDFContext->m_pDocument) + return false; + + XRef* xref = pPDFContext->m_pDocument->getXRef(); + Object oMeta, oID; + if (!xref->fetch(1, 0, &oMeta)->isStream("MetaOForm") || !oMeta.streamGetDict()->lookup("ID", &oID)->isString()) { - oMeta.free(); oType.free(); oID.free(); + oMeta.free(); oID.free(); return false; } - oMeta.free(); oType.free(); + oMeta.free(); Object oTID, oID2; Object* pTrailerDict = xref->getTrailerDict(); @@ -534,27 +568,102 @@ bool CPdfReader::ValidMetaData() oID.free(); oID2.free(); return bRes; } +bool CPdfReader::MergePages(BYTE* pData, DWORD nLength, const std::wstring& wsPassword, int nMaxID, const std::string& sPrefixForm) +{ + if (m_eError) + return false; + + GString* owner_pswd = NSStrings::CreateString(wsPassword); + GString* user_pswd = NSStrings::CreateString(wsPassword); + + Object obj; + obj.initNull(); + // будет освобожден в деструкторе PDFDoc + BaseStream *str = new MemStream((char*)pData, 0, nLength, &obj); + CPdfReaderContext* pContext = new CPdfReaderContext(); + pContext->m_pDocument = new PDFDoc(str, owner_pswd, user_pswd); + pContext->m_pFontList = new PdfReader::CPdfFontList(); + pContext->m_sPrefixForm = sPrefixForm; + if (nMaxID != 0) + pContext->m_nStartID = nMaxID; + else if (!m_vPDFContext.empty()) + pContext->m_nStartID = m_vPDFContext.back()->m_nStartID + m_vPDFContext.back()->m_pDocument->getXRef()->getNumObjects(); + PDFDoc* pDoc = pContext->m_pDocument; + m_vPDFContext.push_back(pContext); + + delete owner_pswd; + delete user_pswd; + + m_eError = pDoc ? pDoc->getErrorCode() : errMemory; + if (!pDoc || !pDoc->isOk()) + { + delete pContext; + m_vPDFContext.pop_back(); + return false; + } + + std::map mFonts = PdfReader::CAnnotFonts::GetAllFonts(pDoc, m_pFontManager, pContext->m_pFontList); + m_mFonts.insert(mFonts.begin(), mFonts.end()); + + return true; +} +bool CPdfReader::MergePages(const std::wstring& wsFile, const std::wstring& wsPassword, int nMaxID, const std::string& sPrefixForm) +{ + if (m_eError) + return false; + GString* owner_pswd = NSStrings::CreateString(wsPassword); + GString* user_pswd = NSStrings::CreateString(wsPassword); + // конвертим путь в utf8 - под виндой они сконвертят в юникод, а на остальных - так и надо + std::string sPathUtf8 = U_TO_UTF8(wsFile); + + CPdfReaderContext* pContext = new CPdfReaderContext(); + pContext->m_pDocument = new PDFDoc((char*)sPathUtf8.c_str(), owner_pswd, user_pswd); + pContext->m_pFontList = new PdfReader::CPdfFontList(); + pContext->m_sPrefixForm = sPrefixForm; + if (nMaxID != 0) + pContext->m_nStartID = nMaxID; + else if (!m_vPDFContext.empty()) + pContext->m_nStartID = m_vPDFContext.back()->m_nStartID + m_vPDFContext.back()->m_pDocument->getXRef()->getNumObjects(); + PDFDoc* pDoc = pContext->m_pDocument; + m_vPDFContext.push_back(pContext); + + delete owner_pswd; + delete user_pswd; + + m_eError = pDoc ? pDoc->getErrorCode() : errMemory; + if (!pDoc || !pDoc->isOk()) + { + delete pContext; + m_vPDFContext.pop_back(); + return false; + } + + std::map mFonts = PdfReader::CAnnotFonts::GetAllFonts(pDoc, m_pFontManager, pContext->m_pFontList); + m_mFonts.insert(mFonts.begin(), mFonts.end()); + + return true; +} void CPdfReader::DrawPageOnRenderer(IRenderer* pRenderer, int _nPageIndex, bool* pbBreak) { - if (m_pPDFDocument && pRenderer) - { - PdfReader::RendererOutputDev oRendererOut(pRenderer, m_pFontManager, m_pFontList); - oRendererOut.NewPDF(m_pPDFDocument->getXRef()); - oRendererOut.SetBreak(pbBreak); - int nRotate = 0; + PDFDoc* pDoc = NULL; + PdfReader::CPdfFontList* pFontList = NULL; + int nPageIndex = GetPageIndex(_nPageIndex, &pDoc, &pFontList); + if (nPageIndex < 0 || !pDoc || !pFontList) + return; + + PdfReader::RendererOutputDev oRendererOut(pRenderer, m_pFontManager, pFontList); + oRendererOut.NewPDF(pDoc->getXRef()); + oRendererOut.SetBreak(pbBreak); + int nRotate = 0; #ifdef BUILDING_WASM_MODULE - nRotate = -m_pPDFDocument->getPageRotate(_nPageIndex + 1); + nRotate = -pDoc->getPageRotate(nPageIndex); #endif - m_pPDFDocument->displayPage(&oRendererOut, _nPageIndex + 1, 72.0, 72.0, nRotate, gFalse, gTrue, gFalse); - } + pDoc->displayPage(&oRendererOut, nPageIndex, 72.0, 72.0, nRotate, gFalse, gTrue, gFalse); } void CPdfReader::SetTempDirectory(const std::wstring& wsTempFolder) { if (!m_wsTempFolder.empty()) - { NSDirectory::DeleteDirectory(m_wsTempFolder); - m_wsTempFolder = wsTempFolder; - } if (!wsTempFolder.empty()) { @@ -581,7 +690,7 @@ std::wstring CPdfReader::GetTempDirectory() } std::wstring CPdfReader::ToXml(const std::wstring& wsFilePath, bool isPrintStream) { - XMLConverter oConverter(m_pPDFDocument->getXRef(), isPrintStream); + XMLConverter oConverter(m_vPDFContext.front()->m_pDocument->getXRef(), isPrintStream); std::wstring wsXml = oConverter.GetXml(); if (wsFilePath != L"") @@ -596,24 +705,43 @@ std::wstring CPdfReader::ToXml(const std::wstring& wsFilePath, bool isPrintStrea return wsXml; } -void CPdfReader::ChangeLength(DWORD nLength) +PDFDoc* CPdfReader::GetLastPDFDocument() { - m_nFileLength = nLength; + if (m_vPDFContext.empty()) + return NULL; + + CPdfReaderContext* pPDFContext = m_vPDFContext.back(); + if (pPDFContext) + return pPDFContext->m_pDocument; + return NULL; +} +PDFDoc* CPdfReader::GetPDFDocument(int PDFIndex) +{ + if (PDFIndex >= 0 && PDFIndex < m_vPDFContext.size()) + return m_vPDFContext[PDFIndex]->m_pDocument; + return NULL; } std::wstring CPdfReader::GetInfo() { - if (!m_pPDFDocument) - return NULL; - XRef* xref = m_pPDFDocument->getXRef(); - BaseStream* str = m_pPDFDocument->getBaseStream(); + std::wstring sRes; + if (m_vPDFContext.empty()) + return sRes; + + CPdfReaderContext* pPDFContext = m_vPDFContext.front(); + if (!pPDFContext || !pPDFContext->m_pDocument) + return sRes; + + PDFDoc* pDoc = pPDFContext->m_pDocument; + XRef* xref = pDoc->getXRef(); + BaseStream* str = pDoc->getBaseStream(); if (!xref || !str) return NULL; - std::wstring sRes = L"{"; + sRes = L"{"; Object oInfo; - if (m_pPDFDocument->getDocInfo(&oInfo)->isDict()) + if (pDoc->getDocInfo(&oInfo)->isDict()) { auto fDictLookup = [&oInfo](const char* sName, const wchar_t* wsName) { @@ -685,7 +813,7 @@ std::wstring CPdfReader::GetInfo() } oInfo.free(); - std::wstring version = std::to_wstring(m_pPDFDocument->getPDFVersion()); + std::wstring version = std::to_wstring(pDoc->getPDFVersion()); std::wstring::size_type posDot = version.find('.'); if (posDot != std::wstring::npos) version.resize(posDot + 2); @@ -701,34 +829,36 @@ std::wstring CPdfReader::GetInfo() sRes += L",\"PageHeight\":"; sRes += std::to_wstring((int)(nH * 100)); sRes += L",\"NumberOfPages\":"; - sRes += std::to_wstring(m_pPDFDocument->getNumPages()); + sRes += std::to_wstring(GetNumPages()); sRes += L",\"FastWebView\":"; - Object obj1, obj2, obj3, obj4, obj5, obj6; bool bLinearized = false; - obj1.initNull(); - Parser* parser = new Parser(xref, new Lexer(xref, str->makeSubStream(str->getStart(), gFalse, 0, &obj1)), gTrue); - parser->getObj(&obj1); - parser->getObj(&obj2); - parser->getObj(&obj3); - parser->getObj(&obj4); - if (obj1.isInt() && obj2.isInt() && obj3.isCmd("obj") && obj4.isDict()) + if (m_vPDFContext.size() == 1) { - obj4.dictLookup("Linearized", &obj5); - obj4.dictLookup("L", &obj6); - if (obj5.isNum() && obj5.getNum() > 0 && obj6.isNum()) + Object obj1, obj2, obj3, obj4, obj5, obj6; + obj1.initNull(); + Parser* parser = new Parser(xref, new Lexer(xref, str->makeSubStream(str->getStart(), gFalse, 0, &obj1)), gTrue); + parser->getObj(&obj1); + parser->getObj(&obj2); + parser->getObj(&obj3); + parser->getObj(&obj4); + if (obj1.isInt() && obj2.isInt() && obj3.isCmd("obj") && obj4.isDict()) { - unsigned long size = (unsigned long)obj6.getNum(); - bLinearized = size == m_nFileLength; + obj4.dictLookup("Linearized", &obj5); + if (obj5.isNum() && obj5.getNum() > 0 && obj4.dictLookup("L", &obj6)->isNum()) + { + unsigned long size = (unsigned long)obj6.getNum(); + bLinearized = size == m_nFileLength; + } + obj6.free(); + obj5.free(); } - obj6.free(); - obj5.free(); + obj4.free(); + obj3.free(); + obj2.free(); + obj1.free(); + delete parser; } - obj4.free(); - obj3.free(); - obj2.free(); - obj1.free(); - delete parser; sRes += bLinearized ? L"true" : L"false"; sRes += L",\"Tagged\":"; @@ -760,7 +890,7 @@ std::wstring CPdfReader::GetFontPath(const std::wstring& wsFontName, bool bSave) std::map::const_iterator oIter = m_mFonts.find(wsFontName); return oIter == m_mFonts.end() ? std::wstring() : oIter->second; } -void getBookmarks(PDFDoc* pdfDoc, OutlineItem* pOutlineItem, NSWasm::CData& out, int level) +void getBookmarks(PDFDoc* pdfDoc, OutlineItem* pOutlineItem, NSWasm::CData& out, int level, int nStartPage) { LinkAction* pLinkAction = pOutlineItem->getAction(); if (!pLinkAction || pLinkAction->getKind() != actionGoTo) @@ -799,7 +929,7 @@ void getBookmarks(PDFDoc* pdfDoc, OutlineItem* pOutlineItem, NSWasm::CData& out, std::string sTitle = NSStringExt::CConverter::GetUtf8FromUTF32(pOutlineItem->getTitle(), pOutlineItem->getTitleLength()); - out.AddInt(pg - 1); + out.AddInt(nStartPage + pg - 1); out.AddInt(level); out.AddDouble(dy); out.WriteString((BYTE*)sTitle.c_str(), (unsigned int)sTitle.length()); @@ -815,49 +945,75 @@ void getBookmarks(PDFDoc* pdfDoc, OutlineItem* pOutlineItem, NSWasm::CData& out, { OutlineItem* pOutlineItemKid = (OutlineItem*)pList->get(i); if (pOutlineItemKid) - getBookmarks(pdfDoc, pOutlineItemKid, out, level + 1); + getBookmarks(pdfDoc, pOutlineItemKid, out, level + 1, nStartPage); } pOutlineItem->close(); } BYTE* CPdfReader::GetStructure() { - if (!m_pPDFDocument) - return NULL; - Outline* pOutline = m_pPDFDocument->getOutline(); - if (!pOutline) - return NULL; - GList* pList = pOutline->getItems(); - if (!pList) + if (m_vPDFContext.empty()) return NULL; NSWasm::CData oRes; oRes.SkipLen(); - for (int i = 0, num = pList->getLength(); i < num; i++) + + int nStartPage = 0; + for (int iPDF = 0; iPDF < m_vPDFContext.size(); ++iPDF) { - OutlineItem* pOutlineItem = (OutlineItem*)pList->get(i); - if (pOutlineItem) - getBookmarks(m_pPDFDocument, pOutlineItem, oRes, 1); + PDFDoc* pDoc = m_vPDFContext[iPDF]->m_pDocument; + Outline* pOutline = pDoc->getOutline(); + if (!pOutline) + { + nStartPage += pDoc->getNumPages(); + continue; + } + + GList* pList = pOutline->getItems(); + if (!pList) + { + nStartPage += pDoc->getNumPages(); + continue; + } + + if (iPDF > 0) + { + oRes.AddInt(nStartPage); + oRes.AddInt(1); + oRes.AddDouble(0); + oRes.WriteString(std::to_string(iPDF)); // TODO Писать имя файла как Adobe? + } + + for (int i = 0, num = pList->getLength(); i < num; i++) + { + OutlineItem* pOutlineItem = (OutlineItem*)pList->get(i); + if (pOutlineItem) + getBookmarks(pDoc, pOutlineItem, oRes, iPDF > 0 ? 2 : 1, nStartPage); + } + nStartPage += pDoc->getNumPages(); } + oRes.WriteLen(); BYTE* bRes = oRes.GetBuffer(); oRes.ClearWithoutAttack(); return bRes; } -BYTE* CPdfReader::GetLinks(int nPageIndex) +BYTE* CPdfReader::GetLinks(int _nPageIndex) { - if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) + // TODO Links должны стать частью Annots + PDFDoc* pDoc = NULL; + int nPageIndex = GetPageIndex(_nPageIndex, &pDoc); + if (nPageIndex < 0 || !pDoc || !pDoc->getCatalog()) return NULL; - nPageIndex++; - Page* pPage = m_pPDFDocument->getCatalog()->getPage(nPageIndex); + Page* pPage = pDoc->getCatalog()->getPage(nPageIndex); if (!pPage) return NULL; NSWasm::CPageLink oLinks; // Гиперссылка - Links* pLinks = m_pPDFDocument->getLinks(nPageIndex); + Links* pLinks = pDoc->getLinks(nPageIndex); if (pLinks) { PDFRectangle* cropBox = pPage->getCropBox(); @@ -882,14 +1038,14 @@ BYTE* CPdfReader::GetLinks(int nPageIndex) if (kind == actionGoTo) { str = ((LinkGoTo*)pLinkAction)->getNamedDest(); - LinkDest* pLinkDest = str ? m_pPDFDocument->findDest(str) : ((LinkGoTo*)pLinkAction)->getDest()->copy(); + LinkDest* pLinkDest = str ? pDoc->findDest(str) : ((LinkGoTo*)pLinkAction)->getDest()->copy(); if (pLinkDest) { int pg; if (pLinkDest->isPageRef()) { Ref pageRef = pLinkDest->getPageRef(); - pg = m_pPDFDocument->findPage(pageRef.num, pageRef.gen); + pg = pDoc->findPage(pageRef.num, pageRef.gen); } else pg = pLinkDest->getPageNum(); @@ -898,7 +1054,7 @@ BYTE* CPdfReader::GetLinks(int nPageIndex) std::string sLink = "#" + std::to_string(pg - 1); str = new GString(sLink.c_str()); - dy = m_pPDFDocument->getPageCropHeight(pg) - pLinkDest->getTop(); + dy = pDoc->getPageCropHeight(pg) - pLinkDest->getTop(); } else str = NULL; @@ -913,8 +1069,8 @@ BYTE* CPdfReader::GetLinks(int nPageIndex) if (!str->cmp("NextPage")) { pg = nPageIndex + 1; - if (pg > m_pPDFDocument->getNumPages()) - pg = m_pPDFDocument->getNumPages(); + if (pg > pDoc->getNumPages()) + pg = pDoc->getNumPages(); } else if (!str->cmp("PrevPage")) { @@ -923,7 +1079,7 @@ BYTE* CPdfReader::GetLinks(int nPageIndex) pg = 1; } else if (!str->cmp("LastPage")) - pg = m_pPDFDocument->getNumPages(); + pg = pDoc->getNumPages(); std::string sLink = "#" + std::to_string(pg - 1); str = new GString(sLink.c_str()); @@ -937,15 +1093,15 @@ BYTE* CPdfReader::GetLinks(int nPageIndex) int nRotate = 0; #ifdef BUILDING_WASM_MODULE - nRotate = -m_pPDFDocument->getPageRotate(nPageIndex); + nRotate = -pDoc->getPageRotate(nPageIndex); #endif // Текст-ссылка TextOutputControl textOutControl; textOutControl.mode = textOutReadingOrder; TextOutputDev* pTextOut = new TextOutputDev(NULL, &textOutControl, gFalse); - m_pPDFDocument->displayPage(pTextOut, nPageIndex, 72.0, 72.0, nRotate, gFalse, gTrue, gFalse); - m_pPDFDocument->processLinks(pTextOut, nPageIndex); + pDoc->displayPage(pTextOut, nPageIndex, 72.0, 72.0, nRotate, gFalse, gTrue, gFalse); + pDoc->processLinks(pTextOut, nPageIndex); TextWordList* pWordList = pTextOut->makeWordList(); for (int i = 0; i < pWordList->getLength(); i++) { @@ -977,18 +1133,54 @@ BYTE* CPdfReader::GetLinks(int nPageIndex) } BYTE* CPdfReader::GetWidgets() { - if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) - return NULL; - if (!m_pPDFDocument->getCatalog()->getForm() || !m_pPDFDocument->getXRef()) - return NULL; - NSWasm::CData oRes; oRes.SkipLen(); - PdfReader::CAnnots* pAnnots = new PdfReader::CAnnots(m_pPDFDocument, m_pFontManager, m_pFontList); - if (pAnnots) - pAnnots->ToWASM(oRes); - RELEASEOBJECT(pAnnots); + std::map mForms; + int nStartPage = 0; + for (int iPDF = 0; iPDF < m_vPDFContext.size(); ++iPDF) + { + PDFDoc* pDoc = m_vPDFContext[iPDF]->m_pDocument; + if (!pDoc || !pDoc->getCatalog()) + continue; + if (!pDoc->getCatalog()->getForm() || !pDoc->getXRef()) + { + nStartPage += pDoc->getNumPages(); + continue; + } + + PdfReader::CAnnots* pAnnots = new PdfReader::CAnnots(pDoc, m_pFontManager, m_vPDFContext[iPDF]->m_pFontList, nStartPage, m_vPDFContext[iPDF]->m_nStartID); + if (pAnnots) + { + const std::vector& arrAnnots = pAnnots->GetAnnots(); + for (int i = 0; i < arrAnnots.size(); ++i) + { + const std::string& sFullName = arrAnnots[i]->GetFullName(); + std::map::iterator it = mForms.find(sFullName); + if (it == mForms.end()) + mForms[sFullName] = arrAnnots[i]->GetType(); + else if (mForms[sFullName] != arrAnnots[i]->GetType()) + { + if (iPDF == 0) + { + // error + // throw "Same full names for forms of different types within the same file"; + } + else + { + int nPrefix = 0; + std::string sPrefix = m_vPDFContext[iPDF]->m_sPrefixForm + "_" + std::to_string(nPrefix); + while (!pAnnots->ChangeFullNameAnnot(i, sPrefix)) + sPrefix = m_vPDFContext[iPDF]->m_sPrefixForm + "_" + std::to_string(++nPrefix); + } + } + } + + pAnnots->ToWASM(oRes); + } + RELEASEOBJECT(pAnnots); + nStartPage += pDoc->getNumPages(); + } oRes.WriteLen(); BYTE* bRes = oRes.GetBuffer(); @@ -1004,7 +1196,7 @@ BYTE* CPdfReader::GetFonts(bool bStandart) int nFontsPos = oRes.GetSize(); oRes.AddInt(nFonts); - for (std::map::iterator it = m_mFonts.begin(); it != m_mFonts.end(); ++it) + for (std::map::const_iterator it = m_mFonts.begin(); it != m_mFonts.end(); ++it) { if (PdfReader::CAnnotFonts::IsBaseFont(it->second)) { @@ -1030,10 +1222,14 @@ BYTE* CPdfReader::GetFonts(bool bStandart) } BYTE* CPdfReader::VerifySign(const std::wstring& sFile, ICertificate* pCertificate, int nWidget) { - if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) + if (m_vPDFContext.empty()) return NULL; - AcroForm* pAcroForms = m_pPDFDocument->getCatalog()->getForm(); + CPdfReaderContext* pPDFContext = m_vPDFContext.front(); + if (!pPDFContext || !pPDFContext->m_pDocument || !pPDFContext->m_pDocument->getCatalog()) + return NULL; + + AcroForm* pAcroForms = pPDFContext->m_pDocument->getCatalog()->getForm(); if (!pAcroForms) return NULL; @@ -1109,12 +1305,16 @@ BYTE* CPdfReader::VerifySign(const std::wstring& sFile, ICertificate* pCertifica oRes.ClearWithoutAttack(); return bRes; } -BYTE* CPdfReader::GetAPWidget(int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget, const char* sView, const char* sButtonView) +BYTE* CPdfReader::GetAPWidget(int nRasterW, int nRasterH, int nBackgroundColor, int _nPageIndex, int nWidget, const char* sView, const char* sButtonView) { - if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) + PDFDoc* pDoc = NULL; + PdfReader::CPdfFontList* pFontList = NULL; + int nStartRefID = 0; + int nPageIndex = GetPageIndex(_nPageIndex, &pDoc, &pFontList, &nStartRefID); + if (nPageIndex < 0 || !pDoc || !pFontList || !pDoc->getCatalog()) return NULL; - AcroForm* pAcroForms = m_pPDFDocument->getCatalog()->getForm(); + AcroForm* pAcroForms = pDoc->getCatalog()->getForm(); if (!pAcroForms) return NULL; @@ -1125,14 +1325,14 @@ BYTE* CPdfReader::GetAPWidget(int nRasterW, int nRasterH, int nBackgroundColor, { AcroFormField* pField = pAcroForms->getField(i); Object oRef; - if (pField->getPageNum() != nPageIndex + 1 || (nWidget >= 0 && pField->getFieldRef(&oRef) && oRef.getRefNum() != nWidget)) + if (pField->getPageNum() != nPageIndex || (nWidget >= 0 && pField->getFieldRef(&oRef) && oRef.getRefNum() + nStartRefID != nWidget)) { oRef.free(); continue; } oRef.free(); - PdfReader::CAnnotAP* pAP = new PdfReader::CAnnotAP(m_pPDFDocument, m_pFontManager, m_pFontList, nRasterW, nRasterH, nBackgroundColor, nPageIndex, sView, sButtonView, pField); + PdfReader::CAnnotAP* pAP = new PdfReader::CAnnotAP(pDoc, m_pFontManager, pFontList, nRasterW, nRasterH, nBackgroundColor, nPageIndex, sView, sButtonView, pField, nStartRefID); if (pAP) pAP->ToWASM(oRes); RELEASEOBJECT(pAP); @@ -1143,12 +1343,16 @@ BYTE* CPdfReader::GetAPWidget(int nRasterW, int nRasterH, int nBackgroundColor, oRes.ClearWithoutAttack(); return bRes; } -BYTE* CPdfReader::GetButtonIcon(int nBackgroundColor, int nPageIndex, bool bBase64, int nButtonWidget, const char* sIconView) +BYTE* CPdfReader::GetButtonIcon(int nBackgroundColor, int _nPageIndex, bool bBase64, int nButtonWidget, const char* sIconView) { - if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) + PDFDoc* pDoc = NULL; + PdfReader::CPdfFontList* pFontList = NULL; + int nStartRefID = 0; + int nPageIndex = GetPageIndex(_nPageIndex, &pDoc, &pFontList, &nStartRefID); + if (nPageIndex < 0 || !pDoc || !pDoc->getCatalog()) return NULL; - AcroForm* pAcroForms = m_pPDFDocument->getCatalog()->getForm(); + AcroForm* pAcroForms = pDoc->getCatalog()->getForm(); if (!pAcroForms) return NULL; @@ -1159,8 +1363,14 @@ BYTE* CPdfReader::GetButtonIcon(int nBackgroundColor, int nPageIndex, bool bBase for (int i = 0, nNum = pAcroForms->getNumFields(); i < nNum; ++i) { AcroFormField* pField = pAcroForms->getField(i); - if (pField->getPageNum() != nPageIndex + 1 || pField->getAcroFormFieldType() != acroFormFieldPushbutton || (nButtonWidget >= 0 && i != nButtonWidget)) + Object oRef; + if (pField->getPageNum() != nPageIndex || pField->getAcroFormFieldType() != acroFormFieldPushbutton || + (nButtonWidget >= 0 && pField->getFieldRef(&oRef) && oRef.getRefNum() + nStartRefID != nButtonWidget)) + { + oRef.free(); continue; + } + oRef.free(); Object oMK; if (!pField->fieldLookup("MK", &oMK)->isDict()) @@ -1168,18 +1378,60 @@ BYTE* CPdfReader::GetButtonIcon(int nBackgroundColor, int nPageIndex, bool bBase oMK.free(); continue; } + Object oAP; + pField->fieldLookup("AP", &oAP); bool bFirst = true; int nMKPos = -1; unsigned int nMKLength = 0; std::vector arrMKName { "I", "RI", "IX" }; + std::vector arrAPName { "N", "D", "R" }; for (unsigned int j = 0; j < arrMKName.size(); ++j) { if (sIconView && strcmp(sIconView, arrMKName[j]) != 0) continue; std::string sMKName(arrMKName[j]); - Object oStr; - if (!oMK.dictLookup(sMKName.c_str(), &oStr)->isStream()) + Object oStr, oXObject, oIm;; + if (oMK.dictLookup(sMKName.c_str(), &oStr)->isStream()) + { + // Получение единственного XObject из Resources, если возможно + Object oResources; + if (!oStr.streamGetDict()->lookup("Resources", &oResources)->isDict() || !oResources.dictLookup("XObject", &oXObject)->isDict() || + oXObject.dictGetLength() != 1 || !oXObject.dictGetVal(0, &oIm)->isStream()) + { + oStr.free(); oResources.free(); oXObject.free(); oIm.free(); + continue; + } + oStr.free(); oResources.free(); + } + else if (oAP.isDict() && (oStr.free(), true) && oAP.dictLookup(arrAPName[j], &oStr)->isStream()) + { + // Получение единственного XObject из Resources, если возможно + Object oResources; + if (!oStr.streamGetDict()->lookup("Resources", &oResources)->isDict() || !oResources.dictLookup("XObject", &oXObject)->isDict() || + oXObject.dictGetLength() != 1 || !oXObject.dictGetVal(0, &oIm)->isStream()) + { + oStr.free(); oResources.free(); oXObject.free(); oIm.free(); + continue; + } + oStr.free(); oResources.free(); + + Object oSubtype; + Dict *oImDict = oIm.streamGetDict(); + if (oImDict->is("XObject") && oImDict->lookup("Subtype", &oSubtype)->isName() && !oSubtype.isName("Image")) + { + if (!oImDict->lookup("Resources", &oResources)->isDict() || (oXObject.free(), false) || !oResources.dictLookup("XObject", &oXObject)->isDict() || + oXObject.dictGetLength() != 1 || (oIm.free(), false) || !oXObject.dictGetVal(0, &oIm)->isStream()) + { + oSubtype.free(); + oResources.free(); oXObject.free(); oIm.free(); + continue; + } + oResources.free(); + } + oSubtype.free(); + } + else { oStr.free(); continue; @@ -1190,7 +1442,7 @@ BYTE* CPdfReader::GetButtonIcon(int nBackgroundColor, int nPageIndex, bool bBase Object oFieldRef; pField->getFieldRef(&oFieldRef); // Номер аннотации для сопоставления с AP - oRes.AddInt(oFieldRef.getRefNum()); + oRes.AddInt(oFieldRef.getRefNum() + nStartRefID); oFieldRef.free(); // Количество иконок 1-3 @@ -1199,29 +1451,20 @@ BYTE* CPdfReader::GetButtonIcon(int nBackgroundColor, int nPageIndex, bool bBase bFirst = false; } - // Получение единственного XObject из Resources, если возможно - Object oResources, oXObject, oIm; - if (!oStr.streamGetDict()->lookup("Resources", &oResources)->isDict() || !oResources.dictLookup("XObject", &oXObject)->isDict() || oXObject.dictGetLength() != 1 || !oXObject.dictGetVal(0, &oIm)->isStream()) - { - oStr.free(); oResources.free(); oXObject.free(); oIm.free(); - continue; - } - oStr.free(); oResources.free(); - Dict *oImDict = oIm.streamGetDict(); - Object oType, oSubtype; - if (!oImDict->lookup("Type", &oType)->isName("XObject") || !oImDict->lookup("Subtype", &oSubtype)->isName("Image")) + Object oSubtype; + if (!oImDict->is("XObject") || !oImDict->lookup("Subtype", &oSubtype)->isName("Image")) { - oType.free(); oSubtype.free(); + oSubtype.free(); oXObject.free(); oIm.free(); continue; } - oType.free(); oSubtype.free(); + oSubtype.free(); oRes.WriteString(sMKName); Object oStrRef; oXObject.dictGetValNF(0, &oStrRef); - int nView = oStrRef.getRefNum(); + int nView = oStrRef.getRefNum() + nStartRefID; oRes.AddInt(nView); oStrRef.free(); oXObject.free(); if (std::find(arrUniqueImage.begin(), arrUniqueImage.end(), nView) != arrUniqueImage.end()) @@ -1407,7 +1650,7 @@ BYTE* CPdfReader::GetButtonIcon(int nBackgroundColor, int nPageIndex, bool bBase oIm.free(); } - oMK.free(); + oMK.free(); oAP.free(); if (nMKPos > 0) oRes.AddInt(nMKLength, nMKPos); @@ -1418,19 +1661,20 @@ BYTE* CPdfReader::GetButtonIcon(int nBackgroundColor, int nPageIndex, bool bBase oRes.ClearWithoutAttack(); return bRes; } -void GetPageAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, PdfReader::CPdfFontList *pFontList, NSWasm::CData& oRes, int nPageIndex) +int GetPageAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, PdfReader::CPdfFontList *pFontList, NSWasm::CData& oRes, int nPageIndex, int nStartPage, int nStartRefID) { - Page* pPage = pdfDoc->getCatalog()->getPage(nPageIndex + 1); + Page* pPage = pdfDoc->getCatalog()->getPage(nPageIndex); if (!pPage) - return; + return 0; Object oAnnots; if (!pPage->getAnnots(&oAnnots)->isArray()) { oAnnots.free(); - return; + return 0; } + int nRes = 0; for (int i = 0, nNum = oAnnots.arrayGetLength(); i < nNum; ++i) { Object oAnnot; @@ -1451,7 +1695,7 @@ void GetPageAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, PdfReade oAnnots.arrayGetNF(i, &oAnnotRef); if (sType == "Text") { - pAnnot = new PdfReader::CAnnotText(pdfDoc, &oAnnotRef, nPageIndex); + pAnnot = new PdfReader::CAnnotText(pdfDoc, &oAnnotRef, nPageIndex, nStartRefID); } else if (sType == "Link") { @@ -1459,143 +1703,125 @@ void GetPageAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, PdfReade } else if (sType == "FreeText") { - PdfReader::CAnnotFreeText* pFreeText = new PdfReader::CAnnotFreeText(pdfDoc, &oAnnotRef, nPageIndex); + PdfReader::CAnnotFreeText* pFreeText = new PdfReader::CAnnotFreeText(pdfDoc, &oAnnotRef, nPageIndex, nStartRefID); pFreeText->SetFont(pdfDoc, &oAnnotRef, pFontManager, pFontList); pAnnot = pFreeText; } else if (sType == "Line") { - pAnnot = new PdfReader::CAnnotLine(pdfDoc, &oAnnotRef, nPageIndex); + pAnnot = new PdfReader::CAnnotLine(pdfDoc, &oAnnotRef, nPageIndex, nStartRefID); } else if (sType == "Square" || sType == "Circle") { - pAnnot = new PdfReader::CAnnotSquareCircle(pdfDoc, &oAnnotRef, nPageIndex); + pAnnot = new PdfReader::CAnnotSquareCircle(pdfDoc, &oAnnotRef, nPageIndex, nStartRefID); } else if (sType == "Polygon" || sType == "PolyLine") { - pAnnot = new PdfReader::CAnnotPolygonLine(pdfDoc, &oAnnotRef, nPageIndex); + pAnnot = new PdfReader::CAnnotPolygonLine(pdfDoc, &oAnnotRef, nPageIndex, nStartRefID); } else if (sType == "Highlight" || sType == "Underline" || sType == "Squiggly" || sType == "StrikeOut") { - pAnnot = new PdfReader::CAnnotTextMarkup(pdfDoc, &oAnnotRef, nPageIndex); + pAnnot = new PdfReader::CAnnotTextMarkup(pdfDoc, &oAnnotRef, nPageIndex, nStartRefID); } else if (sType == "Stamp") { - pAnnot = new PdfReader::CAnnotStamp(pdfDoc, &oAnnotRef, nPageIndex); + pAnnot = new PdfReader::CAnnotStamp(pdfDoc, &oAnnotRef, nPageIndex, nStartRefID); } else if (sType == "Caret") { - pAnnot = new PdfReader::CAnnotCaret(pdfDoc, &oAnnotRef, nPageIndex); + pAnnot = new PdfReader::CAnnotCaret(pdfDoc, &oAnnotRef, nPageIndex, nStartRefID); } else if (sType == "Ink") { - pAnnot = new PdfReader::CAnnotInk(pdfDoc, &oAnnotRef, nPageIndex); + pAnnot = new PdfReader::CAnnotInk(pdfDoc, &oAnnotRef, nPageIndex, nStartRefID); } // else if (sType == "FileAttachment") // { - // pAnnot = new PdfReader::CAnnotFileAttachment(pdfDoc, &oAnnotRef, nPageIndex); + // pAnnot = new PdfReader::CAnnotFileAttachment(pdfDoc, &oAnnotRef, nPageIndex, nStartRefID); // } // else if (sType == "Popup") // { - // pAnnot = new PdfReader::CAnnotPopup(pdfDoc, &oAnnotRef, nPageIndex); + // pAnnot = new PdfReader::CAnnotPopup(pdfDoc, &oAnnotRef, nPageIndex, nStartRefID); // } // TODO Все аннотации oAnnotRef.free(); if (pAnnot) + { + pAnnot->SetPage(nStartPage + nPageIndex); pAnnot->ToWASM(oRes); + nRes++; + } RELEASEOBJECT(pAnnot); } oAnnots.free(); + return nRes; } -BYTE* CPdfReader::GetAnnots(int nPageIndex) +BYTE* CPdfReader::GetAnnots(int _nPageIndex) { - if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) + if (m_vPDFContext.empty()) return NULL; NSWasm::CData oRes; oRes.SkipLen(); - if (nPageIndex >= 0) - GetPageAnnots(m_pPDFDocument, m_pFontManager, m_pFontList, oRes, nPageIndex); + if (_nPageIndex >= 0) + { + PDFDoc* pDoc = NULL; + PdfReader::CPdfFontList* pFontList = NULL; + int nStartRefID = 0; + int nPageIndex = GetPageIndex(_nPageIndex, &pDoc, &pFontList, &nStartRefID); + if (nPageIndex < 0 || !pDoc || !pFontList || !pDoc->getCatalog()) + return NULL; + + int nAnnots = 0; + int nPosAnnots = oRes.GetSize(); + oRes.AddInt(nAnnots); + + nAnnots = GetPageAnnots(pDoc, m_pFontManager, pFontList, oRes, nPageIndex, _nPageIndex + 1 - nPageIndex, nStartRefID); + + oRes.AddInt(nAnnots, nPosAnnots); + } else - for (int nPage = 0, nLastPage = m_pPDFDocument->getNumPages(); nPage < nLastPage; ++nPage) - GetPageAnnots(m_pPDFDocument, m_pFontManager, m_pFontList, oRes, nPage); - - oRes.WriteLen(); - BYTE* bRes = oRes.GetBuffer(); - oRes.ClearWithoutAttack(); - return bRes; -} -BYTE* CPdfReader::GetShapes(int nPageIndex) -{ - if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) - return NULL; - Dict* pResources = m_pPDFDocument->getCatalog()->getPage(nPageIndex + 1)->getResourceDict(); - if (!pResources) - return NULL; - - Object oProperties, oMetaOForm, oID; - XRef* xref = m_pPDFDocument->getXRef(); - if (!pResources->lookup("Properties", &oProperties)->isDict() || !oProperties.dictLookup("OShapes", &oMetaOForm)->isDict("OShapes") || !oMetaOForm.dictLookup("ID", &oID)->isString()) { - oProperties.free(); oMetaOForm.free(); oID.free(); - return NULL; - } - oProperties.free(); - - Object oTID, oID2; - Object* pTrailerDict = xref->getTrailerDict(); - if (!pTrailerDict->dictLookup("ID", &oTID)->isArray() || !oTID.arrayGet(1, &oID2)->isString() || oID2.getString()->cmp(oID.getString()) != 0) - { - oMetaOForm.free(); oID.free(); oTID.free(); oID2.free(); - return NULL; - } - oID.free(); oTID.free(); oID2.free(); - - Object oMetadata; - if (!oMetaOForm.dictLookup("Metadata", &oMetadata)->isArray()) - { - oMetaOForm.free(); oMetadata.free(); - return NULL; - } - oMetaOForm.free(); - - NSWasm::CData oRes; - oRes.SkipLen(); - int nMetadataLength = oMetadata.arrayGetLength(); - oRes.AddInt(nMetadataLength); - - for (int i = 0; i < nMetadataLength; ++i) - { - Object oMetaStr; - std::string sStr; - if (oMetadata.arrayGet(i, &oMetaStr)->isString()) + int nStartPage = 0; + for (CPdfReaderContext* pPDFContext : m_vPDFContext) { - TextString* s = new TextString(oMetaStr.getString()); - sStr = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); - delete s; + PDFDoc* pDoc = pPDFContext->m_pDocument; + if (!pDoc || !pDoc->getCatalog() || !pPDFContext->m_pFontList) + continue; + int nAnnots = 0; + int nPosAnnots = oRes.GetSize(); + oRes.AddInt(nAnnots); + + for (int nPage = 1, nPages = pDoc->getNumPages(); nPage <= nPages; ++nPage) + nAnnots += GetPageAnnots(pDoc, m_pFontManager, pPDFContext->m_pFontList, oRes, nPage, nStartPage, pPDFContext->m_nStartID); + + oRes.AddInt(nAnnots, nPosAnnots); + nStartPage += pDoc->getNumPages(); } - oRes.WriteString(sStr); } - oMetadata.free(); oRes.WriteLen(); BYTE* bRes = oRes.GetBuffer(); oRes.ClearWithoutAttack(); return bRes; } -BYTE* CPdfReader::GetAPAnnots(int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nAnnot, const char* sView) +BYTE* CPdfReader::GetAPAnnots(int nRasterW, int nRasterH, int nBackgroundColor, int _nPageIndex, int nAnnot, const char* sView) { - if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) + PDFDoc* pDoc = NULL; + PdfReader::CPdfFontList* pFontList = NULL; + int nStartRefID = 0; + int nPageIndex = GetPageIndex(_nPageIndex, &pDoc, &pFontList, &nStartRefID); + if (nPageIndex < 0 || !pDoc || !pFontList || !pDoc->getCatalog()) return NULL; Object oAnnots; - Page* pPage = m_pPDFDocument->getCatalog()->getPage(nPageIndex + 1); + Page* pPage = pDoc->getCatalog()->getPage(nPageIndex); if (!pPage || !pPage->getAnnots(&oAnnots)->isArray()) { oAnnots.free(); @@ -1608,7 +1834,7 @@ BYTE* CPdfReader::GetAPAnnots(int nRasterW, int nRasterH, int nBackgroundColor, for (int i = 0, nNum = oAnnots.arrayGetLength(); i < nNum; ++i) { Object oAnnotRef; - if (!oAnnots.arrayGetNF(i, &oAnnotRef)->isRef() || (nAnnot >= 0 && oAnnotRef.getRefNum() != nAnnot)) + if (!oAnnots.arrayGetNF(i, &oAnnotRef)->isRef() || (nAnnot >= 0 && oAnnotRef.getRefNum() + nStartRefID != nAnnot)) { oAnnotRef.free(); continue; @@ -1627,7 +1853,7 @@ BYTE* CPdfReader::GetAPAnnots(int nRasterW, int nRasterH, int nBackgroundColor, continue; } - PdfReader::CAnnotAP* pAP = new PdfReader::CAnnotAP(m_pPDFDocument, m_pFontManager, m_pFontList, nRasterW, nRasterH, nBackgroundColor, nPageIndex, sView, &oAnnotRef); + PdfReader::CAnnotAP* pAP = new PdfReader::CAnnotAP(pDoc, m_pFontManager, pFontList, nRasterW, nRasterH, nBackgroundColor, nPageIndex, sView, &oAnnotRef, nStartRefID); if (pAP) pAP->ToWASM(oRes); RELEASEOBJECT(pAP); @@ -1642,7 +1868,3 @@ BYTE* CPdfReader::GetAPAnnots(int nRasterW, int nRasterH, int nBackgroundColor, oRes.ClearWithoutAttack(); return bRes; } -std::map CPdfReader::GetAnnotFonts(Object* pRefAnnot) -{ - return PdfReader::CAnnotFonts::GetAnnotFont(m_pPDFDocument, m_pFontManager, m_pFontList, pRefAnnot); -} diff --git a/PdfFile/PdfReader.h b/PdfFile/PdfReader.h index 2cb86aeb75..e02874cc50 100644 --- a/PdfFile/PdfReader.h +++ b/PdfFile/PdfReader.h @@ -32,16 +32,29 @@ #ifndef _PDF_READER_H #define _PDF_READER_H -#include "../../DesktopEditor/graphics/pro/Fonts.h" -#include "../../DesktopEditor/graphics/pro/officedrawingfile.h" -#include "../../DesktopEditor/xmlsec/src/include/Certificate.h" +#include "../DesktopEditor/graphics/pro/Fonts.h" +#include "../DesktopEditor/graphics/pro/officedrawingfile.h" +#include "../DesktopEditor/xmlsec/src/include/Certificate.h" #include "SrcReader/RendererOutputDev.h" +#include +#include + class PDFDoc; +struct CPdfReaderContext +{ + PDFDoc* m_pDocument; + PdfReader::CPdfFontList* m_pFontList; + unsigned int m_nStartID; + std::string m_sPrefixForm; + + CPdfReaderContext() : m_pDocument(NULL), m_pFontList(NULL), m_nStartID(0) {} + ~CPdfReaderContext(); +}; + class CPdfReader { public: - CPdfReader(NSFonts::IApplicationFonts* pAppFonts); ~CPdfReader(); @@ -62,37 +75,43 @@ public: int GetError(); int GetRotate(int nPageIndex); int GetMaxRefID(); + int GetNumPages(); bool ValidMetaData(); + bool MergePages(BYTE* pData, DWORD nLength, const std::wstring& wsPassword = L"", int nMaxID = 0, const std::string& sPrefixForm = ""); + bool MergePages(const std::wstring& wsFile, const std::wstring& wsPassword = L"", int nMaxID = 0, const std::string& sPrefixForm = ""); void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY); void DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak); std::wstring GetInfo(); std::wstring GetFontPath(const std::wstring& wsFontName, bool bSave = true); - std::wstring ToXml(const std::wstring& wsXmlPath, bool isPrintStreams = false); - void ChangeLength(DWORD nLength); + void ChangeLength(DWORD nLength) { m_nFileLength = nLength; } + NSFonts::IFontManager* GetFontManager() { return m_pFontManager; } - PDFDoc* GetPDFDocument() { return m_pPDFDocument; } + PDFDoc* GetLastPDFDocument(); + PDFDoc* GetPDFDocument(int PDFIndex); + int GetStartRefID(PDFDoc* pDoc); + int FindRefNum(int nObjID, PDFDoc** pDoc = NULL, int* nStartRefID = NULL); + int GetPageIndex(int nPageIndex, PDFDoc** pDoc = NULL, PdfReader::CPdfFontList** pFontList = NULL, int* nStartRefID = NULL); BYTE* GetStructure(); BYTE* GetLinks(int nPageIndex); BYTE* GetWidgets(); BYTE* GetFonts(bool bStandart); BYTE* GetAnnots(int nPageIndex = -1); - BYTE* GetShapes(int nPageIndex); BYTE* VerifySign(const std::wstring& sFile, ICertificate* pCertificate, int nWidget = -1); BYTE* GetAPWidget (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nWidget = -1, const char* sView = NULL, const char* sBView = NULL); BYTE* GetAPAnnots (int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, int nAnnot = -1, const char* sView = NULL); BYTE* GetButtonIcon(int nBackgroundColor, int nPageIndex, bool bBase64 = false, int nBWidget = -1, const char* sIView = NULL); - std::map GetAnnotFonts(Object* pRefAnnot); - std::map GetFonts() { return m_mFonts; } + const std::map& GetFonts() { return m_mFonts; } private: - PDFDoc* m_pPDFDocument; + void Clear(); + std::wstring m_wsTempFolder; NSFonts::IFontManager* m_pFontManager; - PdfReader::CPdfFontList* m_pFontList; DWORD m_nFileLength; int m_eError; + std::vector m_vPDFContext; std::map m_mFonts; }; diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 56e4d1f8a9..69df9405ea 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -57,7 +57,9 @@ #include "../DesktopEditor/raster/Metafile/MetaFileCommon.h" #include "../UnicodeConverter/UnicodeConverter.h" +#ifndef BUILDING_WASM_MODULE #include "../Common/Network/FileTransporter/include/FileTransporter.h" +#endif #if defined(GetTempPath) #undef GetTempPath @@ -140,6 +142,7 @@ CPdfWriter::CPdfWriter(NSFonts::IApplicationFonts* pAppFonts, bool isPDFA, IRend pMeasurerCache->SetStreams(pAppFonts->GetStreams()); m_pFontManager->SetOwnerCache(pMeasurerCache); m_pRenderer = pRenderer; + m_bNeedAddHelvetica = true; m_pDocument = new PdfWriter::CDocument(); @@ -190,7 +193,7 @@ int CPdfWriter::SaveToFile(const std::wstring& wsPath) if (!IsValid()) return 1; - if (!m_pFont && !m_pFont14 && !m_pDocument->IsPDFA()) + if (!m_pFont && !m_pFont14 && !m_pDocument->IsPDFA() && m_bNeedAddHelvetica) { m_bNeedUpdateTextFont = false; m_pFont14 = m_pDocument->CreateFont14(L"Helvetica", 0, PdfWriter::EStandard14Fonts::standard14fonts_Helvetica); @@ -204,6 +207,19 @@ int CPdfWriter::SaveToFile(const std::wstring& wsPath) return 0; } +int CPdfWriter::SaveToMemory(BYTE** pData, int* pLength) +{ + // TODO: Переделать на код ошибки + if (!IsValid()) + return 1; + + m_oCommandManager.Flush(); + + if (!m_pDocument->SaveToMemory(pData, pLength)) + return 1; + + return 0; +} void CPdfWriter::SetDocumentInfo(const std::wstring& wsTitle, const std::wstring& wsCreator, const std::wstring& wsSubject, const std::wstring& wsKeywords) { if (!IsValid()) @@ -1669,6 +1685,121 @@ void GetRCSpanStyle(CAnnotFieldInfo::CMarkupAnnotPr::CFontData* pFontData, NSStr oRC.AddDouble(pFontData->dVAlign, 2); } } +PdfWriter::CAction* GetAction(PdfWriter::CDocument* m_pDocument, CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget* pAction) +{ + PdfWriter::CAction* pA = m_pDocument->CreateAction(pAction->nActionType); + if (!pA) + return NULL; + pA->SetType(pAction->wsType); + + switch (pAction->nActionType) + { + case 1: + { + PdfWriter::CActionGoTo* ppA = (PdfWriter::CActionGoTo*)pA; + PdfWriter::CPage* pPageD = m_pDocument->GetPage(pAction->nInt1); + PdfWriter::CDestination* pDest = m_pDocument->CreateDestination(pPageD); + if (!pDest) + break; + ppA->SetDestination(pDest); + + PdfWriter::CArrayObject* pPageBoxD = (PdfWriter::CArrayObject*)pPageD->Get("CropBox"); + if (!pPageBoxD) + pPageBoxD = (PdfWriter::CArrayObject*)pPageD->Get("MediaBox"); + if (!pPageBoxD) + return NULL; + PdfWriter::CObjectBase* pD = pPageBoxD->Get(3); + double dPageDH = pD->GetType() == PdfWriter::object_type_NUMBER ? ((PdfWriter::CNumberObject*)pD)->Get() : ((PdfWriter::CRealObject*)pD)->Get(); + pD = pPageBoxD->Get(0); + double dPageDX = pD->GetType() == PdfWriter::object_type_NUMBER ? ((PdfWriter::CNumberObject*)pD)->Get() : ((PdfWriter::CRealObject*)pD)->Get(); + + switch (pAction->nKind) + { + case 0: + { + pDest->SetXYZ(pAction->dD[0] + dPageDX, dPageDH - pAction->dD[1], pAction->dD[2]); + break; + } + case 1: + { + pDest->SetFit(); + break; + } + case 2: + { + pDest->SetFitH(dPageDH - pAction->dD[1]); + break; + } + case 3: + { + pDest->SetFitV(pAction->dD[0] + dPageDX); + break; + } + case 4: + { + pDest->SetFitR(pAction->dD[0] + dPageDX, dPageDH - pAction->dD[1], pAction->dD[2] + dPageDX, dPageDH - pAction->dD[3]); + break; + } + case 5: + { + pDest->SetFitB(); + break; + } + case 6: + { + pDest->SetFitBH(dPageDH - pAction->dD[1]); + break; + } + case 7: + { + pDest->SetFitBV(pAction->dD[0] + dPageDX); + break; + } + } + break; + } + case 6: + { + PdfWriter::CActionURI* ppA = (PdfWriter::CActionURI*)pA; + ppA->SetURI(pAction->wsStr1); + break; + } + case 9: + { + PdfWriter::CActionHide* ppA = (PdfWriter::CActionHide*)pA; + ppA->SetH(pAction->nKind); + ppA->SetT(pAction->arrStr); + break; + } + case 10: + { + PdfWriter::CActionNamed* ppA = (PdfWriter::CActionNamed*)pA; + ppA->SetN(pAction->wsStr1); + break; + } + case 12: + { + PdfWriter::CActionResetForm* ppA = (PdfWriter::CActionResetForm*)pA; + ppA->SetFlags(pAction->nInt1); + ppA->SetFields(pAction->arrStr); + break; + } + case 14: + { + PdfWriter::CActionJavaScript* ppA = (PdfWriter::CActionJavaScript*)pA; + ppA->SetJS(pAction->wsStr1); + break; + } + } + + if (pAction->pNext) + { + PdfWriter::CAction* pANext = GetAction(m_pDocument, pAction->pNext); + pA->SetNext(pANext); + } + + return pA; +} HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotFieldInfo* pFieldInfo) { if (!m_pDocument || 0 == m_pDocument->GetPagesCount() || !pFieldInfo) @@ -1701,68 +1832,13 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF if (!pAnnot) { - if (oInfo.IsText()) - pAnnot = m_pDocument->CreateTextAnnot(); - else if (oInfo.IsInk()) - pAnnot = m_pDocument->CreateInkAnnot(); - else if (oInfo.IsLine()) - pAnnot = m_pDocument->CreateLineAnnot(); - else if (oInfo.IsTextMarkup()) - pAnnot = m_pDocument->CreateTextMarkupAnnot(); - else if (oInfo.IsSquareCircle()) - pAnnot = m_pDocument->CreateSquareCircleAnnot(); - else if (oInfo.IsPolygonLine()) - pAnnot = m_pDocument->CreatePolygonLineAnnot(); - else if (oInfo.IsPopup()) - pAnnot = m_pDocument->CreatePopupAnnot(); - else if (oInfo.IsFreeText()) - pAnnot = m_pDocument->CreateFreeTextAnnot(); - else if (oInfo.IsCaret()) - pAnnot = m_pDocument->CreateCaretAnnot(); - else if (oInfo.IsStamp()) - pAnnot = m_pDocument->CreateStampAnnot(); - - if (oInfo.IsWidget()) - { - switch (nWidgetType) - { - case 26: - { - pAnnot = m_pDocument->CreateWidgetAnnot(); - break; - } - case 27: - { - pAnnot = m_pDocument->CreatePushButtonWidget(); - break; - } - case 28: - case 29: - { - pAnnot = m_pDocument->CreateCheckBoxWidget(); - break; - } - case 30: - { - pAnnot = m_pDocument->CreateTextWidget(); - break; - } - case 31: - case 32: - { - pAnnot = m_pDocument->CreateChoiceWidget(); - break; - } - case 33: - { - pAnnot = m_pDocument->CreateSignatureWidget(); - break; - } - } - } + CAnnotFieldInfo::EAnnotType oType = oInfo.GetType(); + BYTE nType = (BYTE) oType; + pAnnot = m_pDocument->CreateAnnot(nType); if (pAnnot) { + m_pDocument->AddObject(pAnnot); m_pDocument->AddAnnotation(nID, pAnnot); pPage->AddAnnotation(pAnnot); } @@ -1812,6 +1888,7 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF bool bRender = (nFlags >> 6) & 1; if (nFlags & (1 << 7)) pAnnot->SetOUserID(oInfo.GetOUserID()); + bool bRenderCopy = (nFlags >> 8) & 1; if (oInfo.IsMarkup()) { @@ -2104,7 +2181,6 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF if (bRender) { - pMarkupAnnot->RemoveAP(); LONG nLen = 0; BYTE* pRender = oInfo.GetRender(nLen); PdfWriter::CAnnotAppearanceObject* pAP = DrawAP(pAnnot, pRender, nLen); @@ -2119,6 +2195,17 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF pArray->Add(MM_2_PT(m_dPageHeight) - dRD2); pStampAnnot->SetAPStream(pAP); } + else if (bRenderCopy) + { + int nID = oInfo.GetCopyAP(); + PdfWriter::CAnnotation* pAnnot2 = m_pDocument->GetAnnot(nID); + if (pAnnot2->GetAnnotationType() == PdfWriter::EAnnotType::AnnotStamp) + { + PdfWriter::CStampAnnotation* pStampAnnot2 = (PdfWriter::CStampAnnotation*)pAnnot2; + PdfWriter::CDictObject* pAPN = (PdfWriter::CDictObject*)pStampAnnot2->GetAPStream(); + pStampAnnot->SetAPStream(pAPN, true); + } + } pStampAnnot->SetRotate(nRotate); } @@ -2155,9 +2242,8 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF BYTE nAlign = pPr->GetQ(); if (nWidgetType != 27 && nWidgetType != 28 && nWidgetType != 29) pWidgetAnnot->SetQ(nAlign); - int nWidgetFlag = pPr->GetFlag(); pWidgetAnnot->SetSubtype(nWidgetType); - pWidgetAnnot->SetFlag(nWidgetFlag); + pWidgetAnnot->SetFlag(pPr->GetFlag()); int nFlags = pPr->GetFlags(); if (nFlags & (1 << 0)) @@ -2174,6 +2260,8 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF pWidgetAnnot->SetBG(pPr->GetBG()); if (nFlags & (1 << 8)) pWidgetAnnot->SetDV(pPr->GetDV()); + if (nFlags & (1 << 17)) + pWidgetAnnot->SetParentID(pPr->GetParentID()); if (nFlags & (1 << 18)) pWidgetAnnot->SetT(pPr->GetT()); if (nFlags & (1 << 20)) @@ -2182,110 +2270,7 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF const std::vector arrActions = pPr->GetActions(); for (CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget* pAction : arrActions) { - PdfWriter::CAction* pA = (PdfWriter::CAction*)m_pDocument->CreateAction(pAction->nActionType); - if (!pA) - continue; - pA->SetType(pAction->wsType); - - switch (pAction->nActionType) - { - case 1: - { - PdfWriter::CActionGoTo* ppA = (PdfWriter::CActionGoTo*)pA; - PdfWriter::CPage* pPageD = m_pDocument->GetPage(pAction->nInt1); - PdfWriter::CDestination* pDest = m_pDocument->CreateDestination(pPageD); - if (!pDest) - break; - ppA->SetDestination(pDest); - - PdfWriter::CArrayObject* pPageBoxD = (PdfWriter::CArrayObject*)pPageD->Get("CropBox"); - if (!pPageBoxD) - pPageBoxD = (PdfWriter::CArrayObject*)pPageD->Get("MediaBox"); - if (!pPageBoxD) - pPageBoxD = pPageBox; - pD = pPageBoxD->Get(3); - double dPageDH = pD->GetType() == PdfWriter::object_type_NUMBER ? ((PdfWriter::CNumberObject*)pD)->Get() : ((PdfWriter::CRealObject*)pD)->Get(); - pD = pPageBoxD->Get(0); - double dPageDX = pD->GetType() == PdfWriter::object_type_NUMBER ? ((PdfWriter::CNumberObject*)pD)->Get() : ((PdfWriter::CRealObject*)pD)->Get(); - - switch (pAction->nKind) - { - case 0: - { - pDest->SetXYZ(pAction->dD[0] + dPageDX, dPageDH - pAction->dD[1], pAction->dD[2]); - break; - } - case 1: - { - pDest->SetFit(); - break; - } - case 2: - { - pDest->SetFitH(dPageDH - pAction->dD[1]); - break; - } - case 3: - { - pDest->SetFitV(pAction->dD[0] + dPageDX); - break; - } - case 4: - { - pDest->SetFitR(pAction->dD[0] + dPageDX, dPageDH - pAction->dD[1], pAction->dD[2] + dPageDX, dPageDH - pAction->dD[3]); - break; - } - case 5: - { - pDest->SetFitB(); - break; - } - case 6: - { - pDest->SetFitBH(dPageDH - pAction->dD[1]); - break; - } - case 7: - { - pDest->SetFitBV(pAction->dD[0] + dPageDX); - break; - } - } - break; - } - case 6: - { - PdfWriter::CActionURI* ppA = (PdfWriter::CActionURI*)pA; - ppA->SetURI(pAction->wsStr1); - break; - } - case 9: - { - PdfWriter::CActionHide* ppA = (PdfWriter::CActionHide*)pA; - ppA->SetH(pAction->nKind); - ppA->SetT(pAction->arrStr); - break; - } - case 10: - { - PdfWriter::CActionNamed* ppA = (PdfWriter::CActionNamed*)pA; - ppA->SetN(pAction->wsStr1); - break; - } - case 12: - { - PdfWriter::CActionResetForm* ppA = (PdfWriter::CActionResetForm*)pA; - ppA->SetFlags(pAction->nInt1); - ppA->SetFields(pAction->arrStr); - break; - } - case 14: - { - PdfWriter::CActionJavaScript* ppA = (PdfWriter::CActionJavaScript*)pA; - ppA->SetJS(pAction->wsStr1); - break; - } - } + PdfWriter::CAction* pA = GetAction(m_pDocument, pAction); pWidgetAnnot->AddAction(pA); } @@ -2365,42 +2350,22 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF CAnnotFieldInfo::CWidgetAnnotPr::CButtonWidgetPr* pPrB = oInfo.GetWidgetAnnotPr()->GetButtonWidgetPr(); PdfWriter::CCheckBoxWidget* pButtonWidget = (PdfWriter::CCheckBoxWidget*)pAnnot; - std::wstring wsValue; if (nFlags & (1 << 14)) pButtonWidget->SetAP_N_Yes(pPrB->GetAP_N_Yes()); - if (nFlags & (1 << 9)) - { - wsValue = pPrB->GetV(); - pButtonWidget->SetV(wsValue); - } - std::wstring wsStyleValue = pButtonWidget->SetStyle(pPrB->GetStyle()); + pButtonWidget->SetStyle(pPrB->GetStyle()); // ВНЕШНИЙ ВИД - // Если изменился текущий внешний вид - if (pButtonWidget->Get("AP")) + if (!pButtonWidget->Get("AP")) + pButtonWidget->SetAP(); + + if (nFlags & (1 << 9)) { - if (!wsValue.empty()) - pButtonWidget->SwitchAP(U_TO_UTF8(wsValue)); - return S_OK; - } - - put_FontName(wsFontName); - put_FontStyle(nStyle); - put_FontSize(dFontSize); - - if (m_bNeedUpdateTextFont) - UpdateFont(); - if (m_pFont) - pFontTT = m_pDocument->CreateTrueTypeFont(m_pFont); - pWidgetAnnot->SetDA(pFontTT, pPr->GetFontSize(), dFontSize, pPr->GetTC()); - - pButtonWidget->SetFont(m_pFont, dFontSize, isBold, isItalic); - if (!wsStyleValue.empty()) - { - double dMargin = 2; - double dBaseLine = dY2 - dY1 - dFontSize - dMargin; - pButtonWidget->SetAP(wsStyleValue, NULL, 0, 0, dBaseLine, NULL, NULL); + std::wstring sValue = pPrB->GetV(); + if (sValue != L"Off") + pButtonWidget->Yes(); + else + pButtonWidget->Off(); } } } @@ -2419,7 +2384,7 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF } if (nFlags & (1 << 10)) pTextWidget->SetMaxLen(pPr->GetMaxLen()); - if (nWidgetFlag & (1 << 25)) + if (nFlags & (1 << 11)) pTextWidget->SetRV(pPr->GetRV()); bool bAPValue = false; if (nFlags & (1 << 12)) @@ -2551,6 +2516,7 @@ void CPdfWriter::SetHeadings(CHeadings* pCommand) CreateOutlines(m_pDocument, pCommand->GetHeading(), NULL); } +void CPdfWriter::SetNeedAddHelvetica(bool bNeedAddHelvetica) { m_bNeedAddHelvetica = bNeedAddHelvetica; } //---------------------------------------------------------------------------------------- // Дополнительные функции Pdf рендерера //---------------------------------------------------------------------------------------- @@ -2620,59 +2586,23 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi CWidgetsInfo::CParent* pParent = arrParents[j]; PdfWriter::CDictObject* pParentObj = m_pDocument->GetParent(pParent->nID); if (!pParentObj) - continue; + pParentObj = m_pDocument->CreateParent(pParent->nID); std::vector arrValue; int nFlags = pParent->nFlags; // Adobe не может смешивать юникод и utf имена полей - // if (nFlags & (1 << 0)) - // pParentObj->Add("T", new PdfWriter::CStringObject((U_TO_UTF8(pParent->sName)).c_str(), true)); - if (nFlags & (1 << 1)) + if (nFlags & (1 << 0)) + pParentObj->Add("T", new PdfWriter::CStringObject((U_TO_UTF8(pParent->sName)).c_str())); + + std::string sFT = m_pDocument->SetParentKids(pParent->nID); + PdfWriter::CArrayObject* pKids = dynamic_cast(pParentObj->Get("Kids")); + if (!pKids) { - std::string sV = U_TO_UTF8(pParent->sV); - bool bName = !sV.empty() && (iswdigit(pParent->sV[0]) || sV == "Off"); - - PdfWriter::CObjectBase* pKids = pParentObj->Get("Kids"); - if (pKids && pKids->GetType() == PdfWriter::object_type_ARRAY) - { - PdfWriter::CArrayObject* pAKids = (PdfWriter::CArrayObject*)pKids; - for (int i = 0; i < pAKids->GetCount(); ++i) - { - PdfWriter::CObjectBase* pObj = pAKids->Get(i); - if (pObj->GetType() != PdfWriter::object_type_DICT || - ((PdfWriter::CDictObject*)pObj)->GetDictType() != PdfWriter::dict_type_ANNOTATION || - ((PdfWriter::CAnnotation*)pObj)->GetAnnotationType() != PdfWriter::AnnotWidget) - continue; - PdfWriter::EWidgetType nType = ((PdfWriter::CWidgetAnnotation*)pObj)->GetWidgetType(); - if (nType == PdfWriter::WidgetCheckbox || nType == PdfWriter::WidgetRadiobutton) - { - PdfWriter::CCheckBoxWidget* pKid = dynamic_cast(pObj); - if (pKid) - pKid->SwitchAP(sV); - } - if (nType == PdfWriter::WidgetCombobox || nType == PdfWriter::WidgetListbox) - { - PdfWriter::CChoiceWidget* pKid = dynamic_cast(pObj); - if (!pKid->HaveAPV()) - DrawChoiceWidget(pAppFonts, pKid, {pParent->sV}); - bName = false; - } - if (nType == PdfWriter::WidgetText) - { - PdfWriter::CTextWidget* pKid = dynamic_cast(pObj); - if (!pKid->HaveAPV()) - DrawTextWidget(pAppFonts, pKid, pParent->sV); - bName = false; - } - } - } - - if (bName) - pParentObj->Add("V", sV.c_str()); - else - pParentObj->Add("V", new PdfWriter::CStringObject(sV.c_str(), true)); + pKids = new PdfWriter::CArrayObject(); + pParentObj->Add("Kids", pKids); } + if (nFlags & (1 << 2)) pParentObj->Add("DV", new PdfWriter::CStringObject((U_TO_UTF8(pParent->sDV)).c_str(), true)); if (nFlags & (1 << 3)) @@ -2687,6 +2617,8 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi if (nFlags & (1 << 4)) { PdfWriter::CDictObject* pParentObj2 = m_pDocument->GetParent(pParent->nParentID); + if (!pParentObj2) + pParentObj2 = m_pDocument->CreateParent(pParent->nParentID); if (pParentObj2) pParentObj->Add("Parent", pParentObj2); } @@ -2696,13 +2628,138 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi pParentObj->Add("V", pArray); for (int i = 0; i < pParent->arrV.size(); ++i) pArray->Add(new PdfWriter::CStringObject(U_TO_UTF8(pParent->arrV[i]).c_str(), true)); - PdfWriter::CObjectBase* pKids = pParentObj->Get("Kids"); - if (pKids && pKids->GetType() == PdfWriter::object_type_ARRAY) + + for (int i = 0; i < pKids->GetCount(); ++i) { - PdfWriter::CArrayObject* pAKids = (PdfWriter::CArrayObject*)pKids; - for (int i = 0; i < pAKids->GetCount(); ++i) + PdfWriter::CObjectBase* pObj = pKids->Get(i); + if (pObj->GetType() != PdfWriter::object_type_DICT || + ((PdfWriter::CDictObject*)pObj)->GetDictType() != PdfWriter::dict_type_ANNOTATION || + ((PdfWriter::CAnnotation*)pObj)->GetAnnotationType() != PdfWriter::AnnotWidget) + continue; + PdfWriter::EWidgetType nType = ((PdfWriter::CWidgetAnnotation*)pObj)->GetWidgetType(); + if (nType == PdfWriter::WidgetCombobox || nType == PdfWriter::WidgetListbox) { - PdfWriter::CObjectBase* pObj = pAKids->Get(i); + PdfWriter::CChoiceWidget* pKid = dynamic_cast(pObj); + if (!pKid->HaveAPV()) + DrawChoiceWidget(pAppFonts, pKid, pParent->arrV); + } + } + } + std::map mNameAP_N_Yes; + if (nFlags & (1 << 6)) + { + PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject(); + pParentObj->Add("Opt", pArray); + + for (int i = 0; i < pParent->arrOpt.size(); ++i) + { + std::pair PV = pParent->arrOpt[i]; + std::string sValue; + if (PV.first.empty()) + { + sValue = U_TO_UTF8(PV.second); + pArray->Add(new PdfWriter::CStringObject(sValue.c_str(), true)); + + if (mNameAP_N_Yes.find(PV.second) == mNameAP_N_Yes.end()) + mNameAP_N_Yes[PV.second] = std::to_wstring(i); + } + else + { + PdfWriter::CArrayObject* pArray2 = new PdfWriter::CArrayObject(); + pArray->Add(pArray2); + + sValue = U_TO_UTF8(PV.first); + pArray2->Add(new PdfWriter::CStringObject(sValue.c_str(), true)); + + if (mNameAP_N_Yes.find(PV.first) == mNameAP_N_Yes.end()) + mNameAP_N_Yes[PV.first] = std::to_wstring(i); + + sValue = U_TO_UTF8(PV.second); + pArray2->Add(new PdfWriter::CStringObject(sValue.c_str(), true)); + } + } + } + if (nFlags & (1 << 1)) + { + std::string sV = U_TO_UTF8(pParent->sV); + if (sFT == "Btn") + { + int nFf = 0; + if (nFlags & (1 << 7)) + nFf = pParent->nFieldFlag; + bool bRadiosInUnison = (bool)(nFf & (1 << 25)); + int nOptIndex = -1; + if (isdigit(sV[0])) + nOptIndex = std::stoi(sV); + + if (!pParent->arrOpt.empty() && nOptIndex >= 0 && nOptIndex < pParent->arrOpt.size()) + { + std::pair PV = pParent->arrOpt[nOptIndex]; + std::wstring sOpt = PV.first.empty() ? PV.second : PV.first; + + for (int i = 0; i < pParent->arrOpt.size(); ++i) + { + if (i >= pKids->GetCount()) + break; + PdfWriter::CObjectBase* pObj = pKids->Get(i); + if (pObj->GetType() != PdfWriter::object_type_DICT || + ((PdfWriter::CDictObject*)pObj)->GetDictType() != PdfWriter::dict_type_ANNOTATION || + ((PdfWriter::CAnnotation*)pObj)->GetAnnotationType() != PdfWriter::AnnotWidget) + continue; + PdfWriter::EWidgetType nType = ((PdfWriter::CWidgetAnnotation*)pObj)->GetWidgetType(); + if (nType != PdfWriter::WidgetCheckbox && nType != PdfWriter::WidgetRadiobutton) + continue; + PdfWriter::CCheckBoxWidget* pKid = dynamic_cast(pObj); + if (!pKid) + continue; + + PV = pParent->arrOpt[i]; + std::wstring sOptI = PV.first.empty() ? PV.second : PV.first; + if (pKid->NeedAP_N_Yes()) + pKid->SetAP_N_Yes((bRadiosInUnison || nType == PdfWriter::WidgetCheckbox) ? mNameAP_N_Yes[sOptI] : std::to_wstring(i)); + + if (((bRadiosInUnison || nType == PdfWriter::WidgetCheckbox) && sOptI == sOpt) || (!bRadiosInUnison && i == nOptIndex)) + sV = pKid->Yes(); + else + pKid->Off(); + } + } + else + { + for (int i = 0; i < pKids->GetCount(); ++i) + { + PdfWriter::CObjectBase* pObj = pKids->Get(i); + if (pObj->GetType() != PdfWriter::object_type_DICT || + ((PdfWriter::CDictObject*)pObj)->GetDictType() != PdfWriter::dict_type_ANNOTATION || + ((PdfWriter::CAnnotation*)pObj)->GetAnnotationType() != PdfWriter::AnnotWidget) + continue; + PdfWriter::EWidgetType nType = ((PdfWriter::CWidgetAnnotation*)pObj)->GetWidgetType(); + if (nType != PdfWriter::WidgetCheckbox && nType != PdfWriter::WidgetRadiobutton) + continue; + PdfWriter::CCheckBoxWidget* pKid = dynamic_cast(pObj); + if (!pKid) + continue; + if (pKid->NeedAP_N_Yes()) + { + std::pair PV = pParent->arrOpt[i]; + std::wstring sOpt = PV.first.empty() ? PV.second : PV.first; + pKid->SetAP_N_Yes(mNameAP_N_Yes[sOpt]); + } + + if (pKid->GetAP_N_Yes() == sV) + sV = pKid->Yes(); + else + pKid->Off(); + } + } + + pParentObj->Add("V", sV.c_str()); + } + else + { + for (int i = 0; i < pKids->GetCount(); ++i) + { + PdfWriter::CObjectBase* pObj = pKids->Get(i); if (pObj->GetType() != PdfWriter::object_type_DICT || ((PdfWriter::CDictObject*)pObj)->GetDictType() != PdfWriter::dict_type_ANNOTATION || ((PdfWriter::CAnnotation*)pObj)->GetAnnotationType() != PdfWriter::AnnotWidget) @@ -2712,11 +2769,45 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi { PdfWriter::CChoiceWidget* pKid = dynamic_cast(pObj); if (!pKid->HaveAPV()) - DrawChoiceWidget(pAppFonts, pKid, pParent->arrV); + DrawChoiceWidget(pAppFonts, pKid, {pParent->sV}); } + else if (nType == PdfWriter::WidgetText) + { + PdfWriter::CTextWidget* pKid = dynamic_cast(pObj); + if (!pKid->HaveAPV()) + DrawTextWidget(pAppFonts, pKid, pParent->sV); + } + } + pParentObj->Add("V", new PdfWriter::CStringObject(sV.c_str(), true)); + } + } + if (nFlags & (1 << 7)) + pParentObj->Add("Ff", pParent->nFieldFlag); + if (nFlags & (1 << 8)) + { + const std::vector arrActions = pParent->arrAction; + for (CAnnotFieldInfo::CWidgetAnnotPr::CActionWidget* pAction : arrActions) + { + PdfWriter::CAction* pA = GetAction(m_pDocument, pAction); + if (!pA) + continue; + + if (pA->m_sType == "A") + pParentObj->Add(pA->m_sType.c_str(), pA); + else + { + PdfWriter::CDictObject* pAA = (PdfWriter::CDictObject*)pParentObj->Get("AA"); + if (!pAA) + { + pAA = new PdfWriter::CDictObject(); + pParentObj->Add("AA", pAA); + } + pAA->Add(pA->m_sType.c_str(), pA); } } } + if (nFlags & (1 << 9)) + pParentObj->Add("MaxLen", pParent->nMaxLen); } std::vector arrBI = pFieldInfo->GetButtonImg(); @@ -2739,14 +2830,15 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi arrForm.push_back(m_pDocument->CreateForm(pImage, std::to_string(i))); } - if (arrForm.empty()) - return S_OK; - std::map mAnnots = m_pDocument->GetAnnots(); for (auto it = mAnnots.begin(); it != mAnnots.end(); it++) { PdfWriter::CAnnotation* pAnnot = it->second; - if (pAnnot->GetAnnotationType() != PdfWriter::AnnotWidget || ((PdfWriter::CWidgetAnnotation*)pAnnot)->GetWidgetType() != PdfWriter::WidgetPushbutton) + if (pAnnot->GetAnnotationType() != PdfWriter::AnnotWidget) + continue; + + PdfWriter::CWidgetAnnotation* pWidget = (PdfWriter::CWidgetAnnotation*)pAnnot; + if (pWidget->GetWidgetType() != PdfWriter::WidgetPushbutton) continue; PdfWriter::CPushButtonWidget* pPBWidget = (PdfWriter::CPushButtonWidget*)pAnnot; @@ -2778,16 +2870,42 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi } } + std::map mParents = m_pDocument->GetParents(); + for (auto it = mParents.begin(); it != mParents.end(); it++) + { + PdfWriter::CDictObject* pP = it->second; + PdfWriter::CObjectBase* pParentOfParent = pP->Get("Parent"); + if (!pParentOfParent || pParentOfParent->GetType() != PdfWriter::object_type_DICT) + continue; + + PdfWriter::CDictObject* pParent = (PdfWriter::CDictObject*)pParentOfParent; + PdfWriter::CArrayObject* pKids = dynamic_cast(pParent->Get("Kids")); + if (!pKids) + { + pKids = new PdfWriter::CArrayObject(); + pParent->Add("Kids", pKids); + } + + bool bReplase = false; + int nID = pP->GetObjId(); + for (int i = 0; i < pKids->GetCount(); ++i) + { + PdfWriter::CObjectBase* pKid = pKids->Get(i); + if (pKid->GetObjId() == nID) + { + pKids->Insert(pKid, pP, true); + bReplase = true; + break; + } + } + if (!bReplase) + pKids->Add(pP); + } + return S_OK; } -PdfWriter::CDocument* CPdfWriter::GetDocument() -{ - return m_pDocument; -} -PdfWriter::CPage* CPdfWriter::GetPage() -{ - return m_pPage; -} +PdfWriter::CDocument* CPdfWriter::GetDocument() { return m_pDocument; } +PdfWriter::CPage* CPdfWriter::GetPage() { return m_pPage; } bool CPdfWriter::EditPage(PdfWriter::CPage* pNewPage) { if (!IsValid()) @@ -3665,7 +3783,7 @@ std::wstring CPdfWriter::GetDownloadFile(const std::wstring& sUrl, const std::ws if (!bIsNeedDownload) return L""; - +#ifndef BUILDING_WASM_MODULE std::wstring sTempFile = GetTempFile(wsTempDirectory); NSNetwork::NSFileTransport::CFileDownloader oDownloader(sUrl, false); oDownloader.SetFilePath(sTempFile); @@ -3675,7 +3793,7 @@ std::wstring CPdfWriter::GetDownloadFile(const std::wstring& sUrl, const std::ws if (NSFile::CFileBinary::Exists(sTempFile)) NSFile::CFileBinary::Remove(sTempFile); - +#endif return L""; } PdfWriter::CAnnotAppearanceObject* CPdfWriter::DrawAP(PdfWriter::CAnnotation* pAnnot, BYTE* pRender, LONG nLenRender) @@ -3684,7 +3802,7 @@ PdfWriter::CAnnotAppearanceObject* CPdfWriter::DrawAP(PdfWriter::CAnnotation* pA return NULL; PdfWriter::CPage* pCurPage = m_pPage; - PdfWriter::CPage* pFakePage = m_pDocument->CreateFakePage(); + PdfWriter::CPage* pFakePage = new PdfWriter::CPage(m_pDocument); m_pPage = pFakePage; m_pDocument->SetCurPage(pFakePage); m_pPage->StartTransform(1, 0, 0, 1, -pAnnot->GetPageX(), 0); @@ -3714,7 +3832,7 @@ void CPdfWriter::DrawWidgetAP(PdfWriter::CAnnotation* pA, BYTE* pRender, LONG nL PdfWriter::CWidgetAnnotation* pAnnot = (PdfWriter::CWidgetAnnotation*)pA; PdfWriter::CPage* pCurPage = m_pPage; - PdfWriter::CPage* pFakePage = m_pDocument->CreateFakePage(); + PdfWriter::CPage* pFakePage = new PdfWriter::CPage(m_pDocument); m_pPage = pFakePage; m_pDocument->SetCurPage(pFakePage); m_oTransform.Set(1, 0, 0, 1, PT_2_MM(-pAnnot->GetPageX() - pAnnot->GetRect().fLeft), PT_2_MM(pAnnot->GetRect().fBottom)); @@ -3761,8 +3879,8 @@ void CPdfWriter::DrawTextWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWriter if (!pTextWidget->HaveBorder() && pTextWidget->HaveBC()) pTextWidget->SetBorder(0, 1, {}); double dShiftBorder = pTextWidget->GetBorderWidth(); - BYTE nType = pTextWidget->GetBorderType(); - if (nType == 1 || nType == 3) + PdfWriter::EBorderType nType = pTextWidget->GetBorderType(); + if (nType == PdfWriter::EBorderType::Beveled || nType == PdfWriter::EBorderType::Inset) dShiftBorder *= 2; // Коды, шрифты, количество @@ -3923,8 +4041,8 @@ void CPdfWriter::DrawChoiceWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWrit if (!pChoiceWidget->HaveBorder() && pChoiceWidget->HaveBC()) pChoiceWidget->SetBorder(0, 1, {}); double dShiftBorder = pChoiceWidget->GetBorderWidth(); - BYTE nType = pChoiceWidget->GetBorderType(); - if (nType == 1 || nType == 3) + PdfWriter::EBorderType nType = pChoiceWidget->GetBorderType(); + if (nType == PdfWriter::EBorderType::Beveled || nType == PdfWriter::EBorderType::Inset) dShiftBorder *= 2; if (arrValue.empty()) @@ -4099,8 +4217,8 @@ void CPdfWriter::DrawButtonWidget(NSFonts::IApplicationFonts* pAppFonts, PdfWrit double dHeight = pButtonWidget->GetHeight(); double dShiftBorder = pButtonWidget->GetBorderWidth(); - BYTE nType = pButtonWidget->GetBorderType(); - if (nType == 1 || nType == 3) + PdfWriter::EBorderType nType = pButtonWidget->GetBorderType(); + if (nType == PdfWriter::EBorderType::Beveled || nType == PdfWriter::EBorderType::Inset) dShiftBorder *= 2; if (dShiftBorder == 0) dShiftBorder = 1; diff --git a/PdfFile/PdfWriter.h b/PdfFile/PdfWriter.h index 38fa7fc70f..98f4ba015a 100644 --- a/PdfFile/PdfWriter.h +++ b/PdfFile/PdfWriter.h @@ -67,6 +67,7 @@ public: CPdfWriter(NSFonts::IApplicationFonts* pAppFonts, bool isPDFA = false, IRenderer* pRenderer = NULL, bool bCreate = true); ~CPdfWriter(); int SaveToFile(const std::wstring& wsPath); + int SaveToMemory(BYTE** pData, int* pLength); void SetPassword(const std::wstring& wsPassword); void SetDocumentID(const std::wstring& wsDocumentID); void SetDocumentInfo(const std::wstring& wsTitle, const std::wstring& wsCreator, const std::wstring& wsSubject, const std::wstring& wsKeywords); @@ -209,16 +210,17 @@ public: //---------------------------------------------------------------------------------------- // Дополнительные функции для дозаписи Pdf //---------------------------------------------------------------------------------------- + HRESULT EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWidgetsInfo* pFieldInfo, const std::wstring& wsTempDirectory); bool EditPage(PdfWriter::CPage* pNewPage); bool AddPage(int nPageIndex); bool EditClose(); void PageRotate(int nRotate); void Sign(const double& dX, const double& dY, const double& dW, const double& dH, const std::wstring& wsPicturePath, ICertificate* pCertificate); - HRESULT EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWidgetsInfo* pFieldInfo, const std::wstring& wsTempDirectory); PdfWriter::CDocument* GetDocument(); PdfWriter::CPage* GetPage(); void AddFont(const std::wstring& wsFontName, const bool& bBold, const bool& bItalic, const std::wstring& wsFontPath, const LONG& lFaceIndex); void SetHeadings(CHeadings* pCommand); + void SetNeedAddHelvetica(bool bNeedAddHelvetica); private: PdfWriter::CImageDict* LoadImage(Aggplus::CImage* pImage, BYTE nAlpha); @@ -269,6 +271,7 @@ private: CPath m_oPath; CTransform m_oTransform; bool m_bNeedUpdateTextFont; + bool m_bNeedAddHelvetica; double m_dPageHeight; double m_dPageWidth; LONG m_lClipDepth; diff --git a/PdfFile/SrcReader/Adaptors.cpp b/PdfFile/SrcReader/Adaptors.cpp index 62ac8e8001..58d2cf6264 100644 --- a/PdfFile/SrcReader/Adaptors.cpp +++ b/PdfFile/SrcReader/Adaptors.cpp @@ -34,10 +34,6 @@ #include "../lib/xpdf/TextString.h" #include "../../DesktopEditor/graphics/pro/js/wasm/src/serialize.h" -void GlobalParamsAdaptor::SetFontManager(NSFonts::IFontManager *pFontManager) -{ - m_pFontManager = pFontManager; -} void GlobalParamsAdaptor::SetCMapFolder(const std::wstring &wsFolder) { m_wsCMapFolder = wsFolder; @@ -185,14 +181,6 @@ bool GlobalParamsAdaptor::GetCMap(const char* sName, char*& pData, unsigned int& return false; } -void GlobalParamsAdaptor::AddTextFormField(const std::wstring& sText) -{ - m_sTextFormField += sText; -} -std::string GlobalParamsAdaptor::GetTextFormField() -{ - return U_TO_UTF8(m_sTextFormField); -} bool operator==(const Ref &a, const Ref &b) { diff --git a/PdfFile/SrcReader/Adaptors.h b/PdfFile/SrcReader/Adaptors.h index ca27ed5f15..fc61d913fa 100644 --- a/PdfFile/SrcReader/Adaptors.h +++ b/PdfFile/SrcReader/Adaptors.h @@ -59,11 +59,9 @@ class GlobalParamsAdaptor : public GlobalParams BYTE* m_bCMapData; DWORD m_nCMapDataLength; - std::wstring m_sTextFormField; bool m_bDrawFormField; public: - NSFonts::IFontManager *m_pFontManager; GlobalParamsAdaptor(const char *filename) : GlobalParams(filename) { m_bCMapData = NULL; @@ -86,14 +84,13 @@ public: m_wsTempFolder = folder; } + bool IsNeedCMap() { return !m_bCMapData; } void SetCMapFolder(const std::wstring &wsFolder); void SetCMapFile(const std::wstring &wsFile); void SetCMapMemory(BYTE* pData, DWORD nSizeData); bool GetCMap(const char* sName, char*& pData, unsigned int& nSize); - void AddTextFormField(const std::wstring& sText); - std::string GetTextFormField(); - void setDrawFormField(bool bDrawFormField) { m_bDrawFormField = bDrawFormField; } + void setDrawFormField(bool bDrawFormField) { m_bDrawFormField = bDrawFormField; } bool getDrawFormField() { return m_bDrawFormField; } private: diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 5a5e5ecf8f..33e6b6889d 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -63,7 +63,7 @@ double ArrGetNum(Object* pArr, int nI) oObj.free(); return dRes; } -TextString* getName(Object* oField) +TextString* getFullFieldName(Object* oField) { TextString* sResName = NULL; @@ -262,7 +262,7 @@ CAction* getAction(PDFDoc* pdfDoc, Object* oAction) if (oHide.isString()) s = new TextString(oHide.getString()); else if (oHide.isDict()) - s = getName(&oHide); + s = getFullFieldName(&oHide); if (s) { @@ -298,7 +298,7 @@ CAction* getAction(PDFDoc* pdfDoc, Object* oAction) if (oField.isString()) s = new TextString(oField.getString()); else if (oField.isDict()) - s = getName(&oField); + s = getFullFieldName(&oField); if (s) { @@ -317,9 +317,7 @@ CAction* getAction(PDFDoc* pdfDoc, Object* oAction) } if (pRes) - { pRes->pNext = NULL; - } Object oNextAction; if (pRes && oAction->dictLookup("Next", &oNextAction)->isDict()) @@ -343,18 +341,14 @@ std::string getValue(Object* oV, bool bArray = true) { Object oContents; if (oV->dictLookup("Contents", &oContents)->isString()) - { s = new TextString(oContents.getString()); - } oContents.free(); } else if (bArray && oV->isArray()) { Object oContents; if (oV->arrayGet(0, &oContents)->isString()) - { s = new TextString(oContents.getString()); - } oContents.free(); } if (s) @@ -428,12 +422,12 @@ CAnnotFileAttachment::CEmbeddedFile* getEF(Object* oObj) pRes->nLength = oObj2.getInt(); oObj2.free(); - Stream* pImage = oObj->getStream(); - pImage->reset(); + Stream* pFile = oObj->getStream(); + pFile->reset(); pRes->pFile = new BYTE[pRes->nLength]; BYTE* pBufferPtr = pRes->pFile; for (int nI = 0; nI < pRes->nLength; ++nI) - *pBufferPtr++ = (BYTE)pImage->getChar(); + *pBufferPtr++ = (BYTE)pFile->getChar(); return pRes; } @@ -1060,7 +1054,7 @@ std::map CAnnotFonts::GetFreeTextFont(PDFDoc* pdfDoc // Widget //------------------------------------------------------------------------ -CAnnotWidgetBtn::CAnnotWidgetBtn(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnotWidget(pdfDoc, pField) +CAnnotWidgetBtn::CAnnotWidgetBtn(PDFDoc* pdfDoc, AcroFormField* pField, int nStartRefID) : CAnnotWidget(pdfDoc, pField, nStartRefID) { m_unIFFlag = 0; @@ -1180,7 +1174,7 @@ CAnnotWidgetBtn::CAnnotWidgetBtn(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot // 14 - Имя вкл состояния - AP - N - Yes Object oNorm; - if (pField->fieldLookup("AP", &oObj)->isDict() && oObj.dictLookup("N", &oNorm)->isDict()) + if (pField->fieldLookup("AP", &oObj)->isDict() && oObj.dictLookup("N", &oNorm)->isDict() && oOpt.isNull()) { for (int j = 0, nNormLength = oNorm.dictGetLength(); j < nNormLength; ++j) { @@ -1189,43 +1183,13 @@ CAnnotWidgetBtn::CAnnotWidgetBtn(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot { m_unFlags |= (1 << 14); m_sAP_N_Yes = sNormName; - - int nOptI; - if (oOpt.isArray() && isdigit(sNormName[0]) && (nOptI = std::stoi(sNormName)) >= 0 && nOptI < oOpt.arrayGetLength()) - { - Object oOptJ; - if (!oOpt.arrayGet(nOptI, &oOptJ) || !(oOptJ.isString() || oOptJ.isArray())) - { - oOptJ.free(); - break; - } - - if (oOptJ.isString()) - { - TextString* s = new TextString(oOptJ.getString()); - m_sAP_N_Yes = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); - delete s; - } - else if (oOptJ.isArray() && oOptJ.arrayGetLength() > 0) - { - Object oOptJ2; - if (oOptJ.arrayGet(0, &oOptJ2)->isString()) - { - TextString* s = new TextString(oOptJ2.getString()); - m_sAP_N_Yes = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); - delete s; - } - oOptJ2.free(); - } - oOptJ.free(); - } break; } } } oNorm.free(); oObj.free(); oOpt.free(); } -CAnnotWidgetTx::CAnnotWidgetTx(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnotWidget(pdfDoc, pField) +CAnnotWidgetTx::CAnnotWidgetTx(PDFDoc* pdfDoc, AcroFormField* pField, int nStartRefID) : CAnnotWidget(pdfDoc, pField, nStartRefID) { Object oObj; Object oFieldRef, oField; @@ -1244,18 +1208,18 @@ CAnnotWidgetTx::CAnnotWidgetTx(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnotWi oField.free(); // 10 - Максимальное количество символов в Tx - MaxLen - int nMaxLen = pField->getMaxLen(); - if (nMaxLen > 0) + if (oField.dictLookup("MaxLen", &oObj)->isInt()) { m_unFlags |= (1 << 10); - m_unMaxLen = nMaxLen; + m_unMaxLen = oObj.getInt(); } + oObj.free(); // 11 - Расширенный текст RV - RichText if (pField->getFlags() & (1 << 25)) m_sRV = FieldLookupString(pField, "RV", 11); } -CAnnotWidgetCh::CAnnotWidgetCh(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnotWidget(pdfDoc, pField) +CAnnotWidgetCh::CAnnotWidgetCh(PDFDoc* pdfDoc, AcroFormField* pField, int nStartRefID) : CAnnotWidget(pdfDoc, pField, nStartRefID) { Object oObj; Object oFieldRef, oField; @@ -1330,8 +1294,7 @@ CAnnotWidgetCh::CAnnotWidgetCh(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnotWi if (oField.dictLookup("I", &oOpt)->isArray()) { m_unFlags |= (1 << 12); - int nILength = oOpt.arrayGetLength(); - for (int j = 0; j < nILength; ++j) + for (int j = 0; j < oOpt.arrayGetLength(); ++j) { if (oOpt.arrayGet(j, &oObj)->isInt()) m_arrI.push_back(oObj.getInt()); @@ -1360,7 +1323,7 @@ CAnnotWidgetCh::CAnnotWidgetCh(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnotWi oField.free(); } -CAnnotWidgetSig::CAnnotWidgetSig(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnotWidget(pdfDoc, pField) +CAnnotWidgetSig::CAnnotWidgetSig(PDFDoc* pdfDoc, AcroFormField* pField, int nStartRefID) : CAnnotWidget(pdfDoc, pField, nStartRefID) { Object oObj; Object oFieldRef, oField; @@ -1375,7 +1338,7 @@ CAnnotWidgetSig::CAnnotWidgetSig(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot oField.free(); } -CAnnotWidget::CAnnotWidget(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot(pdfDoc, pField) +CAnnotWidget::CAnnotWidget(PDFDoc* pdfDoc, AcroFormField* pField, int nStartRefID) : CAnnot(pdfDoc, pField, nStartRefID) { Object oObj, oField; XRef* xref = pdfDoc->getXRef(); @@ -1418,7 +1381,10 @@ CAnnotWidget::CAnnotWidget(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot(pdfDo } // Флаг - Ff - m_unFieldFlag = pField->getFlags(); + m_unFieldFlag = -1; + if (oField.dictLookup("Ff", &oObj)->isInt()) + m_unFieldFlag = oObj.getInt(); + oObj.free(); // 0 - Альтернативное имя поля, используется во всплывающей подсказке и сообщениях об ошибке - TU m_sTU = FieldLookupString(pField, "TU", 0); @@ -1492,22 +1458,24 @@ CAnnotWidget::CAnnotWidget(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot(pdfDo oObj.free(); // 17 - Родитель - Parent + m_unRefNumParent = 0; if (oField.dictLookupNF("Parent", &oObj)->isRef()) { - m_unRefNumParent = oObj.getRefNum(); + m_unRefNumParent = oObj.getRefNum() + nStartRefID; m_unFlags |= (1 << 17); } oObj.free(); // 18 - Частичное имя поля - T m_sT = DictLookupString(&oField, "T", 18); + m_sFullName = m_sT; // 20 - OO метаданные форм - OMetadata m_sOMetadata = DictLookupString(&oField, "OMetadata", 20); // Action - A Object oAction; - if (pField->fieldLookup("A", &oAction)->isDict()) + if (oField.dictLookup("A", &oAction)->isDict()) { std::string sAA = "A"; CAction* pA = getAction(pdfDoc, &oAction); @@ -1521,11 +1489,6 @@ CAnnotWidget::CAnnotWidget(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot(pdfDo // Actions - AA Object oAA; - Object parent, parent2; - bool bParent = oField.dictLookup("Parent", &parent)->isDict(); - bool bAA = bParent && parent.dictLookup("AA", &oAA)->isDict(); - oAA.free(); - if (oField.dictLookup("AA", &oAA)->isDict()) { for (int j = 0; j < oAA.dictGetLength(); ++j) @@ -1533,8 +1496,6 @@ CAnnotWidget::CAnnotWidget(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot(pdfDo if (oAA.dictGetVal(j, &oAction)->isDict()) { std::string sAA(oAA.dictGetKey(j)); - if (bAA && (sAA == "K" || sAA == "F" || sAA == "V" || sAA == "C")) - continue; CAction* pA = getAction(pdfDoc, &oAction); if (pA) { @@ -1547,45 +1508,11 @@ CAnnotWidget::CAnnotWidget(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot(pdfDo } oAA.free(); - if (bParent) - { - int depth = 0; - while (parent.isDict() && depth < 50) - { - if (parent.dictLookup("AA", &oAA)->isDict()) - { - for (int j = 0; j < oAA.dictGetLength(); ++j) - { - if (oAA.dictGetVal(j, &oAction)->isDict()) - { - std::string sAA(oAA.dictGetKey(j)); - if (sAA == "E" || sAA == "X" || sAA == "D" || sAA == "U" || sAA == "Fo" || sAA == "Bl" || sAA == "PO" || sAA == "PC" || sAA == "PV" || sAA == "PI") - continue; - CAction* pA = getAction(pdfDoc, &oAction); - if (pA) - { - pA->sType = sAA; - m_arrAction.push_back(pA); - } - } - oAction.free(); - } - } - oAA.free(); - parent.dictLookup("Parent", &parent2); - parent.free(); - parent = parent2; - ++depth; - } - } - parent.free(); - oField.free(); } CAnnotWidget::~CAnnotWidget() { - for (int i = 0; i < m_arrAction.size(); ++i) - RELEASEOBJECT(m_arrAction[i]); + ClearActions(); } std::string CAnnotWidget::FieldLookupString(AcroFormField* pField, const char* sName, int nByte) { @@ -1654,12 +1581,29 @@ void CAnnotWidget::SetButtonFont(PDFDoc* pdfDoc, AcroFormField* pField, NSFonts: oFontRef.free(); } +bool CAnnotWidget::ChangeFullName(const std::string& sPrefixForm) +{ + if (m_unFlags & (1 << 18)) + { + m_sT += sPrefixForm; + m_sFullName += sPrefixForm; + // ClearActions(); + return true; + } + return false; +} +void CAnnotWidget::ClearActions() +{ + for (int i = 0; i < m_arrAction.size(); ++i) + RELEASEOBJECT(m_arrAction[i]); + m_arrAction.clear(); +} //------------------------------------------------------------------------ // Popup //------------------------------------------------------------------------ -CAnnotPopup::CAnnotPopup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnot(pdfDoc, oAnnotRef, nPageIndex) +CAnnotPopup::CAnnotPopup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int nStartRefID) : CAnnot(pdfDoc, oAnnotRef, nPageIndex, nStartRefID) { m_unFlags = 0; @@ -1676,7 +1620,7 @@ CAnnotPopup::CAnnotPopup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CA if (oAnnot.dictLookupNF("Parent", &oObj)->isRef()) { m_unFlags |= (1 << 1); - m_unRefNumParent = oObj.getRefNum(); + m_unRefNumParent = oObj.getRefNum() + nStartRefID; } oObj.free(); oAnnot.free(); @@ -1686,7 +1630,7 @@ CAnnotPopup::CAnnotPopup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CA // Text //------------------------------------------------------------------------ -CAnnotText::CAnnotText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) +CAnnotText::CAnnotText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int nStartRefID) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex, nStartRefID) { Object oAnnot, oObj; XRef* pXref = pdfDoc->getXRef(); @@ -1752,7 +1696,7 @@ CAnnotText::CAnnotText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnn // Ink //------------------------------------------------------------------------ -CAnnotInk::CAnnotInk(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) +CAnnotInk::CAnnotInk(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int nStartRefID) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex, nStartRefID) { Object oAnnot, oObj, oObj2; XRef* pXref = pdfDoc->getXRef(); @@ -1788,7 +1732,7 @@ CAnnotInk::CAnnotInk(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnot // Line //------------------------------------------------------------------------ -CAnnotLine::CAnnotLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) +CAnnotLine::CAnnotLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int nStartRefID) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex, nStartRefID) { Object oAnnot, oObj, oObj2; XRef* pXref = pdfDoc->getXRef(); @@ -1896,7 +1840,7 @@ CAnnotLine::CAnnotLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnn // TextMarkup: Highlight, Underline, Squiggly, StrikeOut //------------------------------------------------------------------------ -CAnnotTextMarkup::CAnnotTextMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) +CAnnotTextMarkup::CAnnotTextMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int nStartRefID) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex, nStartRefID) { Object oAnnot, oObj, oObj2; XRef* pXref = pdfDoc->getXRef(); @@ -1936,7 +1880,7 @@ CAnnotTextMarkup::CAnnotTextMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageI // Square, Circle //------------------------------------------------------------------------ -CAnnotSquareCircle::CAnnotSquareCircle(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) +CAnnotSquareCircle::CAnnotSquareCircle(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int nStartRefID) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex, nStartRefID) { Object oAnnot, oObj, oObj2; XRef* pXref = pdfDoc->getXRef(); @@ -1983,7 +1927,7 @@ CAnnotSquareCircle::CAnnotSquareCircle(PDFDoc* pdfDoc, Object* oAnnotRef, int nP // Polygon, PolyLine //------------------------------------------------------------------------ -CAnnotPolygonLine::CAnnotPolygonLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) +CAnnotPolygonLine::CAnnotPolygonLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int nStartRefID) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex, nStartRefID) { Object oAnnot, oObj, oObj2; XRef* pXref = pdfDoc->getXRef(); @@ -2059,7 +2003,7 @@ CAnnotPolygonLine::CAnnotPolygonLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPag // FreeText //------------------------------------------------------------------------ -CAnnotFreeText::CAnnotFreeText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) +CAnnotFreeText::CAnnotFreeText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int nStartRefID) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex, nStartRefID) { Object oAnnot, oObj, oObj2; XRef* pXref = pdfDoc->getXRef(); @@ -2200,7 +2144,7 @@ CAnnotFreeText::CAnnotFreeText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex // Caret //------------------------------------------------------------------------ -CAnnotCaret::CAnnotCaret(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) +CAnnotCaret::CAnnotCaret(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int nStartRefID) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex, nStartRefID) { Object oAnnot, oObj, oObj2; XRef* pXref = pdfDoc->getXRef(); @@ -2236,7 +2180,7 @@ CAnnotCaret::CAnnotCaret(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CA // FileAttachment //------------------------------------------------------------------------ -CAnnotFileAttachment::CAnnotFileAttachment(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) +CAnnotFileAttachment::CAnnotFileAttachment(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int nStartRefID) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex, nStartRefID) { m_pEF = NULL; @@ -2333,21 +2277,16 @@ CAnnotFileAttachment::CAnnotFileAttachment(PDFDoc* pdfDoc, Object* oAnnotRef, in oEF.free(); // 25 - Встроенные файловые потоки - RF - Object oRF; - if (oFS.dictLookup("RF", &oRF)->isDict()) - { + if (oFS.dictLookup("RF", &oObj)->isDict()) m_unFlags |= (1 << 25); - } - oRF.free(); + oObj.free(); // 26 - Описание файла - Desc m_sDesc = DictLookupString(&oFS, "Desc", 26); // 27 - Коллекция - Cl if (oFS.dictLookup("Cl", &oObj)->isDict()) - { m_unFlags |= (1 << 27); - } oObj.free(); oFS.free(); oAnnot.free(); @@ -2361,7 +2300,7 @@ CAnnotFileAttachment::~CAnnotFileAttachment() // Stamp //------------------------------------------------------------------------ -CAnnotStamp::CAnnotStamp(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex) +CAnnotStamp::CAnnotStamp(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int nStartRefID) : CAnnotMarkup(pdfDoc, oAnnotRef, nPageIndex, nStartRefID) { Object oAnnot, oObj; XRef* pXref = pdfDoc->getXRef(); @@ -2369,9 +2308,7 @@ CAnnotStamp::CAnnotStamp(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CA // Иконка - Name if (oAnnot.dictLookup("Name", &oObj)->isName()) - { m_sName = oObj.getName(); - } oObj.free(); m_dRotate = 0; @@ -2394,8 +2331,8 @@ CAnnotStamp::CAnnotStamp(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CA oObj1.free(); } } - oObj.free(); + if (oObj2.streamGetDict()->lookup("Matrix", &oObj)->isArray() && oObj.arrayGetLength() == 6) { for (int i = 0; i < 6; ++i) @@ -2481,7 +2418,7 @@ CAnnotStamp::CAnnotStamp(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CA // Annots //------------------------------------------------------------------------ -CAnnots::CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList) +CAnnots::CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, int nStartPage, int nStartRefID) { Object oObj1, oObj2; XRef* xref = pdfDoc->getXRef(); @@ -2494,7 +2431,7 @@ CAnnots::CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontLi for (int j = 0; j < oObj1.arrayGetLength(); ++j) { if (oObj1.arrayGetNF(j, &oObj2)->isRef()) - m_arrCO.push_back(oObj2.getRefNum()); + m_arrCO.push_back(oObj2.getRefNum() + nStartRefID); oObj2.free(); } } @@ -2514,7 +2451,7 @@ CAnnots::CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontLi if (pField->getPageNum() < 1) { oField.free(); oFieldRef.free(); - std::vector::iterator it = std::find(m_arrCO.begin(), m_arrCO.end(), oFieldRef.getRefNum()); + std::vector::iterator it = std::find(m_arrCO.begin(), m_arrCO.end(), oFieldRef.getRefNum() + nStartRefID); if (it != m_arrCO.end()) m_arrCO.erase(it); continue; @@ -2523,7 +2460,7 @@ CAnnots::CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontLi // Родители Object oParentRefObj; if (oField.dictLookupNF("Parent", &oParentRefObj)->isRef()) - getParents(xref, &oParentRefObj); + getParents(pdfDoc, &oParentRefObj, nStartRefID); oParentRefObj.free(); oField.free(); oFieldRef.free(); @@ -2535,7 +2472,7 @@ CAnnots::CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontLi case acroFormFieldRadioButton: case acroFormFieldCheckbox: { - pAnnot = new CAnnotWidgetBtn(pdfDoc, pField); + pAnnot = new CAnnotWidgetBtn(pdfDoc, pField, nStartRefID); break; } case acroFormFieldFileSelect: @@ -2543,18 +2480,18 @@ CAnnots::CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontLi case acroFormFieldText: case acroFormFieldBarcode: { - pAnnot = new CAnnotWidgetTx(pdfDoc, pField); + pAnnot = new CAnnotWidgetTx(pdfDoc, pField, nStartRefID); break; } case acroFormFieldComboBox: case acroFormFieldListBox: { - pAnnot = new CAnnotWidgetCh(pdfDoc, pField); + pAnnot = new CAnnotWidgetCh(pdfDoc, pField, nStartRefID); break; } case acroFormFieldSignature: { - pAnnot = new CAnnotWidgetSig(pdfDoc, pField); + pAnnot = new CAnnotWidgetSig(pdfDoc, pField, nStartRefID); break; } default: @@ -2565,6 +2502,22 @@ CAnnots::CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontLi pAnnot->SetFont(pdfDoc, pField, pFontManager, pFontList); if (pField->getAcroFormFieldType() == acroFormFieldPushbutton) pAnnot->SetButtonFont(pdfDoc, pField, pFontManager, pFontList); + pAnnot->SetPage(nStartPage + pField->getPageNum()); + + unsigned int unRefNumParent = pAnnot->GetRefNumParent(); + if (unRefNumParent) + { + std::vector::iterator it = std::find_if(m_arrParents.begin(), m_arrParents.end(), [unRefNumParent](CAnnotParent* pP) { return pP->unRefNum == unRefNumParent; }); + if (it != m_arrParents.end() && !((*it)->sFullName.empty())) + { + const std::string& sFullNameChild = pAnnot->GetFullName(); + if (sFullNameChild.empty()) + pAnnot->SetFullName((*it)->sFullName); + else + pAnnot->SetFullName((*it)->sFullName + "." + sFullNameChild); + } + } + m_arrAnnots.push_back(pAnnot); } } @@ -2577,22 +2530,22 @@ CAnnots::~CAnnots() for (int i = 0; i < m_arrAnnots.size(); ++i) RELEASEOBJECT(m_arrAnnots[i]); } -void CAnnots::getParents(XRef* xref, Object* oFieldRef) +void CAnnots::getParents(PDFDoc* pdfDoc, Object* oFieldRef, int nStartRefID) { - if (!oFieldRef || !xref || !oFieldRef->isRef() || - std::find_if(m_arrParents.begin(), m_arrParents.end(), [oFieldRef] (CAnnotParent* pAP) { return oFieldRef->getRefNum() == pAP->unRefNum; }) != m_arrParents.end()) + if (!oFieldRef || !pdfDoc || !oFieldRef->isRef() || + std::find_if(m_arrParents.begin(), m_arrParents.end(), [oFieldRef, nStartRefID] (CAnnotParent* pAP) { return oFieldRef->getRefNum() + nStartRefID == pAP->unRefNum; }) != m_arrParents.end()) return; Object oField; CAnnotParent* pAnnotParent = new CAnnotParent(); - if (!pAnnotParent || !oFieldRef->fetch(xref, &oField)->isDict()) + if (!pAnnotParent || !oFieldRef->fetch(pdfDoc->getXRef(), &oField)->isDict()) { oField.free(); RELEASEOBJECT(pAnnotParent); return; } - pAnnotParent->unRefNum = oFieldRef->getRefNum(); + pAnnotParent->unRefNum = oFieldRef->getRefNum() + nStartRefID; Object oObj; if (oField.dictLookup("T", &oObj)->isString()) @@ -2601,6 +2554,7 @@ void CAnnots::getParents(XRef* xref, Object* oFieldRef) std::string sStr = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); pAnnotParent->unFlags |= (1 << 0); pAnnotParent->sT = sStr; + pAnnotParent->sFullName = sStr; delete s; } oObj.free(); @@ -2661,41 +2615,181 @@ void CAnnots::getParents(XRef* xref, Object* oFieldRef) for (int j = 0; j < nOptLength; ++j) { Object oOptJ; - if (!oOpt.arrayGet(j, &oOptJ) || !oOptJ.isString()) + if (!oOpt.arrayGet(j, &oOptJ) || !(oOptJ.isString() || oOptJ.isArray())) { oOptJ.free(); continue; } - TextString* s = new TextString(oOptJ.getString()); - pAnnotParent->arrOpt.push_back(NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength())); - delete s; + std::string sOpt1, sOpt2; + if (oOptJ.isArray() && oOptJ.arrayGetLength() > 1) + { + Object oOptJ2; + if (oOptJ.arrayGet(0, &oOptJ2)->isString()) + { + TextString* s = new TextString(oOptJ2.getString()); + sOpt1 = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); + delete s; + } + oOptJ2.free(); + if (oOptJ.arrayGet(1, &oOptJ2)->isString()) + { + TextString* s = new TextString(oOptJ2.getString()); + sOpt2 = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); + delete s; + } + oOptJ2.free(); + } + else if (oOptJ.isString()) + { + TextString* s = new TextString(oOptJ.getString()); + sOpt2 = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); + delete s; + } + pAnnotParent->arrOpt.push_back(std::make_pair(sOpt1, sOpt2)); oOptJ.free(); } + if (!pAnnotParent->arrOpt.empty()) pAnnotParent->unFlags |= (1 << 6); } oOpt.free(); + // 7 - Флаг - Ff + if (oField.dictLookup("Ff", &oObj)->isInt()) + { + pAnnotParent->unFieldFlag = oObj.getInt(); + pAnnotParent->unFlags |= (1 << 7); + } + oObj.free(); + + // 8 - Actions - A/AA + Object oAction; + if (oField.dictLookup("A", &oAction)->isDict()) + { + std::string sAA = "A"; + CAction* pA = getAction(pdfDoc, &oAction); + if (pA) + { + pA->sType = sAA; + pAnnotParent->arrAction.push_back(pA); + pAnnotParent->unFlags |= (1 << 8); + } + } + oAction.free(); + + Object oAA; + if (oField.dictLookup("AA", &oAA)->isDict()) + { + for (int j = 0; j < oAA.dictGetLength(); ++j) + { + if (oAA.dictGetVal(j, &oAction)->isDict()) + { + std::string sAA(oAA.dictGetKey(j)); + CAction* pA = getAction(pdfDoc, &oAction); + if (pA) + { + pA->sType = sAA; + pAnnotParent->arrAction.push_back(pA); + pAnnotParent->unFlags |= (1 << 8); + } + } + oAction.free(); + } + } + oAA.free(); + + // 9 - MaxLen + if (oField.dictLookup("MaxLen", &oObj)->isInt()) + { + pAnnotParent->unMaxLen = oObj.getInt(); + pAnnotParent->unFlags |= (1 << 9); + } + oObj.free(); + m_arrParents.push_back(pAnnotParent); Object oParentRefObj; if (oField.dictLookupNF("Parent", &oParentRefObj)->isRef()) { pAnnotParent->unFlags |= (1 << 4); - pAnnotParent->unRefNumParent = oParentRefObj.getRefNum(); - getParents(xref, &oParentRefObj); + pAnnotParent->unRefNumParent = oParentRefObj.getRefNum() + nStartRefID; + getParents(pdfDoc, &oParentRefObj, nStartRefID); + + unsigned int unRefNumParent = pAnnotParent->unRefNumParent; + std::vector::iterator it = std::find_if(m_arrParents.begin(), m_arrParents.end(), [unRefNumParent](CAnnotParent* pP) { return pP->unRefNum == unRefNumParent; }); + if (it != m_arrParents.end() && !((*it)->sFullName.empty())) + { + if (pAnnotParent->sFullName.empty()) + pAnnotParent->sFullName = (*it)->sFullName; + else + pAnnotParent->sFullName = (*it)->sFullName + "." + pAnnotParent->sFullName; + } } oParentRefObj.free(); oField.free(); } +bool CAnnots::ChangeFullNameAnnot(int nAnnot, const std::string& sPrefixForm) +{ + if (nAnnot < 0 || nAnnot > m_arrAnnots.size()) + return false; + + CAnnotWidget* pWidget = m_arrAnnots[nAnnot]; + if (pWidget->ChangeFullName(sPrefixForm)) + return true; + unsigned int unRefNumParent = pWidget->GetRefNumParent(); + if (unRefNumParent) + { + std::vector::iterator it = std::find_if(m_arrParents.begin(), m_arrParents.end(), [unRefNumParent](CAnnotParent* pP) { return pP->unRefNum == unRefNumParent; }); + if (it != m_arrParents.end() && ChangeFullNameParent(std::distance(m_arrParents.begin(), it), sPrefixForm)) + { + pWidget->AddFullName(sPrefixForm); + // pWidget->ClearActions(); + return true; + } + } + return false; +} +bool CAnnots::ChangeFullNameParent(int nParent, const std::string& sPrefixForm) +{ + if (nParent < 0 || nParent > m_arrParents.size()) + return false; + + CAnnotParent* pParent = m_arrParents[nParent]; + if (pParent->unFlags & (1 << 0)) + { + pParent->sT += sPrefixForm; + pParent->sFullName += sPrefixForm; + // pParent->ClearActions(); + return true; + } + else if (pParent->unFlags & (1 << 4)) + { + unsigned int unRefNumParent = pParent->unRefNumParent; + std::vector::iterator it = std::find_if(m_arrParents.begin(), m_arrParents.end(), [unRefNumParent](CAnnotParent* pP) { return pP->unRefNum == unRefNumParent; }); + if (it != m_arrParents.end() && ChangeFullNameParent(std::distance(m_arrParents.begin(), it), sPrefixForm)) + { + pParent->sFullName += sPrefixForm; + // pParent->ClearActions(); + return true; + } + } + return false; +} +void CAnnots::CAnnotParent::ClearActions() +{ + unFlags &= ~(1 << 8); + for (int i = 0; i < arrAction.size(); ++i) + RELEASEOBJECT(arrAction[i]); + arrAction.clear(); +} //------------------------------------------------------------------------ // Markup //------------------------------------------------------------------------ -CAnnotMarkup::CAnnotMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CAnnot(pdfDoc, oAnnotRef, nPageIndex) +CAnnotMarkup::CAnnotMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int nStartRefID) : CAnnot(pdfDoc, oAnnotRef, nPageIndex, nStartRefID) { m_unFlags = 0; @@ -2707,7 +2801,7 @@ CAnnotMarkup::CAnnotMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : if (oAnnot.dictLookupNF("Popup", &oObj)->isRef()) { m_unFlags |= (1 << 0); - m_unRefNumPopup = oObj.getRefNum(); + m_unRefNumPopup = oObj.getRefNum() + nStartRefID; } // 1 - Текстовая метка пользователя - T @@ -2739,7 +2833,7 @@ CAnnotMarkup::CAnnotMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : if (oAnnot.dictLookupNF("IRT", &oObj)->isRef()) { m_unFlags |= (1 << 5); - m_unRefNumIRT = oObj.getRefNum(); + m_unRefNumIRT = oObj.getRefNum() + nStartRefID; } oObj.free(); @@ -2917,7 +3011,7 @@ void CAnnotMarkup::SetFont(PDFDoc* pdfDoc, Object* oAnnotRef, NSFonts::IFontMana // Annot //------------------------------------------------------------------------ -CAnnot::CAnnot(PDFDoc* pdfDoc, AcroFormField* pField) +CAnnot::CAnnot(PDFDoc* pdfDoc, AcroFormField* pField, int nStartRefID) { m_pBorder = NULL; m_unAnnotFlag = 0; @@ -2926,7 +3020,7 @@ CAnnot::CAnnot(PDFDoc* pdfDoc, AcroFormField* pField) Object oObj; pField->getFieldRef(&oObj); - m_unRefNum = oObj.getRefNum(); + m_unRefNum = oObj.getRefNum() + nStartRefID; oObj.free(); // Флаг аннотации - F @@ -2936,12 +3030,10 @@ CAnnot::CAnnot(PDFDoc* pdfDoc, AcroFormField* pField) // Номер страницы - P m_unPage = pField->getPageNum(); - if (m_unPage > 0) - --m_unPage; // Координаты - Rect pField->getBBox(&m_pRect[0], &m_pRect[1], &m_pRect[2], &m_pRect[3]); - PDFRectangle* pCropBox = pdfDoc->getCatalog()->getPage(m_unPage + 1)->getCropBox(); + PDFRectangle* pCropBox = pdfDoc->getCatalog()->getPage(m_unPage)->getCropBox(); m_dHeight = pCropBox->y2; m_dX = pCropBox->x1; double dTemp = m_pRect[1]; @@ -3041,7 +3133,7 @@ CAnnot::CAnnot(PDFDoc* pdfDoc, AcroFormField* pField) } oObj.free(); } -CAnnot::CAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) +CAnnot::CAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int nStartRefID) { m_pBorder = NULL; m_unAnnotFlag = 0; @@ -3053,7 +3145,7 @@ CAnnot::CAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) oAnnotRef->fetch(pXref, &oAnnot); // Номер объекта аннотации - m_unRefNum = oAnnotRef->getRefNum(); + m_unRefNum = oAnnotRef->getRefNum() + nStartRefID; // Флаг аннотации - F if (oAnnot.dictLookup("F", &oObj)->isInt()) @@ -3062,7 +3154,7 @@ CAnnot::CAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) // Номер страницы - P m_unPage = nPageIndex; - PDFRectangle* pCropBox = pdfDoc->getCatalog()->getPage(m_unPage + 1)->getCropBox(); + PDFRectangle* pCropBox = pdfDoc->getCatalog()->getPage(m_unPage)->getCropBox(); m_dHeight = pCropBox->y2; m_dX = pCropBox->x1; @@ -3192,7 +3284,7 @@ std::string CAnnot::DictLookupString(Object* pObj, const char* sName, int nByte) // AP //------------------------------------------------------------------------ -CAnnotAP::CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, const char* sView, const char* sButtonView, AcroFormField* pField) +CAnnotAP::CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, const char* sView, const char* sButtonView, AcroFormField* pField, int nStartRefID) { m_gfx = NULL; m_pFrame = NULL; @@ -3205,7 +3297,15 @@ CAnnotAP::CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFont Object oAP; if (pField->fieldLookup("AP", &oAP)->isDict() && oAP.dictGetLength()) { - Init(pField); + // Номер аннотации для сопоставления с AP + Object oRef; + pField->getFieldRef(&oRef); + m_unRefNum = oRef.getRefNum() + nStartRefID; + oRef.free(); + + // Координаты - BBox + pField->getBBox(&m_dx1, &m_dy1, &m_dx2, &m_dy2); + Init(pdfDoc, pFontManager, pFontList, nRasterW, nRasterH, nBackgroundColor, nPageIndex); Draw(pdfDoc, &oAP, nRasterH, nBackgroundColor, nPageIndex, pField, sView, sButtonView); } @@ -3213,7 +3313,7 @@ CAnnotAP::CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFont Clear(); } -CAnnotAP::CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, const char* sView, Object* oAnnotRef) +CAnnotAP::CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, const char* sView, Object* oAnnotRef, int nStartRefID) { m_gfx = NULL; m_pFrame = NULL; @@ -3228,7 +3328,7 @@ CAnnotAP::CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFont m_bIsStamp = oAnnot.dictLookup("Subtype", &oSubtype)->isName("Stamp") == gTrue; if (oAnnot.dictLookup("AP", &oAP)->isDict()) { - m_unRefNum = oAnnotRef->getRefNum(); + m_unRefNum = oAnnotRef->getRefNum() + nStartRefID; Init(&oAnnot); Init(pdfDoc, pFontManager, pFontList, nRasterW, nRasterH, nBackgroundColor, nPageIndex); @@ -3256,13 +3356,13 @@ void CAnnotAP::Clear() } void CAnnotAP::Init(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex) { - Page* pPage = pdfDoc->getCatalog()->getPage(nPageIndex + 1); + Page* pPage = pdfDoc->getCatalog()->getPage(nPageIndex); PDFRectangle* pCropBox = pPage->getCropBox(); m_dCropX = pCropBox->x1; m_dCropY = pCropBox->y1; - double dWidth = round(pdfDoc->getPageCropWidth(nPageIndex + 1)); - double dHeight = round(pdfDoc->getPageCropHeight(nPageIndex + 1)); + double dWidth = round(pdfDoc->getPageCropWidth(nPageIndex)); + double dHeight = round(pdfDoc->getPageCropHeight(nPageIndex)); double dRasterW = (double)nRasterW * m_dRWScale; double dRasterH = (double)nRasterH * m_dRHScale; @@ -3310,22 +3410,11 @@ void CAnnotAP::Init(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFon pPage->makeBox(72.0, 72.0, 0, gFalse, m_pRendererOut->upsideDown(), -1, -1, -1, -1, &box, &crop); PDFRectangle* cropBox = pPage->getCropBox(); - m_gfx = new Gfx(pdfDoc, m_pRendererOut, nPageIndex + 1, pPage->getAttrs()->getResourceDict(), 72.0, 72.0, &box, crop ? cropBox : (PDFRectangle *)NULL, 0, NULL, NULL); + m_gfx = new Gfx(pdfDoc, m_pRendererOut, nPageIndex, pPage->getAttrs()->getResourceDict(), 72.0, 72.0, &box, crop ? cropBox : (PDFRectangle *)NULL, 0, NULL, NULL); // Координаты внешнего вида m_dRx1 = (m_dx1 - m_dCropX) * m_dWScale - 1; - m_dRy1 = (pdfDoc->getPageCropHeight(nPageIndex + 1) - m_dy2 + m_dCropY) * m_dHScale - 1; -} -void CAnnotAP::Init(AcroFormField* pField) -{ - // Номер аннотации для сопоставления с AP - Object oRef; - pField->getFieldRef(&oRef); - m_unRefNum = oRef.getRefNum(); - oRef.free(); - - // Координаты - BBox - pField->getBBox(&m_dx1, &m_dy1, &m_dx2, &m_dy2); + m_dRy1 = (pdfDoc->getPageCropHeight(nPageIndex) - m_dy2 + m_dCropY) * m_dHScale - 1; } void CAnnotAP::Init(Object* oAnnot) { @@ -3442,7 +3531,6 @@ void CAnnotAP::Draw(PDFDoc* pdfDoc, Object* oAP, int nRasterH, int nBackgroundCo double dOffsetX = -(m_dx1 - m_dCropX) * m_dWScale + 1 + m_dWTale / 2; double dOffsetY = (m_dy2 - m_dCropY) * m_dHScale - nRasterH + 1 + m_dHTale / 2; - nPageIndex++; std::vector arrAPName { "N", "D", "R" }; for (unsigned int j = 0; j < arrAPName.size(); ++j) @@ -3492,6 +3580,7 @@ void CAnnotAP::Draw(PDFDoc* pdfDoc, Object* oAP, int nRasterH, int nBackgroundCo void CAnnotAP::Draw(PDFDoc* pdfDoc, Object* oAP, int nRasterH, int nBackgroundColor, Object* oAnnotRef, const char* sView) { ((GlobalParamsAdaptor*)globalParams)->setDrawFormField(true); + // Отрисовка внешних видов аннотации Object oAnnot; XRef* xref = pdfDoc->getXRef(); @@ -3548,7 +3637,6 @@ void CAnnotAP::WriteAppearance(unsigned int nColor, CAnnotAPView* pView) } pView->pAP = pSubMatrix; - pView->sText = ((GlobalParamsAdaptor*)globalParams)->GetTextFormField(); } BYTE CAnnotAP::GetBlendMode() { @@ -3581,14 +3669,6 @@ void CAnnotAP::ToWASM(NSWasm::CData& oRes) oRes.AddInt(npSubMatrix >> 32); oRes.WriteBYTE(m_arrAP[i]->nBlendMode); - - if (m_arrAP[i]->sText.empty()) - oRes.WriteBYTE(0); - else - { - oRes.WriteBYTE(1); - oRes.WriteString(m_arrAP[i]->sText); - } } } void CAnnots::ToWASM(NSWasm::CData& oRes) @@ -3633,16 +3713,32 @@ void CAnnots::CAnnotParent::ToWASM(NSWasm::CData& oRes) } if (unFlags & (1 << 6)) { - oRes.AddInt((unsigned int)arrOpt.size()); + oRes.AddInt(arrOpt.size()); for (int i = 0; i < arrOpt.size(); ++i) - oRes.WriteString(arrOpt[i]); + { + oRes.WriteString(arrOpt[i].first); + oRes.WriteString(arrOpt[i].second); + } } + if (unFlags & (1 << 7)) + oRes.AddInt(unFieldFlag); + if (unFlags & (1 << 8)) + { + oRes.AddInt(arrAction.size()); + for (int i = 0; i < arrAction.size(); ++i) + { + oRes.WriteString(arrAction[i]->sType); + arrAction[i]->ToWASM(oRes); + } + } + if (unFlags & (1 << 9)) + oRes.AddInt(unMaxLen); } void CAnnot::ToWASM(NSWasm::CData& oRes) { oRes.AddInt(m_unRefNum); oRes.AddInt(m_unAnnotFlag); - oRes.AddInt(m_unPage); + oRes.AddInt(m_unPage - 1); for (int i = 0; i < 4; ++i) oRes.WriteDouble(m_pRect[i]); oRes.AddInt(m_unAFlags); @@ -3875,7 +3971,7 @@ void CAnnotWidgetTx::ToWASM(NSWasm::CData& oRes) oRes.WriteString(m_sV); if (m_unFlags & (1 << 10)) oRes.AddInt(m_unMaxLen); - if (m_unFieldFlag & (1 << 25)) + if (m_unFlags & (1 << 11)) oRes.WriteString(m_sRV); } void CAnnotWidgetCh::ToWASM(NSWasm::CData& oRes) diff --git a/PdfFile/SrcReader/PdfAnnot.h b/PdfFile/SrcReader/PdfAnnot.h index 7b10bf5360..39dab706fb 100644 --- a/PdfFile/SrcReader/PdfAnnot.h +++ b/PdfFile/SrcReader/PdfAnnot.h @@ -117,8 +117,8 @@ struct CActionResetForm final : public CAction class CAnnotAP final { public: - CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, const char* sView, const char* sButtonView, AcroFormField* pField); - CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, const char* sView, Object* oAnnotRef); + CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, const char* sView, const char* sButtonView, AcroFormField* pField, int nStartRefID); + CAnnotAP(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex, const char* sView, Object* oAnnotRef, int nStartRefID); ~CAnnotAP(); void ToWASM(NSWasm::CData& oRes); @@ -129,14 +129,12 @@ private: BYTE nBlendMode; std::string sAPName; std::string sASName; - std::string sText; BYTE* pAP; }; void WriteAppearance(unsigned int nColor, CAnnotAPView* pView); BYTE GetBlendMode(); void Init(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList* pFontList, int nRasterW, int nRasterH, int nBackgroundColor, int nPageIndex); - void Init(AcroFormField* pField); void Init(Object* oAnnot); void Draw(PDFDoc* pdfDoc, Object* oAP, int nRasterH, int nBackgroundColor, int nPageIndex, AcroFormField* pField, const char* sView, const char* sButtonView); void Draw(PDFDoc* pdfDoc, Object* oAP, int nRasterH, int nBackgroundColor, Object* oAnnotRef, const char* sView); @@ -169,6 +167,7 @@ public: virtual ~CAnnot(); virtual void ToWASM(NSWasm::CData& oRes); + void SetPage(unsigned int nPage) { m_unPage = nPage; } struct CBorderType final { @@ -186,8 +185,8 @@ public: }; protected: - CAnnot(PDFDoc* pdfDoc, AcroFormField* pField); - CAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); + CAnnot(PDFDoc* pdfDoc, AcroFormField* pField, int nStartRefID); + CAnnot(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int nStartRefID); std::string DictLookupString(Object* pObj, const char* sName, int nByte); unsigned int m_unAFlags; @@ -220,12 +219,19 @@ public: void SetFont(PDFDoc* pdfDoc, AcroFormField* pField, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList); void SetButtonFont(PDFDoc* pdfDoc, AcroFormField* pField, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList); + unsigned int GetRefNumParent() { return m_unRefNumParent; } + const std::string& GetFullName() { return m_sFullName; } + void SetFullName(const std::string& sFullName) { m_sFullName = sFullName; } + void AddFullName(const std::string& sPrefixForm) { m_sFullName += sPrefixForm; } + bool ChangeFullName(const std::string& sPrefixForm); + void ClearActions(); + virtual std::string GetType() = 0; + virtual void ToWASM(NSWasm::CData& oRes) override; protected: - CAnnotWidget(PDFDoc* pdfDoc, AcroFormField* pField); + CAnnotWidget(PDFDoc* pdfDoc, AcroFormField* pField, int nStartRefID); std::string FieldLookupString(AcroFormField* pField, const char* sName, int nByte); - virtual void ToWASM(NSWasm::CData& oRes) override; BYTE m_nType; // Тип - FT + флаги unsigned int m_unFieldFlag; // Флаг - Ff @@ -246,6 +252,7 @@ private: std::string m_sDV; // Значение по-умолчанию - DV std::string m_sT; // Частичное имя поля - T std::string m_sFontKey; // Уникальный идентификатор шрифта + std::string m_sFullName; // Полное имя поля std::string m_sFontName; // Имя шрифта - из DA std::string m_sOMetadata; // OO метаданные формы std::string m_sActualFontName; // Имя замененного шрифта @@ -255,7 +262,8 @@ private: class CAnnotWidgetBtn final : public CAnnotWidget { public: - CAnnotWidgetBtn(PDFDoc* pdfDoc, AcroFormField* pField); + CAnnotWidgetBtn(PDFDoc* pdfDoc, AcroFormField* pField, int nStartRefID); + virtual std::string GetType() override { return "Btn"; } void ToWASM(NSWasm::CData& oRes) override; private: @@ -275,7 +283,8 @@ private: class CAnnotWidgetTx final : public CAnnotWidget { public: - CAnnotWidgetTx(PDFDoc* pdfDoc, AcroFormField* pField); + CAnnotWidgetTx(PDFDoc* pdfDoc, AcroFormField* pField, int nStartRefID); + virtual std::string GetType() override { return "Tx"; } void ToWASM(NSWasm::CData& oRes) override; private: @@ -287,7 +296,8 @@ private: class CAnnotWidgetCh final : public CAnnotWidget { public: - CAnnotWidgetCh(PDFDoc* pdfDoc, AcroFormField* pField); + CAnnotWidgetCh(PDFDoc* pdfDoc, AcroFormField* pField, int nStartRefID); + virtual std::string GetType() override { return "Ch"; } void ToWASM(NSWasm::CData& oRes) override; private: @@ -301,7 +311,8 @@ private: class CAnnotWidgetSig final : public CAnnotWidget { public: - CAnnotWidgetSig(PDFDoc* pdfDoc, AcroFormField* pField); + CAnnotWidgetSig(PDFDoc* pdfDoc, AcroFormField* pField, int nStartRefID); + virtual std::string GetType() override { return "Sig"; } void ToWASM(NSWasm::CData& oRes) override; }; @@ -313,7 +324,7 @@ public: class CAnnotPopup final : public CAnnot { public: - CAnnotPopup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); + CAnnotPopup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int nStartRefID); void ToWASM(NSWasm::CData& oRes) override; @@ -350,7 +361,7 @@ public: static std::vector ReadRC(const std::string& sRC); protected: - CAnnotMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); + CAnnotMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int nStartRefID); virtual ~CAnnotMarkup(); virtual void ToWASM(NSWasm::CData& oRes) override; @@ -374,7 +385,7 @@ private: class CAnnotText final : public CAnnotMarkup { public: - CAnnotText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); + CAnnotText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int nStartRefID); void ToWASM(NSWasm::CData& oRes) override; private: @@ -390,7 +401,7 @@ private: class CAnnotInk final : public CAnnotMarkup { public: - CAnnotInk(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); + CAnnotInk(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int nStartRefID); void ToWASM(NSWasm::CData& oRes) override; @@ -405,7 +416,7 @@ private: class CAnnotLine final : public CAnnotMarkup { public: - CAnnotLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); + CAnnotLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int nStartRefID); void ToWASM(NSWasm::CData& oRes) override; @@ -429,7 +440,7 @@ private: class CAnnotTextMarkup final : public CAnnotMarkup { public: - CAnnotTextMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); + CAnnotTextMarkup(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int nStartRefID); void ToWASM(NSWasm::CData& oRes) override; @@ -445,7 +456,7 @@ private: class CAnnotSquareCircle final : public CAnnotMarkup { public: - CAnnotSquareCircle(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); + CAnnotSquareCircle(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int nStartRefID); void ToWASM(NSWasm::CData& oRes) override; @@ -462,7 +473,7 @@ private: class CAnnotPolygonLine final : public CAnnotMarkup { public: - CAnnotPolygonLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); + CAnnotPolygonLine(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int nStartRefID); void ToWASM(NSWasm::CData& oRes) override; @@ -482,7 +493,7 @@ private: class CAnnotFreeText final : public CAnnotMarkup { public: - CAnnotFreeText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); + CAnnotFreeText(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int nStartRefID); void ToWASM(NSWasm::CData& oRes) override; @@ -504,7 +515,7 @@ private: class CAnnotCaret final : public CAnnotMarkup { public: - CAnnotCaret(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); + CAnnotCaret(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int nStartRefID); void ToWASM(NSWasm::CData& oRes) override; @@ -520,7 +531,7 @@ private: class CAnnotFileAttachment final : public CAnnotMarkup { public: - CAnnotFileAttachment(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); + CAnnotFileAttachment(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int nStartRefID); virtual ~CAnnotFileAttachment(); void ToWASM(NSWasm::CData& oRes) override; @@ -576,7 +587,7 @@ private: class CAnnotStamp final : public CAnnotMarkup { public: - CAnnotStamp(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex); + CAnnotStamp(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int nStartRefID); void ToWASM(NSWasm::CData& oRes) override; private: @@ -592,10 +603,13 @@ private: class CAnnots { public: - CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList); + CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, int nStartPage, int nStartRefID); ~CAnnots(); void ToWASM(NSWasm::CData& oRes); + bool ChangeFullNameAnnot(int nAnnot, const std::string& sPrefixForm); + bool ChangeFullNameParent(int nParent, const std::string& sPrefixForm); + const std::vector& GetAnnots() { return m_arrAnnots; } private: struct CAnnotParent final @@ -606,25 +620,34 @@ private: unRefNum = 0; unRefNumParent = 0; } + ~CAnnotParent() + { + ClearActions(); + } + void ClearActions(); void ToWASM(NSWasm::CData& oRes); unsigned int unFlags; unsigned int unRefNum; // Номер ссылки на объект + unsigned int unMaxLen; // Ограничение на максимальную длину text field + unsigned int unFieldFlag; // Флаг Ff unsigned int unRefNumParent; // Номер ссылки на объект родителя std::vector arrI; std::vector arrV; - std::vector arrOpt; + std::vector< std::pair > arrOpt; + std::vector arrAction; // Действия std::string sT; std::string sV; std::string sDV; + std::string sFullName; }; - void getParents(XRef* xref, Object* oFieldRef); + void getParents(PDFDoc* pdfDoc, Object* oFieldRef, int nStartRefID); std::vector m_arrCO; // Порядок вычислений - CO std::vector m_arrParents; // Родительские Fields - std::vector m_arrAnnots; + std::vector m_arrAnnots; }; //------------------------------------------------------------------------ diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index 69eb23eb36..003e6738b5 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -474,6 +474,13 @@ namespace PdfReader void RendererOutputDev::restoreState(GfxState* pGState) { RELEASEINTERFACE(m_pSoftMask); + if (m_sStates.empty()) + { // Несбалансированный q/Q - сломанный файл + updateAll(pGState); + UpdateAllClip(pGState); + return; + } + m_pSoftMask = m_sStates.back().pSoftMask; if (c_nGrRenderer == m_lRendererType) { @@ -1812,12 +1819,13 @@ namespace PdfReader return true; case 6: case 7: - int nComps = ((GfxPatchMeshShading*)pShading)->getNComps(); + // int nComps = ((GfxPatchMeshShading*)pShading)->getNComps(); int nPatches = ((GfxPatchMeshShading*)pShading)->getNPatches(); NSGraphics::IGraphicsRenderer* GRenderer = dynamic_cast(m_pRenderer); if (GRenderer) GRenderer->SetSoftMask(NULL); + m_pRenderer->BeginCommand(c_nLayerType); for (int i = 0; i < nPatches; i++) { @@ -2168,7 +2176,7 @@ namespace PdfReader } void RendererOutputDev::clip(GfxState* pGState) { - if (m_bDrawOnlyText) + if (m_bDrawOnlyText || m_sStates.empty()) return; if (!m_sStates.back().pClip) @@ -2179,7 +2187,7 @@ namespace PdfReader } void RendererOutputDev::eoClip(GfxState* pGState) { - if (m_bDrawOnlyText) + if (m_bDrawOnlyText || m_sStates.empty()) return; if (!m_sStates.back().pClip) @@ -2190,7 +2198,7 @@ namespace PdfReader } void RendererOutputDev::clipToStrokePath(GfxState* pGState) { - if (m_bDrawOnlyText) + if (m_bDrawOnlyText || m_sStates.empty()) return; if (!m_sStates.back().pClip) @@ -2244,7 +2252,7 @@ namespace PdfReader } void RendererOutputDev::endTextObject(GfxState* pGState) { - if (m_sStates.back().pTextClip && 4 <= pGState->getRender()) + if (!m_sStates.empty() && m_sStates.back().pTextClip && 4 <= pGState->getRender()) { AddTextClip(pGState, &m_sStates.back()); updateFont(pGState); @@ -2307,10 +2315,6 @@ namespace PdfReader if (3 == nRendererMode) // Невидимый текст return; - double* pCTM = pGState->getCTM(); - double* pTm = pGState->getTextMat(); - GfxFont* pFont = pGState->getFont(); - unsigned int unGidsCount = seString->getLength(); unsigned int* pGids = new unsigned int[unGidsCount]; if (!pGids) @@ -2319,7 +2323,7 @@ namespace PdfReader std::wstring wsUnicodeText; for (int nIndex = 0; nIndex < seString->getLength(); nIndex++) { - char nChar = seString->getChar(nIndex); + int nChar = seString->getChar(nIndex); if (NULL != oEntry.pCodeToUnicode) { @@ -2417,9 +2421,6 @@ namespace PdfReader double dShiftX = 0, dShiftY = 0; DoTransform(arrMatrix, &dShiftX, &dShiftY, true); - // Здесь мы посылаем координаты текста в пунктах - double dPageHeight = pGState->getPageHeight(); - std::wstring wsUnicodeText; bool isCIDFont = pFont->isCIDFont(); @@ -2518,8 +2519,6 @@ namespace PdfReader } } } - if (((GlobalParamsAdaptor*)globalParams)->getDrawFormField()) - ((GlobalParamsAdaptor*)globalParams)->AddTextFormField(wsUnicodeText); #endif m_pRenderer->CommandDrawTextEx(wsUnicodeText, &unGid, unGidsCount, PDFCoordsToMM(dShiftX), PDFCoordsToMM(dShiftY), PDFCoordsToMM(dDx), PDFCoordsToMM(dDy)); if (bReplace) @@ -2586,9 +2585,13 @@ namespace PdfReader m_pRenderer->get_FontSize(&dTempFontSize); m_pRenderer->get_FontStyle(&lTempFontStyle); // tmpchange - if (!m_sStates.back().pTextClip) - m_sStates.back().pTextClip = new GfxTextClip(); - m_sStates.back().pTextClip->ClipToText(wsTempFontName, wsTempFontPath, dTempFontSize, (int)lTempFontStyle, arrMatrix, wsClipText, dShiftX, /*-fabs(pFont->getFontBBox()[3]) * dTfs + */ dShiftY, 0, 0, 0); + if (!m_sStates.empty()) + { + if (!m_sStates.back().pTextClip) + m_sStates.back().pTextClip = new GfxTextClip(); + m_sStates.back().pTextClip->ClipToText(wsTempFontName, wsTempFontPath, dTempFontSize, (int)lTempFontStyle, arrMatrix, wsClipText, dShiftX, /*-fabs(pFont->getFontBBox()[3]) * dTfs + */ dShiftY, 0, 0, 0); + + } } m_pRenderer->put_FontSize(dOldSize); diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index eb123ae3a8..bb0a932c3e 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -71,6 +71,15 @@ namespace PdfWriter { "Check", "Checkmark", "Circle", "Comment", "Cross", "CrossHairs", "Help", "Insert", "Key", "NewParagraph", "Note", "Paragraph", "RightArrow", "RightPointer", "Star", "UpArrow", "UpLeftArrow" }; + const static char* c_sCheckBoxStyleNames[] = + { + "4", // Check + "8", // Cross + "u", // Diamond + "l", // Circle + "H", // Star + "n" // Square + }; void AddToVectorD(CDictObject* pObj, const std::string& sName, const std::vector& arrV) { @@ -86,7 +95,8 @@ namespace PdfWriter std::string AddLE(const BYTE& nLE) { std::string sValue; - switch (nLE) + ELineEndType eLE = ELineEndType(nLE); + switch (eLE) { case ELineEndType::Square: sValue = "Square"; break; case ELineEndType::Circle: sValue = "Circle"; break; @@ -168,6 +178,7 @@ namespace PdfWriter m_pAppearance = NULL; m_pDocument = NULL; m_pXref = pXref; + m_oBorder.bHave = false; Add("Type", "Annot"); Add("Subtype", c_sAnnotTypeNames[(int)eType]); @@ -303,6 +314,17 @@ namespace PdfWriter sRes.append(" ] 0 d\012"); return sRes; } + std::string CAnnotation::GetColorName(const std::string& sName, bool bCAPS) + { + std::string sRes; + CObjectBase* pObj = Get(sName); + if (pObj && pObj->GetType() == object_type_ARRAY) + { + sRes += GetColor(dynamic_cast(pObj), bCAPS).c_str(); + sRes += "\012"; + } + return sRes; + } CAnnotAppearanceObject* CAnnotation::StartAP() { m_pAppearance = new CAnnotAppearance(m_pXref, this); @@ -683,7 +705,8 @@ namespace PdfWriter void CLineAnnotation::SetIT(BYTE nIT) { std::string sValue; - switch (nIT) + ELineIntentType eIT = ELineIntentType(nIT); + switch (eIT) { case ELineIntentType::LineDimension: sValue = "LineDimension"; break; case ELineIntentType::LineArrow: sValue = "LineArrow"; break; @@ -698,7 +721,8 @@ namespace PdfWriter return; std::string sValue; - switch (nCP) + ECaptionPositioning eCP = ECaptionPositioning(nCP); + switch (eCP) { case ECaptionPositioning::Inline: sValue = "Inline"; break; case ECaptionPositioning::Top: sValue = "Top"; break; @@ -766,299 +790,12 @@ namespace PdfWriter { AddToVectorD(this, "IC", arrIC); } - void AdjustLineEndpoint(ELineEndType nType, double x, double y, double dx, double dy, double w, double& tx, double& ty) - { - tx = x; - ty = y; - - switch (nType) - { - case ELineEndType::ClosedArrow: - case ELineEndType::OpenArrow: - case ELineEndType::Diamond: - { - tx += w * dx; - if ((dx > 0.001 && dy > 0) || (dx < -0.001 && dy < 0)) - ty += w * dy; - break; - } - case ELineEndType::Square: - case ELineEndType::Circle: - { - if ((dx > -0.02 && dy < 0.02) || (dx < 0.02 && dy > -0.02)) - tx += w * dx; - break; - } - case ELineEndType::Slash: - case ELineEndType::Butt: - case ELineEndType::ROpenArrow: - case ELineEndType::RClosedArrow: - case ELineEndType::None: - default: - break; - } - } - void SreamWriteXYMove(CStream* pStream, double x, double y) - { - pStream->WriteReal(x); - pStream->WriteChar(' '); - pStream->WriteReal(y); - pStream->WriteStr(" m\012"); - } - void SreamWriteXYLine(CStream* pStream, double x, double y) - { - pStream->WriteReal(x); - pStream->WriteChar(' '); - pStream->WriteReal(y); - pStream->WriteStr(" l\012"); - } - void SreamWriteXYCurve(CStream* pStream, double x1, double y1, double x2, double y2, double x3, double y3) - { - pStream->WriteReal(x1); - pStream->WriteChar(' '); - pStream->WriteReal(y1); - pStream->WriteChar(' '); - pStream->WriteReal(x2); - pStream->WriteChar(' '); - pStream->WriteReal(y2); - pStream->WriteChar(' '); - pStream->WriteReal(x3); - pStream->WriteChar(' '); - pStream->WriteReal(y3); - pStream->WriteStr(" c\012"); - } - void StreamWriteRect(CStream* pStream, double x1, double y1, double x2, double y2) - { - pStream->WriteReal(x1); - pStream->WriteChar(' '); - pStream->WriteReal(y1); - pStream->WriteChar(' '); - pStream->WriteReal(x2); - pStream->WriteChar(' '); - pStream->WriteReal(y2); - pStream->WriteStr(" re\012"); - } - void SreamWriteCircle(CStream* pStream, double cx, double cy, double r) - { - double bezierCircle = 0.55228475 * r; - SreamWriteXYMove(pStream, cx + r, cy); - SreamWriteXYCurve(pStream, cx + r, cy + bezierCircle, cx + bezierCircle, cy + r, cx, cy + r); - SreamWriteXYCurve(pStream, cx - bezierCircle, cy + r, cx - r, cy + bezierCircle, cx - r, cy); - SreamWriteXYCurve(pStream, cx - r, cy - bezierCircle, cx - bezierCircle, cy - r, cx, cy - r); - SreamWriteXYCurve(pStream, cx + bezierCircle, cy - r, cx + r, cy - bezierCircle, cx + r, cy); - } - void DrawArrow(CStream* pStream, ELineEndType nType, double x, double y, double dx, double dy, double w) - { - double lineEndSize1 = 3, pi = 3.14159265358979323846; - switch (nType) - { - case ELineEndType::Butt: - { - w *= lineEndSize1; - SreamWriteXYMove(pStream, x + w * dy, y - w * dx); - SreamWriteXYLine(pStream, x - w * dy, y + w * dx); - pStream->WriteStr("S\012"); - break; - } - case ELineEndType::Circle: - { - SreamWriteCircle(pStream, x, y, w * lineEndSize1); - pStream->WriteStr("h\012B\012"); - break; - } - case ELineEndType::Diamond: - { - w *= lineEndSize1; - SreamWriteXYMove(pStream, x - w, y); - SreamWriteXYLine(pStream, x, y + w); - SreamWriteXYLine(pStream, x + w, y); - SreamWriteXYLine(pStream, x, y - w); - pStream->WriteStr("b\012"); - break; - } - case ELineEndType::OpenArrow: - case ELineEndType::ClosedArrow: - { - w *= lineEndSize1 * lineEndSize1; - double d32 = pi * 32.0 / 180.0; - double d28 = pi * 28.0 / 180.0; - if ((dx > 0.001 && dy < 0) || (dx < -0.001 && dy > 0)) - { - SreamWriteXYMove(pStream, x + w * cos(d32) * dx + w * sin(d32) * dy, y + w * cos(d32) * dy - w * sin(d32) * dx); - SreamWriteXYLine(pStream, x, y); - SreamWriteXYLine(pStream, x + w * cos(d28) * dx - w * sin(d28) * dy, y + w * cos(d28) * dy + w * sin(d28) * dx); - } - else - { - double dCos = w * cos(pi / 6.0); - double dSin = w * sin(pi / 6.0); - - SreamWriteXYMove(pStream, x + dCos * dx + dSin * dy, y + dCos * dy - dSin * dx); - SreamWriteXYLine(pStream, x, y); - SreamWriteXYLine(pStream, x + dCos * dx - dSin * dy, y + dCos * dy + dSin * dx); - } - pStream->WriteStr(nType == ELineEndType::OpenArrow ? "S\012" : "b\012"); - break; - } - case ELineEndType::ROpenArrow: - case ELineEndType::RClosedArrow: - { - x -= cos(pi / 18.0) * dx * w; - y -= cos(pi / 18.0) * dy * w; - w *= lineEndSize1 * lineEndSize1; - double dCos = w * cos(pi / 6.0); - double dSin = w * sin(pi / 6.0); - SreamWriteXYMove(pStream, x - dCos * dx + dSin * dy, y - dCos * dy - dSin * dx); - SreamWriteXYLine(pStream, x, y); - SreamWriteXYLine(pStream, x - dCos * dx - dSin * dy, y - dCos * dy + dSin * dx); - pStream->WriteStr(nType == ELineEndType::ROpenArrow ? "S\012" : "b\012"); - break; - } - case ELineEndType::Slash: - { - w *= lineEndSize1 * lineEndSize1; - double dCos = w * cos(pi / 6.0); - double dSin = w * sin(pi / 6.0); - SreamWriteXYMove(pStream, x + dCos * dy - dSin * dx, y - dCos * dx - dSin * dy); - SreamWriteXYLine(pStream, x - dCos * dy + dSin * dx, y + dCos * dx + dSin * dy); - pStream->WriteStr("S\012"); - break; - } - case ELineEndType::Square: - { - w *= lineEndSize1; - pStream->WriteReal(x - w); - pStream->WriteChar(' '); - pStream->WriteReal(y - w); - pStream->WriteChar(' '); - pStream->WriteReal(w * 2); - pStream->WriteChar(' '); - pStream->WriteReal(w * 2); - pStream->WriteStr(" re\012"); - pStream->WriteStr("B\012"); - break; - } - case ELineEndType::None: - default: - { - break; - } - } - } - void DrawLineArrow(CStream* pStream, double dBorderSize, double x1, double y1, double x2, double y2, ELineEndType nLE1, ELineEndType nLE2, double dLL = 0, double dLLO = 0, double dLLE = 0) - { - double dDX = x2 - x1; - double dDY = y2 - y1; - double dLen = sqrt(dDX * dDX + dDY * dDY); - if (dLen > 0) - { - dDX /= dLen; - dDY /= dLen; - } - - double lx1, ly1, lx2, ly2; - double ax1, ay1, ax2, ay2; - double bx1, by1, bx2, by2; - if (dLL != 0) - { - ax1 = x1 + dLLO * dDY; - ay1 = y1 - dLLO * dDX; - lx1 = ax1 + dLL * dDY; - ly1 = ay1 - dLL * dDX; - bx1 = lx1 + dLLE * dDY; - by1 = ly1 - dLLE * dDX; - ax2 = x2 + dLLO * dDY; - ay2 = y2 - dLLO * dDX; - lx2 = ax2 + dLL * dDY; - ly2 = ay2 - dLL * dDX; - bx2 = lx2 + dLLE * dDY; - by2 = ly2 - dLLE * dDX; - } - else - { - lx1 = x1; - ly1 = y1; - lx2 = x2; - ly2 = y2; - ax1 = ay1 = ax2 = ay2 = 0; - bx1 = by1 = bx2 = by2 = 0; - } - - double tx1, ty1, tx2, ty2; - AdjustLineEndpoint(nLE1, lx1, ly1, dDX, dDY, dBorderSize, tx1, ty1); - AdjustLineEndpoint(nLE2, lx2, ly2, -dDX, -dDY, dBorderSize, tx2, ty2); - - if (dLL) - { - SreamWriteXYMove(pStream, ax1, ay1); - SreamWriteXYLine(pStream, bx1, by1); - - SreamWriteXYMove(pStream, ax2, ay2); - SreamWriteXYLine(pStream, bx2, by2); - } - - SreamWriteXYMove(pStream, tx1, ty1); - SreamWriteXYLine(pStream, tx2, ty2); - pStream->WriteStr("S\012"); - - DrawArrow(pStream, nLE1, tx1, ty1, dDX, dDY, dBorderSize); - DrawArrow(pStream, nLE2, tx2, ty2, -dDX, -dDY, dBorderSize); - } void CLineAnnotation::SetAP() { CAnnotAppearance* pAppearance = new CAnnotAppearance(m_pXref, this); Add("AP", pAppearance); CAnnotAppearanceObject* pNormal = pAppearance->GetNormal(); - CStream* pStream = pNormal->GetStream(); - - pNormal->AddBBox(GetRect().fLeft, GetRect().fBottom, GetRect().fRight, GetRect().fTop); - pNormal->AddMatrix(1, 0, 0, 1, -GetRect().fLeft, -GetRect().fBottom); - - if (GetBorderType() == EBorderType::Dashed) - pStream->WriteStr(GetBorderDash().c_str()); - - double dBorderSize = GetBorderWidth(); - pStream->WriteReal(dBorderSize); - pStream->WriteStr(" w\012"); - - CObjectBase* pObj = Get("IC"); - if (pObj && pObj->GetType() == object_type_ARRAY) - { - pStream->WriteStr(GetColor(dynamic_cast(pObj), false).c_str()); - pStream->WriteStr("\012"); - } - - pStream->WriteStr(GetColor(dynamic_cast(Get("C")), true).c_str()); - pStream->WriteStr("\012"); - - pObj = Get("CA"); - if (pObj && pObj->GetType() == object_type_REAL) - { - float dAlpha = ((CRealObject*)pObj)->Get(); - if (dAlpha != 1) - { - CExtGrState* pExtGrState = m_pDocument->GetExtGState(dAlpha, dAlpha); - const char* sExtGrStateName = m_pDocument->GetFieldsResources()->GetExtGrStateName(pExtGrState); - if (sExtGrStateName) - { - pStream->WriteEscapeName(sExtGrStateName); - pStream->WriteStr(" gs\012"); - } - } - } - - double dLL = 0, dLLE = 0, dLLO = 0; - pObj = Get("LL"); - if (pObj && pObj->GetType() == object_type_REAL) - dLL = ((CRealObject*)pObj)->Get(); - pObj = Get("LLE"); - if (pObj && pObj->GetType() == object_type_REAL) - dLLE = ((CRealObject*)pObj)->Get(); - pObj = Get("LLO"); - if (pObj && pObj->GetType() == object_type_REAL) - dLLO = ((CRealObject*)pObj)->Get(); - - DrawLineArrow(pStream, dBorderSize, dL[0], dL[1], dL[2], dL[3], m_nLE1, m_nLE2, dLL, dLLE, dLLO); + pNormal->DrawLine(); } //---------------------------------------------------------------------------------------- // CPopupAnnotation @@ -1442,10 +1179,27 @@ namespace PdfWriter std::string sValue = U_TO_UTF8(wsName); Add("Name", sValue.c_str()); } - void CStampAnnotation::SetAPStream(CDictObject* pStream) + void CStampAnnotation::SetAPStream(CDictObject* pStream, bool bCopy) { + if (bCopy) + { + CDictObject* pStreamNew = (CDictObject*)pStream->Copy(); + CStream* pStr = new CMemoryStream(); + pStreamNew->SetStream(m_pXref, pStr, true); + pStr->WriteStream(pStream->GetStream(), 0, NULL); + pStreamNew->SetFilter(STREAM_FILTER_FLATE_DECODE); + pStream = pStreamNew; + + CDictObject* pAP = new PdfWriter::CDictObject(); + Add("AP", pAP); + pAP->Add("N", pStreamNew); + } m_pAPStream = pStream; } + CDictObject* CStampAnnotation::GetAPStream() + { + return m_pAPStream; + } //---------------------------------------------------------------------------------------- // CWidgetAnnotation //---------------------------------------------------------------------------------------- @@ -1456,6 +1210,7 @@ namespace PdfWriter m_pAppearance = NULL; m_pFont = NULL; m_dFontSizeAP = 0; + m_nParentID = 0; m_nQ = 0; m_dFontSize = 10.0; m_bBold = false; @@ -1582,6 +1337,8 @@ namespace PdfWriter } void CWidgetAnnotation::SetFlag(const int& nFlag) { + if (nFlag < 0) + return; CDictObject* pOwner = GetObjOwnValue("Ff"); if (!pOwner) pOwner = this; @@ -1594,6 +1351,10 @@ namespace PdfWriter m_pParent = pParent; Add("Parent", pParent); } + void CWidgetAnnotation::SetParentID(int nParentID) + { + m_nParentID = nParentID; + } void CWidgetAnnotation::SetTU(const std::wstring& wsTU) { std::string sValue = U_TO_UTF8(wsTU); @@ -1655,40 +1416,18 @@ namespace PdfWriter if (pAction->m_sType == "A") { - CDictObject* pOwner = GetObjOwnValue(pAction->m_sType); - if (!pOwner) - pOwner = this; - - pOwner->Add(pAction->m_sType.c_str(), pAction); + Add(pAction->m_sType.c_str(), pAction); return; } - std::string sAA = pAction->m_sType; - CDictObject* pAA = NULL; - if (m_pParent && (sAA == "K" || sAA == "F" || sAA == "V" || sAA == "C")) - pAA = (CDictObject*)m_pParent->Get("AA"); - else if (sAA == "E" || sAA == "X" || sAA == "D" || sAA == "U" || sAA == "Fo" || sAA == "Bl" || sAA == "PO" || sAA == "PC" || sAA == "PV" || sAA == "PI") - { - pAA = (CDictObject*)Get("AA"); - if (!pAA) - { - pAA = new CDictObject(); - Add("AA", pAA); - } - } - + CDictObject* pAA = (CDictObject*)Get("AA"); if (!pAA) { - pAA = (CDictObject*)GetObjValue("AA"); - if (!pAA) - { - pAA = new CDictObject(); - Add("AA", pAA); - } + pAA = new CDictObject(); + Add("AA", pAA); } - if (pAA) - pAA->Add(sAA.c_str(), pAction); + pAA->Add(pAction->m_sType.c_str(), pAction); } std::string CWidgetAnnotation::GetDAforAP(CFontDict* pFont) { @@ -1708,10 +1447,10 @@ namespace PdfWriter return sDA; } - std::string CWidgetAnnotation::GetBGforAP(double dDiff) + std::string CWidgetAnnotation::GetBGforAP(double dDiff, bool bCAPS) { if (m_pMK) - return GetColor(dynamic_cast(m_pMK->Get("BG")), false, dDiff); + return GetColor(dynamic_cast(m_pMK->Get("BG")), bCAPS, dDiff); return ""; } std::string CWidgetAnnotation::GetBCforAP() @@ -1876,6 +1615,8 @@ namespace PdfWriter } void CPushButtonWidget::SetFlag(const int& nFlag) { + if (nFlag < 0) + return; int nFlags = nFlag; nFlags |= (1 << 16); CWidgetAnnotation::SetFlag(nFlags); @@ -1994,7 +1735,7 @@ namespace PdfWriter || (3 == m_nScaleType && dOriginH < dH && dOriginW < dW)); double dBorderSize = m_oBorder.dWidth; - if (m_oBorder.nType == 1 || m_oBorder.nType == 3) + if (m_oBorder.nType == EBorderType::Beveled || m_oBorder.nType == EBorderType::Inset) dBorderSize *= 2; double dDstW = dOriginW; @@ -2062,9 +1803,11 @@ namespace PdfWriter //---------------------------------------------------------------------------------------- // CCheckBoxWidget //---------------------------------------------------------------------------------------- - CCheckBoxWidget::CCheckBoxWidget(CXref* pXref) : CWidgetAnnotation(pXref, AnnotWidget) + CCheckBoxWidget::CCheckBoxWidget(CXref* pXref, EWidgetType nSubtype) : CWidgetAnnotation(pXref, AnnotWidget) { - m_nSubtype = WidgetRadiobutton; + m_nSubtype = nSubtype; + m_nStyle = ECheckBoxStyle::Circle; + m_pAP = NULL; } void CCheckBoxWidget::SetV(const std::wstring& wsV) { @@ -2078,75 +1821,180 @@ namespace PdfWriter else pOwner->Add("V", new CStringObject(sV.c_str(), true)); } - std::wstring CCheckBoxWidget::SetStyle(BYTE nStyle) + void CCheckBoxWidget::SetStyle(BYTE nStyle) { + m_nStyle = ECheckBoxStyle(nStyle); CheckMK(); - std::string sValue; - switch (nStyle) - { - case 1: - { sValue = "8"; break; } - case 2: - { sValue = "u"; break; } - case 3: - { sValue = "l"; break; } - case 4: - { sValue = "H"; break; } - case 5: - { sValue = "n"; break; } - default: - case 0: - { sValue = "4"; break; } - } - - m_pMK->Add("CA", new CStringObject(sValue.c_str())); - - return UTF8_TO_U(sValue); + m_pMK->Add("CA", new CStringObject(c_sCheckBoxStyleNames[(int)nStyle])); } void CCheckBoxWidget::SetAP_N_Yes(const std::wstring& wsAP_N_Yes) { std::string sValue = U_TO_UTF8(wsAP_N_Yes); - m_sAP_N_Yes = sValue; + if (m_sAP_N_Yes.empty()) + m_sAP_N_Yes = sValue; + + if (m_pAP) + { + CDictObject* pDict = (CDictObject*)m_pAP->Get("N"); + pDict->Add(m_sAP_N_Yes, m_pAP->GetYesN()); + pDict->Remove("Yes"); + pDict = (CDictObject*)m_pAP->Get("D"); + pDict->Add(m_sAP_N_Yes, m_pAP->GetYesD()); + pDict->Remove("Yes"); + } } - void CCheckBoxWidget::SwitchAP(const std::string& sV) + void CCheckBoxWidget::RenameAP_N_Yes(const std::wstring& wsAP_N_Yes) + { + std::string sValue = U_TO_UTF8(wsAP_N_Yes); + m_sAP_N_Yes = sValue; + if (m_pAP) + { + CDictObject* pDict = (CDictObject*)m_pAP->Get("N"); + pDict->Add(m_sAP_N_Yes, m_pAP->GetYesN()); + pDict->Remove("Yes"); + pDict = (CDictObject*)m_pAP->Get("D"); + pDict->Add(m_sAP_N_Yes, m_pAP->GetYesD()); + pDict->Remove("Yes"); + } + else + { + CObjectBase* pAPN = NULL; + CObjectBase* pAP = Get("AP"); + if (pAP->GetType() == object_type_DICT) + pAPN = ((CDictObject*)pAP)->Get("N"); + if (pAPN && pAPN->GetType() == object_type_DICT) + { + CDictObject* pDictAPN = (CDictObject*)pAPN; + std::map mDict = pDictAPN->GetDict(); + for (std::pair it : mDict) + { + if (it.first != "Off" && it.first != m_sAP_N_Yes) + { + CObjectBase* pObject = it.second; + pDictAPN->Add(m_sAP_N_Yes, pObject->Copy()); + pDictAPN->Remove(it.first); + break; + } + } + } + pAPN = NULL; + if (pAP->GetType() == object_type_DICT) + pAPN = ((CDictObject*)pAP)->Get("D"); + if (pAPN && pAPN->GetType() == object_type_DICT) + { + CDictObject* pDictAPN = (CDictObject*)pAPN; + std::map mDict = pDictAPN->GetDict(); + for (std::pair it : mDict) + { + if (it.first != "Off" && it.first != m_sAP_N_Yes) + { + CObjectBase* pObject = it.second; + pDictAPN->Add(m_sAP_N_Yes, pObject->Copy()); + pDictAPN->Remove(it.first); + break; + } + } + } + } + } + bool CCheckBoxWidget::NeedAP_N_Yes() + { + return m_sAP_N_Yes.empty(); + } + void CCheckBoxWidget::SetAP() + { + if (!m_pAP) + { + m_pAP = new CCheckBoxAnnotAppearance(m_pXref, this, m_sAP_N_Yes.empty() ? NULL : m_sAP_N_Yes.c_str()); + Add("AP", m_pAP); + } + + if (m_nStyle == ECheckBoxStyle::Circle && m_nSubtype == WidgetRadiobutton) + { + m_pAP->GetYesN()->DrawCheckBoxCircle(true, true); + m_pAP->GetOffN()->DrawCheckBoxCircle(false, true); + m_pAP->GetYesD()->DrawCheckBoxCircle(true, false); + m_pAP->GetOffD()->DrawCheckBoxCircle(false, false); + } + else + { + m_pAP->GetYesN()->DrawCheckBoxSquare(true, true); + m_pAP->GetOffN()->DrawCheckBoxSquare(false, true); + m_pAP->GetYesD()->DrawCheckBoxSquare(true, false); + m_pAP->GetOffD()->DrawCheckBoxSquare(false, false); + } + } + std::string CCheckBoxWidget::Yes() + { + std::string sName = m_sAP_N_Yes.empty() ? "Yes" : m_sAP_N_Yes; + Add("AS", sName.c_str()); + return sName; + } + void CCheckBoxWidget::Off() + { + Add("AS", "Off"); + } + void CCheckBoxWidget::SwitchAP(const std::string& sV, int nI) { CObjectBase* pAP, *pAPN; Add("AS", "Off"); - if (!m_sAP_N_Yes.empty()) + CObjectBase* pObj = GetObjValue("Opt"); + if (!m_sAP_N_Yes.empty() && pObj && pObj->GetType() == object_type_ARRAY) { - CObjectBase* pObj = GetObjValue("Opt"); - if (pObj && pObj->GetType() == object_type_ARRAY) + if (m_pAP) { - CArrayObject* pArr = (CArrayObject*)pObj; - for (int i = 0; i < pArr->GetCount(); ++i) + CDictObject* pDict = (CDictObject*)m_pAP->Get("N"); + pDict->Remove(m_sAP_N_Yes); + pDict = (CDictObject*)m_pAP->Get("D"); + pDict->Remove(m_sAP_N_Yes); + } + CArrayObject* pArr = (CArrayObject*)pObj; + for (int i = 0; i < pArr->GetCount(); ++i) + { + pObj = pArr->Get(i); + if (pObj->GetType() == object_type_ARRAY && ((CArrayObject*)pObj)->GetCount() > 0) + pObj = ((CArrayObject*)pObj)->Get(0); + if (pObj->GetType() == object_type_STRING) { - pObj = pArr->Get(i); - if (pObj->GetType() == object_type_ARRAY && ((CArrayObject*)pObj)->GetCount() > 0) - pObj = ((CArrayObject*)pObj)->Get(0); - if (pObj->GetType() == object_type_STRING) + CStringObject* pStr = (CStringObject*)pObj; + const BYTE* pBinary = pStr->GetString(); + if (pStr->GetLength() == m_sAP_N_Yes.length() && !StrCmp((const char*)pBinary, m_sAP_N_Yes.c_str())) { - CStringObject* pStr = (CStringObject*)pObj; - const BYTE* pBinary = pStr->GetString(); - if (pStr->GetLength() == m_sAP_N_Yes.length() && !StrCmp((const char*)pBinary, m_sAP_N_Yes.c_str())) - { - m_sAP_N_Yes = std::to_string(i); - SetV(UTF8_TO_U(m_sAP_N_Yes)); - break; - } + m_sAP_N_Yes = std::to_string(i); + SetV(UTF8_TO_U(m_sAP_N_Yes)); + break; } } } Add("AS", m_sAP_N_Yes.c_str()); + if (nI >= 0 && m_pAP) + { + CDictObject* pDict = (CDictObject*)m_pAP->Get("N"); + pDict->Add(m_sAP_N_Yes, m_pAP->GetYesN()); + pDict = (CDictObject*)m_pAP->Get("D"); + pDict->Add(m_sAP_N_Yes, m_pAP->GetYesD()); + } } else if ((pAP = Get("AP")) && pAP->GetType() == object_type_DICT && (pAPN = ((CDictObject*)pAP)->Get("N")) && pAPN->GetType() == object_type_DICT && ((CDictObject*)pAPN)->Get(sV)) Add("AS", sV.c_str()); + else if (nI >= 0 && m_pAP) + { + CDictObject* pDict = (CDictObject*)m_pAP->Get("N"); + pDict->Add(std::to_string(nI), m_pAP->GetYesN()); + pDict->Remove("Yes"); + pDict = (CDictObject*)m_pAP->Get("D"); + pDict->Add(std::to_string(nI), m_pAP->GetYesD()); + pDict->Remove("Yes"); + } } void CCheckBoxWidget::SetFlag(const int& nFlag) { + if (nFlag < 0) + return; int nFlags = nFlag; - if (m_nSubtype == WidgetRadiobutton) - nFlags |= (1 << 15); + if (nFlags & (1 << 15)) + m_nSubtype = WidgetRadiobutton; CWidgetAnnotation::SetFlag(nFlags); } //---------------------------------------------------------------------------------------- @@ -2184,12 +2032,18 @@ namespace PdfWriter } bool CTextWidget::IsCombFlag() { - int nFlags = ((CNumberObject*)GetObjValue("Ff"))->Get(); + int nFlags = 0; + CNumberObject* pFf = (CNumberObject*)GetObjValue("Ff"); + if (pFf) + nFlags = pFf->Get(); return (nFlags & (1 << 24)); } bool CTextWidget::IsMultiLine() { - int nFlags = ((CNumberObject*)GetObjValue("Ff"))->Get(); + int nFlags = 0; + CNumberObject* pFf = (CNumberObject*)GetObjValue("Ff"); + if (pFf) + nFlags = pFf->Get(); return (nFlags & (1 << 12)); } unsigned int CTextWidget::GetMaxLen() @@ -2208,6 +2062,8 @@ namespace PdfWriter } void CChoiceWidget::SetFlag(const int& nFlag) { + if (nFlag < 0) + return; int nFlags = nFlag; if (m_nSubtype == WidgetCombobox) nFlags |= (1 << 17); @@ -2270,6 +2126,9 @@ namespace PdfWriter void CChoiceWidget::SetOpt(const std::vector< std::pair >& arrOpt) { m_arrOpt = arrOpt; + if (m_arrOpt.empty()) + return; + CArrayObject* pArray = new CArrayObject(); if (!pArray) return; @@ -2375,6 +2234,10 @@ namespace PdfWriter { m_sType = U_TO_UTF8(wsType); } + void CAction::SetNext(CAction* pNext) + { + Add("Next", pNext); + } //---------------------------------------------------------------------------------------- CActionResetForm::CActionResetForm(CXref* pXref) : CAction(pXref) { diff --git a/PdfFile/SrcWriter/Annotation.h b/PdfFile/SrcWriter/Annotation.h index e1bb6a46ec..b9c0d44636 100644 --- a/PdfFile/SrcWriter/Annotation.h +++ b/PdfFile/SrcWriter/Annotation.h @@ -41,12 +41,12 @@ namespace PdfWriter { class CDestination; - enum ELineIntentType + enum class ELineIntentType { LineDimension = 0, LineArrow }; - enum ELineEndType + enum class ELineEndType { Square = 0, Circle, @@ -59,12 +59,12 @@ namespace PdfWriter RClosedArrow, Slash }; - enum ECaptionPositioning + enum class ECaptionPositioning { Inline = 0, Top }; - enum EBorderType + enum class EBorderType { Solid = 0, Beveled, @@ -72,6 +72,15 @@ namespace PdfWriter Inset, Underline }; + enum class ECheckBoxStyle + { + Check = 0, + Cross, + Diamond, + Circle, + Star, + Square + }; class CAction : public CDictObject { @@ -193,6 +202,7 @@ namespace PdfWriter EBorderType GetBorderType() { return m_oBorder.nType; } double GetBorderWidth() { return m_oBorder.dWidth; } std::string GetBorderDash(); + std::string GetColorName(const std::string& sName, bool bCAPS); double GetWidth() { return abs(m_oRect.fRight - m_oRect.fLeft); } double GetHeight() { return abs(m_oRect.fTop - m_oRect.fBottom); } double GetPageX() { return m_dPageX; } @@ -284,10 +294,10 @@ namespace PdfWriter }; class CLineAnnotation : public CMarkupAnnotation { - private: + public: ELineEndType m_nLE1, m_nLE2; double dL[4]; - public: + CLineAnnotation(CXref* pXref); EAnnotType GetAnnotationType() const override { @@ -400,7 +410,9 @@ namespace PdfWriter void SetRotate(double nRotate); void SetName(const std::wstring& wsName); - void SetAPStream(CDictObject* pStream); + void SetAPStream(CDictObject* pStream, bool bCopy = false); + + CDictObject* GetAPStream(); }; class CWidgetAnnotation : public CAnnotation { @@ -418,6 +430,7 @@ namespace PdfWriter double m_dFontSizeAP; std::vector m_arrTC; BYTE m_nQ; + int m_nParentID; void CheckMK(); @@ -443,6 +456,7 @@ namespace PdfWriter void SetR(const int& nR); virtual void SetFlag (const int& nFlag); void SetParent(CDictObject* pParent); + void SetParentID(int nParentID); void SetTU(const std::wstring& wsTU); void SetDS(const std::wstring& wsDS); void SetDV(const std::wstring& wsDV); @@ -453,10 +467,11 @@ namespace PdfWriter void AddAction(CAction* pAction); std::string GetDAforAP(CFontDict* pFont); - std::string GetBGforAP(double dDiff = 0); + std::string GetBGforAP(double dDiff = 0, bool bCAPS = false); std::string GetBCforAP(); CFontCidTrueType* GetFont() { return m_pFont; } double GetFontSize() { return m_dFontSize; } + int GetParentID() { return m_nParentID; } bool GetFontIsBold() { return m_bBold; } bool GetFontIsItalic() { return m_bItalic; } bool HaveBG(); @@ -516,16 +531,25 @@ namespace PdfWriter { private: std::string m_sAP_N_Yes; + ECheckBoxStyle m_nStyle; + CCheckBoxAnnotAppearance* m_pAP; public: - CCheckBoxWidget(CXref* pXref); + CCheckBoxWidget(CXref* pXref, EWidgetType nSubtype = WidgetCheckbox); void SetV(const std::wstring& wsV); - std::wstring SetStyle(BYTE nStyle); + void SetStyle(BYTE nStyle); + ECheckBoxStyle GetStyle() { return m_nStyle; } void SetAP_N_Yes(const std::wstring& wsAP_N_Yes); + std::string GetAP_N_Yes() { return m_sAP_N_Yes; } + bool NeedAP_N_Yes(); + void RenameAP_N_Yes(const std::wstring& wsAP_N_Yes); virtual void SetFlag (const int& nFlag); + void SetAP(); + void SwitchAP(const std::string& sV, int nI = -1); - void SwitchAP(const std::string& sV); + std::string Yes(); + void Off(); }; class CTextWidget : public CWidgetAnnotation { diff --git a/PdfFile/SrcWriter/Destination.cpp b/PdfFile/SrcWriter/Destination.cpp index 2f2a342923..bd63c6709f 100644 --- a/PdfFile/SrcWriter/Destination.cpp +++ b/PdfFile/SrcWriter/Destination.cpp @@ -30,20 +30,19 @@ * */ #include "Destination.h" -#include "Pages.h" namespace PdfWriter { //---------------------------------------------------------------------------------------- // CDestination //---------------------------------------------------------------------------------------- - CDestination::CDestination(CPage* pPage, CXref* pXref, bool bInline) + CDestination::CDestination(CObjectBase* pPage, CXref* pXref, bool bInline) { if (!bInline) pXref->Add(this); // Первый элемент массива должен быть страницей, которой принадлежит объект - Add((CObjectBase*)pPage); + Add(pPage); Add("Fit"); // Значение по умолчанию Fit } bool CDestination::IsValid() const @@ -51,21 +50,28 @@ namespace PdfWriter if (m_arrList.size() < 2) return false; - CObjectBase* pObject = Get(0, false); - if ((object_type_DICT != pObject->GetType() || dict_type_PAGE != ((CDictObject*)pObject)->GetDictType()) && - (object_type_PROXY != pObject->GetType() || object_type_DICT != ((CProxyObject*)pObject)->Get()->GetType() || dict_type_PAGE != ((CDictObject*)((CProxyObject*)pObject)->Get())->GetDictType())) - return false; + // Проверка, что объект является страницей. Но это может быть ссылка на нередактируемую страницу + // CObjectBase* pObject = Get(0, false); + // if ((object_type_DICT != pObject->GetType() || dict_type_PAGE != ((CDictObject*)pObject)->GetDictType()) && + // (object_type_PROXY != pObject->GetType() || object_type_DICT != ((CProxyObject*)pObject)->Get()->GetType() || dict_type_PAGE != ((CDictObject*)((CProxyObject*)pObject)->Get())->GetDictType())) + // return false; return true; } void CDestination::PrepareArray() { - CPage* pPage = (CPage*)Get(0); - if (m_arrList.size() > 1) { + CObjectBase* pPage = Get(0); + if (pPage->GetType() != object_type_DICT) + { + CObjectBase* pCopy = pPage->Copy(); + pCopy->SetRef(pPage->GetObjId(), pPage->GetGenNo()); + pPage = new CProxyObject(pCopy, true); + } + Clear(); - Add((CObjectBase*)pPage); + Add(pPage); } } void CDestination::SetXYZ(float fLeft, float fTop, float fZoom) diff --git a/PdfFile/SrcWriter/Destination.h b/PdfFile/SrcWriter/Destination.h index d0e73bb6eb..ea5bfec429 100644 --- a/PdfFile/SrcWriter/Destination.h +++ b/PdfFile/SrcWriter/Destination.h @@ -36,12 +36,10 @@ namespace PdfWriter { - class CPage; - class CDestination : public CArrayObject { public: - CDestination(CPage* pPage, CXref* pXref, bool bInline = false); + CDestination(CObjectBase* pPage, CXref* pXref, bool bInline = false); bool IsValid() const; void SetXYZ (float fLeft, float fTop, float fZoom); void SetFit (); diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 3a8727a72c..f65fde2934 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -203,8 +203,6 @@ namespace PdfWriter m_pFieldsResources = NULL; memset((void*)m_sTTFontTag, 0x00, 8); m_pDefaultCheckBoxFont = NULL; - m_wsDocumentID = L""; - m_wsFilePath = L""; m_vExtGrStates.clear(); m_vStrokeAlpha.clear(); @@ -238,6 +236,22 @@ namespace PdfWriter return true; } + bool CDocument::SaveToMemory(BYTE** pData, int* pLength) + { + CMemoryStream* pStream = new CMemoryStream(); + if (!pStream) + return false; + + if (m_pJbig2) + m_pJbig2->FlushStreams(); + + SaveToStream(pStream); + + *pData = pStream->GetBuffer(); + *pLength = pStream->Size(); + pStream->ClearWithoutAttack(); + return true; + } void CDocument::SaveToStream(CStream* pStream) { m_pCatalog->AddMetadata(m_pXref, m_pInfo); @@ -266,7 +280,7 @@ namespace PdfWriter PrepareEncryption(); } - m_pXref->WriteToStream(pStream, pEncrypt); + m_pXref->WriteToStream(pStream, pEncrypt, true); } bool CDocument::SaveNewWithPassword(CXref* pXref, CXref* _pXref, const std::wstring& wsPath, const std::wstring& wsOwnerPassword, const std::wstring& wsUserPassword, CDictObject* pTrailer) { @@ -513,7 +527,7 @@ namespace PdfWriter return new COutline(pParent, sTitle, m_pXref); } - CDestination* CDocument::CreateDestination(CPage* pPage, bool bInline) + CDestination* CDocument::CreateDestination(CObjectBase* pPage, bool bInline) { if (pPage) return new CDestination(pPage, m_pXref, bInline); @@ -610,11 +624,91 @@ namespace PdfWriter m_vFillAlpha.push_back(pExtGrState); return pExtGrState; } - CAnnotation* CDocument::CreateTextAnnot() + CAnnotation* CDocument::CreateAnnot(BYTE m_nType) { - CTextAnnotation* pNew = new CTextAnnotation(m_pXref); - pNew->SetC({ 1.0, 0.8, 0.0 }); - return pNew; + CAnnotation* pAnnot = NULL; + if (m_nType == 0) + { + pAnnot = new CTextAnnotation(m_pXref); + pAnnot->SetC({ 1.0, 0.8, 0.0 }); + } + else if (m_nType == 14) + pAnnot = new CInkAnnotation(m_pXref); + else if (m_nType == 3) + pAnnot = new CLineAnnotation(m_pXref); + else if (m_nType >= 8 && m_nType <= 11) + pAnnot = new CTextMarkupAnnotation(m_pXref); + else if (m_nType == 4 || m_nType == 5) + pAnnot = new CSquareCircleAnnotation(m_pXref); + else if (m_nType == 6 || m_nType == 7) + pAnnot = new CPolygonLineAnnotation(m_pXref); + else if (m_nType == 15) + pAnnot = new CPopupAnnotation(m_pXref); + else if (m_nType == 2) + pAnnot = new CFreeTextAnnotation(m_pXref); + else if (m_nType == 13) + pAnnot = new CCaretAnnotation(m_pXref); + else if (m_nType == 12) + pAnnot = new CStampAnnotation(m_pXref); + + if (pAnnot) + m_pXref->Add(pAnnot); + + if (m_nType >= 26) + { + if (!CheckAcroForm()) + return NULL; + + switch (m_nType) + { + case 26: + { + pAnnot = new CWidgetAnnotation(m_pXref, EAnnotType::AnnotWidget); + break; + } + case 27: + { + pAnnot = new CPushButtonWidget(m_pXref); + pAnnot->Add("FT", "Btn"); + break; + } + case 28: + case 29: + { + pAnnot = new CCheckBoxWidget(m_pXref); + pAnnot->Add("FT", "Btn"); + break; + } + case 30: + { + pAnnot = new CTextWidget(m_pXref); + pAnnot->Add("FT", "Tx"); + break; + } + case 31: + case 32: + { + pAnnot = new CChoiceWidget(m_pXref); + pAnnot->Add("FT", "Ch"); + break; + } + case 33: + { + pAnnot = new CSignatureWidget(m_pXref); + pAnnot->Add("FT", "Sig"); + break; + } + default: break; + } + + if (pAnnot) + { + m_pXref->Add(pAnnot); + CArrayObject* ppFields = (CArrayObject*)m_pAcroForm->Get("Fields"); + ppFields->Add(pAnnot); + } + } + return pAnnot; } CAnnotation* CDocument::CreateLinkAnnot(const TRect& oRect, CDestination* pDest) { @@ -630,78 +724,6 @@ namespace PdfWriter m_pXref->Add(pAnnot); return pAnnot; } - CAnnotation* CDocument::CreateInkAnnot() - { - return new CInkAnnotation(m_pXref); - } - CAnnotation* CDocument::CreateLineAnnot() - { - return new CLineAnnotation(m_pXref); - } - CAnnotation* CDocument::CreateTextMarkupAnnot() - { - return new CTextMarkupAnnotation(m_pXref); - } - CAnnotation* CDocument::CreateSquareCircleAnnot() - { - return new CSquareCircleAnnotation(m_pXref); - } - CAnnotation* CDocument::CreatePolygonLineAnnot() - { - return new CPolygonLineAnnotation(m_pXref); - } - CAnnotation* CDocument::CreatePopupAnnot() - { - return new CPopupAnnotation(m_pXref); - } - CAnnotation* CDocument::CreateFreeTextAnnot() - { - return new CFreeTextAnnotation(m_pXref); - } - CAnnotation* CDocument::CreateCaretAnnot() - { - return new CCaretAnnotation(m_pXref); - } - CAnnotation* CDocument::CreateStampAnnot() - { - return new CStampAnnotation(m_pXref); - } - CAnnotation* CDocument::CreateWidgetAnnot() - { - if (!CheckAcroForm()) - return NULL; - - CWidgetAnnotation* pWidget = new CWidgetAnnotation(m_pXref, EAnnotType::AnnotWidget); - if (!pWidget) - return NULL; - - CArrayObject* ppFields = (CArrayObject*)m_pAcroForm->Get("Fields"); - ppFields->Add(pWidget); - - return pWidget; - } - CAnnotation* CDocument::CreatePushButtonWidget() - { - return new CPushButtonWidget(m_pXref); - } - CAnnotation* CDocument::CreateCheckBoxWidget() - { - return new CCheckBoxWidget(m_pXref); - } - CAnnotation* CDocument::CreateTextWidget() - { - CAnnotation* pNew = new CTextWidget(m_pXref); - pNew->Add("FT", "Tx"); - return pNew; - } - CAnnotation* CDocument::CreateChoiceWidget() - { - return new CChoiceWidget(m_pXref); - } - CAnnotation* CDocument::CreateSignatureWidget() - { - return new CSignatureWidget(m_pXref); - } CAction* CDocument::CreateAction(BYTE nType) { switch (nType) @@ -718,7 +740,6 @@ namespace PdfWriter } void CDocument::AddAnnotation(const int& nID, CAnnotation* pAnnot) { - m_pXref->Add(pAnnot); m_mAnnotations[nID] = pAnnot; } CImageDict* CDocument::CreateImage() @@ -1290,6 +1311,10 @@ namespace PdfWriter m_pCurImage = pImage; m_vImages.push_back({wsImagePath, nAlpha, pImage}); } + void CDocument::AddObject(CObjectBase* pObj) + { + m_pXref->Add(pObj); + } bool CDocument::CheckFieldName(CFieldBase* pField, const std::string& sName) { CFieldBase* pBase = m_mFields[sName]; @@ -1370,6 +1395,17 @@ namespace PdfWriter return (!!m_pAcroForm); } + void CDocument::SetAcroForm(CDictObject* pObj) + { + if (!m_pXref || !m_pCatalog) + return; + m_pCatalog->Add("AcroForm", pObj); + m_pAcroForm = pObj; + } + CResourcesDict* CDocument::CreateResourcesDict(bool bInline, bool bProcSet) + { + return new CResourcesDict(m_pXref, bInline, bProcSet); + } bool CDocument::CreatePageTree(CXref* pXref, CPageTree* pPageTree) { if (!pPageTree || !EditXref(pXref)) @@ -1382,7 +1418,7 @@ namespace PdfWriter return true; } - bool CDocument::EditPdf(const std::wstring& wsPath, int nPosLastXRef, int nSizeXRef, CXref* pXref, CCatalog* pCatalog, CEncryptDict* pEncrypt, int nFormField) + bool CDocument::EditPdf(int nPosLastXRef, int nSizeXRef, CXref* pXref, CCatalog* pCatalog, CEncryptDict* pEncrypt, int nFormField) { if (!pXref || !pCatalog) return false; @@ -1415,7 +1451,6 @@ namespace PdfWriter } m_unFormFields = nFormField; - m_wsFilePath = wsPath; return true; } bool CDocument::EditResources(CXref* pXref, CResourcesDict* pResources) @@ -1454,7 +1489,7 @@ namespace PdfWriter pPage->SetFilter(STREAM_FILTER_FLATE_DECODE); #endif - m_pCurPage = pPage; + m_pCurPage = pPage; m_mEditPages[nPageIndex] = pPage; if (m_pPageTree) @@ -1462,6 +1497,22 @@ namespace PdfWriter return true; } + void CDocument::FixEditPage(CPage* _pPage, int nPageIndex) + { + CPage* pPage = _pPage ? _pPage : m_mEditPages[nPageIndex]; + if (!pPage) + return; + + pPage->AddContents(m_pXref); +#ifndef FILTER_FLATE_DECODE_DISABLED + if (m_unCompressMode & COMP_TEXT) + pPage->SetFilter(STREAM_FILTER_FLATE_DECODE); +#endif + } + void CDocument::AddEditPage(CPage* pPage, int nPageIndex) + { + m_mEditPages[nPageIndex] = pPage; + } bool CDocument::EditAnnot(CXref* pXref, CAnnotation* pAnnot, int nID) { if (!pAnnot || !EditXref(pXref)) @@ -1472,19 +1523,28 @@ namespace PdfWriter return true; } + void CDocument::AddParent(int nID, CDictObject* pParent) + { + m_mParents[nID] = pParent; + } + CDictObject* CDocument::CreateParent(int nID) + { + CDictObject* pParent = new CDictObject(); + m_pXref->Add(pParent); + m_mParents[nID] = pParent; + return pParent; + } bool CDocument::EditParent(CXref* pXref, CDictObject* pParent, int nID) { if (!pParent || !EditXref(pXref)) return false; - m_mParents[nID] = pParent; - return true; } bool CDocument::EditXref(CXref* pXref) { if (!pXref) - return false; + return true; pXref->SetPrev(m_pLastXref); m_pLastXref = pXref; @@ -1519,9 +1579,56 @@ namespace PdfWriter return p->second; return NULL; } - CPage* CDocument::CreateFakePage() + std::string CDocument::SetParentKids(int nParentID) { - return new CPage(this, NULL); + CDictObject* pParent = GetParent(nParentID); + if (!pParent) + return ""; + + for (auto it = m_mAnnotations.begin(); it != m_mAnnotations.end(); it++) + { + CAnnotation* pAnnot = it->second; + if (pAnnot->GetAnnotationType() != AnnotWidget) + continue; + + CWidgetAnnotation* pWidget = (CWidgetAnnotation*)pAnnot; + int nWidgetParentID = pWidget->GetParentID(); + if (nWidgetParentID != nParentID) + continue; + + pWidget->SetParent(pParent); + + CObjectBase* pFT = pParent->Get("FT"); + CObjectBase* pWidgetFT = pWidget->Get("FT"); + if (!pFT && pParent->Get("T") && pWidgetFT) + pParent->Add("FT", pWidgetFT->Copy()); + + CArrayObject* pKids = dynamic_cast(pParent->Get("Kids")); + if (!pKids) + { + pKids = new CArrayObject(); + pParent->Add("Kids", pKids); + } + bool bReplase = false; + int nID = pWidget->GetObjId(); + for (int i = 0; i < pKids->GetCount(); ++i) + { + CObjectBase* pKid = pKids->Get(i); + if (pKid->GetObjId() == nID) + { + pKids->Insert(pKid, pWidget, true); + bReplase = true; + break; + } + } + if (!bReplase) + pKids->Add(pWidget); + } + + CObjectBase* pFT = pParent->Get("FT"); + if (pFT && pFT->GetType() == object_type_NAME) + return ((CNameObject*)pFT)->Get(); + return ""; } bool CDocument::EditCO(const std::vector& arrCO) { @@ -1552,22 +1659,20 @@ namespace PdfWriter return true; } - CPage* CDocument::AddPage(int nPageIndex) + CPage* CDocument::AddPage(int nPageIndex, CPage* _pNewPage) { if (!m_pPageTree) return NULL; - CPage* pNewPage = new CPage(m_pXref, NULL, this); + CPage* pNewPage = _pNewPage ? _pNewPage : new CPage(m_pXref, NULL, this); if (!pNewPage) return NULL; bool bRes = m_pPageTree->InsertPage(nPageIndex, pNewPage); if (!bRes) return NULL; -#ifndef FILTER_FLATE_DECODE_DISABLED - if (m_unCompressMode & COMP_TEXT) + if (!_pNewPage) pNewPage->SetFilter(STREAM_FILTER_FLATE_DECODE); -#endif m_pCurPage = pNewPage; return pNewPage; } @@ -1579,6 +1684,8 @@ namespace PdfWriter CObjectBase* pObj = m_pPageTree->RemovePage(nPageIndex); if (pObj) { + if (pObj->IsIndirect()) + return true; CXref* pXref = new CXref(this, pObj->GetObjId(), pObj->GetGenNo()); delete pObj; if (!pXref) @@ -1600,16 +1707,16 @@ namespace PdfWriter } return false; } - bool CDocument::AddToFile(CXref* pXref, CDictObject* pTrailer, CXref* pInfoXref, CInfoDict* pInfo) + bool CDocument::AddToFile(const std::wstring& wsPath, CXref* pXref, CDictObject* pTrailer, CXref* pInfoXref, CInfoDict* pInfo) { - if (!pTrailer || m_wsFilePath.empty()) + if (!pTrailer || wsPath.empty()) return false; CFileStream* pStream = new CFileStream(); if (!pStream) return false; - if (!pStream->OpenFile(m_wsFilePath, false)) + if (!pStream->OpenFile(wsPath, false)) { RELEASEOBJECT(pStream); return false; @@ -1698,7 +1805,7 @@ namespace PdfWriter RELEASEOBJECT(pStream); unsigned int nSizeXRef = m_pXref->GetSizeXRef(); m_pXref = m_pLastXref; - Sign(m_wsFilePath, nSizeXRef, bNeedStreamXRef); + Sign(wsPath, nSizeXRef, bNeedStreamXRef); RELEASEOBJECT(m_pEncryptDict); return true; diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index 9bbb4045b6..7e447ce993 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -92,6 +92,7 @@ namespace PdfWriter class CFieldBase; class CStreamData; class CXObject; + class CObjectBase; //---------------------------------------------------------------------------------------- // CDocument //---------------------------------------------------------------------------------------- @@ -105,6 +106,7 @@ namespace PdfWriter bool CreateNew(); void Close(); bool SaveToFile(const std::wstring& wsPath); + bool SaveToMemory(BYTE** pData, int* pLength); bool SaveNewWithPassword(CXref* pXref, CXref* _pXref, const std::wstring& wsPath, const std::wstring& wsOwnerPassword, const std::wstring& wsUserPassword, CDictObject* pTrailer); void SetPasswords(const std::wstring & wsOwnerPassword, const std::wstring & wsUserPassword); @@ -119,7 +121,7 @@ namespace PdfWriter void SetPDFAConformanceMode(bool isPDFA); bool IsPDFA() const; - + CPage* AddPage(); CPage* GetPage (const unsigned int& unPage); CPage* GetEditPage(const unsigned int& unPage); @@ -128,7 +130,8 @@ namespace PdfWriter void AddPageLabel(EPageNumStyle eStyle, unsigned int unFirstPage, const char* sPrefix); void AddPageLabel(unsigned int unPageIndex, EPageNumStyle eStyle, unsigned int unFirstPage, const char* sPrefix); COutline* CreateOutline(COutline* pParent, const char* sTitle); - CDestination* CreateDestination(CPage* pPage, bool bInline = false); + COutline* GetOutlines() { return m_pOutlines; } + CDestination* CreateDestination(CObjectBase* pPage, bool bInline = false); bool AddMetaData(const std::wstring& sMetaName, BYTE* pMetaData, DWORD nMetaLength); CExtGrState* GetExtGState(double dAlphaStroke = -1, double dAlphaFill = -1, EBlendMode eMode = blendmode_Unknown, int nStrokeAdjustment = -1); @@ -136,24 +139,9 @@ namespace PdfWriter CExtGrState* GetFillAlpha(double dAlpha); CJbig2Global* GetJbig2Global(); + CAnnotation* CreateAnnot(BYTE nType); CAnnotation* CreateLinkAnnot(const TRect& oRect, CDestination* pDest); CAnnotation* CreateUriLinkAnnot(const TRect& oRect, const char* sUrl); - CAnnotation* CreateTextAnnot(); - CAnnotation* CreateInkAnnot(); - CAnnotation* CreateLineAnnot(); - CAnnotation* CreateTextMarkupAnnot(); - CAnnotation* CreateSquareCircleAnnot(); - CAnnotation* CreatePolygonLineAnnot(); - CAnnotation* CreatePopupAnnot(); - CAnnotation* CreateFreeTextAnnot(); - CAnnotation* CreateCaretAnnot(); - CAnnotation* CreateStampAnnot(); - CAnnotation* CreateWidgetAnnot(); - CAnnotation* CreatePushButtonWidget(); - CAnnotation* CreateCheckBoxWidget(); - CAnnotation* CreateTextWidget(); - CAnnotation* CreateChoiceWidget(); - CAnnotation* CreateSignatureWidget(); void AddAnnotation(const int& nID, CAnnotation* pAnnot); CAction* CreateAction(BYTE nType); @@ -189,30 +177,38 @@ namespace PdfWriter void SetCurImage(CImageDict* pImage) { m_pCurImage = pImage; } bool CreatePageTree(CXref* pXref, CPageTree* pPageTree); - bool EditPdf(const std::wstring& wsPath, int nPosLastXRef, int nSizeXRef, CXref* pXref, CCatalog* pCatalog, CEncryptDict* pEncrypt, int nFormField); + bool EditPdf(int nPosLastXRef, int nSizeXRef, CXref* pXref, CCatalog* pCatalog, CEncryptDict* pEncrypt, int nFormField); bool EditResources(CXref* pXref, CResourcesDict* pResources); std::pair GetPageRef(int nPageIndex); bool EditPage(CXref* pXref, CPage* pPage, int nPageIndex); - CPage* AddPage(int nPageIndex); + void FixEditPage(CPage* pPage, int nPageIndex = 0); + void AddEditPage(CPage* pPage, int nPageIndex); + CPage* AddPage(int nPageIndex, CPage* _pNewPage = NULL); bool DeletePage(int nPageIndex); + bool AddToFile(const std::wstring& wsPath, CXref* pXref, CDictObject* pTrailer, CXref* pInfoXref, CInfoDict* pInfo); + void AddObject(CObjectBase* pObj); bool MovePage(int nPageIndex, int nPos); - bool AddToFile(CXref* pXref, CDictObject* pTrailer, CXref* pInfoXref, CInfoDict* pInfo); void Sign(const TRect& oRect, CImageDict* pImage, ICertificate* pCert); - std::wstring GetEditPdfPath() { return m_wsFilePath; } bool EditAnnot (CXref* pXref, CAnnotation* pAnnot, int nID); + void AddParent(int nID, CDictObject* pParent); + CDictObject* CreateParent(int nID); bool EditParent(CXref* pXref, CDictObject* pParent, int nID); bool DeleteAnnot(int nObjNum, int nObjGen); CAnnotation* GetAnnot(int nID); CDictObject* GetParent(int nID); CPage* GetCurPage() { return m_pCurPage; } void SetCurPage(CPage* pPage) { m_pCurPage = pPage; } - CPage* CreateFakePage(); bool EditCO(const std::vector& arrCO); + std::string SetParentKids(int nParentID); const std::map& GetAnnots() { return m_mAnnotations; } + const std::map& GetParents() { return m_mParents; } void AddShapeXML(const std::string& sXML); void EndShapeXML(); void ClearPage(); bool EditXref(CXref* pXref); + void SetAcroForm(CDictObject* pObj); + CDictObject* GetAcroForm() { return m_pAcroForm; } + CResourcesDict* CreateResourcesDict(bool bInline, bool bProcSet); private: char* GetTTFontTag(); @@ -306,7 +302,6 @@ namespace PdfWriter FT_Library m_pFreeTypeLibrary; bool m_bPDFAConformance; std::wstring m_wsDocumentID; - std::wstring m_wsFilePath; CDictObject* m_pAcroForm; CResourcesDict* m_pFieldsResources; std::vector m_vRadioGroups; diff --git a/PdfFile/SrcWriter/Field.cpp b/PdfFile/SrcWriter/Field.cpp index ba50565fb4..9b78b7c1cd 100644 --- a/PdfFile/SrcWriter/Field.cpp +++ b/PdfFile/SrcWriter/Field.cpp @@ -53,6 +53,261 @@ namespace PdfWriter { + + void AdjustLineEndpoint(ELineEndType nType, double x, double y, double dx, double dy, double w, double& tx, double& ty) + { + tx = x; + ty = y; + + switch (nType) + { + case ELineEndType::ClosedArrow: + case ELineEndType::OpenArrow: + case ELineEndType::Diamond: + { + tx += w * dx; + if ((dx > 0.001 && dy > 0) || (dx < -0.001 && dy < 0)) + ty += w * dy; + break; + } + case ELineEndType::Square: + case ELineEndType::Circle: + { + if ((dx > -0.02 && dy < 0.02) || (dx < 0.02 && dy > -0.02)) + tx += w * dx; + break; + } + case ELineEndType::Slash: + case ELineEndType::Butt: + case ELineEndType::ROpenArrow: + case ELineEndType::RClosedArrow: + case ELineEndType::None: + default: + break; + } + } + void StreamWriteCM(CStream* pStream, double m11, double m12, double m21, double m22, double tx, double ty) + { + pStream->WriteReal(m11); + pStream->WriteChar(' '); + pStream->WriteReal(m12); + pStream->WriteChar(' '); + pStream->WriteReal(m21); + pStream->WriteChar(' '); + pStream->WriteReal(m22); + pStream->WriteChar(' '); + pStream->WriteReal(tx); + pStream->WriteChar(' '); + pStream->WriteReal(ty); + pStream->WriteStr(" cm\012"); + } + void StreamWriteXYMove(CStream* pStream, double x, double y) + { + pStream->WriteReal(x); + pStream->WriteChar(' '); + pStream->WriteReal(y); + pStream->WriteStr(" m\012"); + } + void StreamWriteXYLine(CStream* pStream, double x, double y) + { + pStream->WriteReal(x); + pStream->WriteChar(' '); + pStream->WriteReal(y); + pStream->WriteStr(" l\012"); + } + void StreamWriteXYCurve(CStream* pStream, double x1, double y1, double x2, double y2, double x3, double y3) + { + pStream->WriteReal(x1); + pStream->WriteChar(' '); + pStream->WriteReal(y1); + pStream->WriteChar(' '); + pStream->WriteReal(x2); + pStream->WriteChar(' '); + pStream->WriteReal(y2); + pStream->WriteChar(' '); + pStream->WriteReal(x3); + pStream->WriteChar(' '); + pStream->WriteReal(y3); + pStream->WriteStr(" c\012"); + } + void StreamWriteRect(CStream* pStream, double x1, double y1, double x2, double y2) + { + pStream->WriteReal(x1); + pStream->WriteChar(' '); + pStream->WriteReal(y1); + pStream->WriteChar(' '); + pStream->WriteReal(x2); + pStream->WriteChar(' '); + pStream->WriteReal(y2); + pStream->WriteStr(" re\012"); + } + void StreamWriteCircle(CStream* pStream, double cx, double cy, double r) + { + double bezierCircle = 0.55228475 * r; + StreamWriteXYMove(pStream, cx + r, cy); + StreamWriteXYCurve(pStream, cx + r, cy + bezierCircle, cx + bezierCircle, cy + r, cx, cy + r); + StreamWriteXYCurve(pStream, cx - bezierCircle, cy + r, cx - r, cy + bezierCircle, cx - r, cy); + StreamWriteXYCurve(pStream, cx - r, cy - bezierCircle, cx - bezierCircle, cy - r, cx, cy - r); + StreamWriteXYCurve(pStream, cx + bezierCircle, cy - r, cx + r, cy - bezierCircle, cx + r, cy); + } + void DrawArrow(CStream* pStream, ELineEndType nType, double x, double y, double dx, double dy, double w) + { + double lineEndSize1 = 3, pi = 3.14159265358979323846; + switch (nType) + { + case ELineEndType::Butt: + { + w *= lineEndSize1; + StreamWriteXYMove(pStream, x + w * dy, y - w * dx); + StreamWriteXYLine(pStream, x - w * dy, y + w * dx); + pStream->WriteStr("S\012"); + break; + } + case ELineEndType::Circle: + { + StreamWriteCircle(pStream, x, y, w * lineEndSize1); + pStream->WriteStr("h\012B\012"); + break; + } + case ELineEndType::Diamond: + { + w *= lineEndSize1; + StreamWriteXYMove(pStream, x - w, y); + StreamWriteXYLine(pStream, x, y + w); + StreamWriteXYLine(pStream, x + w, y); + StreamWriteXYLine(pStream, x, y - w); + pStream->WriteStr("b\012"); + break; + } + case ELineEndType::OpenArrow: + case ELineEndType::ClosedArrow: + { + w *= lineEndSize1 * lineEndSize1; + double d32 = pi * 32.0 / 180.0; + double d28 = pi * 28.0 / 180.0; + if ((dx > 0.001 && dy < 0) || (dx < -0.001 && dy > 0)) + { + StreamWriteXYMove(pStream, x + w * cos(d32) * dx + w * sin(d32) * dy, y + w * cos(d32) * dy - w * sin(d32) * dx); + StreamWriteXYLine(pStream, x, y); + StreamWriteXYLine(pStream, x + w * cos(d28) * dx - w * sin(d28) * dy, y + w * cos(d28) * dy + w * sin(d28) * dx); + } + else + { + double dCos = w * cos(pi / 6.0); + double dSin = w * sin(pi / 6.0); + + StreamWriteXYMove(pStream, x + dCos * dx + dSin * dy, y + dCos * dy - dSin * dx); + StreamWriteXYLine(pStream, x, y); + StreamWriteXYLine(pStream, x + dCos * dx - dSin * dy, y + dCos * dy + dSin * dx); + } + pStream->WriteStr(nType == ELineEndType::OpenArrow ? "S\012" : "b\012"); + break; + } + case ELineEndType::ROpenArrow: + case ELineEndType::RClosedArrow: + { + x -= cos(pi / 18.0) * dx * w; + y -= cos(pi / 18.0) * dy * w; + w *= lineEndSize1 * lineEndSize1; + double dCos = w * cos(pi / 6.0); + double dSin = w * sin(pi / 6.0); + StreamWriteXYMove(pStream, x - dCos * dx + dSin * dy, y - dCos * dy - dSin * dx); + StreamWriteXYLine(pStream, x, y); + StreamWriteXYLine(pStream, x - dCos * dx - dSin * dy, y - dCos * dy + dSin * dx); + pStream->WriteStr(nType == ELineEndType::ROpenArrow ? "S\012" : "b\012"); + break; + } + case ELineEndType::Slash: + { + w *= lineEndSize1 * lineEndSize1; + double dCos = w * cos(pi / 6.0); + double dSin = w * sin(pi / 6.0); + StreamWriteXYMove(pStream, x + dCos * dy - dSin * dx, y - dCos * dx - dSin * dy); + StreamWriteXYLine(pStream, x - dCos * dy + dSin * dx, y + dCos * dx + dSin * dy); + pStream->WriteStr("S\012"); + break; + } + case ELineEndType::Square: + { + w *= lineEndSize1; + pStream->WriteReal(x - w); + pStream->WriteChar(' '); + pStream->WriteReal(y - w); + pStream->WriteChar(' '); + pStream->WriteReal(w * 2); + pStream->WriteChar(' '); + pStream->WriteReal(w * 2); + pStream->WriteStr(" re\012"); + pStream->WriteStr("B\012"); + break; + } + case ELineEndType::None: + default: + { + break; + } + } + } + void DrawLineArrow(CStream* pStream, double dBorderSize, double x1, double y1, double x2, double y2, ELineEndType nLE1, ELineEndType nLE2, double dLL = 0, double dLLO = 0, double dLLE = 0) + { + double dDX = x2 - x1; + double dDY = y2 - y1; + double dLen = sqrt(dDX * dDX + dDY * dDY); + if (dLen > 0) + { + dDX /= dLen; + dDY /= dLen; + } + + double lx1, ly1, lx2, ly2; + double ax1, ay1, ax2, ay2; + double bx1, by1, bx2, by2; + if (dLL != 0) + { + ax1 = x1 + dLLO * dDY; + ay1 = y1 - dLLO * dDX; + lx1 = ax1 + dLL * dDY; + ly1 = ay1 - dLL * dDX; + bx1 = lx1 + dLLE * dDY; + by1 = ly1 - dLLE * dDX; + ax2 = x2 + dLLO * dDY; + ay2 = y2 - dLLO * dDX; + lx2 = ax2 + dLL * dDY; + ly2 = ay2 - dLL * dDX; + bx2 = lx2 + dLLE * dDY; + by2 = ly2 - dLLE * dDX; + } + else + { + lx1 = x1; + ly1 = y1; + lx2 = x2; + ly2 = y2; + ax1 = ay1 = ax2 = ay2 = 0; + bx1 = by1 = bx2 = by2 = 0; + } + + double tx1, ty1, tx2, ty2; + AdjustLineEndpoint(nLE1, lx1, ly1, dDX, dDY, dBorderSize, tx1, ty1); + AdjustLineEndpoint(nLE2, lx2, ly2, -dDX, -dDY, dBorderSize, tx2, ty2); + + if (dLL) + { + StreamWriteXYMove(pStream, ax1, ay1); + StreamWriteXYLine(pStream, bx1, by1); + + StreamWriteXYMove(pStream, ax2, ay2); + StreamWriteXYLine(pStream, bx2, by2); + } + + StreamWriteXYMove(pStream, tx1, ty1); + StreamWriteXYLine(pStream, tx2, ty2); + pStream->WriteStr("S\012"); + + DrawArrow(pStream, nLE1, tx1, ty1, dDX, dDY, dBorderSize); + DrawArrow(pStream, nLE2, tx2, ty2, -dDX, -dDY, dBorderSize); + } + //---------------------------------------------------------------------------------------- // CFieldBase //---------------------------------------------------------------------------------------- @@ -1591,7 +1846,6 @@ namespace PdfWriter CCheckBoxAnnotAppearance::CCheckBoxAnnotAppearance(CXref* pXref, CFieldBase* pField, const char* sYesName) { m_pXref = pXref; - m_pField = pField; m_pYesN = new CAnnotAppearanceObject(pXref, pField); m_pOffN = new CAnnotAppearanceObject(pXref, pField); @@ -1608,6 +1862,25 @@ namespace PdfWriter pDictD->Add(sYesName ? sYesName : "Yes", m_pYesD); pDictD->Add("Off", m_pOffD); } + CCheckBoxAnnotAppearance::CCheckBoxAnnotAppearance(CXref* pXref, CAnnotation* pAnnot, const char* sYesName) + { + m_pXref = pXref; + + m_pYesN = new CAnnotAppearanceObject(pXref, pAnnot); + m_pOffN = new CAnnotAppearanceObject(pXref, pAnnot); + m_pYesD = new CAnnotAppearanceObject(pXref, pAnnot); + m_pOffD = new CAnnotAppearanceObject(pXref, pAnnot); + + CDictObject* pDictN = new CDictObject(); + Add("N", pDictN); + pDictN->Add(sYesName ? sYesName : "Yes", m_pYesN); + pDictN->Add("Off", m_pOffN); + + CDictObject* pDictD = new CDictObject(); + Add("D", pDictD); + pDictD->Add(sYesName ? sYesName : "Yes", m_pYesD); + pDictD->Add("Off", m_pOffD); + } CAnnotAppearanceObject* CCheckBoxAnnotAppearance::GetYesN() { return m_pYesN; @@ -1757,7 +2030,7 @@ namespace PdfWriter BYTE nType = 0; if (pAnnot) { - nType = pAnnot->GetBorderType(); + nType = (BYTE)pAnnot->GetBorderType(); switch (nType) { case 1: // Beveled @@ -1979,7 +2252,7 @@ namespace PdfWriter dBorderSize = pAnnot->GetBorderWidth(); dBorderSizeStyle = dBorderSize; - if (pAnnot->GetBorderType() == 1 || pAnnot->GetBorderType() == 3) + if (pAnnot->GetBorderType() == EBorderType::Beveled || pAnnot->GetBorderType() == EBorderType::Inset) dBorderSizeStyle *= 2; } @@ -1993,7 +2266,7 @@ namespace PdfWriter BYTE nType = 0; if (pAnnot) { - nType = pAnnot->GetBorderType(); + nType = (BYTE)pAnnot->GetBorderType(); switch (nType) { case 1: // Beveled @@ -2242,8 +2515,8 @@ namespace PdfWriter m_pStream->WriteStr("q\012"); double dBorderSize = pAnnot->GetBorderWidth(); - BYTE nType = pAnnot->GetBorderType(); - if (nType == 1 || nType == 3) + EBorderType nType = pAnnot->GetBorderType(); + if (nType == EBorderType::Beveled || nType == EBorderType::Inset) dBorderSize *= 2; if (pAnnot->GetWidgetType() == WidgetPushbutton && !((CPushButtonWidget*)pAnnot)->GetRespectBorder()) @@ -2309,8 +2582,8 @@ namespace PdfWriter double dHeight = fabs(oRect.fBottom - oRect.fTop); double dBorderSize = pAnnot->GetBorderWidth(); - BYTE nType = pAnnot->GetBorderType(); - if (nType == 1 || nType == 3) + EBorderType nType = pAnnot->GetBorderType(); + if (nType == EBorderType::Beveled || nType == EBorderType::Inset) dBorderSize *= 2; m_pStream->WriteReal(2 * dBorderSize); @@ -2371,14 +2644,14 @@ namespace PdfWriter m_pStream->WriteStr("q\012"); double dBorderSize = pAnnot->GetBorderWidth(); - BYTE nType = pAnnot->GetBorderType(); + EBorderType nType = pAnnot->GetBorderType(); switch (nType) { - case 1: // Beveled - case 3: // Inset + case EBorderType::Beveled: + case EBorderType::Inset: { - m_pStream->WriteStr(nType == 1 ? "1 g\012" : "0.501953 g\012"); + m_pStream->WriteStr(nType == EBorderType::Beveled ? "1 g\012" : "0.501953 g\012"); m_pStream->WriteReal(dBorderSize); m_pStream->WriteChar(' '); @@ -2412,7 +2685,7 @@ namespace PdfWriter m_pStream->WriteStr("f\012"); - if (nType == 1 && pAnnot->HaveBG()) + if (nType == EBorderType::Beveled && pAnnot->HaveBG()) { m_pStream->WriteStr(pAnnot->GetBGforAP(-0.25).c_str()); m_pStream->WriteStr("\012"); @@ -2453,7 +2726,7 @@ namespace PdfWriter m_pStream->WriteStr("f\012"); break; } - case 2: // Dashed + case EBorderType::Dashed: { m_pStream->WriteStr(pAnnot->GetBorderDash().c_str()); break; @@ -2466,7 +2739,7 @@ namespace PdfWriter m_pStream->WriteReal(dBorderSize); m_pStream->WriteStr(" w\0120 j\0120 J\012"); - if (nType == 4) // Underline + if (nType == EBorderType::Underline) { m_pStream->WriteInt(0); m_pStream->WriteChar(' '); @@ -2844,4 +3117,351 @@ namespace PdfWriter m_pStream->WriteStr(sColor.c_str()); m_pStream->WriteStr(" 0 G 0 i 0.59 w 4 M 1 j 0 J [] 0 d 1 0 0 1 2.8335 1.7627 cm 0 0 m -2.74 15.16 l 12.345 12.389 l 9.458 9.493 l 14.027 4.91 l 7.532 -1.607 l 2.964 2.975 l b"); } + void CAnnotAppearanceObject::DrawLine() + { + AddBBox(m_pAnnot->GetRect().fLeft, m_pAnnot->GetRect().fBottom, m_pAnnot->GetRect().fRight, m_pAnnot->GetRect().fTop); + AddMatrix(1, 0, 0, 1, -m_pAnnot->GetRect().fLeft, -m_pAnnot->GetRect().fBottom); + + if (m_pAnnot->GetBorderType() == EBorderType::Dashed) + m_pStream->WriteStr(m_pAnnot->GetBorderDash().c_str()); + + double dBorderSize = m_pAnnot->GetBorderWidth(); + m_pStream->WriteReal(dBorderSize); + m_pStream->WriteStr(" w\012"); + + m_pStream->WriteStr(m_pAnnot->GetColorName("IC", false).c_str()); + + m_pStream->WriteStr(m_pAnnot->GetColorName("C", true).c_str()); + + CObjectBase* pObj = m_pAnnot->Get("CA"); + if (pObj && pObj->GetType() == object_type_REAL) + { + float dAlpha = ((CRealObject*)pObj)->Get(); + if (dAlpha != 1) + { + CExtGrState* pExtGrState = m_pAnnot->GetDocument()->GetExtGState(dAlpha, dAlpha); + const char* sExtGrStateName = m_pAnnot->GetDocument()->GetFieldsResources()->GetExtGrStateName(pExtGrState); + if (sExtGrStateName) + { + m_pStream->WriteEscapeName(sExtGrStateName); + m_pStream->WriteStr(" gs\012"); + } + } + } + + double dLL = 0, dLLE = 0, dLLO = 0; + pObj = m_pAnnot->Get("LL"); + if (pObj && pObj->GetType() == object_type_REAL) + dLL = ((CRealObject*)pObj)->Get(); + pObj = m_pAnnot->Get("LLE"); + if (pObj && pObj->GetType() == object_type_REAL) + dLLE = ((CRealObject*)pObj)->Get(); + pObj = m_pAnnot->Get("LLO"); + if (pObj && pObj->GetType() == object_type_REAL) + dLLO = ((CRealObject*)pObj)->Get(); + + CLineAnnotation* pAnnot = (CLineAnnotation*)m_pAnnot; + DrawLineArrow(m_pStream, dBorderSize, pAnnot->dL[0], pAnnot->dL[1], pAnnot->dL[2], pAnnot->dL[3], pAnnot->m_nLE1, pAnnot->m_nLE2, dLL, dLLE, dLLO); + } + void CAnnotAppearanceObject::DrawCheckBoxCircle(bool bSet, bool bN) + { + CCheckBoxWidget* pAnnot = dynamic_cast(m_pAnnot); + if (!pAnnot) + return; + + double dBorder = 1; + EBorderType nBorderType = EBorderType::Inset; + if (m_pAnnot->HaveBorder()) + { + dBorder = m_pAnnot->GetBorderWidth(); + nBorderType = m_pAnnot->GetBorderType(); + } + double dW = m_pAnnot->GetRect().fRight - m_pAnnot->GetRect().fLeft; + double dH = std::abs(m_pAnnot->GetRect().fBottom - m_pAnnot->GetRect().fTop); + double dCX = dW / 2.0, dCY = dH / 2.0; + double dR = std::min(dW, dH) / 2.0; + + // Задний фон + std::string sBG; + if (!bN && nBorderType != EBorderType::Beveled) + { + sBG = pAnnot->GetBGforAP(); + if (sBG == "1 g") + sBG = "0.749023 -0.250977 -0.250977 rg"; + else if (sBG.empty()) + sBG = "0.749023 g"; + else + sBG = pAnnot->GetBGforAP(-0.250977); + } + else + sBG = pAnnot->GetBGforAP(); + if (!sBG.empty()) + { + m_pStream->WriteStr(sBG.c_str()); + m_pStream->WriteStr("\012q\012"); + m_pStream->WriteStr("1 0 0 1 "); + m_pStream->WriteReal(dCX); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dCY); + m_pStream->WriteStr(" cm\012"); + StreamWriteCircle(m_pStream, 0, 0, dR); + m_pStream->WriteStr("f\012Q\012"); + } + + // Граница + if (dBorder != 1) + { + m_pStream->WriteReal(dBorder); + m_pStream->WriteStr(" w\012"); + } + if (nBorderType == EBorderType::Dashed) + m_pStream->WriteStr(m_pAnnot->GetBorderDash().c_str()); + m_pStream->WriteStr(pAnnot->GetBCforAP().c_str()); + m_pStream->WriteStr("\012q\012"); + m_pStream->WriteStr("1 0 0 1 "); + m_pStream->WriteReal(dCX); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dCY); + m_pStream->WriteStr(" cm\012"); + + StreamWriteCircle(m_pStream, 0, 0, dR - dBorder / 2.0); + m_pStream->WriteStr("s\012Q\012"); + + if (nBorderType == EBorderType::Beveled || nBorderType == EBorderType::Inset) + { + double ca = cos(45.0 / 180.0 * M_PI); + double cx = 0, cy = 0, r = dR - dBorder * 1.5; + double bezierCircle = 0.55228475 * r; + + if (nBorderType == EBorderType::Inset) + m_pStream->WriteStr(bN ? "0.501953 G" : "0 G"); + else // Beveled + m_pStream->WriteStr(bN ? "1 G" : pAnnot->GetBGforAP(-0.250977, true).c_str()); + + m_pStream->WriteStr("\012q\012"); + StreamWriteCM(m_pStream, ca, ca, -ca, ca, dCX, dCY); + StreamWriteXYMove(m_pStream, cx + r, cy); + StreamWriteXYCurve(m_pStream, cx + r, cy + bezierCircle, cx + bezierCircle, cy + r, cx, cy + r); + StreamWriteXYCurve(m_pStream, cx - bezierCircle, cy + r, cx - r, cy + bezierCircle, cx - r, cy); + m_pStream->WriteStr("S\012Q\012"); + + if (nBorderType == EBorderType::Inset) + m_pStream->WriteStr(bN ? "0.75293 G" : "1 G"); + else // Beveled + m_pStream->WriteStr(bN ? pAnnot->GetBGforAP(-0.250977, true).c_str() : "1 G"); + + m_pStream->WriteStr("\012q\012"); + StreamWriteCM(m_pStream, ca, ca, -ca, ca, dCX, dCY); + StreamWriteXYMove(m_pStream, cx - r, cy); + StreamWriteXYCurve(m_pStream, cx - r, cy - bezierCircle, cx - bezierCircle, cy - r, cx, cy - r); + StreamWriteXYCurve(m_pStream, cx + bezierCircle, cy - r, cx + r, cy - bezierCircle, cx + r, cy); + m_pStream->WriteStr("S\012Q\012"); + } + + // Установлен + if (!bSet) + return; + double dShift = dBorder / 2.0; + if (nBorderType == EBorderType::Beveled || nBorderType == EBorderType::Inset) + dShift *= 2.0; + m_pStream->WriteStr("0 g\012q\012"); + m_pStream->WriteStr("1 0 0 1 "); + m_pStream->WriteReal(dCX); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dCY); + m_pStream->WriteStr(" cm\012"); + StreamWriteCircle(m_pStream, 0, 0, dR / 2.0 - dShift); + m_pStream->WriteStr("f\012Q\012"); + } + void CAnnotAppearanceObject::DrawCheckBoxSquare(bool bSet, bool bN) + { + CCheckBoxWidget* pAnnot = dynamic_cast(m_pAnnot); + if (!pAnnot) + return; + + double dBorder = 1; + EBorderType nBorderType = EBorderType::Inset; + if (m_pAnnot->HaveBorder()) + { + dBorder = m_pAnnot->GetBorderWidth(); + nBorderType = m_pAnnot->GetBorderType(); + } + double dW = m_pAnnot->GetRect().fRight - m_pAnnot->GetRect().fLeft; + double dH = std::abs(m_pAnnot->GetRect().fBottom - m_pAnnot->GetRect().fTop); + + // Задний фон + m_pStream->WriteStr("q\012"); + m_pStream->WriteStr(pAnnot->GetBGforAP(!bN && nBorderType != EBorderType::Beveled ? -0.250977 : 0).c_str()); + m_pStream->WriteStr("\012"); + StreamWriteRect(m_pStream, 0, 0, dW, dH); + m_pStream->WriteStr("f\012"); + + // Граница + if (nBorderType == EBorderType::Beveled || nBorderType == EBorderType::Inset) + { + if (nBorderType == EBorderType::Inset) + m_pStream->WriteStr(bN ? "0.501953 g" : "0 g"); + else // Beveled + m_pStream->WriteStr(bN ? "1 g" : pAnnot->GetBGforAP(-0.250977).c_str()); + m_pStream->WriteStr("\012"); + + StreamWriteXYMove(m_pStream, dBorder, dBorder); + StreamWriteXYLine(m_pStream, dBorder, dH - dBorder); + StreamWriteXYLine(m_pStream, dW - dBorder, dH - dBorder); + StreamWriteXYLine(m_pStream, dW - dBorder * 2.0, dH - dBorder * 2.0); + StreamWriteXYLine(m_pStream, dBorder * 2.0, dH - dBorder * 2.0); + StreamWriteXYLine(m_pStream, dBorder * 2.0, dBorder * 2.0); + m_pStream->WriteStr("f\012"); + + if (nBorderType == EBorderType::Inset) + m_pStream->WriteStr(bN ? "0.75293 g" : "1 g"); + else // Beveled + m_pStream->WriteStr(bN ? pAnnot->GetBGforAP(-0.250977).c_str() : "1 g"); + m_pStream->WriteStr("\012"); + + StreamWriteXYMove(m_pStream, dW - dBorder, dH - dBorder); + StreamWriteXYLine(m_pStream, dW - dBorder, dBorder); + StreamWriteXYLine(m_pStream, dBorder, dBorder); + StreamWriteXYLine(m_pStream, dBorder * 2.0, dBorder * 2.0); + StreamWriteXYLine(m_pStream, dW - dBorder * 2.0, dBorder * 2.0); + StreamWriteXYLine(m_pStream, dW - dBorder * 2.0, dH - dBorder * 2.0); + m_pStream->WriteStr("f\012"); + } + + if (dBorder != 1) + { + m_pStream->WriteReal(dBorder); + m_pStream->WriteStr(" w\012"); + } + if (nBorderType == EBorderType::Dashed) + m_pStream->WriteStr(m_pAnnot->GetBorderDash().c_str()); + m_pStream->WriteStr(pAnnot->GetBCforAP().c_str()); + m_pStream->WriteStr("\012"); + + if (nBorderType == EBorderType::Underline) + { + StreamWriteXYMove(m_pStream, 0, dBorder / 2.0); + StreamWriteXYLine(m_pStream, dW, dBorder / 2.0); + } + else + StreamWriteRect(m_pStream, dBorder / 2.0, dBorder / 2.0, dW - dBorder, dH - dBorder); + m_pStream->WriteStr("s\012Q\012"); + + // Установлен + if (!bSet) + return; + double dDiff = std::abs(dW - dH) / 2.0; + double dShift = dBorder; + if (nBorderType == EBorderType::Beveled || nBorderType == EBorderType::Inset) + dShift *= 2; + bool bW = dW > dH; + double dCX = dW / 2.0, dCY = dH / 2.0; + double dC = std::min(dW, dH) / 2.0; + + ECheckBoxStyle nStyle = pAnnot->GetStyle(); + switch (nStyle) + { + case ECheckBoxStyle::Check: + { + m_pStream->WriteStr("0 g\012q\012"); + m_pStream->WriteStr("1 0 0 1 "); + m_pStream->WriteReal((bW ? dDiff : 0) + dShift); + m_pStream->WriteChar(' '); + m_pStream->WriteReal((bW ? 0 : dDiff) + dShift); + m_pStream->WriteStr(" cm\012"); + + double dScale = (std::min(dW, dH) - dShift * 2.0) / 20.0; + StreamWriteXYMove(m_pStream, 5.2381 * dScale, 11.2 * dScale); + StreamWriteXYLine(m_pStream, 4 * dScale, 8.2 * dScale); + StreamWriteXYLine(m_pStream, 7.71429 * dScale, 4 * dScale); + StreamWriteXYCurve(m_pStream, 12.0476 * dScale, 10.6 * dScale, 13.2857 * dScale, 11.8 * dScale, 17 * dScale, 16 * dScale); + StreamWriteXYCurve(m_pStream, 14.5238 * dScale, 16 * dScale, 9.77778 * dScale, 11.2 * dScale, 7.71429 * dScale, 8.2 * dScale); + StreamWriteXYLine(m_pStream, 5.2381 * dScale, 11.2 * dScale); + + m_pStream->WriteStr("f\012Q\012"); + break; + } + case ECheckBoxStyle::Cross: + { + double dCross = dBorder; + if (nBorderType == EBorderType::Beveled || nBorderType == EBorderType::Inset) + dCross *= 2; + m_pStream->WriteStr("q\012"); + StreamWriteRect(m_pStream, dCross, dCross, dW - dCross, dH - dCross); + m_pStream->WriteStr("W\012n\0120 G\0121 w\012"); + + double x1 = dShift + 1 + (bW ? dDiff : 0); + double y1 = dShift + 1 + (bW ? 0 : dDiff); + double x2 = dW - dShift - 1 - (bW ? dDiff : 0); + double y2 = dH - dShift - 1 - (bW ? 0 : dDiff); + StreamWriteXYMove(m_pStream, x1, y2); + StreamWriteXYLine(m_pStream, x2, y1); + StreamWriteXYMove(m_pStream, x2, y2); + StreamWriteXYLine(m_pStream, x1, y1); + + m_pStream->WriteStr("s\012Q\012"); + break; + } + case ECheckBoxStyle::Diamond: + { + double dSq = dC - dShift * 2.0 - 1; + m_pStream->WriteStr("0 g\012q\012"); + m_pStream->WriteStr("1 0 0 1 "); + m_pStream->WriteReal(dCX); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dCY); + m_pStream->WriteStr(" cm\012"); + StreamWriteXYMove(m_pStream, -dSq, 0); + StreamWriteXYLine(m_pStream, 0, dSq); + StreamWriteXYLine(m_pStream, dSq, 0); + StreamWriteXYLine(m_pStream, 0, -dSq); + m_pStream->WriteStr("f\012Q\012"); + break; + } + case ECheckBoxStyle::Circle: + { + double dR = dC - dShift * 2.0 - 1; + + m_pStream->WriteStr("0 g\012q\012"); + m_pStream->WriteStr("1 0 0 1 "); + m_pStream->WriteReal(dCX); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dCY); + m_pStream->WriteStr(" cm\012"); + StreamWriteCircle(m_pStream, 0, 0, dR); + m_pStream->WriteStr("f\012Q\012"); + break; + } + case ECheckBoxStyle::Star: + { + double dROuter = dC - dShift * 2.0 - 1; + double dRInner = dROuter / 2.5; + int nPoints = 5; + + m_pStream->WriteStr("0 g\012q\012"); + for (int i = 0; i < nPoints * 2; ++i) + { + double dR = i % 2 == 0 ? dROuter : dRInner; + double dAngle = M_PI / nPoints * i; + double dX = dCX - dR * std::sin(dAngle); + double dY = dCY + dR * std::cos(dAngle); + if (i == 0) + StreamWriteXYMove(m_pStream, dX, dY); + else + StreamWriteXYLine(m_pStream, dX, dY); + } + m_pStream->WriteStr("f\012Q\012"); + break; + } + case ECheckBoxStyle::Square: + { + double dSq = std::min(dW, dH) * 2.0 / 3.0 - dShift * 2.0 - 1; + + m_pStream->WriteStr("0 g\012q\012"); + StreamWriteRect(m_pStream, dCX - dSq / 2.0, dCY - dSq / 2.0, dSq, dSq); + m_pStream->WriteStr("f\012Q\012"); + break; + } + } + } } diff --git a/PdfFile/SrcWriter/Field.h b/PdfFile/SrcWriter/Field.h index 5c11b57be4..2ba79b83df 100644 --- a/PdfFile/SrcWriter/Field.h +++ b/PdfFile/SrcWriter/Field.h @@ -363,6 +363,7 @@ namespace PdfWriter { public: CCheckBoxAnnotAppearance(CXref* pXref, CFieldBase* pField, const char* sYesName = NULL); + CCheckBoxAnnotAppearance(CXref* pXref, CAnnotation* pAnnot, const char* sYesName = NULL); CAnnotAppearanceObject* GetYesN(); CAnnotAppearanceObject* GetOffN(); @@ -372,7 +373,6 @@ namespace PdfWriter private: CXref* m_pXref; - CFieldBase* m_pField; CAnnotAppearanceObject* m_pYesN; CAnnotAppearanceObject* m_pOffN; CAnnotAppearanceObject* m_pYesD; @@ -418,6 +418,11 @@ namespace PdfWriter void DrawTextUpArrow(const std::string& sColor); void DrawTextUpLeftArrow(const std::string& sColor); + void DrawLine(); + + void DrawCheckBoxCircle(bool bSet, bool bN); + void DrawCheckBoxSquare(bool bSet, bool bN); + CStream* GetStream() const { return m_pStream; } CFontDict* GetFont() { return m_pFont; } diff --git a/PdfFile/SrcWriter/Objects.cpp b/PdfFile/SrcWriter/Objects.cpp index 1522834b98..dd178ac5ac 100644 --- a/PdfFile/SrcWriter/Objects.cpp +++ b/PdfFile/SrcWriter/Objects.cpp @@ -167,18 +167,18 @@ namespace PdfWriter //---------------------------------------------------------------------------------------- // CBinaryObject //---------------------------------------------------------------------------------------- - CBinaryObject::CBinaryObject(const BYTE* pValue, unsigned int unLen) + CBinaryObject::CBinaryObject(BYTE* pValue, unsigned int unLen, bool bCopy) { m_pValue = NULL; m_unLen = 0; - Set(pValue, unLen); + Set(pValue, unLen, bCopy); } CBinaryObject::~CBinaryObject() { if (m_pValue) delete[] m_pValue; } - void CBinaryObject::Set(const BYTE* pValue, unsigned int unLen) + void CBinaryObject::Set(BYTE* pValue, unsigned int unLen, bool bCopy) { unLen = std::min((unsigned int)LIMIT_MAX_STRING_LEN, unLen); if (m_pValue) @@ -192,9 +192,13 @@ namespace PdfWriter return; m_unLen = unLen; - m_pValue = new BYTE[unLen]; - - MemCpy(m_pValue, pValue, unLen); + if (bCopy) + { + m_pValue = new BYTE[unLen]; + MemCpy(m_pValue, pValue, unLen); + } + else + m_pValue = pValue; } //---------------------------------------------------------------------------------------- // CProxyObject @@ -542,7 +546,7 @@ namespace PdfWriter if (m_pStream) delete m_pStream; } - CObjectBase* CDictObject::Get(const std::string& sKey) const + CObjectBase* CDictObject::Get(const std::string& sKey) const { std::map::const_iterator oIter = m_mList.find(sKey); if (m_mList.end() != oIter) @@ -615,7 +619,7 @@ namespace PdfWriter { Add(sKey, new CBoolObject(bBool)); } - const char* CDictObject::GetKey(const CObjectBase* pObject) + const char* CDictObject::GetKey(const CObjectBase* pObject) { for (auto const &oIter : m_mList) { @@ -669,7 +673,7 @@ namespace PdfWriter pXref->Add((CObjectBase*)this); pXref->Add((CObjectBase*)pLength); - Add("Length", (CObjectBase*)pLength); + Add("Length", pLength); } m_pStream = pStream; @@ -923,11 +927,19 @@ namespace PdfWriter pTrailer->Add("Size", unMaxObjId + 1); if (m_pPrev && pPrev->m_unAddr) pTrailer->Add("Prev", pPrev->m_unAddr); + int nStreamOffset = pStream->Tell(); + int nOffsetSize = 1; + if (nStreamOffset > 1 << 24) + nOffsetSize = 4; + else if (nStreamOffset > 1 << 16) + nOffsetSize = 3; + else if (nStreamOffset > 1 << 8) + nOffsetSize = 2; CArrayObject* pW = new CArrayObject(); - pTrailer->Add("W", pW); pW->Add(1); - pW->Add(4); + pW->Add(nOffsetSize); pW->Add(2); + pTrailer->Add("W", pW); CArrayObject* pIndex = new CArrayObject(); pTrailer->Add("Index", pIndex); CNumberObject* pLength = new CNumberObject(0); @@ -959,7 +971,6 @@ namespace PdfWriter // Записываем поток pXref = out; - int nStreamOffset = pStream->Tell(); pXref->m_unAddr = nStreamOffset; CStream* pTrailerStream = new CMemoryStream(); unsigned int unEntries = 0, unEntriesSize = 0; @@ -986,10 +997,8 @@ namespace PdfWriter pTrailerStream->WriteChar('\000'); else if (pEntry->nEntryType == IN_USE_ENTRY) pTrailerStream->WriteChar('\001'); - pTrailerStream->WriteChar((unsigned char)(pEntry->unByteOffset >> 24)); - pTrailerStream->WriteChar((unsigned char)(pEntry->unByteOffset >> 16)); - pTrailerStream->WriteChar((unsigned char)(pEntry->unByteOffset >> 8)); - pTrailerStream->WriteChar((unsigned char)(pEntry->unByteOffset)); + for (int i = nOffsetSize - 1; i >= 0; --i) + pTrailerStream->WriteChar((pEntry->unByteOffset >> (8 * i)) & 0xFF); pTrailerStream->WriteChar((unsigned char)(pEntry->unGenNo >> 8)); pTrailerStream->WriteChar((unsigned char)(pEntry->unGenNo)); } @@ -1001,10 +1010,8 @@ namespace PdfWriter pIndex->Add(unEntries); pIndex->Add(unEntriesSize); pTrailerStream->WriteChar('\001'); - pTrailerStream->WriteChar((unsigned char)(nStreamOffset >> 24)); - pTrailerStream->WriteChar((unsigned char)(nStreamOffset >> 16)); - pTrailerStream->WriteChar((unsigned char)(nStreamOffset >> 8)); - pTrailerStream->WriteChar((unsigned char)(nStreamOffset)); + for (int i = nOffsetSize - 1; i >= 0; --i) + pTrailerStream->WriteChar((nStreamOffset >> (8 * i)) & 0xFF); pTrailerStream->WriteChar('\000'); pTrailerStream->WriteChar('\000'); diff --git a/PdfFile/SrcWriter/Objects.h b/PdfFile/SrcWriter/Objects.h index cac33259bc..1c5d9de08a 100644 --- a/PdfFile/SrcWriter/Objects.h +++ b/PdfFile/SrcWriter/Objects.h @@ -338,9 +338,9 @@ namespace PdfWriter class CBinaryObject : public CObjectBase { public: - CBinaryObject(const BYTE* pValue, unsigned int unLen); + CBinaryObject(BYTE* pValue, unsigned int unLen, bool bCopy = true); ~CBinaryObject(); - void Set(const BYTE* pValue, unsigned int unLen); + void Set(BYTE* pValue, unsigned int unLen, bool bCopy = true); BYTE* GetValue() const { return m_pValue; @@ -467,7 +467,7 @@ namespace PdfWriter } void SetFilter(unsigned int unFiler) { - m_unFilter = unFiler; + m_unFilter |= unFiler; } void SetStream(CXref* pXref, CStream* pStream, bool bThis = true); @@ -482,6 +482,7 @@ namespace PdfWriter virtual void WriteToStream(CStream* pStream, CEncrypt* pEncrypt); unsigned int GetSize() { return m_mList.size(); } + std::map GetDict() { return m_mList; } void FromXml(const std::wstring& sXml); protected: diff --git a/PdfFile/SrcWriter/Pages.cpp b/PdfFile/SrcWriter/Pages.cpp index 8b470e79f9..4c4883735c 100644 --- a/PdfFile/SrcWriter/Pages.cpp +++ b/PdfFile/SrcWriter/Pages.cpp @@ -224,7 +224,7 @@ namespace PdfWriter if (pResources) pResources->Fix(); } - void CPageTree::AddPage(CDictObject* pPage) + void CPageTree::AddPage(CPage* pPage) { m_pPages->Add(pPage); (*m_pCount)++; @@ -346,16 +346,9 @@ namespace PdfWriter //---------------------------------------------------------------------------------------- // CPage //---------------------------------------------------------------------------------------- - CPage::CPage(CDocument* pDocument, CXref* pXref) + CPage::CPage(CDocument* pDocument) { Init(pDocument); - if (pXref) - { - AddResource(pXref); - m_pContents = new CArrayObject(); - Add("Contents", m_pContents); - AddContents(pXref); - } } void CPage::Fix() { @@ -373,6 +366,12 @@ namespace PdfWriter m_pContents->Add(pNewContents); Add("Contents", m_pContents); } + else if (pContents->GetType() == object_type_DICT) + { + m_pContents = new CArrayObject(); + m_pContents->Add(pContents); + Add("Contents", m_pContents); + } } else { @@ -1123,8 +1122,8 @@ namespace PdfWriter for (int i = 0; i < pArray->GetCount(); i++) { - CObjectBase* pObj = pArray->Get(i, false); - if (pObj->GetType() == object_type_PROXY && ((CProxyObject*)pObj)->Get()->GetObjId() == nID) + CObjectBase* pObj = pArray->Get(i); + if (pObj->GetObjId() == nID) { CObjectBase* pDelete = pArray->Remove(i); RELEASEOBJECT(pDelete); diff --git a/PdfFile/SrcWriter/Pages.h b/PdfFile/SrcWriter/Pages.h index a264940131..9c3c81a16b 100644 --- a/PdfFile/SrcWriter/Pages.h +++ b/PdfFile/SrcWriter/Pages.h @@ -65,7 +65,7 @@ namespace PdfWriter CPageTree(CXref* pXref); CPageTree(); void Fix(); - void AddPage(CDictObject* pPage); + void AddPage(CPage* pPage); CObjectBase* GetObj(int nPageIndex); CPage* GetPage(int nPageIndex); CObjectBase* RemovePage(int nPageIndex); @@ -93,7 +93,7 @@ namespace PdfWriter class CPage : public CDictObject { public: - CPage(CDocument* pDocument, CXref* pXref = NULL); + CPage(CDocument* pDocument); CPage(CXref* pXref, CPageTree* pParent, CDocument* pDocument); ~CPage(); diff --git a/PdfFile/SrcWriter/Streams.cpp b/PdfFile/SrcWriter/Streams.cpp index e5a873b2b5..3cf2f4da74 100644 --- a/PdfFile/SrcWriter/Streams.cpp +++ b/PdfFile/SrcWriter/Streams.cpp @@ -476,7 +476,7 @@ namespace PdfWriter #ifndef FILTER_FLATE_DECODE_DISABLED - if (unFilter & STREAM_FILTER_FLATE_DECODE) + if ((unFilter & STREAM_FILTER_FLATE_DECODE) && !(unFilter & STREAM_FILTER_ALREADY_DECODE)) return WriteStreamWithDeflate(pStream, pEncrypt); #endif @@ -614,7 +614,7 @@ namespace PdfWriter if (pDict->GetStream()) { unsigned int unFilter = pDict->GetFilter(); - if (STREAM_FILTER_NONE != unFilter) + if (STREAM_FILTER_NONE != unFilter && STREAM_FILTER_ALREADY_DECODE != unFilter) { CArrayObject* pFilter = new CArrayObject(); pDict->Add("Filter", pFilter); @@ -787,6 +787,17 @@ namespace PdfWriter { return m_unSize; } + BYTE* CMemoryStream::GetBuffer() + { + return m_pBuffer; + } + void CMemoryStream::ClearWithoutAttack() + { + m_nBufferSize = 0; + m_pBuffer = NULL; + m_pCur = NULL; + m_unSize = 0; + } void CMemoryStream::Shrink(unsigned int unSize) { if (m_pBuffer) diff --git a/PdfFile/SrcWriter/Streams.h b/PdfFile/SrcWriter/Streams.h index 471bbaa5f2..15f3be69c1 100644 --- a/PdfFile/SrcWriter/Streams.h +++ b/PdfFile/SrcWriter/Streams.h @@ -36,6 +36,7 @@ #include "../../DesktopEditor/common/File.h" #define STREAM_FILTER_NONE 0x0000 +#define STREAM_FILTER_ALREADY_DECODE 0x0001 #define STREAM_FILTER_ASCIIHEX 0x0100 #define STREAM_FILTER_ASCII85 0x0200 #define STREAM_FILTER_FLATE_DECODE 0x0400 @@ -158,6 +159,8 @@ namespace PdfWriter { return StreamMemory; } + BYTE* GetBuffer(); + void ClearWithoutAttack(); private: diff --git a/PdfFile/lib/goo/GString.cc b/PdfFile/lib/goo/GString.cc index 54de35b0a7..67b95603b2 100644 --- a/PdfFile/lib/goo/GString.cc +++ b/PdfFile/lib/goo/GString.cc @@ -134,6 +134,7 @@ GString::GString() { s = NULL; resize(length = 0); s[0] = '\0'; + bBinary = false; } GString::GString(const char *sA) { @@ -142,13 +143,15 @@ GString::GString(const char *sA) { s = NULL; resize(length = n); memcpy(s, sA, n + 1); + bBinary = false; } -GString::GString(const char *sA, int lengthA) { +GString::GString(const char *sA, int lengthA, bool _bBinary) { s = NULL; resize(length = lengthA); memcpy(s, sA, length * sizeof(char)); s[length] = '\0'; + bBinary = _bBinary; } GString::GString(GString *str, int idx, int lengthA) { @@ -156,12 +159,14 @@ GString::GString(GString *str, int idx, int lengthA) { resize(length = lengthA); memcpy(s, str->getCString() + idx, length); s[length] = '\0'; + bBinary = str->bBinary; } GString::GString(GString *str) { s = NULL; resize(length = str->getLength()); memcpy(s, str->getCString(), length + 1); + bBinary = str->bBinary; } GString::GString(GString *str1, GString *str2) { @@ -175,6 +180,7 @@ GString::GString(GString *str1, GString *str2) { resize(length = n1 + n2); memcpy(s, str1->getCString(), n1); memcpy(s + n1, str2->getCString(), n2 + 1); + bBinary = false; } GString *GString::fromInt(int x) { diff --git a/PdfFile/lib/goo/GString.h b/PdfFile/lib/goo/GString.h index 6b342f85ec..3698889827 100644 --- a/PdfFile/lib/goo/GString.h +++ b/PdfFile/lib/goo/GString.h @@ -32,7 +32,7 @@ public: // Create a string from chars at . This string // can contain null characters. - GString(const char *sA, int lengthA); + GString(const char *sA, int lengthA, bool _bBinary = false); // Create a string from chars at in . GString(GString *str, int idx, int lengthA); @@ -120,8 +120,11 @@ public: int cmp(const char *sA); int cmpN(const char *sA, int n); + bool isBinary() { return bBinary; } + private: + bool bBinary; int length; char *s; diff --git a/PdfFile/lib/xpdf/Lexer.cc b/PdfFile/lib/xpdf/Lexer.cc index 0c74dbb04e..2cd97ebf83 100644 --- a/PdfFile/lib/xpdf/Lexer.cc +++ b/PdfFile/lib/xpdf/Lexer.cc @@ -455,7 +455,7 @@ Object *Lexer::getObj(Object *obj) { if (++m == 2) { if (n == tokBufSize) { if (!s) - s = new GString(tokBuf, tokBufSize); + s = new GString(tokBuf, tokBufSize, true); else s->append(tokBuf, tokBufSize); p = tokBuf; @@ -469,7 +469,7 @@ Object *Lexer::getObj(Object *obj) { } } if (!s) - s = new GString(tokBuf, n); + s = new GString(tokBuf, n, true); else s->append(tokBuf, n); if (m == 1) diff --git a/PdfFile/lib/xpdf/TextString.cc b/PdfFile/lib/xpdf/TextString.cc index 8e54a1d547..e223b36edf 100644 --- a/PdfFile/lib/xpdf/TextString.cc +++ b/PdfFile/lib/xpdf/TextString.cc @@ -25,16 +25,19 @@ TextString::TextString() { u = NULL; len = size = 0; + bPDFDocEncoding = true; } TextString::TextString(GString *s) { u = NULL; len = size = 0; + bPDFDocEncoding = true; append(s); } TextString::TextString(TextString *s) { len = size = s->len; + bPDFDocEncoding = s->bPDFDocEncoding; if (len) { u = (Unicode *)gmallocn(size, sizeof(Unicode)); memcpy(u, s->u, len * sizeof(Unicode)); @@ -90,6 +93,7 @@ TextString *TextString::insert(int idx, GString *s) { // look for a UTF-16BE BOM if ((s->getChar(0) & 0xff) == 0xfe && (s->getChar(1) & 0xff) == 0xff) { + bPDFDocEncoding = false; i = 2; n = 0; while (getUTF16BE(s, &i, uBuf + n)) { @@ -109,6 +113,7 @@ TextString *TextString::insert(int idx, GString *s) { // PDF files use it) } else if ((s->getChar(0) & 0xff) == 0xff && (s->getChar(1) & 0xff) == 0xfe) { + bPDFDocEncoding = false; i = 2; n = 0; while (getUTF16LE(s, &i, uBuf + n)) { @@ -127,6 +132,7 @@ TextString *TextString::insert(int idx, GString *s) { } else if ((s->getChar(0) & 0xff) == 0xef && (s->getChar(1) & 0xff) == 0xbb && (s->getChar(2) & 0xff) == 0xbf) { + bPDFDocEncoding = false; i = 3; n = 0; while (getUTF8(s, &i, uBuf + n)) { @@ -143,6 +149,7 @@ TextString *TextString::insert(int idx, GString *s) { // otherwise, use PDFDocEncoding } else { + bPDFDocEncoding = true; n = s->getLength(); expand(n); if (idx < len) { diff --git a/PdfFile/lib/xpdf/TextString.h b/PdfFile/lib/xpdf/TextString.h index c296d7d6d7..c861321868 100644 --- a/PdfFile/lib/xpdf/TextString.h +++ b/PdfFile/lib/xpdf/TextString.h @@ -52,6 +52,7 @@ public: // Get the Unicode characters in the TextString. int getLength() { return len; } Unicode *getUnicode() { return u; } + bool isPDFDocEncoding() { return bPDFDocEncoding; } // Create a PDF text string from a TextString. GString *toPDFTextString(); @@ -63,6 +64,7 @@ private: void expand(int delta); + bool bPDFDocEncoding; Unicode *u; // NB: not null-terminated int len; int size; diff --git a/PdfFile/test/test.cpp b/PdfFile/test/test.cpp index 49e36f3bc8..0b16d4a4de 100644 --- a/PdfFile/test/test.cpp +++ b/PdfFile/test/test.cpp @@ -90,13 +90,13 @@ public: RELEASEOBJECT(oWorker); } - void LoadFromFile() + void LoadFromFile(const std::wstring& _wsSrcFile = L"") { - bool bResult = pdfFile->LoadFromFile(wsSrcFile); + bool bResult = pdfFile->LoadFromFile(_wsSrcFile.empty() ? wsSrcFile : _wsSrcFile); if (!bResult) { std::wstring wsPassword = L"123456"; - bResult = pdfFile->LoadFromFile(wsSrcFile, L"", wsPassword, wsPassword); + bResult = pdfFile->LoadFromFile(_wsSrcFile.empty() ? wsSrcFile : _wsSrcFile, L"", wsPassword, wsPassword); } ASSERT_TRUE(bResult); @@ -350,6 +350,41 @@ TEST_F(CPdfFileTest, VerifySign) RELEASEOBJECT(pCertificate); } +TEST_F(CPdfFileTest, SplitPdf) +{ + GTEST_SKIP(); + + LoadFromFile(); + std::vector arrPages = { 0 }; + BYTE* pFile = pdfFile->SplitPages(arrPages.data(), arrPages.size()); + ASSERT_TRUE(pFile != NULL); + + NSFile::CFileBinary oFile; + std::wstring wsSplitFile = NSFile::GetProcessDirectory() + L"/test_split.pdf"; + if (oFile.CreateFileW(wsSplitFile)) + { + int nLength = pFile[0] | pFile[1] << 8 | pFile[2] << 16 | pFile[3] << 24; + oFile.WriteFile(pFile + 4, nLength); + } + oFile.CloseFile(); + + RELEASEARRAYOBJECTS(pFile); +} + +TEST_F(CPdfFileTest, MergePdf) +{ + GTEST_SKIP(); + + LoadFromFile(); + + ASSERT_TRUE(pdfFile->EditPdf(wsDstFile)); + + std::wstring wsSplitFile = NSFile::GetProcessDirectory() + L"/test_split.pdf"; + pdfFile->MergePages(wsSplitFile, 0, L""); + + pdfFile->Close(); +} + TEST_F(CPdfFileTest, EditPdf) { GTEST_SKIP(); @@ -424,7 +459,7 @@ TEST_F(CPdfFileTest, EditPdfFromBin) // чтение бинарника NSFile::CFileBinary oFile; - ASSERT_TRUE(oFile.OpenFile(NSFile::GetProcessDirectory() + L"/changes0.json")); + ASSERT_TRUE(oFile.OpenFile(NSFile::GetProcessDirectory() + L"/changes.bin")); DWORD dwFileSize = oFile.GetFileSize(); BYTE* pFileContent = new BYTE[dwFileSize]; @@ -440,7 +475,7 @@ TEST_F(CPdfFileTest, EditPdfFromBin) CConvertFromBinParams* pParams = new CConvertFromBinParams(); pParams->m_sMediaDirectory = NSFile::GetProcessDirectory(); - pdfFile->AddToPdfFromBinary(pFileContent, dwReaded, pParams); + pdfFile->AddToPdfFromBinary(pFileContent + 4, dwReaded - 4, pParams); RELEASEOBJECT(pParams); RELEASEARRAYOBJECTS(pFileContent); diff --git a/Test/Applications/x2tTester/x2tTester.cpp b/Test/Applications/x2tTester/x2tTester.cpp index 50fd098819..0b07b91a72 100644 --- a/Test/Applications/x2tTester/x2tTester.cpp +++ b/Test/Applications/x2tTester/x2tTester.cpp @@ -194,6 +194,7 @@ CFormatsList CFormatsList::GetDefaultExts() list.m_documents.push_back(L"odt"); list.m_documents.push_back(L"ott"); list.m_documents.push_back(L"oxps"); + list.m_documents.push_back(L"pages"); list.m_documents.push_back(L"rtf"); list.m_documents.push_back(L"stw"); list.m_documents.push_back(L"sxw"); @@ -205,6 +206,7 @@ CFormatsList CFormatsList::GetDefaultExts() list.m_presentations.push_back(L"dps"); list.m_presentations.push_back(L"dpt"); list.m_presentations.push_back(L"fodp"); + list.m_presentations.push_back(L"key"); list.m_presentations.push_back(L"odp"); list.m_presentations.push_back(L"otp"); list.m_presentations.push_back(L"pot"); @@ -223,6 +225,7 @@ CFormatsList CFormatsList::GetDefaultExts() list.m_spreadsheets.push_back(L"et"); list.m_spreadsheets.push_back(L"ett"); list.m_spreadsheets.push_back(L"fods"); + list.m_spreadsheets.push_back(L"numbers"); list.m_spreadsheets.push_back(L"ods"); list.m_spreadsheets.push_back(L"ots"); list.m_spreadsheets.push_back(L"sxc"); diff --git a/X2tConverter/build/Android/libx2t/src/main/cpp/jni/X2t.cpp b/X2tConverter/build/Android/libx2t/src/main/cpp/jni/X2t.cpp index fa05caa4fc..fa85a68974 100644 --- a/X2tConverter/build/Android/libx2t/src/main/cpp/jni/X2t.cpp +++ b/X2tConverter/build/Android/libx2t/src/main/cpp/jni/X2t.cpp @@ -68,6 +68,7 @@ extern "C" { jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP_FLAT", AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP_FLAT); jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_PRESENTATION_OTP", AVS_OFFICESTUDIO_FILE_PRESENTATION_OTP); jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_PRESENTATION_KEY", AVS_OFFICESTUDIO_FILE_PRESENTATION_KEY); + jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_PRESENTATION_ODG", AVS_OFFICESTUDIO_FILE_PRESENTATION_ODG); jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_SPREADSHEET", AVS_OFFICESTUDIO_FILE_SPREADSHEET); jjniHashMap.put(env, "AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX", AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSX); diff --git a/X2tConverter/src/ASCConverters.cpp b/X2tConverter/src/ASCConverters.cpp index 6b35e25cb8..fada4c3fee 100644 --- a/X2tConverter/src/ASCConverters.cpp +++ b/X2tConverter/src/ASCConverters.cpp @@ -34,6 +34,7 @@ #include "lib/docx.h" #include "lib/xlsx.h" #include "lib/pptx.h" +#include "lib/vsdx.h" #include "lib/doc.h" @@ -1305,7 +1306,9 @@ namespace NExtractTools nRes = ppt2pptx_dir(sFrom, sPptxDir, params, convertParams); } } - else if (AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP == nFormatFrom || AVS_OFFICESTUDIO_FILE_PRESENTATION_OTP == nFormatFrom) + else if ( AVS_OFFICESTUDIO_FILE_PRESENTATION_ODP == nFormatFrom || + AVS_OFFICESTUDIO_FILE_PRESENTATION_OTP == nFormatFrom || + AVS_OFFICESTUDIO_FILE_PRESENTATION_ODG == nFormatFrom) { nRes = odf2oox_dir(sFrom, sPptxDir, params, convertParams); } @@ -1393,7 +1396,7 @@ namespace NExtractTools return nRes; } - // visio + // draw _UINT32 fromVsdxDir(const std::wstring& sFrom, const std::wstring& sTo, int nFormatTo, InputParams& params, ConvertParams& convertParams) { _UINT32 nRes = 0; @@ -1409,6 +1412,18 @@ namespace NExtractTools else nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; } + else if (AVS_OFFICESTUDIO_FILE_OTHER_OOXML == nFormatTo) + { + nRes = dir2zipMscrypt(sFrom, sTo, params, convertParams); + } + else if (AVS_OFFICESTUDIO_FILE_CANVAS_DRAW == nFormatTo) + { + nRes = vsdx_dir2vsdt_bin(sFrom, sTo, params, convertParams); + } + else if (AVS_OFFICESTUDIO_FILE_TEAMLAB_VSDY == nFormatTo) + { + nRes = vsdx_dir2vsdt(sFrom, sTo, params, convertParams); + } else if ((0 != (AVS_OFFICESTUDIO_FILE_IMAGE & nFormatTo)) || AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo) { std::wstring sToRender = convertParams.m_sTempParamOOXMLFile; @@ -1435,6 +1450,57 @@ namespace NExtractTools nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; return nRes; } + _UINT32 fromVsdtBin(const std::wstring& sFrom, const std::wstring& sTo, int nFormatTo, InputParams& params, ConvertParams& convertParams) + { + _UINT32 nRes = 0; + if (AVS_OFFICESTUDIO_FILE_TEAMLAB_VSDY == nFormatTo) + { + std::wstring sFromDir = NSDirectory::GetFolderPath(sFrom); + nRes = dir2zip(sFromDir, sTo); + } + else if (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF == nFormatTo) + { + NSDoctRenderer::DoctRendererFormat::FormatFile eFromType = NSDoctRenderer::DoctRendererFormat::FormatFile::PPTT; + nRes = doct_bin2pdf(eFromType, sFrom, sTo, params, convertParams); + } + else if (0 != (AVS_OFFICESTUDIO_FILE_IMAGE & nFormatTo)) + { + NSDoctRenderer::DoctRendererFormat::FormatFile eFromType = NSDoctRenderer::DoctRendererFormat::FormatFile::PPTT; + nRes = doct_bin2image(eFromType, sFrom, sTo, params, convertParams); + } + else if (0 != (AVS_OFFICESTUDIO_FILE_DRAW & nFormatTo) || + AVS_OFFICESTUDIO_FILE_OTHER_OOXML == nFormatTo) + { + std::wstring sVsdxDir = combinePath(convertParams.m_sTempDir, L"vsdx_unpacked"); + + if (true == NSDirectory::CreateDirectory(sVsdxDir)) + { + params.m_bMacro = AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTM == nFormatTo || + AVS_OFFICESTUDIO_FILE_DRAW_VSSM == nFormatTo || + AVS_OFFICESTUDIO_FILE_DRAW_VSTM == nFormatTo; + + convertParams.m_sTempResultOOXMLDirectory = sVsdxDir; + nRes = vsdt_bin2vsdx_dir(sFrom, sTo, params, convertParams); + if (SUCCEEDED_X2T(nRes)) + { + std::wstring sFileToCurrent = *params.m_sFileTo; + params.changeFormatFromPost(*params.m_nFormatFrom, params.m_bMacro); + + if (NULL != params.m_nFormatTo) + nFormatTo = *params.m_nFormatTo; + + nRes = fromVsdxDir(sVsdxDir, *params.m_sFileTo, nFormatTo, params, convertParams); + } + } + else + { + nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; + } + } + else + nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; + return nRes; + } _UINT32 fromDraw(const std::wstring& sFrom, int nFormatFrom, InputParams& params, ConvertParams& convertParams) { @@ -1444,7 +1510,7 @@ namespace NExtractTools nFormatTo = *params.m_nFormatTo; _UINT32 nRes = 0; - std::wstring sVsdxDir = combinePath(convertParams.m_sTempDir, L"xsdx_unpacked"); + std::wstring sVsdxDir = combinePath(convertParams.m_sTempDir, L"vsdx_unpacked"); NSDirectory::CreateDirectory(sVsdxDir); if (0 != (AVS_OFFICESTUDIO_FILE_DRAW & nFormatFrom)) @@ -1684,6 +1750,39 @@ namespace NExtractTools result = xlst2xlsx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; + case TCD_VSDX2VSDT: + { + result = vsdx2vsdt(sFileFrom, sFileTo, oInputParams, oConvertParams); + } + break; + case TCD_VSDT2VSDX: + { + oInputParams.m_bMacro = false; + oInputParams.m_nFormatTo = new int(AVS_OFFICESTUDIO_FILE_DRAW_VSDX); + result = vsdt2vsdx(sFileFrom, sFileTo, oInputParams, oConvertParams); + } + break; + case TCD_VSDT2VSTX: + { + oInputParams.m_bMacro = false; + oInputParams.m_nFormatTo = new int(AVS_OFFICESTUDIO_FILE_DRAW_VSTX); + result = vsdt2vsdx(sFileFrom, sFileTo, oInputParams, oConvertParams); + } + break; + case TCD_VSDT2VSTM: + { + oInputParams.m_bMacro = true; + oInputParams.m_nFormatTo = new int(AVS_OFFICESTUDIO_FILE_DRAW_VSTM); + result = vsdt2vsdx(sFileFrom, sFileTo, oInputParams, oConvertParams); + } + break; + case TCD_VSDT2VSDM: + { + oInputParams.m_bMacro = true; + oInputParams.m_nFormatTo = new int(AVS_OFFICESTUDIO_FILE_DRAW_VSDM); + result = vsdt2vsdx(sFileFrom, sFileTo, oInputParams, oConvertParams); + } + break; case TCD_PPTX2PPTT: { result = pptx2pptt(sFileFrom, sFileTo, oInputParams, oConvertParams); @@ -2061,6 +2160,11 @@ namespace NExtractTools result = fromPpttBin(sFileFrom, sFileTo, nFormatTo, oInputParams, oConvertParams); } break; + case TCD_VSDT_BIN2: + { + result = fromVsdtBin(sFileFrom, sFileTo, nFormatTo, oInputParams, oConvertParams); + } + break; case TCD_CROSSPLATFORM2: { result = fromCrossPlatform(sFileFrom, nFormatFrom, sFileTo, nFormatTo, oInputParams, oConvertParams); diff --git a/X2tConverter/src/ASCConverters.h b/X2tConverter/src/ASCConverters.h index 5e93affe34..d83cd9d412 100644 --- a/X2tConverter/src/ASCConverters.h +++ b/X2tConverter/src/ASCConverters.h @@ -148,6 +148,15 @@ namespace NExtractTools DECLARE_CONVERT_FUNC(potm2pptx); DECLARE_CONVERT_FUNC(potm2pptx_dir); + // vsdx + DECLARE_CONVERT_FUNC(vsdx2vsdt); + DECLARE_CONVERT_FUNC(vsdx2vsdt_bin); + DECLARE_CONVERT_FUNC(vsdx_dir2vsdt); + DECLARE_CONVERT_FUNC(vsdx_dir2vsdt_bin); + DECLARE_CONVERT_FUNC(vsdt_bin2vsdx); + DECLARE_CONVERT_FUNC(vsdt_bin2vsdx_dir); + DECLARE_CONVERT_FUNC(vsdt2vsdx); + // doc DECLARE_CONVERT_FUNC(doc2docx); DECLARE_CONVERT_FUNC(doc2docx_dir); @@ -303,6 +312,7 @@ namespace NExtractTools _UINT32 fromCrossPlatform(const std::wstring& sFrom, int nFormatFrom, const std::wstring& sTo, int nFormatTo, InputParams& params, ConvertParams& convertParams); _UINT32 fromCanvasPdf(const std::wstring& sFrom, int nFormatFrom, const std::wstring& sTo, int nFormatTo, InputParams& params, ConvertParams& convertParams); + _UINT32 fromVsdtBin(const std::wstring& sFrom, const std::wstring& sTo, int nFormatTo, InputParams& params, ConvertParams& convertParams); _UINT32 fromDraw(const std::wstring& sFrom, int nFormatFrom, InputParams& params, ConvertParams& convertParams); _UINT32 fromInputParams(InputParams& oInputParams); diff --git a/X2tConverter/src/cextracttools.cpp b/X2tConverter/src/cextracttools.cpp index dfd7c90dec..9c5c992841 100644 --- a/X2tConverter/src/cextracttools.cpp +++ b/X2tConverter/src/cextracttools.cpp @@ -161,6 +161,30 @@ namespace NExtractTools } } break; + case AVS_OFFICESTUDIO_FILE_DRAW_VSDX: + case AVS_OFFICESTUDIO_FILE_DRAW_VSSX: + case AVS_OFFICESTUDIO_FILE_DRAW_VSTX: + case AVS_OFFICESTUDIO_FILE_DRAW_VSDM: + case AVS_OFFICESTUDIO_FILE_DRAW_VSSM: + case AVS_OFFICESTUDIO_FILE_DRAW_VSTM: + { + if (0 == sExt2.compare(L".vsdt")) + res = TCD_VSDX2VSDT; + else if (0 == sExt2.compare(L".bin")) + res = TCD_VSDX2VSDT_BIN; + }break; + case AVS_OFFICESTUDIO_FILE_TEAMLAB_VSDY: + { + if (0 == sExt2.compare(L".vsdx")) + res = TCD_VSDT2VSDX; + else if (0 == sExt2.compare(L".vsdm")) + res = TCD_VSDT2VSDM; + else if (0 == sExt2.compare(L".vstx")) + res = TCD_VSDT2VSTX; + else if (0 == sExt2.compare(L".vstm")) + res = TCD_VSDT2VSTM; + } + break; case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX: case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM: case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTX: @@ -486,7 +510,7 @@ namespace NExtractTools res = TCD_OTF2ODF; else if (0 == sExt2.compare(L".ods") && type == AVS_OFFICESTUDIO_FILE_SPREADSHEET_OTS) res = TCD_OTF2ODF; - else if (0 == sExt2.compare(L".odp") && type == AVS_OFFICESTUDIO_FILE_PRESENTATION_OTP) + else if ((0 == sExt2.compare(L".odp") || 0 == sExt2.compare(L".odg")) && type == AVS_OFFICESTUDIO_FILE_PRESENTATION_OTP) res = TCD_OTF2ODF; } break; diff --git a/X2tConverter/src/cextracttools.h b/X2tConverter/src/cextracttools.h index c13dfde3c4..c1a9853121 100644 --- a/X2tConverter/src/cextracttools.h +++ b/X2tConverter/src/cextracttools.h @@ -111,6 +111,14 @@ namespace NExtractTools TCD_POTM2PPTM, TCD_PPSM2PPTM, + TCD_VSDX2VSDT, + TCD_VSDX2VSDT_BIN, + TCD_VSDT2VSDX, + TCD_VSDT2VSDM, + TCD_VSDT2VSTX, + TCD_VSDT2VSTM, + TCD_VSDT_BIN2VSDX, + TCD_ZIPDIR, TCD_UNZIPDIR, @@ -221,6 +229,7 @@ namespace NExtractTools TCD_DOCT_BIN2, TCD_XLST_BIN2, TCD_PPTT_BIN2, + TCD_VSDT_BIN2, TCD_DOCUMENT2, TCD_SPREADSHEET2, TCD_PRESENTATION2, @@ -996,6 +1005,8 @@ namespace NExtractTools eRes = TCD_XLST_BIN2; else if (AVS_OFFICESTUDIO_FILE_CANVAS_PRESENTATION == nFormatFrom) eRes = TCD_PPTT_BIN2; + else if (AVS_OFFICESTUDIO_FILE_CANVAS_DRAW == nFormatFrom) + eRes = TCD_VSDT_BIN2; else if (0 != (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM & nFormatFrom)) eRes = TCD_CROSSPLATFORM2; else if (AVS_OFFICESTUDIO_FILE_CANVAS_PDF == nFormatFrom) diff --git a/X2tConverter/src/lib/crypt.h b/X2tConverter/src/lib/crypt.h index 0cb92a794c..0fd0cfd7f5 100644 --- a/X2tConverter/src/lib/crypt.h +++ b/X2tConverter/src/lib/crypt.h @@ -231,6 +231,14 @@ namespace NExtractTools return fromPresentation(sResultDecryptFile, AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX, params, convertParams); } break; + case AVS_OFFICESTUDIO_FILE_DRAW_VSDX: + case AVS_OFFICESTUDIO_FILE_DRAW_VSDM: + case AVS_OFFICESTUDIO_FILE_DRAW_VSTX: + case AVS_OFFICESTUDIO_FILE_DRAW_VSTM: + { + return fromDraw(sResultDecryptFile, AVS_OFFICESTUDIO_FILE_DRAW_VSDX, params, convertParams); + } + break; } } } diff --git a/X2tConverter/src/lib/vsdx.h b/X2tConverter/src/lib/vsdx.h new file mode 100644 index 0000000000..bd05ee8099 --- /dev/null +++ b/X2tConverter/src/lib/vsdx.h @@ -0,0 +1,180 @@ +/* + * (c) Copyright Ascensio System SIA 2010-2023 + * + * 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. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * 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: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +#pragma once + +#include "../../../OOXML/Binary/Document/DocWrapper/VsdxSerializer.h" +#include "common.h" + +namespace NExtractTools +{ + _UINT32 vsdx2vsdt(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2oot(sFrom, sTo, params, convertParams, L"vsdt", vsdx2vsdt_bin); + } + _UINT32 vsdx2vsdt_bin(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + // Extract vsdx to temp directory + std::wstring sTempUnpackedVSDX = combinePath(convertParams.m_sTempDir, L"vsdx_unpacked"); + NSDirectory::CreateDirectory(sTempUnpackedVSDX); + + COfficeUtils oCOfficeUtils(NULL); + if (S_OK != oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedVSDX, NULL, 0)) + { + //check crypt + COfficeFileFormatChecker OfficeFileFormatChecker; + if (OfficeFileFormatChecker.isOfficeFile(sFrom)) + { + if (OfficeFileFormatChecker.nFileType == AVS_OFFICESTUDIO_FILE_OTHER_MS_OFFCRYPTO) + { + return mscrypt2oot_bin(sFrom, sTo, params, convertParams); + } + else if (OfficeFileFormatChecker.nFileType == AVS_OFFICESTUDIO_FILE_OTHER_MS_MITCRYPTO) + return mitcrypt2oot_bin(sFrom, sTo, params, convertParams); + else + { + if (create_if_empty(sFrom, sTo, L"VSDY;v10;0;")) + return 0; + return AVS_FILEUTILS_ERROR_CONVERT; + } + } + else + return AVS_FILEUTILS_ERROR_CONVERT; + } + + convertParams.m_bTempIsXmlOptions = true; + convertParams.m_sTempParamOOXMLFile = sFrom; + return vsdx_dir2vsdt_bin(sTempUnpackedVSDX, sTo, params, convertParams); + } + _UINT32 vsdx_dir2vsdt(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::format2oot(sFrom, sTo, params, convertParams, L"vsdt", vsdx_dir2vsdt_bin); + } + _UINT32 vsdx_dir2vsdt_bin(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + _UINT32 nRes = S_OK; + std::wstring sToDir = NSDirectory::GetFolderPath(sTo); + if (params.needConvertToOrigin(AVS_OFFICESTUDIO_FILE_DRAW_VSDX) && !convertParams.m_sTempParamOOXMLFile.empty()) + { + nRes = CopyOOXOrigin(sToDir, sFrom, L"origin.vsdx", convertParams.m_sTempParamOOXMLFile); + } + else + { + BinVsdxRW::CVsdxSerializer oVsdxSerializer; + + // Save to file (from temp dir) + oVsdxSerializer.setIsNoBase64(params.getIsNoBase64()); + oVsdxSerializer.setFontDir(params.getFontPath()); + + nRes = oVsdxSerializer.saveToFile(sTo, sFrom); + } + + convertParams.m_sTempParamOOXMLFile = L""; + convertParams.m_bTempIsXmlOptions = false; + return nRes; + } + _UINT32 vsdt_bin2vsdx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + // Extract vsdx to temp directory + std::wstring sResultVsdxDir = combinePath(convertParams.m_sTempDir, L"vsdx_unpacked"); + NSDirectory::CreateDirectory(sResultVsdxDir); + + convertParams.m_sTempResultOOXMLDirectory = sResultVsdxDir; + _UINT32 nRes = vsdt_bin2vsdx_dir(sFrom, sTo, params, convertParams); + + if (SUCCEEDED_X2T(nRes) && params.m_nFormatTo) + { + if (AVS_OFFICESTUDIO_FILE_DRAW_VSTX == *params.m_nFormatTo || + AVS_OFFICESTUDIO_FILE_DRAW_VSTM == *params.m_nFormatTo) + { + std::wstring sCTFrom = _T("application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"); + std::wstring sCTTo; + switch (*params.m_nFormatTo) + { + case AVS_OFFICESTUDIO_FILE_DRAW_VSTX: + sCTTo = _T("application/vnd.ms-visio.template.main+xml"); + break; + case AVS_OFFICESTUDIO_FILE_DRAW_VSTM: + sCTFrom = _T("application/vnd.ms-visio.drawing.macroEnabled.main+xml"); + sCTTo = _T("application/vnd.ms-visio.template.macroEnabled.main+xml"); + break; + } + nRes = replaceContentType(sResultVsdxDir, sCTFrom, sCTTo); + } + } + if (SUCCEEDED_X2T(nRes)) + { + nRes = dir2zipMscrypt(sResultVsdxDir, sTo, params, convertParams); + } + return nRes; + } + _UINT32 vsdt2vsdx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::oot2format(sFrom, sTo, params, convertParams, L"vsdt", vsdt_bin2vsdx); + } + _UINT32 vsdt_bin2vsdx_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + _UINT32 nRes = 0; + + std::wstring sTargetBin; + if (params.getFromChanges()) + { + params.setFromChanges(false); + nRes = apply_changes(sFrom, sTo, NSDoctRenderer::DoctRendererFormat::FormatFile::VSDT, sTargetBin, params, convertParams); + } + else + sTargetBin = sFrom; + + BinVsdxRW::CVsdxSerializer oVsdxSerializer; + + oVsdxSerializer.setMacroEnabled(params.m_bMacro); + oVsdxSerializer.setIsNoBase64(params.getIsNoBase64()); + oVsdxSerializer.setFontDir(params.getFontPath()); + + std::wstring sMediaPath; + std::wstring sEmbedPath; + + oVsdxSerializer.CreateVsdxFolders(convertParams.m_sTempResultOOXMLDirectory, sMediaPath, sEmbedPath); + + if (SUCCEEDED_X2T(nRes)) + { + nRes = oVsdxSerializer.loadFromFile(sTargetBin, convertParams.m_sTempResultOOXMLDirectory, sMediaPath, sEmbedPath); + params.m_bMacro = oVsdxSerializer.getMacroEnabled(); + } + // удаляем EditorWithChanges, потому что он не в Temp + if (sFrom != sTargetBin) + NSFile::CFileBinary::Remove(sTargetBin); + + convertParams.m_sTempResultOOXMLDirectory = L""; + return nRes; + } + +} diff --git a/X2tConverter/src/lib/xlsx.h b/X2tConverter/src/lib/xlsx.h index 2e82444d64..72eb0fe4b2 100644 --- a/X2tConverter/src/lib/xlsx.h +++ b/X2tConverter/src/lib/xlsx.h @@ -1,4 +1,4 @@ -/* +/* * (c) Copyright Ascensio System SIA 2010-2023 * * This program is a free software product. You can redistribute it and/or @@ -142,11 +142,6 @@ namespace NExtractTools else { BinXlsxRW::CXlsxSerializer oCXlsxSerializer; - if (oCXlsxSerializer.hasPivot(sFrom)) - { - // save Editor.xlsx for pivot - nRes = CopyOOXOrigin(sToDir, sFrom, L"Editor.xlsx", convertParams.m_sTempParamOOXMLFile); - } // Save to file (from temp dir) oCXlsxSerializer.setIsNoBase64(params.getIsNoBase64()); @@ -178,8 +173,6 @@ namespace NExtractTools } _UINT32 xlst_bin2xlsb_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) { - std::wstring sTempUnpackedXLSX = combinePath(convertParams.m_sTempDir, L"xlsx_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedXLSX); _UINT32 nRes = 0; @@ -194,14 +187,9 @@ namespace NExtractTools std::wstring sTempUnpackedXLSB = convertParams.m_sTempResultOOXMLDirectory; - convertParams.m_sTempResultOOXMLDirectory = sTempUnpackedXLSX; - nRes = xlst_bin2xlsx_dir(sTargetBin, sTempUnpackedXLSX, params, convertParams); + convertParams.m_sTempResultOOXMLDirectory = sTempUnpackedXLSB; + nRes = xlst_bin2xlsx_dir(sTargetBin, sTempUnpackedXLSB, params, convertParams); - if (SUCCEEDED_X2T(nRes)) - { - convertParams.m_sTempResultOOXMLDirectory = sTempUnpackedXLSB; - nRes = xlsx_dir2xlsb_dir(sTempUnpackedXLSX, sTempUnpackedXLSB, params, convertParams); - } // удаляем EditorWithChanges, потому что он не в Temp if (sFrom != sTargetBin) NSFile::CFileBinary::Remove(sTargetBin); @@ -279,7 +267,7 @@ namespace NExtractTools oCXlsxSerializer.setIsNoBase64(params.getIsNoBase64()); oCXlsxSerializer.setFontDir(params.getFontPath()); - std::wstring sXmlOptions = _T(""); + std::wstring sXmlOptions = params.getXmlOptions(); std::wstring sMediaPath; // will be filled by 'CreateXlsxFolders' method std::wstring sEmbedPath; // will be filled by 'CreateXlsxFolders' method @@ -301,7 +289,6 @@ namespace NExtractTools { return NSCommon::oot2format(sFrom, sTo, params, convertParams, L"xlst", xlst_bin2xlsx); } - _UINT32 xlst2xlsb(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) { return NSCommon::oot2format(sFrom, sTo, params, convertParams, L"xlst", xlst_bin2xlsb); diff --git a/X2tConverter/src/run.h b/X2tConverter/src/run.h index 009d6e839e..c6f32e49b3 100644 --- a/X2tConverter/src/run.h +++ b/X2tConverter/src/run.h @@ -181,33 +181,29 @@ namespace NSX2T char** penv; #ifndef _MAC + char* nenv[2]; + nenv[0] = &sLibraryDir[0]; + nenv[1] = NULL; + penv = nenv; + if(bIsSaveEnvironment) { putenv(&sLibraryDir[0]); penv = environ; } - else - { - char* nenv[2]; - nenv[0] = &sLibraryDir[0]; - nenv[1] = NULL; - penv = nenv; - } #else + char* nenv[3]; + nenv[0] = &sLibraryDir[0]; + nenv[1] = &sPATH[0]; + nenv[2] = NULL; + penv = nenv; + if(bIsSaveEnvironment) { putenv(&sLibraryDir[0]); putenv(&sPATH[0]); penv = environ; } - else - { - char* nenv[3]; - nenv[0] = &sLibraryDir[0]; - nenv[1] = &sPATH[0]; - nenv[2] = NULL; - penv = nenv; - } #endif execve(sProgramm.c_str(), (char * const *)nargs, diff --git a/X2tConverter/test/win32Test/X2tTest.vcxproj b/X2tConverter/test/win32Test/X2tTest.vcxproj index e21180ad19..63471259d1 100644 --- a/X2tConverter/test/win32Test/X2tTest.vcxproj +++ b/X2tConverter/test/win32Test/X2tTest.vcxproj @@ -192,6 +192,7 @@ + diff --git a/X2tConverter/test/win32Test/X2tTest.vcxproj.filters b/X2tConverter/test/win32Test/X2tTest.vcxproj.filters index 4bf78a3029..5005354bf4 100644 --- a/X2tConverter/test/win32Test/X2tTest.vcxproj.filters +++ b/X2tConverter/test/win32Test/X2tTest.vcxproj.filters @@ -61,6 +61,9 @@ libs + + libs + diff --git a/XpsFile/XpsLib/StaticResources.cpp b/XpsFile/XpsLib/StaticResources.cpp index 0242e97704..ea8382f0f7 100644 --- a/XpsFile/XpsLib/StaticResources.cpp +++ b/XpsFile/XpsLib/StaticResources.cpp @@ -180,9 +180,11 @@ namespace XPS IFolder::CBuffer* buffer = NULL; m_wsRoot->readFileWithChunks(wsPath, buffer); + if (!buffer) + return false; int nBase64BufferLen = NSBase64::Base64EncodeGetRequiredLength(buffer->Size); BYTE* pbBase64Buffer = new BYTE[nBase64BufferLen + 64]; - if (true == NSBase64::Base64Encode(buffer->Buffer, buffer->Size, pbBase64Buffer, &nBase64BufferLen)) + if (TRUE == NSBase64::Base64Encode(buffer->Buffer, buffer->Size, pbBase64Buffer, &nBase64BufferLen)) { pRenderer->put_BrushType(c_BrushTypeTexture); pRenderer->put_BrushTexturePath(L"data:," + NSFile::CUtf8Converter::GetUnicodeStringFromUTF8(pbBase64Buffer, nBase64BufferLen));