From ba46a97bde9a515e0c13ecfad7036e9519264bb1 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 27 Jan 2025 13:52:54 +0300 Subject: [PATCH 001/186] Create readAnnotationsInfoFromBinary --- .../graphics/pro/js/wasm/js/drawingfile.js | 692 ++++++++++++++++++ .../graphics/pro/js/wasm/js/stream.js | 17 + 2 files changed, 709 insertions(+) diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js index c75590e0e7..a13e87d3db 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js @@ -401,6 +401,95 @@ function readAction(reader, rec) readAction(reader, rec["Next"]); } } +function readAction2(reader, rec) +{ + let SType = reader.readByte(); + // 0 - Unknown, 1 - GoTo, 2 - GoToR, 3 - GoToE, 4 - Launch + // 5 - Thread, 6 - URI, 7 - Sound, 8 - Movie, 9 - Hide + // 10 - Named, 11 - SubmitForm, 12 - ResetForm, 13 - ImportData + // 14 - JavaScript, 15 - SetOCGState, 16 - Rendition + // 17 - Trans, 18 - GoTo3DView + rec["S"] = SType; + if (SType == 14) + { + rec["JS"] = reader.readString2(); + } + else if (SType == 1) + { + rec["page"] = reader.readInt(); + rec["kind"] = reader.readByte(); + // 0 - XYZ + // 1 - Fit + // 2 - FitH + // 3 - FitV + // 4 - FitR + // 5 - FitB + // 6 - FitBH + // 7 - FitBV + switch (rec["kind"]) + { + case 0: + case 2: + case 3: + case 6: + case 7: + { + let nFlag = reader.readByte(); + if (nFlag & (1 << 0)) + rec["left"] = reader.readDouble2(); + if (nFlag & (1 << 1)) + rec["top"] = reader.readDouble2(); + if (nFlag & (1 << 2)) + rec["zoom"] = reader.readDouble2(); + break; + } + case 4: + { + rec["left"] = reader.readDouble2(); + rec["bottom"] = reader.readDouble2(); + rec["right"] = reader.readDouble2(); + rec["top"] = reader.readDouble2(); + break; + } + case 1: + case 5: + default: + break; + } + } + else if (SType == 10) + { + rec["N"] = reader.readString2(); + } + else if (SType == 6) + { + rec["URI"] = reader.readString2(); + } + else if (SType == 9) + { + rec["H"] = reader.readByte(); + let m = reader.readInt(); + rec["T"] = []; + // array of annotation names - rec["name"] + for (let j = 0; j < m; ++j) + rec["T"].push(reader.readString2()); + } + else if (SType == 12) + { + rec["Flags"] = reader.readInt(); + let m = reader.readInt(); + rec["Fields"] = []; + // array of annotation names - rec["name"] + for (let j = 0; j < m; ++j) + rec["Fields"].push(reader.readString2()); + } + let NextAction = reader.readByte(); + if (NextAction) + { + rec["Next"] = {}; + readAction2(reader, rec["Next"]); + } +} function readAnnot(reader, rec) { rec["AP"] = {}; @@ -1326,6 +1415,609 @@ 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 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 + rec["AP"] = {}; + // number for relations with AP + rec["AP"]["i"] = reader.readInt(); + rec["annotflag"] = reader.readInt(); + // 12.5.3 + let bHidden = (rec["annotflag"] >> 1) & 1; // Hidden + let bPrint = (rec["annotflag"] >> 2) & 1; // Print + rec["noZoom"] = (rec["annotflag"] >> 3) & 1; // NoZoom + rec["noRotate"] = (rec["annotflag"] >> 4) & 1; // NoRotate + let bNoView = (rec["annotflag"] >> 5) & 1; // NoView + rec["locked"] = (rec["annotflag"] >> 7) & 1; // Locked + rec["ToggleNoView"] = (rec["annotflag"] >> 8) & 1; // ToggleNoView + rec["lockedC"] = (rec["annotflag"] >> 9) & 1; // LockedContents + // 0 - visible, 1 - hidden, 2 - noPrint, 3 - noView + rec["display"] = 0; + if (bHidden) + rec["display"] = 1; + else + { + if (bPrint) + { + if (bNoView) + rec["display"] = 3; + else + rec["display"] = 0; + } + else + { + if (bNoView) + rec["display"] = 0; // ??? no hidden, but noView and no print + else + rec["display"] = 2; + } + } + 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(); + let flags = reader.readInt(); + // Unique name - NM + if (flags & (1 << 0)) + rec["UniqueName"] = reader.readString2(); + // Alternate annotation text - Contents + if (flags & (1 << 1)) + rec["Contents"] = reader.readString2(); + // Border effect - BE + if (flags & (1 << 2)) + { + rec["BE"] = {}; + rec["BE"]["S"] = reader.readByte(); + rec["BE"]["I"] = reader.readDouble2(); + } + // Special annotation color - С + if (flags & (1 << 3)) + { + let n = reader.readInt(); + rec["C"] = []; + for (let i = 0; i < n; ++i) + rec["C"].push(reader.readDouble2()); + } + // Border/BS + if (flags & (1 << 4)) + { + // 0 - solid, 1 - beveled, 2 - dashed, 3 - inset, 4 - underline + rec["border"] = reader.readByte(); + rec["borderWidth"] = reader.readDouble2(); + // Border Dash Pattern + if (rec["border"] == 2) + { + let n = reader.readInt(); + rec["dashed"] = []; + for (let i = 0; i < n; ++i) + rec["dashed"].push(reader.readDouble2()); + } + } + // Date of last change - M + if (flags & (1 << 5)) + rec["LastModified"] = reader.readString2(); + // AP + if (flags & (1 << 6)) + { + // TODO use Render - Uint8Array + rec["AP"]["render"] = reader.readData(); + } + // User ID + if (flags & (1 << 7)) + rec["OUserID"] = reader.readString2(); + // Markup + 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"] = reader.readString2(); + // CA + if (flags & (1 << 2)) + rec["CA"] = reader.readDouble2(); + // 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.readDouble2(); + if (nFontFlag & (1 << 6)) + oFont["actual"] = reader.readString2(); + oFont["size"] = reader.readDouble2(); + oFont["color"] = []; + oFont["color"].push(reader.readDouble2()); + oFont["color"].push(reader.readDouble2()); + oFont["color"].push(reader.readDouble2()); + oFont["name"] = reader.readString2(); + oFont["text"] = reader.readString2(); + rec["RC"].push(oFont); + } + } + // CreationDate + if (flags & (1 << 4)) + rec["CreationDate"] = reader.readString2(); + // 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.readString2(); + } + // 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(reader.readDouble2()); + // 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.readDouble2(); + // LLE + if (flags & (1 << 18)) + rec["LLE"] = reader.readDouble2(); + // 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.readDouble2(); + // CP + // 0 - Inline, 1 - Top + if (flags & (1 << 22)) + rec["CP"] = reader.readByte(); + // CO + if (flags & (1 << 23)) + { + rec["CO"] = []; + rec["CO"].push(reader.readDouble2()); + rec["CO"].push(reader.readDouble2()); + } + } + // 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.readDouble2()); + } + } + // 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.readDouble2()); + } + // 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.readDouble2()); + } + // 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.readDouble2()); + // 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(); + } + // 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.readDouble2()); + } + // CL + if (flags & (1 << 16)) + { + let n = reader.readInt(); + rec["CL"] = []; + for (let i = 0; i < n; ++i) + rec["CL"].push(reader.readDouble2()); + } + // Default style (CSS2 format) - DS + if (flags & (1 << 17)) + rec["defaultStyle"] = reader.readString2(); + // 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.readDouble2()); + } + // Sy + // 0 - None, 1 - P, 2 - S + if (flags & (1 << 16)) + rec["Sy"] = reader.readByte(); + } + // TODO FileAttachment + // Stamp + else if (rec["Type"] == 12) + { + rec["Icon"] = reader.readString2(); + rec["Rotate"] = reader.readDouble2(); + rec["InRect"] = []; + for (let i = 0; i < 4; ++i) + rec["InRect"].push(reader.readDouble2()); + } + else if (rec["Type"] >= 26 && rec["Type"] <= 33) + { + // Widget + rec["font"] = {}; + rec["font"]["name"] = reader.readString2(); + rec["font"]["size"] = reader.readDouble2(); + rec["font"]["sizeAP"] = reader.readDouble2(); + 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 + if (rec["Type"] != 29 && rec["Type"] != 28 && rec["Type"] != 27) + 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.readString2(); + // Default style string (CSS2 format) - DS + if (flags & (1 << 1)) + rec["defaultStyle"] = reader.readString2(); + // Actual font + if (flags & (1 << 2)) + rec["font"]["actual"] = reader.readString2(); + // 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.readString2(); + // 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.readString2(); + if (flags & (1 << 17)) + rec["Parent"] = reader.readInt(); + if (flags & (1 << 18)) + rec["name"] = reader.readString2(); + if (flags & (1 << 19)) + rec["font"]["AP"] = reader.readString2(); + // Action + let nAction = reader.readInt(); + if (nAction > 0) + rec["AA"] = {}; + for (let i = 0; i < nAction; ++i) + { + let AAType = reader.readString2(); + rec["AA"][AAType] = {}; + readAction2(reader, rec["AA"][AAType]); + } + // Widget types + if (rec["type"] == 27) + { + if (flags & (1 << 9)) + rec["value"] = reader.readString2(); + let IFflags = reader.readInt(); + // Header - СA + if (flags & (1 << 10)) + rec["caption"] = reader.readString2(); + // Rollover header - RC + if (flags & (1 << 11)) + rec["rolloverCaption"] = reader.readString2(); + // Alternate header - AC + if (flags & (1 << 12)) + rec["alternateCaption"] = reader.readString2(); + // 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(reader.readDouble2()); + rec["IF"]["A"].push(reader.readDouble2()); + } + rec["IF"]["FB"] = (IFflags >> 4) & 1; + } + 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"] = reader.readString2(); + // 0 - check, 1 - cross, 2 - diamond, 3 - circle, 4 - star, 5 - square + rec["style"] = reader.readByte(); + if (flags & (1 << 14)) + rec["ExportValue"] = reader.readString2(); + // 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.readString2(); + if (flags & (1 << 10)) + rec["maxLen"] = reader.readInt(); + if (rec["flag"] & (1 << 25)) + rec["richValue"] = reader.readString2(); + if (flags & (1 << 12)) + rec["AP"]["V"] = reader.readString2(); + if (flags & (1 << 13)) + { + // TODO use Render - Uint8Array + rec["AP"]["render"] = reader.readData(); + } + // 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.readString2(); + if (flags & (1 << 10)) + { + let n = reader.readInt(); + rec["opt"] = []; + for (let i = 0; i < n; ++i) + { + let opt1 = reader.readString2(); + let opt2 = reader.readString2(); + if (opt1 == "") + rec["opt"].push(opt2); + else + rec["opt"].push([opt2, opt1]); + } + } + if (flags & (1 << 11)) + rec["TI"] = reader.readInt(); + if (flags & (1 << 12)) + rec["AP"]["V"] = reader.readString2(); + if (flags & (1 << 13)) + { + let n = reader.readInt(); + rec["value"] = []; + for (let i = 0; i < n; ++i) + rec["value"].push(reader.readString2()); + } + 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)) + { + // TODO use Render - Uint8Array + rec["AP"]["render"] = reader.readData(); + } + // 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 + } + else if (rec["type"] == 33) + { + rec["Sig"] = (flags >> 9) & 1; + } + } + res.push(rec); + } + + return res; +}; + // SCAN PAGES CFile.prototype["scanPage"] = function(page, mode) { diff --git a/DesktopEditor/graphics/pro/js/wasm/js/stream.js b/DesktopEditor/graphics/pro/js/wasm/js/stream.js index 2345ff97ff..4bfd7cae0f 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; @@ -63,6 +69,17 @@ 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.prototype.fromCharCode(c); + } + return val; +}; CBinaryReader.prototype.readData = function() { let len = this.readInt(); From 894f88e475584421d17ad988691d4b39dd86903e Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 27 Jan 2025 18:54:09 +0300 Subject: [PATCH 002/186] Separation of common parts into functions --- .../graphics/pro/js/wasm/js/drawingfile.js | 1917 ++++++----------- 1 file changed, 667 insertions(+), 1250 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js index a13e87d3db..744d995768 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js @@ -312,7 +312,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 +323,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 +347,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 +370,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 +383,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,105 +392,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 readAction2(reader, rec) -{ - let SType = reader.readByte(); - // 0 - Unknown, 1 - GoTo, 2 - GoToR, 3 - GoToE, 4 - Launch - // 5 - Thread, 6 - URI, 7 - Sound, 8 - Movie, 9 - Hide - // 10 - Named, 11 - SubmitForm, 12 - ResetForm, 13 - ImportData - // 14 - JavaScript, 15 - SetOCGState, 16 - Rendition - // 17 - Trans, 18 - GoTo3DView - rec["S"] = SType; - if (SType == 14) - { - rec["JS"] = reader.readString2(); - } - else if (SType == 1) - { - rec["page"] = reader.readInt(); - rec["kind"] = reader.readByte(); - // 0 - XYZ - // 1 - Fit - // 2 - FitH - // 3 - FitV - // 4 - FitR - // 5 - FitB - // 6 - FitBH - // 7 - FitBV - switch (rec["kind"]) - { - case 0: - case 2: - case 3: - case 6: - case 7: - { - let nFlag = reader.readByte(); - if (nFlag & (1 << 0)) - rec["left"] = reader.readDouble2(); - if (nFlag & (1 << 1)) - rec["top"] = reader.readDouble2(); - if (nFlag & (1 << 2)) - rec["zoom"] = reader.readDouble2(); - break; - } - case 4: - { - rec["left"] = reader.readDouble2(); - rec["bottom"] = reader.readDouble2(); - rec["right"] = reader.readDouble2(); - rec["top"] = reader.readDouble2(); - break; - } - case 1: - case 5: - default: - break; - } - } - else if (SType == 10) - { - rec["N"] = reader.readString2(); - } - else if (SType == 6) - { - rec["URI"] = reader.readString2(); - } - else if (SType == 9) - { - rec["H"] = reader.readByte(); - let m = reader.readInt(); - rec["T"] = []; - // array of annotation names - rec["name"] - for (let j = 0; j < m; ++j) - rec["T"].push(reader.readString2()); - } - else if (SType == 12) - { - rec["Flags"] = reader.readInt(); - let m = reader.readInt(); - rec["Fields"] = []; - // array of annotation names - rec["name"] - for (let j = 0; j < m; ++j) - rec["Fields"].push(reader.readString2()); - } - let NextAction = reader.readByte(); - if (NextAction) - { - rec["Next"] = {}; - readAction2(reader, rec["Next"]); - } -} -function readAnnot(reader, rec) +function readAnnot(reader, rec, readDoubleFunc, readStringFunc, isRead = false) { rec["AP"] = {}; // Annot @@ -537,16 +448,16 @@ function readAnnot(reader, rec) 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)) @@ -561,24 +472,30 @@ function readAnnot(reader, rec) { // 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); } function readAnnotAP(reader, AP) { @@ -610,6 +527,632 @@ function readAnnotAP(reader, AP) APi["BlendMode"] = reader.readByte(); } } +function readAnnotType(reader, rec, readDoubleFunc, 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(reader.readDouble2()); + oFont["color"].push(reader.readDouble2()); + oFont["color"].push(reader.readDouble2()); + 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) + { + // 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(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(reader.readDouble2()); + } + // 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(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(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(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(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(); + 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(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"] = reader.readDouble2(); + rec["InRect"] = []; + if (isRead) + { + let x1 = reader.readDouble2(); + let y1 = reader.readDouble2(); + let x2 = reader.readDouble2(); + let y2 = reader.readDouble2(); + rec["InRect"] = [ x1, y1, x1, y2, x2, y2, y1, x2 ]; + } + else + { + for (let i = 0; i < 8; ++i) + rec["InRect"].push(reader.readDouble2()); + } + } +} +function readWidgetType(reader, rec, readDoubleFunc, 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(reader.readDouble2()); + } + // 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 + 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(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"] = 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); + // 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 + 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 (rec["flag"] & (1 << 25)) + 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 + 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 + 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; + } +} CFile.prototype["getInteractiveFormsInfo"] = function() { @@ -673,196 +1216,9 @@ CFile.prototype["getInteractiveFormsInfo"] = function() // 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(); - // 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)) - 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)) - { - 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; - } - } - 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)) - { - let n = reader.readInt(); - rec["opt"] = []; - for (let i = 0; i < n; ++i) - { - let opt1 = reader.readString(); - let opt2 = reader.readString(); - if (opt1 == "") - rec["opt"].push(opt2); - else - rec["opt"].push([opt2, opt1]); - } - } - if (flags & (1 << 11)) - rec["TI"] = reader.readInt(); - 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(reader.readString()); - } - // 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 - } - else if (rec["type"] == 33) - { - rec["Sig"] = (flags >> 9) & 1; - } + readAnnot(reader, rec, reader.readDouble, reader.readString); + // Widget type + readWidgetType(reader, rec, reader.readDouble, reader.readString); res["Fields"].push(rec); } @@ -999,380 +1355,9 @@ CFile.prototype["getAnnotationsInfo"] = function(pageIndex) // 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) - { - 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(); - } - // 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()); - } + readAnnot(reader, rec, reader.readDouble, reader.readString); + // Annot type + readAnnotType(reader, rec, reader.readDouble, reader.readString); res.push(rec); } @@ -1436,581 +1421,13 @@ CFile.prototype["readAnnotationsInfoFromBinary"] = function(AnnotInfo) // 22 - TrapNet, 23 - Watermark, 24 - 3D, 25 - Redact rec["Type"] = reader.readByte(); // Annot - rec["AP"] = {}; - // number for relations with AP - rec["AP"]["i"] = reader.readInt(); - rec["annotflag"] = reader.readInt(); - // 12.5.3 - let bHidden = (rec["annotflag"] >> 1) & 1; // Hidden - let bPrint = (rec["annotflag"] >> 2) & 1; // Print - rec["noZoom"] = (rec["annotflag"] >> 3) & 1; // NoZoom - rec["noRotate"] = (rec["annotflag"] >> 4) & 1; // NoRotate - let bNoView = (rec["annotflag"] >> 5) & 1; // NoView - rec["locked"] = (rec["annotflag"] >> 7) & 1; // Locked - rec["ToggleNoView"] = (rec["annotflag"] >> 8) & 1; // ToggleNoView - rec["lockedC"] = (rec["annotflag"] >> 9) & 1; // LockedContents - // 0 - visible, 1 - hidden, 2 - noPrint, 3 - noView - rec["display"] = 0; - if (bHidden) - rec["display"] = 1; - else + readAnnot(reader, rec, reader.readDouble2, reader.readString2, true); + // Annot type + readAnnotType(reader, rec, reader.readDouble2, reader.readString2, true); + if (rec["Type"] >= 26 && rec["Type"] <= 33) { - if (bPrint) - { - if (bNoView) - rec["display"] = 3; - else - rec["display"] = 0; - } - else - { - if (bNoView) - rec["display"] = 0; // ??? no hidden, but noView and no print - else - rec["display"] = 2; - } - } - 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(); - let flags = reader.readInt(); - // Unique name - NM - if (flags & (1 << 0)) - rec["UniqueName"] = reader.readString2(); - // Alternate annotation text - Contents - if (flags & (1 << 1)) - rec["Contents"] = reader.readString2(); - // Border effect - BE - if (flags & (1 << 2)) - { - rec["BE"] = {}; - rec["BE"]["S"] = reader.readByte(); - rec["BE"]["I"] = reader.readDouble2(); - } - // Special annotation color - С - if (flags & (1 << 3)) - { - let n = reader.readInt(); - rec["C"] = []; - for (let i = 0; i < n; ++i) - rec["C"].push(reader.readDouble2()); - } - // Border/BS - if (flags & (1 << 4)) - { - // 0 - solid, 1 - beveled, 2 - dashed, 3 - inset, 4 - underline - rec["border"] = reader.readByte(); - rec["borderWidth"] = reader.readDouble2(); - // Border Dash Pattern - if (rec["border"] == 2) - { - let n = reader.readInt(); - rec["dashed"] = []; - for (let i = 0; i < n; ++i) - rec["dashed"].push(reader.readDouble2()); - } - } - // Date of last change - M - if (flags & (1 << 5)) - rec["LastModified"] = reader.readString2(); - // AP - if (flags & (1 << 6)) - { - // TODO use Render - Uint8Array - rec["AP"]["render"] = reader.readData(); - } - // User ID - if (flags & (1 << 7)) - rec["OUserID"] = reader.readString2(); - // Markup - 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"] = reader.readString2(); - // CA - if (flags & (1 << 2)) - rec["CA"] = reader.readDouble2(); - // 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.readDouble2(); - if (nFontFlag & (1 << 6)) - oFont["actual"] = reader.readString2(); - oFont["size"] = reader.readDouble2(); - oFont["color"] = []; - oFont["color"].push(reader.readDouble2()); - oFont["color"].push(reader.readDouble2()); - oFont["color"].push(reader.readDouble2()); - oFont["name"] = reader.readString2(); - oFont["text"] = reader.readString2(); - rec["RC"].push(oFont); - } - } - // CreationDate - if (flags & (1 << 4)) - rec["CreationDate"] = reader.readString2(); - // 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.readString2(); - } - // 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(reader.readDouble2()); - // 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.readDouble2(); - // LLE - if (flags & (1 << 18)) - rec["LLE"] = reader.readDouble2(); - // 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.readDouble2(); - // CP - // 0 - Inline, 1 - Top - if (flags & (1 << 22)) - rec["CP"] = reader.readByte(); - // CO - if (flags & (1 << 23)) - { - rec["CO"] = []; - rec["CO"].push(reader.readDouble2()); - rec["CO"].push(reader.readDouble2()); - } - } - // 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.readDouble2()); - } - } - // 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.readDouble2()); - } - // 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.readDouble2()); - } - // 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.readDouble2()); - // 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(); - } - // 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.readDouble2()); - } - // CL - if (flags & (1 << 16)) - { - let n = reader.readInt(); - rec["CL"] = []; - for (let i = 0; i < n; ++i) - rec["CL"].push(reader.readDouble2()); - } - // Default style (CSS2 format) - DS - if (flags & (1 << 17)) - rec["defaultStyle"] = reader.readString2(); - // 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.readDouble2()); - } - // Sy - // 0 - None, 1 - P, 2 - S - if (flags & (1 << 16)) - rec["Sy"] = reader.readByte(); - } - // TODO FileAttachment - // Stamp - else if (rec["Type"] == 12) - { - rec["Icon"] = reader.readString2(); - rec["Rotate"] = reader.readDouble2(); - rec["InRect"] = []; - for (let i = 0; i < 4; ++i) - rec["InRect"].push(reader.readDouble2()); - } - else if (rec["Type"] >= 26 && rec["Type"] <= 33) - { - // Widget - rec["font"] = {}; - rec["font"]["name"] = reader.readString2(); - rec["font"]["size"] = reader.readDouble2(); - rec["font"]["sizeAP"] = reader.readDouble2(); - 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 - if (rec["Type"] != 29 && rec["Type"] != 28 && rec["Type"] != 27) - 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.readString2(); - // Default style string (CSS2 format) - DS - if (flags & (1 << 1)) - rec["defaultStyle"] = reader.readString2(); - // Actual font - if (flags & (1 << 2)) - rec["font"]["actual"] = reader.readString2(); - // 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.readString2(); - // 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.readString2(); - if (flags & (1 << 17)) - rec["Parent"] = reader.readInt(); - if (flags & (1 << 18)) - rec["name"] = reader.readString2(); - if (flags & (1 << 19)) - rec["font"]["AP"] = reader.readString2(); - // Action - let nAction = reader.readInt(); - if (nAction > 0) - rec["AA"] = {}; - for (let i = 0; i < nAction; ++i) - { - let AAType = reader.readString2(); - rec["AA"][AAType] = {}; - readAction2(reader, rec["AA"][AAType]); - } - // Widget types - if (rec["type"] == 27) - { - if (flags & (1 << 9)) - rec["value"] = reader.readString2(); - let IFflags = reader.readInt(); - // Header - СA - if (flags & (1 << 10)) - rec["caption"] = reader.readString2(); - // Rollover header - RC - if (flags & (1 << 11)) - rec["rolloverCaption"] = reader.readString2(); - // Alternate header - AC - if (flags & (1 << 12)) - rec["alternateCaption"] = reader.readString2(); - // 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(reader.readDouble2()); - rec["IF"]["A"].push(reader.readDouble2()); - } - rec["IF"]["FB"] = (IFflags >> 4) & 1; - } - 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"] = reader.readString2(); - // 0 - check, 1 - cross, 2 - diamond, 3 - circle, 4 - star, 5 - square - rec["style"] = reader.readByte(); - if (flags & (1 << 14)) - rec["ExportValue"] = reader.readString2(); - // 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.readString2(); - if (flags & (1 << 10)) - rec["maxLen"] = reader.readInt(); - if (rec["flag"] & (1 << 25)) - rec["richValue"] = reader.readString2(); - if (flags & (1 << 12)) - rec["AP"]["V"] = reader.readString2(); - if (flags & (1 << 13)) - { - // TODO use Render - Uint8Array - rec["AP"]["render"] = reader.readData(); - } - // 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.readString2(); - if (flags & (1 << 10)) - { - let n = reader.readInt(); - rec["opt"] = []; - for (let i = 0; i < n; ++i) - { - let opt1 = reader.readString2(); - let opt2 = reader.readString2(); - if (opt1 == "") - rec["opt"].push(opt2); - else - rec["opt"].push([opt2, opt1]); - } - } - if (flags & (1 << 11)) - rec["TI"] = reader.readInt(); - if (flags & (1 << 12)) - rec["AP"]["V"] = reader.readString2(); - if (flags & (1 << 13)) - { - let n = reader.readInt(); - rec["value"] = []; - for (let i = 0; i < n; ++i) - rec["value"].push(reader.readString2()); - } - 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)) - { - // TODO use Render - Uint8Array - rec["AP"]["render"] = reader.readData(); - } - // 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 - } - else if (rec["type"] == 33) - { - rec["Sig"] = (flags >> 9) & 1; - } + // Widget type + readWidgetType(reader, rec, reader.readDouble2, reader.readString2, true); } res.push(rec); } From dd02c9594b2f266e3a85f17ac45390777ea00b5d Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 28 Jan 2025 10:20:48 +0300 Subject: [PATCH 003/186] Fix ctAnnotField --- DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js index 744d995768..51adff7a20 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js @@ -1412,6 +1412,14 @@ CFile.prototype["readAnnotationsInfoFromBinary"] = function(AnnotInfo) let res = []; while (reader.isValid()) { + let nCommand = reader.readByte(); + let nPos = reader.GetCurPosition(); + let nSize = reader.readInt(); + if (nCommand != 164) // ctAnnotField + { + reader.Seek(nPos + nSize); + continue; + } let rec = {}; // Annotation type // 0 - Text, 1 - Link, 2 - FreeText, 3 - Line, 4 - Square, 5 - Circle, From dabedf612194964cb32acdfaba5e362aaff637bb Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 28 Jan 2025 11:12:35 +0300 Subject: [PATCH 004/186] Fix test Text --- DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js | 4 ++-- DesktopEditor/graphics/pro/js/wasm/js/stream.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js index 51adff7a20..923abce935 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js @@ -1413,11 +1413,11 @@ CFile.prototype["readAnnotationsInfoFromBinary"] = function(AnnotInfo) while (reader.isValid()) { let nCommand = reader.readByte(); - let nPos = reader.GetCurPosition(); + let nPos = reader.pos; let nSize = reader.readInt(); if (nCommand != 164) // ctAnnotField { - reader.Seek(nPos + nSize); + reader.pos = nPos + nSize; continue; } let rec = {}; diff --git a/DesktopEditor/graphics/pro/js/wasm/js/stream.js b/DesktopEditor/graphics/pro/js/wasm/js/stream.js index 4bfd7cae0f..8335fee636 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/stream.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/stream.js @@ -76,7 +76,7 @@ CBinaryReader.prototype.readString2 = function() for (let i = 0; i < len; ++i) { let c = this.readShort(); - val += String.prototype.fromCharCode(c); + val += String.fromCharCode(c); } return val; }; From c2eb402ebf96eb05809a35df3c60c7d87fc0aa95 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 28 Jan 2025 12:01:22 +0300 Subject: [PATCH 005/186] Fix readAnnotationsInfoFromBinary --- .../graphics/pro/js/wasm/js/drawingfile.js | 62 +++++++++---------- .../graphics/pro/js/wasm/js/stream.js | 6 +- 2 files changed, 36 insertions(+), 32 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js index 923abce935..7e8820c5fa 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js @@ -401,7 +401,7 @@ function readAction(reader, rec, readDoubleFunc, readStringFunc) readAction(reader, rec["Next"], readDoubleFunc, readStringFunc); } } -function readAnnot(reader, rec, readDoubleFunc, readStringFunc, isRead = false) +function readAnnot(reader, rec, readDoubleFunc, readDouble2Func, readStringFunc, isRead = false) { rec["AP"] = {}; // Annot @@ -441,10 +441,10 @@ function readAnnot(reader, rec, readDoubleFunc, readStringFunc, isRead = false) 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)) @@ -465,7 +465,7 @@ function readAnnot(reader, rec, readDoubleFunc, readStringFunc, isRead = false) 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)) @@ -527,7 +527,7 @@ function readAnnotAP(reader, AP) APi["BlendMode"] = reader.readByte(); } } -function readAnnotType(reader, rec, readDoubleFunc, readStringFunc, isRead = false) +function readAnnotType(reader, rec, readDoubleFunc, readDouble2Func, readStringFunc, isRead = false) { // Markup let flags = 0; @@ -563,9 +563,9 @@ function readAnnotType(reader, rec, readDoubleFunc, readStringFunc, isRead = fal oFont["actual"] = readStringFunc.call(reader); oFont["size"] = readDoubleFunc.call(reader); oFont["color"] = []; - oFont["color"].push(reader.readDouble2()); - oFont["color"].push(reader.readDouble2()); - oFont["color"].push(reader.readDouble2()); + 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); @@ -630,7 +630,7 @@ function readAnnotType(reader, rec, readDoubleFunc, readStringFunc, isRead = fal let n = reader.readInt(); rec["IC"] = []; for (let i = 0; i < n; ++i) - rec["IC"].push(reader.readDouble2()); + rec["IC"].push(readDouble2Func.call(reader)); } // LL if (flags & (1 << 17)) @@ -698,7 +698,7 @@ function readAnnotType(reader, rec, readDoubleFunc, readStringFunc, isRead = fal let n = reader.readInt(); rec["IC"] = []; for (let i = 0; i < n; ++i) - rec["IC"].push(reader.readDouble2()); + rec["IC"].push(readDouble2Func.call(reader)); } } // Polygon, PolyLine @@ -722,7 +722,7 @@ function readAnnotType(reader, rec, readDoubleFunc, readStringFunc, isRead = fal let n = reader.readInt(); rec["IC"] = []; for (let i = 0; i < n; ++i) - rec["IC"].push(reader.readDouble2()); + rec["IC"].push(readDouble2Func.call(reader)); } // IT // 0 - PolygonCloud, 1 - PolyLineDimension, 2 - PolygonDimension @@ -784,7 +784,7 @@ function readAnnotType(reader, rec, readDoubleFunc, readStringFunc, isRead = fal let n = reader.readInt(); rec["C"] = []; for (let i = 0; i < n; ++i) - rec["C"].push(reader.readDouble2()); + rec["C"].push(readDouble2Func.call(reader)); } } // Caret @@ -905,24 +905,24 @@ function readAnnotType(reader, rec, readDoubleFunc, readStringFunc, isRead = fal else if (rec["Type"] == 12) { rec["Icon"] = readStringFunc.call(reader); - rec["Rotate"] = reader.readDouble2(); + rec["Rotate"] = readDouble2Func.call(reader); rec["InRect"] = []; if (isRead) { - let x1 = reader.readDouble2(); - let y1 = reader.readDouble2(); - let x2 = reader.readDouble2(); - let y2 = reader.readDouble2(); + let x1 = readDouble2Func.call(reader); + let y1 = readDouble2Func.call(reader); + let x2 = readDouble2Func.call(reader); + let y2 = readDouble2Func.call(reader); rec["InRect"] = [ x1, y1, x1, y2, x2, y2, y1, x2 ]; } else { for (let i = 0; i < 8; ++i) - rec["InRect"].push(reader.readDouble2()); + rec["InRect"].push(readDouble2Func.call(reader)); } } } -function readWidgetType(reader, rec, readDoubleFunc, readStringFunc, isRead = false) +function readWidgetType(reader, rec, readDoubleFunc, readDouble2Func, readStringFunc, isRead = false) { // Widget rec["font"] = {}; @@ -936,7 +936,7 @@ function readWidgetType(reader, rec, readDoubleFunc, readStringFunc, isRead = fa { rec["font"]["color"] = []; for (let i = 0; i < tc; ++i) - rec["font"]["color"].push(reader.readDouble2()); + 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)) @@ -971,7 +971,7 @@ function readWidgetType(reader, rec, readDoubleFunc, readStringFunc, isRead = fa let n = reader.readInt(); rec["BC"] = []; for (let i = 0; i < n; ++i) - rec["BC"].push(reader.readDouble2()); + rec["BC"].push(readDouble2Func.call(reader)); } // Rotate an annotation relative to the page - R if (flags & (1 << 6)) @@ -982,7 +982,7 @@ function readWidgetType(reader, rec, readDoubleFunc, readStringFunc, isRead = fa let n = reader.readInt(); rec["BG"] = []; for (let i = 0; i < n; ++i) - rec["BG"].push(reader.readDouble2()); + rec["BG"].push(readDouble2Func.call(reader)); } // Default value - DV if (flags & (1 << 8)) @@ -1216,9 +1216,9 @@ CFile.prototype["getInteractiveFormsInfo"] = function() // 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.readString); + readAnnot(reader, rec, reader.readDouble, reader.readDouble2, reader.readString); // Widget type - readWidgetType(reader, rec, reader.readDouble, reader.readString); + readWidgetType(reader, rec, reader.readDouble, reader.readDouble2, reader.readString); res["Fields"].push(rec); } @@ -1355,9 +1355,9 @@ CFile.prototype["getAnnotationsInfo"] = function(pageIndex) // 22 - TrapNet, 23 - Watermark, 24 - 3D, 25 - Redact rec["Type"] = reader.readByte(); // Annot - readAnnot(reader, rec, reader.readDouble, reader.readString); + readAnnot(reader, rec, reader.readDouble, reader.readDouble2, reader.readString); // Annot type - readAnnotType(reader, rec, reader.readDouble, reader.readString); + readAnnotType(reader, rec, reader.readDouble, reader.readDouble2, reader.readString); res.push(rec); } @@ -1429,13 +1429,13 @@ CFile.prototype["readAnnotationsInfoFromBinary"] = function(AnnotInfo) // 22 - TrapNet, 23 - Watermark, 24 - 3D, 25 - Redact rec["Type"] = reader.readByte(); // Annot - readAnnot(reader, rec, reader.readDouble2, reader.readString2, true); + readAnnot(reader, rec, reader.readDouble3, reader.readDouble3, reader.readString2, true); // Annot type - readAnnotType(reader, rec, reader.readDouble2, reader.readString2, true); + readAnnotType(reader, rec, reader.readDouble3, reader.readDouble3, reader.readString2, true); if (rec["Type"] >= 26 && rec["Type"] <= 33) { // Widget type - readWidgetType(reader, rec, reader.readDouble2, reader.readString2, true); + readWidgetType(reader, rec, reader.readDouble3, reader.readDouble3, reader.readString2, true); } res.push(rec); } diff --git a/DesktopEditor/graphics/pro/js/wasm/js/stream.js b/DesktopEditor/graphics/pro/js/wasm/js/stream.js index 8335fee636..3527185f6e 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/stream.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/stream.js @@ -62,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(); @@ -82,7 +86,7 @@ CBinaryReader.prototype.readString2 = function() }; 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; From b46df522e992ed5bdf81598e3b70b12e05fd14c2 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 30 Jan 2025 15:27:33 +0300 Subject: [PATCH 006/186] Copy AP --- .../graphics/commands/AnnotField.cpp | 3 +++ DesktopEditor/graphics/commands/AnnotField.h | 2 ++ PdfFile/PdfFile.cpp | 8 ++++++++ PdfFile/PdfWriter.cpp | 13 ++++++++++++- PdfFile/SrcWriter/Annotation.cpp | 19 ++++++++++++++++++- PdfFile/SrcWriter/Annotation.h | 4 +++- PdfFile/SrcWriter/Objects.cpp | 2 +- 7 files changed, 47 insertions(+), 4 deletions(-) diff --git a/DesktopEditor/graphics/commands/AnnotField.cpp b/DesktopEditor/graphics/commands/AnnotField.cpp index 7569ec5dce..ec2b2875bc 100644 --- a/DesktopEditor/graphics/commands/AnnotField.cpp +++ b/DesktopEditor/graphics/commands/AnnotField.cpp @@ -224,6 +224,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) { @@ -367,6 +368,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()) { diff --git a/DesktopEditor/graphics/commands/AnnotField.h b/DesktopEditor/graphics/commands/AnnotField.h index 49f6bc3075..a972b3e388 100644 --- a/DesktopEditor/graphics/commands/AnnotField.h +++ b/DesktopEditor/graphics/commands/AnnotField.h @@ -431,6 +431,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(); @@ -488,6 +489,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; diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 0539c85ac0..bede929870 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -1231,7 +1231,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/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 595defc42f..8773c83440 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -1810,6 +1810,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()) { @@ -2102,7 +2103,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); @@ -2117,6 +2117,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); } diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index 2cf08c0312..bd2c461ff5 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -1442,10 +1442,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 //---------------------------------------------------------------------------------------- diff --git a/PdfFile/SrcWriter/Annotation.h b/PdfFile/SrcWriter/Annotation.h index 890249a9de..8fd07f6a8e 100644 --- a/PdfFile/SrcWriter/Annotation.h +++ b/PdfFile/SrcWriter/Annotation.h @@ -400,7 +400,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 { diff --git a/PdfFile/SrcWriter/Objects.cpp b/PdfFile/SrcWriter/Objects.cpp index 1522834b98..356263bac4 100644 --- a/PdfFile/SrcWriter/Objects.cpp +++ b/PdfFile/SrcWriter/Objects.cpp @@ -669,7 +669,7 @@ namespace PdfWriter pXref->Add((CObjectBase*)this); pXref->Add((CObjectBase*)pLength); - Add("Length", (CObjectBase*)pLength); + Add("Length", pLength); } m_pStream = pStream; From a9b225782d070ff7e19e2abadb50212ca9c58be3 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 31 Jan 2025 13:38:29 +0300 Subject: [PATCH 007/186] Create MovePage --- PdfFile/OnlineOfficeBinToPdf.cpp | 10 ++++++++++ PdfFile/PdfEditor.cpp | 13 +++++++++++-- PdfFile/PdfEditor.h | 3 ++- PdfFile/PdfFile.cpp | 6 ++++++ PdfFile/PdfFile.h | 1 + PdfFile/SrcWriter/Document.cpp | 17 +++++++++++++++-- PdfFile/SrcWriter/Document.h | 3 ++- 7 files changed, 47 insertions(+), 6 deletions(-) diff --git a/PdfFile/OnlineOfficeBinToPdf.cpp b/PdfFile/OnlineOfficeBinToPdf.cpp index b41b122b24..674f2c30e6 100644 --- a/PdfFile/OnlineOfficeBinToPdf.cpp +++ b/PdfFile/OnlineOfficeBinToPdf.cpp @@ -150,6 +150,7 @@ namespace NSOnlineOfficeBinToPdf AddPage = 1, RemovePage = 2, WidgetInfo = 3, + MovePage = 4, Undefined = 255 }; @@ -198,6 +199,15 @@ namespace NSOnlineOfficeBinToPdf oReader.Skip(nLen - 9); break; } + case AddCommandType::MovePage: + { + int nPos = oReader.ReadInt(); + pPdf->MovePage(nPageNum, nPos); + + NSOnlineOfficeBinToPdf::ConvertBufferToRenderer(oReader.GetCurrentBuffer(), (LONG)(nLen - 13) , &oCorrector); + oReader.Skip(nLen - 13); + break; + } case AddCommandType::RemovePage: { pPdf->DeletePage(nPageNum); diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 2874f4ce90..fe0ee45886 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -895,7 +895,7 @@ void CPdfEditor::GetPageTree(XRef* xref, Object* pPagesRefObj, PdfWriter::CPageT } kidsArrObj.free(); } -bool CPdfEditor::EditPage(int nPageIndex, bool bSet) +bool CPdfEditor::EditPage(int nPageIndex, bool bSet, int nNewPage) { PDFDoc* pPDFDocument = pReader->GetPDFDocument(); PdfWriter::CDocument* pDoc = pWriter->GetDocument(); @@ -1030,7 +1030,7 @@ bool CPdfEditor::EditPage(int nPageIndex, bool bSet) pageObj.free(); // Применение редактирования страницы для writer - if (pDoc->EditPage(pXref, pPage, nPageIndex)) + if (pDoc->EditPage(pXref, pPage, nPageIndex, nNewPage)) { if (bSet) { @@ -1073,6 +1073,15 @@ bool CPdfEditor::AddPage(int nPageIndex) pWriter->put_Height(dHeight); return true; } +bool CPdfEditor::MovePage(int nPageIndex, int nPos) +{ + if (EditPage(nPageIndex)) + { + m_nEditPage = nPos; + return pWriter->GetDocument()->MovePage(nPageIndex, nPos); + } + return false; +} bool CPdfEditor::EditAnnot(int nPageIndex, int nID) { PDFDoc* pPDFDocument = pReader->GetPDFDocument(); diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h index 61e3b15513..d5439c8644 100644 --- a/PdfFile/PdfEditor.h +++ b/PdfFile/PdfEditor.h @@ -44,9 +44,10 @@ public: int GetError(); void Close(); - bool EditPage(int nPageIndex, bool bSet = true); + bool EditPage(int nPageIndex, bool bSet = true, int nNewPage = -1); bool DeletePage(int nPageIndex); bool AddPage(int nPageIndex); + bool MovePage(int nPageIndex, int nPos); bool EditAnnot(int nPageIndex, int nID); bool DeleteAnnot(int nID, Object* oAnnots = NULL); bool EditWidgets(IAdvancedCommand* pCommand); diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index bede929870..25b9164474 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -165,6 +165,12 @@ bool CPdfFile::AddPage(int nPageIndex) return false; return m_pInternal->pEditor->AddPage(nPageIndex); } +bool CPdfFile::MovePage(int nPageIndex, int nPos) +{ + if (!m_pInternal->pEditor) + return false; + return m_pInternal->pEditor->MovePage(nPageIndex, nPos); +} HRESULT CPdfFile::ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword) { RELEASEOBJECT(m_pInternal->pWriter); diff --git a/PdfFile/PdfFile.h b/PdfFile/PdfFile.h index dc64c231df..d055c338c6 100644 --- a/PdfFile/PdfFile.h +++ b/PdfFile/PdfFile.h @@ -97,6 +97,7 @@ public: bool EditPage (int nPageIndex); bool DeletePage (int nPageIndex); bool AddPage (int nPageIndex); + bool MovePage (int nPageIndex, int nPos); HRESULT ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword = L""); #endif diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 237e6edf64..120205ebc3 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -1442,7 +1442,7 @@ namespace PdfWriter return pRes; } - bool CDocument::EditPage(CXref* pXref, CPage* pPage, int nPageIndex) + bool CDocument::EditPage(CXref* pXref, CPage* pPage, int nPageIndex, int nNewPage) { if (!pPage || !EditXref(pXref)) return false; @@ -1454,7 +1454,10 @@ namespace PdfWriter #endif m_pCurPage = pPage; - m_mEditPages[nPageIndex] = pPage; + if (nNewPage > 0) + m_mEditPages[nNewPage] = pPage; + else + m_mEditPages[nPageIndex] = pPage; if (m_pPageTree) m_pPageTree->ReplacePage(nPageIndex, pPage); @@ -1589,6 +1592,16 @@ namespace PdfWriter } return false; } + bool CDocument::MovePage(int nPageIndex, int nPos) + { + if (m_pPageTree) + { + CObjectBase* pObj = m_pPageTree->RemovePage(nPageIndex); + if (pObj->GetType() == object_type_DICT && ((CDictObject*)pObj)->GetDictType() == dict_type_PAGE) + return m_pPageTree->InsertPage(nPageIndex, (CPage*)pObj); + } + return false; + } bool CDocument::AddToFile(CXref* pXref, CDictObject* pTrailer, CXref* pInfoXref, CInfoDict* pInfo) { if (!pTrailer || m_wsFilePath.empty()) diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index 6e5fc1f065..af1888598f 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -191,9 +191,10 @@ namespace PdfWriter bool EditPdf(const std::wstring& wsPath, 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); + bool EditPage(CXref* pXref, CPage* pPage, int nPageIndex, int nNewPage = -1); CPage* AddPage(int nPageIndex); bool DeletePage(int nPageIndex); + 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; } From aeb657ef25b64860a58f9748a8318056d15e0b70 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 31 Jan 2025 14:53:23 +0300 Subject: [PATCH 008/186] Fix MovePage --- PdfFile/PdfEditor.cpp | 2 +- PdfFile/SrcWriter/Document.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index fe0ee45886..7c939042e6 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -1075,7 +1075,7 @@ bool CPdfEditor::AddPage(int nPageIndex) } bool CPdfEditor::MovePage(int nPageIndex, int nPos) { - if (EditPage(nPageIndex)) + if (EditPage(nPageIndex, true, nPos)) { m_nEditPage = nPos; return pWriter->GetDocument()->MovePage(nPageIndex, nPos); diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 120205ebc3..bfc8de3469 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -1598,7 +1598,7 @@ namespace PdfWriter { CObjectBase* pObj = m_pPageTree->RemovePage(nPageIndex); if (pObj->GetType() == object_type_DICT && ((CDictObject*)pObj)->GetDictType() == dict_type_PAGE) - return m_pPageTree->InsertPage(nPageIndex, (CPage*)pObj); + return m_pPageTree->InsertPage(nPos, (CPage*)pObj); } return false; } From e7a462fb604cf8c222a17bbe843a2d80e48f8f06 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 4 Feb 2025 13:10:54 +0300 Subject: [PATCH 009/186] Fix actual pos MovePage --- PdfFile/OnlineOfficeBinToPdf.cpp | 3 --- PdfFile/PdfEditor.cpp | 9 +++++---- PdfFile/PdfEditor.h | 2 +- PdfFile/PdfWriter.cpp | 4 +++- PdfFile/SrcWriter/Document.cpp | 16 +++++++--------- PdfFile/SrcWriter/Document.h | 3 ++- PdfFile/SrcWriter/Pages.cpp | 16 ++++++++++++++++ PdfFile/SrcWriter/Pages.h | 1 + 8 files changed, 35 insertions(+), 19 deletions(-) diff --git a/PdfFile/OnlineOfficeBinToPdf.cpp b/PdfFile/OnlineOfficeBinToPdf.cpp index 674f2c30e6..b9bf950496 100644 --- a/PdfFile/OnlineOfficeBinToPdf.cpp +++ b/PdfFile/OnlineOfficeBinToPdf.cpp @@ -203,9 +203,6 @@ namespace NSOnlineOfficeBinToPdf { int nPos = oReader.ReadInt(); pPdf->MovePage(nPageNum, nPos); - - NSOnlineOfficeBinToPdf::ConvertBufferToRenderer(oReader.GetCurrentBuffer(), (LONG)(nLen - 13) , &oCorrector); - oReader.Skip(nLen - 13); break; } case AddCommandType::RemovePage: diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 7c939042e6..d16f2ae2b0 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -895,14 +895,15 @@ void CPdfEditor::GetPageTree(XRef* xref, Object* pPagesRefObj, PdfWriter::CPageT } kidsArrObj.free(); } -bool CPdfEditor::EditPage(int nPageIndex, bool bSet, int nNewPage) +bool CPdfEditor::EditPage(int nPageIndex, bool bSet, bool bActualPos) { PDFDoc* pPDFDocument = pReader->GetPDFDocument(); PdfWriter::CDocument* pDoc = pWriter->GetDocument(); if (!pPDFDocument || !pDoc) return false; - PdfWriter::CPage* pEditPage = pDoc->GetEditPage(nPageIndex); + PdfWriter::CPage* pEditPage = NULL; + pEditPage = bActualPos ? pDoc->GetPage(nPageIndex) : pDoc->GetEditPage(nPageIndex); if (pEditPage) { if (bSet) @@ -1030,7 +1031,7 @@ bool CPdfEditor::EditPage(int nPageIndex, bool bSet, int nNewPage) pageObj.free(); // Применение редактирования страницы для writer - if (pDoc->EditPage(pXref, pPage, nPageIndex, nNewPage)) + if (pDoc->EditPage(pXref, pPage, nPageIndex)) { if (bSet) { @@ -1075,7 +1076,7 @@ bool CPdfEditor::AddPage(int nPageIndex) } bool CPdfEditor::MovePage(int nPageIndex, int nPos) { - if (EditPage(nPageIndex, true, nPos)) + if (EditPage(nPageIndex, true, true)) { m_nEditPage = nPos; return pWriter->GetDocument()->MovePage(nPageIndex, nPos); diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h index d5439c8644..c41b5bcd9f 100644 --- a/PdfFile/PdfEditor.h +++ b/PdfFile/PdfEditor.h @@ -44,7 +44,7 @@ public: int GetError(); void Close(); - bool EditPage(int nPageIndex, bool bSet = true, int nNewPage = -1); + bool EditPage(int nPageIndex, bool bSet = true, bool bActualPos = false); bool DeletePage(int nPageIndex); bool AddPage(int nPageIndex); bool MovePage(int nPageIndex, int nPos); diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 8773c83440..e455a0f285 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -1677,7 +1677,9 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF CAnnotFieldInfo& oInfo = *pFieldInfo; PdfWriter::CAnnotation* pAnnot = NULL; - PdfWriter::CPage* pOrigPage = m_pDocument->GetPage(oInfo.GetPage()); + PdfWriter::CPage* pOrigPage = m_pDocument->GetEditPage(oInfo.GetPage()); + if (!pOrigPage) + pOrigPage = m_pDocument->GetPage(oInfo.GetPage()); PdfWriter::CPage* pPage = m_pPage; int nID = oInfo.GetID(); diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index bfc8de3469..3a8727a72c 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -353,10 +353,6 @@ namespace PdfWriter } CPage* CDocument::GetPage(const unsigned int &unPage) { - CPage* pRes = GetEditPage(unPage); - if (pRes) - return pRes; - if (unPage >= m_pPageTree->GetCount()) return NULL; @@ -370,6 +366,11 @@ namespace PdfWriter pRes = p->second; return pRes; } + int CDocument::FindPage(CPage* pPage) + { + int nI = 0; + return m_pPageTree->Find(pPage, nI) ? nI : -1; + } unsigned int CDocument::GetPagesCount() const { return m_pPageTree->GetCount(); @@ -1442,7 +1443,7 @@ namespace PdfWriter return pRes; } - bool CDocument::EditPage(CXref* pXref, CPage* pPage, int nPageIndex, int nNewPage) + bool CDocument::EditPage(CXref* pXref, CPage* pPage, int nPageIndex) { if (!pPage || !EditXref(pXref)) return false; @@ -1454,10 +1455,7 @@ namespace PdfWriter #endif m_pCurPage = pPage; - if (nNewPage > 0) - m_mEditPages[nNewPage] = pPage; - else - m_mEditPages[nPageIndex] = pPage; + m_mEditPages[nPageIndex] = pPage; if (m_pPageTree) m_pPageTree->ReplacePage(nPageIndex, pPage); diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index af1888598f..9bbb4045b6 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -123,6 +123,7 @@ namespace PdfWriter CPage* AddPage(); CPage* GetPage (const unsigned int& unPage); CPage* GetEditPage(const unsigned int& unPage); + int FindPage (CPage* pPage); unsigned int GetPagesCount() const; void AddPageLabel(EPageNumStyle eStyle, unsigned int unFirstPage, const char* sPrefix); void AddPageLabel(unsigned int unPageIndex, EPageNumStyle eStyle, unsigned int unFirstPage, const char* sPrefix); @@ -191,7 +192,7 @@ namespace PdfWriter bool EditPdf(const std::wstring& wsPath, 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, int nNewPage = -1); + bool EditPage(CXref* pXref, CPage* pPage, int nPageIndex); CPage* AddPage(int nPageIndex); bool DeletePage(int nPageIndex); bool MovePage(int nPageIndex, int nPos); diff --git a/PdfFile/SrcWriter/Pages.cpp b/PdfFile/SrcWriter/Pages.cpp index 8212a8f984..8b470e79f9 100644 --- a/PdfFile/SrcWriter/Pages.cpp +++ b/PdfFile/SrcWriter/Pages.cpp @@ -271,6 +271,22 @@ namespace PdfWriter return true; return false; } + bool CPageTree::Find(CPage* pPage, int& nI) + { + for (int i = 0, count = m_pPages->GetCount(); i < count; ++i) + { + CObjectBase* pObj = m_pPages->Get(i); + if (pObj->GetType() == object_type_DICT && ((CDictObject*)pObj)->GetDictType() == dict_type_PAGES && ((CPageTree*)pObj)->Find(pPage, nI)) + return true; + else + { + if (pPage == pObj) + return true; + nI++; + } + } + return false; + } CObjectBase* CPageTree::GetFromPageTree(int nPageIndex, int& nI, bool bRemove, bool bInsert, CPage* pPage) { for (int i = 0, count = m_pPages->GetCount(); i < count; ++i) diff --git a/PdfFile/SrcWriter/Pages.h b/PdfFile/SrcWriter/Pages.h index 29099cc4dd..a264940131 100644 --- a/PdfFile/SrcWriter/Pages.h +++ b/PdfFile/SrcWriter/Pages.h @@ -72,6 +72,7 @@ namespace PdfWriter bool InsertPage(int nPageIndex, CPage* pPage); bool ReplacePage(int nPageIndex, CPage* pPage); bool Join(CPageTree* pPageTree); + bool Find(CPage* pPage, int& nI); unsigned int GetCount() { return m_pCount ? m_pCount->Get() : 0; From 8a86347eb6869eb4fc9f176d968798a8c866b4d4 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 5 Feb 2025 13:56:51 +0300 Subject: [PATCH 010/186] Fix build --- DesktopEditor/graphics/pro/js/qt/nativegraphics.pro | 2 ++ DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js | 3 +++ PdfFile/PdfFile.cpp | 4 +--- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro b/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro index 3b3710f95f..8f532e4fa5 100644 --- a/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro +++ b/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro @@ -682,6 +682,7 @@ HEADERS += \ $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/DropCap.h \ $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Paragraph.h \ $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Shape.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Table.h \ $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/TextLine.h \ $$DOCX_RENDERER_ROOT_DIR/src/logic/managers/ExternalImageStorage.h \ $$DOCX_RENDERER_ROOT_DIR/src/logic/managers/FontStyleManager.h \ @@ -706,6 +707,7 @@ SOURCES += \ $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/ContText.cpp \ $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Paragraph.cpp \ $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Shape.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Table.cpp \ $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/TextLine.cpp \ $$DOCX_RENDERER_ROOT_DIR/src/logic/managers/FontManager.cpp \ $$DOCX_RENDERER_ROOT_DIR/src/logic/managers/FontStyleManager.cpp \ diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js index 7e8820c5fa..a5f8645d11 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js @@ -496,6 +496,9 @@ function readAnnot(reader, rec, readDoubleFunc, readDouble2Func, readStringFunc, // User ID if (flags & (1 << 7)) rec["OUserID"] = readStringFunc.call(reader); + // User ID + if (flags & (1 << 8)) + rec["AP"]["Copy"] = reader.readInt(); } function readAnnotAP(reader, AP) { diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 382387125a..4d23555b37 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -36,14 +36,12 @@ #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" -#include "Resources/BaseFonts.h" - #else class CPdfEditor { From d196a15a0e5f17a82afda1d6be1dcf887b7332e4 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 5 Feb 2025 20:06:59 +0600 Subject: [PATCH 011/186] Change xlst->xlsb conversion --- OOXML/Binary/Sheets/Writer/BinaryReader.cpp | 6 +++++- OOXML/Binary/Sheets/Writer/BinaryReader.h | 1 + X2tConverter/src/lib/xlsx.h | 15 ++++----------- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index 2963967f66..c11c98d3ca 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp @@ -8893,7 +8893,11 @@ 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.Read(); }break; case c_oSerTableTypes::Customs: { diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.h b/OOXML/Binary/Sheets/Writer/BinaryReader.h index d1551af149..91dd6b86c4 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.h +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.h @@ -403,6 +403,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/X2tConverter/src/lib/xlsx.h b/X2tConverter/src/lib/xlsx.h index 2e82444d64..89c01c7d3a 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 @@ -178,8 +178,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 +192,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 +272,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 From e2df5a8ab0605f5d32de406a54854faee4f15490 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 6 Feb 2025 11:58:24 +0300 Subject: [PATCH 012/186] Fix C&IC FreeText --- .../graphics/pro/js/wasm/js/drawingfile.js | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js index a5f8645d11..bece983daf 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js @@ -747,7 +747,7 @@ function readAnnotType(reader, rec, readDoubleFunc, readDouble2Func, readStringF else if (rec["Type"] == 2) { // Background color - C->IC - if (rec["C"]) + if (!isRead && rec["C"]) { rec["IC"] = rec["C"]; delete rec["C"]; @@ -785,9 +785,18 @@ function readAnnotType(reader, rec, readDoubleFunc, readDouble2Func, readStringF if (flags & (1 << 21)) { let n = reader.readInt(); - rec["C"] = []; - for (let i = 0; i < n; ++i) - rec["C"].push(readDouble2Func.call(reader)); + 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 From eb751507c031e9fe82674c764a64d3f4d74c9260 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 7 Feb 2025 13:32:02 +0600 Subject: [PATCH 013/186] Add worksheet direct conversion method --- OOXML/Binary/Sheets/Writer/BinaryReader.cpp | 46 +++++++++++++++++++-- OOXML/Binary/Sheets/Writer/BinaryReader.h | 3 ++ 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index c11c98d3ca..9c6857e713 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp @@ -4074,6 +4074,13 @@ 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; + READ_TABLE_DEF(res, this->ReadWorksheetsTableContent, this); + return res; +} int BinaryWorksheetsTableReader::ReadWorksheetsTableContent(BYTE type, long length, void* poResult) { int res = c_oSerConstants::ReadOk; @@ -4090,22 +4097,35 @@ int BinaryWorksheetsTableReader::ReadWorksheetsTableContent(BYTE type, long leng boost::unordered_map> mapPos; READ1_DEF(length, res, this->ReadWorksheetSeekPositions, &mapPos); - - m_pCurWorksheet->m_bWriteDirectlyToFile = true; + if(!m_bWriteToXlsb) + 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); + res = ReadWorksheet(mapPos, streamWriter, poResult); + m_pXlsb->WriteSreamCache(streamWriter); + } if (m_pCurSheet->m_oName.IsInit()) { const OOX::RId oRId = m_oWorkbook.Add(oCurWorksheetFile); @@ -4574,6 +4594,20 @@ int BinaryWorksheetsTableReader::ReadWorksheet(boost::unordered_maptoXMLEnd(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); + } + + { + auto endSheet = oStreamWriter->getNextRecord(XLSB::rt_EndSheet); + oStreamWriter->storeNextRecord(endSheet); + } + return res; +} void BinaryWorksheetsTableReader::WriteComments() { if (m_pCurWorksheet->m_mapComments.empty()) return; @@ -8896,8 +8930,12 @@ int BinaryFileReader::ReadMainTable(OOX::Spreadsheet::CXlsx& oXlsx, NSBinPptxRW: 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.Read(); + res = sheetreader.Read2xlsb(*xlsb); + } + else + res = sheetreader.Read(); }break; case c_oSerTableTypes::Customs: { diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.h b/OOXML/Binary/Sheets/Writer/BinaryReader.h index 91dd6b86c4..5b71e85260 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.h +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.h @@ -302,6 +302,7 @@ namespace BinXlsxRW Binary_CommonReader2 m_oBcr2; NSFile::CStreamWriter* m_pCurStreamWriter; NSBinPptxRW::CDrawingConverter* m_pOfficeDrawingConverter; + OOX::Spreadsheet::CXlsb* m_pXlsb; OOX::Spreadsheet::CWorkbook& m_oWorkbook; OOX::Spreadsheet::CSharedStrings* m_pSharedStrings; @@ -330,9 +331,11 @@ 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 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 ReadPivotTable(BYTE type, long length, void* poResult); int ReadWorksheetProp(BYTE type, long length, void* poResult); int ReadWorksheetCols(BYTE type, long length, void* poResult); From 9352721ec48858bfab5aa5f833b7756cf5cba2ad Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 7 Feb 2025 10:44:31 +0300 Subject: [PATCH 014/186] Fix copy Stamp InRect --- .../graphics/pro/js/wasm/js/drawingfile.js | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js index bece983daf..cc47211257 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js @@ -591,7 +591,7 @@ function readAnnotType(reader, rec, readDoubleFunc, readDouble2Func, readStringF // Text if (rec["Type"] == 0) { - // Bachground color - C->IC + // Background color - C->IC if (rec["C"]) { rec["IC"] = rec["C"]; @@ -919,19 +919,8 @@ function readAnnotType(reader, rec, readDoubleFunc, readDouble2Func, readStringF rec["Icon"] = readStringFunc.call(reader); rec["Rotate"] = readDouble2Func.call(reader); rec["InRect"] = []; - if (isRead) - { - let x1 = readDouble2Func.call(reader); - let y1 = readDouble2Func.call(reader); - let x2 = readDouble2Func.call(reader); - let y2 = readDouble2Func.call(reader); - rec["InRect"] = [ x1, y1, x1, y2, x2, y2, y1, x2 ]; - } - else - { - for (let i = 0; i < 8; ++i) - rec["InRect"].push(readDouble2Func.call(reader)); - } + for (let i = 0; i < 8; ++i) + rec["InRect"].push(readDouble2Func.call(reader)); } } function readWidgetType(reader, rec, readDoubleFunc, readDouble2Func, readStringFunc, isRead = false) From 662f318d6bd7afb5ac592396d0227df7b7102711 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 7 Feb 2025 15:39:51 +0600 Subject: [PATCH 015/186] add workbook conversion --- OOXML/Binary/Sheets/Writer/BinaryReader.cpp | 27 +++++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index 9c6857e713..5d0f37a70a 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp @@ -4113,12 +4113,12 @@ int BinaryWorksheetsTableReader::ReadWorksheetsTableContent(BYTE type, long leng 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(); + NSFile::CStreamWriter oStreamWriter; + oStreamWriter.CreateFileW(sWsPath); + + m_pCurStreamWriter = &oStreamWriter; + res = ReadWorksheet(mapPos, oStreamWriter, poResult); + oStreamWriter.CloseFile(); } else { @@ -4134,7 +4134,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(); } } @@ -4601,7 +4602,12 @@ int BinaryWorksheetsTableReader::ReadWorksheet(boost::unordered_mapgetNextRecord(XLSB::rt_BeginSheet); oStreamWriter->storeNextRecord(beginSHeet); } - + boost::unordered_map>::iterator pFind; + LONG nPos; + LONG length; + SEEK_TO_POS_START(c_oSerWorksheetsTypes::WorksheetProp); + READ2_DEF_SPREADSHEET(length, res, this->ReadWorksheetProp, poResult); + SEEK_TO_POS_END2(); { auto endSheet = oStreamWriter->getNextRecord(XLSB::rt_EndSheet); oStreamWriter->storeNextRecord(endSheet); @@ -8761,6 +8767,11 @@ 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); + oXlsb.m_pWorkbook->OOX::File::m_pMainDocument = &oXlsb; + oXlsb.m_pStyles->OOX::File::m_pMainDocument = &oXlsb; + oXlsb.m_pSharedStrings->OOX::File::m_pMainDocument = &oXlsb; oXlsb.PrepareToWrite(); oXlsb.WriteBin(sDstPath, *oSaveParams.pContentTypes); From 650a5c4c1fa9a8fa72096dc788de900368e51796 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 10 Feb 2025 16:12:16 +0600 Subject: [PATCH 016/186] Add simple worksheet xlsb writing --- OOXML/Binary/Sheets/Writer/BinaryReader.cpp | 32 +++++++++++++++++---- OOXML/Binary/Sheets/Writer/BinaryReader.h | 1 + OOXML/XlsxFormat/Worksheets/SheetData.h | 2 +- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index 5d0f37a70a..0e3fb28ba9 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp @@ -4097,8 +4097,7 @@ int BinaryWorksheetsTableReader::ReadWorksheetsTableContent(BYTE type, long leng boost::unordered_map> mapPos; READ1_DEF(length, res, this->ReadWorksheetSeekPositions, &mapPos); - if(!m_bWriteToXlsb) - m_pCurWorksheet->m_bWriteDirectlyToFile = true; + m_pCurWorksheet->m_bWriteDirectlyToFile = true; smart_ptr oCurWorksheetFile = m_pCurWorksheet.smart_dynamic_cast(); //for correct file extension @@ -4123,6 +4122,7 @@ int BinaryWorksheetsTableReader::ReadWorksheetsTableContent(BYTE type, long leng else { auto streamWriter = m_pXlsb->GetFileWriter(sWsPath); + m_pCurStreamWriterBin = streamWriter; res = ReadWorksheet(mapPos, streamWriter, poResult); m_pXlsb->WriteSreamCache(streamWriter); } @@ -4206,7 +4206,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; @@ -4608,6 +4608,19 @@ int BinaryWorksheetsTableReader::ReadWorksheet(boost::unordered_mapReadWorksheetProp, poResult); 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); + { + auto end = m_pCurStreamWriterBin->getNextRecord(XLSB::rt_EndSheetData); + m_pCurStreamWriterBin->storeNextRecord(end); + } + SEEK_TO_POS_END2() + { auto endSheet = oStreamWriter->getNextRecord(XLSB::rt_EndSheet); oStreamWriter->storeNextRecord(endSheet); @@ -6300,12 +6313,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); @@ -6379,10 +6397,14 @@ 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) + { + oCell.toBin(m_pCurStreamWriterBin); + } else { m_oSaveParams.pCSVWriter->WriteCell(&oCell); diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.h b/OOXML/Binary/Sheets/Writer/BinaryReader.h index 5b71e85260..722205a32c 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.h +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.h @@ -301,6 +301,7 @@ namespace BinXlsxRW { Binary_CommonReader2 m_oBcr2; NSFile::CStreamWriter* m_pCurStreamWriter; + XLS::StreamCacheWriterPtr m_pCurStreamWriterBin; NSBinPptxRW::CDrawingConverter* m_pOfficeDrawingConverter; OOX::Spreadsheet::CXlsb* m_pXlsb; diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.h b/OOXML/XlsxFormat/Worksheets/SheetData.h index cb03de47c3..50132fa6c4 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); From 6411aed137c8ecb9489bd8ed0d07deccc711a0d9 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 10 Feb 2025 21:33:10 +0600 Subject: [PATCH 017/186] Fix shared formula conversion --- OOXML/Binary/Sheets/Reader/BinaryWriter.cpp | 2 +- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp index 9d6714908f..6d25a9abb3 100644 --- a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp +++ b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp @@ -8691,7 +8691,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/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index a0f84fefce..2277310630 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -1894,7 +1894,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(nRow, xlsx->m_nLastReadCol); } void CCell::AfterRead() { @@ -2708,7 +2708,7 @@ namespace OOX } else { - CellReference.row = m_oRow.get() - 1; + CellReference.row = m_oRow.get(); CellReference.column = m_oCol.get(); } if(SharedFormulasRef::ArrayRefsLocations && SharedFormulasRef::ArrayRefsLocations->size()) @@ -3507,7 +3507,7 @@ namespace OOX if (parseRefA(m_oRef->c_str(), nRow, nCol)) { bRes = true; - //nRow--; + nRow--; nCol--; } } From 7e8e4586ca6a98df89078ce5a78b4fa4806a8351 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 10 Feb 2025 18:34:57 +0300 Subject: [PATCH 018/186] Create SplitPage --- PdfFile/PdfEditor.cpp | 277 +++++++++++++++++++++++++++++---- PdfFile/PdfEditor.h | 1 + PdfFile/PdfFile.cpp | 7 + PdfFile/PdfFile.h | 1 + PdfFile/SrcWriter/Document.cpp | 4 + PdfFile/SrcWriter/Document.h | 2 + PdfFile/SrcWriter/Objects.cpp | 16 +- PdfFile/SrcWriter/Objects.h | 4 +- PdfFile/lib/goo/GString.cc | 8 +- PdfFile/lib/goo/GString.h | 5 +- PdfFile/lib/xpdf/Lexer.cc | 4 +- PdfFile/lib/xpdf/TextString.cc | 7 + PdfFile/lib/xpdf/TextString.h | 2 + PdfFile/test/test.cpp | 15 ++ 14 files changed, 308 insertions(+), 45 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index bdc7ec1dfb..6549f55ce2 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -54,14 +54,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 +77,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 +112,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 +125,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,6 +149,106 @@ void DictToCDictObject(Object* obj, PdfWriter::CObjectBase* pObj, bool bBinary, break; } } +PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CObjectBase* pObj, const std::string& sKey, PdfWriter::CDocument* pDoc, XRef* xref, bool bNeedAdd) +{ + 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(); + for (int nIndex = 0; nIndex < obj->arrayGetLength(); ++nIndex) + { + obj->arrayGetNF(nIndex, &oTemp); + DictToCDictObject2(&oTemp, pArray, "", pDoc, xref, false); + oTemp.free(); + } + break; + } + case objDict: + { + PdfWriter::CDictObject* pDict = new PdfWriter::CDictObject(); + for (int nIndex = 0; nIndex < obj->dictGetLength(); ++nIndex) + { + char* chKey = obj->dictGetKey(nIndex); + obj->dictGetValNF(nIndex, &oTemp); + DictToCDictObject2(&oTemp, pDict, chKey, pDoc, xref, false); + oTemp.free(); + } + break; + } + case objRef: + { + obj->fetch(xref, &oTemp); + pBase = DictToCDictObject2(&oTemp, pObj, "", pDoc, xref, true); + oTemp.free(); + break; + } + case objNone: + { + pBase = new PdfWriter::CNameObject("None"); + break; + } + case objStream: + { + break; + } + case objCmd: + case objError: + case objEOF: + break; + } + if (bNeedAdd) + pDoc->AddObject(pBase); + AddToObject(pBase) + return pBase; +} PdfWriter::CDictObject* GetWidgetParent(PDFDoc* pdfDoc, PdfWriter::CDocument* pDoc, Object* pParentRef) { if (!pParentRef || !pParentRef->isRef() || !pdfDoc) @@ -193,7 +292,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(); } @@ -285,7 +384,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 +398,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 +437,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 +471,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(); } @@ -578,7 +677,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 +687,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 +700,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 +758,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 +769,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(); @@ -731,7 +830,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,7 +863,7 @@ 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); @@ -851,7 +950,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 +970,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); @@ -966,7 +1065,7 @@ bool CPdfEditor::EditPage(int nPageIndex, bool bSet) oTemp.dictGetVal(nIndex, &oRes); else oTemp.dictGetValNF(nIndex, &oRes); - DictToCDictObject(&oRes, pDict, false, chKey2); + DictToCDictObject(&oRes, pDict, chKey2); oRes.free(); } @@ -989,7 +1088,7 @@ bool CPdfEditor::EditPage(int nPageIndex, bool bSet) { Object oAnnot; oTemp.arrayGetNF(nIndex, &oAnnot); - DictToCDictObject(&oAnnot, pArray, false, ""); + DictToCDictObject(&oAnnot, pArray, ""); oAnnot.free(); } oTemp.free(); @@ -1005,7 +1104,7 @@ bool CPdfEditor::EditPage(int nPageIndex, bool bSet) { if (pageObj.dictGetVal(nIndex, &oTemp)->isArray()) { - DictToCDictObject(&oTemp, pPage, true, chKey); + DictToCDictObject(&oTemp, pPage, chKey); oTemp.free(); continue; } @@ -1021,7 +1120,7 @@ bool CPdfEditor::EditPage(int nPageIndex, bool bSet) } else pageObj.dictGetValNF(nIndex, &oTemp); - DictToCDictObject(&oTemp, pPage, true, chKey); + DictToCDictObject(&oTemp, pPage, chKey); oTemp.free(); } pPage->Fix(); @@ -1052,6 +1151,121 @@ bool CPdfEditor::EditPage(int nPageIndex, bool bSet) RELEASEOBJECT(pXref); return false; } +bool CPdfEditor::SplitPage(int nPageIndex) +{ + PDFDoc* pPDFDocument = pReader->GetPDFDocument(); + PdfWriter::CDocument* pDoc = pWriter->GetDocument(); + if (!pPDFDocument || !pDoc) + return false; + + XRef* xref = pPDFDocument->getXRef(); + Catalog* pCatalog = pPDFDocument->getCatalog(); + if (!xref || !pCatalog) + return false; + std::pair pPageRef = pDoc->GetPageRef(nPageIndex); + if (pPageRef.first == 0) + return false; + + HRESULT nRes = pWriter->NewPage(); + if (nRes == S_FALSE) + return false; + PdfWriter::CPage* pPage = pWriter->GetPage(); + if (!pPage) + return false; + + // Получение объекта страницы + Object pageRefObj, pageObj; + pageRefObj.initRef(pPageRef.first, pPageRef.second); + if (!pageRefObj.fetch(xref, &pageObj) || !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) + { + if (pageObj.dictGetVal(nIndex, &oTemp)->isDict()) + { + PdfWriter::CResourcesDict* pDict = new PdfWriter::CResourcesDict(NULL, true, false); + pPage->Add("Resources", pDict); + for (int nIndex = 0; nIndex < oTemp.dictGetLength(); ++nIndex) + { + Object oRes; + char* chKey2 = oTemp.dictGetKey(nIndex); + if (strcmp("Font", chKey2) == 0 || strcmp("ExtGState", chKey2) == 0 || strcmp("XObject", chKey2) == 0 || strcmp("Shading", chKey2) == 0 || strcmp("Pattern", chKey2) == 0) + oTemp.dictGetVal(nIndex, &oRes); + else + oTemp.dictGetValNF(nIndex, &oRes); + DictToCDictObject2(&oRes, pDict, chKey2, pDoc, xref, false); + oRes.free(); + } + + oTemp.free(); + continue; + } + else + { + oTemp.free(); + pageObj.dictGetValNF(nIndex, &oTemp); + } + } + else if (strcmp("Annots", chKey) == 0) + { + if (pageObj.dictGetVal(nIndex, &oTemp)->isArray()) + { + PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject(); + pPage->Add("Annots", pArray); + for (int nIndex = 0; nIndex < oTemp.arrayGetLength(); ++nIndex) + { + Object oAnnot; + oTemp.arrayGetNF(nIndex, &oAnnot); + DictToCDictObject2(&oAnnot, pArray, "", pDoc, xref, false); + oAnnot.free(); + } + oTemp.free(); + continue; + } + else + { + oTemp.free(); + pageObj.dictGetValNF(nIndex, &oTemp); + } + } + else if (strcmp("Contents", chKey) == 0) + { + if (pageObj.dictGetVal(nIndex, &oTemp)->isArray()) + { + DictToCDictObject2(&oTemp, pPage, chKey, pDoc, xref, false); + oTemp.free(); + continue; + } + else + { + oTemp.free(); + pageObj.dictGetValNF(nIndex, &oTemp); + } + } + else if (strcmp("Parent", chKey) == 0) + { + pageObj.dictGetValNF(nIndex, &oTemp); + } + else + pageObj.dictGetValNF(nIndex, &oTemp); + DictToCDictObject2(&oTemp, pPage, chKey, pDoc, xref, false); + oTemp.free(); + } + pPage->Fix(); + pageObj.free(); + + return true; +} bool CPdfEditor::DeletePage(int nPageIndex) { return pWriter->GetDocument()->DeletePage(nPageIndex); @@ -1235,7 +1449,6 @@ 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)) { @@ -1282,11 +1495,9 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID) } oParentRef.free(); } - 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(); } @@ -1311,7 +1522,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; diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h index 61e3b15513..d173375dea 100644 --- a/PdfFile/PdfEditor.h +++ b/PdfFile/PdfEditor.h @@ -45,6 +45,7 @@ public: int GetError(); void Close(); bool EditPage(int nPageIndex, bool bSet = true); + bool SplitPage(int nPageIndex); bool DeletePage(int nPageIndex); bool AddPage(int nPageIndex); bool EditAnnot(int nPageIndex, int nID); diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index a720c61644..535407051a 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -51,6 +51,7 @@ public: int GetError() { return 0; } void Close() {} bool EditPage(int nPageIndex, bool bSet = true) { return false; } + bool SplitPage(int nPageIndex) { return false; } bool DeletePage(int nPageIndex) { return false; } bool AddPage(int nPageIndex) { return false; } bool EditAnnot(int nPageIndex, int nID) { return false; } @@ -166,6 +167,12 @@ bool CPdfFile::AddPage(int nPageIndex) return false; return m_pInternal->pEditor->AddPage(nPageIndex); } +bool CPdfFile::SplitPage(int nPageIndex) +{ + if (!m_pInternal->pEditor) + return false; + return m_pInternal->pEditor->SplitPage(nPageIndex); +} HRESULT CPdfFile::ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword) { RELEASEOBJECT(m_pInternal->pWriter); diff --git a/PdfFile/PdfFile.h b/PdfFile/PdfFile.h index dc64c231df..febe740eaa 100644 --- a/PdfFile/PdfFile.h +++ b/PdfFile/PdfFile.h @@ -97,6 +97,7 @@ public: bool EditPage (int nPageIndex); bool DeletePage (int nPageIndex); bool AddPage (int nPageIndex); + bool SplitPage (int nPageIndex); HRESULT ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword = L""); #endif diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 237e6edf64..8de13cfb20 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -1289,6 +1289,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]; diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index 6e5fc1f065..0bb55a6748 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 //---------------------------------------------------------------------------------------- @@ -195,6 +196,7 @@ namespace PdfWriter CPage* AddPage(int nPageIndex); bool DeletePage(int nPageIndex); bool AddToFile(CXref* pXref, CDictObject* pTrailer, CXref* pInfoXref, CInfoDict* pInfo); + void AddObject(CObjectBase* pObj); void Sign(const TRect& oRect, CImageDict* pImage, ICertificate* pCert); std::wstring GetEditPdfPath() { return m_wsFilePath; } bool EditAnnot (CXref* pXref, CAnnotation* pAnnot, int nID); diff --git a/PdfFile/SrcWriter/Objects.cpp b/PdfFile/SrcWriter/Objects.cpp index 1522834b98..0f1d98eefc 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 diff --git a/PdfFile/SrcWriter/Objects.h b/PdfFile/SrcWriter/Objects.h index cac33259bc..2430322680 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; 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..efdc3b9e90 100644 --- a/PdfFile/test/test.cpp +++ b/PdfFile/test/test.cpp @@ -350,6 +350,21 @@ TEST_F(CPdfFileTest, VerifySign) RELEASEOBJECT(pCertificate); } +TEST_F(CPdfFileTest, SplitPdf) +{ + GTEST_SKIP(); +} + +TEST_F(CPdfFileTest, MergePdf) +{ + GTEST_SKIP(); +} + +TEST_F(CPdfFileTest, CopyAnotherPdf) +{ + GTEST_SKIP(); +} + TEST_F(CPdfFileTest, EditPdf) { GTEST_SKIP(); From fff7f4e63f212ed50d955a337c51d21f0764931a Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 11 Feb 2025 13:47:26 +0300 Subject: [PATCH 019/186] Test SplitPages --- PdfFile/PdfEditor.cpp | 154 ++++++++++++++++++++++++------------------ PdfFile/PdfEditor.h | 14 ++-- PdfFile/PdfFile.cpp | 23 ++++++- PdfFile/PdfFile.h | 2 + PdfFile/test/test.cpp | 6 ++ 5 files changed, 129 insertions(+), 70 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 6549f55ce2..7833870f20 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -550,57 +550,58 @@ void GetCTM(XRef* pXref, Object* oPage, double* dCTM) CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPassword, CPdfReader* _pReader, const std::wstring& _wsDstFile, CPdfWriter* _pWriter) { - wsSrcFile = _wsSrcFile; - wsPassword = _wsPassword; - pReader = _pReader; - pWriter = _pWriter; + m_wsSrcFile = _wsSrcFile; + m_wsPassword = _wsPassword; + m_pReader = _pReader; + m_pWriter = _pWriter; m_nEditPage = -1; - nError = 0; + m_nError = 0; + m_nMode = 0; - PDFDoc* pPDFDocument = pReader->GetPDFDocument(); + PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); if (!pPDFDocument) { - nError = 1; + m_nError = 1; return; } // Если результат редактирования будет сохранен в тот же файл, что открыт для чтения, то файл необходимо сделать редактируемым std::string sPathUtf8New = U_TO_UTF8(_wsDstFile); - std::string sPathUtf8Old = U_TO_UTF8(wsSrcFile); + 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; // Не удалось проверить файл для записи + m_nError = 2; // Не удалось проверить файл для записи return; } } else { - if (!NSFile::CFileBinary::Copy(wsSrcFile, _wsDstFile)) + if (!NSFile::CFileBinary::Copy(m_wsSrcFile, _wsDstFile)) { - nError = 2; + m_nError = 2; return; } NSFile::CFileBinary oFile; if (!oFile.OpenFile(_wsDstFile, true)) { - nError = 2; + m_nError = 2; return; } oFile.CloseFile(); } XRef* xref = pPDFDocument->getXRef(); - PdfWriter::CDocument* pDoc = pWriter->GetDocument(); + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); if (!xref || !pDoc) { - nError = 1; + m_nError = 1; return; } @@ -609,14 +610,14 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa if (!xref->getCatalog(&catDict)->isDict() || !catDict.dictLookupNF("Pages", &pagesRefObj)) { pagesRefObj.free(); catDict.free(); - nError = 3; // Не удалось получить каталог и дерево страниц + m_nError = 3; // Не удалось получить каталог и дерево страниц return; } Object* trailer = xref->getTrailerDict(); if (!trailer || !trailer->isDict() || !trailer->dictLookupNF("Root", &catRefObj)->isRef()) { pagesRefObj.free(); catDict.free(); catRefObj.free(); - nError = 3; // Не удалось получить каталог и дерево страниц + m_nError = 3; // Не удалось получить каталог и дерево страниц return; } Ref catRef = catRefObj.getRef(); @@ -627,14 +628,14 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa if (!pXref) { pagesRefObj.free(); catDict.free(); - nError = 1; + m_nError = 1; return; } PdfWriter::CCatalog* pCatalog = new PdfWriter::CCatalog(); if (!pCatalog) { pagesRefObj.free(); catDict.free(); RELEASEOBJECT(pXref); - nError = 1; + m_nError = 1; return; } pXref->Add(pCatalog, catRef.gen); @@ -777,13 +778,13 @@ 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; // Ошибка шифрования файла + m_nError = 4; // Ошибка шифрования файла return; } } @@ -801,12 +802,37 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa } pagesRefObj.free(); if (!bRes) - nError = 5; // Ошибка применения редактирования + m_nError = 5; // Ошибка применения редактирования +} +CPdfEditor::CPdfEditor(CPdfReader* _pReader, CPdfWriter* _pWriter) +{ + m_pReader = _pReader; + m_pWriter = _pWriter; + m_nEditPage = -1; + m_nError = 0; + m_nMode = 1; + + PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); + if (!pPDFDocument) + { + m_nError = 1; + return; + } + + XRef* xref = pPDFDocument->getXRef(); + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); + if (!xref || !pDoc) + { + m_nError = 1; + return; + } } void CPdfEditor::Close() { - PDFDoc* pPDFDocument = pReader->GetPDFDocument(); - PdfWriter::CDocument* pDoc = pWriter->GetDocument(); + if (m_nMode != 0) + return; + PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); if (!pPDFDocument || !pDoc) return; XRef* xref = pPDFDocument->getXRef(); @@ -870,7 +896,7 @@ void CPdfEditor::Close() } info.free(); - if (!pWriter->EditClose() || !pDoc->AddToFile(pXref, pTrailer, pInfoXref, pInfoDict)) + if (!m_pWriter->EditClose() || !pDoc->AddToFile(pXref, pTrailer, pInfoXref, pInfoDict)) { RELEASEOBJECT(pXref); return; @@ -878,34 +904,34 @@ void CPdfEditor::Close() std::wstring wsPath = pDoc->GetEditPdfPath(); std::string sPathUtf8New = U_TO_UTF8(wsPath); - std::string sPathUtf8Old = U_TO_UTF8(wsSrcFile); + 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; @@ -996,8 +1022,8 @@ void CPdfEditor::GetPageTree(XRef* xref, Object* pPagesRefObj, PdfWriter::CPageT } bool CPdfEditor::EditPage(int nPageIndex, bool bSet) { - PDFDoc* pPDFDocument = pReader->GetPDFDocument(); - PdfWriter::CDocument* pDoc = pWriter->GetDocument(); + PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); if (!pPDFDocument || !pDoc) return false; @@ -1007,7 +1033,7 @@ bool CPdfEditor::EditPage(int nPageIndex, bool bSet) if (bSet) { pDoc->SetCurPage(pEditPage); - pWriter->EditPage(pEditPage); + m_pWriter->EditPage(pEditPage); m_nEditPage = nPageIndex; } return true; @@ -1133,7 +1159,7 @@ bool CPdfEditor::EditPage(int nPageIndex, bool bSet) { if (bSet) { - pWriter->EditPage(pPage); + m_pWriter->EditPage(pPage); m_nEditPage = nPageIndex; } pPage->StartTransform(dCTM[0], dCTM[1], dCTM[2], dCTM[3], dCTM[4], dCTM[5]); @@ -1153,8 +1179,8 @@ bool CPdfEditor::EditPage(int nPageIndex, bool bSet) } bool CPdfEditor::SplitPage(int nPageIndex) { - PDFDoc* pPDFDocument = pReader->GetPDFDocument(); - PdfWriter::CDocument* pDoc = pWriter->GetDocument(); + PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); if (!pPDFDocument || !pDoc) return false; @@ -1166,10 +1192,10 @@ bool CPdfEditor::SplitPage(int nPageIndex) if (pPageRef.first == 0) return false; - HRESULT nRes = pWriter->NewPage(); + HRESULT nRes = m_pWriter->NewPage(); if (nRes == S_FALSE) return false; - PdfWriter::CPage* pPage = pWriter->GetPage(); + PdfWriter::CPage* pPage = m_pWriter->GetPage(); if (!pPage) return false; @@ -1268,29 +1294,29 @@ bool CPdfEditor::SplitPage(int nPageIndex) } bool CPdfEditor::DeletePage(int nPageIndex) { - return pWriter->GetDocument()->DeletePage(nPageIndex); + return m_pWriter->GetDocument()->DeletePage(nPageIndex); } bool CPdfEditor::AddPage(int nPageIndex) { // Применение добавления страницы для 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::EditAnnot(int nPageIndex, int nID) { - PDFDoc* pPDFDocument = pReader->GetPDFDocument(); - PdfWriter::CDocument* pDoc = pWriter->GetDocument(); + PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); if (!pPDFDocument || !pDoc) return false; @@ -1329,7 +1355,7 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID) pEditPage = pDoc->GetCurPage(); EditPage(nPageIndex); pDoc->SetCurPage(pEditPage); - pWriter->EditPage(pEditPage); + m_pWriter->EditPage(pEditPage); } // Воспроизведение словаря аннотации из reader для writer @@ -1356,7 +1382,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 = m_pReader->GetAnnotFonts(&oAnnotRef); m_mFonts.insert(mapFont.begin(), mapFont.end()); pAnnot = new PdfWriter::CFreeTextAnnotation(pXref); } @@ -1548,8 +1574,8 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID) } bool CPdfEditor::DeleteAnnot(int nID, Object* oAnnots) { - PDFDoc* pPDFDocument = pReader->GetPDFDocument(); - PdfWriter::CDocument* pDoc = pWriter->GetDocument(); + PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); if (!pPDFDocument || !pDoc) return false; @@ -1612,8 +1638,8 @@ bool CPdfEditor::DeleteAnnot(int nID, Object* oAnnots) bool CPdfEditor::EditWidgets(IAdvancedCommand* pCommand) { CWidgetsInfo* pFieldInfo = (CWidgetsInfo*)pCommand; - PDFDoc* pPDFDocument = pReader->GetPDFDocument(); - PdfWriter::CDocument* pDoc = pWriter->GetDocument(); + PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); std::vector arrParents = pFieldInfo->GetParents(); for (CWidgetsInfo::CParent* pParent : arrParents) @@ -1633,11 +1659,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; @@ -1658,7 +1684,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(); @@ -1669,9 +1695,9 @@ bool CPdfEditor::IsEditPage() } void CPdfEditor::ClearPage() { - PDFDoc* pPDFDocument = pReader->GetPDFDocument(); + PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); XRef* xref = pPDFDocument->getXRef(); - PdfWriter::CDocument* pDoc = pWriter->GetDocument(); + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); std::pair pPageRef = pDoc->GetPageRef(m_nEditPage); // Получение объекта страницы @@ -1705,11 +1731,11 @@ 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) { @@ -1718,7 +1744,7 @@ bool CPdfEditor::IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bIt wsFontPath = it->second; if (wsFontPath.empty()) { - std::map mFonts = pReader->GetFonts(); + std::map mFonts = m_pReader->GetFonts(); std::map::iterator it2 = mFonts.find(wsFontName); if (it2 != mFonts.end()) wsFontPath = it2->second; diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h index d173375dea..c52baf57a6 100644 --- a/PdfFile/PdfEditor.h +++ b/PdfFile/PdfEditor.h @@ -41,6 +41,7 @@ class CPdfEditor { public: CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPassword, CPdfReader* _pReader, const std::wstring& _wsDstFile, CPdfWriter* _pWriter); + CPdfEditor(CPdfReader* _pReader, CPdfWriter* _pWriter); int GetError(); void Close(); @@ -63,14 +64,17 @@ public: private: void GetPageTree(XRef* xref, Object* pPagesRefObj, PdfWriter::CPageTree* pPageParent = NULL); - std::wstring wsSrcFile; - std::wstring wsPassword; + std::wstring m_wsSrcFile; + std::wstring m_wsPassword; std::map m_mFonts; - CPdfReader* pReader; - CPdfWriter* pWriter; + CPdfReader* m_pReader; + CPdfWriter* m_pWriter; - int nError; + int m_nError; + // 0 - Дозапись. pReader и pWriter работают с одним файлом + // 1 - Split. pReader и pWriter работают с разными файлами + int m_nMode; int m_nEditPage; }; diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 535407051a..e7d9419bea 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -170,9 +170,30 @@ bool CPdfFile::AddPage(int nPageIndex) bool CPdfFile::SplitPage(int nPageIndex) { if (!m_pInternal->pEditor) - return false; + { + if (!m_pInternal->pReader) + return false; + + if (!m_pInternal->pWriter) + m_pInternal->pWriter = new CPdfWriter(m_pInternal->pAppFonts, false, this); + + m_pInternal->pEditor = new CPdfEditor(m_pInternal->pReader, m_pInternal->pWriter); + if (m_pInternal->pEditor->GetError() != 0) + return false; + } return m_pInternal->pEditor->SplitPage(nPageIndex); } +bool CPdfFile::SplitPages(const std::vector& arrPageIndex) +{ + return SplitPages(arrPageIndex.data(), arrPageIndex.size()); +} +bool CPdfFile::SplitPages(const int* arrPageIndex, unsigned int unLength) +{ + bool bRes = true; + for (unsigned int i = 0; i < unLength; ++i) + bRes &= SplitPage(arrPageIndex[i]); + return bRes; +} HRESULT CPdfFile::ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword) { RELEASEOBJECT(m_pInternal->pWriter); diff --git a/PdfFile/PdfFile.h b/PdfFile/PdfFile.h index febe740eaa..36db98434c 100644 --- a/PdfFile/PdfFile.h +++ b/PdfFile/PdfFile.h @@ -98,6 +98,8 @@ public: bool DeletePage (int nPageIndex); bool AddPage (int nPageIndex); bool SplitPage (int nPageIndex); + bool SplitPages (const std::vector& arrPageIndex); + bool SplitPages (const int* arrPageIndex, unsigned int unLength); HRESULT ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword = L""); #endif diff --git a/PdfFile/test/test.cpp b/PdfFile/test/test.cpp index efdc3b9e90..0a860eb614 100644 --- a/PdfFile/test/test.cpp +++ b/PdfFile/test/test.cpp @@ -353,6 +353,12 @@ TEST_F(CPdfFileTest, VerifySign) TEST_F(CPdfFileTest, SplitPdf) { GTEST_SKIP(); + + LoadFromFile(); + + pdfFile->CreatePdf(); + + pdfFile->SplitPage(0); } TEST_F(CPdfFileTest, MergePdf) From 7556d0859d203434556e091bf81419811503b97a Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 11 Feb 2025 17:32:56 +0600 Subject: [PATCH 020/186] Fix shared fmla conversion --- OOXML/Binary/Sheets/Writer/BinaryReader.cpp | 1 + OOXML/XlsxFormat/Worksheets/SheetData.cpp | 15 +++++++++------ OOXML/XlsxFormat/Worksheets/SheetData.h | 1 + 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index 0e3fb28ba9..24602cc29a 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp @@ -4615,6 +4615,7 @@ int BinaryWorksheetsTableReader::ReadWorksheet(boost::unordered_mapstoreNextRecord(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); diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 2277310630..2356bcd333 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -4587,6 +4587,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 +4730,7 @@ namespace OOX else delete pRow; } - if(SharedFormulasRef::sharedRefsLocations) - SharedFormulasRef::sharedRefsLocations.reset(); + ClearSharedFmlaRefs(); } XLS::BaseObjectPtr CSheetData::toBin() { @@ -4781,10 +4787,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 50132fa6c4..c01066637f 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.h +++ b/OOXML/XlsxFormat/Worksheets/SheetData.h @@ -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); From ed63f9cf2944acefcc7aa060580902bf7d0fdd50 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 11 Feb 2025 19:40:31 +0600 Subject: [PATCH 021/186] Fix row cords conversion --- OOXML/Binary/Sheets/Writer/BinaryReader.cpp | 11 ++++++++--- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 6 +++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index 24602cc29a..96f51b97fe 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp @@ -6404,6 +6404,8 @@ int BinaryWorksheetsTableReader::ReadCells(BYTE type, long length, void* poResul } else if(m_pCurStreamWriterBin != NULL) { + if(oCell.m_oRow.IsInit()) + *(oCell.m_oRow) += 1; oCell.toBin(m_pCurStreamWriterBin); } else @@ -8792,9 +8794,12 @@ int BinaryFileReader::ReadFile(const std::wstring& sSrcFileName, std::wstring sD OOX::CPath oXlPath = OOX::CPath(sDstPath).GetDirectory() / oXlsb.m_pWorkbook->DefaultDirectory(); oXlsb.WriteWorkbook(oXlPath); - oXlsb.m_pWorkbook->OOX::File::m_pMainDocument = &oXlsb; - oXlsb.m_pStyles->OOX::File::m_pMainDocument = &oXlsb; - oXlsb.m_pSharedStrings->OOX::File::m_pMainDocument = &oXlsb; + if(oXlsb.m_pWorkbook) + oXlsb.m_pWorkbook->OOX::File::m_pMainDocument = &oXlsb; + 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); diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 2356bcd333..da576eabbb 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -1894,7 +1894,7 @@ namespace OOX int nCol = 0; getRowCol(nRow, nCol); xlsx->m_nLastReadCol = nCol > xlsx->m_nLastReadCol ? nCol : xlsx->m_nLastReadCol + 1; - setRowCol(nRow, xlsx->m_nLastReadCol); + setRowCol(xlsx->m_nLastReadRow, xlsx->m_nLastReadCol); } void CCell::AfterRead() { @@ -2708,7 +2708,7 @@ namespace OOX } else { - CellReference.row = m_oRow.get(); + CellReference.row = m_oRow.get() -1; CellReference.column = m_oCol.get(); } if(SharedFormulasRef::ArrayRefsLocations && SharedFormulasRef::ArrayRefsLocations->size()) @@ -3507,7 +3507,7 @@ namespace OOX if (parseRefA(m_oRef->c_str(), nRow, nCol)) { bRes = true; - nRow--; + //nRow--; nCol--; } } From ec0ed4d2f0475a16072fbc0ec8a2a740c1571e3f Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 11 Feb 2025 17:23:08 +0300 Subject: [PATCH 022/186] Unique obj split pages --- PdfFile/PdfEditor.cpp | 130 +++++++++++++++++---------------- PdfFile/PdfEditor.h | 1 + PdfFile/PdfWriter.cpp | 3 +- PdfFile/PdfWriter.h | 2 + PdfFile/SrcWriter/Document.cpp | 5 ++ PdfFile/SrcWriter/Document.h | 3 +- PdfFile/test/test.cpp | 7 +- 7 files changed, 85 insertions(+), 66 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 7833870f20..2d88844746 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -149,7 +149,7 @@ void DictToCDictObject(Object* obj, PdfWriter::CObjectBase* pObj, const std::str break; } } -PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CObjectBase* pObj, const std::string& sKey, PdfWriter::CDocument* pDoc, XRef* xref, bool bNeedAdd) +PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CDocument* pDoc, XRef* xref, std::map& mUniqueRef) { PdfWriter::CObjectBase* pBase = NULL; Object oTemp; @@ -206,9 +206,11 @@ PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CObjectBase* for (int nIndex = 0; nIndex < obj->arrayGetLength(); ++nIndex) { obj->arrayGetNF(nIndex, &oTemp); - DictToCDictObject2(&oTemp, pArray, "", pDoc, xref, false); + pBase = DictToCDictObject2(&oTemp, pDoc, xref, mUniqueRef); + pArray->Add(pBase); oTemp.free(); } + pBase = pArray; break; } case objDict: @@ -218,15 +220,24 @@ PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CObjectBase* { char* chKey = obj->dictGetKey(nIndex); obj->dictGetValNF(nIndex, &oTemp); - DictToCDictObject2(&oTemp, pDict, chKey, pDoc, xref, false); + pBase = DictToCDictObject2(&oTemp, pDoc, xref, mUniqueRef); + pDict->Add(chKey, pBase); oTemp.free(); } + pBase = pDict; break; } case objRef: { + int nObjNum = obj->getRefNum(); + std::map::iterator it = mUniqueRef.find(nObjNum); + if (it != mUniqueRef.end()) + return it->second; + obj->fetch(xref, &oTemp); - pBase = DictToCDictObject2(&oTemp, pObj, "", pDoc, xref, true); + pBase = DictToCDictObject2(&oTemp, pDoc, xref, mUniqueRef); + pDoc->AddObject(pBase); + mUniqueRef[nObjNum] = pBase; oTemp.free(); break; } @@ -237,6 +248,35 @@ PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CObjectBase* } case objStream: { + Dict* pODict = obj->streamGetDict(); + PdfWriter::CDictObject* pDict = new PdfWriter::CDictObject(); + 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, mUniqueRef); + pDict->Add(chKey, pBase); + oTemp.free(); + } + pBase = pDict; + + PdfWriter::CStream* pStream = new PdfWriter::CMemoryStream(nLength); + pDict->SetStream(pStream); + Stream* pOStream = obj->getStream()->getBaseStream(); + pOStream->reset(); + int nChar = pOStream->getChar(); + while (nChar != EOF) + { + pStream->WriteChar(nChar); + nChar = pOStream->getChar(); + } break; } case objCmd: @@ -244,9 +284,7 @@ PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CObjectBase* case objEOF: break; } - if (bNeedAdd) - pDoc->AddObject(pBase); - AddToObject(pBase) + return pBase; } PdfWriter::CDictObject* GetWidgetParent(PDFDoc* pdfDoc, PdfWriter::CDocument* pDoc, Object* pParentRef) @@ -1188,21 +1226,18 @@ bool CPdfEditor::SplitPage(int nPageIndex) Catalog* pCatalog = pPDFDocument->getCatalog(); if (!xref || !pCatalog) return false; - std::pair pPageRef = pDoc->GetPageRef(nPageIndex); - if (pPageRef.first == 0) + Ref* pPageRef = pCatalog->getPageRef(nPageIndex + 1); + if (pPageRef->num == 0) return false; - HRESULT nRes = m_pWriter->NewPage(); - if (nRes == S_FALSE) - return false; - PdfWriter::CPage* pPage = m_pWriter->GetPage(); - if (!pPage) - return false; + PdfWriter::CPage* pPage = new PdfWriter::CPage(pDoc); + pDoc->AddObject(pPage); + pDoc->AddPage(pPage); // Получение объекта страницы Object pageRefObj, pageObj; - pageRefObj.initRef(pPageRef.first, pPageRef.second); - if (!pageRefObj.fetch(xref, &pageObj) || !pageObj.isDict()) + pageRefObj.initRef(pPageRef->num, pPageRef->gen); + if (!pageRefObj.fetch(xref, &pageObj)->isDict()) { pageObj.free(); pageRefObj.free(); @@ -1210,7 +1245,8 @@ bool CPdfEditor::SplitPage(int nPageIndex) } pageRefObj.free(); - // Воспроизведение словаря страницы из reader для writer + // Копирование страницы со всеми ресурсами из reader для writer + for (int nIndex = 0; nIndex < pageObj.dictGetLength(); ++nIndex) { Object oTemp; @@ -1219,17 +1255,19 @@ bool CPdfEditor::SplitPage(int nPageIndex) { if (pageObj.dictGetVal(nIndex, &oTemp)->isDict()) { - PdfWriter::CResourcesDict* pDict = new PdfWriter::CResourcesDict(NULL, true, false); + Object oTemp2; + pageObj.dictGetValNF(nIndex, &oTemp2); + PdfWriter::CResourcesDict* pDict = new PdfWriter::CResourcesDict(NULL, !oTemp2.isRef(), false); + oTemp2.free(); + pPage->Add("Resources", pDict); for (int nIndex = 0; nIndex < oTemp.dictGetLength(); ++nIndex) { Object oRes; char* chKey2 = oTemp.dictGetKey(nIndex); - if (strcmp("Font", chKey2) == 0 || strcmp("ExtGState", chKey2) == 0 || strcmp("XObject", chKey2) == 0 || strcmp("Shading", chKey2) == 0 || strcmp("Pattern", chKey2) == 0) - oTemp.dictGetVal(nIndex, &oRes); - else - oTemp.dictGetValNF(nIndex, &oRes); - DictToCDictObject2(&oRes, pDict, chKey2, pDoc, xref, false); + oTemp.dictGetValNF(nIndex, &oRes); + PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oRes, pDoc, xref, m_mSplitUniqueRef); + pDict->Add(chKey2, pBase); oRes.free(); } @@ -1242,52 +1280,20 @@ bool CPdfEditor::SplitPage(int nPageIndex) pageObj.dictGetValNF(nIndex, &oTemp); } } - else if (strcmp("Annots", chKey) == 0) - { - if (pageObj.dictGetVal(nIndex, &oTemp)->isArray()) - { - PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject(); - pPage->Add("Annots", pArray); - for (int nIndex = 0; nIndex < oTemp.arrayGetLength(); ++nIndex) - { - Object oAnnot; - oTemp.arrayGetNF(nIndex, &oAnnot); - DictToCDictObject2(&oAnnot, pArray, "", pDoc, xref, false); - oAnnot.free(); - } - oTemp.free(); - continue; - } - else - { - oTemp.free(); - pageObj.dictGetValNF(nIndex, &oTemp); - } - } - else if (strcmp("Contents", chKey) == 0) - { - if (pageObj.dictGetVal(nIndex, &oTemp)->isArray()) - { - DictToCDictObject2(&oTemp, pPage, chKey, pDoc, xref, false); - oTemp.free(); - continue; - } - else - { - oTemp.free(); - pageObj.dictGetValNF(nIndex, &oTemp); - } - } else if (strcmp("Parent", chKey) == 0) { - pageObj.dictGetValNF(nIndex, &oTemp); + oTemp.free(); + continue; } else pageObj.dictGetValNF(nIndex, &oTemp); - DictToCDictObject2(&oTemp, pPage, chKey, pDoc, xref, false); + PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp, pDoc, xref, m_mSplitUniqueRef); + pPage->Add(chKey, pBase); oTemp.free(); } pPage->Fix(); + // TODO pPage->AddContents чтобы можно было дописать изменения, если понадобится + m_pWriter->SetNeedAddHelvetica(false); // TODO дописывает шрифт для адекватного редактирования Adobe pdf без текст. Убрать при реализации map шрифтов pageObj.free(); return true; diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h index c52baf57a6..5b49e1f05e 100644 --- a/PdfFile/PdfEditor.h +++ b/PdfFile/PdfEditor.h @@ -67,6 +67,7 @@ private: std::wstring m_wsSrcFile; std::wstring m_wsPassword; std::map m_mFonts; + std::map m_mSplitUniqueRef; // map уникальных объектов для Split CPdfReader* m_pReader; CPdfWriter* m_pWriter; diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 595defc42f..8af71663f3 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -140,6 +140,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 +191,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); diff --git a/PdfFile/PdfWriter.h b/PdfFile/PdfWriter.h index 38fa7fc70f..297cc96434 100644 --- a/PdfFile/PdfWriter.h +++ b/PdfFile/PdfWriter.h @@ -219,6 +219,7 @@ public: 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) { m_bNeedAddHelvetica = bNeedAddHelvetica; } private: PdfWriter::CImageDict* LoadImage(Aggplus::CImage* pImage, BYTE nAlpha); @@ -269,6 +270,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/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 8de13cfb20..c7f7a3f191 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -337,6 +337,11 @@ namespace PdfWriter m_pTrailer->Add("Encrypt", m_pEncryptDict); m_bEncrypt = true; } + void CDocument::AddPage(CPage* pPage) + { + m_pPageTree->AddPage(pPage); + m_pCurPage = pPage; + } CPage* CDocument::AddPage() { CPage* pPage = new CPage(m_pXref, m_pPageTree, this); diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index 0bb55a6748..31418d13c0 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -120,7 +120,8 @@ namespace PdfWriter void SetPDFAConformanceMode(bool isPDFA); bool IsPDFA() const; - + + void AddPage(CPage* pPage); CPage* AddPage(); CPage* GetPage (const unsigned int& unPage); CPage* GetEditPage(const unsigned int& unPage); diff --git a/PdfFile/test/test.cpp b/PdfFile/test/test.cpp index 0a860eb614..cd72d7fe12 100644 --- a/PdfFile/test/test.cpp +++ b/PdfFile/test/test.cpp @@ -352,13 +352,16 @@ TEST_F(CPdfFileTest, VerifySign) TEST_F(CPdfFileTest, SplitPdf) { - GTEST_SKIP(); + //GTEST_SKIP(); LoadFromFile(); pdfFile->CreatePdf(); pdfFile->SplitPage(0); + pdfFile->SplitPages({2, 3}); + + pdfFile->SaveToFile(wsDstFile); } TEST_F(CPdfFileTest, MergePdf) @@ -393,7 +396,7 @@ TEST_F(CPdfFileTest, EditPdf) TEST_F(CPdfFileTest, EditPdfFromBase64) { - //GTEST_SKIP(); + GTEST_SKIP(); NSFonts::NSApplicationFontStream::SetGlobalMemoryStorage(NSFonts::NSApplicationFontStream::CreateDefaultGlobalMemoryStorage()); From 826d3fc678c10d8c28689c8a47bc5d1b718a1d46 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 11 Feb 2025 17:55:09 +0300 Subject: [PATCH 023/186] Fix build --- DesktopEditor/graphics/pro/js/qt/nativegraphics.pro | 2 ++ PdfFile/PdfFile.cpp | 4 +--- PdfFile/SrcWriter/Document.cpp | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro b/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro index 3b3710f95f..8f532e4fa5 100644 --- a/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro +++ b/DesktopEditor/graphics/pro/js/qt/nativegraphics.pro @@ -682,6 +682,7 @@ HEADERS += \ $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/DropCap.h \ $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Paragraph.h \ $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Shape.h \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Table.h \ $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/TextLine.h \ $$DOCX_RENDERER_ROOT_DIR/src/logic/managers/ExternalImageStorage.h \ $$DOCX_RENDERER_ROOT_DIR/src/logic/managers/FontStyleManager.h \ @@ -706,6 +707,7 @@ SOURCES += \ $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/ContText.cpp \ $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Paragraph.cpp \ $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Shape.cpp \ + $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/Table.cpp \ $$DOCX_RENDERER_ROOT_DIR/src/logic/elements/TextLine.cpp \ $$DOCX_RENDERER_ROOT_DIR/src/logic/managers/FontManager.cpp \ $$DOCX_RENDERER_ROOT_DIR/src/logic/managers/FontStyleManager.cpp \ diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index e7d9419bea..34f86534df 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -36,14 +36,12 @@ #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" -#include "Resources/BaseFonts.h" - #else class CPdfEditor { diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index c7f7a3f191..6665c0b720 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -339,6 +339,7 @@ namespace PdfWriter } void CDocument::AddPage(CPage* pPage) { + pPage->Add("Parent", m_pPageTree); m_pPageTree->AddPage(pPage); m_pCurPage = pPage; } From 3227b91a7c5e7b281730ef290fa33dfddfcfd6e4 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 12 Feb 2025 14:20:22 +0600 Subject: [PATCH 024/186] Add cond format conversion --- OOXML/Binary/Sheets/Writer/BinaryReader.cpp | 40 ++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index 96f51b97fe..0607444845 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp @@ -4605,10 +4605,41 @@ int BinaryWorksheetsTableReader::ReadWorksheet(boost::unordered_map>::iterator pFind; LONG nPos; LONG length; + //------------------------------------------------------------------------------------------------------------- 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); @@ -4622,6 +4653,13 @@ int BinaryWorksheetsTableReader::ReadWorksheet(boost::unordered_mapReadConditionalFormatting, pConditionalFormatting); + pConditionalFormatting->toBin(oStreamWriter); + delete pConditionalFormatting; + SEEK_TO_POS_END2(); + { auto endSheet = oStreamWriter->getNextRecord(XLSB::rt_EndSheet); oStreamWriter->storeNextRecord(endSheet); From 3ec3aa8575773019f799c8bf1484ce386cc64025 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 12 Feb 2025 16:38:51 +0600 Subject: [PATCH 025/186] add protection & mergeCells conversion --- OOXML/Binary/Sheets/Writer/BinaryReader.cpp | 36 ++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index 0607444845..53534c6768 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp @@ -4652,7 +4652,41 @@ int BinaryWorksheetsTableReader::ReadWorksheet(boost::unordered_mapstoreNextRecord(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::Spreadsheet::CConditionalFormatting *pConditionalFormatting = new OOX::Spreadsheet::CConditionalFormatting(); READ1_DEF(length, res, this->ReadConditionalFormatting, pConditionalFormatting); From 7c1636a33e6af351e38e8c01ba57457bcc84ed8d Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 12 Feb 2025 20:17:03 +0600 Subject: [PATCH 026/186] add hyperlinks conversion --- OOXML/Binary/Sheets/Writer/BinaryReader.cpp | 57 ++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index 53534c6768..57473fb251 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp @@ -4693,7 +4693,62 @@ int BinaryWorksheetsTableReader::ReadWorksheet(boost::unordered_maptoBin(oStreamWriter); delete pConditionalFormatting; 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(); +//------------------------------------------------------------------------------------------------------------- + /*SEEK_TO_POS_START(c_oSerWorksheetsTypes::CellWatches); + OOX::Spreadsheet::CCellWatches oCellWatches; + READ1_DEF(length, res, this->ReadCellWatches, &oCellWatches); + oCellWatches.toBin(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();*/ +//------------------------------------------------------------------------------------------------------------- { auto endSheet = oStreamWriter->getNextRecord(XLSB::rt_EndSheet); oStreamWriter->storeNextRecord(endSheet); From c60ff31fd4ef74e9b86240966b4f77d2baf190ad Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 13 Feb 2025 10:13:44 +0300 Subject: [PATCH 027/186] Fix Resources ref --- PdfFile/PdfEditor.cpp | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 2d88844746..7ac52c61f1 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -149,6 +149,17 @@ void DictToCDictObject(Object* obj, PdfWriter::CObjectBase* pObj, const std::str break; } } +bool SplitSkipDict(Object* obj) +{ + Object oType; + if (!obj->dictLookup("Type", &oType)->isName()) + { + oType.free(); + return false; + } + oType.free(); + return false; +} PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CDocument* pDoc, XRef* xref, std::map& mUniqueRef) { PdfWriter::CObjectBase* pBase = NULL; @@ -215,6 +226,8 @@ PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CDocument* pD } case objDict: { + if (SplitSkipDict(obj)) + return new PdfWriter::CNullObject(); PdfWriter::CDictObject* pDict = new PdfWriter::CDictObject(); for (int nIndex = 0; nIndex < obj->dictGetLength(); ++nIndex) { @@ -1243,6 +1256,7 @@ bool CPdfEditor::SplitPage(int nPageIndex) pageRefObj.free(); return false; } + m_mSplitUniqueRef[pPageRef->num] = pPage; pageRefObj.free(); // Копирование страницы со всеми ресурсами из reader для writer @@ -1253,12 +1267,23 @@ bool CPdfEditor::SplitPage(int nPageIndex) 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(); + + std::map::iterator it = m_mSplitUniqueRef.find(oResourcesRef.num); + if (oResourcesRef.num > 0 && it != m_mSplitUniqueRef.end()) + { + pPage->Add("Resources", it->second); + continue; + } + if (pageObj.dictGetVal(nIndex, &oTemp)->isDict()) { - Object oTemp2; - pageObj.dictGetValNF(nIndex, &oTemp2); - PdfWriter::CResourcesDict* pDict = new PdfWriter::CResourcesDict(NULL, !oTemp2.isRef(), false); - oTemp2.free(); + PdfWriter::CResourcesDict* pDict = new PdfWriter::CResourcesDict(NULL, oResourcesRef.num < 0, false); + if (oResourcesRef.num > 0) + m_mSplitUniqueRef[oResourcesRef.num] = pDict; pPage->Add("Resources", pDict); for (int nIndex = 0; nIndex < oTemp.dictGetLength(); ++nIndex) From 70be48fec3904947b37be3b826640cefe19fdf15 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 13 Feb 2025 11:11:11 +0300 Subject: [PATCH 028/186] Test SplitPage --- PdfFile/PdfEditor.cpp | 49 +++++++++++++++++++++++++++++++++++++------ PdfFile/PdfEditor.h | 2 +- PdfFile/PdfFile.cpp | 40 +++++++++++++++++++++-------------- PdfFile/PdfFile.h | 1 - PdfFile/test/test.cpp | 3 +-- 5 files changed, 69 insertions(+), 26 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 7ac52c61f1..64469b8af7 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -160,7 +160,7 @@ bool SplitSkipDict(Object* obj) oType.free(); return false; } -PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CDocument* pDoc, XRef* xref, std::map& mUniqueRef) +PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CDocument* pDoc, XRef* xref, std::map& mUniqueRef, int nAddObjToXRef = 0) { PdfWriter::CObjectBase* pBase = NULL; Object oTemp; @@ -214,6 +214,12 @@ PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CDocument* pD case objArray: { PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject(); + if (nAddObjToXRef > 0) + { + pDoc->AddObject(pArray); + mUniqueRef[nAddObjToXRef] = pArray; + nAddObjToXRef = 0; + } for (int nIndex = 0; nIndex < obj->arrayGetLength(); ++nIndex) { obj->arrayGetNF(nIndex, &oTemp); @@ -229,6 +235,12 @@ PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CDocument* pD if (SplitSkipDict(obj)) return new PdfWriter::CNullObject(); PdfWriter::CDictObject* pDict = new PdfWriter::CDictObject(); + if (nAddObjToXRef > 0) + { + pDoc->AddObject(pDict); + mUniqueRef[nAddObjToXRef] = pDict; + nAddObjToXRef = 0; + } for (int nIndex = 0; nIndex < obj->dictGetLength(); ++nIndex) { char* chKey = obj->dictGetKey(nIndex); @@ -248,9 +260,7 @@ PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CDocument* pD return it->second; obj->fetch(xref, &oTemp); - pBase = DictToCDictObject2(&oTemp, pDoc, xref, mUniqueRef); - pDoc->AddObject(pBase); - mUniqueRef[nObjNum] = pBase; + pBase = DictToCDictObject2(&oTemp, pDoc, xref, mUniqueRef, nObjNum); oTemp.free(); break; } @@ -261,8 +271,15 @@ PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CDocument* pD } case objStream: { - Dict* pODict = obj->streamGetDict(); PdfWriter::CDictObject* pDict = new PdfWriter::CDictObject(); + if (nAddObjToXRef > 0) + { + pDoc->AddObject(pDict); + mUniqueRef[nAddObjToXRef] = pDict; + nAddObjToXRef = 0; + } + + Dict* pODict = obj->streamGetDict(); int nLength = 0; for (int nIndex = 0; nIndex < pODict->getLength(); ++nIndex) { @@ -297,6 +314,11 @@ PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CDocument* pD case objEOF: break; } + if (nAddObjToXRef > 0) + { + pDoc->AddObject(pBase); + mUniqueRef[nAddObjToXRef] = pBase; + } return pBase; } @@ -855,7 +877,7 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa if (!bRes) m_nError = 5; // Ошибка применения редактирования } -CPdfEditor::CPdfEditor(CPdfReader* _pReader, CPdfWriter* _pWriter) +CPdfEditor::CPdfEditor(CPdfReader* _pReader, CPdfWriter* _pWriter, unsigned int unPages) { m_pReader = _pReader; m_pWriter = _pWriter; @@ -877,6 +899,21 @@ CPdfEditor::CPdfEditor(CPdfReader* _pReader, CPdfWriter* _pWriter) m_nError = 1; return; } + + // Страницы должны быть созданы заранее для ссылки + Catalog* pCatalog = pPDFDocument->getCatalog(); + for (int i = 1; i <= unPages; ++i) + { + Ref* pPageRef = pCatalog->getPageRef(i); + if (pPageRef->num == 0) + { + return; + } + + PdfWriter::CPage* pPage = new PdfWriter::CPage(pDoc); + pDoc->AddObject(pPage); + pDoc->AddPage(pPage); + } } void CPdfEditor::Close() { diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h index 5b49e1f05e..1a43060c63 100644 --- a/PdfFile/PdfEditor.h +++ b/PdfFile/PdfEditor.h @@ -41,7 +41,7 @@ class CPdfEditor { public: CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPassword, CPdfReader* _pReader, const std::wstring& _wsDstFile, CPdfWriter* _pWriter); - CPdfEditor(CPdfReader* _pReader, CPdfWriter* _pWriter); + CPdfEditor(CPdfReader* _pReader, CPdfWriter* _pWriter, unsigned int unPages); int GetError(); void Close(); diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 34f86534df..5013a01b49 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -68,6 +68,10 @@ public: class CPdfFile_Private { +public: + bool SplitPage(int nPageIndex); + bool SplitPages(const int* arrPageIndex, unsigned int unLength, IRenderer* pRenderer); + public: std::wstring wsSrcFile; std::wstring wsPassword; @@ -165,28 +169,32 @@ bool CPdfFile::AddPage(int nPageIndex) return false; return m_pInternal->pEditor->AddPage(nPageIndex); } -bool CPdfFile::SplitPage(int nPageIndex) -{ - if (!m_pInternal->pEditor) - { - if (!m_pInternal->pReader) - return false; - - if (!m_pInternal->pWriter) - m_pInternal->pWriter = new CPdfWriter(m_pInternal->pAppFonts, false, this); - - m_pInternal->pEditor = new CPdfEditor(m_pInternal->pReader, m_pInternal->pWriter); - if (m_pInternal->pEditor->GetError() != 0) - return false; - } - return m_pInternal->pEditor->SplitPage(nPageIndex); -} bool CPdfFile::SplitPages(const std::vector& arrPageIndex) { return SplitPages(arrPageIndex.data(), arrPageIndex.size()); } bool CPdfFile::SplitPages(const int* arrPageIndex, unsigned int unLength) { + return m_pInternal->SplitPages(arrPageIndex, unLength, this); +} +bool CPdfFile_Private::SplitPage(int nPageIndex) +{ + return pEditor->SplitPage(nPageIndex); +} +bool CPdfFile_Private::SplitPages(const int* arrPageIndex, unsigned int unLength, IRenderer* pRenderer) +{ + if (!pEditor) + { + if (!pReader) + return false; + + if (!pWriter) + pWriter = new CPdfWriter(pAppFonts, false, pRenderer); + + pEditor = new CPdfEditor(pReader, pWriter, unLength); + if (pEditor->GetError() != 0) + return false; + } bool bRes = true; for (unsigned int i = 0; i < unLength; ++i) bRes &= SplitPage(arrPageIndex[i]); diff --git a/PdfFile/PdfFile.h b/PdfFile/PdfFile.h index 36db98434c..7a03e0190b 100644 --- a/PdfFile/PdfFile.h +++ b/PdfFile/PdfFile.h @@ -97,7 +97,6 @@ public: bool EditPage (int nPageIndex); bool DeletePage (int nPageIndex); bool AddPage (int nPageIndex); - bool SplitPage (int nPageIndex); bool SplitPages (const std::vector& arrPageIndex); bool SplitPages (const int* arrPageIndex, unsigned int unLength); HRESULT ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword = L""); diff --git a/PdfFile/test/test.cpp b/PdfFile/test/test.cpp index cd72d7fe12..181711fd2e 100644 --- a/PdfFile/test/test.cpp +++ b/PdfFile/test/test.cpp @@ -358,8 +358,7 @@ TEST_F(CPdfFileTest, SplitPdf) pdfFile->CreatePdf(); - pdfFile->SplitPage(0); - pdfFile->SplitPages({2, 3}); + pdfFile->SplitPages({0, 1}); pdfFile->SaveToFile(wsDstFile); } From feeb471aad704c4c8fa82b9f4f0a7dfbc79b68da Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 13 Feb 2025 17:49:54 +0600 Subject: [PATCH 029/186] Add drawing & comments conversion --- OOXML/Binary/Sheets/Writer/BinaryReader.cpp | 94 +++++++++++++++++++-- 1 file changed, 88 insertions(+), 6 deletions(-) diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index 57473fb251..cb751cac90 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp @@ -4735,18 +4735,98 @@ int BinaryWorksheetsTableReader::ReadWorksheet(boost::unordered_mapReadRowColBreaks, &oColBreaks); oColBreaks.toBinColumn(oStreamWriter); SEEK_TO_POS_END2(); -//------------------------------------------------------------------------------------------------------------- - /*SEEK_TO_POS_START(c_oSerWorksheetsTypes::CellWatches); - OOX::Spreadsheet::CCellWatches oCellWatches; - READ1_DEF(length, res, this->ReadCellWatches, &oCellWatches); - oCellWatches.toBin(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();*/ //------------------------------------------------------------------------------------------------------------- { @@ -4763,6 +4843,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; From e7a7400801aeb26f013e1a83f3665819cf8e73ef Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 13 Feb 2025 19:16:16 +0600 Subject: [PATCH 030/186] Add ext conversion --- OOXML/Binary/Sheets/Writer/BinaryReader.cpp | 42 ++++++++++++++++++++- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index cb751cac90..463fcaf8e0 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp @@ -4688,10 +4688,30 @@ int BinaryWorksheetsTableReader::ReadWorksheet(boost::unordered_mapReadConditionalFormatting, pConditionalFormatting); - pConditionalFormatting->toBin(oStreamWriter); - delete 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::Hyperlinks); @@ -4829,6 +4849,24 @@ int BinaryWorksheetsTableReader::ReadWorksheet(boost::unordered_mapm_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(); +//------------------------------------------------------------------------------------------------------------- + if (m_pCurWorksheet->m_oExtLst.IsInit()) + { + auto extLst = m_pCurWorksheet->m_oExtLst->toBinWorksheet(); + extLst->write(oStreamWriter, nullptr); + } { auto endSheet = oStreamWriter->getNextRecord(XLSB::rt_EndSheet); oStreamWriter->storeNextRecord(endSheet); From 4de7ba4e525080289f79f3b80c50f363536f171d Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 13 Feb 2025 18:04:00 +0300 Subject: [PATCH 031/186] Fix Skip Action GoTo another Page --- PdfFile/PdfEditor.cpp | 93 +++++++++++++++++++++++++++------- PdfFile/PdfEditor.h | 3 +- PdfFile/PdfFile.cpp | 28 ++++------ PdfFile/SrcWriter/Document.cpp | 7 +++ PdfFile/SrcWriter/Document.h | 1 + 5 files changed, 95 insertions(+), 37 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 64469b8af7..ceb91ceace 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -149,15 +149,32 @@ void DictToCDictObject(Object* obj, PdfWriter::CObjectBase* pObj, const std::str break; } } -bool SplitSkipDict(Object* obj) +bool SplitSkipDict(Object* obj, std::map& mUniqueRef) { - Object oType; - if (!obj->dictLookup("Type", &oType)->isName()) + Object oTemp, oTemp2; + if (obj->dictLookup("Type", &oTemp)->isName("Page")) { - oType.free(); - return false; + oTemp.free(); + return true; } - oType.free(); + oTemp.free(); + + if (obj->dictLookup("S", &oTemp)->isName("GoTo")) + { + oTemp.free(); + if (obj->dictLookup("D", &oTemp)->isArray() && oTemp.arrayGetLength() > 1 && oTemp.arrayGetNF(0, &oTemp2)->isRef()) + { + std::map::iterator it = mUniqueRef.find(oTemp2.getRefNum()); + if (it == mUniqueRef.end()) + { + oTemp.free(); oTemp2.free(); + return true; + } + } + oTemp2.free(); + } + oTemp.free(); + return false; } PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CDocument* pDoc, XRef* xref, std::map& mUniqueRef, int nAddObjToXRef = 0) @@ -232,8 +249,8 @@ PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CDocument* pD } case objDict: { - if (SplitSkipDict(obj)) - return new PdfWriter::CNullObject(); + if (SplitSkipDict(obj, mUniqueRef)) + return NULL; PdfWriter::CDictObject* pDict = new PdfWriter::CDictObject(); if (nAddObjToXRef > 0) { @@ -877,7 +894,7 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa if (!bRes) m_nError = 5; // Ошибка применения редактирования } -CPdfEditor::CPdfEditor(CPdfReader* _pReader, CPdfWriter* _pWriter, unsigned int unPages) +CPdfEditor::CPdfEditor(CPdfReader* _pReader, CPdfWriter* _pWriter, const int* arrPageIndex, unsigned int unLength) { m_pReader = _pReader; m_pWriter = _pWriter; @@ -902,17 +919,31 @@ CPdfEditor::CPdfEditor(CPdfReader* _pReader, CPdfWriter* _pWriter, unsigned int // Страницы должны быть созданы заранее для ссылки Catalog* pCatalog = pPDFDocument->getCatalog(); - for (int i = 1; i <= unPages; ++i) + for (int i = 0; i < unLength; ++i) { - Ref* pPageRef = pCatalog->getPageRef(i); + Ref* pPageRef = pCatalog->getPageRef(arrPageIndex[i] + 1); if (pPageRef->num == 0) { + m_nError = 3; return; } PdfWriter::CPage* pPage = new PdfWriter::CPage(pDoc); pDoc->AddObject(pPage); pDoc->AddPage(pPage); + + // Получение объекта страницы + Object pageRefObj, pageObj; + pageRefObj.initRef(pPageRef->num, pPageRef->gen); + if (!pageRefObj.fetch(xref, &pageObj)->isDict()) + { + pageObj.free(); + pageRefObj.free(); + m_nError = 3; + return; + } + m_mSplitUniqueRef[pPageRef->num] = pPage; + pageRefObj.free(); } } void CPdfEditor::Close() @@ -1280,11 +1311,8 @@ bool CPdfEditor::SplitPage(int nPageIndex) if (pPageRef->num == 0) return false; - PdfWriter::CPage* pPage = new PdfWriter::CPage(pDoc); - pDoc->AddObject(pPage); - pDoc->AddPage(pPage); - // Получение объекта страницы + PdfWriter::CPage* pPage = (PdfWriter::CPage*)m_mSplitUniqueRef[pPageRef->num]; Object pageRefObj, pageObj; pageRefObj.initRef(pPageRef->num, pPageRef->gen); if (!pageRefObj.fetch(xref, &pageObj)->isDict()) @@ -1293,11 +1321,9 @@ bool CPdfEditor::SplitPage(int nPageIndex) pageRefObj.free(); return false; } - m_mSplitUniqueRef[pPageRef->num] = pPage; pageRefObj.free(); // Копирование страницы со всеми ресурсами из reader для writer - for (int nIndex = 0; nIndex < pageObj.dictGetLength(); ++nIndex) { Object oTemp; @@ -1360,6 +1386,39 @@ bool CPdfEditor::SplitPage(int nPageIndex) return true; } +void CPdfEditor::SplitEnd() +{ + PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); + XRef* xref = pPDFDocument->getXRef(); + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); + + Object oCatalog; + if (!xref->getCatalog(&oCatalog)->isDict()) + { + oCatalog.free(); + return; + } + + Object oAcroForm; + if (oCatalog.dictLookupNF("AcroForm", &oAcroForm)->isRef() || oAcroForm.isDict()) + { + PdfWriter::CDictObject* pAcroForm = new PdfWriter::CDictObject(); + if (oAcroForm.isRef()) + pDoc->AddObject(pAcroForm); + pDoc->SetAcroForm(pAcroForm); + + for (int nIndex = 0; nIndex < oAcroForm.dictGetLength(); ++nIndex) + { + Object oTemp; + char* chKey = oAcroForm.dictGetKey(nIndex); + oAcroForm.dictGetValNF(nIndex, &oTemp); + PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp, pDoc, xref, m_mSplitUniqueRef); + pAcroForm->Add(chKey, pBase); + oTemp.free(); + } + } + oAcroForm.free(); oCatalog.free(); +} bool CPdfEditor::DeletePage(int nPageIndex) { return m_pWriter->GetDocument()->DeletePage(nPageIndex); diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h index 1a43060c63..a2318c95b0 100644 --- a/PdfFile/PdfEditor.h +++ b/PdfFile/PdfEditor.h @@ -41,12 +41,13 @@ class CPdfEditor { public: CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPassword, CPdfReader* _pReader, const std::wstring& _wsDstFile, CPdfWriter* _pWriter); - CPdfEditor(CPdfReader* _pReader, CPdfWriter* _pWriter, unsigned int unPages); + CPdfEditor(CPdfReader* _pReader, CPdfWriter* _pWriter, const int* arrPageIndex, unsigned int unLength); int GetError(); void Close(); bool EditPage(int nPageIndex, bool bSet = true); bool SplitPage(int nPageIndex); + void SplitEnd(); bool DeletePage(int nPageIndex); bool AddPage(int nPageIndex); bool EditAnnot(int nPageIndex, int nID); diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 5013a01b49..59523c7cd4 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -68,10 +68,6 @@ public: class CPdfFile_Private { -public: - bool SplitPage(int nPageIndex); - bool SplitPages(const int* arrPageIndex, unsigned int unLength, IRenderer* pRenderer); - public: std::wstring wsSrcFile; std::wstring wsPassword; @@ -175,29 +171,23 @@ bool CPdfFile::SplitPages(const std::vector& arrPageIndex) } bool CPdfFile::SplitPages(const int* arrPageIndex, unsigned int unLength) { - return m_pInternal->SplitPages(arrPageIndex, unLength, this); -} -bool CPdfFile_Private::SplitPage(int nPageIndex) -{ - return pEditor->SplitPage(nPageIndex); -} -bool CPdfFile_Private::SplitPages(const int* arrPageIndex, unsigned int unLength, IRenderer* pRenderer) -{ - if (!pEditor) + if (!m_pInternal->pEditor) { - if (!pReader) + if (!m_pInternal->pReader) return false; - if (!pWriter) - pWriter = new CPdfWriter(pAppFonts, false, pRenderer); + if (!m_pInternal->pWriter) + m_pInternal->pWriter = new CPdfWriter(m_pInternal->pAppFonts, false, this); - pEditor = new CPdfEditor(pReader, pWriter, unLength); - if (pEditor->GetError() != 0) + m_pInternal->pEditor = new CPdfEditor(m_pInternal->pReader, m_pInternal->pWriter, arrPageIndex, unLength); + if (m_pInternal->pEditor->GetError() != 0) return false; } bool bRes = true; for (unsigned int i = 0; i < unLength; ++i) - bRes &= SplitPage(arrPageIndex[i]); + bRes &= m_pInternal->pEditor->SplitPage(arrPageIndex[i]); + if (bRes) + m_pInternal->pEditor->SplitEnd(); return bRes; } HRESULT CPdfFile::ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword) diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 6665c0b720..a43a02705a 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -1379,6 +1379,13 @@ namespace PdfWriter return (!!m_pAcroForm); } + void CDocument::SetAcroForm(CDictObject* pObj) + { + if (!m_pXref || !m_pCatalog) + return; + m_pCatalog->Add("AcroForm", pObj); + m_pAcroForm = pObj; + } bool CDocument::CreatePageTree(CXref* pXref, CPageTree* pPageTree) { if (!pPageTree || !EditXref(pXref)) diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index 31418d13c0..70ca31e621 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -214,6 +214,7 @@ namespace PdfWriter void EndShapeXML(); void ClearPage(); bool EditXref(CXref* pXref); + void SetAcroForm(CDictObject* pObj); private: char* GetTTFontTag(); From af4e0243d28d5a4461908b1bf2565bcff5680efa Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 14 Feb 2025 11:07:27 +0300 Subject: [PATCH 032/186] XRef write to stream --- .../pro/js/wasm/src/drawingfile_test.cpp | 4 ++-- PdfFile/SrcWriter/Document.cpp | 2 +- PdfFile/SrcWriter/Objects.cpp | 17 +++++++++++------ PdfFile/test/test.cpp | 4 +--- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp index e36f48cd53..99aa6ec245 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp @@ -1090,7 +1090,7 @@ int main(int argc, char* argv[]) } // GLYPHS - if (true && nPagesCount > 0) + if (false && nPagesCount > 0) { BYTE* pGlyphs = GetGlyphs(pGrFile, nTestPage); nLength = READ_INT(pGlyphs); @@ -1165,7 +1165,7 @@ int main(int argc, char* argv[]) } // INTERACTIVE FORMS - if (false) + if (true) { ReadInteractiveFormsFonts(pGrFile, 1); ReadInteractiveFormsFonts(pGrFile, 2); diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index a43a02705a..1c744d2f7f 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -266,7 +266,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) { diff --git a/PdfFile/SrcWriter/Objects.cpp b/PdfFile/SrcWriter/Objects.cpp index 0f1d98eefc..3d1f2ddced 100644 --- a/PdfFile/SrcWriter/Objects.cpp +++ b/PdfFile/SrcWriter/Objects.cpp @@ -927,10 +927,18 @@ 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); CArrayObject* pIndex = new CArrayObject(); pTrailer->Add("Index", pIndex); @@ -963,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; @@ -990,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 = 0; i < nOffsetSize; ++i) + pTrailerStream->WriteChar((pEntry->unByteOffset >> (8 * i)) & 0xFF); pTrailerStream->WriteChar((unsigned char)(pEntry->unGenNo >> 8)); pTrailerStream->WriteChar((unsigned char)(pEntry->unGenNo)); } diff --git a/PdfFile/test/test.cpp b/PdfFile/test/test.cpp index 181711fd2e..407fad324a 100644 --- a/PdfFile/test/test.cpp +++ b/PdfFile/test/test.cpp @@ -356,9 +356,7 @@ TEST_F(CPdfFileTest, SplitPdf) LoadFromFile(); - pdfFile->CreatePdf(); - - pdfFile->SplitPages({0, 1}); + pdfFile->SplitPages({2, 5, 6, 7}); pdfFile->SaveToFile(wsDstFile); } From 342853711394eed0e1b79c1d823da181cb37eda3 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 14 Feb 2025 17:29:45 +0600 Subject: [PATCH 033/186] Add table conversion --- OOXML/Binary/Sheets/Writer/BinaryReader.cpp | 118 +++++++++++++++++--- OOXML/Binary/Sheets/Writer/BinaryReader.h | 1 + 2 files changed, 106 insertions(+), 13 deletions(-) diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index 463fcaf8e0..4757adbe00 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp @@ -418,12 +418,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); @@ -3427,23 +3432,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, L""); 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 @@ -3484,6 +3502,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 @@ -4522,7 +4542,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) @@ -4713,7 +4733,13 @@ int BinaryWorksheetsTableReader::ReadWorksheet(boost::unordered_mapm_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); @@ -4840,14 +4866,25 @@ int BinaryWorksheetsTableReader::ReadWorksheet(boost::unordered_mapSetValue((unsigned int)oTableParts.m_arrItems.size()); - //oTableParts.toBin(oStreamWriter); - SEEK_TO_POS_END2();*/ + 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(); @@ -4861,12 +4898,59 @@ int BinaryWorksheetsTableReader::ReadWorksheet(boost::unordered_mapm_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(); +//------------------------------------------------------------------------------------------------------------- + { auto endSheet = oStreamWriter->getNextRecord(XLSB::rt_EndSheet); oStreamWriter->storeNextRecord(endSheet); @@ -7973,6 +8057,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 @@ -9160,7 +9246,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; diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.h b/OOXML/Binary/Sheets/Writer/BinaryReader.h index 722205a32c..a809c42af6 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.h +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.h @@ -276,6 +276,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; }; class BinaryCommentReader : public Binary_CommonReader { From bc0a582bf6af320faeb968516f39a4d61eaab4b0 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 14 Feb 2025 19:57:08 +0600 Subject: [PATCH 034/186] Fix pivot conversion --- OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h | 1 + OOXML/XlsxFormat/Pivot/PivotTable.h | 1 + OOXML/XlsxFormat/Pivot/Pivots.cpp | 79 ++++++++++++++++--- 3 files changed, 68 insertions(+), 13 deletions(-) diff --git a/OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h b/OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h index 444b2e9494..554a8bb607 100644 --- a/OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h +++ b/OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h @@ -684,6 +684,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 a73e874c05..cb5d2b227f 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 { @@ -3733,6 +3760,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) { @@ -3763,8 +3810,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()); } @@ -3800,6 +3847,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 { From 028157d2ef8b7d679ed43651b1d7eecb66127cc0 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 14 Feb 2025 17:36:31 +0300 Subject: [PATCH 035/186] Fix AcroForm --- PdfFile/PdfEditor.cpp | 69 ++++++++++++++++++++++++++++++---- PdfFile/SrcWriter/Document.cpp | 4 ++ PdfFile/SrcWriter/Document.h | 1 + PdfFile/SrcWriter/Objects.cpp | 10 ++--- 4 files changed, 71 insertions(+), 13 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index ceb91ceace..96fd141f1d 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -157,7 +157,16 @@ bool SplitSkipDict(Object* obj, std::map& mUniqueR oTemp.free(); return true; } - oTemp.free(); + else if (oTemp.isName("Annot") && obj->dictLookupNF("P", &oTemp2)->isRef()) + { + std::map::iterator it = mUniqueRef.find(oTemp2.getRefNum()); + if (it == mUniqueRef.end()) + { + oTemp.free(); oTemp2.free(); + return true; + } + } + oTemp.free(); oTemp2.free(); if (obj->dictLookup("S", &oTemp)->isName("GoTo")) { @@ -316,7 +325,7 @@ PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CDocument* pD PdfWriter::CStream* pStream = new PdfWriter::CMemoryStream(nLength); pDict->SetStream(pStream); - Stream* pOStream = obj->getStream()->getBaseStream(); + Stream* pOStream = obj->getStream()->getUndecodedStream(); pOStream->reset(); int nChar = pOStream->getChar(); while (nChar != EOF) @@ -1338,17 +1347,16 @@ bool CPdfEditor::SplitPage(int nPageIndex) std::map::iterator it = m_mSplitUniqueRef.find(oResourcesRef.num); if (oResourcesRef.num > 0 && it != m_mSplitUniqueRef.end()) { - pPage->Add("Resources", it->second); + pPage->Add(chKey, it->second); continue; } if (pageObj.dictGetVal(nIndex, &oTemp)->isDict()) { - PdfWriter::CResourcesDict* pDict = new PdfWriter::CResourcesDict(NULL, oResourcesRef.num < 0, false); + PdfWriter::CResourcesDict* pDict = pDoc->CreateResourcesDict(oResourcesRef.num < 0, false); if (oResourcesRef.num > 0) m_mSplitUniqueRef[oResourcesRef.num] = pDict; - - pPage->Add("Resources", pDict); + pPage->Add(chKey, pDict); for (int nIndex = 0; nIndex < oTemp.dictGetLength(); ++nIndex) { Object oRes; @@ -1411,7 +1419,54 @@ void CPdfEditor::SplitEnd() { Object oTemp; char* chKey = oAcroForm.dictGetKey(nIndex); - oAcroForm.dictGetValNF(nIndex, &oTemp); + if (strcmp("Fields", chKey) == 0) + { + Ref oFieldsRef = { -1, -1 }; + if (oAcroForm.dictGetValNF(nIndex, &oTemp)->isRef()) + oFieldsRef = oTemp.getRef(); + oTemp.free(); + + std::map::iterator it = m_mSplitUniqueRef.find(oFieldsRef.num); + if (oFieldsRef.num > 0 && it != m_mSplitUniqueRef.end()) + { + pAcroForm->Add(chKey, it->second); + continue; + } + + if (oAcroForm.dictGetVal(nIndex, &oTemp)->isArray()) + { + PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject(); + if (oFieldsRef.num > 0) + { + pDoc->AddObject(pArray); + m_mSplitUniqueRef[oFieldsRef.num] = pArray; + } + pAcroForm->Add(chKey, pArray); + for (int nIndex = 0; nIndex < oTemp.arrayGetLength(); ++nIndex) + { + Object oRes; + if (oTemp.arrayGetNF(nIndex, &oRes)->isRef()) + { + it = m_mSplitUniqueRef.find(oRes.getRefNum()); + if (it != m_mSplitUniqueRef.end()) + { + PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oRes, pDoc, xref, m_mSplitUniqueRef); + pArray->Add(pBase); + } + } + oRes.free(); + } + oTemp.free(); + continue; + } + else + { + oTemp.free(); + oAcroForm.dictGetValNF(nIndex, &oTemp); + } + } + else + oAcroForm.dictGetValNF(nIndex, &oTemp); PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp, pDoc, xref, m_mSplitUniqueRef); pAcroForm->Add(chKey, pBase); oTemp.free(); diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 1c744d2f7f..5a3e62bafc 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -1386,6 +1386,10 @@ namespace PdfWriter 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)) diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index 70ca31e621..e449be6eb1 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -215,6 +215,7 @@ namespace PdfWriter void ClearPage(); bool EditXref(CXref* pXref); void SetAcroForm(CDictObject* pObj); + CResourcesDict* CreateResourcesDict(bool bInline, bool bProcSet); private: char* GetTTFontTag(); diff --git a/PdfFile/SrcWriter/Objects.cpp b/PdfFile/SrcWriter/Objects.cpp index 3d1f2ddced..8a72e09f24 100644 --- a/PdfFile/SrcWriter/Objects.cpp +++ b/PdfFile/SrcWriter/Objects.cpp @@ -936,10 +936,10 @@ namespace PdfWriter else if (nStreamOffset > 1 << 8) nOffsetSize = 2; CArrayObject* pW = new CArrayObject(); - pTrailer->Add("W", pW); pW->Add(1); pW->Add(nOffsetSize); pW->Add(2); + pTrailer->Add("W", pW); CArrayObject* pIndex = new CArrayObject(); pTrailer->Add("Index", pIndex); CNumberObject* pLength = new CNumberObject(0); @@ -997,7 +997,7 @@ namespace PdfWriter pTrailerStream->WriteChar('\000'); else if (pEntry->nEntryType == IN_USE_ENTRY) pTrailerStream->WriteChar('\001'); - for (int i = 0; i < nOffsetSize; ++i) + 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)); @@ -1010,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'); From 229b263a9f42c955542b2b24aed481422c9599c8 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 17 Feb 2025 18:07:17 +0300 Subject: [PATCH 036/186] Fix AcroForm SplitPage --- PdfFile/PdfEditor.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 96fd141f1d..5a06fc3f08 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -1412,7 +1412,15 @@ void CPdfEditor::SplitEnd() { PdfWriter::CDictObject* pAcroForm = new PdfWriter::CDictObject(); if (oAcroForm.isRef()) + { pDoc->AddObject(pAcroForm); + oAcroForm.free(); + if (!oCatalog.dictLookup("AcroForm", &oAcroForm)->isDict()) + { + oAcroForm.free(); oCatalog.free(); + return; + } + } pDoc->SetAcroForm(pAcroForm); for (int nIndex = 0; nIndex < oAcroForm.dictGetLength(); ++nIndex) @@ -1449,10 +1457,7 @@ void CPdfEditor::SplitEnd() { it = m_mSplitUniqueRef.find(oRes.getRefNum()); if (it != m_mSplitUniqueRef.end()) - { - PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oRes, pDoc, xref, m_mSplitUniqueRef); - pArray->Add(pBase); - } + pArray->Add(it->second); } oRes.free(); } From 9f3ab7cc29dd92af2ebd192646435586cd99d458 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 18 Feb 2025 16:00:57 +0300 Subject: [PATCH 037/186] Create MergePages --- PdfFile/PdfEditor.cpp | 261 +++++++++++++++++---------------- PdfFile/PdfEditor.h | 9 +- PdfFile/PdfFile.cpp | 49 +++++-- PdfFile/PdfFile.h | 11 +- PdfFile/SrcWriter/Document.cpp | 13 +- PdfFile/SrcWriter/Document.h | 6 +- PdfFile/test/test.cpp | 11 +- 7 files changed, 204 insertions(+), 156 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 5a06fc3f08..52b2897e35 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -650,6 +650,7 @@ void GetCTM(XRef* pXref, Object* oPage, double* dCTM) CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPassword, CPdfReader* _pReader, const std::wstring& _wsDstFile, CPdfWriter* _pWriter) { m_wsSrcFile = _wsSrcFile; + m_wsDstFile = _wsDstFile; m_wsPassword = _wsPassword; m_pReader = _pReader; m_pWriter = _pWriter; @@ -665,7 +666,7 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa } // Если результат редактирования будет сохранен в тот же файл, что открыт для чтения, то файл необходимо сделать редактируемым - std::string sPathUtf8New = U_TO_UTF8(_wsDstFile); + 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)) { @@ -680,15 +681,15 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa return; } } - else + else if (!m_wsDstFile.empty()) { - if (!NSFile::CFileBinary::Copy(m_wsSrcFile, _wsDstFile)) + if (!NSFile::CFileBinary::Copy(m_wsSrcFile, m_wsDstFile)) { m_nError = 2; return; } NSFile::CFileBinary oFile; - if (!oFile.OpenFile(_wsDstFile, true)) + if (!oFile.OpenFile(m_wsDstFile, true)) { m_nError = 2; return; @@ -890,7 +891,7 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa } // Применение редактирования для 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 @@ -903,7 +904,7 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa if (!bRes) m_nError = 5; // Ошибка применения редактирования } -CPdfEditor::CPdfEditor(CPdfReader* _pReader, CPdfWriter* _pWriter, const int* arrPageIndex, unsigned int unLength) +CPdfEditor::CPdfEditor(CPdfReader* _pReader, CPdfWriter* _pWriter) { m_pReader = _pReader; m_pWriter = _pWriter; @@ -925,39 +926,16 @@ CPdfEditor::CPdfEditor(CPdfReader* _pReader, CPdfWriter* _pWriter, const int* ar m_nError = 1; return; } - - // Страницы должны быть созданы заранее для ссылки - Catalog* pCatalog = pPDFDocument->getCatalog(); - for (int i = 0; i < unLength; ++i) - { - Ref* pPageRef = pCatalog->getPageRef(arrPageIndex[i] + 1); - if (pPageRef->num == 0) - { - m_nError = 3; - return; - } - - PdfWriter::CPage* pPage = new PdfWriter::CPage(pDoc); - pDoc->AddObject(pPage); - pDoc->AddPage(pPage); - - // Получение объекта страницы - Object pageRefObj, pageObj; - pageRefObj.initRef(pPageRef->num, pPageRef->gen); - if (!pageRefObj.fetch(xref, &pageObj)->isDict()) - { - pageObj.free(); - pageRefObj.free(); - m_nError = 3; - return; - } - m_mSplitUniqueRef[pPageRef->num] = pPage; - pageRefObj.free(); - } +} +int CPdfEditor::Close(const std::wstring& wsPath) +{ + m_wsDstFile = wsPath; + Close(); + return 0; } void CPdfEditor::Close() { - if (m_nMode != 0) + if (m_nMode != 0 || m_wsDstFile.empty()) return; PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); @@ -1024,14 +1002,13 @@ void CPdfEditor::Close() } info.free(); - if (!m_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 sPathUtf8New = U_TO_UTF8(m_wsDstFile); std::string sPathUtf8Old = U_TO_UTF8(m_wsSrcFile); if (sPathUtf8Old == sPathUtf8New || NSSystemPath::NormalizePath(sPathUtf8Old) == NSSystemPath::NormalizePath(sPathUtf8New)) { @@ -1305,6 +1282,127 @@ bool CPdfEditor::EditPage(int nPageIndex, bool bSet) RELEASEOBJECT(pXref); return false; } +bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength) +{ + PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); + XRef* xref = pPDFDocument->getXRef(); + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); + + // Страницы должны быть созданы заранее для ссылки + Catalog* pCatalog = pPDFDocument->getCatalog(); + for (int i = 0; i < unLength; ++i) + { + Ref* pPageRef = pCatalog->getPageRef(arrPageIndex[i] + 1); + if (pPageRef->num == 0) + { + m_nError = 3; + return false; + } + + PdfWriter::CPage* pPage = new PdfWriter::CPage(pDoc); + pDoc->AddObject(pPage); + pDoc->AddPage(pPage); + + // Получение объекта страницы + Object pageRefObj, pageObj; + pageRefObj.initRef(pPageRef->num, pPageRef->gen); + if (!pageRefObj.fetch(xref, &pageObj)->isDict()) + { + pageObj.free(); + pageRefObj.free(); + m_nError = 3; + return false; + } + m_mSplitUniqueRef[pPageRef->num] = pPage; + pageRefObj.free(); + } + bool bRes = true; + for (unsigned int i = 0; i < unLength; ++i) + bRes &= SplitPage(arrPageIndex[i]); + if (!bRes) + return false; + + Object oCatalog; + if (!xref->getCatalog(&oCatalog)->isDict()) + { + oCatalog.free(); + return false; + } + + Object oAcroForm; + if (oCatalog.dictLookupNF("AcroForm", &oAcroForm)->isRef() || oAcroForm.isDict()) + { + PdfWriter::CDictObject* pAcroForm = new PdfWriter::CDictObject(); + if (oAcroForm.isRef()) + { + pDoc->AddObject(pAcroForm); + oAcroForm.free(); + if (!oCatalog.dictLookup("AcroForm", &oAcroForm)->isDict()) + { + oAcroForm.free(); oCatalog.free(); + return false; + } + } + pDoc->SetAcroForm(pAcroForm); + + 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(); + + std::map::iterator it = m_mSplitUniqueRef.find(oFieldsRef.num); + if (oFieldsRef.num > 0 && it != m_mSplitUniqueRef.end()) + { + pAcroForm->Add(chKey, it->second); + continue; + } + + if (oAcroForm.dictGetVal(nIndex, &oTemp)->isArray()) + { + PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject(); + if (oFieldsRef.num > 0) + { + pDoc->AddObject(pArray); + m_mSplitUniqueRef[oFieldsRef.num] = pArray; + } + pAcroForm->Add(chKey, pArray); + for (int nIndex = 0; nIndex < oTemp.arrayGetLength(); ++nIndex) + { + Object oRes; + if (oTemp.arrayGetNF(nIndex, &oRes)->isRef()) + { + it = m_mSplitUniqueRef.find(oRes.getRefNum()); + if (it != m_mSplitUniqueRef.end()) + pArray->Add(it->second); + } + oRes.free(); + } + oTemp.free(); + continue; + } + else + { + oTemp.free(); + oAcroForm.dictGetValNF(nIndex, &oTemp); + } + } + else + oAcroForm.dictGetValNF(nIndex, &oTemp); + PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp, pDoc, xref, m_mSplitUniqueRef); + pAcroForm->Add(chKey, pBase); + oTemp.free(); + } + } + oAcroForm.free(); oCatalog.free(); + + return bRes; +} bool CPdfEditor::SplitPage(int nPageIndex) { PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); @@ -1394,91 +1492,6 @@ bool CPdfEditor::SplitPage(int nPageIndex) return true; } -void CPdfEditor::SplitEnd() -{ - PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); - XRef* xref = pPDFDocument->getXRef(); - PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); - - Object oCatalog; - if (!xref->getCatalog(&oCatalog)->isDict()) - { - oCatalog.free(); - return; - } - - Object oAcroForm; - if (oCatalog.dictLookupNF("AcroForm", &oAcroForm)->isRef() || oAcroForm.isDict()) - { - PdfWriter::CDictObject* pAcroForm = new PdfWriter::CDictObject(); - if (oAcroForm.isRef()) - { - pDoc->AddObject(pAcroForm); - oAcroForm.free(); - if (!oCatalog.dictLookup("AcroForm", &oAcroForm)->isDict()) - { - oAcroForm.free(); oCatalog.free(); - return; - } - } - pDoc->SetAcroForm(pAcroForm); - - 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(); - - std::map::iterator it = m_mSplitUniqueRef.find(oFieldsRef.num); - if (oFieldsRef.num > 0 && it != m_mSplitUniqueRef.end()) - { - pAcroForm->Add(chKey, it->second); - continue; - } - - if (oAcroForm.dictGetVal(nIndex, &oTemp)->isArray()) - { - PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject(); - if (oFieldsRef.num > 0) - { - pDoc->AddObject(pArray); - m_mSplitUniqueRef[oFieldsRef.num] = pArray; - } - pAcroForm->Add(chKey, pArray); - for (int nIndex = 0; nIndex < oTemp.arrayGetLength(); ++nIndex) - { - Object oRes; - if (oTemp.arrayGetNF(nIndex, &oRes)->isRef()) - { - it = m_mSplitUniqueRef.find(oRes.getRefNum()); - if (it != m_mSplitUniqueRef.end()) - pArray->Add(it->second); - } - oRes.free(); - } - oTemp.free(); - continue; - } - else - { - oTemp.free(); - oAcroForm.dictGetValNF(nIndex, &oTemp); - } - } - else - oAcroForm.dictGetValNF(nIndex, &oTemp); - PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp, pDoc, xref, m_mSplitUniqueRef); - pAcroForm->Add(chKey, pBase); - oTemp.free(); - } - } - oAcroForm.free(); oCatalog.free(); -} bool CPdfEditor::DeletePage(int nPageIndex) { return m_pWriter->GetDocument()->DeletePage(nPageIndex); diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h index a2318c95b0..a3a776fd19 100644 --- a/PdfFile/PdfEditor.h +++ b/PdfFile/PdfEditor.h @@ -41,13 +41,12 @@ class CPdfEditor { public: CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPassword, CPdfReader* _pReader, const std::wstring& _wsDstFile, CPdfWriter* _pWriter); - CPdfEditor(CPdfReader* _pReader, CPdfWriter* _pWriter, const int* arrPageIndex, unsigned int unLength); + CPdfEditor(CPdfReader* _pReader, CPdfWriter* _pWriter); int GetError(); void Close(); + int Close(const std::wstring& wsPath); bool EditPage(int nPageIndex, bool bSet = true); - bool SplitPage(int nPageIndex); - void SplitEnd(); bool DeletePage(int nPageIndex); bool AddPage(int nPageIndex); bool EditAnnot(int nPageIndex, int nID); @@ -62,10 +61,14 @@ public: void EndMarkedContent(); bool IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bItalic, std::wstring& wsFontPath); + bool SplitPage(int nPageIndex); + bool SplitPages(const int* arrPageIndex, unsigned int unLength); + private: void GetPageTree(XRef* xref, Object* pPagesRefObj, PdfWriter::CPageTree* pPageParent = NULL); std::wstring m_wsSrcFile; + std::wstring m_wsDstFile; std::wstring m_wsPassword; std::map m_mFonts; std::map m_mSplitUniqueRef; // map уникальных объектов для Split diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 59523c7cd4..ccd0b2731b 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -165,10 +165,6 @@ bool CPdfFile::AddPage(int nPageIndex) return false; return m_pInternal->pEditor->AddPage(nPageIndex); } -bool CPdfFile::SplitPages(const std::vector& arrPageIndex) -{ - return SplitPages(arrPageIndex.data(), arrPageIndex.size()); -} bool CPdfFile::SplitPages(const int* arrPageIndex, unsigned int unLength) { if (!m_pInternal->pEditor) @@ -179,15 +175,46 @@ bool CPdfFile::SplitPages(const int* arrPageIndex, unsigned int unLength) if (!m_pInternal->pWriter) m_pInternal->pWriter = new CPdfWriter(m_pInternal->pAppFonts, false, this); - m_pInternal->pEditor = new CPdfEditor(m_pInternal->pReader, m_pInternal->pWriter, arrPageIndex, unLength); + m_pInternal->pEditor = new CPdfEditor(m_pInternal->pReader, m_pInternal->pWriter); if (m_pInternal->pEditor->GetError() != 0) return false; } - bool bRes = true; - for (unsigned int i = 0; i < unLength; ++i) - bRes &= m_pInternal->pEditor->SplitPage(arrPageIndex[i]); - if (bRes) - m_pInternal->pEditor->SplitEnd(); + return m_pInternal->pEditor->SplitPages(arrPageIndex, unLength); +} +bool CPdfFile::MergePages(CPdfFile* pMergeFile, const int* arrPageIndex, unsigned int unLength, int nMergePos) +{ + if (!pMergeFile || !pMergeFile->m_pInternal || !pMergeFile->m_pInternal->pReader) + return false; + + if (!m_pInternal->pEditor) + { + if (!m_pInternal->pReader) + return false; + + if (!m_pInternal->pWriter) + m_pInternal->pWriter = new CPdfWriter(m_pInternal->pAppFonts, false, this); + + m_pInternal->pEditor = new CPdfEditor(m_pInternal->wsSrcFile, m_pInternal->wsPassword, m_pInternal->pReader, L"", m_pInternal->pWriter); + if (m_pInternal->pEditor->GetError() != 0) + return false; + } + + // TODO + return m_pInternal->pEditor->SplitPages(arrPageIndex, unLength); +} +bool CPdfFile::MergePages(const std::wstring& wsPath, const std::wstring& wsPassword, const int* arrPageIndex, unsigned int unLength, int nMergePos) +{ + CPdfFile* pMergeFile = new CPdfFile(m_pInternal->pAppFonts); + pMergeFile->SetTempDirectory(m_pInternal->wsTempFolder); + + if (!pMergeFile->LoadFromFile(wsPath, L"", wsPassword, wsPassword)) + { + RELEASEOBJECT(pMergeFile); + return false; + } + + bool bRes = MergePages(pMergeFile, arrPageIndex, unLength, nMergePos); + RELEASEOBJECT(pMergeFile); return bRes; } HRESULT CPdfFile::ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword) @@ -503,6 +530,8 @@ int CPdfFile::SaveToFile(const std::wstring& wsPath) { if (!m_pInternal->pWriter) return 1; + if (m_pInternal->pEditor) + return m_pInternal->pEditor->Close(wsPath); return m_pInternal->pWriter->SaveToFile(wsPath); } void CPdfFile::SetPassword(const std::wstring& wsPassword) diff --git a/PdfFile/PdfFile.h b/PdfFile/PdfFile.h index 7a03e0190b..2a0283a0be 100644 --- a/PdfFile/PdfFile.h +++ b/PdfFile/PdfFile.h @@ -94,11 +94,12 @@ public: // Переходит в режим редактирования. Pdf уже должен быть открыт на чтение - LoadFromFile/LoadFromMemory bool EditPdf(const std::wstring& wsDstFile = L""); // Манипуляции со страницами возможны в режиме редактирования - bool EditPage (int nPageIndex); - bool DeletePage (int nPageIndex); - bool AddPage (int nPageIndex); - bool SplitPages (const std::vector& arrPageIndex); - bool SplitPages (const int* arrPageIndex, unsigned int unLength); + bool EditPage (int nPageIndex); + bool DeletePage(int nPageIndex); + bool AddPage (int nPageIndex); + bool SplitPages(const int* arrPageIndex, unsigned int unLength); + bool MergePages(CPdfFile* pMergeFile, const int* arrPageIndex = NULL, unsigned int unLength = 0, int nMergePos = -1); + bool MergePages(const std::wstring& wsPath, const std::wstring& wsPassword = L"", const int* arrPageIndex = NULL, unsigned int unLength = 0, int nMergePos = -1); HRESULT ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword = L""); #endif diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 5a3e62bafc..2e7f0e4658 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(); @@ -1402,7 +1400,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; @@ -1435,7 +1433,6 @@ namespace PdfWriter } m_unFormFields = nFormField; - m_wsFilePath = wsPath; return true; } bool CDocument::EditResources(CXref* pXref, CResourcesDict* pResources) @@ -1610,16 +1607,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; @@ -1708,7 +1705,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 e449be6eb1..931830540c 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -190,16 +190,15 @@ 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); bool DeletePage(int nPageIndex); - bool AddToFile(CXref* pXref, CDictObject* pTrailer, CXref* pInfoXref, CInfoDict* pInfo); + bool AddToFile(const std::wstring& wsPath, CXref* pXref, CDictObject* pTrailer, CXref* pInfoXref, CInfoDict* pInfo); void AddObject(CObjectBase* pObj); void Sign(const TRect& oRect, CImageDict* pImage, ICertificate* pCert); - std::wstring GetEditPdfPath() { return m_wsFilePath; } bool EditAnnot (CXref* pXref, CAnnotation* pAnnot, int nID); bool EditParent(CXref* pXref, CDictObject* pParent, int nID); bool DeleteAnnot(int nObjNum, int nObjGen); @@ -309,7 +308,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/test/test.cpp b/PdfFile/test/test.cpp index 407fad324a..dbd83c86f3 100644 --- a/PdfFile/test/test.cpp +++ b/PdfFile/test/test.cpp @@ -356,14 +356,21 @@ TEST_F(CPdfFileTest, SplitPdf) LoadFromFile(); - pdfFile->SplitPages({2, 5, 6, 7}); + std::vector arrPages = { 0, 1, 2, 3 }; + pdfFile->SplitPages(arrPages.empty() ? NULL : arrPages.data(), arrPages.size()); pdfFile->SaveToFile(wsDstFile); } TEST_F(CPdfFileTest, MergePdf) { - GTEST_SKIP(); + //GTEST_SKIP(); + + LoadFromFile(); + + pdfFile->MergePages(wsSrcFile); + + pdfFile->SaveToFile(wsDstFile); } TEST_F(CPdfFileTest, CopyAnotherPdf) From e1b13913accf911563bbcf79dd4e64ff8c631b96 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 19 Feb 2025 11:38:55 +0300 Subject: [PATCH 038/186] Fix EditPdf --- PdfFile/PdfEditor.cpp | 126 ++++++++++++++++++------------------------ PdfFile/PdfEditor.h | 8 +-- PdfFile/PdfFile.cpp | 46 ++------------- PdfFile/PdfFile.h | 1 - PdfFile/test/test.cpp | 7 ++- 5 files changed, 69 insertions(+), 119 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 52b2897e35..a036c07ab9 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -647,7 +647,7 @@ 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) +CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPassword, const std::wstring& _wsDstFile, CPdfReader* _pReader, CPdfWriter* _pWriter) { m_wsSrcFile = _wsSrcFile; m_wsDstFile = _wsDstFile; @@ -656,7 +656,7 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa m_pWriter = _pWriter; m_nEditPage = -1; m_nError = 0; - m_nMode = 0; + m_nMode = -1; PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); if (!pPDFDocument) @@ -665,7 +665,24 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa return; } - // Если результат редактирования будет сохранен в тот же файл, что открыт для чтения, то файл необходимо сделать редактируемым + XRef* xref = pPDFDocument->getXRef(); + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); + if (!xref || !pDoc) + { + m_nError = 1; + return; + } +} +bool CPdfEditor::IncrementalUpdates() +{ + if (m_nMode == 0) + return true; + + m_nMode = 0; + PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); + 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)) @@ -676,49 +693,30 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa delete owner_pswd; delete user_pswd; if (!bRes) - { - m_nError = 2; // Не удалось проверить файл для записи - return; - } + return false; } - else if (!m_wsDstFile.empty()) + else { if (!NSFile::CFileBinary::Copy(m_wsSrcFile, m_wsDstFile)) - { - m_nError = 2; - return; - } + return false; NSFile::CFileBinary oFile; if (!oFile.OpenFile(m_wsDstFile, true)) - { - m_nError = 2; - return; - } + return false; oFile.CloseFile(); } - XRef* xref = pPDFDocument->getXRef(); - PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); - if (!xref || !pDoc) - { - m_nError = 1; - return; - } - // Получение каталога и дерева страниц из reader Object catDict, catRefObj, pagesRefObj; if (!xref->getCatalog(&catDict)->isDict() || !catDict.dictLookupNF("Pages", &pagesRefObj)) { pagesRefObj.free(); catDict.free(); - m_nError = 3; // Не удалось получить каталог и дерево страниц - return; + return false; } Object* trailer = xref->getTrailerDict(); if (!trailer || !trailer->isDict() || !trailer->dictLookupNF("Root", &catRefObj)->isRef()) { pagesRefObj.free(); catDict.free(); catRefObj.free(); - m_nError = 3; // Не удалось получить каталог и дерево страниц - return; + return false; } Ref catRef = catRefObj.getRef(); catRefObj.free(); @@ -728,15 +726,13 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa if (!pXref) { pagesRefObj.free(); catDict.free(); - m_nError = 1; - return; + return false; } PdfWriter::CCatalog* pCatalog = new PdfWriter::CCatalog(); if (!pCatalog) { pagesRefObj.free(); catDict.free(); RELEASEOBJECT(pXref); - m_nError = 1; - return; + return false; } pXref->Add(pCatalog, catRef.gen); PdfWriter::CResourcesDict* pDR = NULL; @@ -884,8 +880,7 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa pagesRefObj.free(); RELEASEOBJECT(pXref); RELEASEOBJECT(pDRXref); - m_nError = 4; // Ошибка шифрования файла - return; + return false; } } } @@ -901,49 +896,22 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa bRes = pDoc->EditResources(pDRXref, pDR); } pagesRefObj.free(); - if (!bRes) - m_nError = 5; // Ошибка применения редактирования -} -CPdfEditor::CPdfEditor(CPdfReader* _pReader, CPdfWriter* _pWriter) -{ - m_pReader = _pReader; - m_pWriter = _pWriter; - m_nEditPage = -1; - m_nError = 0; - m_nMode = 1; - - PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); - if (!pPDFDocument) - { - m_nError = 1; - return; - } - - XRef* xref = pPDFDocument->getXRef(); - PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); - if (!xref || !pDoc) - { - m_nError = 1; - return; - } -} -int CPdfEditor::Close(const std::wstring& wsPath) -{ - m_wsDstFile = wsPath; - Close(); - return 0; + return bRes; } void CPdfEditor::Close() { - if (m_nMode != 0 || m_wsDstFile.empty()) + if (m_wsDstFile.empty()) return; + + if (m_nMode == 1) + { + m_pWriter->SaveToFile(m_wsDstFile); + return; + } + PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); - if (!pPDFDocument || !pDoc) - return; XRef* xref = pPDFDocument->getXRef(); - if (!xref) - return; // Добавляем первый элемент в таблицу xref // он должен иметь вид 0000000000 65535 f @@ -1127,6 +1095,9 @@ void CPdfEditor::GetPageTree(XRef* xref, Object* pPagesRefObj, PdfWriter::CPageT } bool CPdfEditor::EditPage(int nPageIndex, bool bSet) { + if (m_nMode != 0 && !IncrementalUpdates()) + return false; + PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); if (!pPDFDocument || !pDoc) @@ -1284,13 +1255,16 @@ bool CPdfEditor::EditPage(int nPageIndex, bool bSet) } bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength) { + if (m_nMode >= 0) + return false; + m_nMode = 1; PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); XRef* xref = pPDFDocument->getXRef(); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); // Страницы должны быть созданы заранее для ссылки Catalog* pCatalog = pPDFDocument->getCatalog(); - for (int i = 0; i < unLength; ++i) + for (unsigned int i = 0; i < unLength; ++i) { Ref* pPageRef = pCatalog->getPageRef(arrPageIndex[i] + 1); if (pPageRef->num == 0) @@ -1316,6 +1290,7 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength) m_mSplitUniqueRef[pPageRef->num] = pPage; pageRefObj.free(); } + bool bRes = true; for (unsigned int i = 0; i < unLength; ++i) bRes &= SplitPage(arrPageIndex[i]); @@ -1494,10 +1469,16 @@ bool CPdfEditor::SplitPage(int nPageIndex) } bool CPdfEditor::DeletePage(int nPageIndex) { + if (m_nMode != 0 && !IncrementalUpdates()) + return false; + return m_pWriter->GetDocument()->DeletePage(nPageIndex); } bool CPdfEditor::AddPage(int nPageIndex) { + if (m_nMode != 0 && !IncrementalUpdates()) + return false; + // Применение добавления страницы для writer if (!m_pWriter->AddPage(nPageIndex)) return false; @@ -1837,6 +1818,9 @@ bool CPdfEditor::DeleteAnnot(int nID, Object* oAnnots) } bool CPdfEditor::EditWidgets(IAdvancedCommand* pCommand) { + if (m_nMode != 0 && !IncrementalUpdates()) + return false; + CWidgetsInfo* pFieldInfo = (CWidgetsInfo*)pCommand; PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h index a3a776fd19..65d441fc03 100644 --- a/PdfFile/PdfEditor.h +++ b/PdfFile/PdfEditor.h @@ -40,12 +40,12 @@ HRESULT _ChangePassword(const std::wstring& wsPath, const std::wstring& wsPasswo class CPdfEditor { public: - CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPassword, CPdfReader* _pReader, const std::wstring& _wsDstFile, CPdfWriter* _pWriter); - CPdfEditor(CPdfReader* _pReader, CPdfWriter* _pWriter); + CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPassword, const std::wstring& _wsDstFile, CPdfReader* _pReader, CPdfWriter* _pWriter); + + bool IncrementalUpdates(); int GetError(); void Close(); - int Close(const std::wstring& wsPath); bool EditPage(int nPageIndex, bool bSet = true); bool DeletePage(int nPageIndex); bool AddPage(int nPageIndex); @@ -61,10 +61,10 @@ public: void EndMarkedContent(); bool IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bItalic, std::wstring& wsFontPath); - bool SplitPage(int nPageIndex); bool SplitPages(const int* arrPageIndex, unsigned int unLength); private: + bool SplitPage(int nPageIndex); void GetPageTree(XRef* xref, Object* pPagesRefObj, PdfWriter::CPageTree* pPageParent = NULL); std::wstring m_wsSrcFile; diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index ccd0b2731b..87fbc61be3 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -133,18 +133,14 @@ void CPdfFile::RotatePage(int 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) @@ -168,42 +164,14 @@ bool CPdfFile::AddPage(int nPageIndex) bool CPdfFile::SplitPages(const int* arrPageIndex, unsigned int unLength) { if (!m_pInternal->pEditor) - { - if (!m_pInternal->pReader) - return false; - - if (!m_pInternal->pWriter) - m_pInternal->pWriter = new CPdfWriter(m_pInternal->pAppFonts, false, this); - - m_pInternal->pEditor = new CPdfEditor(m_pInternal->pReader, m_pInternal->pWriter); - if (m_pInternal->pEditor->GetError() != 0) - return false; - } - return m_pInternal->pEditor->SplitPages(arrPageIndex, unLength); -} -bool CPdfFile::MergePages(CPdfFile* pMergeFile, const int* arrPageIndex, unsigned int unLength, int nMergePos) -{ - if (!pMergeFile || !pMergeFile->m_pInternal || !pMergeFile->m_pInternal->pReader) return false; - - if (!m_pInternal->pEditor) - { - if (!m_pInternal->pReader) - return false; - - if (!m_pInternal->pWriter) - m_pInternal->pWriter = new CPdfWriter(m_pInternal->pAppFonts, false, this); - - m_pInternal->pEditor = new CPdfEditor(m_pInternal->wsSrcFile, m_pInternal->wsPassword, m_pInternal->pReader, L"", m_pInternal->pWriter); - if (m_pInternal->pEditor->GetError() != 0) - return false; - } - - // TODO return m_pInternal->pEditor->SplitPages(arrPageIndex, unLength); } bool CPdfFile::MergePages(const std::wstring& wsPath, const std::wstring& wsPassword, const int* arrPageIndex, unsigned int unLength, int nMergePos) { + if (!m_pInternal->pEditor) + return false; + CPdfFile* pMergeFile = new CPdfFile(m_pInternal->pAppFonts); pMergeFile->SetTempDirectory(m_pInternal->wsTempFolder); @@ -213,7 +181,7 @@ bool CPdfFile::MergePages(const std::wstring& wsPath, const std::wstring& wsPass return false; } - bool bRes = MergePages(pMergeFile, arrPageIndex, unLength, nMergePos); + bool bRes = m_pInternal->pEditor->SplitPages(arrPageIndex, unLength); RELEASEOBJECT(pMergeFile); return bRes; } @@ -530,8 +498,6 @@ int CPdfFile::SaveToFile(const std::wstring& wsPath) { if (!m_pInternal->pWriter) return 1; - if (m_pInternal->pEditor) - return m_pInternal->pEditor->Close(wsPath); return m_pInternal->pWriter->SaveToFile(wsPath); } void CPdfFile::SetPassword(const std::wstring& wsPassword) diff --git a/PdfFile/PdfFile.h b/PdfFile/PdfFile.h index 2a0283a0be..cec8f5e493 100644 --- a/PdfFile/PdfFile.h +++ b/PdfFile/PdfFile.h @@ -98,7 +98,6 @@ public: bool DeletePage(int nPageIndex); bool AddPage (int nPageIndex); bool SplitPages(const int* arrPageIndex, unsigned int unLength); - bool MergePages(CPdfFile* pMergeFile, const int* arrPageIndex = NULL, unsigned int unLength = 0, int nMergePos = -1); bool MergePages(const std::wstring& wsPath, const std::wstring& wsPassword = L"", const int* arrPageIndex = NULL, unsigned int unLength = 0, int nMergePos = -1); HRESULT ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword = L""); #endif diff --git a/PdfFile/test/test.cpp b/PdfFile/test/test.cpp index dbd83c86f3..32c46785ae 100644 --- a/PdfFile/test/test.cpp +++ b/PdfFile/test/test.cpp @@ -355,16 +355,17 @@ TEST_F(CPdfFileTest, SplitPdf) //GTEST_SKIP(); LoadFromFile(); + ASSERT_TRUE(pdfFile->EditPdf(wsDstFile)); - std::vector arrPages = { 0, 1, 2, 3 }; + std::vector arrPages = { 0 }; pdfFile->SplitPages(arrPages.empty() ? NULL : arrPages.data(), arrPages.size()); - pdfFile->SaveToFile(wsDstFile); + pdfFile->Close(); } TEST_F(CPdfFileTest, MergePdf) { - //GTEST_SKIP(); + GTEST_SKIP(); LoadFromFile(); From edcd90774931ffd39d5acc3a2139131e4b6a2ee8 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 19 Feb 2025 17:51:10 +0300 Subject: [PATCH 039/186] Fix MergePages --- PdfFile/PdfEditor.cpp | 266 ++++++++++++++++++--------------- PdfFile/PdfEditor.h | 4 +- PdfFile/PdfFile.cpp | 2 +- PdfFile/SrcWriter/Document.cpp | 14 +- PdfFile/SrcWriter/Document.h | 4 +- PdfFile/test/test.cpp | 9 +- 6 files changed, 157 insertions(+), 142 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index a036c07ab9..3a3c109325 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -1253,49 +1253,125 @@ bool CPdfEditor::EditPage(int nPageIndex, bool bSet) RELEASEOBJECT(pXref); return false; } -bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength) +bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, CPdfReader* _pReader, int nMergePos) { - if (m_nMode >= 0) + if (m_nMode == 1 || (m_nMode == 0 && !_pReader)) return false; - m_nMode = 1; - PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); + if (m_nMode < 0) + m_nMode = 1; + PDFDoc* pPDFDocument = _pReader ? _pReader->GetPDFDocument() : m_pReader->GetPDFDocument(); XRef* xref = pPDFDocument->getXRef(); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); - // Страницы должны быть созданы заранее для ссылки + if (unLength == 0) + unLength = pPDFDocument->getNumPages(); + + // Страницы должны быть созданы заранее для ссылки на них Catalog* pCatalog = pPDFDocument->getCatalog(); for (unsigned int i = 0; i < unLength; ++i) { - Ref* pPageRef = pCatalog->getPageRef(arrPageIndex[i] + 1); + Ref* pPageRef = pCatalog->getPageRef((arrPageIndex ? arrPageIndex[i] : i) + 1); if (pPageRef->num == 0) - { - m_nError = 3; return false; - } PdfWriter::CPage* pPage = new PdfWriter::CPage(pDoc); pDoc->AddObject(pPage); - pDoc->AddPage(pPage); + pDoc->AddPage(nMergePos == -1 ? pDoc->GetPagesCount() : (nMergePos + i), pPage); // Получение объекта страницы Object pageRefObj, pageObj; pageRefObj.initRef(pPageRef->num, pPageRef->gen); if (!pageRefObj.fetch(xref, &pageObj)->isDict()) { - pageObj.free(); - pageRefObj.free(); - m_nError = 3; + pageObj.free(); pageRefObj.free(); return false; } m_mSplitUniqueRef[pPageRef->num] = pPage; - pageRefObj.free(); + pageObj.free(); pageRefObj.free(); } - bool bRes = true; for (unsigned int i = 0; i < unLength; ++i) - bRes &= SplitPage(arrPageIndex[i]); - if (!bRes) - return false; + { + Ref* pPageRef = pCatalog->getPageRef((arrPageIndex ? arrPageIndex[i] : i) + 1); + if (pPageRef->num == 0) + return false; + + // Получение объекта страницы + PdfWriter::CPage* pPage = (PdfWriter::CPage*)m_mSplitUniqueRef[pPageRef->num]; + 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(); + + std::map::iterator it = m_mSplitUniqueRef.find(oResourcesRef.num); + if (oResourcesRef.num > 0 && it != m_mSplitUniqueRef.end()) + { + pPage->Add(chKey, it->second); + continue; + } + + if (pageObj.dictGetVal(nIndex, &oTemp)->isDict()) + { + PdfWriter::CResourcesDict* pDict = pDoc->CreateResourcesDict(oResourcesRef.num < 0, false); + if (oResourcesRef.num > 0) + m_mSplitUniqueRef[oResourcesRef.num] = 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_mSplitUniqueRef); + pDict->Add(chKey2, pBase); + oRes.free(); + } + + oTemp.free(); + continue; + } + else + { + oTemp.free(); + pageObj.dictGetValNF(nIndex, &oTemp); + } + } + else if (strcmp("Parent", chKey) == 0) + { + oTemp.free(); + continue; + } + else + pageObj.dictGetValNF(nIndex, &oTemp); + PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp, pDoc, xref, m_mSplitUniqueRef); + pPage->Add(chKey, pBase); + oTemp.free(); + } + pPage->Fix(); + if (m_nMode == 0) + { + // pPage->AddContents(); // TODO pPage->AddContents чтобы можно было дописать изменения, если понадобится + } + else + m_pWriter->SetNeedAddHelvetica(false); // TODO дописывает шрифт для адекватного редактирования Adobe pdf без текст. Убрать при реализации map шрифтов + pageObj.free(); + } Object oCatalog; if (!xref->getCatalog(&oCatalog)->isDict()) @@ -1307,10 +1383,17 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength) Object oAcroForm; if (oCatalog.dictLookupNF("AcroForm", &oAcroForm)->isRef() || oAcroForm.isDict()) { - PdfWriter::CDictObject* pAcroForm = new PdfWriter::CDictObject(); + PdfWriter::CDictObject* pAcroForm = pDoc->GetAcroForm(); + if (!pAcroForm) + { + pAcroForm = new PdfWriter::CDictObject(); + if (oAcroForm.isRef()) + pDoc->AddObject(pAcroForm); + pDoc->SetAcroForm(pAcroForm); + } + if (oAcroForm.isRef()) { - pDoc->AddObject(pAcroForm); oAcroForm.free(); if (!oCatalog.dictLookup("AcroForm", &oAcroForm)->isDict()) { @@ -1318,7 +1401,6 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength) return false; } } - pDoc->SetAcroForm(pAcroForm); for (int nIndex = 0; nIndex < oAcroForm.dictGetLength(); ++nIndex) { @@ -1331,41 +1413,64 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength) oFieldsRef = oTemp.getRef(); oTemp.free(); - std::map::iterator it = m_mSplitUniqueRef.find(oFieldsRef.num); - if (oFieldsRef.num > 0 && it != m_mSplitUniqueRef.end()) + PdfWriter::CArrayObject* pFields = dynamic_cast(pAcroForm->Get("Fields")); + if (!pFields) { - pAcroForm->Add(chKey, it->second); - continue; + std::map::iterator it = m_mSplitUniqueRef.find(oFieldsRef.num); + if (oFieldsRef.num > 0 && it != m_mSplitUniqueRef.end()) + { + pAcroForm->Add(chKey, it->second); + continue; + } } if (oAcroForm.dictGetVal(nIndex, &oTemp)->isArray()) { - PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject(); - if (oFieldsRef.num > 0) + if (!pFields) { - pDoc->AddObject(pArray); - m_mSplitUniqueRef[oFieldsRef.num] = pArray; + pFields = new PdfWriter::CArrayObject(); + if (oFieldsRef.num > 0) + { + pDoc->AddObject(pFields); + m_mSplitUniqueRef[oFieldsRef.num] = pFields; + } + pAcroForm->Add(chKey, pFields); } - pAcroForm->Add(chKey, pArray); + for (int nIndex = 0; nIndex < oTemp.arrayGetLength(); ++nIndex) { Object oRes; if (oTemp.arrayGetNF(nIndex, &oRes)->isRef()) { - it = m_mSplitUniqueRef.find(oRes.getRefNum()); + std::map::iterator it = m_mSplitUniqueRef.find(oRes.getRefNum()); if (it != m_mSplitUniqueRef.end()) - pArray->Add(it->second); + pFields->Add(it->second); } oRes.free(); } oTemp.free(); continue; } - else + 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"))) + { + oTemp.free(); + continue; + } + else if (strcmp("DR", chKey) == 0) + { + // TODO объединение ресурсов >(0o0)< + oAcroForm.dictGetValNF(nIndex, &oTemp); } else oAcroForm.dictGetValNF(nIndex, &oTemp); @@ -1376,97 +1481,14 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength) } oAcroForm.free(); oCatalog.free(); - return bRes; -} -bool CPdfEditor::SplitPage(int nPageIndex) -{ - PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); - PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); - if (!pPDFDocument || !pDoc) - return false; - - XRef* xref = pPDFDocument->getXRef(); - Catalog* pCatalog = pPDFDocument->getCatalog(); - if (!xref || !pCatalog) - return false; - Ref* pPageRef = pCatalog->getPageRef(nPageIndex + 1); - if (pPageRef->num == 0) - return false; - - // Получение объекта страницы - PdfWriter::CPage* pPage = (PdfWriter::CPage*)m_mSplitUniqueRef[pPageRef->num]; - 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(); - - std::map::iterator it = m_mSplitUniqueRef.find(oResourcesRef.num); - if (oResourcesRef.num > 0 && it != m_mSplitUniqueRef.end()) - { - pPage->Add(chKey, it->second); - continue; - } - - if (pageObj.dictGetVal(nIndex, &oTemp)->isDict()) - { - PdfWriter::CResourcesDict* pDict = pDoc->CreateResourcesDict(oResourcesRef.num < 0, false); - if (oResourcesRef.num > 0) - m_mSplitUniqueRef[oResourcesRef.num] = 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_mSplitUniqueRef); - pDict->Add(chKey2, pBase); - oRes.free(); - } - - oTemp.free(); - continue; - } - else - { - oTemp.free(); - pageObj.dictGetValNF(nIndex, &oTemp); - } - } - else if (strcmp("Parent", chKey) == 0) - { - oTemp.free(); - continue; - } - else - pageObj.dictGetValNF(nIndex, &oTemp); - PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp, pDoc, xref, m_mSplitUniqueRef); - pPage->Add(chKey, pBase); - oTemp.free(); - } - pPage->Fix(); - // TODO pPage->AddContents чтобы можно было дописать изменения, если понадобится - m_pWriter->SetNeedAddHelvetica(false); // TODO дописывает шрифт для адекватного редактирования Adobe pdf без текст. Убрать при реализации map шрифтов - pageObj.free(); - return true; } +bool CPdfEditor::MergePages(CPdfReader* _pReader, const int* arrPageIndex, unsigned int unLength, int nMergePos) +{ + if (m_nMode != 0 && !IncrementalUpdates()) + return false; + return SplitPages(arrPageIndex, unLength, _pReader, nMergePos); +} bool CPdfEditor::DeletePage(int nPageIndex) { if (m_nMode != 0 && !IncrementalUpdates()) diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h index 65d441fc03..aab15d52da 100644 --- a/PdfFile/PdfEditor.h +++ b/PdfFile/PdfEditor.h @@ -61,10 +61,10 @@ public: void EndMarkedContent(); bool IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bItalic, std::wstring& wsFontPath); - bool SplitPages(const int* arrPageIndex, unsigned int unLength); + bool SplitPages(const int* arrPageIndex, unsigned int unLength, CPdfReader* _pReader = NULL, int nMergePos = -1); + bool MergePages(CPdfReader* _pReader, const int* arrPageIndex, unsigned int unLength, int nMergePos); private: - bool SplitPage(int nPageIndex); void GetPageTree(XRef* xref, Object* pPagesRefObj, PdfWriter::CPageTree* pPageParent = NULL); std::wstring m_wsSrcFile; diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 87fbc61be3..1f04e1cce5 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -181,7 +181,7 @@ bool CPdfFile::MergePages(const std::wstring& wsPath, const std::wstring& wsPass return false; } - bool bRes = m_pInternal->pEditor->SplitPages(arrPageIndex, unLength); + bool bRes = m_pInternal->pEditor->MergePages(pMergeFile->m_pInternal->pReader, arrPageIndex, unLength, nMergePos); RELEASEOBJECT(pMergeFile); return bRes; } diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 2e7f0e4658..a5bb8097df 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -335,12 +335,6 @@ namespace PdfWriter m_pTrailer->Add("Encrypt", m_pEncryptDict); m_bEncrypt = true; } - void CDocument::AddPage(CPage* pPage) - { - pPage->Add("Parent", m_pPageTree); - m_pPageTree->AddPage(pPage); - m_pCurPage = pPage; - } CPage* CDocument::AddPage() { CPage* pPage = new CPage(m_pXref, m_pPageTree, this); @@ -1569,22 +1563,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; } diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index 931830540c..4041bf0ae4 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -121,7 +121,6 @@ namespace PdfWriter void SetPDFAConformanceMode(bool isPDFA); bool IsPDFA() const; - void AddPage(CPage* pPage); CPage* AddPage(); CPage* GetPage (const unsigned int& unPage); CPage* GetEditPage(const unsigned int& unPage); @@ -194,7 +193,7 @@ namespace PdfWriter bool EditResources(CXref* pXref, CResourcesDict* pResources); std::pair GetPageRef(int nPageIndex); bool EditPage(CXref* pXref, CPage* pPage, int nPageIndex); - CPage* AddPage(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); @@ -214,6 +213,7 @@ namespace PdfWriter void ClearPage(); bool EditXref(CXref* pXref); void SetAcroForm(CDictObject* pObj); + CDictObject* GetAcroForm() { return m_pAcroForm; } CResourcesDict* CreateResourcesDict(bool bInline, bool bProcSet); private: diff --git a/PdfFile/test/test.cpp b/PdfFile/test/test.cpp index 32c46785ae..a1bd68a537 100644 --- a/PdfFile/test/test.cpp +++ b/PdfFile/test/test.cpp @@ -352,7 +352,7 @@ TEST_F(CPdfFileTest, VerifySign) TEST_F(CPdfFileTest, SplitPdf) { - //GTEST_SKIP(); + GTEST_SKIP(); LoadFromFile(); ASSERT_TRUE(pdfFile->EditPdf(wsDstFile)); @@ -365,13 +365,14 @@ TEST_F(CPdfFileTest, SplitPdf) TEST_F(CPdfFileTest, MergePdf) { - GTEST_SKIP(); + //GTEST_SKIP(); LoadFromFile(); + ASSERT_TRUE(pdfFile->EditPdf(NSFile::GetProcessDirectory() + L"/test3.pdf")); - pdfFile->MergePages(wsSrcFile); + pdfFile->MergePages(wsDstFile); - pdfFile->SaveToFile(wsDstFile); + pdfFile->Close(); } TEST_F(CPdfFileTest, CopyAnotherPdf) From bb65d1a90b5806c539ab234b7772767d60923de2 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 20 Feb 2025 17:53:40 +0600 Subject: [PATCH 040/186] Add connections conversion --- .../XlsFile/Format/Auxiliary/HelpFunc.cpp | 11 +- .../XlsFile/Format/Auxiliary/HelpFunc.h | 1 + .../Logic/Biff_structures/SyntaxPtg.cpp | 6 + OOXML/Binary/Sheets/Writer/BinaryReader.cpp | 6 +- OOXML/XlsxFormat/Table/Connections.cpp | 177 ++++++++---------- 5 files changed, 103 insertions(+), 98 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp index 379449bd1a..b2eef912e2 100644 --- a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp +++ b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp @@ -725,7 +725,16 @@ unsigned short sheetsnames2ixti(std::wstring name) XLS::GlobalWorkbookInfo::arXti_External_static.push_back(newXti); return newXti.iSup; } - +unsigned short AddXti(const std::wstring& name) +{ + XLS::GlobalWorkbookInfo::_xti newXti; + newXti.iSup = XLS::GlobalWorkbookInfo::arXti_External_static.size(); + newXti.itabFirst = XLS::GlobalWorkbookInfo::arXti_External_static.size(); + newXti.itabLast = XLS::GlobalWorkbookInfo::arXti_External_static.size(); + newXti.link = name; + XLS::GlobalWorkbookInfo::arXti_External_static.push_back(newXti); + return newXti.iSup; +} unsigned int AddDefinedName(const std::wstring& name) { XLS::GlobalWorkbookInfo::arDefineNames_static.push_back(name); diff --git a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h index bf9abf6a92..51f9e2b7e3 100644 --- a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h +++ b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h @@ -97,6 +97,7 @@ 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 short AddXti(const std::wstring& name); unsigned int AddDefinedName(const std::wstring& name); } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp index a93b32f0a9..8933fdc320 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp @@ -755,6 +755,12 @@ const bool SyntaxPtg::extract_3D_part(std::wstring::const_iterator& first, std:: return true; } } + else + { + ixti = XMLSTUFF::AddXti(boost::algorithm::replace_all_copy(sheets_names, L"''", L"'")); + first = results[0].second; + return true; + } } return false; } diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index 1b672f021b..73405ee38a 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp @@ -2154,6 +2154,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); @@ -2280,6 +2282,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()); @@ -9187,8 +9191,6 @@ int BinaryFileReader::ReadFile(const std::wstring& sSrcFileName, std::wstring sD OOX::CPath oXlPath = OOX::CPath(sDstPath).GetDirectory() / oXlsb.m_pWorkbook->DefaultDirectory(); oXlsb.WriteWorkbook(oXlPath); - if(oXlsb.m_pWorkbook) - oXlsb.m_pWorkbook->OOX::File::m_pMainDocument = &oXlsb; if(oXlsb.m_pStyles) oXlsb.m_pStyles->OOX::File::m_pMainDocument = &oXlsb; if(oXlsb.m_pSharedStrings) 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 From 7eb0892ab9f5cc232dfa5bcb06919327df603151 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 20 Feb 2025 14:56:34 +0300 Subject: [PATCH 041/186] Fix DR AcroForm MergePages --- PdfFile/PdfEditor.cpp | 100 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 95 insertions(+), 5 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 3a3c109325..b07e2ca78a 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -1391,6 +1391,10 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, CPdf pDoc->AddObject(pAcroForm); pDoc->SetAcroForm(pAcroForm); } + else + { + pAcroForm->Remove("NeedAppearances"); + } if (oAcroForm.isRef()) { @@ -1424,6 +1428,11 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, CPdf } } + // TODO нужна проверка полных имён + // Если имя совпадает, то: + // Если другие поля - тип, флаг и т.д. совпадает, то выносим общее в общего родителя + // Иначе переименовываем, action обрубаем + if (oAcroForm.dictGetVal(nIndex, &oTemp)->isArray()) { if (!pFields) @@ -1462,15 +1471,96 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, CPdf continue; } } - else if (strcmp("SigFlags", chKey) == 0 || strcmp("XFA", chKey) == 0 || (strcmp("DA", chKey) == 0 && pAcroForm->Get("DA"))) - { + 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) - { - // TODO объединение ресурсов >(0o0)< - oAcroForm.dictGetValNF(nIndex, &oTemp); + { // Добавляем только уникальные ключи + 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()) + { + std::map::iterator it = m_mSplitUniqueRef.find(oTempRef.getRefNum()); + if (it != m_mSplitUniqueRef.end()) + { + pDR->Add(chKey2, it->second); + oTemp2.free(); oTempRef.free(); + continue; + } + } + PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp2, pDoc, xref, m_mSplitUniqueRef); + 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()) + { + std::map::iterator it = m_mSplitUniqueRef.find(oTempRef.getRefNum()); + if (it != m_mSplitUniqueRef.end()) + { + pDict->Add(chKey3, it->second); + oTemp2.free(); oTempRef.free(); + continue; + } + } + PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp2, pDoc, xref, m_mSplitUniqueRef); + 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); From 49a40fa8419f1a3316d171bace958b19ebd26d88 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 20 Feb 2025 17:39:10 +0300 Subject: [PATCH 042/186] MergePages SplitPages commands --- PdfFile/OnlineOfficeBinToPdf.cpp | 31 ++++++++++++++++++++++++++++++- PdfFile/PdfEditor.cpp | 10 +++++----- PdfFile/PdfEditor.h | 4 ++-- PdfFile/PdfFile.cpp | 4 ++-- PdfFile/PdfFile.h | 2 +- 5 files changed, 40 insertions(+), 11 deletions(-) diff --git a/PdfFile/OnlineOfficeBinToPdf.cpp b/PdfFile/OnlineOfficeBinToPdf.cpp index b9bf950496..4ee10b03a5 100644 --- a/PdfFile/OnlineOfficeBinToPdf.cpp +++ b/PdfFile/OnlineOfficeBinToPdf.cpp @@ -151,6 +151,8 @@ namespace NSOnlineOfficeBinToPdf RemovePage = 2, WidgetInfo = 3, MovePage = 4, + MergePages = 5, + SplitPages = 6, Undefined = 255 }; @@ -175,7 +177,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 && CommandType != AddCommandType::SplitPages) nPageNum = oReader.ReadInt(); if (nPageNum < 0) @@ -210,6 +212,33 @@ namespace NSOnlineOfficeBinToPdf pPdf->DeletePage(nPageNum); break; } + case AddCommandType::MergePages: + { + std::wstring wsPath = oReader.ReadString(); + std::wstring wsPassword = oReader.ReadString(); + int nLength = oReader.ReadInt(); + int* pPageIndex = new int[nLength]; + int* pPositions = new int[nLength]; + for (int i = 0; i < nLength; ++i) + { + pPageIndex[i] = oReader.ReadInt(); + pPositions[i] = oReader.ReadInt(); + } + pPdf->MergePages(wsPath, wsPassword, pPageIndex, nLength, pPositions); + delete[] pPageIndex; + delete[] pPositions; + break; + } + case AddCommandType::SplitPages: + { + int nLength = oReader.ReadInt(); + int* pPageIndex = new int[nLength]; + for (int i = 0; i < nLength; ++i) + pPageIndex[i] = oReader.ReadInt(); + pPdf->SplitPages(pPageIndex, nLength); + delete[] pPageIndex; + break; + } case AddCommandType::WidgetInfo: { NSOnlineOfficeBinToPdf::ConvertBufferToRenderer(oReader.GetCurrentBuffer(), (LONG)(nLen - 5) , &oCorrector); diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 275081291d..9e380d78b1 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -1254,7 +1254,7 @@ bool CPdfEditor::EditPage(int nPageIndex, bool bSet, bool bActualPos) RELEASEOBJECT(pXref); return false; } -bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, CPdfReader* _pReader, int nMergePos) +bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, CPdfReader* _pReader, const int* arrPositions) { if (m_nMode == 1 || (m_nMode == 0 && !_pReader)) return false; @@ -1277,7 +1277,7 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, CPdf PdfWriter::CPage* pPage = new PdfWriter::CPage(pDoc); pDoc->AddObject(pPage); - pDoc->AddPage(nMergePos == -1 ? pDoc->GetPagesCount() : (nMergePos + i), pPage); + pDoc->AddPage(arrPositions ? arrPositions[i] : pDoc->GetPagesCount(), pPage); // Получение объекта страницы Object pageRefObj, pageObj; @@ -1574,11 +1574,11 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, CPdf return true; } -bool CPdfEditor::MergePages(CPdfReader* _pReader, const int* arrPageIndex, unsigned int unLength, int nMergePos) +bool CPdfEditor::MergePages(CPdfReader* _pReader, const int* arrPageIndex, unsigned int unLength, const int* arrPositions) { if (m_nMode != 0 && !IncrementalUpdates()) return false; - return SplitPages(arrPageIndex, unLength, _pReader, nMergePos); + return SplitPages(arrPageIndex, unLength, _pReader, arrPositions); } bool CPdfEditor::DeletePage(int nPageIndex) { @@ -1612,7 +1612,7 @@ bool CPdfEditor::MovePage(int nPageIndex, int nPos) if (EditPage(nPageIndex, true, true)) { m_nEditPage = nPos; - return pWriter->GetDocument()->MovePage(nPageIndex, nPos); + return m_pWriter->GetDocument()->MovePage(nPageIndex, nPos); } return false; } diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h index 8f4c3ac553..6c4eac58ec 100644 --- a/PdfFile/PdfEditor.h +++ b/PdfFile/PdfEditor.h @@ -62,8 +62,8 @@ public: void EndMarkedContent(); bool IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bItalic, std::wstring& wsFontPath); - bool SplitPages(const int* arrPageIndex, unsigned int unLength, CPdfReader* _pReader = NULL, int nMergePos = -1); - bool MergePages(CPdfReader* _pReader, const int* arrPageIndex, unsigned int unLength, int nMergePos); + bool SplitPages(const int* arrPageIndex, unsigned int unLength, CPdfReader* _pReader = NULL, const int* arrPositions = NULL); + bool MergePages(CPdfReader* _pReader, const int* arrPageIndex, unsigned int unLength, const int* arrPositions); private: void GetPageTree(XRef* xref, Object* pPagesRefObj, PdfWriter::CPageTree* pPageParent = NULL); diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 0c288278c2..2827d17bd3 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -167,7 +167,7 @@ bool CPdfFile::SplitPages(const int* arrPageIndex, unsigned int unLength) return false; return m_pInternal->pEditor->SplitPages(arrPageIndex, unLength); } -bool CPdfFile::MergePages(const std::wstring& wsPath, const std::wstring& wsPassword, const int* arrPageIndex, unsigned int unLength, int nMergePos) +bool CPdfFile::MergePages(const std::wstring& wsPath, const std::wstring& wsPassword, const int* arrPageIndex, unsigned int unLength, const int* arrPosition) { if (!m_pInternal->pEditor) return false; @@ -181,7 +181,7 @@ bool CPdfFile::MergePages(const std::wstring& wsPath, const std::wstring& wsPass return false; } - bool bRes = m_pInternal->pEditor->MergePages(pMergeFile->m_pInternal->pReader, arrPageIndex, unLength, nMergePos); + bool bRes = m_pInternal->pEditor->MergePages(pMergeFile->m_pInternal->pReader, arrPageIndex, unLength, arrPosition); RELEASEOBJECT(pMergeFile); return bRes; } diff --git a/PdfFile/PdfFile.h b/PdfFile/PdfFile.h index 4b3d8a8d9c..f1816091de 100644 --- a/PdfFile/PdfFile.h +++ b/PdfFile/PdfFile.h @@ -99,7 +99,7 @@ public: bool AddPage (int nPageIndex); bool MovePage (int nPageIndex, int nPos); bool SplitPages(const int* arrPageIndex, unsigned int unLength); - bool MergePages(const std::wstring& wsPath, const std::wstring& wsPassword = L"", const int* arrPageIndex = NULL, unsigned int unLength = 0, int nMergePos = -1); + bool MergePages(const std::wstring& wsPath, const std::wstring& wsPassword = L"", const int* arrPageIndex = NULL, unsigned int unLength = 0, const int* arrPosition = NULL); HRESULT ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword = L""); #endif From 54c094375400457d450776728336ee5608b4a6db Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 21 Feb 2025 19:30:10 +0600 Subject: [PATCH 043/186] Add sheet&table names pre reading for formulas --- .../XlsFile/Format/Auxiliary/HelpFunc.cpp | 11 +- .../XlsFile/Format/Auxiliary/HelpFunc.h | 1 - .../Logic/Biff_structures/SyntaxPtg.cpp | 6 - OOXML/Binary/Sheets/Writer/BinaryReader.cpp | 122 +++++++++++++++++- OOXML/Binary/Sheets/Writer/BinaryReader.h | 5 + OOXML/XlsxFormat/Workbook/Sheets.h | 3 +- 6 files changed, 127 insertions(+), 21 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp index b2eef912e2..379449bd1a 100644 --- a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp +++ b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp @@ -725,16 +725,7 @@ unsigned short sheetsnames2ixti(std::wstring name) XLS::GlobalWorkbookInfo::arXti_External_static.push_back(newXti); return newXti.iSup; } -unsigned short AddXti(const std::wstring& name) -{ - XLS::GlobalWorkbookInfo::_xti newXti; - newXti.iSup = XLS::GlobalWorkbookInfo::arXti_External_static.size(); - newXti.itabFirst = XLS::GlobalWorkbookInfo::arXti_External_static.size(); - newXti.itabLast = XLS::GlobalWorkbookInfo::arXti_External_static.size(); - newXti.link = name; - XLS::GlobalWorkbookInfo::arXti_External_static.push_back(newXti); - return newXti.iSup; -} + unsigned int AddDefinedName(const std::wstring& name) { XLS::GlobalWorkbookInfo::arDefineNames_static.push_back(name); diff --git a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h index 51f9e2b7e3..bf9abf6a92 100644 --- a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h +++ b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h @@ -97,7 +97,6 @@ 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 short AddXti(const std::wstring& name); unsigned int AddDefinedName(const std::wstring& name); } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp index 8933fdc320..a93b32f0a9 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SyntaxPtg.cpp @@ -755,12 +755,6 @@ const bool SyntaxPtg::extract_3D_part(std::wstring::const_iterator& first, std:: return true; } } - else - { - ixti = XMLSTUFF::AddXti(boost::algorithm::replace_all_copy(sheets_names, L"''", L"'")); - first = results[0].second; - return true; - } } return false; } diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index 73405ee38a..5243842850 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp @@ -410,7 +410,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; @@ -437,6 +442,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; @@ -4162,6 +4233,12 @@ 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; } @@ -4227,6 +4304,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); @@ -4689,6 +4781,7 @@ int BinaryWorksheetsTableReader::ReadWorksheet(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); @@ -5014,13 +5107,38 @@ int BinaryWorksheetsTableReader::ReadWorksheet(boost::unordered_mapgetNextRecord(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; diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.h b/OOXML/Binary/Sheets/Writer/BinaryReader.h index a809c42af6..3886cb8848 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.h +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.h @@ -143,6 +143,9 @@ namespace BinXlsxRW 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 { @@ -335,9 +338,11 @@ namespace BinXlsxRW 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); 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); }; From f28dc0a36a938d7370a9be4d351e59efe506cbe3 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 24 Feb 2025 15:47:03 +0300 Subject: [PATCH 044/186] Create CPdfReaderContext --- PdfFile/PdfFile.cpp | 11 +- PdfFile/PdfFile.h | 1 + PdfFile/PdfReader.cpp | 294 +++++++++++++++++---------------- PdfFile/PdfReader.h | 32 +++- PdfFile/SrcReader/Adaptors.cpp | 4 - PdfFile/SrcReader/Adaptors.h | 1 - 6 files changed, 184 insertions(+), 159 deletions(-) diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 2827d17bd3..34f55ec4c0 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -341,7 +341,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); } @@ -386,6 +386,15 @@ void CPdfFile::GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, do else m_pInternal->pReader->GetPageInfo(nPageIndex, pdWidth, pdHeight, pdDpiX, pdDpiY); } +bool CPdfFile::AddPdf(BYTE* data, DWORD length, const std::wstring& wsPassword) +{ + m_pInternal->pReader = new CPdfReader(m_pInternal->pAppFonts); + if (!m_pInternal->pReader) + return false; + m_pInternal->wsSrcFile.clear(); + m_pInternal->wsPassword = wsPassword; + return m_pInternal->pReader->LoadFromMemory(m_pInternal->pAppFonts, data, length, wsPassword, wsPassword) && (m_pInternal->pReader->GetError() == 0); +} int CPdfFile::GetRotate(int nPageIndex) { if (!m_pInternal->pReader) diff --git a/PdfFile/PdfFile.h b/PdfFile/PdfFile.h index f1816091de..05f13555f3 100644 --- a/PdfFile/PdfFile.h +++ b/PdfFile/PdfFile.h @@ -129,6 +129,7 @@ public: virtual BYTE* GetStructure(); virtual BYTE* GetLinks(int nPageIndex); bool ValidMetaData(); + bool AddPdf(BYTE* data, DWORD length, const std::wstring& wsPassword = L""); int GetRotate(int nPageIndex); int GetMaxRefID(); BYTE* GetWidgets(); diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index ba49925cb3..a32e5a1582 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,164 @@ 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 (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,17 +367,12 @@ 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()); @@ -373,10 +380,13 @@ bool CPdfReader::LoadFromFile(NSFonts::IApplicationFonts* pAppFonts, const std:: 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); + + CPdfReaderContext* pContext = new CPdfReaderContext(); + pContext->m_pDocument = new PDFDoc((char*)sPathUtf8.c_str(), owner_pswd, user_pswd); + pContext->m_pFontList = new PdfReader::CPdfFontList(); + PDFDoc* pDoc = pContext->m_pDocument; delete owner_pswd; delete user_pswd; @@ -388,17 +398,14 @@ bool CPdfReader::LoadFromFile(NSFonts::IApplicationFonts* pAppFonts, const std:: oFile.CloseFile(); } - m_eError = m_pPDFDocument ? m_pPDFDocument->getErrorCode() : errMemory; - - if (!m_pPDFDocument || !m_pPDFDocument->isOk()) + m_eError = pDoc ? pDoc->getErrorCode() : errMemory; + if (!pDoc || !pDoc->isOk()) { - RELEASEOBJECT(m_pPDFDocument); + Clear(); return false; } - m_pFontList->Clear(); - - std::map mFonts = PdfReader::CAnnotFonts::GetAllFonts(m_pPDFDocument, m_pFontManager, m_pFontList); + std::map mFonts = PdfReader::CAnnotFonts::GetAllFonts(pDoc, m_pFontManager, pContext->m_pFontList); m_mFonts.insert(mFonts.begin(), mFonts.end()); return true; @@ -411,7 +418,6 @@ bool CPdfReader::LoadFromMemory(NSFonts::IApplicationFonts* pAppFonts, BYTE* dat pMeasurerCache->SetStreams(pAppFonts->GetStreams()); m_pFontManager->SetOwnerCache(pMeasurerCache); pMeasurerCache->SetCacheSize(1); - ((GlobalParamsAdaptor*)globalParams)->SetFontManager(m_pFontManager); RELEASEOBJECT(m_pPDFDocument); m_eError = errNone; @@ -443,6 +449,10 @@ bool CPdfReader::LoadFromMemory(NSFonts::IApplicationFonts* pAppFonts, BYTE* dat return true; } +bool CPdfReader::AddFromMemory(BYTE* pData, DWORD nLength, const std::wstring& wsPassword) +{ + return true; +} void CPdfReader::Close() { RELEASEOBJECT(m_pPDFDocument); @@ -596,10 +606,6 @@ std::wstring CPdfReader::ToXml(const std::wstring& wsFilePath, bool isPrintStrea return wsXml; } -void CPdfReader::ChangeLength(DWORD nLength) -{ - m_nFileLength = nLength; -} std::wstring CPdfReader::GetInfo() { diff --git a/PdfFile/PdfReader.h b/PdfFile/PdfReader.h index 2cb86aeb75..f314f15386 100644 --- a/PdfFile/PdfReader.h +++ b/PdfFile/PdfReader.h @@ -32,21 +32,34 @@ #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; + + CPdfReaderContext() : m_pDocument(NULL), m_pFontList(NULL) {} + CPdfReaderContext(PDFDoc* pDocument, PdfReader::CPdfFontList* pFontList) : m_pDocument(pDocument), m_pFontList(pFontList) {} + ~CPdfReaderContext(); +}; + class CPdfReader { public: - CPdfReader(NSFonts::IApplicationFonts* pAppFonts); ~CPdfReader(); bool LoadFromFile (NSFonts::IApplicationFonts* pAppFonts, const std::wstring& file, const std::wstring& owner_password = L"", const std::wstring& user_password = L""); bool LoadFromMemory(NSFonts::IApplicationFonts* pAppFonts, BYTE* data, DWORD length, const std::wstring& owner_password = L"", const std::wstring& user_password = L""); + bool AddFromMemory (BYTE* pData, DWORD nLength, const std::wstring& wsPassword = L""); void Close(); @@ -67,11 +80,10 @@ public: 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); + NSFonts::IFontManager* GetFontManager() { return m_pFontManager; } - PDFDoc* GetPDFDocument() { return m_pPDFDocument; } + // PDFDoc* GetPDFDocument() { return m_pPDFDocument; } BYTE* GetStructure(); BYTE* GetLinks(int nPageIndex); @@ -87,12 +99,14 @@ public: std::map GetFonts() { return m_mFonts; } private: - PDFDoc* m_pPDFDocument; + void Clear(); + void ReadFonts(); + 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/SrcReader/Adaptors.cpp b/PdfFile/SrcReader/Adaptors.cpp index ad8da8382c..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; diff --git a/PdfFile/SrcReader/Adaptors.h b/PdfFile/SrcReader/Adaptors.h index 825c4801f1..e5e0495f6b 100644 --- a/PdfFile/SrcReader/Adaptors.h +++ b/PdfFile/SrcReader/Adaptors.h @@ -62,7 +62,6 @@ class GlobalParamsAdaptor : public GlobalParams bool m_bDrawFormField; public: - NSFonts::IFontManager *m_pFontManager; GlobalParamsAdaptor(const char *filename) : GlobalParams(filename) { m_bCMapData = NULL; From f5d2ff992ac3f449e328214e7c34ca09d9b7bcf4 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 25 Feb 2025 18:09:10 +0600 Subject: [PATCH 045/186] Fix worksheetProp conversion --- .../XlsxFormat/Worksheets/DataValidation.cpp | 4 +-- .../Worksheets/WorksheetChildOther.cpp | 27 ++++++++++++++----- 2 files changed, 23 insertions(+), 8 deletions(-) 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/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 2a01c9e9d5..7e431e7bb6 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -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""; + 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); From 4085f58b093a86651873410343f000382a6dddaa Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 25 Feb 2025 17:48:42 +0300 Subject: [PATCH 046/186] Fix CPdfReader functions --- PdfFile/PdfReader.cpp | 260 ++++++++++++++++++++++++++---------------- PdfFile/PdfReader.h | 2 +- 2 files changed, 161 insertions(+), 101 deletions(-) diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index a32e5a1582..0175dbb23e 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -410,41 +410,38 @@ bool CPdfReader::LoadFromFile(NSFonts::IApplicationFonts* pAppFonts, const std:: return true; } -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); + m_pFontManager = InitFontManager(pAppFonts); - RELEASEOBJECT(m_pPDFDocument); m_eError = errNone; - GString* owner_pswd = NSStrings::CreateString(owner_password); - GString* user_pswd = NSStrings::CreateString(user_password); + GString* owner_pswd = NSStrings::CreateString(wsOwnerPassword); + GString* user_pswd = NSStrings::CreateString(wsUserPassword); 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; + CPdfReaderContext* pContext = new CPdfReaderContext(); + pContext->m_pDocument = new PDFDoc(str, owner_pswd, user_pswd); + pContext->m_pFontList = new PdfReader::CPdfFontList(); + PDFDoc* pDoc = pContext->m_pDocument; delete owner_pswd; delete user_pswd; - m_eError = m_pPDFDocument ? m_pPDFDocument->getErrorCode() : errMemory; + m_nFileLength = length; - if (!m_pPDFDocument || !m_pPDFDocument->isOk()) + m_eError = pDoc ? pDoc->getErrorCode() : errMemory; + if (!pDoc || !pDoc->isOk()) { - RELEASEOBJECT(m_pPDFDocument); + Clear(); return false; } - m_pFontList->Clear(); - - std::map mFonts = PdfReader::CAnnotFonts::GetAllFonts(m_pPDFDocument, m_pFontManager, m_pFontList); + std::map mFonts = PdfReader::CAnnotFonts::GetAllFonts(pDoc, m_pFontManager, pContext->m_pFontList); m_mFonts.insert(mFonts.begin(), mFonts.end()); return true; @@ -455,7 +452,7 @@ bool CPdfReader::AddFromMemory(BYTE* pData, DWORD nLength, const std::wstring& w } void CPdfReader::Close() { - RELEASEOBJECT(m_pPDFDocument); + Clear(); m_mFonts.clear(); } void CPdfReader::SetParams(COfficeDrawingPageParams* pParams) @@ -468,37 +465,64 @@ void CPdfReader::SetParams(COfficeDrawingPageParams* pParams) globalParams->setDrawAnnotations(bDraw); } +int CPdfReader::GetPageIndex(int nPageIndex, PDFDoc** pDoc, PdfReader::CPdfFontList** pFontList) +{ + int nTotalPages = 0; + for (CPdfReaderContext* pPDFContext : m_vPDFContext) + { + if (!pPDFContext || !pPDFContext->m_pDocument) + continue; + + int nPages = pPDFContext->m_pDocument->getNumPages(); + if (nPageIndex < nTotalPages + nPages) + { + if (pDoc) + *pDoc = pPDFContext->m_pDocument; + if (pFontList) + *pFontList = pPDFContext->m_pFontList; + return nPageIndex - 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 @@ -507,29 +531,40 @@ 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(); + int nMaxRefID = 0; + for (CPdfReaderContext* pPDFContext : m_vPDFContext) + { + if (!pPDFContext || !pPDFContext->m_pDocument || !pPDFContext->m_pDocument->getXRef()) + continue; + nMaxRefID = std::max(nMaxRefID, pPDFContext->m_pDocument->getXRef()->getNumObjects()); + } + return nMaxRefID; } 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(); @@ -546,25 +581,25 @@ bool CPdfReader::ValidMetaData() } 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()) { @@ -591,7 +626,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"") @@ -609,17 +644,24 @@ std::wstring CPdfReader::ToXml(const std::wstring& wsFilePath, bool isPrintStrea 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) { @@ -691,7 +733,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); @@ -707,34 +749,46 @@ std::wstring CPdfReader::GetInfo() sRes += L",\"PageHeight\":"; sRes += std::to_wstring((int)(nH * 100)); sRes += L",\"NumberOfPages\":"; - sRes += std::to_wstring(m_pPDFDocument->getNumPages()); + + int nNumPages = 0; + for (CPdfReaderContext* pPDFContext : m_vPDFContext) + { + if (!pPDFContext || !pPDFContext->m_pDocument) + continue; + PDFDoc* pDoc = pPDFContext->m_pDocument; + nNumPages += pDoc->getNumPages(); + } + + sRes += std::to_wstring(nNumPages); 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\":"; @@ -827,9 +881,14 @@ void getBookmarks(PDFDoc* pdfDoc, OutlineItem* pOutlineItem, NSWasm::CData& out, } BYTE* CPdfReader::GetStructure() { - if (!m_pPDFDocument) + if (m_vPDFContext.empty()) return NULL; - Outline* pOutline = m_pPDFDocument->getOutline(); + CPdfReaderContext* pPDFContext = m_vPDFContext.front(); + if (!pPDFContext || !pPDFContext->m_pDocument) + return NULL; + + PDFDoc* pDoc = pPDFContext->m_pDocument; + Outline* pOutline = pDoc->getOutline(); if (!pOutline) return NULL; GList* pList = pOutline->getItems(); @@ -842,7 +901,7 @@ BYTE* CPdfReader::GetStructure() { OutlineItem* pOutlineItem = (OutlineItem*)pList->get(i); if (pOutlineItem) - getBookmarks(m_pPDFDocument, pOutlineItem, oRes, 1); + getBookmarks(pDoc, pOutlineItem, oRes, 1); } oRes.WriteLen(); @@ -850,20 +909,21 @@ BYTE* CPdfReader::GetStructure() oRes.ClearWithoutAttack(); return bRes; } -BYTE* CPdfReader::GetLinks(int nPageIndex) +BYTE* CPdfReader::GetLinks(int _nPageIndex) { - if (!m_pPDFDocument || !m_pPDFDocument->getCatalog()) + 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(); @@ -888,14 +948,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(); @@ -904,7 +964,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; @@ -919,8 +979,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")) { @@ -929,7 +989,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()); @@ -950,8 +1010,8 @@ BYTE* CPdfReader::GetLinks(int nPageIndex) 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++) { diff --git a/PdfFile/PdfReader.h b/PdfFile/PdfReader.h index f314f15386..177758f512 100644 --- a/PdfFile/PdfReader.h +++ b/PdfFile/PdfReader.h @@ -100,7 +100,7 @@ public: private: void Clear(); - void ReadFonts(); + int GetPageIndex(int nPageIndex, PDFDoc** pDoc = NULL, PdfReader::CPdfFontList** pFontList = NULL); std::wstring m_wsTempFolder; NSFonts::IFontManager* m_pFontManager; From 62dbbc6d0d1cfdf8a7e92d40b9c2ff0ab610fe61 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 26 Feb 2025 15:18:18 +0300 Subject: [PATCH 047/186] Fix CPdfReader functions --- .../graphics/pro/js/wasm/js/drawingfile.js | 125 +++++------ PdfFile/OnlineOfficeBinToPdf.cpp | 7 +- PdfFile/PdfEditor.cpp | 81 ++++---- PdfFile/PdfEditor.h | 6 +- PdfFile/PdfFile.cpp | 22 +- PdfFile/PdfFile.h | 2 +- PdfFile/PdfReader.cpp | 194 +++++++++--------- PdfFile/PdfReader.h | 10 +- PdfFile/SrcWriter/Document.cpp | 2 +- 9 files changed, 222 insertions(+), 227 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js index cc47211257..09d5b85acf 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js @@ -1161,71 +1161,78 @@ CFile.prototype["getInteractiveFormsInfo"] = function() let reader = ptr.getReader(); 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) - { - 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 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); - } + let arrRes = []; - res["Fields"] = []; - k = reader.readInt(); - for (let q = 0; reader.isValid() && q < k; ++q) + while (reader.isValid()) { - 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); + let res = {}; + let k = reader.readInt(); + if (k > 0) + res["CO"] = []; + for (let i = 0; i < k; ++i) + res["CO"].push(reader.readInt()); - res["Fields"].push(rec); + k = reader.readInt(); + if (k > 0) + res["Parents"] = []; + for (let i = 0; i < k; ++i) + { + 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 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, reader.readDouble, reader.readDouble2, reader.readString); + // Widget type + readWidgetType(reader, rec, reader.readDouble, reader.readDouble2, reader.readString); + + res["Fields"].push(rec); + } + + arrRes.push(res); } ptr.free(); - return res; + return arrRes; }; // optional nWidget - rec["AP"]["i"] diff --git a/PdfFile/OnlineOfficeBinToPdf.cpp b/PdfFile/OnlineOfficeBinToPdf.cpp index 4ee10b03a5..bdc3663490 100644 --- a/PdfFile/OnlineOfficeBinToPdf.cpp +++ b/PdfFile/OnlineOfficeBinToPdf.cpp @@ -218,15 +218,10 @@ namespace NSOnlineOfficeBinToPdf std::wstring wsPassword = oReader.ReadString(); int nLength = oReader.ReadInt(); int* pPageIndex = new int[nLength]; - int* pPositions = new int[nLength]; for (int i = 0; i < nLength; ++i) - { pPageIndex[i] = oReader.ReadInt(); - pPositions[i] = oReader.ReadInt(); - } - pPdf->MergePages(wsPath, wsPassword, pPageIndex, nLength, pPositions); + pPdf->MergePages(wsPath, wsPassword, pPageIndex, nLength); delete[] pPageIndex; - delete[] pPositions; break; } case AddCommandType::SplitPages: diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 9e380d78b1..b6e7c9ff83 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -34,6 +34,7 @@ #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" @@ -402,7 +403,7 @@ HRESULT _ChangePassword(const std::wstring& wsPath, const std::wstring& wsPasswo { if (!_pReader || !_pWriter) return S_FALSE; - PDFDoc* pPDFDocument = _pReader->GetPDFDocument(); + PDFDoc* pPDFDocument = _pReader->GetFirstPDFDocument(); if (!pPDFDocument) return S_FALSE; XRef* xref = pPDFDocument->getXRef(); @@ -658,7 +659,7 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa m_nError = 0; m_nMode = -1; - PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); + PDFDoc* pPDFDocument = m_pReader->GetFirstPDFDocument(); if (!pPDFDocument) { m_nError = 1; @@ -679,7 +680,7 @@ bool CPdfEditor::IncrementalUpdates() return true; m_nMode = 0; - PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); + PDFDoc* pPDFDocument = m_pReader->GetFirstPDFDocument(); XRef* xref = pPDFDocument->getXRef(); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); @@ -909,7 +910,7 @@ void CPdfEditor::Close() return; } - PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); + PDFDoc* pPDFDocument = m_pReader->GetFirstPDFDocument(); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); XRef* xref = pPDFDocument->getXRef(); @@ -1093,25 +1094,31 @@ 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) { if (m_nMode != 0 && !IncrementalUpdates()) return false; - PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); + PDFDoc* pPDFDocument = NULL; + int nPageIndex = m_pReader->GetPageIndex(_nPageIndex - 1, &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 = pDoc->GetEditPage(_nPageIndex); + if (!pEditPage) + pEditPage = pDoc->GetPage(nPageIndex); if (pEditPage) { if (bSet) { pDoc->SetCurPage(pEditPage); m_pWriter->EditPage(pEditPage); - m_nEditPage = nPageIndex; + m_nEditPage = _nPageIndex; } return true; } @@ -1232,12 +1239,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) { m_pWriter->EditPage(pPage); - m_nEditPage = nPageIndex; + m_nEditPage = _nPageIndex; } pPage->StartTransform(dCTM[0], dCTM[1], dCTM[2], dCTM[3], dCTM[4], dCTM[5]); pPage->SetStrokeColor(0, 0, 0); @@ -1254,13 +1261,13 @@ bool CPdfEditor::EditPage(int nPageIndex, bool bSet, bool bActualPos) RELEASEOBJECT(pXref); return false; } -bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, CPdfReader* _pReader, const int* arrPositions) +bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFDoc* _pDoc) { - if (m_nMode == 1 || (m_nMode == 0 && !_pReader)) + if (m_nMode == 1 || (m_nMode == 0 && !_pDoc)) return false; if (m_nMode < 0) m_nMode = 1; - PDFDoc* pPDFDocument = _pReader ? _pReader->GetPDFDocument() : m_pReader->GetPDFDocument(); + PDFDoc* pPDFDocument = _pDoc ? _pDoc : m_pReader->GetFirstPDFDocument(); XRef* xref = pPDFDocument->getXRef(); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); @@ -1277,7 +1284,7 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, CPdf PdfWriter::CPage* pPage = new PdfWriter::CPage(pDoc); pDoc->AddObject(pPage); - pDoc->AddPage(arrPositions ? arrPositions[i] : pDoc->GetPagesCount(), pPage); + pDoc->AddPage(pDoc->GetPagesCount(), pPage); // Получение объекта страницы Object pageRefObj, pageObj; @@ -1574,11 +1581,11 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, CPdf return true; } -bool CPdfEditor::MergePages(CPdfReader* _pReader, const int* arrPageIndex, unsigned int unLength, const int* arrPositions) +bool CPdfEditor::MergePages(PDFDoc* pDoc, const int* arrPageIndex, unsigned int unLength) { if (m_nMode != 0 && !IncrementalUpdates()) return false; - return SplitPages(arrPageIndex, unLength, _pReader, arrPositions); + return SplitPages(arrPageIndex, unLength, pDoc); } bool CPdfEditor::DeletePage(int nPageIndex) { @@ -1609,18 +1616,20 @@ bool CPdfEditor::AddPage(int nPageIndex) } bool CPdfEditor::MovePage(int nPageIndex, int nPos) { - if (EditPage(nPageIndex, true, true)) + if (EditPage(nPageIndex)) { m_nEditPage = 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 = m_pReader->GetPDFDocument(); + PDFDoc* pPDFDocument = NULL; + PdfReader::CPdfFontList* pFontList = NULL; + int nPageIndex = m_pReader->GetPageIndex(_nPageIndex - 1, &pPDFDocument, &pFontList); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); - if (!pPDFDocument || !pDoc) + if (nPageIndex < 0 || !pPDFDocument || !pDoc) return false; XRef* xref = pPDFDocument->getXRef(); @@ -1652,14 +1661,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); - m_pWriter->EditPage(pEditPage); - } + if (!pDoc->GetEditPage(_nPageIndex)) + EditPage(_nPageIndex, false); // Воспроизведение словаря аннотации из reader для writer PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, oAnnotRef.getRefNum()); @@ -1685,7 +1688,7 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID) pAnnot = new PdfWriter::CPolygonLineAnnotation(pXref); else if (oType.isName("FreeText")) { - std::map mapFont = m_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); } @@ -1877,16 +1880,18 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID) } bool CPdfEditor::DeleteAnnot(int nID, Object* oAnnots) { - PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); + PDFDoc* pPDFDocument = NULL; + int nPageIndex = m_pReader->GetPageIndex(m_nEditPage - 1, &pPDFDocument); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); - if (!pPDFDocument || !pDoc) + 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; @@ -1944,7 +1949,7 @@ bool CPdfEditor::EditWidgets(IAdvancedCommand* pCommand) return false; CWidgetsInfo* pFieldInfo = (CWidgetsInfo*)pCommand; - PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); + PDFDoc* pPDFDocument = m_pReader->GetFirstPDFDocument(); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); std::vector arrParents = pFieldInfo->GetParents(); @@ -2001,10 +2006,14 @@ bool CPdfEditor::IsEditPage() } void CPdfEditor::ClearPage() { - PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(); - XRef* xref = pPDFDocument->getXRef(); + PDFDoc* pPDFDocument = NULL; + int nPageIndex = m_pReader->GetPageIndex(m_nEditPage - 1, &pPDFDocument); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); - std::pair pPageRef = pDoc->GetPageRef(m_nEditPage); + if (nPageIndex < 0 || !pPDFDocument || !pDoc) + return; + XRef* xref = pPDFDocument->getXRef(); + PdfWriter::CPage* pPage = pDoc->GetCurPage(); + std::pair pPageRef = { pPage->GetObjId(), pPage->GetObjId() }; // Получение объекта страницы Object pageRefObj, pageObj; diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h index 6c4eac58ec..bee40bc7c3 100644 --- a/PdfFile/PdfEditor.h +++ b/PdfFile/PdfEditor.h @@ -46,7 +46,7 @@ public: int GetError(); void Close(); - bool EditPage(int nPageIndex, bool bSet = true, bool bActualPos = false); + bool EditPage(int nPageIndex, bool bSet = true); bool DeletePage(int nPageIndex); bool AddPage(int nPageIndex); bool MovePage(int nPageIndex, int nPos); @@ -62,8 +62,8 @@ public: void EndMarkedContent(); bool IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bItalic, std::wstring& wsFontPath); - bool SplitPages(const int* arrPageIndex, unsigned int unLength, CPdfReader* _pReader = NULL, const int* arrPositions = NULL); - bool MergePages(CPdfReader* _pReader, const int* arrPageIndex, unsigned int unLength, const int* arrPositions); + bool SplitPages(const int* arrPageIndex, unsigned int unLength, PDFDoc* pDoc = NULL); + bool MergePages(PDFDoc* pDoc, const int* arrPageIndex, unsigned int unLength); private: void GetPageTree(XRef* xref, Object* pPagesRefObj, PdfWriter::CPageTree* pPageParent = NULL); diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 34f55ec4c0..663d7caf09 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -167,23 +167,13 @@ bool CPdfFile::SplitPages(const int* arrPageIndex, unsigned int unLength) return false; return m_pInternal->pEditor->SplitPages(arrPageIndex, unLength); } -bool CPdfFile::MergePages(const std::wstring& wsPath, const std::wstring& wsPassword, const int* arrPageIndex, unsigned int unLength, const int* arrPosition) +bool CPdfFile::MergePages(const std::wstring& wsPath, const std::wstring& wsPassword, const int* arrPageIndex, unsigned int unLength) { if (!m_pInternal->pEditor) return false; - CPdfFile* pMergeFile = new CPdfFile(m_pInternal->pAppFonts); - pMergeFile->SetTempDirectory(m_pInternal->wsTempFolder); - - if (!pMergeFile->LoadFromFile(wsPath, L"", wsPassword, wsPassword)) - { - RELEASEOBJECT(pMergeFile); - return false; - } - - bool bRes = m_pInternal->pEditor->MergePages(pMergeFile->m_pInternal->pReader, arrPageIndex, unLength, arrPosition); - RELEASEOBJECT(pMergeFile); - return bRes; + if (m_pInternal->pReader->AddFromFile(wsPath, wsPassword)) + return m_pInternal->pEditor->MergePages(m_pInternal->pReader->GetLastPDFDocument(), arrPageIndex, unLength); } bool CPdfFile::MovePage(int nPageIndex, int nPos) { @@ -367,15 +357,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) { diff --git a/PdfFile/PdfFile.h b/PdfFile/PdfFile.h index 05f13555f3..f744409604 100644 --- a/PdfFile/PdfFile.h +++ b/PdfFile/PdfFile.h @@ -99,7 +99,7 @@ public: bool AddPage (int nPageIndex); bool MovePage (int nPageIndex, int nPos); bool SplitPages(const int* arrPageIndex, unsigned int unLength); - bool MergePages(const std::wstring& wsPath, const std::wstring& wsPassword = L"", const int* arrPageIndex = NULL, unsigned int unLength = 0, const int* arrPosition = NULL); + bool MergePages(const std::wstring& wsPath, const std::wstring& wsPassword = L"", const int* arrPageIndex = NULL, unsigned int unLength = 0); HRESULT ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword = L""); #endif diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 0175dbb23e..ab2d453661 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -446,6 +446,10 @@ bool CPdfReader::LoadFromMemory(NSFonts::IApplicationFonts* pAppFonts, BYTE* dat return true; } +bool CPdfReader::AddFromFile(const std::wstring& wsFile, const std::wstring& wsPassword) +{ + return true; +} bool CPdfReader::AddFromMemory(BYTE* pData, DWORD nLength, const std::wstring& wsPassword) { return true; @@ -548,6 +552,17 @@ int CPdfReader::GetMaxRefID() } return nMaxRefID; } +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_vPDFContext.empty() || m_vPDFContext.size() != 1) @@ -641,6 +656,26 @@ std::wstring CPdfReader::ToXml(const std::wstring& wsFilePath, bool isPrintStrea return wsXml; } +PDFDoc* CPdfReader::GetFirstPDFDocument() +{ + if (m_vPDFContext.empty()) + return NULL; + + CPdfReaderContext* pPDFContext = m_vPDFContext.front(); + if (pPDFContext) + return pPDFContext->m_pDocument; + return NULL; +} +PDFDoc* CPdfReader::GetLastPDFDocument() +{ + if (m_vPDFContext.empty()) + return NULL; + + CPdfReaderContext* pPDFContext = m_vPDFContext.back(); + if (pPDFContext) + return pPDFContext->m_pDocument; + return NULL; +} std::wstring CPdfReader::GetInfo() { @@ -749,17 +784,7 @@ std::wstring CPdfReader::GetInfo() sRes += L",\"PageHeight\":"; sRes += std::to_wstring((int)(nH * 100)); sRes += L",\"NumberOfPages\":"; - - int nNumPages = 0; - for (CPdfReaderContext* pPDFContext : m_vPDFContext) - { - if (!pPDFContext || !pPDFContext->m_pDocument) - continue; - PDFDoc* pDoc = pPDFContext->m_pDocument; - nNumPages += pDoc->getNumPages(); - } - - sRes += std::to_wstring(nNumPages); + sRes += std::to_wstring(GetNumPages()); sRes += L",\"FastWebView\":"; bool bLinearized = false; @@ -1003,7 +1028,7 @@ BYTE* CPdfReader::GetLinks(int _nPageIndex) int nRotate = 0; #ifdef BUILDING_WASM_MODULE - nRotate = -m_pPDFDocument->getPageRotate(nPageIndex); + nRotate = -pDoc->getPageRotate(nPageIndex); #endif // Текст-ссылка @@ -1043,18 +1068,22 @@ 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); + for (CPdfReaderContext* pPDFContext : m_vPDFContext) + { + PDFDoc* pDoc = pPDFContext->m_pDocument; + if (!pDoc || !pDoc->getCatalog()) + continue; + if (!pDoc->getCatalog()->getForm() || !pDoc->getXRef()) + continue; + + PdfReader::CAnnots* pAnnots = new PdfReader::CAnnots(pDoc, m_pFontManager, pPDFContext->m_pFontList); + if (pAnnots) + pAnnots->ToWASM(oRes); + RELEASEOBJECT(pAnnots); + } oRes.WriteLen(); BYTE* bRes = oRes.GetBuffer(); @@ -1096,10 +1125,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; @@ -1175,12 +1208,15 @@ 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 nPageIndex = GetPageIndex(_nPageIndex, &pDoc, &pFontList); + if (nPageIndex < 0 || !pDoc || !pFontList || !pDoc->getCatalog()) return NULL; - AcroForm* pAcroForms = m_pPDFDocument->getCatalog()->getForm(); + AcroForm* pAcroForms = pDoc->getCatalog()->getForm(); if (!pAcroForms) return NULL; @@ -1191,14 +1227,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() != 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); if (pAP) pAP->ToWASM(oRes); RELEASEOBJECT(pAP); @@ -1209,12 +1245,14 @@ 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; + int nPageIndex = GetPageIndex(_nPageIndex, &pDoc); + if (nPageIndex < 0 || !pDoc || !pDoc->getCatalog()) return NULL; - AcroForm* pAcroForms = m_pPDFDocument->getCatalog()->getForm(); + AcroForm* pAcroForms = pDoc->getCatalog()->getForm(); if (!pAcroForms) return NULL; @@ -1225,7 +1263,7 @@ 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)) + if (pField->getPageNum() != nPageIndex || pField->getAcroFormFieldType() != acroFormFieldPushbutton || (nButtonWidget >= 0 && i != nButtonWidget)) continue; Object oMK; @@ -1578,90 +1616,50 @@ void GetPageAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, PdfReade oAnnots.free(); } -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 nPageIndex = GetPageIndex(_nPageIndex, &pDoc, &pFontList); + if (nPageIndex < 0 || !pDoc || !pFontList || !pDoc->getCatalog()) + return NULL; + GetPageAnnots(pDoc, m_pFontManager, pFontList, oRes, nPageIndex - 1); + } 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()) + 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; + for (int nPage = 0, nLastPage = pDoc->getNumPages(); nPage < nLastPage; ++nPage) + GetPageAnnots(pDoc, m_pFontManager, pPDFContext->m_pFontList, oRes, nPage); } - 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 nPageIndex = GetPageIndex(_nPageIndex, &pDoc, &pFontList); + 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(); @@ -1693,7 +1691,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 - 1, sView, &oAnnotRef); if (pAP) pAP->ToWASM(oRes); RELEASEOBJECT(pAP); @@ -1708,7 +1706,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 177758f512..66f79f2947 100644 --- a/PdfFile/PdfReader.h +++ b/PdfFile/PdfReader.h @@ -59,6 +59,7 @@ public: bool LoadFromFile (NSFonts::IApplicationFonts* pAppFonts, const std::wstring& file, const std::wstring& owner_password = L"", const std::wstring& user_password = L""); bool LoadFromMemory(NSFonts::IApplicationFonts* pAppFonts, BYTE* data, DWORD length, const std::wstring& owner_password = L"", const std::wstring& user_password = L""); + bool AddFromFile (const std::wstring& wsFile, const std::wstring& wsPassword = L""); bool AddFromMemory (BYTE* pData, DWORD nLength, const std::wstring& wsPassword = L""); void Close(); @@ -75,32 +76,33 @@ public: int GetError(); int GetRotate(int nPageIndex); int GetMaxRefID(); + int GetNumPages(); bool ValidMetaData(); 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) { m_nFileLength = nLength; } NSFonts::IFontManager* GetFontManager() { return m_pFontManager; } - // PDFDoc* GetPDFDocument() { return m_pPDFDocument; } + PDFDoc* GetFirstPDFDocument(); + PDFDoc* GetLastPDFDocument(); + int GetPageIndex(int nPageIndex, PDFDoc** pDoc = NULL, PdfReader::CPdfFontList** pFontList = 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; } private: void Clear(); - int GetPageIndex(int nPageIndex, PDFDoc** pDoc = NULL, PdfReader::CPdfFontList** pFontList = NULL); std::wstring m_wsTempFolder; NSFonts::IFontManager* m_pFontManager; diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index aca4e506e2..1c43a08202 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -1466,7 +1466,7 @@ namespace PdfWriter pPage->SetFilter(STREAM_FILTER_FLATE_DECODE); #endif - m_pCurPage = pPage; + m_pCurPage = pPage; m_mEditPages[nPageIndex] = pPage; if (m_pPageTree) From 09567e225e3c1ecd63dc5c62885185f5b28227d8 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 26 Feb 2025 18:34:22 +0600 Subject: [PATCH 048/186] Fix shared strings conversion --- OOXML/XlsxFormat/SharedStrings/Si.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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]); From 258890352a8c095fcb5e02cfa775042b6b440655 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 26 Feb 2025 17:55:29 +0300 Subject: [PATCH 049/186] Fix getAnnotationsInfo --- .../graphics/pro/js/wasm/js/drawingfile.js | 36 +- .../pro/js/wasm/src/drawingfile_test.cpp | 1168 +++++++++-------- PdfFile/PdfReader.cpp | 37 +- PdfFile/SrcReader/PdfAnnot.cpp | 8 +- PdfFile/SrcReader/PdfAnnot.h | 1 + 5 files changed, 644 insertions(+), 606 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js index 09d5b85acf..3a987b728c 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js @@ -1351,26 +1351,32 @@ CFile.prototype["getAnnotationsInfo"] = function(pageIndex) if (!reader) return []; - let res = []; + let arrRes = []; 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, reader.readDouble, reader.readDouble2, reader.readString); - // Annot type - readAnnotType(reader, rec, reader.readDouble, reader.readDouble2, reader.readString); - res.push(rec); + let res = []; + let n = reader.readInt(); + for (let i = 0; i < n; ++i) + { + 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); + } + arrRes.push(res); } ptr.free(); - return res; + return arrRes; }; // optional nAnnot ... // optional sView ... diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp index 99aa6ec245..bc48af5f5d 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp @@ -1176,8 +1176,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); @@ -1291,406 +1295,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); @@ -1698,14 +1480,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; @@ -1713,199 +1593,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) diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index ab2d453661..6c9b3c16cf 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -387,6 +387,7 @@ bool CPdfReader::LoadFromFile(NSFonts::IApplicationFonts* pAppFonts, const std:: pContext->m_pDocument = new PDFDoc((char*)sPathUtf8.c_str(), owner_pswd, user_pswd); pContext->m_pFontList = new PdfReader::CPdfFontList(); PDFDoc* pDoc = pContext->m_pDocument; + m_vPDFContext.push_back(pContext); delete owner_pswd; delete user_pswd; @@ -428,6 +429,7 @@ bool CPdfReader::LoadFromMemory(NSFonts::IApplicationFonts* pAppFonts, BYTE* dat pContext->m_pDocument = new PDFDoc(str, owner_pswd, user_pswd); pContext->m_pFontList = new PdfReader::CPdfFontList(); PDFDoc* pDoc = pContext->m_pDocument; + m_vPDFContext.push_back(pContext); delete owner_pswd; delete user_pswd; @@ -1522,19 +1524,20 @@ BYTE* CPdfReader::GetButtonIcon(int nBackgroundColor, int _nPageIndex, bool bBas 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) { - 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; @@ -1610,11 +1613,16 @@ void GetPageAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, PdfReade oAnnotRef.free(); if (pAnnot) + { + pAnnot->SetPage(nStartPage + nPageIndex); pAnnot->ToWASM(oRes); + nRes++; + } RELEASEOBJECT(pAnnot); } oAnnots.free(); + return nRes; } BYTE* CPdfReader::GetAnnots(int _nPageIndex) { @@ -1631,17 +1639,32 @@ BYTE* CPdfReader::GetAnnots(int _nPageIndex) int nPageIndex = GetPageIndex(_nPageIndex, &pDoc, &pFontList); if (nPageIndex < 0 || !pDoc || !pFontList || !pDoc->getCatalog()) return NULL; - GetPageAnnots(pDoc, m_pFontManager, pFontList, oRes, nPageIndex - 1); + + int nAnnots = 0; + int nPosAnnots = oRes.GetSize(); + oRes.AddInt(nAnnots); + + nAnnots = GetPageAnnots(pDoc, m_pFontManager, pFontList, oRes, nPageIndex, _nPageIndex + 1 - nPageIndex); + + oRes.AddInt(nAnnots, nPosAnnots); } else { + int nStartPage = 0; for (CPdfReaderContext* pPDFContext : m_vPDFContext) { PDFDoc* pDoc = pPDFContext->m_pDocument; if (!pDoc || !pDoc->getCatalog() || !pPDFContext->m_pFontList) continue; - for (int nPage = 0, nLastPage = pDoc->getNumPages(); nPage < nLastPage; ++nPage) - GetPageAnnots(pDoc, m_pFontManager, pPDFContext->m_pFontList, oRes, nPage); + 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); + + oRes.AddInt(nAnnots, nPosAnnots); + nStartPage += pDoc->getNumPages(); } } diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 6db2cbd03b..9be0d2d2af 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -2933,12 +2933,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]; @@ -3059,7 +3057,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; @@ -3630,7 +3628,7 @@ 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); diff --git a/PdfFile/SrcReader/PdfAnnot.h b/PdfFile/SrcReader/PdfAnnot.h index 4eeec542c6..4c913515a2 100644 --- a/PdfFile/SrcReader/PdfAnnot.h +++ b/PdfFile/SrcReader/PdfAnnot.h @@ -168,6 +168,7 @@ public: virtual ~CAnnot(); virtual void ToWASM(NSWasm::CData& oRes); + void SetPage(unsigned int nPage) { m_unPage = nPage; } struct CBorderType final { From 4d4a67b15ad12ae628e1fe7ba4707d14c28eb753 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 27 Feb 2025 17:45:12 +0300 Subject: [PATCH 050/186] Create AddFromFile and AddFromMemory --- DesktopEditor/doctrenderer/drawingfile.h | 15 +++- .../graphics/pro/js/wasm/src/drawingfile.cpp | 7 ++ .../pro/js/wasm/src/drawingfile_test.cpp | 14 +++- PdfFile/PdfFile.cpp | 13 ++-- PdfFile/PdfFile.h | 4 +- PdfFile/PdfReader.cpp | 71 ++++++++++--------- PdfFile/SrcReader/PdfAnnot.cpp | 3 +- PdfFile/SrcReader/PdfAnnot.h | 2 +- PdfFile/SrcReader/RendererOutputDev.cpp | 12 +--- 9 files changed, 88 insertions(+), 53 deletions(-) diff --git a/DesktopEditor/doctrenderer/drawingfile.h b/DesktopEditor/doctrenderer/drawingfile.h index 9cb406f0dd..921ec48e08 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(); @@ -222,6 +221,20 @@ public: return m_pFile ? true : false; } + bool AddFile(const std::wstring& sFile, const std::wstring& sPassword) + { + if (0 != m_nType) + return false; + + return ((CPdfFile*)m_pFile)->AddFromFile(sFile, sPassword); + } + bool AddFile(BYTE* data, LONG size, const std::wstring& sPassword) + { + if (0 != m_nType) + return false; + + return ((CPdfFile*)m_pFile)->AddFromMemory(data, size, sPassword); + } void CloseFile() { diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp index 19bb4b4e3f..9fed48121b 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp @@ -102,6 +102,13 @@ WASM_EXPORT CDrawingFile* Open(BYTE* data, LONG size, const char* password) pFile->OpenFile(data, size, sPassword); return pFile; } +WASM_EXPORT int AddPDF(CDrawingFile* pFile, BYTE* data, LONG size, const char* password) +{ + std::wstring sPassword = L""; + if (NULL != password) + sPassword = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)password, strlen(password)); + return pFile->AddFile(data, size, sPassword); +} WASM_EXPORT int GetErrorCode(CDrawingFile* pFile) { if (!pFile) diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp index bc48af5f5d..8dd3bbebc9 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp @@ -952,6 +952,14 @@ int main(int argc, char* argv[]) } } + // ADD PDF + if (AddPDF(pGrFile, pFileData, (LONG)nFileDataLen, "") == 0) + { + Close(pGrFile); + RELEASEARRAYOBJECTS(pFileData); + return 1; + } + // INFO BYTE* pInfo = GetInfo(pGrFile); int nLength = READ_INT(pInfo); @@ -1024,7 +1032,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); @@ -1060,7 +1068,7 @@ int main(int argc, char* argv[]) } // STRUCTURE - if (false) + if (true) { BYTE* pStructure = GetStructure(pGrFile); nLength = READ_INT(pStructure); @@ -1090,7 +1098,7 @@ int main(int argc, char* argv[]) } // GLYPHS - if (false && nPagesCount > 0) + if (true && nPagesCount > 0) { BYTE* pGlyphs = GetGlyphs(pGrFile, nTestPage); nLength = READ_INT(pGlyphs); diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 663d7caf09..4922f33b2e 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -374,14 +374,17 @@ void CPdfFile::GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, do else m_pInternal->pReader->GetPageInfo(nPageIndex, pdWidth, pdHeight, pdDpiX, pdDpiY); } -bool CPdfFile::AddPdf(BYTE* data, DWORD length, const std::wstring& wsPassword) +bool CPdfFile::AddFromFile(const std::wstring& file, const std::wstring& wsPassword) { - m_pInternal->pReader = new CPdfReader(m_pInternal->pAppFonts); if (!m_pInternal->pReader) return false; - m_pInternal->wsSrcFile.clear(); - m_pInternal->wsPassword = wsPassword; - return m_pInternal->pReader->LoadFromMemory(m_pInternal->pAppFonts, data, length, wsPassword, wsPassword) && (m_pInternal->pReader->GetError() == 0); + return m_pInternal->pReader->AddFromFile(file, wsPassword) && (m_pInternal->pReader->GetError() == 0); +} +bool CPdfFile::AddFromMemory(BYTE* data, DWORD length, const std::wstring& wsPassword) +{ + if (!m_pInternal->pReader) + return false; + return m_pInternal->pReader->AddFromMemory(data, length, wsPassword) && (m_pInternal->pReader->GetError() == 0); } int CPdfFile::GetRotate(int nPageIndex) { diff --git a/PdfFile/PdfFile.h b/PdfFile/PdfFile.h index f744409604..d053f92dd2 100644 --- a/PdfFile/PdfFile.h +++ b/PdfFile/PdfFile.h @@ -128,8 +128,10 @@ public: virtual std::wstring GetInfo(); virtual BYTE* GetStructure(); virtual BYTE* GetLinks(int nPageIndex); + + bool AddFromFile (const std::wstring& file, const std::wstring& wsPassword = L""); + bool AddFromMemory(BYTE* data, DWORD length, const std::wstring& wsPassword = L""); bool ValidMetaData(); - bool AddPdf(BYTE* data, DWORD length, const std::wstring& wsPassword = L""); int GetRotate(int nPageIndex); int GetMaxRefID(); BYTE* GetWidgets(); diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 6c9b3c16cf..13ad1a47da 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -378,10 +378,33 @@ bool CPdfReader::LoadFromFile(NSFonts::IApplicationFonts* pAppFonts, const std:: SetTempDirectory(NSDirectory::GetTempPath()); m_eError = errNone; - GString* owner_pswd = NSStrings::CreateString(wsOwnerPassword); - GString* user_pswd = NSStrings::CreateString(wsUserPassword); + NSFile::CFileBinary oFile; + if (oFile.OpenFile(wsSrcPath)) + { + m_nFileLength = oFile.GetFileSize(); + oFile.CloseFile(); + } + return AddFromFile(wsSrcPath, wsOwnerPassword); +} +bool CPdfReader::LoadFromMemory(NSFonts::IApplicationFonts* pAppFonts, BYTE* data, DWORD length, const std::wstring& wsOwnerPassword, const std::wstring& wsUserPassword) +{ + Clear(); + RELEASEINTERFACE(m_pFontManager); + m_pFontManager = InitFontManager(pAppFonts); + + m_eError = errNone; + m_nFileLength = length; + + return AddFromMemory(data, length, wsOwnerPassword); +} +bool CPdfReader::AddFromFile(const std::wstring& wsFile, const std::wstring& wsPassword) +{ + if (m_eError) + return false; + GString* owner_pswd = NSStrings::CreateString(wsPassword); + GString* user_pswd = NSStrings::CreateString(wsPassword); // конвертим путь в utf8 - под виндой они сконвертят в юникод, а на остальных - так и надо - std::string sPathUtf8 = U_TO_UTF8(wsSrcPath); + std::string sPathUtf8 = U_TO_UTF8(wsFile); CPdfReaderContext* pContext = new CPdfReaderContext(); pContext->m_pDocument = new PDFDoc((char*)sPathUtf8.c_str(), owner_pswd, user_pswd); @@ -392,17 +415,11 @@ bool CPdfReader::LoadFromFile(NSFonts::IApplicationFonts* pAppFonts, const std:: delete owner_pswd; delete user_pswd; - NSFile::CFileBinary oFile; - if (oFile.OpenFile(wsSrcPath)) - { - m_nFileLength = oFile.GetFileSize(); - oFile.CloseFile(); - } - m_eError = pDoc ? pDoc->getErrorCode() : errMemory; if (!pDoc || !pDoc->isOk()) { - Clear(); + delete pContext; + m_vPDFContext.pop_back(); return false; } @@ -411,20 +428,17 @@ bool CPdfReader::LoadFromFile(NSFonts::IApplicationFonts* pAppFonts, const std:: return true; } -bool CPdfReader::LoadFromMemory(NSFonts::IApplicationFonts* pAppFonts, BYTE* data, DWORD length, const std::wstring& wsOwnerPassword, const std::wstring& wsUserPassword) +bool CPdfReader::AddFromMemory(BYTE* pData, DWORD nLength, const std::wstring& wsPassword) { - Clear(); - RELEASEINTERFACE(m_pFontManager); - m_pFontManager = InitFontManager(pAppFonts); - - m_eError = errNone; - GString* owner_pswd = NSStrings::CreateString(wsOwnerPassword); - GString* user_pswd = NSStrings::CreateString(wsUserPassword); + 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*)data, 0, length, &obj); + 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(); @@ -434,12 +448,11 @@ bool CPdfReader::LoadFromMemory(NSFonts::IApplicationFonts* pAppFonts, BYTE* dat delete owner_pswd; delete user_pswd; - m_nFileLength = length; - m_eError = pDoc ? pDoc->getErrorCode() : errMemory; if (!pDoc || !pDoc->isOk()) { - Clear(); + delete pContext; + m_vPDFContext.pop_back(); return false; } @@ -448,14 +461,6 @@ bool CPdfReader::LoadFromMemory(NSFonts::IApplicationFonts* pAppFonts, BYTE* dat return true; } -bool CPdfReader::AddFromFile(const std::wstring& wsFile, const std::wstring& wsPassword) -{ - return true; -} -bool CPdfReader::AddFromMemory(BYTE* pData, DWORD nLength, const std::wstring& wsPassword) -{ - return true; -} void CPdfReader::Close() { Clear(); @@ -1073,6 +1078,7 @@ BYTE* CPdfReader::GetWidgets() NSWasm::CData oRes; oRes.SkipLen(); + int nStartPage = 0; for (CPdfReaderContext* pPDFContext : m_vPDFContext) { PDFDoc* pDoc = pPDFContext->m_pDocument; @@ -1081,10 +1087,11 @@ BYTE* CPdfReader::GetWidgets() if (!pDoc->getCatalog()->getForm() || !pDoc->getXRef()) continue; - PdfReader::CAnnots* pAnnots = new PdfReader::CAnnots(pDoc, m_pFontManager, pPDFContext->m_pFontList); + PdfReader::CAnnots* pAnnots = new PdfReader::CAnnots(pDoc, m_pFontManager, pPDFContext->m_pFontList, nStartPage); if (pAnnots) pAnnots->ToWASM(oRes); RELEASEOBJECT(pAnnots); + nStartPage += pDoc->getNumPages(); } oRes.WriteLen(); diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 9be0d2d2af..9673fa7482 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -2478,7 +2478,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) { Object oObj1, oObj2; XRef* xref = pdfDoc->getXRef(); @@ -2562,6 +2562,7 @@ 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()); m_arrAnnots.push_back(pAnnot); } } diff --git a/PdfFile/SrcReader/PdfAnnot.h b/PdfFile/SrcReader/PdfAnnot.h index 4c913515a2..ae2e0409cb 100644 --- a/PdfFile/SrcReader/PdfAnnot.h +++ b/PdfFile/SrcReader/PdfAnnot.h @@ -591,7 +591,7 @@ private: class CAnnots { public: - CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList); + CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, int nStartPage); ~CAnnots(); void ToWASM(NSWasm::CData& oRes); diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index 44fed8e90f..9047a40d09 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -1812,12 +1812,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++) { @@ -2307,10 +2308,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 +2316,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 +2414,6 @@ namespace PdfReader double dShiftX = 0, dShiftY = 0; DoTransform(arrMatrix, &dShiftX, &dShiftY, true); - // Здесь мы посылаем координаты текста в пунктах - double dPageHeight = pGState->getPageHeight(); - std::wstring wsUnicodeText; bool isCIDFont = pFont->isCIDFont(); From 9ed356c103ed3cdb07d3ee43941435af80f17a41 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 28 Feb 2025 14:38:04 +0600 Subject: [PATCH 051/186] fix empty cells conversion --- OOXML/Binary/Sheets/Reader/BinaryWriter.cpp | 41 +++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp index 4002f93950..7fbdad0424 100644 --- a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp +++ b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp @@ -5659,6 +5659,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--; + } + } } } } @@ -5720,6 +5735,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) { @@ -5730,6 +5752,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) From 3d58a8565a5dd86671443a39651aa629286553ea Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 28 Feb 2025 16:54:38 +0600 Subject: [PATCH 052/186] Fix definded names conversion --- OOXML/Binary/Sheets/Writer/BinaryReader.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index 5243842850..9ff4b874fa 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp @@ -3075,6 +3075,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) { From 6e6ffbf6045180da80232515add1f5679e36e41e Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 28 Feb 2025 14:03:47 +0300 Subject: [PATCH 053/186] Create AddPDF --- .../graphics/pro/js/drawingfile.json | 1 + .../graphics/pro/js/wasm/js/drawingfile.js | 17 ++++++--- .../pro/js/wasm/js/drawingfile_native.js | 5 +++ .../pro/js/wasm/js/drawingfile_wasm.js | 37 +++++++++++++++++-- .../graphics/pro/js/wasm/src/drawingfile.cpp | 2 +- 5 files changed, 51 insertions(+), 11 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/drawingfile.json b/DesktopEditor/graphics/pro/js/drawingfile.json index 681f8f2b6b..6387d17721 100644 --- a/DesktopEditor/graphics/pro/js/drawingfile.json +++ b/DesktopEditor/graphics/pro/js/drawingfile.json @@ -29,6 +29,7 @@ "_GetType", "_Open", "_Close", + "_AddPDF", "_GetErrorCode", "_GetInfo", "_GetPixmap", diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js index 3a987b728c..2fa7f1e886 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,17 +128,17 @@ 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() @@ -146,6 +146,11 @@ CFile.prototype["isNeedPassword"] = function() return this._isNeedPassword; }; +CFile.prototype["addPDF"] = function() +{ + return this._addPDF(); +}; + // INFO DOCUMENT CFile.prototype.getInfo = function() { 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..2f2ad25b33 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,34 @@ CFile.prototype._getError = function() return Module["_GetErrorCode"](this.nativeFile); }; +CFile.prototype._addPDF = function(buffer, password) +{ + if (!buffer) + return false; + + let data = new Uint8Array(buffer); + let stream = Module["_malloc"](data.length); + Module["HEAP8"].set(data, stream); + + let passwordPtr = 0; + if (password) + { + let passwordBuf = password.toUtf8(); + passwordPtr = Module["_malloc"](passwordBuf.length); + Module["HEAP8"].set(passwordBuf, passwordPtr); + } + + let bRes = Module["_addPDF"](this.nativeFile, stream, data.length, passwordPtr); + if (bRes == 1) + this.stream.push(stream); + else + this._free(stream); + + if (passwordPtr) + Module["_free"](passwordPtr); + return bRes == 1; +}; + // FONTS CFile.prototype._isNeedCMap = function() { diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp index 9fed48121b..7285e29a52 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp @@ -107,7 +107,7 @@ WASM_EXPORT int AddPDF(CDrawingFile* pFile, BYTE* data, LONG size, const char* p std::wstring sPassword = L""; if (NULL != password) sPassword = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)password, strlen(password)); - return pFile->AddFile(data, size, sPassword); + return pFile->AddFile(data, size, sPassword) ? 1 : 0; } WASM_EXPORT int GetErrorCode(CDrawingFile* pFile) { From 06a287dffe87b973eb278f17cc162a1e60918cb8 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 28 Feb 2025 17:42:29 +0600 Subject: [PATCH 054/186] fix shared strings fonts conversion --- OOXML/Binary/Sheets/Writer/BinaryReader.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index 9ff4b874fa..30cc7898a3 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp @@ -9316,6 +9316,7 @@ int BinaryFileReader::ReadFile(const std::wstring& sSrcFileName, std::wstring sD if(oXlsb.m_pSharedStrings) oXlsb.m_pSharedStrings->OOX::File::m_pMainDocument = &oXlsb; oXlsb.PrepareToWrite(); + oXlsb.PrepareRichStr(); oXlsb.WriteBin(sDstPath, *oSaveParams.pContentTypes); bMacro = oSaveParams.bMacroEnabled; From 55cae3d38c6eddaa011a3648213c74a2708c80a5 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 3 Mar 2025 16:58:13 +0600 Subject: [PATCH 055/186] fix table formula conversion --- .../Logic/Biff_structures/SyntaxPtg.cpp | 20 +++++-------------- .../Worksheets/WorksheetChildOther.cpp | 2 +- 2 files changed, 6 insertions(+), 16 deletions(-) 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/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 7e431e7bb6..7414a19920 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -3630,7 +3630,7 @@ namespace OOX void CSheetProtection::toBin(XLS::StreamCacheWriterPtr& writer) { XLS::CFRecordPtr record; - unsigned char *flagBuf; + unsigned char *flagBuf = 0; if(m_oSpinCount.IsInit() || m_oHashValue.IsInit() || m_oSaltValue.IsInit()) { record = writer->getNextRecord(XLSB::rt_SheetProtectionIso); From 06cc67a925231a50a3da040fe4b80a00dfc04cd9 Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Mon, 3 Mar 2025 14:43:41 +0300 Subject: [PATCH 056/186] add pars and conversion sm in custom shape --- .../SMCustomShape2OOXML.pri | 15 + .../SMCustomShape2OOXML/smcustomshapepars.cpp | 528 ++++++++++++++++++ .../SMCustomShape2OOXML/smcustomshapepars.h | 153 +++++ 3 files changed, 696 insertions(+) create mode 100644 OdfFile/Reader/Converter/SMCustomShape2OOXML/SMCustomShape2OOXML.pri create mode 100644 OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.cpp create mode 100644 OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.h 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/smcustomshapepars.cpp b/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.cpp new file mode 100644 index 0000000000..effe74fcbb --- /dev/null +++ b/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.cpp @@ -0,0 +1,528 @@ +#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); + } + } + } + std::vector& SMCustomShapePars::GetVector() + { + return m_arVecElements; + } +//class CElemnt + CElement::CElement() + {} + 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); + return nullptr; + } + void CElement::SetBaseType(const TypeElement& enType) + { + m_enBaseType = enType; + } + TypeElement CElement::GetBaseType() + { + return m_enBaseType; + } +//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) + { + if(m_wsNumber[0] == L'?' && m_wsNumber[1] == L'f') + m_wsNumber.replace(0,2,L"gd"); + pXmlWriter->WriteString(m_wsNumber + L" "); + } +//CElementArithmeticOperations + CElementArithmeticOperations::CElementArithmeticOperations():m_enTypeSign(TypeElement::empty),m_pSecondSign(nullptr),m_pFirstValue(nullptr),m_pSecondValue(nullptr) + {} + CElementArithmeticOperations::CElementArithmeticOperations(const std::wstring& wsSign):m_enTypeSign(TypeElement::empty),m_pSecondSign(nullptr),m_pFirstValue(nullptr),m_pSecondValue(nullptr) + { + 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; + 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); + } + } + void CElementArithmeticOperations::ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter) + { + 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_pFirstValue); + pXmlWriter->WriteNodeBegin(L"a:gd",true); + pXmlWriter->WriteAttribute(L"name",L"Text"); + pXmlWriter->WriteString(L" fmla=\""); + SignRecording(pXmlWriter,m_enTypeSign); + SignRecording(pXmlWriter,pTemp->GetTypeSign()); + pXmlWriter->WriteString(L" "); + if(!wsNameFirstValue.empty()) + pXmlWriter->WriteString(wsNameFirstValue + L" "); + else if(m_pFirstValue != nullptr) + m_pFirstValue->ConversionOOXml(pXmlWriter); + if(!wsNameSecondValue.empty()) + pXmlWriter->WriteString(wsNameSecondValue + L" "); + else if(m_pSecondValue != nullptr) + m_pSecondValue->ConversionOOXml(pXmlWriter); + if(!wsNameValueSecondSign.empty()) + pXmlWriter->WriteString(wsNameValueSecondSign + L" "); + else if(pTemp->GetSecondValue() != nullptr) + pTemp->GetSecondValue()->ConversionOOXml(pXmlWriter); + 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); + pXmlWriter->WriteAttribute(L"name",L"Text"); + pXmlWriter->WriteString(L" fmla=\""); + // SignRecording(pXmlWriter,m_enTypeSign); + 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) + { + if(!wsNameFirstValue.empty()) + pXmlWriter->WriteString(wsNameFirstValue + L" "); + else if(m_pFirstValue != nullptr) + m_pFirstValue->ConversionOOXml(pXmlWriter); + if(!wsNameSecondValue.empty()) + pXmlWriter->WriteString(wsNameSecondValue + L" "); + else if(m_pSecondValue != nullptr) + m_pSecondValue->ConversionOOXml(pXmlWriter); + pXmlWriter->WriteString(L"1 "); + } + else if(bMinusDivision) + { + pXmlWriter->WriteString(L"0 "); + if(!wsNameFirstValue.empty()) + pXmlWriter->WriteString(wsNameFirstValue + L" "); + else if(m_pFirstValue != nullptr) + m_pFirstValue->ConversionOOXml(pXmlWriter); + if(!wsNameSecondValue.empty()) + pXmlWriter->WriteString(wsNameSecondValue + L" "); + else if(m_pSecondValue != nullptr) + m_pSecondValue->ConversionOOXml(pXmlWriter); + } + 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) + { + pElement->ConversionOOXml(pXmlWriter); + std::wstring wsName = L"Good"; + return wsName; + } + else + return L""; + } +//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()) + { + // std::wcout << wsOneElement << std::endl; + return wsOneElement; + } + else + continue; + } + else if(!wsOneElement.empty() && (L'+' == *itStart || L'-' == *itStart || L'*' == *itStart || L'/' == *itStart || L',' == *itStart || L'(' == *itStart || L')' == *itStart)) + { + // std::wcout << wsOneElement << std::endl; + 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++; + // std::wcout << wsOneElement << std::endl; + return wsOneElement; + } + else + wsOneElement.push_back(*itStart); + } + if(!wsOneElement.empty()) + { + // std::wcout << wsOneElement << std::endl; + return wsOneElement; + } + else + return L""; + } + CElement *CSMReader::ReadingElement() + { + std::wstring wsElement = GetElement(m_itStart,m_itEnd); + return CElement::CreateElement(wsElement); + } + bool CSMReader::ReadingNextElement() + { + 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; + for(;m_itStart !=m_itEnd;m_itStart++) + { + if(*m_itStart == L')') + { + m_itEndForBrecket = m_itEnd; + m_itEnd = m_itStart; + m_itStart = itStartTemp; + return; + } + } + } + void CSMReader::RemovingTheParenthesisIterator() + { + if(m_itEndForBrecket != m_itEnd) + m_itEnd = m_itEndForBrecket; + } + 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) + {} +//CElementFunction + CElementFunction::CElementFunction():m_enTypeFunction(TypeElement::empty),m_pValue(nullptr) + { + SetBaseType(TypeElement::Function); + } + CElementFunction::CElementFunction(const TypeElement& enType):m_pValue(nullptr) + { + SetBaseType(TypeElement::Function); + m_enTypeFunction = enType; + } + CElementFunction::~CElementFunction() + {} + TypeElement CElementFunction::TypeCheckingByFunction(const std::wstring& wsFunction) + { + if(wsFunction == L"sqrt") + return TypeElement::sqrt; + else + return TypeElement::empty; + } + void CElementFunction::Parse(CSMReader* pReader) + { + m_pValue = SMCustomShapePars::ParseElement(pReader); + } + void CElementFunction::ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter) + {} +//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) + {} +//SMCustomShapeConversion + SMCustomShapeConversion::SMCustomShapeConversion() + {}; + SMCustomShapeConversion::~SMCustomShapeConversion() + { + delete m_pXmlWriter; + } + void SMCustomShapeConversion::StartConversion(std::vector& arElements) + { + 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); + m_pXmlWriter->WriteAttribute(L"name",L"Text"); + m_pXmlWriter->WriteString(L" fmla=\"val "); + arElements[0]->ConversionOOXml(m_pXmlWriter); + m_pXmlWriter->WriteString(L"\""); + } + else + { + for(CElement* pElement:arElements) + { + if(pElement != nullptr) + pElement->ConversionOOXml(m_pXmlWriter); + } + } + + } + std::wstring SMCustomShapeConversion::GetStringXml() + { + return m_pXmlWriter->GetXmlString(); + } +} diff --git a/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.h b/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.h new file mode 100644 index 0000000000..e608bc5f2b --- /dev/null +++ b/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.h @@ -0,0 +1,153 @@ +#ifndef SMCUSTOMSHAPEPARS_H +#define SMCUSTOMSHAPEPARS_H +#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, + 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::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); + std::wstring GetStringXml(); + private: + XmlUtils::CXmlWriter* m_pXmlWriter; + }; + class CElement + { + public: + CElement(); + virtual ~CElement(); + virtual void Parse(CSMReader* pReader) = 0; + virtual void ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter) = 0; + static CElement* CreateElement(const std::wstring& wsElement); + void SetBaseType(const TypeElement& enType); + TypeElement GetBaseType(); + private: + TypeElement m_enBaseType; + }; + class CElementNumber:public CElement + { + public: + CElementNumber(); + CElementNumber(const std::wstring& wsName); + virtual ~CElementNumber(); + void Parse(CSMReader* pReader) override; + void ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter) override; + static bool CheckNumber(const std::wstring& wsNumber); + 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) 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); + private: + TypeElement m_enTypeSign; + CElement* m_pSecondSign; + CElement* m_pFirstValue; + CElement* m_pSecondValue; + }; + class CElementBracket: public CElement + { + public: + CElementBracket(); + virtual ~CElementBracket(); + void Parse(CSMReader* pReader) override; + void ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter) override; + 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) override; + static TypeElement TypeCheckingByFunction(const std::wstring& wsFunction); + private: + TypeElement m_enTypeFunction; + CElement* m_pValue; + }; + class CElementComma: public CElement + { + public: + CElementComma(); + virtual ~CElementComma(); + void Parse(CSMReader* pReader) override; + void ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter) override; + }; +} +#endif // SMCUSTOMSHAPEPARS_H From 0796745158aa66768e366add5046c23d1f0bb7d3 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 3 Mar 2025 19:14:08 +0300 Subject: [PATCH 057/186] Add PdfWriter to drawingfile --- .../graphics/pro/js/qt/nativegraphics.pro | 92 +++++++++++++++++-- .../graphics/pro/js/wasm/js/drawingfile.js | 4 +- .../pro/js/wasm/js/drawingfile_wasm.js | 10 +- DjVuFile/DjVuFileImplementation.cpp | 2 - PdfFile/PdfFile.cpp | 33 +------ PdfFile/PdfFile.h | 2 - XpsFile/XpsLib/StaticResources.cpp | 4 +- 7 files changed, 93 insertions(+), 54 deletions(-) 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 2fa7f1e886..1c15af66c5 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js @@ -146,9 +146,9 @@ CFile.prototype["isNeedPassword"] = function() return this._isNeedPassword; }; -CFile.prototype["addPDF"] = function() +CFile.prototype["addPDF"] = function(arrayBuffer, password) { - return this._addPDF(); + return this._addPDF(arrayBuffer, password); }; // INFO DOCUMENT diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_wasm.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_wasm.js index 2f2ad25b33..964f4164a4 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_wasm.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_wasm.js @@ -127,8 +127,8 @@ CFile.prototype._addPDF = function(buffer, password) return false; let data = new Uint8Array(buffer); - let stream = Module["_malloc"](data.length); - Module["HEAP8"].set(data, stream); + let stream2 = Module["_malloc"](data.length); + Module["HEAP8"].set(data, stream2); let passwordPtr = 0; if (password) @@ -138,11 +138,11 @@ CFile.prototype._addPDF = function(buffer, password) Module["HEAP8"].set(passwordBuf, passwordPtr); } - let bRes = Module["_addPDF"](this.nativeFile, stream, data.length, passwordPtr); + let bRes = Module["_AddPDF"](this.nativeFile, stream2, data.length, passwordPtr); if (bRes == 1) - this.stream.push(stream); + this.stream.push(stream2); else - this._free(stream); + Module["_free"](stream2); if (passwordPtr) Module["_free"](passwordPtr); 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/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 4922f33b2e..1c677dda59 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -38,33 +38,9 @@ #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 SplitPage(int nPageIndex) { 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 { @@ -130,7 +106,6 @@ void CPdfFile::RotatePage(int nRotate) // Применение поворота страницы для writer m_pInternal->pWriter->PageRotate(nRotate); } -#ifndef BUILDING_WASM_MODULE bool CPdfFile::EditPdf(const std::wstring& wsDstFile) { if (wsDstFile.empty() || !m_pInternal->pReader) @@ -174,6 +149,7 @@ bool CPdfFile::MergePages(const std::wstring& wsPath, const std::wstring& wsPass if (m_pInternal->pReader->AddFromFile(wsPath, wsPassword)) return m_pInternal->pEditor->MergePages(m_pInternal->pReader->GetLastPDFDocument(), arrPageIndex, unLength); + return false; } bool CPdfFile::MovePage(int nPageIndex, int nPos) { @@ -187,7 +163,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 // ------------------------------------------------------------------------ @@ -526,26 +501,20 @@ void CPdfFile::AddMetaData(const std::wstring& sMetaName, BYTE* pMetaData, DWORD } 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) diff --git a/PdfFile/PdfFile.h b/PdfFile/PdfFile.h index d053f92dd2..2f720a03df 100644 --- a/PdfFile/PdfFile.h +++ b/PdfFile/PdfFile.h @@ -90,7 +90,6 @@ public: virtual void Close(); // --- EDIT --- -#ifndef BUILDING_WASM_MODULE // Переходит в режим редактирования. Pdf уже должен быть открыт на чтение - LoadFromFile/LoadFromMemory bool EditPdf(const std::wstring& wsDstFile = L""); // Манипуляции со страницами возможны в режиме редактирования @@ -101,7 +100,6 @@ public: bool SplitPages(const int* arrPageIndex, unsigned int unLength); bool MergePages(const std::wstring& wsPath, const std::wstring& wsPassword = L"", const int* arrPageIndex = NULL, unsigned int unLength = 0); HRESULT ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword = L""); -#endif // --- READER --- 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)); From 7a1c1be59975a801120d0ca4139b7d99b187df2a Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 4 Mar 2025 15:37:49 +0600 Subject: [PATCH 058/186] remove unused function --- .../XlsFile/Format/Auxiliary/HelpFunc.cpp | 15 --------------- MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h | 1 - 2 files changed, 16 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp index a9c0f88e04..92ce470349 100644 --- a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp +++ b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.cpp @@ -780,20 +780,5 @@ bool isColumn(const std::wstring& columnName, _UINT32 listIndex, _UINT16& indexC } return false; } -unsigned int getColumnsCount(_UINT32 listIndex) -{ - auto arrColumn = XLS::GlobalWorkbookInfo::mapTableColumnNames_static.find(listIndex); - if(arrColumn != XLS::GlobalWorkbookInfo::mapTableColumnNames_static.end()) - { - auto counter = 0; - for(auto i:arrColumn->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..457f0d88d5 100644 --- a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h +++ b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h @@ -95,7 +95,6 @@ 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); } From a3878b3770f6477bdd49409657843047d6ac9456 Mon Sep 17 00:00:00 2001 From: Prokhorov Kirill Date: Tue, 4 Mar 2025 16:34:29 +0300 Subject: [PATCH 059/186] Fix bug 72950 --- DesktopEditor/agg-2.4/include/agg_pixfmt_rgba.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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, From a7551f69eb88660c36ff86cf7fde57cbc7c143a0 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 4 Mar 2025 21:22:36 +0600 Subject: [PATCH 060/186] Fix formula with blank value conversion --- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index da576eabbb..fd897b5396 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -2924,7 +2924,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 +2934,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 From 462556599ffb0697dbcda1f44e66c20316287c45 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 4 Mar 2025 18:49:04 +0300 Subject: [PATCH 061/186] Build drawingfile --- DesktopEditor/graphics/pro/js/drawingfile.json | 16 ++++++++++++++-- PdfFile/PdfWriter.cpp | 6 ++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/drawingfile.json b/DesktopEditor/graphics/pro/js/drawingfile.json index 6387d17721..e7e7f9f94b 100644 --- a/DesktopEditor/graphics/pro/js/drawingfile.json +++ b/DesktopEditor/graphics/pro/js/drawingfile.json @@ -136,7 +136,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/", @@ -180,7 +180,19 @@ }, { "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"] + }, + { + "folder": "../../../../PdfFile/SrcReader/", + "files": ["Adaptors.cpp", "GfxClip.cpp", "RendererOutputDev.cpp", "JPXStream2.cpp", "PdfAnnot.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", "PdfFile.cpp", "PdfReader.cpp"] }, { "folder": "../../../raster/Jp2/openjpeg/openjpeg-2.4.0/src/lib/openjp2/", diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 3b5edb470f..32e002cd23 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 @@ -3675,7 +3677,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); @@ -3685,7 +3687,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) From ba9d3bcda5786f7c6b20c581900059d3ee20fc55 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 4 Mar 2025 19:46:43 +0300 Subject: [PATCH 062/186] Fix pdf properties exists --- PdfFile/PdfEditor.cpp | 5 +---- PdfFile/test/test.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 055d309137..ed34386b31 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -963,10 +963,7 @@ bool CPdfEditor::EditPage(int nPageIndex, bool bSet, bool bActualPos) { Object oRes; char* chKey2 = oTemp.dictGetKey(nIndex); - if (strcmp("Font", chKey2) == 0 || strcmp("ExtGState", chKey2) == 0 || strcmp("XObject", chKey2) == 0 || strcmp("Shading", chKey2) == 0 || strcmp("Pattern", chKey2) == 0) - oTemp.dictGetVal(nIndex, &oRes); - else - oTemp.dictGetValNF(nIndex, &oRes); + oTemp.dictGetVal(nIndex, &oRes); DictToCDictObject(&oRes, pDict, false, chKey2); oRes.free(); } diff --git a/PdfFile/test/test.cpp b/PdfFile/test/test.cpp index 49e36f3bc8..8dbdcec31a 100644 --- a/PdfFile/test/test.cpp +++ b/PdfFile/test/test.cpp @@ -372,7 +372,7 @@ TEST_F(CPdfFileTest, EditPdf) TEST_F(CPdfFileTest, EditPdfFromBase64) { - //GTEST_SKIP(); + GTEST_SKIP(); NSFonts::NSApplicationFontStream::SetGlobalMemoryStorage(NSFonts::NSApplicationFontStream::CreateDefaultGlobalMemoryStorage()); @@ -417,14 +417,14 @@ TEST_F(CPdfFileTest, EditPdfFromBase64) TEST_F(CPdfFileTest, EditPdfFromBin) { - GTEST_SKIP(); + // GTEST_SKIP(); LoadFromFile(); ASSERT_TRUE(pdfFile->EditPdf(wsDstFile)); // чтение бинарника 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 +440,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); From 4957b610338bd469cbe7569fa5807991f8d276d4 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 5 Mar 2025 13:31:38 +0300 Subject: [PATCH 063/186] SplitPages in PdfReader --- DesktopEditor/doctrenderer/drawingfile.h | 26 ++-- .../graphics/pro/js/wasm/src/drawingfile.cpp | 17 +-- .../pro/js/wasm/src/drawingfile_test.cpp | 17 ++- PdfFile/OnlineOfficeBinToPdf.cpp | 15 +- PdfFile/PdfEditor.cpp | 26 ++-- PdfFile/PdfEditor.h | 10 +- PdfFile/PdfFile.cpp | 30 ++-- PdfFile/PdfFile.h | 5 +- PdfFile/PdfReader.cpp | 133 +++++++++--------- PdfFile/PdfReader.h | 4 +- 10 files changed, 143 insertions(+), 140 deletions(-) diff --git a/DesktopEditor/doctrenderer/drawingfile.h b/DesktopEditor/doctrenderer/drawingfile.h index 921ec48e08..b8f08d28ca 100644 --- a/DesktopEditor/doctrenderer/drawingfile.h +++ b/DesktopEditor/doctrenderer/drawingfile.h @@ -221,20 +221,6 @@ public: return m_pFile ? true : false; } - bool AddFile(const std::wstring& sFile, const std::wstring& sPassword) - { - if (0 != m_nType) - return false; - - return ((CPdfFile*)m_pFile)->AddFromFile(sFile, sPassword); - } - bool AddFile(BYTE* data, LONG size, const std::wstring& sPassword) - { - if (0 != m_nType) - return false; - - return ((CPdfFile*)m_pFile)->AddFromMemory(data, size, sPassword); - } void CloseFile() { @@ -297,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) + { + if (m_nType == 0) + return ((CPdfFile*)m_pFile)->MergePages(data, size); + return false; + } BYTE* GetGlyphs(int nPageIndex) { diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp index 7285e29a52..b28b296052 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp @@ -102,13 +102,6 @@ WASM_EXPORT CDrawingFile* Open(BYTE* data, LONG size, const char* password) pFile->OpenFile(data, size, sPassword); return pFile; } -WASM_EXPORT int AddPDF(CDrawingFile* pFile, BYTE* data, LONG size, const char* password) -{ - std::wstring sPassword = L""; - if (NULL != password) - sPassword = NSFile::CUtf8Converter::GetUnicodeStringFromUTF8((BYTE*)password, strlen(password)); - return pFile->AddFile(data, size, sPassword) ? 1 : 0; -} WASM_EXPORT int GetErrorCode(CDrawingFile* pFile) { if (!pFile) @@ -132,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); } @@ -184,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) +{ + return pFile->MergePages(data, size) ? 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 8dd3bbebc9..6fa61fac9a 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp @@ -952,12 +952,18 @@ int main(int argc, char* argv[]) } } - // ADD PDF - if (AddPDF(pGrFile, pFileData, (LONG)nFileDataLen, "") == 0) + // SPLIT & MERGE + BYTE* pSplitPages = NULL; + if (true) { - Close(pGrFile); - RELEASEARRAYOBJECTS(pFileData); - return 1; + std::vector arrPages = { 0, 1 }; + pSplitPages = SplitPages(pGrFile, arrPages.data(), arrPages.size()); + if (pSplitPages) + { + int nLength = READ_INT(pSplitPages); + if (MergePages(pGrFile, pSplitPages + 4, nLength - 4) == 0) + RELEASEARRAYOBJECTS(pSplitPages); + } } // INFO @@ -1953,6 +1959,7 @@ int main(int argc, char* argv[]) Close(pGrFile); RELEASEARRAYOBJECTS(pFileData); + RELEASEARRAYOBJECTS(pSplitPages); RELEASEARRAYOBJECTS(pCMapData); return 0; diff --git a/PdfFile/OnlineOfficeBinToPdf.cpp b/PdfFile/OnlineOfficeBinToPdf.cpp index bdc3663490..64d603ef8c 100644 --- a/PdfFile/OnlineOfficeBinToPdf.cpp +++ b/PdfFile/OnlineOfficeBinToPdf.cpp @@ -146,13 +146,12 @@ namespace NSOnlineOfficeBinToPdf enum class AddCommandType { - EditPage = 0, // ранее Annotation + EditPage = 0, AddPage = 1, RemovePage = 2, WidgetInfo = 3, MovePage = 4, MergePages = 5, - SplitPages = 6, Undefined = 255 }; @@ -177,7 +176,7 @@ namespace NSOnlineOfficeBinToPdf int nLen = oReader.ReadInt(); AddCommandType CommandType = (AddCommandType)oReader.ReadByte(); int nPageNum = 0; - if (CommandType != AddCommandType::WidgetInfo && CommandType != AddCommandType::MergePages && CommandType != AddCommandType::SplitPages) + if (CommandType != AddCommandType::WidgetInfo && CommandType != AddCommandType::MergePages) nPageNum = oReader.ReadInt(); if (nPageNum < 0) @@ -224,16 +223,6 @@ namespace NSOnlineOfficeBinToPdf delete[] pPageIndex; break; } - case AddCommandType::SplitPages: - { - int nLength = oReader.ReadInt(); - int* pPageIndex = new int[nLength]; - for (int i = 0; i < nLength; ++i) - pPageIndex[i] = oReader.ReadInt(); - pPdf->SplitPages(pPageIndex, nLength); - delete[] pPageIndex; - break; - } case AddCommandType::WidgetInfo: { NSOnlineOfficeBinToPdf::ConvertBufferToRenderer(oReader.GetCurrentBuffer(), (LONG)(nLen - 5) , &oCorrector); diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index b6e7c9ff83..c07e3eb969 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -657,7 +657,7 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa m_pWriter = _pWriter; m_nEditPage = -1; m_nError = 0; - m_nMode = -1; + m_nMode = Mode::Unknown; PDFDoc* pPDFDocument = m_pReader->GetFirstPDFDocument(); if (!pPDFDocument) @@ -676,10 +676,10 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa } bool CPdfEditor::IncrementalUpdates() { - if (m_nMode == 0) + if (m_nMode == Mode::Unknown) return true; - m_nMode = 0; + m_nMode = Mode::WriteAppend; PDFDoc* pPDFDocument = m_pReader->GetFirstPDFDocument(); XRef* xref = pPDFDocument->getXRef(); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); @@ -904,7 +904,7 @@ void CPdfEditor::Close() if (m_wsDstFile.empty()) return; - if (m_nMode == 1) + if (m_nMode == Mode::WriteAppend) { m_pWriter->SaveToFile(m_wsDstFile); return; @@ -1096,7 +1096,7 @@ void CPdfEditor::GetPageTree(XRef* xref, Object* pPagesRefObj, PdfWriter::CPageT } bool CPdfEditor::EditPage(int _nPageIndex, bool bSet) { - if (m_nMode != 0 && !IncrementalUpdates()) + if (m_nMode != Mode::WriteAppend && !IncrementalUpdates()) return false; PDFDoc* pPDFDocument = NULL; @@ -1263,10 +1263,10 @@ bool CPdfEditor::EditPage(int _nPageIndex, bool bSet) } bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFDoc* _pDoc) { - if (m_nMode == 1 || (m_nMode == 0 && !_pDoc)) + if (m_nMode == Mode::WriteNew || (m_nMode == Mode::WriteAppend && !_pDoc)) return false; - if (m_nMode < 0) - m_nMode = 1; + if (m_nMode == Mode::Unknown) + m_nMode = Mode::WriteNew; PDFDoc* pPDFDocument = _pDoc ? _pDoc : m_pReader->GetFirstPDFDocument(); XRef* xref = pPDFDocument->getXRef(); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); @@ -1372,7 +1372,7 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFD oTemp.free(); } pPage->Fix(); - if (m_nMode == 0) + if (m_nMode == Mode::WriteAppend) { // pPage->AddContents(); // TODO pPage->AddContents чтобы можно было дописать изменения, если понадобится } @@ -1583,20 +1583,20 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFD } bool CPdfEditor::MergePages(PDFDoc* pDoc, const int* arrPageIndex, unsigned int unLength) { - if (m_nMode != 0 && !IncrementalUpdates()) + if (m_nMode != Mode::WriteAppend && !IncrementalUpdates()) return false; return SplitPages(arrPageIndex, unLength, pDoc); } bool CPdfEditor::DeletePage(int nPageIndex) { - if (m_nMode != 0 && !IncrementalUpdates()) + if (m_nMode != Mode::WriteAppend && !IncrementalUpdates()) return false; return m_pWriter->GetDocument()->DeletePage(nPageIndex); } bool CPdfEditor::AddPage(int nPageIndex) { - if (m_nMode != 0 && !IncrementalUpdates()) + if (m_nMode != Mode::WriteAppend && !IncrementalUpdates()) return false; // Применение добавления страницы для writer @@ -1945,7 +1945,7 @@ bool CPdfEditor::DeleteAnnot(int nID, Object* oAnnots) } bool CPdfEditor::EditWidgets(IAdvancedCommand* pCommand) { - if (m_nMode != 0 && !IncrementalUpdates()) + if (m_nMode != Mode::WriteAppend && !IncrementalUpdates()) return false; CWidgetsInfo* pFieldInfo = (CWidgetsInfo*)pCommand; diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h index bee40bc7c3..39c98294d6 100644 --- a/PdfFile/PdfEditor.h +++ b/PdfFile/PdfEditor.h @@ -40,6 +40,14 @@ HRESULT _ChangePassword(const std::wstring& wsPath, const std::wstring& wsPasswo class CPdfEditor { public: + 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(); @@ -80,7 +88,7 @@ private: int m_nError; // 0 - Дозапись. pReader и pWriter работают с одним файлом // 1 - Split. pReader и pWriter работают с разными файлами - int m_nMode; + Mode m_nMode; int m_nEditPage; }; diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 1c677dda59..855dbac63a 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -136,18 +136,12 @@ bool CPdfFile::AddPage(int nPageIndex) return false; return m_pInternal->pEditor->AddPage(nPageIndex); } -bool CPdfFile::SplitPages(const int* arrPageIndex, unsigned int unLength) -{ - if (!m_pInternal->pEditor) - return false; - return m_pInternal->pEditor->SplitPages(arrPageIndex, unLength); -} bool CPdfFile::MergePages(const std::wstring& wsPath, const std::wstring& wsPassword, const int* arrPageIndex, unsigned int unLength) { if (!m_pInternal->pEditor) return false; - if (m_pInternal->pReader->AddFromFile(wsPath, wsPassword)) + if (m_pInternal->pReader->MergePages(wsPath, wsPassword)) return m_pInternal->pEditor->MergePages(m_pInternal->pReader->GetLastPDFDocument(), arrPageIndex, unLength); return false; } @@ -349,17 +343,11 @@ void CPdfFile::GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, do else m_pInternal->pReader->GetPageInfo(nPageIndex, pdWidth, pdHeight, pdDpiX, pdDpiY); } -bool CPdfFile::AddFromFile(const std::wstring& file, const std::wstring& wsPassword) +bool CPdfFile::MergePages(BYTE* data, DWORD length) { if (!m_pInternal->pReader) return false; - return m_pInternal->pReader->AddFromFile(file, wsPassword) && (m_pInternal->pReader->GetError() == 0); -} -bool CPdfFile::AddFromMemory(BYTE* data, DWORD length, const std::wstring& wsPassword) -{ - if (!m_pInternal->pReader) - return false; - return m_pInternal->pReader->AddFromMemory(data, length, wsPassword) && (m_pInternal->pReader->GetError() == 0); + return m_pInternal->pReader->MergePages(data, length) && (m_pInternal->pReader->GetError() == 0); } int CPdfFile::GetRotate(int nPageIndex) { @@ -443,6 +431,18 @@ 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 false; + 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); + + return m_pInternal->pReader->SplitPages(arrPageIndex, unLength); +} BYTE* CPdfFile::VerifySign(const std::wstring& sFile, ICertificate* pCertificate, int nWidget) { if (!m_pInternal->pReader) diff --git a/PdfFile/PdfFile.h b/PdfFile/PdfFile.h index 2f720a03df..8e2f3b2cca 100644 --- a/PdfFile/PdfFile.h +++ b/PdfFile/PdfFile.h @@ -97,7 +97,6 @@ public: bool DeletePage(int nPageIndex); bool AddPage (int nPageIndex); bool MovePage (int nPageIndex, int nPos); - bool SplitPages(const int* arrPageIndex, unsigned int unLength); bool MergePages(const std::wstring& wsPath, const std::wstring& wsPassword = L"", const int* arrPageIndex = NULL, unsigned int unLength = 0); HRESULT ChangePassword(const std::wstring& wsPath, const std::wstring& wsPassword = L""); @@ -127,8 +126,7 @@ public: virtual BYTE* GetStructure(); virtual BYTE* GetLinks(int nPageIndex); - bool AddFromFile (const std::wstring& file, const std::wstring& wsPassword = L""); - bool AddFromMemory(BYTE* data, DWORD length, const std::wstring& wsPassword = L""); + bool MergePages(BYTE* data, DWORD length); bool ValidMetaData(); int GetRotate(int nPageIndex); int GetMaxRefID(); @@ -136,6 +134,7 @@ public: 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 13ad1a47da..31bf2efe49 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -384,7 +384,7 @@ bool CPdfReader::LoadFromFile(NSFonts::IApplicationFonts* pAppFonts, const std:: m_nFileLength = oFile.GetFileSize(); oFile.CloseFile(); } - return AddFromFile(wsSrcPath, wsOwnerPassword); + return MergePages(wsSrcPath, wsOwnerPassword); } bool CPdfReader::LoadFromMemory(NSFonts::IApplicationFonts* pAppFonts, BYTE* data, DWORD length, const std::wstring& wsOwnerPassword, const std::wstring& wsUserPassword) { @@ -395,71 +395,7 @@ bool CPdfReader::LoadFromMemory(NSFonts::IApplicationFonts* pAppFonts, BYTE* dat m_eError = errNone; m_nFileLength = length; - return AddFromMemory(data, length, wsOwnerPassword); -} -bool CPdfReader::AddFromFile(const std::wstring& wsFile, const std::wstring& wsPassword) -{ - 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(); - 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::AddFromMemory(BYTE* pData, DWORD nLength, const std::wstring& wsPassword) -{ - 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(); - 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; + return MergePages(data, length, wsOwnerPassword); } void CPdfReader::Close() { @@ -601,6 +537,71 @@ bool CPdfReader::ValidMetaData() oID.free(); oID2.free(); return bRes; } +bool CPdfReader::MergePages(BYTE* pData, DWORD nLength, const std::wstring& wsPassword) +{ + 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, NULL, NULL); + pContext->m_pFontList = new PdfReader::CPdfFontList(); + 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) +{ + 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(); + 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) { PDFDoc* pDoc = NULL; diff --git a/PdfFile/PdfReader.h b/PdfFile/PdfReader.h index 66f79f2947..fec272fc72 100644 --- a/PdfFile/PdfReader.h +++ b/PdfFile/PdfReader.h @@ -59,8 +59,6 @@ public: bool LoadFromFile (NSFonts::IApplicationFonts* pAppFonts, const std::wstring& file, const std::wstring& owner_password = L"", const std::wstring& user_password = L""); bool LoadFromMemory(NSFonts::IApplicationFonts* pAppFonts, BYTE* data, DWORD length, const std::wstring& owner_password = L"", const std::wstring& user_password = L""); - bool AddFromFile (const std::wstring& wsFile, const std::wstring& wsPassword = L""); - bool AddFromMemory (BYTE* pData, DWORD nLength, const std::wstring& wsPassword = L""); void Close(); @@ -78,6 +76,8 @@ public: int GetMaxRefID(); int GetNumPages(); bool ValidMetaData(); + bool MergePages(BYTE* pData, DWORD nLength, const std::wstring& wsPassword = L""); + bool MergePages(const std::wstring& wsFile, const std::wstring& wsPassword = L""); void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY); void DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak); std::wstring GetInfo(); From 1830a1103ae1168ddde42559f4c1cb990ae7e3da Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 5 Mar 2025 15:40:12 +0300 Subject: [PATCH 064/186] Fix SplitPages --- PdfFile/PdfEditor.cpp | 46 +++++++++++++++++++++++++++++----- PdfFile/PdfEditor.h | 3 ++- PdfFile/PdfFile.cpp | 8 ++++-- PdfFile/PdfWriter.cpp | 13 ++++++++++ PdfFile/PdfWriter.h | 1 + PdfFile/SrcWriter/Document.cpp | 16 ++++++++++++ PdfFile/SrcWriter/Document.h | 1 + PdfFile/SrcWriter/Streams.cpp | 11 ++++++++ PdfFile/SrcWriter/Streams.h | 2 ++ 9 files changed, 92 insertions(+), 9 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index c07e3eb969..ba4b479c6f 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -1100,7 +1100,7 @@ bool CPdfEditor::EditPage(int _nPageIndex, bool bSet) return false; PDFDoc* pPDFDocument = NULL; - int nPageIndex = m_pReader->GetPageIndex(_nPageIndex - 1, &pPDFDocument); + int nPageIndex = m_pReader->GetPageIndex(_nPageIndex, &pPDFDocument); if (nPageIndex < 0 || !pPDFDocument) return NULL; @@ -1581,11 +1581,45 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFD return true; } -bool CPdfEditor::MergePages(PDFDoc* pDoc, const int* arrPageIndex, unsigned int unLength) +BYTE* CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength) +{ + if (m_nMode != Mode::Unknown) + return NULL; + m_nMode = Mode::WriteNew; + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); + if (!pDoc) + return NULL; + + for (unsigned int i = 0; i < unLength; ++i) + { + PDFDoc* pPDFDocument = NULL; + int nPageIndex = m_pReader->GetPageIndex(arrPageIndex[i], &pPDFDocument); + SplitPages(&nPageIndex, 1, pPDFDocument); + } + + BYTE* pRes = NULL; + int nLength = 0; + if (m_pWriter->SaveToMemory(&pRes, &nLength)) + { + 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; +} +bool CPdfEditor::MergePages(PDFDoc* pDocument, const int* arrPageIndex, unsigned int unLength) { if (m_nMode != Mode::WriteAppend && !IncrementalUpdates()) return false; - return SplitPages(arrPageIndex, unLength, pDoc); + return SplitPages(arrPageIndex, unLength, pDocument); } bool CPdfEditor::DeletePage(int nPageIndex) { @@ -1627,7 +1661,7 @@ bool CPdfEditor::EditAnnot(int _nPageIndex, int nID) { PDFDoc* pPDFDocument = NULL; PdfReader::CPdfFontList* pFontList = NULL; - int nPageIndex = m_pReader->GetPageIndex(_nPageIndex - 1, &pPDFDocument, &pFontList); + int nPageIndex = m_pReader->GetPageIndex(_nPageIndex, &pPDFDocument, &pFontList); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); if (nPageIndex < 0 || !pPDFDocument || !pDoc) return false; @@ -1881,7 +1915,7 @@ bool CPdfEditor::EditAnnot(int _nPageIndex, int nID) bool CPdfEditor::DeleteAnnot(int nID, Object* oAnnots) { PDFDoc* pPDFDocument = NULL; - int nPageIndex = m_pReader->GetPageIndex(m_nEditPage - 1, &pPDFDocument); + int nPageIndex = m_pReader->GetPageIndex(m_nEditPage, &pPDFDocument); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); if (nPageIndex < 0 || !pPDFDocument || !pDoc) return false; @@ -2007,7 +2041,7 @@ bool CPdfEditor::IsEditPage() void CPdfEditor::ClearPage() { PDFDoc* pPDFDocument = NULL; - int nPageIndex = m_pReader->GetPageIndex(m_nEditPage - 1, &pPDFDocument); + int nPageIndex = m_pReader->GetPageIndex(m_nEditPage, &pPDFDocument); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); if (nPageIndex < 0 || !pPDFDocument || !pDoc) return; diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h index 39c98294d6..66bf114465 100644 --- a/PdfFile/PdfEditor.h +++ b/PdfFile/PdfEditor.h @@ -70,7 +70,8 @@ public: void EndMarkedContent(); bool IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bItalic, std::wstring& wsFontPath); - bool SplitPages(const int* arrPageIndex, unsigned int unLength, PDFDoc* pDoc = NULL); + BYTE* SplitPages(const int* arrPageIndex, unsigned int unLength); + bool SplitPages(const int* arrPageIndex, unsigned int unLength, PDFDoc* _pDoc); bool MergePages(PDFDoc* pDoc, const int* arrPageIndex, unsigned int unLength); private: diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 855dbac63a..5ed2f52c69 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -434,14 +434,18 @@ BYTE* CPdfFile::GetAnnots(int nPageIndex) BYTE* CPdfFile::SplitPages(const int* arrPageIndex, unsigned int unLength) { if (!m_pInternal->pReader) - return false; + 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); - return m_pInternal->pReader->SplitPages(arrPageIndex, unLength); + 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) { diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 32e002cd23..3db57e3013 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -207,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()) diff --git a/PdfFile/PdfWriter.h b/PdfFile/PdfWriter.h index 297cc96434..445f7c63c1 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); diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 1c43a08202..632f3938f7 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -236,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); diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index e663425f7b..0fc429bf56 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -106,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); diff --git a/PdfFile/SrcWriter/Streams.cpp b/PdfFile/SrcWriter/Streams.cpp index e5a873b2b5..6a3ab108ff 100644 --- a/PdfFile/SrcWriter/Streams.cpp +++ b/PdfFile/SrcWriter/Streams.cpp @@ -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..18c585da32 100644 --- a/PdfFile/SrcWriter/Streams.h +++ b/PdfFile/SrcWriter/Streams.h @@ -158,6 +158,8 @@ namespace PdfWriter { return StreamMemory; } + BYTE* GetBuffer(); + void ClearWithoutAttack(); private: From e1c1ff3eb4327d03679356af8f46dec988425d43 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 5 Mar 2025 18:02:48 +0300 Subject: [PATCH 065/186] Fix pages from arrPageIndex --- PdfFile/PdfEditor.cpp | 21 ++++++++++++++++++--- PdfFile/PdfReader.cpp | 9 +++++++++ PdfFile/PdfReader.h | 1 + 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index ba4b479c6f..eea44f4013 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -1590,11 +1590,26 @@ BYTE* CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength) if (!pDoc) return NULL; + int nTotalPages = 0; + int nPDFIndex = 0; + std::map> mFileToPages; for (unsigned int i = 0; i < unLength; ++i) { - PDFDoc* pPDFDocument = NULL; - int nPageIndex = m_pReader->GetPageIndex(arrPageIndex[i], &pPDFDocument); - SplitPages(&nPageIndex, 1, pPDFDocument); + PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(nPDFIndex); + if (!pPDFDocument) + break; + int nPages = pPDFDocument->getNumPages(); + if (arrPageIndex[i] < nTotalPages + nPages) + mFileToPages[nPDFIndex].push_back(arrPageIndex[i] - nTotalPages + 1); + else + ++nPDFIndex; + } + + for (const std::pair>& it : mFileToPages) + { + PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(it.first); + if (!SplitPages(it.second.data(), it.second.size(), pPDFDocument)) + return NULL; } BYTE* pRes = NULL; diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 31bf2efe49..25daeefb0c 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -684,6 +684,15 @@ PDFDoc* CPdfReader::GetLastPDFDocument() return pPDFContext->m_pDocument; return NULL; } +PDFDoc* CPdfReader::GetPDFDocument(int PDFIndex) +{ + if (m_vPDFContext.empty()) + return NULL; + + if (PDFIndex >= 0 && PDFIndex < m_vPDFContext.size()) + return m_vPDFContext[PDFIndex]->m_pDocument; + return NULL; +} std::wstring CPdfReader::GetInfo() { diff --git a/PdfFile/PdfReader.h b/PdfFile/PdfReader.h index fec272fc72..1d3a1b86d7 100644 --- a/PdfFile/PdfReader.h +++ b/PdfFile/PdfReader.h @@ -88,6 +88,7 @@ public: NSFonts::IFontManager* GetFontManager() { return m_pFontManager; } PDFDoc* GetFirstPDFDocument(); PDFDoc* GetLastPDFDocument(); + PDFDoc* GetPDFDocument(int PDFIndex); int GetPageIndex(int nPageIndex, PDFDoc** pDoc = NULL, PdfReader::CPdfFontList** pFontList = NULL); BYTE* GetStructure(); From d2ea9521b5d5becba5ddfecb4f28834f7053082f Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Wed, 5 Mar 2025 18:59:59 +0300 Subject: [PATCH 066/186] Add support license --- .../doctrenderer/addon/docbuilder_addon.h | 5 +-- .../doctrenderer/app_builder/main.cpp | 36 +++++++++++++++++++ .../docbuilder.python/src/docbuilder.py | 6 ++++ DesktopEditor/doctrenderer/docbuilder_p.h | 4 +-- 4 files changed, 47 insertions(+), 4 deletions(-) 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..2b3a2ffe12 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,13 @@ void parse_args(NSDoctRenderer::CDocBuilder* builder, int argc, char *argv[]) } } +bool CheckLicense(const std::wstring& sSrc, const std::wstring& sDst) +{ + 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 +97,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 +130,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.python/src/docbuilder.py b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py index ac06615386..e7973c4cab 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py @@ -612,4 +612,10 @@ builder_path = os.path.dirname(os.path.realpath(__file__)) _loadLibrary(builder_path) CDocBuilder.Initialize(builder_path) +def registerLibrary(license_path): + docbuilder_bin = os.path.dirname(os.path.realpath(__file__)) + os.pathsep + "docbuilder" + if ("windows" == platform.system().lower()): + docbuilder_bin += ".exe" + return subprocess.call([docbuilder_bin, license_path], stderr=subprocess.STDOUT, shell=True) + atexit.register(CDocBuilder.Dispose) 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""); From e9852e812f7a1f30502c52e99eee6034ff813623 Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Wed, 5 Mar 2025 19:13:38 +0300 Subject: [PATCH 067/186] Turn on ligatures for arabic & syriac scripts --- DesktopEditor/fontengine/TextShaper.cpp | 7 +++++++ DesktopEditor/fontengine/js/cpp/text.cpp | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/DesktopEditor/fontengine/TextShaper.cpp b/DesktopEditor/fontengine/TextShaper.cpp index 4e509d5cc8..6efcb547ed 100644 --- a/DesktopEditor/fontengine/TextShaper.cpp +++ b/DesktopEditor/fontengine/TextShaper.cpp @@ -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/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) { From 6aa68f1c8141517c73495ad0134347cd7c92a4bb Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Thu, 6 Mar 2025 15:56:30 +0300 Subject: [PATCH 068/186] Add GetPropertyInt method --- DesktopEditor/doctrenderer/docbuilder.h | 7 +++++++ DesktopEditor/doctrenderer/docbuilder_p.cpp | 9 +++++++++ 2 files changed, 16 insertions(+) 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_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""; From 8791f446b7197b81c3c549ad98511bb4e9a94d11 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 6 Mar 2025 18:16:14 +0300 Subject: [PATCH 069/186] Add PdfWriter to build drawingfile --- .../graphics/pro/js/drawingfile.json | 14 +++++++++----- .../pro/js/wasm/src/drawingfile_test.cpp | 8 +++++++- PdfFile/PdfEditor.cpp | 19 +++++++++++-------- 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/drawingfile.json b/DesktopEditor/graphics/pro/js/drawingfile.json index e7e7f9f94b..17a4a13a6c 100644 --- a/DesktopEditor/graphics/pro/js/drawingfile.json +++ b/DesktopEditor/graphics/pro/js/drawingfile.json @@ -2,7 +2,7 @@ "name": "drawingfile", "res_folder": "./deploy", "wasm": true, - "asm": true, + "asm": false, "embed_mem_file": true, "run_before": "before.py", "run_after": "after.py", @@ -144,7 +144,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"] }, { "folder": "../../../fontengine/", @@ -156,7 +156,7 @@ }, { "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/", @@ -180,19 +180,23 @@ }, { "folder": "../../../../PdfFile/", - "files": ["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", "PdfFile.cpp", "PdfReader.cpp"] + "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/wasm/src/drawingfile_test.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp index 6fa61fac9a..a71df98d4e 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp @@ -961,6 +961,12 @@ int main(int argc, char* argv[]) if (pSplitPages) { int nLength = READ_INT(pSplitPages); + + NSFile::CFileBinary oFile; + if (oFile.CreateFileW(NSFile::GetProcessDirectory() + L"/test2.pdf")) + oFile.WriteFile(pSplitPages + 4, nLength - 4); + oFile.CloseFile(); + if (MergePages(pGrFile, pSplitPages + 4, nLength - 4) == 0) RELEASEARRAYOBJECTS(pSplitPages); } @@ -1104,7 +1110,7 @@ int main(int argc, char* argv[]) } // GLYPHS - if (true && nPagesCount > 0) + if (false && nPagesCount > 0) { BYTE* pGlyphs = GetGlyphs(pGrFile, nTestPage); nLength = READ_INT(pGlyphs); diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index eea44f4013..d92cc7e5ec 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -1585,7 +1585,6 @@ BYTE* CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength) { if (m_nMode != Mode::Unknown) return NULL; - m_nMode = Mode::WriteNew; PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); if (!pDoc) return NULL; @@ -1593,28 +1592,32 @@ BYTE* CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength) 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) { - PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(nPDFIndex); - if (!pPDFDocument) - break; - int nPages = pPDFDocument->getNumPages(); if (arrPageIndex[i] < nTotalPages + nPages) - mFileToPages[nPDFIndex].push_back(arrPageIndex[i] - nTotalPages + 1); + mFileToPages[nPDFIndex].push_back(arrPageIndex[i] - nTotalPages); else + { ++nPDFIndex; + pPDFDocument = m_pReader->GetPDFDocument(nPDFIndex); + if (!pPDFDocument) + break; + nPages = pPDFDocument->getNumPages(); + } } for (const std::pair>& it : mFileToPages) { - PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(it.first); + pPDFDocument = m_pReader->GetPDFDocument(it.first); if (!SplitPages(it.second.data(), it.second.size(), pPDFDocument)) return NULL; } BYTE* pRes = NULL; int nLength = 0; - if (m_pWriter->SaveToMemory(&pRes, &nLength)) + if (m_pWriter->SaveToMemory(&pRes, &nLength) == 0) { NSWasm::CData oRes; oRes.SkipLen(); From 43becd1cdb290621599de2b8c26335d95d40e1c3 Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Fri, 7 Mar 2025 11:03:20 +0300 Subject: [PATCH 070/186] Fix registerLibrary method --- .../doctrenderer/docbuilder.python/src/docbuilder.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py index e7973c4cab..a09d1f4afd 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,14 +609,14 @@ class FileTypes: PNG = _IMAGE_MASK + 0x0005 BMP = _IMAGE_MASK + 0x0008 -builder_path = os.path.dirname(os.path.realpath(__file__)) +builder_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'lib') _loadLibrary(builder_path) CDocBuilder.Initialize(builder_path) def registerLibrary(license_path): - docbuilder_bin = os.path.dirname(os.path.realpath(__file__)) + os.pathsep + "docbuilder" + docbuilder_bin = os.path.dirname(os.path.realpath(__file__)) + "/lib/docbuilder" if ("windows" == platform.system().lower()): docbuilder_bin += ".exe" - return subprocess.call([docbuilder_bin, license_path], stderr=subprocess.STDOUT, shell=True) + return subprocess.call([docbuilder_bin, "-register", license_path], stderr=subprocess.STDOUT, shell=True) atexit.register(CDocBuilder.Dispose) From 56179f70bf35d8b9ae238d297a87bd9d33a6a242 Mon Sep 17 00:00:00 2001 From: Elena Subbotina Date: Fri, 7 Mar 2025 14:34:34 +0300 Subject: [PATCH 071/186] add binary vsdx --- Common/OfficeFileFormatChecker.h | 1 + Common/OfficeFileFormatChecker2.cpp | 23 + Common/OfficeFileFormats.h | 2 + .../{Readers.cpp => BinaryReaderD.cpp} | 4 +- .../BinReader/{Readers.h => BinaryReaderD.h} | 0 .../{BinWriters.cpp => BinaryWriterD.cpp} | 4 +- .../{BinWriters.h => BinaryWriterD.h} | 0 .../Document/DocWrapper/DocxSerializer.cpp | 4 +- .../Document/DocWrapper/VsdxSerializer.cpp | 141 + .../Document/DocWrapper/VsdxSerializer.h | 78 + .../Document/DocWrapper/XlsxSerializer.cpp | 8 +- OOXML/Binary/Draw/BinReaderWriterDefines.h | 69 + OOXML/Binary/Draw/BinaryReaderV.cpp | 284 + OOXML/Binary/Draw/BinaryReaderV.h | 58 + OOXML/Binary/Draw/BinaryWriterV.cpp | 265 + OOXML/Binary/Draw/BinaryWriterV.h | 92 + .../Presentation/BinReaderWriterDefines.h | 1 + .../Presentation/BinaryFileReaderWriter.cpp | 16 +- .../Presentation/BinaryFileReaderWriter.h | 18 +- OOXML/Binary/Sheets/Reader/BinaryWriterS.cpp | 9112 ++++++++++++++++ .../{BinaryWriter.h => BinaryWriterS.h} | 0 .../Sheets/Reader/ChartFromToBinary.cpp | 4 +- OOXML/Binary/Sheets/Reader/CommonWriter.h | 4 +- OOXML/Binary/Sheets/Writer/BinaryReaderS.cpp | 9519 +++++++++++++++++ .../{BinaryReader.h => BinaryReaderS.h} | 0 OOXML/Common/SimpleTypes_Draw.cpp | 117 + OOXML/Common/SimpleTypes_Draw.h | 74 + OOXML/DocxFormat/Diagram/DiagramData.cpp | 2 + OOXML/DocxFormat/IFileContainer.cpp | 5 + OOXML/DocxFormat/IFileContainer.h | 4 +- OOXML/DocxFormat/Media/OleObject.cpp | 28 +- OOXML/DocxFormat/Media/OleObject.h | 11 +- OOXML/DocxFormat/WritingElement.h | 47 +- OOXML/PPTXFormat/Logic/Pic.cpp | 12 +- .../PPTXFormat/Logic/Runs/MathParaWrapper.cpp | 2 +- OOXML/PPTXFormat/Logic/SmartArt.cpp | 4 +- OOXML/PPTXFormat/Theme.h | 4 - .../Linux/BinDocument/BinDocument.pro | 29 +- .../Linux/DocxFormatLib/DocxFormatLib.pro | 24 +- .../Linux/DocxFormatLib/common_format.cpp | 1 + .../Linux/DocxFormatLib/docx_format_logic.cpp | 1 + .../Linux/DocxFormatLib/vsdx_format_logic.cpp | 39 + .../BinaryFormatLib/BinaryFormatLib.vcxproj | 23 +- .../BinaryFormatLib.vcxproj.filters | 64 +- .../DocxFormatLib/DocxFormatLib.vcxproj | 16 + .../DocxFormatLib.vcxproj.filters | 51 + OOXML/VsdxFormat/FileFactory_Draw.cpp | 133 + OOXML/VsdxFormat/FileFactory_Draw.h | 53 + OOXML/VsdxFormat/FileTypes_Draw.cpp | 95 + OOXML/VsdxFormat/FileTypes_Draw.h | 66 + OOXML/VsdxFormat/Shapes.cpp | 1604 +++ OOXML/VsdxFormat/Shapes.h | 473 + OOXML/VsdxFormat/VisioConnections.cpp | 1293 +++ OOXML/VsdxFormat/VisioConnections.h | 353 + OOXML/VsdxFormat/VisioDocument.cpp | 1802 ++++ OOXML/VsdxFormat/VisioDocument.h | 465 + OOXML/VsdxFormat/VisioPages.cpp | 1313 +++ OOXML/VsdxFormat/VisioPages.h | 267 + OOXML/VsdxFormat/Vsdx.cpp | 292 + OOXML/VsdxFormat/Vsdx.h | 118 + OOXML/XlsxFormat/FileFactory_Spreadsheet.cpp | 4 +- OOXML/XlsxFormat/FileFactory_Spreadsheet.h | 4 - .../NamedSheetViews/NamedSheetViews.cpp | 4 +- OdfFile/Writer/Converter/Converter.cpp | 2 +- X2tConverter/src/ASCConverters.cpp | 15 +- X2tConverter/src/ASCConverters.h | 9 + X2tConverter/src/cextracttools.cpp | 18 + X2tConverter/src/cextracttools.h | 5 + X2tConverter/src/lib/vsdx.h | 160 + X2tConverter/src/lib/xlsx.h | 1 - X2tConverter/test/win32Test/X2tTest.vcxproj | 1 + .../test/win32Test/X2tTest.vcxproj.filters | 3 + 72 files changed, 28711 insertions(+), 107 deletions(-) rename OOXML/Binary/Document/BinReader/{Readers.cpp => BinaryReaderD.cpp} (99%) rename OOXML/Binary/Document/BinReader/{Readers.h => BinaryReaderD.h} (100%) rename OOXML/Binary/Document/BinWriter/{BinWriters.cpp => BinaryWriterD.cpp} (99%) rename OOXML/Binary/Document/BinWriter/{BinWriters.h => BinaryWriterD.h} (100%) create mode 100644 OOXML/Binary/Document/DocWrapper/VsdxSerializer.cpp create mode 100644 OOXML/Binary/Document/DocWrapper/VsdxSerializer.h create mode 100644 OOXML/Binary/Draw/BinReaderWriterDefines.h create mode 100644 OOXML/Binary/Draw/BinaryReaderV.cpp create mode 100644 OOXML/Binary/Draw/BinaryReaderV.h create mode 100644 OOXML/Binary/Draw/BinaryWriterV.cpp create mode 100644 OOXML/Binary/Draw/BinaryWriterV.h create mode 100644 OOXML/Binary/Sheets/Reader/BinaryWriterS.cpp rename OOXML/Binary/Sheets/Reader/{BinaryWriter.h => BinaryWriterS.h} (100%) create mode 100644 OOXML/Binary/Sheets/Writer/BinaryReaderS.cpp rename OOXML/Binary/Sheets/Writer/{BinaryReader.h => BinaryReaderS.h} (100%) create mode 100644 OOXML/Common/SimpleTypes_Draw.cpp create mode 100644 OOXML/Common/SimpleTypes_Draw.h create mode 100644 OOXML/Projects/Linux/DocxFormatLib/vsdx_format_logic.cpp create mode 100644 OOXML/VsdxFormat/FileFactory_Draw.cpp create mode 100644 OOXML/VsdxFormat/FileFactory_Draw.h create mode 100644 OOXML/VsdxFormat/FileTypes_Draw.cpp create mode 100644 OOXML/VsdxFormat/FileTypes_Draw.h create mode 100644 OOXML/VsdxFormat/Shapes.cpp create mode 100644 OOXML/VsdxFormat/Shapes.h create mode 100644 OOXML/VsdxFormat/VisioConnections.cpp create mode 100644 OOXML/VsdxFormat/VisioConnections.h create mode 100644 OOXML/VsdxFormat/VisioDocument.cpp create mode 100644 OOXML/VsdxFormat/VisioDocument.h create mode 100644 OOXML/VsdxFormat/VisioPages.cpp create mode 100644 OOXML/VsdxFormat/VisioPages.h create mode 100644 OOXML/VsdxFormat/Vsdx.cpp create mode 100644 OOXML/VsdxFormat/Vsdx.h create mode 100644 X2tConverter/src/lib/vsdx.h diff --git a/Common/OfficeFileFormatChecker.h b/Common/OfficeFileFormatChecker.h index 83cc47271a..612d587302 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 e1ea7b2d88..0751e32d8b 100644 --- a/Common/OfficeFileFormatChecker2.cpp +++ b/Common/OfficeFileFormatChecker2.cpp @@ -222,6 +222,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) @@ -816,6 +826,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; @@ -1150,6 +1164,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; @@ -1568,12 +1586,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: @@ -1735,6 +1756,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 fb7d280ac3..f5251edb2c 100644 --- a/Common/OfficeFileFormats.h +++ b/Common/OfficeFileFormats.h @@ -138,12 +138,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 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..3a3a43bba4 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" 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/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..89653af11e 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" diff --git a/OOXML/Binary/Document/BinWriter/BinWriters.h b/OOXML/Binary/Document/BinWriter/BinaryWriterD.h similarity index 100% rename from OOXML/Binary/Document/BinWriter/BinWriters.h rename to OOXML/Binary/Document/BinWriter/BinaryWriterD.h diff --git a/OOXML/Binary/Document/DocWrapper/DocxSerializer.cpp b/OOXML/Binary/Document/DocWrapper/DocxSerializer.cpp index 20b1760ee0..ecc17bccc8 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" 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..094ea2468e 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; 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..2b19f558d3 --- /dev/null +++ b/OOXML/Binary/Draw/BinaryReaderV.cpp @@ -0,0 +1,284 @@ +/* + * (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); + + smart_ptr oCurFile(pDocument); + oVsdx.m_pDocument = oCurFile.smart_dynamic_cast(); + + pDocument->fromPPTY(&oBufferedStream); + oVsdx.Add(oCurFile); + }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..97055bc20b 100644 --- a/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp +++ b/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp @@ -1821,10 +1821,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 +1836,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; diff --git a/OOXML/Binary/Presentation/BinaryFileReaderWriter.h b/OOXML/Binary/Presentation/BinaryFileReaderWriter.h index 5a14f63d26..a00e32ecdb 100644 --- a/OOXML/Binary/Presentation/BinaryFileReaderWriter.h +++ b/OOXML/Binary/Presentation/BinaryFileReaderWriter.h @@ -515,17 +515,23 @@ namespace NSBinPptxRW 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 +543,7 @@ namespace NSBinPptxRW _INT32 m_nCountActiveX = 1; _INT32 m_nThemeOverrideCount = 1; - BinDocxRW::CDocxSerializer* m_pMainDocument; + BinDocxRW::CDocxSerializer* m_pMainDocument = NULL; int m_nDocumentType; CBinaryFileReader(); 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 100% rename from OOXML/Binary/Sheets/Reader/BinaryWriter.h rename to OOXML/Binary/Sheets/Reader/BinaryWriterS.h 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/BinaryReaderS.cpp b/OOXML/Binary/Sheets/Writer/BinaryReaderS.cpp new file mode 100644 index 0000000000..044f12478b --- /dev/null +++ b/OOXML/Binary/Sheets/Writer/BinaryReaderS.cpp @@ -0,0 +1,9519 @@ +/* + * (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); + 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.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); + 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; + + 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()); + + 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 100% rename from OOXML/Binary/Sheets/Writer/BinaryReader.h rename to OOXML/Binary/Sheets/Writer/BinaryReaderS.h diff --git a/OOXML/Common/SimpleTypes_Draw.cpp b/OOXML/Common/SimpleTypes_Draw.cpp new file mode 100644 index 0000000000..30377800e0 --- /dev/null +++ b/OOXML/Common/SimpleTypes_Draw.cpp @@ -0,0 +1,117 @@ +/* + * (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 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"; + default: return L"Bitmap"; + + } + } + 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 = typeDrawing; + else this->m_eValue = EWindowType::typeSheet; + + return this->m_eValue; + } + std::wstring CWindowType::ToString() const + { + switch (this->m_eValue) + { + case typeDrawing: return L"Drawing"; + case typeSheet: return L"Sheet"; + 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..316c965249 --- /dev/null +++ b/OOXML/Common/SimpleTypes_Draw.h @@ -0,0 +1,74 @@ +/* + * (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 EShapeType + { + typeGroup = 0, + typeGuide = 1, + typeForeign = 2, + typeShape = 3 + }; + DEFINE_SIMPLE_TYPE(CShapeType, EShapeType, typeShape) + + enum EWindowType + { + typeDrawing = 0, + typeSheet = 1 + }; + 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/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/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/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..1e42e8a339 100644 --- a/OOXML/DocxFormat/WritingElement.h +++ b/OOXML/DocxFormat/WritingElement.h @@ -1544,7 +1544,52 @@ namespace OOX et_x_MdxKPI, et_x_DynamicArrayProperties, - et_x_RichValueBlock + et_x_RichValueBlock, + + 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_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_Windows, + et_dr_Window }; class File; diff --git a/OOXML/PPTXFormat/Logic/Pic.cpp b/OOXML/PPTXFormat/Logic/Pic.cpp index c337d76e48..93b08c1baf 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" @@ -1800,7 +1800,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 +1873,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/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/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/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/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..eb5bdbe622 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 \ @@ -187,8 +188,15 @@ 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/Shapes.cpp \ + ../../../VsdxFormat/FileFactory_Draw.cpp \ + ../../../VsdxFormat/FileTypes_Draw.cpp + } SOURCES += \ @@ -212,7 +220,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 \ @@ -383,4 +392,11 @@ 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/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..4995c59277 --- /dev/null +++ b/OOXML/Projects/Linux/DocxFormatLib/vsdx_format_logic.cpp @@ -0,0 +1,39 @@ +/* + * (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/Shapes.cpp" +#include "../../../VsdxFormat/FileFactory_Draw.cpp" +#include "../../../VsdxFormat/FileTypes_Draw.cpp" 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..f3200456d7 100644 --- a/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj +++ b/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj @@ -242,6 +242,7 @@ + @@ -327,6 +328,13 @@ + + + + + + + @@ -412,6 +420,7 @@ + @@ -493,6 +502,13 @@ + + + + + + + diff --git a/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj.filters b/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj.filters index 8b9170151f..9362160f72 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,30 @@ XlsxFormat\Pivots + + VsdxFormat + + + VsdxFormat + + + VsdxFormat + + + VsdxFormat + + + VsdxFormat + + + Common + + + VsdxFormat + + + VsdxFormat + @@ -975,5 +1002,29 @@ XlsxFormat\Pivots + + VsdxFormat + + + VsdxFormat + + + VsdxFormat + + + VsdxFormat + + + VsdxFormat + + + Common + + + VsdxFormat + + + VsdxFormat + \ No newline at end of file diff --git a/OOXML/VsdxFormat/FileFactory_Draw.cpp b/OOXML/VsdxFormat/FileFactory_Draw.cpp new file mode 100644 index 0000000000..5700a29dd9 --- /dev/null +++ b/OOXML/VsdxFormat/FileFactory_Draw.cpp @@ -0,0 +1,133 @@ +/* + * (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 "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 CValidation(pMain, oRootPath, oFileName)); + else if (oRelation.Type() == FileTypes::Comments) + return smart_ptr(new CComments(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 CComments(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 CValidation(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)); + + 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..78e6fa6a33 --- /dev/null +++ b/OOXML/VsdxFormat/FileTypes_Draw.cpp @@ -0,0 +1,95 @@ +/* + * (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 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); + + } // namespace FileTypes + } +} // namespace OOX diff --git a/OOXML/VsdxFormat/FileTypes_Draw.h b/OOXML/VsdxFormat/FileTypes_Draw.h new file mode 100644 index 0000000000..2d21a382af --- /dev/null +++ b/OOXML/VsdxFormat/FileTypes_Draw.h @@ -0,0 +1,66 @@ +/* + * (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; + } // namespace FileTypes + } +} // namespace OOX diff --git a/OOXML/VsdxFormat/Shapes.cpp b/OOXML/VsdxFormat/Shapes.cpp new file mode 100644 index 0000000000..ddb347cb3b --- /dev/null +++ b/OOXML/VsdxFormat/Shapes.cpp @@ -0,0 +1,1604 @@ +/* + * (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 "../Binary/Presentation/BinaryFileReaderWriter.h" +#include "../Binary/Presentation/XmlWriter.h" +#include "../DocxFormat/Media/OleObject.h" +#include "../DocxFormat/Media/Image.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::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + { + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); + + pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + void CRel::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: + { + }break; + } + } + pReader->Seek(_end_rec); + } + 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, "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) + } + 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); + 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()); + if (pOleObject) + { + CPath cache = pOleObject->filename_cache(); + CPath ole = pOleObject->filename(); + + //todooo check correct path inside container + + NSFile::CFileBinary::Copy(cache.GetPath(), out.GetPath() + FILE_SEPARATOR_STR + cache.GetFilename()); + NSFile::CFileBinary::Copy(ole.GetPath(), out.GetPath() + FILE_SEPARATOR_STR + ole.GetFilename()); + + pWriter->StartRecord(1); + pWriter->WriteString(cache.GetFilename()); + pWriter->EndRecord(); + + pWriter->StartRecord(2); + pWriter->WriteString(ole.GetFilename()); + pWriter->EndRecord(); + } + else + { + OOX::Media* pMedia = dynamic_cast(pFile.GetPointer()); + if (pMedia) + { + CPath media = pMedia->filename(); + pMedia->copy_to(out.GetPath()); + + pWriter->StartRecord(1); + pWriter->WriteString(media.GetFilename()); + pWriter->EndRecord(); + } + } + } + } + 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; + } + } + 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); + + 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() + 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()); + 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 nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + 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(); + } + else + { + content += oReader.GetText2(); + } + content += oReader.GetText2(); + 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; + } + 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; + 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->WriteString(content); + + pWriter->WriteNodeEnd(L"Text"); + } + 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.GetText(); + } + 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->WriteString(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_ReadAttributes_Read_else_ifChar(oReader, "N", N) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "LocalName", LocalName) + WritingElement_ReadAttributes_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->GetString2(); + }break; + case 2: + { + LocalName = pReader->GetString2(); + }break; + case 3: + { + T = pReader->GetString2(); + }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"IX", IX); + pWriter->WriteAttribute2(L"T", T); + 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_ReadAttributes_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->GetString2(); + }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"IX", IX); + pWriter->WriteAttribute2(L"N", N); + 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"ID", ID); + pWriter->WriteAttribute2(L"T", T); + 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_ReadAttributes_Read_ifChar(oReader, "N", N) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "U", U) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "E", E) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "F", F) + WritingElement_ReadAttributes_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 nParentDepth = oReader.GetDepth(); + while (oReader.ReadNextSiblingNode(nParentDepth)) + { + 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); + } + 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->GetString2(); + }break; + case 1: + { + U = pReader->GetString2(); + }break; + case 2: + { + E = pReader->GetString2(); + }break; + case 3: + { + F = pReader->GetString2(); + }break; + case 4: + { + V = pReader->GetString2(); + }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 CCell::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + { + pWriter->StartNode(L"Cell"); + pWriter->StartAttributes(); + pWriter->WriteAttribute2(L"N", N); + pWriter->WriteAttribute2(L"V", V); + pWriter->WriteAttribute2(L"U", U); + pWriter->WriteAttribute2(L"E", E); + pWriter->WriteAttribute2(L"F", F); + pWriter->EndAttributes(); + pWriter->WriteNodeEnd(L"Cell"); + + if (RefBy.IsInit()) + RefBy->toXmlWriter(pWriter); + } + EElementType CTrigger::getType() const + { + return et_dr_Trigger; + } + void CTrigger::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) + { + WritingElement_ReadAttributes_StartChar_No_NS(oReader) + WritingElement_ReadAttributes_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->GetString2(); + }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(); + pWriter->WriteNodeEnd(L"Trigger"); + + if (RefBy.IsInit()) + RefBy->toXmlWriter(pWriter); + } + 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); + 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); + if (Type.IsInit()) pWriter->WriteAttribute2(L"Type", Type->ToString()); + 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_ReadAttributes_Read_else_ifChar(oReader, "FromCell", FromCell) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "FromPart", FromPart) + WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ToSheet", ToSheet) + WritingElement_ReadAttributes_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->GetString2(); + }break; + case 2: + { + FromPart = pReader->GetLong(); + }break; + case 3: + { + ToSheet = pReader->GetULong(); + }break; + case 4: + { + ToCell = pReader->GetString2(); + }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..ba00f2117b --- /dev/null +++ b/OOXML/VsdxFormat/Shapes.h @@ -0,0 +1,473 @@ +/* + * (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 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 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_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 : 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; + + std::wstring content; // todooo !!! + }; + 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_string N; + nullable_string LocalName; + nullable_uint IX; + nullable_string 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_string 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_string N; + nullable_string U; //todooo type + nullable_string E; //todooo err + nullable_string F; + nullable_string V; + + nullable RefBy; + }; + 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_string 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_string FromCell; + nullable_int FromPart; + nullable_uint ToSheet; + nullable_string 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..c669474e1f --- /dev/null +++ b/OOXML/VsdxFormat/VisioConnections.cpp @@ -0,0 +1,1293 @@ +/* + * (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(); + } + } + 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 + { + 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 + { + } + else if (strcmp("AutoLinkComparison", 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; + } + 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 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(0, PageID); + pWriter->WriteUInt2(0, 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"); + } +} +} // namespace OOX diff --git a/OOXML/VsdxFormat/VisioConnections.h b/OOXML/VsdxFormat/VisioConnections.h new file mode 100644 index 0000000000..cede0c7966 --- /dev/null +++ b/OOXML/VsdxFormat/VisioConnections.h @@ -0,0 +1,353 @@ +/* + * (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 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..21c26ea675 --- /dev/null +++ b/OOXML/VsdxFormat/VisioDocument.cpp @@ -0,0 +1,1802 @@ +/* + * (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 "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 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_bVisioPages = true; + } + OOX::Draw::CDocumentFile::CDocumentFile(OOX::Document* pMain, const CPath& uri) : OOX::IFileContainer(pMain), OOX::File(pMain) + { + 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_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); + + 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 + { + return 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 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; + 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::Windows); + CWindowsFile* pWindows = dynamic_cast(pFile.GetPointer()); + if (pPages) + { + pWriter->StartRecord(14); + pWindows->toPPTY(pWriter); + pWriter->EndRecord(); + } + //comments + //validation + 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(); + } + } + 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 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; + } + 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->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); + } + + 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->GetULong(); + }break; + case 4: + { + WindowTop = pReader->GetULong(); + }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; + } + } + 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->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..cb67b29d31 --- /dev/null +++ b/OOXML/VsdxFormat/VisioDocument.h @@ -0,0 +1,465 @@ +/* + * (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 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 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_bool ShowGuides; + //nullable_bool ShowGuides; + //nullable_uint GlueSettings; + //nullable_uint SnapSettings; + //nullable_uint SnapExtensions; + //nullable_bool SnapAngles; + //nullable_bool DynamicGridEnabled; + //nullable_double TabSplitterPos; + //nullable_uint StencilGroup; + //nullable_uint StencilGroupPos + }; + 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; + + 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/VisioPages.cpp b/OOXML/VsdxFormat/VisioPages.cpp new file mode 100644 index 0000000000..fb13319e9e --- /dev/null +++ b/OOXML/VsdxFormat/VisioPages.cpp @@ -0,0 +1,1313 @@ +/* + * (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()); + } + 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"Name", Name); + pWriter->WriteAttribute2(L"NameU", NameU); + pWriter->WriteAttribute(L"IsCustomName", IsCustomName); + pWriter->WriteAttribute(L"IsCustomNameU", IsCustomNameU); + 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"Name", Name); + pWriter->WriteAttribute2(L"NameU", NameU); + pWriter->WriteAttribute2(L"BaseID", BaseID); + pWriter->WriteAttribute2(L"UniqueID", UniqueID); + pWriter->WriteAttribute(L"MatchByName", MatchByName); + pWriter->WriteAttribute(L"IsCustomName", IsCustomName); + pWriter->WriteAttribute(L"IsCustomNameU", IsCustomNameU); + pWriter->WriteAttribute2(L"IconSize", IconSize); + pWriter->WriteAttribute2(L"PatternFlags", PatternFlags); + pWriter->WriteAttribute2(L"Prompt", Prompt); + pWriter->WriteAttribute(L"Hidden", Hidden); + pWriter->WriteAttribute(L"IconUpdate", IconUpdate); + pWriter->WriteAttribute2(L"AlignName", AlignName); + 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"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"PageSheet"); + } +} +} // namespace OOX diff --git a/OOXML/VsdxFormat/VisioPages.h b/OOXML/VsdxFormat/VisioPages.h new file mode 100644 index 0000000000..58a79abd12 --- /dev/null +++ b/OOXML/VsdxFormat/VisioPages.h @@ -0,0 +1,267 @@ +/* + * (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..2f7e3b308d --- /dev/null +++ b/OOXML/VsdxFormat/Vsdx.cpp @@ -0,0 +1,292 @@ +/* + * (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; +} +//----------------------------------------------------------------------------------------------------------------------------- +OOX::Draw::CValidation::CValidation(OOX::Document* pMain) : OOX::File(pMain) +{ +} +OOX::Draw::CValidation::CValidation(OOX::Document* pMain, const CPath& uri) : OOX::File(pMain) +{ + read(uri.GetDirectory(), uri); +} +OOX::Draw::CValidation::CValidation(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::File(pMain) +{ + read(oRootPath, oPath); +} +OOX::Draw::CValidation::~CValidation() +{ +} +void OOX::Draw::CValidation::read(const CPath& oFilePath) +{ + CPath oRootPath; + read(oRootPath, oFilePath); +} +void OOX::Draw::CValidation::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"dgm:dataModel" == sName && !oReader.IsEmptyNode()) + //{ + // m_oDataModel = oReader; + //} + //if (false == id_drawing.IsInit() && m_oDataModel.IsInit()) + //{ + // for (size_t i = 0; m_oDataModel->m_oExtLst.IsInit() && (i < m_oDataModel->m_oExtLst->m_arrExt.size()); i++) + // { + // if (m_oDataModel->m_oExtLst->m_arrExt[i]->m_oDataModelExt.IsInit()) + // { + // id_drawing = m_oDataModel->m_oExtLst->m_arrExt[i]->m_oDataModelExt->m_oRelId; + // break; + // } + // } + //} +} +void OOX::Draw::CValidation::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::CValidation::type() const +{ + return FileTypes::Validation; +} +const OOX::CPath OOX::Draw::CValidation::DefaultDirectory() const +{ + return type().DefaultDirectory(); +} +const OOX::CPath OOX::Draw::CValidation::DefaultFileName() const +{ + return type().DefaultFileName(); +} +void OOX::Draw::CValidation::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) +{ + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + + switch (_rec) + { + case 0: + { + //m_oDataModel.Init(); + //m_oDataModel->fromPPTY(pReader); + + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); +} +void OOX::Draw::CValidation::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const +{ + //pWriter->WriteRecord2(0, m_oDataModel); +} +void OOX::Draw::CValidation::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const +{ + //if (m_oDataModel.IsInit()) + // m_oDataModel->toXmlWriter(pWriter); +} +//----------------------------------------------------------------------------------------------------------------------------- +OOX::Draw::CComments::CComments(OOX::Document* pMain) : OOX::File(pMain) +{ +} +OOX::Draw::CComments::CComments(OOX::Document* pMain, const CPath& uri) : OOX::File(pMain) +{ + read(uri.GetDirectory(), uri); +} +OOX::Draw::CComments::CComments(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::File(pMain) +{ + read(oRootPath, oPath); +} +OOX::Draw::CComments::~CComments() +{ +} +void OOX::Draw::CComments::read(const CPath& oFilePath) +{ + CPath oRootPath; + read(oRootPath, oFilePath); +} +void OOX::Draw::CComments::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"dgm:dataModel" == sName && !oReader.IsEmptyNode()) + //{ + // m_oDataModel = oReader; + //} + //if (false == id_drawing.IsInit() && m_oDataModel.IsInit()) + //{ + // for (size_t i = 0; m_oDataModel->m_oExtLst.IsInit() && (i < m_oDataModel->m_oExtLst->m_arrExt.size()); i++) + // { + // if (m_oDataModel->m_oExtLst->m_arrExt[i]->m_oDataModelExt.IsInit()) + // { + // id_drawing = m_oDataModel->m_oExtLst->m_arrExt[i]->m_oDataModelExt->m_oRelId; + // break; + // } + // } + //} +} +void OOX::Draw::CComments::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::CComments::type() const +{ + return FileTypes::Comments; +} +const OOX::CPath OOX::Draw::CComments::DefaultDirectory() const +{ + return type().DefaultDirectory(); +} +const OOX::CPath OOX::Draw::CComments::DefaultFileName() const +{ + return type().DefaultFileName(); +} +void OOX::Draw::CComments::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) +{ + LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; + + while (pReader->GetPos() < end) + { + BYTE _rec = pReader->GetUChar(); + + switch (_rec) + { + case 0: + { + //m_oDataModel.Init(); + //m_oDataModel->fromPPTY(pReader); + + }break; + default: + { + pReader->SkipRecord(); + }break; + } + } + pReader->Seek(end); +} +void OOX::Draw::CComments::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const +{ + //pWriter->WriteRecord2(0, m_oDataModel); +} +void OOX::Draw::CComments::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const +{ + //if (m_oDataModel.IsInit()) + // m_oDataModel->toXmlWriter(pWriter); +} +//----------------------------------------------------------------------------------------------------------------------------- diff --git a/OOXML/VsdxFormat/Vsdx.h b/OOXML/VsdxFormat/Vsdx.h new file mode 100644 index 0000000000..15a0780d62 --- /dev/null +++ b/OOXML/VsdxFormat/Vsdx.h @@ -0,0 +1,118 @@ +/* + * (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 CValidation : public OOX::File + { + public: + CValidation(OOX::Document* pMain); + CValidation(OOX::Document* pMain, const CPath& uri); + CValidation(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); + virtual ~CValidation(); + + 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; + + + }; + class CComments : public OOX::File + { + public: + CComments(OOX::Document* pMain); + CComments(OOX::Document* pMain, const CPath& uri); + CComments(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); + virtual ~CComments(); + + 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; + + + }; +//--------------------------------------------------------------------------------------------------------------------------------- + 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/XlsxFormat/FileFactory_Spreadsheet.cpp b/OOXML/XlsxFormat/FileFactory_Spreadsheet.cpp index 8b692b6291..e8bf88384f 100644 --- a/OOXML/XlsxFormat/FileFactory_Spreadsheet.cpp +++ b/OOXML/XlsxFormat/FileFactory_Spreadsheet.cpp @@ -83,8 +83,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()) { 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/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/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/X2tConverter/src/ASCConverters.cpp b/X2tConverter/src/ASCConverters.cpp index 6b35e25cb8..8d6be4948d 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" @@ -1393,7 +1394,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; @@ -1684,6 +1685,18 @@ 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_PPTX2PPTT: { result = pptx2pptt(sFileFrom, sFileTo, oInputParams, oConvertParams); diff --git a/X2tConverter/src/ASCConverters.h b/X2tConverter/src/ASCConverters.h index 5e93affe34..d6a4c24356 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); diff --git a/X2tConverter/src/cextracttools.cpp b/X2tConverter/src/cextracttools.cpp index dfd7c90dec..673b4f2e66 100644 --- a/X2tConverter/src/cextracttools.cpp +++ b/X2tConverter/src/cextracttools.cpp @@ -161,6 +161,24 @@ 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; + } + break; case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX: case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCM: case AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTX: diff --git a/X2tConverter/src/cextracttools.h b/X2tConverter/src/cextracttools.h index c13dfde3c4..cff84c53dd 100644 --- a/X2tConverter/src/cextracttools.h +++ b/X2tConverter/src/cextracttools.h @@ -111,6 +111,11 @@ namespace NExtractTools TCD_POTM2PPTM, TCD_PPSM2PPTM, + TCD_VSDX2VSDT, + TCD_VSDT2VSDX, + TCD_VSDX2VSDT_BIN, + TCD_VSDT_BIN2VSDX, + TCD_ZIPDIR, TCD_UNZIPDIR, diff --git a/X2tConverter/src/lib/vsdx.h b/X2tConverter/src/lib/vsdx.h new file mode 100644 index 0000000000..412c989a79 --- /dev/null +++ b/X2tConverter/src/lib/vsdx.h @@ -0,0 +1,160 @@ +/* + * (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)) + { + 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 89c01c7d3a..a616be2ecd 100644 --- a/X2tConverter/src/lib/xlsx.h +++ b/X2tConverter/src/lib/xlsx.h @@ -294,7 +294,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/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 + From ac2562f83e718a00743873c21fe116253ad32caf Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 10 Mar 2025 14:32:00 +0600 Subject: [PATCH 072/186] fix bug #73466 --- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index a0f84fefce..6bb8be4261 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -2912,6 +2912,8 @@ namespace OOX XLSB::XLWideString str; if(m_oValue.IsInit()) str = m_oValue->m_sText; + else + str = L""; *CellRecord << str; } else From 08ae28224fdd94f623edd04be9228caf23cc46db Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Mon, 10 Mar 2025 14:54:58 +0300 Subject: [PATCH 073/186] conversion of functions --- .../SMCustomShape2OOXML/smcustomshapepars.cpp | 262 ++++++++++++++++-- .../SMCustomShape2OOXML/smcustomshapepars.h | 34 ++- 2 files changed, 269 insertions(+), 27 deletions(-) diff --git a/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.cpp b/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.cpp index effe74fcbb..09c3fb17b3 100644 --- a/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.cpp +++ b/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.cpp @@ -48,7 +48,7 @@ namespace StarMathCustomShape return m_arVecElements; } //class CElemnt - CElement::CElement() + CElement::CElement():m_wsNameFormula(L"") {} CElement::~CElement() {} @@ -75,6 +75,14 @@ namespace StarMathCustomShape { 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"") {} @@ -102,16 +110,22 @@ namespace StarMathCustomShape } return true; } - void CElementNumber::ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter) + 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) + CElementArithmeticOperations::CElementArithmeticOperations():m_enTypeSign(TypeElement::empty),m_pSecondSign(nullptr),m_pFirstValue(nullptr),m_pSecondValue(nullptr),m_uiNumberFormula(1),m_wsNameFormula(L""),m_wsNumberFormula(L"") {} - CElementArithmeticOperations::CElementArithmeticOperations(const std::wstring& wsSign):m_enTypeSign(TypeElement::empty),m_pSecondSign(nullptr),m_pFirstValue(nullptr),m_pSecondValue(nullptr) + CElementArithmeticOperations::CElementArithmeticOperations(const std::wstring& wsSign):m_enTypeSign(TypeElement::empty),m_pSecondSign(nullptr),m_pFirstValue(nullptr),m_pSecondValue(nullptr),m_uiNumberFormula(1),m_wsNameFormula(L""),m_wsNumberFormula(L"") { m_enTypeSign = CElementArithmeticOperations::SetTypeSign(wsSign); SetBaseType(TypeElement::ArithmeticOperation); @@ -153,8 +167,13 @@ namespace StarMathCustomShape pReader->SetDoubleSign(false); } } - void CElementArithmeticOperations::ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter) + void CElementArithmeticOperations::ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter, const std::wstring &wsName) { + if(wsName != L"") + { + SetNameFormula(wsName); + m_wsNumberFormula = SMCustomShapeConversion::ParsFormulaName(wsName,m_wsNameFormula); + } if(m_pSecondSign != nullptr) { CElementArithmeticOperations* pTemp = dynamic_cast(m_pSecondSign); @@ -166,7 +185,10 @@ namespace StarMathCustomShape if(m_pSecondValue != nullptr) wsNameSecondValue = ConversionValueSign(pXmlWriter,m_pFirstValue); pXmlWriter->WriteNodeBegin(L"a:gd",true); - pXmlWriter->WriteAttribute(L"name",L"Text"); + 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()); @@ -194,9 +216,11 @@ namespace StarMathCustomShape if(m_pSecondValue != nullptr) wsNameSecondValue = ConversionValueSign(pXmlWriter,m_pSecondValue); pXmlWriter->WriteNodeBegin(L"a:gd",true); - pXmlWriter->WriteAttribute(L"name",L"Text"); + if(!GetNameFormula().empty()) + pXmlWriter->WriteAttribute(L"name",GetNameFormula()); + else + pXmlWriter->WriteAttribute(L"name",L"Unknown"); pXmlWriter->WriteString(L" fmla=\""); - // SignRecording(pXmlWriter,m_enTypeSign); switch(m_enTypeSign) { case TypeElement::multiplication: case TypeElement::plus: @@ -326,9 +350,11 @@ namespace StarMathCustomShape { if(pElement->GetBaseType() != TypeElement::NumberOrName) { - pElement->ConversionOOXml(pXmlWriter); - std::wstring wsName = L"Good"; - return wsName; + // m_uiNumberFormula++; + std::wstring wsTempName = m_wsNameFormula + m_wsNumberFormula + L"-" + std::to_wstring(m_uiNumberFormula); + m_uiNumberFormula++; + pElement->ConversionOOXml(pXmlWriter,wsTempName); + return pElement->GetNameFormula(); } else return L""; @@ -452,8 +478,19 @@ namespace StarMathCustomShape SMCustomShapePars::ParsString(pReader,m_arElements); pReader->RemovingTheParenthesisIterator(); } - void CElementBracket::ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter) - {} + void CElementBracket::ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter, const std::wstring &wsName) + { + for(CElement* pElement:m_arElements) + { + if(pElement != nullptr) + pElement->ConversionOOXml(pXmlWriter); + } + + } + std::vector CElementBracket::GetVector() + { + return m_arElements; + } //CElementFunction CElementFunction::CElementFunction():m_enTypeFunction(TypeElement::empty),m_pValue(nullptr) { @@ -470,15 +507,176 @@ namespace StarMathCustomShape { 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) { m_pValue = SMCustomShapePars::ParseElement(pReader); + pReader->ReadingNextElement(); + if(CElementArithmeticOperations::CheckArithmeticOperators(pReader->GetElement())) + { + CElement* pSign = SMCustomShapePars::ParseElement(pReader); + CElementArithmeticOperations* pTempSign = dynamic_cast(pSign); + pTempSign->SetFirstValue(m_pValue); + m_pValue = pTempSign; + } + } + void CElementFunction::ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter, const std::wstring &wsName) + { + if(m_pValue == nullptr) + return; + switch (m_enTypeFunction) { + case TypeElement::If: + { + SetNameFormula(L"FunctionIf"); + 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; + std::wstring wsNameFormula; + if(m_enTypeFunction == TypeElement::abs) + { + wsFormula = L"abs "; + wsNameFormula = L"FunctionAbs"; + } + else + { + wsFormula = L"sqrt "; + wsNameFormula = L"FunctionSqrt"; + } + SetNameFormula(wsNameFormula); + 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,wsNameFormula,wsFormula); + break; + } + case TypeElement::min: + case TypeElement::max: + { + std::wstring wsNameFormula; + std::wstring wsFormula; + if(m_enTypeFunction == TypeElement::max) + { + wsNameFormula = L"FunctionMax"; + wsFormula = L"max "; + } + else + { + wsNameFormula = L"FunctionMin"; + 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()) + ConversionElement(pXmlWriter,pElements[i+1],wsFormula); + i = pElements.size(); + } + } + SMCustomShapeConversion::WritingFormulaXml(pXmlWriter,wsNameFormula,wsFormula); + } + break; + } + case TypeElement::sin: + case TypeElement::cos: + { + std::wstring wsNameFormula; + std::wstring wsFormula; + if(m_enTypeFunction == TypeElement::sin) + { + wsNameFormula = L"FunctionSin"; + wsFormula = L"sin 1 "; + } + else + { + wsNameFormula = L"FunctionCos"; + wsFormula = L"cos 1 "; + } + if(m_pValue->GetBaseType() == TypeElement::Bracket) + { + CElementBracket* pBracket = dynamic_cast(m_pValue); + std::vector arVec = pBracket->GetVector(); + if(arVec[0] != nullptr) + ConversionElement(pXmlWriter,arVec[0],wsFormula); + } + else + ConversionElement(pXmlWriter,m_pValue,wsFormula); + SMCustomShapeConversion::WritingFormulaXml(pXmlWriter,wsNameFormula,wsFormula); + } + 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 + { + pElement->ConversionOOXml(pXmlWriter); + wsFormula += pElement->GetNameFormula() + L" "; + } } - void CElementFunction::ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter) - {} //CElementComma CElementComma::CElementComma() {SetBaseType(TypeElement::comma);} @@ -489,16 +687,16 @@ namespace StarMathCustomShape if(!pReader->GetElement().empty()) pReader->ClearElement(); } - void CElementComma::ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter) + void CElementComma::ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter, const std::wstring &wsName) {} //SMCustomShapeConversion - SMCustomShapeConversion::SMCustomShapeConversion() + SMCustomShapeConversion::SMCustomShapeConversion():m_pXmlWriter(nullptr) {}; SMCustomShapeConversion::~SMCustomShapeConversion() { delete m_pXmlWriter; } - void SMCustomShapeConversion::StartConversion(std::vector& arElements) + void SMCustomShapeConversion::StartConversion(std::vector& arElements, const std::wstring& wsFormulaName) { if(arElements.empty()) return; @@ -508,7 +706,7 @@ namespace StarMathCustomShape m_pXmlWriter->WriteNodeBegin(L"a:gd",true); m_pXmlWriter->WriteAttribute(L"name",L"Text"); m_pXmlWriter->WriteString(L" fmla=\"val "); - arElements[0]->ConversionOOXml(m_pXmlWriter); + arElements[0]->ConversionOOXml(m_pXmlWriter,wsFormulaName); m_pXmlWriter->WriteString(L"\""); } else @@ -516,7 +714,7 @@ namespace StarMathCustomShape for(CElement* pElement:arElements) { if(pElement != nullptr) - pElement->ConversionOOXml(m_pXmlWriter); + pElement->ConversionOOXml(m_pXmlWriter,wsFormulaName); } } @@ -525,4 +723,28 @@ namespace StarMathCustomShape { 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) + 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 index e608bc5f2b..5eb41795d5 100644 --- a/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.h +++ b/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include "../../../../DesktopEditor/xml/include/xmlwriter.h" @@ -23,6 +24,15 @@ namespace StarMathCustomShape multiplication, //function sqrt, + abs, + sin, + cos, + tan, + min, + max, + If, + atan, + atan2, empty, comma, }; @@ -65,8 +75,10 @@ namespace StarMathCustomShape public: SMCustomShapeConversion(); ~SMCustomShapeConversion(); - void StartConversion(std::vector& arElements); + 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; }; @@ -76,12 +88,15 @@ namespace StarMathCustomShape CElement(); virtual ~CElement(); virtual void Parse(CSMReader* pReader) = 0; - virtual void ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter) = 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 { @@ -90,8 +105,9 @@ namespace StarMathCustomShape CElementNumber(const std::wstring& wsName); virtual ~CElementNumber(); void Parse(CSMReader* pReader) override; - void ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter) 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; }; @@ -102,7 +118,7 @@ namespace StarMathCustomShape CElementArithmeticOperations(const std::wstring& wsSign); virtual ~CElementArithmeticOperations(); void Parse(CSMReader* pReader) override; - void ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter) 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); @@ -117,6 +133,8 @@ namespace StarMathCustomShape CElement* m_pSecondSign; CElement* m_pFirstValue; CElement* m_pSecondValue; + unsigned int m_uiNumberFormula; + std::wstring m_wsNameFormula,m_wsNumberFormula; }; class CElementBracket: public CElement { @@ -124,7 +142,8 @@ namespace StarMathCustomShape CElementBracket(); virtual ~CElementBracket(); void Parse(CSMReader* pReader) override; - void ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter) override; + void ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter,const std::wstring& wsName = L"") override; + std::vector GetVector(); private: std::vector m_arElements; }; @@ -135,7 +154,8 @@ namespace StarMathCustomShape CElementFunction(const TypeElement& enType); virtual ~CElementFunction(); void Parse(CSMReader* pReader) override; - void ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter) 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); private: TypeElement m_enTypeFunction; @@ -147,7 +167,7 @@ namespace StarMathCustomShape CElementComma(); virtual ~CElementComma(); void Parse(CSMReader* pReader) override; - void ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter) override; + void ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter, const std::wstring& wsName = L"") override; }; } #endif // SMCUSTOMSHAPEPARS_H From 7a3815bc5f0dddcffcc05f3a52d017647b9cb08f Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 10 Mar 2025 15:40:16 +0300 Subject: [PATCH 074/186] Add CryptoPP to drawingfile --- .../graphics/pro/js/drawingfile.json | 13 +++++--- .../graphics/pro/js/wasm/js/drawingfile.js | 32 +++++++++++++++++-- .../pro/js/wasm/js/drawingfile_wasm.js | 25 +++++++-------- PdfFile/test/test.cpp | 15 +-------- 4 files changed, 51 insertions(+), 34 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/drawingfile.json b/DesktopEditor/graphics/pro/js/drawingfile.json index 17a4a13a6c..efd27ff4eb 100644 --- a/DesktopEditor/graphics/pro/js/drawingfile.json +++ b/DesktopEditor/graphics/pro/js/drawingfile.json @@ -2,7 +2,7 @@ "name": "drawingfile", "res_folder": "./deploy", "wasm": true, - "asm": false, + "asm": true, "embed_mem_file": true, "run_before": "before.py", "run_after": "after.py", @@ -29,7 +29,6 @@ "_GetType", "_Open", "_Close", - "_AddPDF", "_GetErrorCode", "_GetInfo", "_GetPixmap", @@ -52,6 +51,8 @@ "_IsNeedCMap", "_SetCMapData", "_ScanPage", + "_SplitPages", + "_MergePages", "_GetImageBase64", "_GetImageBase64Len", "_GetImageBase64Ptr", @@ -87,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": [ { @@ -144,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", "MetafileToRenderer.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/", @@ -162,6 +163,10 @@ "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"] diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js index 1c15af66c5..80ab962e13 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js @@ -145,10 +145,36 @@ CFile.prototype["isNeedPassword"] = function() { return this._isNeedPassword; }; - -CFile.prototype["addPDF"] = function(arrayBuffer, password) +CFile.prototype["SplitPages"] = function(arrPageIndex) { - return this._addPDF(arrayBuffer, password); + 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) +{ + return this._MergePages(arrayBuffer); }; // INFO DOCUMENT diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_wasm.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_wasm.js index 964f4164a4..d17d66d4b4 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_wasm.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_wasm.js @@ -121,31 +121,30 @@ CFile.prototype._getError = function() return Module["_GetErrorCode"](this.nativeFile); }; -CFile.prototype._addPDF = function(buffer, password) +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) { if (!buffer) return false; - let data = new Uint8Array(buffer); + let data = (undefined !== buf.byteLength) ? new Uint8Array(buffer) : buffer; let stream2 = Module["_malloc"](data.length); Module["HEAP8"].set(data, stream2); - let passwordPtr = 0; - if (password) - { - let passwordBuf = password.toUtf8(); - passwordPtr = Module["_malloc"](passwordBuf.length); - Module["HEAP8"].set(passwordBuf, passwordPtr); - } - - let bRes = Module["_AddPDF"](this.nativeFile, stream2, data.length, passwordPtr); + let bRes = Module["_MergePages"](this.nativeFile, stream2, data.length); if (bRes == 1) this.stream.push(stream2); else Module["_free"](stream2); - if (passwordPtr) - Module["_free"](passwordPtr); return bRes == 1; }; diff --git a/PdfFile/test/test.cpp b/PdfFile/test/test.cpp index a1bd68a537..6752c14052 100644 --- a/PdfFile/test/test.cpp +++ b/PdfFile/test/test.cpp @@ -350,22 +350,9 @@ TEST_F(CPdfFileTest, VerifySign) RELEASEOBJECT(pCertificate); } -TEST_F(CPdfFileTest, SplitPdf) -{ - GTEST_SKIP(); - - LoadFromFile(); - ASSERT_TRUE(pdfFile->EditPdf(wsDstFile)); - - std::vector arrPages = { 0 }; - pdfFile->SplitPages(arrPages.empty() ? NULL : arrPages.data(), arrPages.size()); - - pdfFile->Close(); -} - TEST_F(CPdfFileTest, MergePdf) { - //GTEST_SKIP(); + GTEST_SKIP(); LoadFromFile(); ASSERT_TRUE(pdfFile->EditPdf(NSFile::GetProcessDirectory() + L"/test3.pdf")); From ba1597a8d5261db5ebbeb3c70c7bf907885edd70 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 11 Mar 2025 12:02:23 +0300 Subject: [PATCH 075/186] Create AddEditPage --- PdfFile/PdfEditor.cpp | 8 +++++--- PdfFile/SrcWriter/Document.cpp | 4 ++++ PdfFile/SrcWriter/Document.h | 1 + 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index d92cc7e5ec..8dc7edc59c 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -1263,11 +1263,11 @@ bool CPdfEditor::EditPage(int _nPageIndex, bool bSet) } bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFDoc* _pDoc) { - if (m_nMode == Mode::WriteNew || (m_nMode == Mode::WriteAppend && !_pDoc)) + if (m_nMode == Mode::WriteNew) return false; if (m_nMode == Mode::Unknown) m_nMode = Mode::WriteNew; - PDFDoc* pPDFDocument = _pDoc ? _pDoc : m_pReader->GetFirstPDFDocument(); + PDFDoc* pPDFDocument = _pDoc; XRef* xref = pPDFDocument->getXRef(); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); @@ -1637,7 +1637,9 @@ bool CPdfEditor::MergePages(PDFDoc* pDocument, const int* arrPageIndex, unsigned { if (m_nMode != Mode::WriteAppend && !IncrementalUpdates()) return false; - return SplitPages(arrPageIndex, unLength, pDocument); + bool bRes = SplitPages(arrPageIndex, unLength, pDocument); + m_mSplitUniqueRef.clear(); + return bRes; } bool CPdfEditor::DeletePage(int nPageIndex) { diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 632f3938f7..87191ab749 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -1490,6 +1490,10 @@ namespace PdfWriter return true; } + void CDocument::AddEditPage(CPage* pPage, int nPageIndex) + { + m_mEditPages[nPageIndex] = pPage; + } bool CDocument::EditAnnot(CXref* pXref, CAnnotation* pAnnot, int nID) { if (!pAnnot || !EditXref(pXref)) diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index 0fc429bf56..991a9d0ad9 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -195,6 +195,7 @@ namespace PdfWriter bool EditResources(CXref* pXref, CResourcesDict* pResources); std::pair GetPageRef(int nPageIndex); bool EditPage(CXref* pXref, CPage* pPage, int nPageIndex); + 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); From 86c994d0a06864549a93a34f4cd476878352eef6 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 11 Mar 2025 12:03:08 +0300 Subject: [PATCH 076/186] Fix test --- PdfFile/test/test.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/PdfFile/test/test.cpp b/PdfFile/test/test.cpp index 6752c14052..5f642d7c59 100644 --- a/PdfFile/test/test.cpp +++ b/PdfFile/test/test.cpp @@ -355,11 +355,16 @@ TEST_F(CPdfFileTest, MergePdf) GTEST_SKIP(); LoadFromFile(); - ASSERT_TRUE(pdfFile->EditPdf(NSFile::GetProcessDirectory() + L"/test3.pdf")); + std::vector arrPages = { 0, 1 }; + BYTE* pFile = pdfFile->SplitPages(arrPages.data(), arrPages.size()); + + ASSERT_TRUE(pdfFile->EditPdf(wsDstFile)); pdfFile->MergePages(wsDstFile); pdfFile->Close(); + + RELEASEARRAYOBJECTS(pFile); } TEST_F(CPdfFileTest, CopyAnotherPdf) From 3a8601c35426b8e70d0af9a77d49da846fadb02e Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 11 Mar 2025 13:23:38 +0300 Subject: [PATCH 077/186] Ff separately parent and widget --- .../graphics/commands/AnnotField.cpp | 2 + DesktopEditor/graphics/commands/AnnotField.h | 1 + .../graphics/pro/js/wasm/js/drawingfile.js | 73 ++++++++++++++----- .../pro/js/wasm/src/drawingfile_test.cpp | 6 ++ PdfFile/PdfWriter.cpp | 7 +- PdfFile/SrcReader/PdfAnnot.cpp | 17 ++++- PdfFile/SrcReader/PdfAnnot.h | 1 + PdfFile/SrcWriter/Annotation.cpp | 8 ++ 8 files changed, 93 insertions(+), 22 deletions(-) diff --git a/DesktopEditor/graphics/commands/AnnotField.cpp b/DesktopEditor/graphics/commands/AnnotField.cpp index c5cb83d205..e00ffe3897 100644 --- a/DesktopEditor/graphics/commands/AnnotField.cpp +++ b/DesktopEditor/graphics/commands/AnnotField.cpp @@ -1104,6 +1104,8 @@ bool CWidgetsInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafil for (int i = 0; i < n; ++i) pParent->arrV.push_back(pReader->ReadString()); } + if (nFlags & (1 << 7)) + pParent->nFieldFlag = pReader->ReadInt(); m_arrParents.push_back(pParent); } diff --git a/DesktopEditor/graphics/commands/AnnotField.h b/DesktopEditor/graphics/commands/AnnotField.h index fe054d3500..10adfbb9d0 100644 --- a/DesktopEditor/graphics/commands/AnnotField.h +++ b/DesktopEditor/graphics/commands/AnnotField.h @@ -568,6 +568,7 @@ public: int nID; int nFlags; int nParentID; + int nFieldFlag; std::wstring sName; std::wstring sV; std::wstring sDV; diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js index 608782cf79..79964f771c 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js @@ -575,6 +575,31 @@ CFile.prototype["getInteractiveFormsInfo"] = function() for (let i = 0; i < n; ++i) rec["Opt"].push(reader.readString()); } + if (flags & (1 << 7)) + { + 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 + } res["Parents"].push(rec); } @@ -604,9 +629,12 @@ CFile.prototype["getInteractiveFormsInfo"] = function() 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 + 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)) @@ -715,8 +743,11 @@ CFile.prototype["getInteractiveFormsInfo"] = function() 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 + if (rec["flag"] >= 0) + { + rec["NoToggleToOff"] = (rec["flag"] >> 14) & 1; // NoToggleToOff + rec["radiosInUnison"] = (rec["flag"] >> 25) & 1; // RadiosInUnison + } } else if (rec["type"] == 30) { @@ -724,16 +755,19 @@ CFile.prototype["getInteractiveFormsInfo"] = function() rec["value"] = reader.readString(); if (flags & (1 << 10)) rec["maxLen"] = reader.readInt(); - if (rec["flag"] & (1 << 25)) + if (flags & (1 << 11)) 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 + 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) { @@ -770,15 +804,20 @@ CFile.prototype["getInteractiveFormsInfo"] = function() rec["value"].push(reader.readString()); } // 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 (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"]; res["Fields"].push(rec); } diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp index d50befd840..7f3d08c7e7 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp @@ -383,6 +383,12 @@ void ReadInteractiveForms(BYTE* pWidgets, int& i) } std::cout << " ], "; } + if (nFlags & (1 << 7)) + { + nPathLength = READ_INT(pWidgets + i); + i += 4; + std::cout << "Ff " << nPathLength; + } std::cout << std::endl; } diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 56e4d1f8a9..0ce5bf756f 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -2155,9 +2155,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)) @@ -2419,7 +2418,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)) @@ -2717,6 +2716,8 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi } } } + if (nFlags & (1 << 7)) + pParentObj->Add("Ff", pParent->nFieldFlag); } std::vector arrBI = pFieldInfo->GetButtonImg(); diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 5a5e5ecf8f..10616f692b 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -1418,7 +1418,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); @@ -2677,6 +2680,14 @@ void CAnnots::getParents(XRef* xref, Object* oFieldRef) } oOpt.free(); + // 7 - Флаг - Ff + if (oField.dictLookup("Ff", &oObj)->isInt()) + { + pAnnotParent->unFieldFlag = oObj.getInt(); + pAnnotParent->unFlags |= (1 << 7); + } + oObj.free(); + m_arrParents.push_back(pAnnotParent); Object oParentRefObj; @@ -3637,6 +3648,8 @@ void CAnnots::CAnnotParent::ToWASM(NSWasm::CData& oRes) for (int i = 0; i < arrOpt.size(); ++i) oRes.WriteString(arrOpt[i]); } + if (unFlags & (1 << 7)) + oRes.AddInt(unFieldFlag); } void CAnnot::ToWASM(NSWasm::CData& oRes) { @@ -3875,7 +3888,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..d696da327d 100644 --- a/PdfFile/SrcReader/PdfAnnot.h +++ b/PdfFile/SrcReader/PdfAnnot.h @@ -611,6 +611,7 @@ private: unsigned int unFlags; unsigned int unRefNum; // Номер ссылки на объект + unsigned int unFieldFlag; // Флаг Ff unsigned int unRefNumParent; // Номер ссылки на объект родителя std::vector arrI; std::vector arrV; diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index eb123ae3a8..291c7bbe43 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -1582,6 +1582,8 @@ namespace PdfWriter } void CWidgetAnnotation::SetFlag(const int& nFlag) { + if (nFlag < 0) + return; CDictObject* pOwner = GetObjOwnValue("Ff"); if (!pOwner) pOwner = this; @@ -1876,6 +1878,8 @@ namespace PdfWriter } void CPushButtonWidget::SetFlag(const int& nFlag) { + if (nFlag < 0) + return; int nFlags = nFlag; nFlags |= (1 << 16); CWidgetAnnotation::SetFlag(nFlags); @@ -2144,6 +2148,8 @@ namespace PdfWriter } void CCheckBoxWidget::SetFlag(const int& nFlag) { + if (nFlag < 0) + return; int nFlags = nFlag; if (m_nSubtype == WidgetRadiobutton) nFlags |= (1 << 15); @@ -2208,6 +2214,8 @@ namespace PdfWriter } void CChoiceWidget::SetFlag(const int& nFlag) { + if (nFlag < 0) + return; int nFlags = nFlag; if (m_nSubtype == WidgetCombobox) nFlags |= (1 << 17); From adea12d9f730f07e45cfb0ad119c3e8ecdb9c14a Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 11 Mar 2025 14:52:17 +0300 Subject: [PATCH 078/186] Parent Opt with pair string --- .../graphics/commands/AnnotField.cpp | 11 ++++++ DesktopEditor/graphics/commands/AnnotField.h | 1 + .../graphics/pro/js/wasm/js/drawingfile.js | 11 +++++- PdfFile/PdfWriter.cpp | 25 ++++++++++++ PdfFile/SrcReader/PdfAnnot.cpp | 39 ++++++++++++++++--- PdfFile/SrcReader/PdfAnnot.h | 2 +- 6 files changed, 80 insertions(+), 9 deletions(-) diff --git a/DesktopEditor/graphics/commands/AnnotField.cpp b/DesktopEditor/graphics/commands/AnnotField.cpp index e00ffe3897..355e5041c4 100644 --- a/DesktopEditor/graphics/commands/AnnotField.cpp +++ b/DesktopEditor/graphics/commands/AnnotField.cpp @@ -1104,6 +1104,17 @@ 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(); m_arrParents.push_back(pParent); diff --git a/DesktopEditor/graphics/commands/AnnotField.h b/DesktopEditor/graphics/commands/AnnotField.h index 10adfbb9d0..1212805aee 100644 --- a/DesktopEditor/graphics/commands/AnnotField.h +++ b/DesktopEditor/graphics/commands/AnnotField.h @@ -574,6 +574,7 @@ public: std::wstring sDV; std::vector arrI; std::vector arrV; + std::vector< std::pair > arrOpt; }; CWidgetsInfo(); diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js index 79964f771c..35afdc4498 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js @@ -571,9 +571,16 @@ CFile.prototype["getInteractiveFormsInfo"] = function() if (flags & (1 << 6)) { let n = reader.readInt(); - rec["Opt"] = []; + rec["opt"] = []; for (let i = 0; i < n; ++i) - rec["Opt"].push(reader.readString()); + { + let opt1 = reader.readString(); + let opt2 = reader.readString(); + if (opt1 == "") + rec["opt"].push(opt2); + else + rec["opt"].push([opt2, opt1]); + } } if (flags & (1 << 7)) { diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 0ce5bf756f..1cc6e2aecc 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -2716,6 +2716,31 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi } } } + if (nFlags & (1 << 6)) + { + PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject(); + pParentObj->Add("Opt", pArray); + + for (const std::pair& PV : pParent->arrOpt) + { + if (PV.first.empty()) + { + std::string sValue = U_TO_UTF8(PV.second); + pArray->Add(new PdfWriter::CStringObject(sValue.c_str(), true)); + } + else + { + PdfWriter::CArrayObject* pArray2 = new PdfWriter::CArrayObject(); + pArray->Add(pArray2); + + std::string sValue = U_TO_UTF8(PV.first); + pArray2->Add(new PdfWriter::CStringObject(sValue.c_str(), true)); + + sValue = U_TO_UTF8(PV.second); + pArray2->Add(new PdfWriter::CStringObject(sValue.c_str(), true)); + } + } + } if (nFlags & (1 << 7)) pParentObj->Add("Ff", pParent->nFieldFlag); } diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 10616f692b..9ab50ae928 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -2664,17 +2664,41 @@ 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); } @@ -3644,9 +3668,12 @@ 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); diff --git a/PdfFile/SrcReader/PdfAnnot.h b/PdfFile/SrcReader/PdfAnnot.h index d696da327d..34515efe5a 100644 --- a/PdfFile/SrcReader/PdfAnnot.h +++ b/PdfFile/SrcReader/PdfAnnot.h @@ -615,7 +615,7 @@ private: unsigned int unRefNumParent; // Номер ссылки на объект родителя std::vector arrI; std::vector arrV; - std::vector arrOpt; + std::vector< std::pair > arrOpt; std::string sT; std::string sV; std::string sDV; From 80ed0318b60d9039896295f1350e180a928819f5 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 11 Mar 2025 18:34:32 +0600 Subject: [PATCH 079/186] fix bug #73433 --- .../Format/Logic/Biff_records/FileSharing.h | 2 +- OOXML/XlsxFormat/Workbook/Workbook.cpp | 14 +++++++-- OOXML/XlsxFormat/Workbook/WorkbookPr.cpp | 19 ++++++++---- OOXML/XlsxFormat/Workbook/WorkbookPr.h | 2 +- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 27 ++++++++++------ .../Worksheets/WorksheetChildOther.cpp | 31 ++++++++++++++----- 6 files changed, 69 insertions(+), 26 deletions(-) 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/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/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 6bb8be4261..073a508084 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)); + SharedFormulasRef::sharedRefsLocations = std::unique_ptr>(new std::map<_UINT32, XLS::CellRef>); m_oSi = (unsigned int)SharedFormulasRef::sharedRefsLocations->size() - 1; + SharedFormulasRef::sharedRefsLocations->emplace(m_oSi->GetValue(), XLS::CellRef(rowRef, ColumnRef, true, true)); + } } auto fmlaRecord = reader->getNextRecord(XLSB::rt_ShrFmla); @@ -2926,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); @@ -2936,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 @@ -2958,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); //пишем флаги для формулы @@ -4727,6 +4734,8 @@ namespace OOX } if(SharedFormulasRef::sharedRefsLocations) SharedFormulasRef::sharedRefsLocations.reset(); + if(SharedFormulasRef::ArrayRefsLocations) + SharedFormulasRef::ArrayRefsLocations.reset(); } XLS::BaseObjectPtr CSheetData::toBin() { diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 2a01c9e9d5..1de30226d1 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -2812,32 +2812,49 @@ 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); From 52de014e14f185053a5867bc2fd2a1eadb5cd958 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 11 Mar 2025 15:51:16 +0300 Subject: [PATCH 080/186] Fix empty Opt --- PdfFile/SrcWriter/Annotation.cpp | 3 +++ PdfFile/test/test.cpp | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index 291c7bbe43..7cd9861e23 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -2278,6 +2278,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; diff --git a/PdfFile/test/test.cpp b/PdfFile/test/test.cpp index 8dbdcec31a..422d217715 100644 --- a/PdfFile/test/test.cpp +++ b/PdfFile/test/test.cpp @@ -372,7 +372,7 @@ TEST_F(CPdfFileTest, EditPdf) TEST_F(CPdfFileTest, EditPdfFromBase64) { - GTEST_SKIP(); + // GTEST_SKIP(); NSFonts::NSApplicationFontStream::SetGlobalMemoryStorage(NSFonts::NSApplicationFontStream::CreateDefaultGlobalMemoryStorage()); @@ -417,7 +417,7 @@ TEST_F(CPdfFileTest, EditPdfFromBase64) TEST_F(CPdfFileTest, EditPdfFromBin) { - // GTEST_SKIP(); + GTEST_SKIP(); LoadFromFile(); ASSERT_TRUE(pdfFile->EditPdf(wsDstFile)); From c0222c03db36897453b7290ae6a446b5bfdecd0c Mon Sep 17 00:00:00 2001 From: Green Date: Tue, 11 Mar 2025 17:32:14 +0300 Subject: [PATCH 081/186] Fix bug #73485 --- Common/3dParty/html/fetch.py | 2 ++ 1 file changed, 2 insertions(+) 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);") From 20a4bcf7083633073ec22635425b181dcafa8d64 Mon Sep 17 00:00:00 2001 From: Green Date: Tue, 11 Mar 2025 17:32:45 +0300 Subject: [PATCH 082/186] Fix bug #73486 --- Common/3dParty/html/htmltoxhtml.h | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) 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 From 18b8e3ed7c9d4ba02297463af899daf30ed7f3c3 Mon Sep 17 00:00:00 2001 From: Alexey Nagaev Date: Tue, 11 Mar 2025 20:12:42 +0300 Subject: [PATCH 083/186] Fix bug 73484 --- Test/Applications/x2tTester/x2tTester.cpp | 3 +++ 1 file changed, 3 insertions(+) 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"); From a438ae3d2e2f71354f5f57039beae2c8d2cdbf3d Mon Sep 17 00:00:00 2001 From: Elena Subbotina Date: Tue, 11 Mar 2025 22:06:23 +0300 Subject: [PATCH 084/186] . --- OOXML/Common/SimpleTypes_Draw.cpp | 37 +- OOXML/Common/SimpleTypes_Draw.h | 13 +- OOXML/DocxFormat/Media/Media.cpp | 5 + OOXML/DocxFormat/WritingElement.h | 5 +- .../Linux/DocxFormatLib/DocxFormatLib.pro | 2 + .../Linux/DocxFormatLib/vsdx_format_logic.cpp | 1 + .../DocxFormatLib/DocxFormatLib.vcxproj | 2 + .../DocxFormatLib.vcxproj.filters | 6 + OOXML/VsdxFormat/FileFactory_Draw.cpp | 10 +- OOXML/VsdxFormat/FileTypes_Draw.cpp | 8 + OOXML/VsdxFormat/FileTypes_Draw.h | 4 + OOXML/VsdxFormat/Shapes.cpp | 169 +++++--- OOXML/VsdxFormat/Shapes.h | 26 +- OOXML/VsdxFormat/VisioConnections.cpp | 1 + OOXML/VsdxFormat/VisioDocument.cpp | 157 ++++++- OOXML/VsdxFormat/VisioDocument.h | 28 +- OOXML/VsdxFormat/VisioOthers.cpp | 386 ++++++++++++++++++ OOXML/VsdxFormat/VisioOthers.h | 136 ++++++ OOXML/VsdxFormat/VisioPages.cpp | 25 +- 19 files changed, 921 insertions(+), 100 deletions(-) create mode 100644 OOXML/VsdxFormat/VisioOthers.cpp create mode 100644 OOXML/VsdxFormat/VisioOthers.h diff --git a/OOXML/Common/SimpleTypes_Draw.cpp b/OOXML/Common/SimpleTypes_Draw.cpp index 30377800e0..0a3c914ee2 100644 --- a/OOXML/Common/SimpleTypes_Draw.cpp +++ b/OOXML/Common/SimpleTypes_Draw.cpp @@ -40,6 +40,7 @@ namespace Draw 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; @@ -51,10 +52,35 @@ namespace Draw 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; @@ -98,8 +124,10 @@ namespace Draw EWindowType CWindowType::FromString(const std::wstring& sValue) { - if (L"Drawing" == sValue) this->m_eValue = typeDrawing; - else this->m_eValue = EWindowType::typeSheet; + 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; } @@ -107,8 +135,9 @@ namespace Draw { switch (this->m_eValue) { - case typeDrawing: return L"Drawing"; - case typeSheet: return L"Sheet"; + case EWindowType::typeDrawing: return L"Drawing"; + case EWindowType::typeSheet: return L"Sheet"; + case EWindowType::typeStencil: return L"Stencil"; default: return L"Sheet"; } diff --git a/OOXML/Common/SimpleTypes_Draw.h b/OOXML/Common/SimpleTypes_Draw.h index 316c965249..67a2e12f90 100644 --- a/OOXML/Common/SimpleTypes_Draw.h +++ b/OOXML/Common/SimpleTypes_Draw.h @@ -46,6 +46,16 @@ namespace Draw }; 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, @@ -58,7 +68,8 @@ namespace Draw enum EWindowType { typeDrawing = 0, - typeSheet = 1 + typeSheet = 1, + typeStencil =2 }; DEFINE_SIMPLE_TYPE(CWindowType, EWindowType, typeDrawing) diff --git a/OOXML/DocxFormat/Media/Media.cpp b/OOXML/DocxFormat/Media/Media.cpp index f6e5638ce1..2de34e98de 100644 --- a/OOXML/DocxFormat/Media/Media.cpp +++ b/OOXML/DocxFormat/Media/Media.cpp @@ -112,6 +112,11 @@ namespace OOX copy_to(newFilePath); } } + else + { + 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/WritingElement.h b/OOXML/DocxFormat/WritingElement.h index 1e42e8a339..a38204d613 100644 --- a/OOXML/DocxFormat/WritingElement.h +++ b/OOXML/DocxFormat/WritingElement.h @@ -1570,6 +1570,7 @@ namespace OOX 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, @@ -1589,7 +1590,9 @@ namespace OOX et_dr_RowKeyValue, et_dr_RowMap, et_dr_Windows, - et_dr_Window + et_dr_Window, + et_dr_Solutions, + et_dr_Solution }; class File; diff --git a/OOXML/Projects/Linux/DocxFormatLib/DocxFormatLib.pro b/OOXML/Projects/Linux/DocxFormatLib/DocxFormatLib.pro index eb5bdbe622..20137857c5 100644 --- a/OOXML/Projects/Linux/DocxFormatLib/DocxFormatLib.pro +++ b/OOXML/Projects/Linux/DocxFormatLib/DocxFormatLib.pro @@ -193,6 +193,7 @@ SOURCES += \ ../../../VsdxFormat/VisioPages.cpp \ ../../../VsdxFormat/VisioDocument.cpp \ ../../../VsdxFormat/VisioConnections.cpp \ + ../../../VsdxFormat/VisioOthers.cpp \ ../../../VsdxFormat/Shapes.cpp \ ../../../VsdxFormat/FileFactory_Draw.cpp \ ../../../VsdxFormat/FileTypes_Draw.cpp @@ -396,6 +397,7 @@ HEADERS += \ ../../../VsdxFormat/VisioPages.h \ ../../../VsdxFormat/VisioDocument.h \ ../../../VsdxFormat/VisioConnections.h \ + ../../../VsdxFormat/VisioOthers.h \ ../../../VsdxFormat/Shapes.h \ ../../../VsdxFormat/FileFactory_Draw.h \ ../../../VsdxFormat/FileTypes_Draw.h \ diff --git a/OOXML/Projects/Linux/DocxFormatLib/vsdx_format_logic.cpp b/OOXML/Projects/Linux/DocxFormatLib/vsdx_format_logic.cpp index 4995c59277..d18d8d3111 100644 --- a/OOXML/Projects/Linux/DocxFormatLib/vsdx_format_logic.cpp +++ b/OOXML/Projects/Linux/DocxFormatLib/vsdx_format_logic.cpp @@ -34,6 +34,7 @@ #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/Windows/DocxFormatLib/DocxFormatLib.vcxproj b/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj index f3200456d7..a69b1c5530 100644 --- a/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj +++ b/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj @@ -333,6 +333,7 @@ + @@ -507,6 +508,7 @@ + diff --git a/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj.filters b/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj.filters index 9362160f72..a298957e5b 100644 --- a/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj.filters +++ b/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj.filters @@ -580,6 +580,9 @@ VsdxFormat + + VsdxFormat + @@ -1026,5 +1029,8 @@ VsdxFormat + + VsdxFormat + \ No newline at end of file diff --git a/OOXML/VsdxFormat/FileFactory_Draw.cpp b/OOXML/VsdxFormat/FileFactory_Draw.cpp index 5700a29dd9..e6e947c03c 100644 --- a/OOXML/VsdxFormat/FileFactory_Draw.cpp +++ b/OOXML/VsdxFormat/FileFactory_Draw.cpp @@ -34,6 +34,7 @@ #include "VisioDocument.h" #include "VisioConnections.h" #include "VisioPages.h" +#include "VisioOthers.h" //#include "Comments.h" #include "../DocxFormat/Rels.h" @@ -83,6 +84,10 @@ namespace OOX return smart_ptr(new CValidation(pMain, oRootPath, oFileName)); else if (oRelation.Type() == FileTypes::Comments) return smart_ptr(new CComments(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) ); } @@ -126,7 +131,10 @@ namespace OOX 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) ); } } diff --git a/OOXML/VsdxFormat/FileTypes_Draw.cpp b/OOXML/VsdxFormat/FileTypes_Draw.cpp index 78e6fa6a33..80f98237d8 100644 --- a/OOXML/VsdxFormat/FileTypes_Draw.cpp +++ b/OOXML/VsdxFormat/FileTypes_Draw.cpp @@ -75,6 +75,10 @@ namespace OOX 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", @@ -90,6 +94,10 @@ namespace OOX 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 index 2d21a382af..7b9fa0add7 100644 --- a/OOXML/VsdxFormat/FileTypes_Draw.h +++ b/OOXML/VsdxFormat/FileTypes_Draw.h @@ -61,6 +61,10 @@ namespace OOX 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 index ddb347cb3b..73a383cbdd 100644 --- a/OOXML/VsdxFormat/Shapes.cpp +++ b/OOXML/VsdxFormat/Shapes.cpp @@ -59,30 +59,6 @@ namespace OOX if (oReader.IsEmptyNode()) return; } - void CRel::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const - { - pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); - - pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); - } - void CRel::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: - { - }break; - } - } - pReader->Seek(_end_rec); - } void CRel::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const { pWriter->StartNode(L"Rel"); @@ -127,6 +103,8 @@ namespace OOX { 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) @@ -135,6 +113,8 @@ namespace OOX 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); @@ -162,6 +142,8 @@ namespace OOX 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()) @@ -245,6 +227,15 @@ namespace OOX { ExtentY = pReader->GetDoubleReal(); }break; + case 7: + { + CompressionType.Init(); + CompressionType->SetValueFromByte(pReader->GetUChar()); + }break; + case 8: + { + CompressionLevel = pReader->GetDoubleReal(); + }break; } } while (pReader->GetPos() < _end_rec) @@ -302,7 +293,7 @@ namespace OOX 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() + media_filename, 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(); @@ -314,6 +305,8 @@ namespace OOX 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); @@ -340,37 +333,51 @@ namespace OOX if (oReader.IsEmptyNode()) return; - int nParentDepth = oReader.GetDepth(); - while (oReader.ReadNextSiblingNode(nParentDepth)) + int nDepth = oReader.GetDepth(); + XmlUtils::XmlNodeType eNodeType = XmlUtils::XmlNodeType_EndElement; + + while (oReader.Read(eNodeType) && oReader.GetDepth() >= nDepth && XmlUtils::XmlNodeType_EndElement != eNodeType) { - std::wstring sName = oReader.GetName(); + if (eNodeType == XmlUtils::XmlNodeType_Text + || eNodeType == XmlUtils::XmlNodeType_Whitespace + || eNodeType == XmlUtils::XmlNodeType_SIGNIFICANT_WHITESPACE + || eNodeType == XmlUtils::XmlNodeType_CDATA) + { + const char* pValue = oReader.GetTextChar(); - WritingElement* pItem = NULL; - if (L"cp" == sName) - { - pItem = new CText_cp(); + 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 (L"pp" == sName) + else if (eNodeType == XmlUtils::XmlNodeType_Element) { - pItem = new CText_pp(); - } - else if (L"tp" == sName) - { - pItem = new CText_tp(); - } - else if (L"fld" == sName) - { - pItem = new CText_fld(); - } - else - { - content += oReader.GetText2(); - } - content += oReader.GetText2(); - if (pItem) - { - pItem->fromXML(oReader); - m_arrItems.push_back(pItem); + 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); + } } } } @@ -385,6 +392,7 @@ namespace OOX 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])); @@ -418,6 +426,11 @@ namespace OOX 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(); @@ -436,10 +449,42 @@ namespace OOX { m_arrItems[i]->toXmlWriter(pWriter); } - pWriter->WriteString(content); 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; @@ -456,7 +501,7 @@ namespace OOX if (oReader.IsEmptyNode()) return; - content = oReader.GetText(); + content = oReader.GetText2(); } void CText_fld::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const { @@ -495,7 +540,7 @@ namespace OOX pWriter->WriteAttribute2(L"IX", IX); pWriter->EndAttributes(); - pWriter->WriteString(content); + pWriter->WriteStringXML(content); pWriter->WriteNodeEnd(L"fld"); } @@ -771,8 +816,8 @@ namespace OOX pWriter->StartAttributes(); pWriter->WriteAttribute2(L"N", N); pWriter->WriteAttribute2(L"LocalName", LocalName); - pWriter->WriteAttribute2(L"IX", IX); pWriter->WriteAttribute2(L"T", T); + pWriter->WriteAttribute2(L"IX", IX); pWriter->WriteAttribute(L"Del", Del); pWriter->EndAttributes(); @@ -903,8 +948,8 @@ namespace OOX { pWriter->StartNode(L"Section"); pWriter->StartAttributes(); - pWriter->WriteAttribute2(L"IX", IX); pWriter->WriteAttribute2(L"N", N); + pWriter->WriteAttribute2(L"IX", IX); pWriter->WriteAttribute(L"Del", Del); pWriter->EndAttributes(); @@ -964,8 +1009,8 @@ namespace OOX { pWriter->StartNode(L"RefBy"); pWriter->StartAttributes(); - pWriter->WriteAttribute2(L"ID", ID); pWriter->WriteAttribute2(L"T", T); + pWriter->WriteAttribute2(L"ID", ID); pWriter->EndAttributes(); pWriter->WriteNodeEnd(L"RefBy"); } @@ -1073,10 +1118,11 @@ namespace OOX pWriter->WriteAttribute2(L"E", E); pWriter->WriteAttribute2(L"F", F); pWriter->EndAttributes(); - pWriter->WriteNodeEnd(L"Cell"); if (RefBy.IsInit()) RefBy->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"Cell"); } EElementType CTrigger::getType() const { @@ -1155,10 +1201,11 @@ namespace OOX pWriter->WriteAttribute2(L"N", N); pWriter->EndAttributes(); - pWriter->WriteNodeEnd(L"Trigger"); if (RefBy.IsInit()) RefBy->toXmlWriter(pWriter); + + pWriter->WriteNodeEnd(L"Trigger"); } EElementType CShape::getType() const { @@ -1379,12 +1426,12 @@ namespace OOX 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); - if (Type.IsInit()) pWriter->WriteAttribute2(L"Type", Type->ToString()); pWriter->WriteAttribute(L"IsCustomName", IsCustomName); pWriter->WriteAttribute(L"IsCustomNameU", IsCustomNameU); pWriter->WriteAttribute2(L"Master", Master); diff --git a/OOXML/VsdxFormat/Shapes.h b/OOXML/VsdxFormat/Shapes.h index ba00f2117b..502895a382 100644 --- a/OOXML/VsdxFormat/Shapes.h +++ b/OOXML/VsdxFormat/Shapes.h @@ -58,8 +58,6 @@ namespace OOX 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: @@ -111,6 +109,8 @@ namespace OOX public: nullable ForeignType; + nullable CompressionType; + nullable_double CompressionLevel; nullable_uint ObjectType; nullable_bool ShowAsIcon; nullable_double ObjectWidth; @@ -217,6 +217,26 @@ namespace OOX 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: @@ -235,8 +255,6 @@ namespace OOX virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); virtual EElementType getType() const; - - std::wstring content; // todooo !!! }; class CRow : public WritingElementWithChilds<> { diff --git a/OOXML/VsdxFormat/VisioConnections.cpp b/OOXML/VsdxFormat/VisioConnections.cpp index c669474e1f..a3a3b0faf2 100644 --- a/OOXML/VsdxFormat/VisioConnections.cpp +++ b/OOXML/VsdxFormat/VisioConnections.cpp @@ -161,6 +161,7 @@ namespace Draw 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 { diff --git a/OOXML/VsdxFormat/VisioDocument.cpp b/OOXML/VsdxFormat/VisioDocument.cpp index 21c26ea675..99e01e89bb 100644 --- a/OOXML/VsdxFormat/VisioDocument.cpp +++ b/OOXML/VsdxFormat/VisioDocument.cpp @@ -32,6 +32,7 @@ #include "VisioDocument.h" #include "VisioPages.h" #include "VisioConnections.h" +#include "VisioOthers.h" #include "Shapes.h" #include "../PPTXFormat/Theme.h" #include "../../DesktopEditor/common/SystemUtils.h" @@ -1317,6 +1318,14 @@ namespace Draw 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 14: { CWindowsFile* pWindows = new CWindowsFile(((OOX::File*)this)->m_pMainDocument); @@ -1391,6 +1400,15 @@ namespace Draw 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::Windows); CWindowsFile* pWindows = dynamic_cast(pFile.GetPointer()); @@ -1475,6 +1493,65 @@ namespace Draw 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.GetText2(); + } + 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 { @@ -1496,6 +1573,19 @@ namespace Draw 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(25, SnapAngles); + pWriter->WriteBool2(26, DynamicGridEnabled); + pWriter->WriteDoubleReal2(27, TabSplitterPos); + pWriter->WriteUInt2(28, StencilGroup); + pWriter->WriteUInt2(29, StencilGroupPos); pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); } @@ -1578,11 +1668,62 @@ namespace Draw { 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 25: + { + SnapAngles = pReader->GetBool(); + }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; } } pReader->Seek(_end_rec); } - void CWindow::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const { pWriter->StartNode(L"Window"); @@ -1608,6 +1749,20 @@ namespace Draw 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"SnapAngles", SnapAngles); + pWriter->WriteNodeValue(L"DynamicGridEnabled", DynamicGridEnabled); + pWriter->WriteNodeValue(L"TabSplitterPos", TabSplitterPos); + pWriter->WriteNodeValue(L"StencilGroup", StencilGroup); + pWriter->WriteNodeValue(L"StencilGroupPos", StencilGroupPos); + pWriter->WriteNodeEnd(L"Window"); } //----------------------------------------------------------------------------------------------------------------------------- diff --git a/OOXML/VsdxFormat/VisioDocument.h b/OOXML/VsdxFormat/VisioDocument.h index cb67b29d31..5bda579414 100644 --- a/OOXML/VsdxFormat/VisioDocument.h +++ b/OOXML/VsdxFormat/VisioDocument.h @@ -364,21 +364,19 @@ namespace OOX nullable_uint ParentWindow; nullable_bool ReadOnly; - //nullable_bool ShowRulers; - //nullable_bool ShowGrid; - //nullable_bool ShowPageBreaks; - //nullable_bool ShowGuides; - //nullable_bool ShowConnectionPoints; - //nullable_bool ShowGuides; - //nullable_bool ShowGuides; - //nullable_uint GlueSettings; - //nullable_uint SnapSettings; - //nullable_uint SnapExtensions; - //nullable_bool SnapAngles; - //nullable_bool DynamicGridEnabled; - //nullable_double TabSplitterPos; - //nullable_uint StencilGroup; - //nullable_uint StencilGroupPos + 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 SnapAngles; + nullable_bool DynamicGridEnabled; + nullable_double TabSplitterPos; + nullable_uint StencilGroup; + nullable_uint StencilGroupPos; }; class CWindows : public WritingElementWithChilds { diff --git a/OOXML/VsdxFormat/VisioOthers.cpp b/OOXML/VsdxFormat/VisioOthers.cpp new file mode 100644 index 0000000000..18e6ca2dfe --- /dev/null +++ b/OOXML/VsdxFormat/VisioOthers.cpp @@ -0,0 +1,386 @@ +/* + * (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 +{ + OOX::Draw::CSolutionFile::CSolutionFile(OOX::Document* pMain) : OOX::File(pMain) + { + } + OOX::Draw::CSolutionFile::CSolutionFile(OOX::Document* pMain, const CPath& uri) : OOX::File(pMain) + { + read(uri.GetDirectory(), uri); + } + OOX::Draw::CSolutionFile::CSolutionFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::File(pMain) + { + read(oRootPath, oPath); + } + OOX::Draw::CSolutionFile::~CSolutionFile() + { + } + void OOX::Draw::CSolutionFile::read(const CPath& oFilePath) + { + CPath oRootPath; + read(oRootPath, oFilePath); + } + void OOX::Draw::CSolutionFile::read(const CPath& oRootPath, const CPath& oFilePath) + { + NSFile::CFileBinary::ReadAllTextUtf8A(oFilePath.GetPath(), m_sXmlA); + } + void OOX::Draw::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 OOX::Draw::CSolutionFile::type() const + { + return FileTypes::Solution; + } + const OOX::CPath OOX::Draw::CSolutionFile::DefaultDirectory() const + { + return type().DefaultDirectory(); + } + const OOX::CPath OOX::Draw::CSolutionFile::DefaultFileName() const + { + return type().DefaultFileName(); + } + void OOX::Draw::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 OOX::Draw::CSolutionFile::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) + { + pWriter->StartRecord(0); + pWriter->WriteStringA(m_sXmlA); + pWriter->EndRecord(); + } +//----------------------------------------------------------------------------------------------------------------------------- + OOX::Draw::CSolutionsFile::CSolutionsFile(OOX::Document* pMain) : OOX::IFileContainer(pMain), OOX::File(pMain) + { + m_bVisioPages = true; + } + OOX::Draw::CSolutionsFile::CSolutionsFile(OOX::Document* pMain, const CPath& uri) : OOX::IFileContainer(pMain), OOX::File(pMain) + { + m_bVisioPages = true; + read(uri.GetDirectory(), uri); + } + OOX::Draw::CSolutionsFile::CSolutionsFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::IFileContainer(pMain), OOX::File(pMain) + { + m_bVisioPages = true; + + read(oRootPath, oPath); + } + OOX::Draw::CSolutionsFile::~CSolutionsFile() + { + } + void OOX::Draw::CSolutionsFile::read(const CPath& oFilePath) + { + CPath oRootPath; + read(oRootPath, oFilePath); + } + void OOX::Draw::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 OOX::Draw::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 OOX::Draw::CSolutionsFile::type() const + { + return FileTypes::Solutions; + } + const OOX::CPath OOX::Draw::CSolutionsFile::DefaultDirectory() const + { + return type().DefaultDirectory(); + } + const OOX::CPath OOX::Draw::CSolutionsFile::DefaultFileName() const + { + return type().DefaultFileName(); + } + void OOX::Draw::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 OOX::Draw::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 OOX::Draw::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"); + } +} +} // namespace OOX diff --git a/OOXML/VsdxFormat/VisioOthers.h b/OOXML/VsdxFormat/VisioOthers.h new file mode 100644 index 0000000000..4c8738b779 --- /dev/null +++ b/OOXML/VsdxFormat/VisioOthers.h @@ -0,0 +1,136 @@ +/* + * (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; + }; + } //Draw +} // namespace OOX diff --git a/OOXML/VsdxFormat/VisioPages.cpp b/OOXML/VsdxFormat/VisioPages.cpp index fb13319e9e..459843ace7 100644 --- a/OOXML/VsdxFormat/VisioPages.cpp +++ b/OOXML/VsdxFormat/VisioPages.cpp @@ -109,6 +109,7 @@ namespace Draw 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 { @@ -908,10 +909,10 @@ namespace Draw pWriter->StartNode(L"Page"); pWriter->StartAttributes(); pWriter->WriteAttribute2(L"ID", ID); - pWriter->WriteAttribute2(L"Name", Name); pWriter->WriteAttribute2(L"NameU", NameU); - pWriter->WriteAttribute(L"IsCustomName", IsCustomName); 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); @@ -1143,19 +1144,19 @@ namespace Draw pWriter->StartNode(L"Master"); pWriter->StartAttributes(); pWriter->WriteAttribute2(L"ID", ID); - pWriter->WriteAttribute2(L"Name", Name); pWriter->WriteAttribute2(L"NameU", NameU); - pWriter->WriteAttribute2(L"BaseID", BaseID); - pWriter->WriteAttribute2(L"UniqueID", UniqueID); - pWriter->WriteAttribute(L"MatchByName", MatchByName); - pWriter->WriteAttribute(L"IsCustomName", IsCustomName); pWriter->WriteAttribute(L"IsCustomNameU", IsCustomNameU); - pWriter->WriteAttribute2(L"IconSize", IconSize); - pWriter->WriteAttribute2(L"PatternFlags", PatternFlags); + pWriter->WriteAttribute2(L"Name", Name); + pWriter->WriteAttribute(L"IsCustomName", IsCustomName); pWriter->WriteAttribute2(L"Prompt", Prompt); - pWriter->WriteAttribute(L"Hidden", Hidden); - pWriter->WriteAttribute(L"IconUpdate", IconUpdate); + 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(); @@ -1298,10 +1299,10 @@ namespace Draw { pWriter->StartNode(L"PageSheet"); pWriter->StartAttributes(); - pWriter->WriteAttribute2(L"UniqueID", UniqueID); 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) From 6e9500a6e71dbb692b94e040e83c2e9758a24592 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 12 Mar 2025 16:18:35 +0300 Subject: [PATCH 085/186] Fix bug 73493 --- PdfFile/SrcReader/RendererOutputDev.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index 4109ae0b24..d6e9ec2e9d 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) { From 89d965283b1fb58380b7602a70b51ed109a35ebe Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 12 Mar 2025 16:23:09 +0300 Subject: [PATCH 086/186] Fix command with empty states --- PdfFile/SrcReader/RendererOutputDev.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index d6e9ec2e9d..a6fced6987 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -2175,7 +2175,7 @@ namespace PdfReader } void RendererOutputDev::clip(GfxState* pGState) { - if (m_bDrawOnlyText) + if (m_bDrawOnlyText || m_sStates.empty()) return; if (!m_sStates.back().pClip) @@ -2186,7 +2186,7 @@ namespace PdfReader } void RendererOutputDev::eoClip(GfxState* pGState) { - if (m_bDrawOnlyText) + if (m_bDrawOnlyText || m_sStates.empty()) return; if (!m_sStates.back().pClip) @@ -2197,7 +2197,7 @@ namespace PdfReader } void RendererOutputDev::clipToStrokePath(GfxState* pGState) { - if (m_bDrawOnlyText) + if (m_bDrawOnlyText || m_sStates.empty()) return; if (!m_sStates.back().pClip) @@ -2251,7 +2251,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); @@ -2591,9 +2591,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); From 561221102e9e5a08e6ca68c9e834fad25f75652c Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Wed, 12 Mar 2025 16:59:27 +0300 Subject: [PATCH 087/186] fix bug #73509 --- .../Format/Logic/Biff_structures/ODRAW/OfficeArtContainer.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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: From c9e3c3452f4f420739d2365fac711a7205bb0f8e Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Wed, 12 Mar 2025 17:24:35 +0300 Subject: [PATCH 088/186] fix bug #73500 --- OOXML/Binary/Document/BinWriter/BinWriters.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/OOXML/Binary/Document/BinWriter/BinWriters.cpp b/OOXML/Binary/Document/BinWriter/BinWriters.cpp index 85aeee134f..8c6dc07ebe 100644 --- a/OOXML/Binary/Document/BinWriter/BinWriters.cpp +++ b/OOXML/Binary/Document/BinWriter/BinWriters.cpp @@ -5110,16 +5110,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; From 6e6a71e46dcf2ce29eb1c13daf27783c9dbde0ec Mon Sep 17 00:00:00 2001 From: Green Date: Wed, 12 Mar 2025 18:01:36 +0300 Subject: [PATCH 089/186] Fix bug #73496 --- DesktopEditor/raster/Metafile/Emf/EmfParser/CEmfPlusParser.cpp | 3 +++ 1 file changed, 3 insertions(+) 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; From 16023ed916fec413b388a094764b644fc46afa00 Mon Sep 17 00:00:00 2001 From: Elena Subbotina Date: Wed, 12 Mar 2025 19:08:23 +0300 Subject: [PATCH 090/186] . --- OOXML/DocxFormat/Media/Media.cpp | 10 ++-------- OOXML/VsdxFormat/Shapes.cpp | 8 ++++++++ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/OOXML/DocxFormat/Media/Media.cpp b/OOXML/DocxFormat/Media/Media.cpp index 2de34e98de..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,11 +109,8 @@ namespace OOX copy_to(newFilePath); } } - else - { - std::wstring ext = filename.GetExtention(); - if (false == ext.empty()) content.AddDefault(ext.substr(1)); - } + 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/VsdxFormat/Shapes.cpp b/OOXML/VsdxFormat/Shapes.cpp index 73a383cbdd..3cc8a41308 100644 --- a/OOXML/VsdxFormat/Shapes.cpp +++ b/OOXML/VsdxFormat/Shapes.cpp @@ -39,6 +39,8 @@ #include "../DocxFormat/Media/OleObject.h" #include "../DocxFormat/Media/Image.h" +#include "../../Common/OfficeFileFormatChecker.h" + namespace OOX { namespace Draw @@ -271,6 +273,12 @@ namespace OOX 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); From 3b67e4ee0ceb598d606b77b9af3879f2368dee37 Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Thu, 13 Mar 2025 10:55:16 +0300 Subject: [PATCH 091/186] fix bug #73494 --- MsBinaryFile/PptFile/PPTXWriter/Converter.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) 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" Date: Thu, 13 Mar 2025 13:57:18 +0600 Subject: [PATCH 092/186] fux bug #73517 --- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 073a508084..9a710afbef 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -1205,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; } } From a8d8f44cefd735d16e8ebf706c1ae33f0a6e6e6b Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 7 Mar 2025 17:28:54 +0600 Subject: [PATCH 093/186] fix bug #73437 (cherry picked from commit 9cde3dc699d0215e4d0bca9a04d9739a0104a396) --- .../Logic/Biff_structures/StringPtgParser.cpp | 3 -- OOXML/Binary/Sheets/Reader/BinaryWriter.cpp | 3 ++ OOXML/Binary/Sheets/Writer/BinaryReader.cpp | 2 +- OOXML/XlsbFormat/Biff12_records/BeginSXPI.h | 10 ++-- OOXML/XlsxFormat/Pivot/Pivots.cpp | 53 +++++++++++++------ 5 files changed, 45 insertions(+), 26 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp index b6c345b5cc..fa24bcb4b8 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/StringPtgParser.cpp @@ -317,9 +317,6 @@ const bool StringPtgParser::parseToPtgs(const std::wstring& assembled_formula, R [&](XLS::GlobalWorkbookInfo::_xti i) { return i.iSup == ixti; }); - if(pos->itabFirst == pos->itabLast) - rgce.addPtg(found_operand = OperandPtgPtr(new PtgRef3d(ixti, operand_str, OperandPtg::ptg_VALUE, rgce.getLocation()))); - else rgce.addPtg(found_operand = OperandPtgPtr(new PtgRef3d(ixti, operand_str, OperandPtg::ptg_REFERENCE, rgce.getLocation()))); } else if(SyntaxPtg::extract_PtgRefErr(it, itEnd)) diff --git a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp index 3767dbebdd..6b6534fb16 100644 --- a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp +++ b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp @@ -2663,6 +2663,9 @@ void BinaryWorkbookTableWriter::WritePivotCache(OOX::Spreadsheet::CWorkbook& wor { nCurPos = m_oBcw.WriteItemStart(c_oSer_PivotTypes::cache); NSStringUtils::CStringBuilder writer; + writer.WriteString(L""); + if(pivotCacheFile->m_oPivotCashDefinition->m_oRid.IsInit()) + pivotCacheFile->m_oPivotCashDefinition->m_oRid.reset(); pivotCacheFile->m_oPivotCashDefinition->toXML(writer); auto wstringData = writer.GetData(); m_oBcw.m_oStream.WriteStringUtf8(wstringData); diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index 05a02799c8..f2b4fa8c9c 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp @@ -3493,7 +3493,7 @@ int BinaryWorkbookTableReader::ReadPivotCaches(BYTE type, long length, void* poR NSCommon::smart_ptr pFileRecords(oPivotCachesTemp.pRecords); srIdRecords = pDefinitionFile->Add(pFileRecords).ToString(); } - pDefinitionFile->setData(oPivotCachesTemp.pDefinitionData, oPivotCachesTemp.nDefinitionLength, L""); + pDefinitionFile->setData(oPivotCachesTemp.pDefinitionData, oPivotCachesTemp.nDefinitionLength, srIdRecords); NSCommon::smart_ptr pFile(pDefinitionFile); OOX::RId rIdDefinition = m_oWorkbook.Add(pFile); diff --git a/OOXML/XlsbFormat/Biff12_records/BeginSXPI.h b/OOXML/XlsbFormat/Biff12_records/BeginSXPI.h index f2c6ab120d..cb384c31e9 100644 --- a/OOXML/XlsbFormat/Biff12_records/BeginSXPI.h +++ b/OOXML/XlsbFormat/Biff12_records/BeginSXPI.h @@ -51,11 +51,11 @@ namespace XLSB void readFields(XLS::CFRecord& record) override; void writeFields(XLS::CFRecord& record) override; - _INT32 isxvd; - _UINT32 isxvi; - _INT32 isxth; - bool fUnique; - bool fDisplay; + _INT32 isxvd = 0; + _UINT32 isxvi = 0x001000FE; + _INT32 isxth = -1; + bool fUnique = false; + bool fDisplay = false; XLWideString irstUnique; XLWideString irstDisplay; }; diff --git a/OOXML/XlsxFormat/Pivot/Pivots.cpp b/OOXML/XlsxFormat/Pivot/Pivots.cpp index 2f5530cb29..b484f94540 100644 --- a/OOXML/XlsxFormat/Pivot/Pivots.cpp +++ b/OOXML/XlsxFormat/Pivot/Pivots.cpp @@ -1885,13 +1885,15 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" if(m_oHier.IsInit()) ptr->isxth = m_oHier.get(); if(m_oName.IsInit()) + { ptr->irstUnique = m_oName.get(); - else - ptr->irstUnique = 0xFFFFFFFF; + ptr->fUnique = true; + } if(m_oCap.IsInit()) + { ptr->irstDisplay = m_oCap.get(); - else - ptr->irstDisplay = 0xFFFFFFFF; + ptr->fDisplay = true; + } return objectPtr; } void CPageField::fromBin(XLS::BaseObjectPtr& obj) @@ -4172,7 +4174,6 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" writer.WriteString(L"GetValue()); WritingStringNullableAttrInt(L"mappingCount", m_oMappingCount, m_oMappingCount->GetValue()); WritingStringNullableAttrInt(L"numFmtId", m_oNumFmtId, m_oNumFmtId->GetValue()); + WritingStringNullableAttrBool2(L"databaseField", m_oDatabaseField); if(!m_oSharedItems.IsInit() && !m_oFieldGroup.IsInit()) { writer.WriteString(L"/>"); @@ -4406,22 +4408,29 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" void CSharedItems::toXML(NSStringUtils::CStringBuilder& writer) const { writer.WriteString(L"ToString()); WritingStringNullableAttrString(L"maxDate", m_oMaxDate, m_oMaxDate->ToString()); - writer.WriteString(L">"); - + if(!m_arrItems.empty()) + { + WritingStringAttrInt(L"count", (int)m_arrItems.size()); + } + WritingStringNullableAttrBool2(L"longText", m_oLongText); + if(m_arrItems.empty()) + { + writer.WriteString(L"/>"); + return; + } + writer.WriteString(L">"); for ( size_t i = 0; i < m_arrItems.size(); ++i) { if ( m_arrItems[i] ) @@ -5127,7 +5136,7 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" //------------------------------------ void CRangeGroupingProperties::toXML(NSStringUtils::CStringBuilder& writer) const { - writer.WriteString(L"ToString()); WritingStringNullableAttrBool2(L"autoStart", m_oAutoStart); WritingStringNullableAttrBool2(L"autoEnd", m_oAutoEnd); @@ -5835,6 +5844,11 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } WritingStringNullableAttrBool2(L"f", m_oCalculated); WritingStringNullableAttrBool2(L"u", m_oUnused); + if(m_arrItems.empty()) + { + writer.WriteString(L"/>"); + return; + } writer.WriteString(L">"); for ( size_t i = 0; i < m_arrItems.size(); ++i) @@ -5967,6 +5981,11 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" } WritingStringNullableAttrBool2(L"f", m_oCalculated); WritingStringNullableAttrBool2(L"u", m_oUnused); + if(m_arrItems.empty()) + { + writer.WriteString(L"/>"); + return; + } writer.WriteString(L">"); for ( size_t i = 0; i < m_arrItems.size(); ++i) @@ -6864,8 +6883,8 @@ xmlns:xr16=\"http://schemas.microsoft.com/office/spreadsheetml/2017/revision16\" void CFieldGroupProperties::toXML(NSStringUtils::CStringBuilder& writer) const { writer.WriteString(L"GetValue()); WritingStringNullableAttrInt(L"par", m_oPar, m_oPar->GetValue()); + WritingStringNullableAttrInt(L"base", m_oBase, m_oBase->GetValue()); writer.WriteString(L">"); if(m_oDiscretePr.IsInit()) From 16c77add4df84c9bcda6e3f4a0e5c74bf2845ec5 Mon Sep 17 00:00:00 2001 From: Elena Subbotina Date: Thu, 13 Mar 2025 19:23:34 +0300 Subject: [PATCH 094/186] visio crypt, template, macros, plugins --- OOXML/Binary/Draw/BinaryReaderV.cpp | 5 +- OOXML/VsdxFormat/VisioDocument.cpp | 83 ++++++++++++++++++++++++++++- OOXML/VsdxFormat/VisioDocument.h | 1 + OOXML/VsdxFormat/Vsdx.h | 2 - X2tConverter/src/ASCConverters.cpp | 35 +++++++++++- X2tConverter/src/cextracttools.cpp | 6 +++ X2tConverter/src/cextracttools.h | 5 +- X2tConverter/src/lib/crypt.h | 8 +++ X2tConverter/src/lib/vsdx.h | 20 +++++++ 9 files changed, 159 insertions(+), 6 deletions(-) diff --git a/OOXML/Binary/Draw/BinaryReaderV.cpp b/OOXML/Binary/Draw/BinaryReaderV.cpp index 2b19f558d3..f38f6d0aa2 100644 --- a/OOXML/Binary/Draw/BinaryReaderV.cpp +++ b/OOXML/Binary/Draw/BinaryReaderV.cpp @@ -263,12 +263,15 @@ namespace BinVsdxRW 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); + oVsdx.Add(oCurFile); + + oSaveParams.bMacroEnabled = pDocument->m_bMacroEnabled; }break; } diff --git a/OOXML/VsdxFormat/VisioDocument.cpp b/OOXML/VsdxFormat/VisioDocument.cpp index 99e01e89bb..6c231ae35c 100644 --- a/OOXML/VsdxFormat/VisioDocument.cpp +++ b/OOXML/VsdxFormat/VisioDocument.cpp @@ -1137,15 +1137,19 @@ namespace Draw //----------------------------------------------------------------------------------------------------------------------------- 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); @@ -1162,6 +1166,12 @@ namespace Draw { 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())) @@ -1226,7 +1236,8 @@ namespace Draw } const OOX::FileType OOX::Draw::CDocumentFile::type() const { - return FileTypes::Document; + if (m_bMacroEnabled) return OOX::Draw::FileTypes::DocumentMacro; + else return OOX::Draw::FileTypes::Document; } const OOX::CPath OOX::Draw::CDocumentFile::DefaultDirectory() const { @@ -1344,6 +1355,40 @@ namespace Draw 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(); @@ -1432,6 +1477,42 @@ namespace Draw 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 diff --git a/OOXML/VsdxFormat/VisioDocument.h b/OOXML/VsdxFormat/VisioDocument.h index 5bda579414..5891f354e4 100644 --- a/OOXML/VsdxFormat/VisioDocument.h +++ b/OOXML/VsdxFormat/VisioDocument.h @@ -422,6 +422,7 @@ namespace OOX virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; std::wstring m_strFilename; + bool m_bMacroEnabled; nullable DocumentSettings; nullable Colors; diff --git a/OOXML/VsdxFormat/Vsdx.h b/OOXML/VsdxFormat/Vsdx.h index 15a0780d62..9923006698 100644 --- a/OOXML/VsdxFormat/Vsdx.h +++ b/OOXML/VsdxFormat/Vsdx.h @@ -65,8 +65,6 @@ namespace OOX virtual void toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const; std::wstring m_strFilename; - - }; class CComments : public OOX::File { diff --git a/X2tConverter/src/ASCConverters.cpp b/X2tConverter/src/ASCConverters.cpp index 8d6be4948d..15e3cadebb 100644 --- a/X2tConverter/src/ASCConverters.cpp +++ b/X2tConverter/src/ASCConverters.cpp @@ -1410,6 +1410,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; @@ -1445,7 +1457,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)) @@ -1697,6 +1709,27 @@ namespace NExtractTools 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); diff --git a/X2tConverter/src/cextracttools.cpp b/X2tConverter/src/cextracttools.cpp index 673b4f2e66..73ec2c1093 100644 --- a/X2tConverter/src/cextracttools.cpp +++ b/X2tConverter/src/cextracttools.cpp @@ -177,6 +177,12 @@ namespace NExtractTools { 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: diff --git a/X2tConverter/src/cextracttools.h b/X2tConverter/src/cextracttools.h index cff84c53dd..876bb6edc7 100644 --- a/X2tConverter/src/cextracttools.h +++ b/X2tConverter/src/cextracttools.h @@ -112,8 +112,11 @@ namespace NExtractTools TCD_PPSM2PPTM, TCD_VSDX2VSDT, - TCD_VSDT2VSDX, TCD_VSDX2VSDT_BIN, + TCD_VSDT2VSDX, + TCD_VSDT2VSDM, + TCD_VSDT2VSTX, + TCD_VSDT2VSTM, TCD_VSDT_BIN2VSDX, TCD_ZIPDIR, 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 index 412c989a79..bd05ee8099 100644 --- a/X2tConverter/src/lib/vsdx.h +++ b/X2tConverter/src/lib/vsdx.h @@ -110,6 +110,26 @@ namespace NExtractTools 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); From 2a5d7a78a3f4005cbf3677c30625c4019e7e2d91 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 14 Mar 2025 10:56:41 +0300 Subject: [PATCH 095/186] Fix merge pages --- PdfFile/PdfEditor.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 8dc7edc59c..aaea217558 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -1637,7 +1637,25 @@ bool CPdfEditor::MergePages(PDFDoc* pDocument, const int* arrPageIndex, unsigned { if (m_nMode != Mode::WriteAppend && !IncrementalUpdates()) return false; + int nPagesBefore = m_pReader->GetNumPages() - pDocument->getNumPages(); bool bRes = SplitPages(arrPageIndex, unLength, pDocument); + if (!bRes) + { + m_mSplitUniqueRef.clear(); + return false; + } + + // Добавление merge страниц в редактируемые + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); + Catalog* pCatalog = pDocument->getCatalog(); + for (int i = 0, nPages = unLength == 0 ? pDocument->getNumPages() : unLength; i < nPages; ++i) + { + Ref* pPageRef = pCatalog->getPageRef((arrPageIndex ? arrPageIndex[i] : i) + 1); + PdfWriter::CObjectBase* pObj = m_mSplitUniqueRef[pPageRef->num]; + if (pObj->GetType() == PdfWriter::object_type_DICT && ((PdfWriter::CDictObject*)pObj)->GetDictType() == PdfWriter::dict_type_PAGE) + pDoc->AddEditPage((PdfWriter::CPage*)pObj, nPagesBefore + i); + } + m_mSplitUniqueRef.clear(); return bRes; } From 2652fb4e65d187720f139e61c308435e3980c26a Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Fri, 14 Mar 2025 11:19:14 +0300 Subject: [PATCH 096/186] Fix bug 73507 --- DesktopEditor/fontengine/TextShaper.cpp | 2 +- DesktopEditor/fontengine/TextShaper_p.h | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/DesktopEditor/fontengine/TextShaper.cpp b/DesktopEditor/fontengine/TextShaper.cpp index 6efcb547ed..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; 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 && From 1346f56d673572e2db8ca9d926dc1f26f3a3149b Mon Sep 17 00:00:00 2001 From: Green Date: Fri, 14 Mar 2025 17:00:37 +0300 Subject: [PATCH 097/186] Fix bug #73487 --- HwpFile/HwpDoc/Common/XMLNode.h | 1 + HwpFile/HwpDoc/Common/XMLReader.cpp | 47 +++++++++++++------ .../HWPElements/HWPRecordBorderFill.cpp | 9 +--- .../HwpDoc/HWPElements/HWPRecordBullet.cpp | 12 ++++- 4 files changed, 46 insertions(+), 23 deletions(-) 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()) From 6fe0f2828e9b796b90d0b850dad624f9845ba697 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 14 Mar 2025 21:53:47 +0600 Subject: [PATCH 098/186] Fix bug #73467 --- OOXML/Common/SimpleTypes_Spreadsheet.cpp | 2 +- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/OOXML/Common/SimpleTypes_Spreadsheet.cpp b/OOXML/Common/SimpleTypes_Spreadsheet.cpp index 24d91f3e28..fb2b990041 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; diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 9a710afbef..f898cee414 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -1158,7 +1158,7 @@ namespace OOX ColumnRef = static_cast(BinFmla.rgcb.getPtgs().back().get())->col; if(!SharedFormulasRef::sharedRefsLocations) SharedFormulasRef::sharedRefsLocations = std::unique_ptr>(new std::map<_UINT32, XLS::CellRef>); - m_oSi = (unsigned int)SharedFormulasRef::sharedRefsLocations->size() - 1; + m_oSi = (unsigned int)SharedFormulasRef::sharedRefsLocations->size(); SharedFormulasRef::sharedRefsLocations->emplace(m_oSi->GetValue(), XLS::CellRef(rowRef, ColumnRef, true, true)); } @@ -4369,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()) From 4f4f61bb1918e0a0a6d79827227ae5129443564f Mon Sep 17 00:00:00 2001 From: Green Date: Sat, 15 Mar 2025 01:04:27 +0300 Subject: [PATCH 099/186] Fix bug #73483 --- Common/OfficeFileFormatChecker2.cpp | 248 +++++++++++++++++++++++----- 1 file changed, 206 insertions(+), 42 deletions(-) diff --git a/Common/OfficeFileFormatChecker2.cpp b/Common/OfficeFileFormatChecker2.cpp index e1ea7b2d88..695efb0628 100644 --- a/Common/OfficeFileFormatChecker2.cpp +++ b/Common/OfficeFileFormatChecker2.cpp @@ -1159,58 +1159,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(); From 005b790e141a5ec63c93a2c460f997961327888b Mon Sep 17 00:00:00 2001 From: Elena Subbotina Date: Sat, 15 Mar 2025 11:14:36 +0300 Subject: [PATCH 100/186] . --- Common/OfficeFileFormatChecker2.cpp | 4 + Common/OfficeFileFormats.h | 2 +- OOXML/DocxFormat/WritingElement.h | 109 +- OOXML/VsdxFormat/FileFactory_Draw.cpp | 8 +- OOXML/VsdxFormat/VisioDocument.cpp | 36 +- OOXML/VsdxFormat/VisioOthers.cpp | 1432 ++++++++++++++++++++++++- OOXML/VsdxFormat/VisioOthers.h | 391 ++++++- OOXML/VsdxFormat/VisioPages.cpp | 2 +- OOXML/VsdxFormat/VisioPages.h | 1 - OOXML/VsdxFormat/Vsdx.cpp | 212 ---- OOXML/VsdxFormat/Vsdx.h | 49 - X2tConverter/src/ASCConverters.cpp | 4 +- X2tConverter/src/cextracttools.cpp | 2 +- 13 files changed, 1907 insertions(+), 345 deletions(-) diff --git a/Common/OfficeFileFormatChecker2.cpp b/Common/OfficeFileFormatChecker2.cpp index 0751e32d8b..12cbde6d7b 100644 --- a/Common/OfficeFileFormatChecker2.cpp +++ b/Common/OfficeFileFormatChecker2.cpp @@ -1514,6 +1514,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"; @@ -1683,6 +1685,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; diff --git a/Common/OfficeFileFormats.h b/Common/OfficeFileFormats.h index f5251edb2c..e56af78f0e 100644 --- a/Common/OfficeFileFormats.h +++ b/Common/OfficeFileFormats.h @@ -153,4 +153,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/OOXML/DocxFormat/WritingElement.h b/OOXML/DocxFormat/WritingElement.h index a38204d613..13a0e79a0c 100644 --- a/OOXML/DocxFormat/WritingElement.h +++ b/OOXML/DocxFormat/WritingElement.h @@ -1546,53 +1546,68 @@ namespace OOX et_x_DynamicArrayProperties, et_x_RichValueBlock, - 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_Windows, - et_dr_Window, - et_dr_Solutions, - et_dr_Solution + 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_Windows, + et_dr_Window, + 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/VsdxFormat/FileFactory_Draw.cpp b/OOXML/VsdxFormat/FileFactory_Draw.cpp index e6e947c03c..0685978287 100644 --- a/OOXML/VsdxFormat/FileFactory_Draw.cpp +++ b/OOXML/VsdxFormat/FileFactory_Draw.cpp @@ -81,9 +81,9 @@ namespace OOX else if (oRelation.Type() == FileTypes::Windows) return smart_ptr(new CWindowsFile(pMain, oRootPath, oFileName)); else if (oRelation.Type() == FileTypes::Validation) - return smart_ptr(new CValidation(pMain, oRootPath, oFileName)); + return smart_ptr(new CValidationFile(pMain, oRootPath, oFileName)); else if (oRelation.Type() == FileTypes::Comments) - return smart_ptr(new CComments(pMain, oRootPath, oFileName)); + 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) @@ -120,13 +120,13 @@ namespace OOX else if (pRelation->Type() == FileTypes::Master) return smart_ptr(new CMasterFile(pMain, oRootPath, oFileName)); else if (pRelation->Type() == FileTypes::Comments) - return smart_ptr(new CComments(pMain, oRootPath, oFileName)); + 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 CValidation(pMain, oRootPath, oFileName)); + 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) diff --git a/OOXML/VsdxFormat/VisioDocument.cpp b/OOXML/VsdxFormat/VisioDocument.cpp index 6c231ae35c..1bd4ffe0a6 100644 --- a/OOXML/VsdxFormat/VisioDocument.cpp +++ b/OOXML/VsdxFormat/VisioDocument.cpp @@ -1337,6 +1337,22 @@ namespace Draw 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); @@ -1455,6 +1471,24 @@ namespace Draw 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) @@ -1463,8 +1497,6 @@ namespace Draw pWindows->toPPTY(pWriter); pWriter->EndRecord(); } - //comments - //validation std::vector>& container = ((OOX::IFileContainer*)(this))->GetContainer(); for (size_t k = 0; k < container.size(); ++k) { diff --git a/OOXML/VsdxFormat/VisioOthers.cpp b/OOXML/VsdxFormat/VisioOthers.cpp index 18e6ca2dfe..844fac6da0 100644 --- a/OOXML/VsdxFormat/VisioOthers.cpp +++ b/OOXML/VsdxFormat/VisioOthers.cpp @@ -39,30 +39,30 @@ namespace OOX { namespace Draw { - OOX::Draw::CSolutionFile::CSolutionFile(OOX::Document* pMain) : OOX::File(pMain) + CSolutionFile::CSolutionFile(OOX::Document* pMain) : OOX::File(pMain) { } - OOX::Draw::CSolutionFile::CSolutionFile(OOX::Document* pMain, const CPath& uri) : OOX::File(pMain) + CSolutionFile::CSolutionFile(OOX::Document* pMain, const CPath& uri) : OOX::File(pMain) { read(uri.GetDirectory(), uri); } - OOX::Draw::CSolutionFile::CSolutionFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::File(pMain) + CSolutionFile::CSolutionFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::File(pMain) { read(oRootPath, oPath); } - OOX::Draw::CSolutionFile::~CSolutionFile() + CSolutionFile::~CSolutionFile() { } - void OOX::Draw::CSolutionFile::read(const CPath& oFilePath) + void CSolutionFile::read(const CPath& oFilePath) { CPath oRootPath; read(oRootPath, oFilePath); } - void OOX::Draw::CSolutionFile::read(const CPath& oRootPath, const CPath& oFilePath) + void CSolutionFile::read(const CPath& oRootPath, const CPath& oFilePath) { NSFile::CFileBinary::ReadAllTextUtf8A(oFilePath.GetPath(), m_sXmlA); } - void OOX::Draw::CSolutionFile::write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const + void CSolutionFile::write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const { NSFile::CFileBinary oFile; if (true == oFile.CreateFileW(oFilePath.GetPath())) @@ -73,19 +73,19 @@ namespace Draw } oContent.Registration(type().OverrideType(), oDirectory, oFilePath.GetFilename()); } - const OOX::FileType OOX::Draw::CSolutionFile::type() const + const OOX::FileType CSolutionFile::type() const { return FileTypes::Solution; } - const OOX::CPath OOX::Draw::CSolutionFile::DefaultDirectory() const + const OOX::CPath CSolutionFile::DefaultDirectory() const { return type().DefaultDirectory(); } - const OOX::CPath OOX::Draw::CSolutionFile::DefaultFileName() const + const OOX::CPath CSolutionFile::DefaultFileName() const { return type().DefaultFileName(); } - void OOX::Draw::CSolutionFile::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + void CSolutionFile::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) { LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; @@ -108,37 +108,37 @@ namespace Draw } pReader->Seek(end); } - void OOX::Draw::CSolutionFile::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) + void CSolutionFile::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) { pWriter->StartRecord(0); pWriter->WriteStringA(m_sXmlA); pWriter->EndRecord(); } //----------------------------------------------------------------------------------------------------------------------------- - OOX::Draw::CSolutionsFile::CSolutionsFile(OOX::Document* pMain) : OOX::IFileContainer(pMain), OOX::File(pMain) + CSolutionsFile::CSolutionsFile(OOX::Document* pMain) : OOX::IFileContainer(pMain), OOX::File(pMain) { m_bVisioPages = true; } - OOX::Draw::CSolutionsFile::CSolutionsFile(OOX::Document* pMain, const CPath& uri) : OOX::IFileContainer(pMain), OOX::File(pMain) + CSolutionsFile::CSolutionsFile(OOX::Document* pMain, const CPath& uri) : OOX::IFileContainer(pMain), OOX::File(pMain) { m_bVisioPages = true; read(uri.GetDirectory(), uri); } - OOX::Draw::CSolutionsFile::CSolutionsFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::IFileContainer(pMain), OOX::File(pMain) + CSolutionsFile::CSolutionsFile(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::IFileContainer(pMain), OOX::File(pMain) { m_bVisioPages = true; read(oRootPath, oPath); } - OOX::Draw::CSolutionsFile::~CSolutionsFile() + CSolutionsFile::~CSolutionsFile() { } - void OOX::Draw::CSolutionsFile::read(const CPath& oFilePath) + void CSolutionsFile::read(const CPath& oFilePath) { CPath oRootPath; read(oRootPath, oFilePath); } - void OOX::Draw::CSolutionsFile::read(const CPath& oRootPath, const CPath& oFilePath) + void CSolutionsFile::read(const CPath& oRootPath, const CPath& oFilePath) { IFileContainer::Read(oRootPath, oFilePath); @@ -154,7 +154,7 @@ namespace Draw Solutions = oReader; } - void OOX::Draw::CSolutionsFile::write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const + void CSolutionsFile::write(const CPath& oFilePath, const CPath& oDirectory, CContentTypes& oContent) const { NSBinPptxRW::CXmlWriter oXmlWriter; oXmlWriter.WriteString((L"")); @@ -167,19 +167,19 @@ namespace Draw oContent.Registration(type().OverrideType(), oDirectory, oFilePath.GetFilename()); IFileContainer::Write(oFilePath, oDirectory, oContent); } - const OOX::FileType OOX::Draw::CSolutionsFile::type() const + const OOX::FileType CSolutionsFile::type() const { return FileTypes::Solutions; } - const OOX::CPath OOX::Draw::CSolutionsFile::DefaultDirectory() const + const OOX::CPath CSolutionsFile::DefaultDirectory() const { return type().DefaultDirectory(); } - const OOX::CPath OOX::Draw::CSolutionsFile::DefaultFileName() const + const OOX::CPath CSolutionsFile::DefaultFileName() const { return type().DefaultFileName(); } - void OOX::Draw::CSolutionsFile::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) + void CSolutionsFile::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) { smart_ptr rels_old = pReader->GetRels(); pReader->SetRels(dynamic_cast((CSolutionsFile*)this)); @@ -206,7 +206,7 @@ namespace Draw pReader->Seek(end); pReader->SetRels(rels_old); } - void OOX::Draw::CSolutionsFile::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const + void CSolutionsFile::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const { smart_ptr rels_old = pWriter->GetRels(); pWriter->SetRels(dynamic_cast((CSolutionsFile*)this)); @@ -215,7 +215,7 @@ namespace Draw pWriter->SetRels(rels_old); } - void OOX::Draw::CSolutionsFile::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const + void CSolutionsFile::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const { if (Solutions.IsInit()) Solutions->toXmlWriter(pWriter); @@ -382,5 +382,1387 @@ namespace Draw 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 index 4c8738b779..6967b74d41 100644 --- a/OOXML/VsdxFormat/VisioOthers.h +++ b/OOXML/VsdxFormat/VisioOthers.h @@ -81,7 +81,6 @@ namespace OOX virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); virtual void toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const; }; - //------------------------------------------------------------------------------------------------------------------------------ class CSolutionsFile : public OOX::IFileContainer, public OOX::File { @@ -132,5 +131,395 @@ namespace OOX 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 index 459843ace7..934d525192 100644 --- a/OOXML/VsdxFormat/VisioPages.cpp +++ b/OOXML/VsdxFormat/VisioPages.cpp @@ -182,7 +182,7 @@ namespace Draw pWriter->WriteNodeEnd(L"MasterContents"); } - //----------------------------------------------------------------------------------------------------------------------------- +//----------------------------------------------------------------------------------------------------------------------------- CPageFile::CPageFile(OOX::Document* pMain) : OOX::IFileContainer(pMain), OOX::File(pMain) { m_bVisioPages = true; diff --git a/OOXML/VsdxFormat/VisioPages.h b/OOXML/VsdxFormat/VisioPages.h index 58a79abd12..9765fd0edf 100644 --- a/OOXML/VsdxFormat/VisioPages.h +++ b/OOXML/VsdxFormat/VisioPages.h @@ -101,7 +101,6 @@ namespace OOX // from masters nullable_uint ID; nullable_string UniqueID; - }; //--------------------------------------------------------------------------------------------------------------------------------- class CPageSheet : public WritingElementWithChilds<> diff --git a/OOXML/VsdxFormat/Vsdx.cpp b/OOXML/VsdxFormat/Vsdx.cpp index 2f7e3b308d..47c54c97fe 100644 --- a/OOXML/VsdxFormat/Vsdx.cpp +++ b/OOXML/VsdxFormat/Vsdx.cpp @@ -78,215 +78,3 @@ bool OOX::Draw::CVsdx::Write(const CPath& oDirPath, OOX::CContentTypes &oContent return true; } //----------------------------------------------------------------------------------------------------------------------------- -OOX::Draw::CValidation::CValidation(OOX::Document* pMain) : OOX::File(pMain) -{ -} -OOX::Draw::CValidation::CValidation(OOX::Document* pMain, const CPath& uri) : OOX::File(pMain) -{ - read(uri.GetDirectory(), uri); -} -OOX::Draw::CValidation::CValidation(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::File(pMain) -{ - read(oRootPath, oPath); -} -OOX::Draw::CValidation::~CValidation() -{ -} -void OOX::Draw::CValidation::read(const CPath& oFilePath) -{ - CPath oRootPath; - read(oRootPath, oFilePath); -} -void OOX::Draw::CValidation::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"dgm:dataModel" == sName && !oReader.IsEmptyNode()) - //{ - // m_oDataModel = oReader; - //} - //if (false == id_drawing.IsInit() && m_oDataModel.IsInit()) - //{ - // for (size_t i = 0; m_oDataModel->m_oExtLst.IsInit() && (i < m_oDataModel->m_oExtLst->m_arrExt.size()); i++) - // { - // if (m_oDataModel->m_oExtLst->m_arrExt[i]->m_oDataModelExt.IsInit()) - // { - // id_drawing = m_oDataModel->m_oExtLst->m_arrExt[i]->m_oDataModelExt->m_oRelId; - // break; - // } - // } - //} -} -void OOX::Draw::CValidation::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::CValidation::type() const -{ - return FileTypes::Validation; -} -const OOX::CPath OOX::Draw::CValidation::DefaultDirectory() const -{ - return type().DefaultDirectory(); -} -const OOX::CPath OOX::Draw::CValidation::DefaultFileName() const -{ - return type().DefaultFileName(); -} -void OOX::Draw::CValidation::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) -{ - LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; - - while (pReader->GetPos() < end) - { - BYTE _rec = pReader->GetUChar(); - - switch (_rec) - { - case 0: - { - //m_oDataModel.Init(); - //m_oDataModel->fromPPTY(pReader); - - }break; - default: - { - pReader->SkipRecord(); - }break; - } - } - pReader->Seek(end); -} -void OOX::Draw::CValidation::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const -{ - //pWriter->WriteRecord2(0, m_oDataModel); -} -void OOX::Draw::CValidation::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const -{ - //if (m_oDataModel.IsInit()) - // m_oDataModel->toXmlWriter(pWriter); -} -//----------------------------------------------------------------------------------------------------------------------------- -OOX::Draw::CComments::CComments(OOX::Document* pMain) : OOX::File(pMain) -{ -} -OOX::Draw::CComments::CComments(OOX::Document* pMain, const CPath& uri) : OOX::File(pMain) -{ - read(uri.GetDirectory(), uri); -} -OOX::Draw::CComments::CComments(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath) : OOX::File(pMain) -{ - read(oRootPath, oPath); -} -OOX::Draw::CComments::~CComments() -{ -} -void OOX::Draw::CComments::read(const CPath& oFilePath) -{ - CPath oRootPath; - read(oRootPath, oFilePath); -} -void OOX::Draw::CComments::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"dgm:dataModel" == sName && !oReader.IsEmptyNode()) - //{ - // m_oDataModel = oReader; - //} - //if (false == id_drawing.IsInit() && m_oDataModel.IsInit()) - //{ - // for (size_t i = 0; m_oDataModel->m_oExtLst.IsInit() && (i < m_oDataModel->m_oExtLst->m_arrExt.size()); i++) - // { - // if (m_oDataModel->m_oExtLst->m_arrExt[i]->m_oDataModelExt.IsInit()) - // { - // id_drawing = m_oDataModel->m_oExtLst->m_arrExt[i]->m_oDataModelExt->m_oRelId; - // break; - // } - // } - //} -} -void OOX::Draw::CComments::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::CComments::type() const -{ - return FileTypes::Comments; -} -const OOX::CPath OOX::Draw::CComments::DefaultDirectory() const -{ - return type().DefaultDirectory(); -} -const OOX::CPath OOX::Draw::CComments::DefaultFileName() const -{ - return type().DefaultFileName(); -} -void OOX::Draw::CComments::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) -{ - LONG end = pReader->GetPos() + pReader->GetRecordSize() + 4; - - while (pReader->GetPos() < end) - { - BYTE _rec = pReader->GetUChar(); - - switch (_rec) - { - case 0: - { - //m_oDataModel.Init(); - //m_oDataModel->fromPPTY(pReader); - - }break; - default: - { - pReader->SkipRecord(); - }break; - } - } - pReader->Seek(end); -} -void OOX::Draw::CComments::toPPTY(NSBinPptxRW::CBinaryFileWriter* pWriter) const -{ - //pWriter->WriteRecord2(0, m_oDataModel); -} -void OOX::Draw::CComments::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const -{ - //if (m_oDataModel.IsInit()) - // m_oDataModel->toXmlWriter(pWriter); -} -//----------------------------------------------------------------------------------------------------------------------------- diff --git a/OOXML/VsdxFormat/Vsdx.h b/OOXML/VsdxFormat/Vsdx.h index 9923006698..f61ce7de01 100644 --- a/OOXML/VsdxFormat/Vsdx.h +++ b/OOXML/VsdxFormat/Vsdx.h @@ -42,56 +42,7 @@ namespace OOX namespace Draw { class CDocumentFile; -//--------------------------------------------------------------------------------------------------------------------------------- - class CValidation : public OOX::File - { - public: - CValidation(OOX::Document* pMain); - CValidation(OOX::Document* pMain, const CPath& uri); - CValidation(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); - virtual ~CValidation(); - 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; - }; - class CComments : public OOX::File - { - public: - CComments(OOX::Document* pMain); - CComments(OOX::Document* pMain, const CPath& uri); - CComments(OOX::Document* pMain, const CPath& oRootPath, const CPath& oPath); - virtual ~CComments(); - - 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; - - - }; -//--------------------------------------------------------------------------------------------------------------------------------- class CVsdx : public OOX::Document, public OOX::IFileContainer { public: diff --git a/X2tConverter/src/ASCConverters.cpp b/X2tConverter/src/ASCConverters.cpp index 15e3cadebb..4b3ceedfd5 100644 --- a/X2tConverter/src/ASCConverters.cpp +++ b/X2tConverter/src/ASCConverters.cpp @@ -1306,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); } diff --git a/X2tConverter/src/cextracttools.cpp b/X2tConverter/src/cextracttools.cpp index 73ec2c1093..9c5c992841 100644 --- a/X2tConverter/src/cextracttools.cpp +++ b/X2tConverter/src/cextracttools.cpp @@ -510,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; From 2d0bb82f410046d5841ef48789a7901e72750964 Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Sat, 15 Mar 2025 15:01:50 +0300 Subject: [PATCH 101/186] refactoring --- .../SMCustomShape2OOXML/smcustomshapepars.cpp | 116 +++++++----------- .../SMCustomShape2OOXML/smcustomshapepars.h | 2 +- 2 files changed, 46 insertions(+), 72 deletions(-) diff --git a/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.cpp b/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.cpp index 09c3fb17b3..20afdf7f13 100644 --- a/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.cpp +++ b/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.cpp @@ -123,9 +123,9 @@ namespace StarMathCustomShape return m_wsNumber; } //CElementArithmeticOperations - CElementArithmeticOperations::CElementArithmeticOperations():m_enTypeSign(TypeElement::empty),m_pSecondSign(nullptr),m_pFirstValue(nullptr),m_pSecondValue(nullptr),m_uiNumberFormula(1),m_wsNameFormula(L""),m_wsNumberFormula(L"") + 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_wsNameFormula(L""),m_wsNumberFormula(L"") + 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); @@ -166,13 +166,20 @@ namespace StarMathCustomShape 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); - m_wsNumberFormula = SMCustomShapeConversion::ParsFormulaName(wsName,m_wsNameFormula); +// m_wsNumberFormula = SMCustomShapeConversion::ParsFormulaName(wsName,m_wsNameFormula); } if(m_pSecondSign != nullptr) { @@ -193,14 +200,7 @@ namespace StarMathCustomShape SignRecording(pXmlWriter,m_enTypeSign); SignRecording(pXmlWriter,pTemp->GetTypeSign()); pXmlWriter->WriteString(L" "); - if(!wsNameFirstValue.empty()) - pXmlWriter->WriteString(wsNameFirstValue + L" "); - else if(m_pFirstValue != nullptr) - m_pFirstValue->ConversionOOXml(pXmlWriter); - if(!wsNameSecondValue.empty()) - pXmlWriter->WriteString(wsNameSecondValue + L" "); - else if(m_pSecondValue != nullptr) - m_pSecondValue->ConversionOOXml(pXmlWriter); + RecordingTheValuesSign(pXmlWriter,wsNameFirstValue,wsNameSecondValue); if(!wsNameValueSecondSign.empty()) pXmlWriter->WriteString(wsNameValueSecondSign + L" "); else if(pTemp->GetSecondValue() != nullptr) @@ -244,27 +244,13 @@ namespace StarMathCustomShape pXmlWriter->WriteString(L" "); if(bPlusMultiplication) { - if(!wsNameFirstValue.empty()) - pXmlWriter->WriteString(wsNameFirstValue + L" "); - else if(m_pFirstValue != nullptr) - m_pFirstValue->ConversionOOXml(pXmlWriter); - if(!wsNameSecondValue.empty()) - pXmlWriter->WriteString(wsNameSecondValue + L" "); - else if(m_pSecondValue != nullptr) - m_pSecondValue->ConversionOOXml(pXmlWriter); + RecordingTheValuesSign(pXmlWriter,wsNameFirstValue,wsNameSecondValue); pXmlWriter->WriteString(L"1 "); } else if(bMinusDivision) { pXmlWriter->WriteString(L"0 "); - if(!wsNameFirstValue.empty()) - pXmlWriter->WriteString(wsNameFirstValue + L" "); - else if(m_pFirstValue != nullptr) - m_pFirstValue->ConversionOOXml(pXmlWriter); - if(!wsNameSecondValue.empty()) - pXmlWriter->WriteString(wsNameSecondValue + L" "); - else if(m_pSecondValue != nullptr) - m_pSecondValue->ConversionOOXml(pXmlWriter); + RecordingTheValuesSign(pXmlWriter,wsNameFirstValue,wsNameSecondValue); } pXmlWriter->WriteNodeEnd(L"",true,true); } @@ -350,8 +336,7 @@ namespace StarMathCustomShape { if(pElement->GetBaseType() != TypeElement::NumberOrName) { - // m_uiNumberFormula++; - std::wstring wsTempName = m_wsNameFormula + m_wsNumberFormula + L"-" + std::to_wstring(m_uiNumberFormula); + std::wstring wsTempName = GetNameFormula() + L"." + std::to_wstring(m_uiNumberFormula); m_uiNumberFormula++; pElement->ConversionOOXml(pXmlWriter,wsTempName); return pElement->GetNameFormula(); @@ -359,6 +344,21 @@ namespace StarMathCustomShape 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) { @@ -377,33 +377,23 @@ namespace StarMathCustomShape if(iswspace(*itStart)) { if(!wsOneElement.empty()) - { - // std::wcout << wsOneElement << std::endl; return wsOneElement; - } else continue; } else if(!wsOneElement.empty() && (L'+' == *itStart || L'-' == *itStart || L'*' == *itStart || L'/' == *itStart || L',' == *itStart || L'(' == *itStart || L')' == *itStart)) - { - // std::wcout << wsOneElement << std::endl; 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++; - // std::wcout << wsOneElement << std::endl; return wsOneElement; } else wsOneElement.push_back(*itStart); } if(!wsOneElement.empty()) - { - // std::wcout << wsOneElement << std::endl; return wsOneElement; - } else return L""; } @@ -544,10 +534,13 @@ namespace StarMathCustomShape { if(m_pValue == nullptr) return; + if(!wsName.empty()) + SetNameFormula(wsName); + else + SetNameFormula(L"Function"); switch (m_enTypeFunction) { case TypeElement::If: { - SetNameFormula(L"FunctionIf"); std::wstring wsFormula = L"?: "; if(m_pValue->GetBaseType() == TypeElement::Bracket) { @@ -575,18 +568,10 @@ namespace StarMathCustomShape case TypeElement::sqrt: { std::wstring wsFormula; - std::wstring wsNameFormula; if(m_enTypeFunction == TypeElement::abs) - { wsFormula = L"abs "; - wsNameFormula = L"FunctionAbs"; - } else - { wsFormula = L"sqrt "; - wsNameFormula = L"FunctionSqrt"; - } - SetNameFormula(wsNameFormula); if(m_pValue->GetBaseType() == TypeElement::Bracket) { CElementBracket* pBracket = dynamic_cast(m_pValue); @@ -595,24 +580,17 @@ namespace StarMathCustomShape } else ConversionElement(pXmlWriter,m_pValue,wsFormula); - SMCustomShapeConversion::WritingFormulaXml(pXmlWriter,wsNameFormula,wsFormula); + SMCustomShapeConversion::WritingFormulaXml(pXmlWriter,GetNameFormula(),wsFormula); break; } case TypeElement::min: case TypeElement::max: { - std::wstring wsNameFormula; std::wstring wsFormula; if(m_enTypeFunction == TypeElement::max) - { - wsNameFormula = L"FunctionMax"; wsFormula = L"max "; - } else - { - wsNameFormula = L"FunctionMin"; wsFormula = L"min "; - } if(m_pValue->GetBaseType() == TypeElement::Bracket) { CElementBracket* pBracket = dynamic_cast(m_pValue); @@ -623,40 +601,35 @@ namespace StarMathCustomShape { if(i - 1 >= 0) ConversionElement(pXmlWriter,pElements[i-1],wsFormula); - if(i + 1 <= pElements.size()) + if(i + 1 <= pElements.size() && pElements[i+1]->GetBaseType() != TypeElement::comma) ConversionElement(pXmlWriter,pElements[i+1],wsFormula); i = pElements.size(); } } - SMCustomShapeConversion::WritingFormulaXml(pXmlWriter,wsNameFormula,wsFormula); + SMCustomShapeConversion::WritingFormulaXml(pXmlWriter,GetNameFormula(),wsFormula); } break; } case TypeElement::sin: case TypeElement::cos: { - std::wstring wsNameFormula; std::wstring wsFormula; if(m_enTypeFunction == TypeElement::sin) - { - wsNameFormula = L"FunctionSin"; wsFormula = L"sin 1 "; - } else - { - wsNameFormula = L"FunctionCos"; wsFormula = L"cos 1 "; - } if(m_pValue->GetBaseType() == TypeElement::Bracket) { CElementBracket* pBracket = dynamic_cast(m_pValue); std::vector arVec = pBracket->GetVector(); - if(arVec[0] != nullptr) + if(arVec[0] != nullptr && arVec[0]->GetBaseType() != TypeElement::comma) ConversionElement(pXmlWriter,arVec[0],wsFormula); } - else + else if(m_pValue->GetBaseType() != TypeElement::comma) ConversionElement(pXmlWriter,m_pValue,wsFormula); - SMCustomShapeConversion::WritingFormulaXml(pXmlWriter,wsNameFormula,wsFormula); + else + wsFormula += L"1 "; + SMCustomShapeConversion::WritingFormulaXml(pXmlWriter,GetNameFormula(),wsFormula); } default: break; @@ -673,7 +646,8 @@ namespace StarMathCustomShape } else { - pElement->ConversionOOXml(pXmlWriter); + std::wstring wsNewNameFormula = GetNameFormula() + L".1"; + pElement->ConversionOOXml(pXmlWriter,wsNewNameFormula); wsFormula += pElement->GetNameFormula() + L" "; } } @@ -691,7 +665,7 @@ namespace StarMathCustomShape {} //SMCustomShapeConversion SMCustomShapeConversion::SMCustomShapeConversion():m_pXmlWriter(nullptr) - {}; + {} SMCustomShapeConversion::~SMCustomShapeConversion() { delete m_pXmlWriter; @@ -737,7 +711,7 @@ namespace StarMathCustomShape std::wstring wsTempNumber; for(wchar_t wcElement: wsFormulaName) { - if(iswdigit(wcElement) && L'-' == wcElement) + if(iswdigit(wcElement) && (L'-' == wcElement || L'.' == wcElement)) wsTempNumber += wcElement; else wsName += wcElement; diff --git a/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.h b/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.h index 5eb41795d5..e9784f5b70 100644 --- a/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.h +++ b/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.h @@ -128,13 +128,13 @@ namespace StarMathCustomShape 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; - std::wstring m_wsNameFormula,m_wsNumberFormula; }; class CElementBracket: public CElement { From 2ab94263f2e2f91f448cfea05cf3e2af0450d33d Mon Sep 17 00:00:00 2001 From: Mikhail Lobotskiy Date: Mon, 17 Mar 2025 15:29:49 +0400 Subject: [PATCH 102/186] Remove `lib` directory --- .../doctrenderer/docbuilder.python/src/docbuilder.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py index a09d1f4afd..bf8f6186a0 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py @@ -609,14 +609,14 @@ class FileTypes: PNG = _IMAGE_MASK + 0x0005 BMP = _IMAGE_MASK + 0x0008 -builder_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'lib') +builder_path = os.path.dirname(os.path.realpath(__file__)) _loadLibrary(builder_path) CDocBuilder.Initialize(builder_path) def registerLibrary(license_path): - docbuilder_bin = os.path.dirname(os.path.realpath(__file__)) + "/lib/docbuilder" + 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) + return subprocess.call([docbuilder_bin, "-register", license_path], stderr=subprocess.STDOUT, shell=True) atexit.register(CDocBuilder.Dispose) From 72ee82211d317069bf2dfdb3226d2c2ad8aa128d Mon Sep 17 00:00:00 2001 From: Mikhail Lobotskiy Date: Mon, 17 Mar 2025 15:36:03 +0400 Subject: [PATCH 103/186] Add note --- DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py | 1 + 1 file changed, 1 insertion(+) diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py index bf8f6186a0..b097c55a2e 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py @@ -609,6 +609,7 @@ 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) From 4e7ccd2506bf3a75d8b0a05372d98cfb6b50e74b Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 17 Mar 2025 18:09:07 +0300 Subject: [PATCH 104/186] Add nStartRefID --- PdfFile/PdfEditor.cpp | 10 +- PdfFile/PdfReader.cpp | 164 +++++++++++++++++++-------------- PdfFile/PdfReader.h | 3 +- PdfFile/SrcReader/PdfAnnot.cpp | 103 ++++++++++----------- PdfFile/SrcReader/PdfAnnot.h | 47 +++++----- PdfFile/test/test.cpp | 5 - 6 files changed, 176 insertions(+), 156 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index aaea217558..cfd562bc3f 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -403,7 +403,7 @@ HRESULT _ChangePassword(const std::wstring& wsPath, const std::wstring& wsPasswo { if (!_pReader || !_pWriter) return S_FALSE; - PDFDoc* pPDFDocument = _pReader->GetFirstPDFDocument(); + PDFDoc* pPDFDocument = _pReader->GetPDFDocument(0); if (!pPDFDocument) return S_FALSE; XRef* xref = pPDFDocument->getXRef(); @@ -659,7 +659,7 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa m_nError = 0; m_nMode = Mode::Unknown; - PDFDoc* pPDFDocument = m_pReader->GetFirstPDFDocument(); + PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(0); if (!pPDFDocument) { m_nError = 1; @@ -680,7 +680,7 @@ bool CPdfEditor::IncrementalUpdates() return true; m_nMode = Mode::WriteAppend; - PDFDoc* pPDFDocument = m_pReader->GetFirstPDFDocument(); + PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(0); XRef* xref = pPDFDocument->getXRef(); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); @@ -910,7 +910,7 @@ void CPdfEditor::Close() return; } - PDFDoc* pPDFDocument = m_pReader->GetFirstPDFDocument(); + PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(0); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); XRef* xref = pPDFDocument->getXRef(); @@ -2021,7 +2021,7 @@ bool CPdfEditor::EditWidgets(IAdvancedCommand* pCommand) return false; CWidgetsInfo* pFieldInfo = (CWidgetsInfo*)pCommand; - PDFDoc* pPDFDocument = m_pReader->GetFirstPDFDocument(); + PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(0); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); std::vector arrParents = pFieldInfo->GetParents(); diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 25daeefb0c..c36ba3e5eb 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -412,23 +412,26 @@ void CPdfReader::SetParams(COfficeDrawingPageParams* pParams) globalParams->setDrawAnnotations(bDraw); } -int CPdfReader::GetPageIndex(int nPageIndex, PDFDoc** pDoc, PdfReader::CPdfFontList** pFontList) +int CPdfReader::GetPageIndex(int nAbsPageIndex, PDFDoc** _pDoc, PdfReader::CPdfFontList** pFontList, int* nStartRefID) { int nTotalPages = 0; + nStartRefID = 0; for (CPdfReaderContext* pPDFContext : m_vPDFContext) { if (!pPDFContext || !pPDFContext->m_pDocument) continue; + PDFDoc* pDoc = pPDFContext->m_pDocument; - int nPages = pPDFContext->m_pDocument->getNumPages(); - if (nPageIndex < nTotalPages + nPages) + int nPages = pDoc->getNumPages(); + if (nAbsPageIndex < nTotalPages + nPages) { - if (pDoc) - *pDoc = pPDFContext->m_pDocument; + if (_pDoc) + *_pDoc = pDoc; if (pFontList) *pFontList = pPDFContext->m_pFontList; - return nPageIndex - nTotalPages + 1; + return nAbsPageIndex - nTotalPages + 1; } + nStartRefID += pDoc->getXRef()->getNumObjects(); nTotalPages += nPages; } return -1; @@ -486,14 +489,14 @@ int CPdfReader::GetRotate(int _nPageIndex) } int CPdfReader::GetMaxRefID() { - int nMaxRefID = 0; + int nSumRefID = 0; for (CPdfReaderContext* pPDFContext : m_vPDFContext) { if (!pPDFContext || !pPDFContext->m_pDocument || !pPDFContext->m_pDocument->getXRef()) continue; - nMaxRefID = std::max(nMaxRefID, pPDFContext->m_pDocument->getXRef()->getNumObjects()); + nSumRefID += pPDFContext->m_pDocument->getXRef()->getNumObjects(); } - return nMaxRefID; + return nSumRefID; } int CPdfReader::GetNumPages() { @@ -664,16 +667,6 @@ std::wstring CPdfReader::ToXml(const std::wstring& wsFilePath, bool isPrintStrea return wsXml; } -PDFDoc* CPdfReader::GetFirstPDFDocument() -{ - if (m_vPDFContext.empty()) - return NULL; - - CPdfReaderContext* pPDFContext = m_vPDFContext.front(); - if (pPDFContext) - return pPDFContext->m_pDocument; - return NULL; -} PDFDoc* CPdfReader::GetLastPDFDocument() { if (m_vPDFContext.empty()) @@ -686,9 +679,6 @@ PDFDoc* CPdfReader::GetLastPDFDocument() } PDFDoc* CPdfReader::GetPDFDocument(int PDFIndex) { - if (m_vPDFContext.empty()) - return NULL; - if (PDFIndex >= 0 && PDFIndex < m_vPDFContext.size()) return m_vPDFContext[PDFIndex]->m_pDocument; return NULL; @@ -862,7 +852,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) @@ -901,7 +891,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()); @@ -917,7 +907,7 @@ 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(); } @@ -925,26 +915,45 @@ BYTE* CPdfReader::GetStructure() { if (m_vPDFContext.empty()) return NULL; - CPdfReaderContext* pPDFContext = m_vPDFContext.front(); - if (!pPDFContext || !pPDFContext->m_pDocument) - return NULL; - - PDFDoc* pDoc = pPDFContext->m_pDocument; - Outline* pOutline = pDoc->getOutline(); - if (!pOutline) - return NULL; - GList* pList = pOutline->getItems(); - if (!pList) - 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(pDoc, pOutlineItem, oRes, 1); + PDFDoc* pDoc = m_vPDFContext[iPDF]->m_pDocument; + if (!pDoc->getOutline()) + { + nStartPage += pDoc->getNumPages(); + continue; + } + + Outline* pOutline = pDoc->getOutline(); + 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(); @@ -953,6 +962,7 @@ BYTE* CPdfReader::GetStructure() } BYTE* CPdfReader::GetLinks(int _nPageIndex) { + // TODO Links должны стать частью Annots PDFDoc* pDoc = NULL; int nPageIndex = GetPageIndex(_nPageIndex, &pDoc); if (nPageIndex < 0 || !pDoc || !pDoc->getCatalog()) @@ -1089,19 +1099,25 @@ BYTE* CPdfReader::GetWidgets() oRes.SkipLen(); int nStartPage = 0; + int nStartRefID = 0; for (CPdfReaderContext* pPDFContext : m_vPDFContext) { PDFDoc* pDoc = pPDFContext->m_pDocument; if (!pDoc || !pDoc->getCatalog()) continue; if (!pDoc->getCatalog()->getForm() || !pDoc->getXRef()) + { + nStartPage += pDoc->getNumPages(); + nStartRefID += pDoc->getXRef()->getNumObjects(); continue; + } - PdfReader::CAnnots* pAnnots = new PdfReader::CAnnots(pDoc, m_pFontManager, pPDFContext->m_pFontList, nStartPage); + PdfReader::CAnnots* pAnnots = new PdfReader::CAnnots(pDoc, m_pFontManager, pPDFContext->m_pFontList, nStartPage, nStartRefID); if (pAnnots) pAnnots->ToWASM(oRes); RELEASEOBJECT(pAnnots); nStartPage += pDoc->getNumPages(); + nStartRefID += pDoc->getXRef()->getNumObjects(); } oRes.WriteLen(); @@ -1231,7 +1247,8 @@ BYTE* CPdfReader::GetAPWidget(int nRasterW, int nRasterH, int nBackgroundColor, { PDFDoc* pDoc = NULL; PdfReader::CPdfFontList* pFontList = NULL; - int nPageIndex = GetPageIndex(_nPageIndex, &pDoc, &pFontList); + int nStartRefID = 0; + int nPageIndex = GetPageIndex(_nPageIndex, &pDoc, &pFontList, &nStartRefID); if (nPageIndex < 0 || !pDoc || !pFontList || !pDoc->getCatalog()) return NULL; @@ -1246,14 +1263,14 @@ BYTE* CPdfReader::GetAPWidget(int nRasterW, int nRasterH, int nBackgroundColor, { AcroFormField* pField = pAcroForms->getField(i); Object oRef; - if (pField->getPageNum() != nPageIndex || (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(pDoc, m_pFontManager, 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); @@ -1267,7 +1284,9 @@ BYTE* CPdfReader::GetAPWidget(int nRasterW, int nRasterH, int nBackgroundColor, BYTE* CPdfReader::GetButtonIcon(int nBackgroundColor, int _nPageIndex, bool bBase64, int nButtonWidget, const char* sIconView) { PDFDoc* pDoc = NULL; - int nPageIndex = GetPageIndex(_nPageIndex, &pDoc); + PdfReader::CPdfFontList* pFontList = NULL; + int nStartRefID = 0; + int nPageIndex = GetPageIndex(_nPageIndex, &pDoc, &pFontList, &nStartRefID); if (nPageIndex < 0 || !pDoc || !pDoc->getCatalog()) return NULL; @@ -1282,8 +1301,14 @@ BYTE* CPdfReader::GetButtonIcon(int nBackgroundColor, int _nPageIndex, bool bBas for (int i = 0, nNum = pAcroForms->getNumFields(); i < nNum; ++i) { AcroFormField* pField = pAcroForms->getField(i); - if (pField->getPageNum() != nPageIndex || 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()) @@ -1313,7 +1338,7 @@ BYTE* CPdfReader::GetButtonIcon(int nBackgroundColor, int _nPageIndex, bool bBas Object oFieldRef; pField->getFieldRef(&oFieldRef); // Номер аннотации для сопоставления с AP - oRes.AddInt(oFieldRef.getRefNum()); + oRes.AddInt(oFieldRef.getRefNum() + nStartRefID); oFieldRef.free(); // Количество иконок 1-3 @@ -1324,7 +1349,8 @@ BYTE* CPdfReader::GetButtonIcon(int nBackgroundColor, int _nPageIndex, bool bBas // Получение единственного 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()) + 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; @@ -1344,7 +1370,7 @@ BYTE* CPdfReader::GetButtonIcon(int nBackgroundColor, int _nPageIndex, bool bBas 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()) @@ -1541,7 +1567,7 @@ BYTE* CPdfReader::GetButtonIcon(int nBackgroundColor, int _nPageIndex, bool bBas oRes.ClearWithoutAttack(); return bRes; } -int GetPageAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, PdfReader::CPdfFontList *pFontList, NSWasm::CData& oRes, int nPageIndex, int nStartPage) +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); if (!pPage) @@ -1575,7 +1601,7 @@ int GetPageAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, PdfReader 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") { @@ -1583,48 +1609,48 @@ int GetPageAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, PdfReader } 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(); @@ -1653,7 +1679,8 @@ BYTE* CPdfReader::GetAnnots(int _nPageIndex) { PDFDoc* pDoc = NULL; PdfReader::CPdfFontList* pFontList = NULL; - int nPageIndex = GetPageIndex(_nPageIndex, &pDoc, &pFontList); + int nStartRefID = 0; + int nPageIndex = GetPageIndex(_nPageIndex, &pDoc, &pFontList, &nStartRefID); if (nPageIndex < 0 || !pDoc || !pFontList || !pDoc->getCatalog()) return NULL; @@ -1661,13 +1688,14 @@ BYTE* CPdfReader::GetAnnots(int _nPageIndex) int nPosAnnots = oRes.GetSize(); oRes.AddInt(nAnnots); - nAnnots = GetPageAnnots(pDoc, m_pFontManager, pFontList, oRes, nPageIndex, _nPageIndex + 1 - nPageIndex); + nAnnots = GetPageAnnots(pDoc, m_pFontManager, pFontList, oRes, nPageIndex, _nPageIndex + 1 - nPageIndex, nStartRefID); oRes.AddInt(nAnnots, nPosAnnots); } else { int nStartPage = 0; + int nStartRefID = 0; for (CPdfReaderContext* pPDFContext : m_vPDFContext) { PDFDoc* pDoc = pPDFContext->m_pDocument; @@ -1678,10 +1706,11 @@ BYTE* CPdfReader::GetAnnots(int _nPageIndex) oRes.AddInt(nAnnots); for (int nPage = 1, nPages = pDoc->getNumPages(); nPage <= nPages; ++nPage) - nAnnots += GetPageAnnots(pDoc, m_pFontManager, pPDFContext->m_pFontList, oRes, nPage, nStartPage); + nAnnots += GetPageAnnots(pDoc, m_pFontManager, pPDFContext->m_pFontList, oRes, nPage, nStartPage, nStartRefID); oRes.AddInt(nAnnots, nPosAnnots); nStartPage += pDoc->getNumPages(); + nStartRefID += pDoc->getXRef()->getNumObjects(); } } @@ -1694,7 +1723,8 @@ BYTE* CPdfReader::GetAPAnnots(int nRasterW, int nRasterH, int nBackgroundColor, { PDFDoc* pDoc = NULL; PdfReader::CPdfFontList* pFontList = NULL; - int nPageIndex = GetPageIndex(_nPageIndex, &pDoc, &pFontList); + int nStartRefID = 0; + int nPageIndex = GetPageIndex(_nPageIndex, &pDoc, &pFontList, &nStartRefID); if (nPageIndex < 0 || !pDoc || !pFontList || !pDoc->getCatalog()) return NULL; @@ -1712,7 +1742,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; @@ -1731,7 +1761,7 @@ BYTE* CPdfReader::GetAPAnnots(int nRasterW, int nRasterH, int nBackgroundColor, continue; } - PdfReader::CAnnotAP* pAP = new PdfReader::CAnnotAP(pDoc, m_pFontManager, pFontList, nRasterW, nRasterH, nBackgroundColor, nPageIndex - 1, sView, &oAnnotRef); + PdfReader::CAnnotAP* pAP = new PdfReader::CAnnotAP(pDoc, m_pFontManager, pFontList, nRasterW, nRasterH, nBackgroundColor, nPageIndex - 1, sView, &oAnnotRef, nStartRefID); if (pAP) pAP->ToWASM(oRes); RELEASEOBJECT(pAP); diff --git a/PdfFile/PdfReader.h b/PdfFile/PdfReader.h index 1d3a1b86d7..360437a3ad 100644 --- a/PdfFile/PdfReader.h +++ b/PdfFile/PdfReader.h @@ -86,10 +86,9 @@ public: void ChangeLength(DWORD nLength) { m_nFileLength = nLength; } NSFonts::IFontManager* GetFontManager() { return m_pFontManager; } - PDFDoc* GetFirstPDFDocument(); PDFDoc* GetLastPDFDocument(); PDFDoc* GetPDFDocument(int PDFIndex); - int GetPageIndex(int nPageIndex, PDFDoc** pDoc = NULL, PdfReader::CPdfFontList** pFontList = NULL); + int GetPageIndex(int nPageIndex, PDFDoc** pDoc = NULL, PdfReader::CPdfFontList** pFontList = NULL, int* nStartRefID = NULL); BYTE* GetStructure(); BYTE* GetLinks(int nPageIndex); diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 9673fa7482..f1ccb6c130 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -1060,7 +1060,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; @@ -1225,7 +1225,7 @@ CAnnotWidgetBtn::CAnnotWidgetBtn(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot } 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; @@ -1255,7 +1255,7 @@ CAnnotWidgetTx::CAnnotWidgetTx(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnotWi 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; @@ -1360,7 +1360,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 +1375,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(); @@ -1494,7 +1494,7 @@ CAnnotWidget::CAnnotWidget(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot(pdfDo // 17 - Родитель - Parent if (oField.dictLookupNF("Parent", &oObj)->isRef()) { - m_unRefNumParent = oObj.getRefNum(); + m_unRefNumParent = oObj.getRefNum() + nStartRefID; m_unFlags |= (1 << 17); } oObj.free(); @@ -1656,7 +1656,7 @@ void CAnnotWidget::SetButtonFont(PDFDoc* pdfDoc, AcroFormField* pField, NSFonts: // 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; @@ -1673,7 +1673,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(); @@ -1683,7 +1683,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(); @@ -1749,7 +1749,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(); @@ -1785,7 +1785,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(); @@ -1893,7 +1893,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(); @@ -1933,7 +1933,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(); @@ -1980,7 +1980,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(); @@ -2056,7 +2056,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(); @@ -2197,7 +2197,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(); @@ -2233,7 +2233,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; @@ -2358,7 +2358,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(); @@ -2478,7 +2478,7 @@ CAnnotStamp::CAnnotStamp(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex) : CA // Annots //------------------------------------------------------------------------ -CAnnots::CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, int nStartPage) +CAnnots::CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, int nStartPage, int nStartRefID) { Object oObj1, oObj2; XRef* xref = pdfDoc->getXRef(); @@ -2491,7 +2491,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(); } } @@ -2511,7 +2511,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; @@ -2520,7 +2520,7 @@ CAnnots::CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontLi // Родители Object oParentRefObj; if (oField.dictLookupNF("Parent", &oParentRefObj)->isRef()) - getParents(xref, &oParentRefObj); + getParents(xref, &oParentRefObj, nStartRefID); oParentRefObj.free(); oField.free(); oFieldRef.free(); @@ -2532,7 +2532,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: @@ -2540,18 +2540,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: @@ -2575,10 +2575,10 @@ 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(XRef* xref, 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()) + 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; @@ -2590,7 +2590,7 @@ void CAnnots::getParents(XRef* xref, Object* oFieldRef) return; } - pAnnotParent->unRefNum = oFieldRef->getRefNum(); + pAnnotParent->unRefNum = oFieldRef->getRefNum() + nStartRefID; Object oObj; if (oField.dictLookup("T", &oObj)->isString()) @@ -2681,8 +2681,8 @@ void CAnnots::getParents(XRef* xref, Object* oFieldRef) if (oField.dictLookupNF("Parent", &oParentRefObj)->isRef()) { pAnnotParent->unFlags |= (1 << 4); - pAnnotParent->unRefNumParent = oParentRefObj.getRefNum(); - getParents(xref, &oParentRefObj); + pAnnotParent->unRefNumParent = oParentRefObj.getRefNum() + nStartRefID; + getParents(xref, &oParentRefObj, nStartRefID); } oParentRefObj.free(); @@ -2693,7 +2693,7 @@ void CAnnots::getParents(XRef* xref, Object* oFieldRef) // 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; @@ -2705,7 +2705,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 @@ -2737,7 +2737,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(); @@ -2915,7 +2915,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; @@ -2924,7 +2924,7 @@ CAnnot::CAnnot(PDFDoc* pdfDoc, AcroFormField* pField) Object oObj; pField->getFieldRef(&oObj); - m_unRefNum = oObj.getRefNum(); + m_unRefNum = oObj.getRefNum() + nStartRefID; oObj.free(); // Флаг аннотации - F @@ -3037,7 +3037,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; @@ -3049,7 +3049,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()) @@ -3188,7 +3188,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; @@ -3201,7 +3201,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); } @@ -3209,7 +3217,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; @@ -3224,7 +3232,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); @@ -3312,17 +3320,6 @@ void CAnnotAP::Init(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFon 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); -} void CAnnotAP::Init(Object* oAnnot) { Object oObj, oObj2; diff --git a/PdfFile/SrcReader/PdfAnnot.h b/PdfFile/SrcReader/PdfAnnot.h index ae2e0409cb..36cbb35f07 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); @@ -135,7 +135,6 @@ private: 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); @@ -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; @@ -222,7 +221,7 @@ public: void SetButtonFont(PDFDoc* pdfDoc, AcroFormField* pField, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList); 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; @@ -254,7 +253,7 @@ private: class CAnnotWidgetBtn final : public CAnnotWidget { public: - CAnnotWidgetBtn(PDFDoc* pdfDoc, AcroFormField* pField); + CAnnotWidgetBtn(PDFDoc* pdfDoc, AcroFormField* pField, int nStartRefID); void ToWASM(NSWasm::CData& oRes) override; private: @@ -274,7 +273,7 @@ private: class CAnnotWidgetTx final : public CAnnotWidget { public: - CAnnotWidgetTx(PDFDoc* pdfDoc, AcroFormField* pField); + CAnnotWidgetTx(PDFDoc* pdfDoc, AcroFormField* pField, int nStartRefID); void ToWASM(NSWasm::CData& oRes) override; private: @@ -286,7 +285,7 @@ private: class CAnnotWidgetCh final : public CAnnotWidget { public: - CAnnotWidgetCh(PDFDoc* pdfDoc, AcroFormField* pField); + CAnnotWidgetCh(PDFDoc* pdfDoc, AcroFormField* pField, int nStartRefID); void ToWASM(NSWasm::CData& oRes) override; private: @@ -300,7 +299,7 @@ private: class CAnnotWidgetSig final : public CAnnotWidget { public: - CAnnotWidgetSig(PDFDoc* pdfDoc, AcroFormField* pField); + CAnnotWidgetSig(PDFDoc* pdfDoc, AcroFormField* pField, int nStartRefID); void ToWASM(NSWasm::CData& oRes) override; }; @@ -312,7 +311,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; @@ -349,7 +348,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; @@ -373,7 +372,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: @@ -389,7 +388,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; @@ -404,7 +403,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; @@ -428,7 +427,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; @@ -444,7 +443,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; @@ -461,7 +460,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; @@ -481,7 +480,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; @@ -503,7 +502,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; @@ -519,7 +518,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; @@ -575,7 +574,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: @@ -591,7 +590,7 @@ private: class CAnnots { public: - CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, int nStartPage); + CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontList *pFontList, int nStartPage, int nStartRefID); ~CAnnots(); void ToWASM(NSWasm::CData& oRes); @@ -619,7 +618,7 @@ private: std::string sDV; }; - void getParents(XRef* xref, Object* oFieldRef); + void getParents(XRef* xref, Object* oFieldRef, int nStartRefID); std::vector m_arrCO; // Порядок вычислений - CO std::vector m_arrParents; // Родительские Fields diff --git a/PdfFile/test/test.cpp b/PdfFile/test/test.cpp index 5f642d7c59..1eb98dc28c 100644 --- a/PdfFile/test/test.cpp +++ b/PdfFile/test/test.cpp @@ -367,11 +367,6 @@ TEST_F(CPdfFileTest, MergePdf) RELEASEARRAYOBJECTS(pFile); } -TEST_F(CPdfFileTest, CopyAnotherPdf) -{ - GTEST_SKIP(); -} - TEST_F(CPdfFileTest, EditPdf) { GTEST_SKIP(); From 49da36637db137c43cfcec7a83e8df8d908a5033 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 18 Mar 2025 11:49:43 +0300 Subject: [PATCH 105/186] Fix unique ID objects --- PdfFile/SrcReader/PdfAnnot.cpp | 45 ++++++++++++---------------------- 1 file changed, 15 insertions(+), 30 deletions(-) diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index f1ccb6c130..9ad81098fb 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; } @@ -1330,8 +1324,7 @@ CAnnotWidgetCh::CAnnotWidgetCh(PDFDoc* pdfDoc, AcroFormField* pField, int nStart 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()); @@ -2330,21 +2323,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(); @@ -2366,9 +2354,7 @@ CAnnotStamp::CAnnotStamp(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int // Иконка - Name if (oAnnot.dictLookup("Name", &oObj)->isName()) - { m_sName = oObj.getName(); - } oObj.free(); m_dRotate = 0; @@ -2391,8 +2377,8 @@ CAnnotStamp::CAnnotStamp(PDFDoc* pdfDoc, Object* oAnnotRef, int nPageIndex, int oObj1.free(); } } - oObj.free(); + if (oObj2.streamGetDict()->lookup("Matrix", &oObj)->isArray() && oObj.arrayGetLength() == 6) { for (int i = 0; i < 6; ++i) @@ -3260,13 +3246,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; @@ -3314,11 +3300,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; + m_dRy1 = (pdfDoc->getPageCropHeight(nPageIndex) - m_dy2 + m_dCropY) * m_dHScale - 1; } void CAnnotAP::Init(Object* oAnnot) { @@ -3435,7 +3421,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) From df0528c69f59425d83839b5e5a44fd602c05e573 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 18 Mar 2025 12:35:52 +0300 Subject: [PATCH 106/186] Fix nStartRefID --- .../graphics/pro/js/wasm/js/drawingfile.js | 21 +++++++---------- .../pro/js/wasm/src/drawingfile_test.cpp | 23 +++++++++++-------- PdfFile/PdfReader.cpp | 6 +++-- 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js index 80ab962e13..1e1b882ddb 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js @@ -1192,19 +1192,17 @@ CFile.prototype["getInteractiveFormsInfo"] = function() let reader = ptr.getReader(); if (!reader) return {}; - let arrRes = []; - + let res = {}; while (reader.isValid()) { - let res = {}; let k = reader.readInt(); - if (k > 0) + 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) + if (k > 0 && res["Parents"] == undefined) res["Parents"] = []; for (let i = 0; i < k; ++i) { @@ -1243,8 +1241,9 @@ CFile.prototype["getInteractiveFormsInfo"] = function() res["Parents"].push(rec); } - res["Fields"] = []; k = reader.readInt(); + if (k > 0 && res["Fields"] == undefined) + res["Fields"] = []; for (let q = 0; reader.isValid() && q < k; ++q) { let rec = {}; @@ -1258,12 +1257,10 @@ CFile.prototype["getInteractiveFormsInfo"] = function() res["Fields"].push(rec); } - - arrRes.push(res); } ptr.free(); - return arrRes; + return res; }; // optional nWidget - rec["AP"]["i"] @@ -1382,10 +1379,9 @@ CFile.prototype["getAnnotationsInfo"] = function(pageIndex) if (!reader) return []; - let arrRes = []; + let res = []; while (reader.isValid()) { - let res = []; let n = reader.readInt(); for (let i = 0; i < n; ++i) { @@ -1403,11 +1399,10 @@ CFile.prototype["getAnnotationsInfo"] = function(pageIndex) readAnnotType(reader, rec, reader.readDouble, reader.readDouble2, reader.readString); res.push(rec); } - arrRes.push(res); } ptr.free(); - return arrRes; + return res; }; // optional nAnnot ... // optional sView ... diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp index a71df98d4e..a43ac82a21 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp @@ -956,19 +956,22 @@ int main(int argc, char* argv[]) BYTE* pSplitPages = NULL; if (true) { - std::vector arrPages = { 0, 1 }; - pSplitPages = SplitPages(pGrFile, arrPages.data(), arrPages.size()); - if (pSplitPages) + std::vector arrPages = { 0 }; + for (int i = 0; i < 3; i++) { - int nLength = READ_INT(pSplitPages); + pSplitPages = SplitPages(pGrFile, arrPages.data(), arrPages.size()); + if (pSplitPages) + { + int nLength = READ_INT(pSplitPages); - NSFile::CFileBinary oFile; - if (oFile.CreateFileW(NSFile::GetProcessDirectory() + L"/test2.pdf")) - oFile.WriteFile(pSplitPages + 4, nLength - 4); - oFile.CloseFile(); + 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) - RELEASEARRAYOBJECTS(pSplitPages); + if (MergePages(pGrFile, pSplitPages + 4, nLength - 4) == 0) + RELEASEARRAYOBJECTS(pSplitPages); + } } } diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index c36ba3e5eb..a1cafa426f 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -415,7 +415,8 @@ void CPdfReader::SetParams(COfficeDrawingPageParams* pParams) int CPdfReader::GetPageIndex(int nAbsPageIndex, PDFDoc** _pDoc, PdfReader::CPdfFontList** pFontList, int* nStartRefID) { int nTotalPages = 0; - nStartRefID = 0; + if (nStartRefID) + *nStartRefID = 0; for (CPdfReaderContext* pPDFContext : m_vPDFContext) { if (!pPDFContext || !pPDFContext->m_pDocument) @@ -431,7 +432,8 @@ int CPdfReader::GetPageIndex(int nAbsPageIndex, PDFDoc** _pDoc, PdfReader::CPdfF *pFontList = pPDFContext->m_pFontList; return nAbsPageIndex - nTotalPages + 1; } - nStartRefID += pDoc->getXRef()->getNumObjects(); + if (nStartRefID) + *nStartRefID += pDoc->getXRef()->getNumObjects(); nTotalPages += nPages; } return -1; From 1181cb222de521de49f84b442cbf950f49858cd5 Mon Sep 17 00:00:00 2001 From: "Oleg.Korshul" Date: Tue, 18 Mar 2025 13:15:55 +0300 Subject: [PATCH 107/186] Fix memory bug --- X2tConverter/src/run.h | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) 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, From d620a53cd01cfd63faf09167601b624874278cd1 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 18 Mar 2025 13:32:06 +0300 Subject: [PATCH 108/186] Fix drawingfile --- DesktopEditor/graphics/pro/js/wasm/js/drawingfile_wasm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_wasm.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_wasm.js index d17d66d4b4..e3186f8f51 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_wasm.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_wasm.js @@ -135,7 +135,7 @@ CFile.prototype._MergePages = function(buffer) if (!buffer) return false; - let data = (undefined !== buf.byteLength) ? new Uint8Array(buffer) : buffer; + let data = (undefined !== buffer.byteLength) ? new Uint8Array(buffer) : buffer; let stream2 = Module["_malloc"](data.length); Module["HEAP8"].set(data, stream2); From e100f594d7510897de7f75ab8d12c4d148f8d7f8 Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Tue, 18 Mar 2025 18:12:52 +0300 Subject: [PATCH 109/186] fix bug #73582 --- .../Sheets/Common/BinReaderWriterDefines.h | 5 +++- OOXML/Binary/Sheets/Reader/BinaryWriter.cpp | 4 ++-- OOXML/Binary/Sheets/Writer/BinaryReader.cpp | 23 +++++++++++++++++-- .../Worksheets/WorksheetChildOther.cpp | 2 +- 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h b/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h index 1b01b39012..f22c30cc1b 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, + PivotCachesTmp = 107 };} namespace c_oSerWorkbookProtection {enum c_oSerWorkbookProtection{ AlgorithmName = 0, @@ -456,6 +457,8 @@ namespace BinXlsxRW TimelinesList = 48, Timelines = 49, Timeline = 50, + PivotTableTmp = 126, + };} namespace c_oSerWorksheetProtection {enum c_oSerWorksheetPropTypes diff --git a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp index 6b6534fb16..36f6195f09 100644 --- a/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp +++ b/OOXML/Binary/Sheets/Reader/BinaryWriter.cpp @@ -2152,7 +2152,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()) { @@ -4772,7 +4772,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); diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index f2b4fa8c9c..c90072bc20 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp @@ -2189,7 +2189,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""); @@ -4621,7 +4622,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(); diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 1de30226d1..670dfd1e7e 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -3632,7 +3632,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); From 9390761867b644c898ff2f60e38619da4fa0f224 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 19 Mar 2025 13:10:50 +0600 Subject: [PATCH 110/186] fix bug #73587 --- OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 1de30226d1..2a3a2db385 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" @@ -3632,7 +3632,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); From 6a4ba5ec8d69e6ed31fc2bbd93d333c83fecb770 Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Wed, 19 Mar 2025 10:39:55 +0300 Subject: [PATCH 111/186] fix bug #73554 --- .../Sheets/Common/BinReaderWriterDefines.h | 12 +- OOXML/Binary/Sheets/Reader/BinaryWriter.cpp | 60 +- OOXML/Binary/Sheets/Reader/BinaryWriter.h | 2 + OOXML/Binary/Sheets/Writer/BinaryReader.cpp | 52 ++ OOXML/Binary/Sheets/Writer/BinaryReader.h | 1 + OOXML/Common/SimpleTypes_Spreadsheet.cpp | 20 + OOXML/Common/SimpleTypes_Spreadsheet.h | 7 + OOXML/DocxFormat/CustomXml.h | 2 - OOXML/DocxFormat/WritingElement.h | 12 +- .../Linux/DocxFormatLib/DocxFormatLib.pro | 6 +- .../Linux/DocxFormatLib/xlsx_format_logic.cpp | 1 + .../DocxFormatLib/DocxFormatLib.vcxproj | 2 + .../DocxFormatLib.vcxproj.filters | 6 + OOXML/XlsxFormat/FileFactory_Spreadsheet.cpp | 13 +- OOXML/XlsxFormat/FileTypes_Spreadsheet.cpp | 11 +- OOXML/XlsxFormat/FileTypes_Spreadsheet.h | 4 + OOXML/XlsxFormat/Table/Table.h | 210 +++++-- OOXML/XlsxFormat/Table/Tables.cpp | 505 +++++++++++++++- OOXML/XlsxFormat/Workbook/CustomsXml.cpp | 561 ++++++++++++++++++ OOXML/XlsxFormat/Workbook/CustomsXml.h | 179 ++++++ 20 files changed, 1610 insertions(+), 56 deletions(-) create mode 100644 OOXML/XlsxFormat/Workbook/CustomsXml.cpp create mode 100644 OOXML/XlsxFormat/Workbook/CustomsXml.h 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..a6af8c4770 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); @@ -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) { @@ -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) { diff --git a/OOXML/Binary/Sheets/Reader/BinaryWriter.h b/OOXML/Binary/Sheets/Reader/BinaryWriter.h index 558520db18..26b7f9d1e2 100644 --- a/OOXML/Binary/Sheets/Reader/BinaryWriter.h +++ b/OOXML/Binary/Sheets/Reader/BinaryWriter.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/Writer/BinaryReader.cpp b/OOXML/Binary/Sheets/Writer/BinaryReader.cpp index f2b4fa8c9c..8373a7aa67 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" @@ -996,6 +997,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 +1090,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; @@ -2332,6 +2364,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; @@ -4629,6 +4671,16 @@ 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); diff --git a/OOXML/Binary/Sheets/Writer/BinaryReader.h b/OOXML/Binary/Sheets/Writer/BinaryReader.h index d1551af149..6a6c8ee8f5 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReader.h +++ b/OOXML/Binary/Sheets/Writer/BinaryReader.h @@ -137,6 +137,7 @@ 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); diff --git a/OOXML/Common/SimpleTypes_Spreadsheet.cpp b/OOXML/Common/SimpleTypes_Spreadsheet.cpp index fb2b990041..17a58c1293 100644 --- a/OOXML/Common/SimpleTypes_Spreadsheet.cpp +++ b/OOXML/Common/SimpleTypes_Spreadsheet.cpp @@ -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/WritingElement.h b/OOXML/DocxFormat/WritingElement.h index 90aede38a6..2a2bc4c581 100644 --- a/OOXML/DocxFormat/WritingElement.h +++ b/OOXML/DocxFormat/WritingElement.h @@ -1342,6 +1342,7 @@ namespace OOX et_x_TableColumns, et_x_TableColumn, et_x_TableStyleInfo, + et_x_xmlColumnPr, et_x_AltTextTable, et_x_SortState, et_x_SortCondition, @@ -1544,7 +1545,16 @@ namespace OOX 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 }; class File; diff --git a/OOXML/Projects/Linux/DocxFormatLib/DocxFormatLib.pro b/OOXML/Projects/Linux/DocxFormatLib/DocxFormatLib.pro index ed6fb5632f..8efa4c13a6 100644 --- a/OOXML/Projects/Linux/DocxFormatLib/DocxFormatLib.pro +++ b/OOXML/Projects/Linux/DocxFormatLib/DocxFormatLib.pro @@ -177,7 +177,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 \ @@ -334,7 +335,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 \ 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/Windows/DocxFormatLib/DocxFormatLib.vcxproj b/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj index 4dc49f0162..9ef90557c9 100644 --- a/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj +++ b/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj @@ -384,6 +384,7 @@ + @@ -545,6 +546,7 @@ + diff --git a/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj.filters b/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj.filters index 8b9170151f..2f28340aef 100644 --- a/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj.filters +++ b/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj.filters @@ -553,6 +553,9 @@ XlsxFormat\Pivots + + XlsxFormat\Workbook + @@ -975,5 +978,8 @@ XlsxFormat\Pivots + + XlsxFormat\Workbook + \ No newline at end of file diff --git a/OOXML/XlsxFormat/FileFactory_Spreadsheet.cpp b/OOXML/XlsxFormat/FileFactory_Spreadsheet.cpp index 8b692b6291..135fea08a1 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" @@ -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/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/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..1c35da1572 --- /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 From 37fc9784a718dae2bfe07ea48f6e6582ed58b709 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 19 Mar 2025 19:21:58 +0600 Subject: [PATCH 112/186] Fix conditional formating conversion --- .../Logic/Biff_structures/BIFF12/FRTSqref.cpp | 5 +-- OOXML/DocxFormat/Drawing/DrawingExt.cpp | 12 +++++- .../Biff12_records/BeginDatabar14.h | 2 +- .../Biff12_structures/FRTProductVersion.h | 6 +-- .../Worksheets/ConditionalFormatting.cpp | 43 +++++++++++-------- 5 files changed, 41 insertions(+), 27 deletions(-) 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/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/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/Worksheets/ConditionalFormatting.cpp b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp index 51e76b6b90..fc050a246c 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); } @@ -3869,7 +3872,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); From ed0f4f9e5ea03d884baf67c66775320a3089d5fe Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 20 Mar 2025 16:27:31 +0600 Subject: [PATCH 113/186] Fix cond fmts formula conversion --- .../Worksheets/ConditionalFormatting.cpp | 58 ++++++++----------- 1 file changed, 23 insertions(+), 35 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp index fc050a246c..54a7654c09 100644 --- a/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp +++ b/OOXML/XlsxFormat/Worksheets/ConditionalFormatting.cpp @@ -2945,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; @@ -3149,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; } From ce129fe49d5543bcb73613aa4abfe82f1390ab08 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 20 Mar 2025 17:08:25 +0600 Subject: [PATCH 114/186] Fix pane conversion --- OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 678870cbe4..c2fd7f75fe 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -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; From 44d76014bfca8604552e38687122927dd6415f76 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 20 Mar 2025 18:52:59 +0300 Subject: [PATCH 115/186] Add nStartRefID to Editor --- PdfFile/OnlineOfficeBinToPdf.cpp | 6 +++-- PdfFile/PdfEditor.cpp | 41 +++++++++++++++++------------- PdfFile/PdfEditor.h | 2 +- PdfFile/PdfFile.cpp | 43 +++++++++++--------------------- PdfFile/PdfReader.cpp | 22 ++++++++++++++++ PdfFile/PdfReader.h | 1 + PdfFile/PdfWriter.cpp | 4 +-- PdfFile/SrcWriter/Document.cpp | 8 ++---- PdfFile/SrcWriter/Document.h | 1 - PdfFile/SrcWriter/Objects.cpp | 4 +-- PdfFile/SrcWriter/Pages.cpp | 11 ++------ PdfFile/SrcWriter/Pages.h | 4 +-- 12 files changed, 77 insertions(+), 70 deletions(-) diff --git a/PdfFile/OnlineOfficeBinToPdf.cpp b/PdfFile/OnlineOfficeBinToPdf.cpp index 64d603ef8c..33e9cb24cd 100644 --- a/PdfFile/OnlineOfficeBinToPdf.cpp +++ b/PdfFile/OnlineOfficeBinToPdf.cpp @@ -216,11 +216,13 @@ namespace NSOnlineOfficeBinToPdf std::wstring wsPath = oReader.ReadString(); std::wstring wsPassword = oReader.ReadString(); int nLength = oReader.ReadInt(); - int* pPageIndex = new int[nLength]; + int* pPageIndex = NULL; + if (nLength > 0) + pPageIndex = new int[nLength]; for (int i = 0; i < nLength; ++i) pPageIndex[i] = oReader.ReadInt(); pPdf->MergePages(wsPath, wsPassword, pPageIndex, nLength); - delete[] pPageIndex; + RELEASEARRAYOBJECTS(pPageIndex); break; } case AddCommandType::WidgetInfo: diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index cfd562bc3f..ba04b17841 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -349,11 +349,11 @@ PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CDocument* pD return pBase; } -PdfWriter::CDictObject* GetWidgetParent(PDFDoc* pdfDoc, PdfWriter::CDocument* pDoc, Object* pParentRef) +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; @@ -367,7 +367,7 @@ PdfWriter::CDictObject* GetWidgetParent(PDFDoc* pdfDoc, PdfWriter::CDocument* pD PdfWriter::CXref* pXref = new PdfWriter::CXref(pDoc, pParentRef->getRefNum()); pParent = new PdfWriter::CDictObject(); pXref->Add(pParent, pParentRef->getRefGen()); - if (!pDoc->EditParent(pXref, pParent, pParentRef->getRefNum())) + if (!pDoc->EditParent(pXref, pParent, pParentRef->getRefNum() + nStartRefID)) { RELEASEOBJECT(pXref); oParent.free(); @@ -381,7 +381,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); @@ -1633,10 +1633,11 @@ BYTE* CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength) RELEASEARRAYOBJECTS(pRes); return NULL; } -bool CPdfEditor::MergePages(PDFDoc* pDocument, const int* arrPageIndex, unsigned int unLength) +bool CPdfEditor::MergePages(const int* arrPageIndex, unsigned int unLength) { if (m_nMode != Mode::WriteAppend && !IncrementalUpdates()) return false; + PDFDoc* pDocument = m_pReader->GetLastPDFDocument(); int nPagesBefore = m_pReader->GetNumPages() - pDocument->getNumPages(); bool bRes = SplitPages(arrPageIndex, unLength, pDocument); if (!bRes) @@ -1668,7 +1669,7 @@ bool CPdfEditor::DeletePage(int nPageIndex) } bool CPdfEditor::AddPage(int nPageIndex) { - if (m_nMode != Mode::WriteAppend && !IncrementalUpdates()) + if (m_nMode == Mode::Unknown) return false; // Применение добавления страницы для writer @@ -1699,7 +1700,8 @@ bool CPdfEditor::EditAnnot(int _nPageIndex, int nID) { PDFDoc* pPDFDocument = NULL; PdfReader::CPdfFontList* pFontList = NULL; - int nPageIndex = m_pReader->GetPageIndex(_nPageIndex, &pPDFDocument, &pFontList); + 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; @@ -1722,7 +1724,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(); } @@ -1857,9 +1859,9 @@ bool CPdfEditor::EditAnnot(int _nPageIndex, int nID) 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); @@ -1872,7 +1874,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) { @@ -2021,7 +2023,6 @@ bool CPdfEditor::EditWidgets(IAdvancedCommand* pCommand) return false; CWidgetsInfo* pFieldInfo = (CWidgetsInfo*)pCommand; - PDFDoc* pPDFDocument = m_pReader->GetPDFDocument(0); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); std::vector arrParents = pFieldInfo->GetParents(); @@ -2031,10 +2032,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; + Object oParentRef; // TODO узнать gen родителя - oParentRef.initRef(pParent->nID, 0); - GetWidgetParent(pPDFDocument, pDoc, &oParentRef); + oParentRef.initRef(nRefID, 0); + GetWidgetParent(pPDFDocument, pDoc, &oParentRef, nStartRefID); // TODO перевыставить детей oParentRef.free(); } @@ -2132,9 +2139,9 @@ bool CPdfEditor::IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bIt if (wsFontPath.empty()) { std::map mFonts = m_pReader->GetFonts(); - std::map::iterator it2 = mFonts.find(wsFontName); - if (it2 != mFonts.end()) - wsFontPath = it2->second; + it = mFonts.find(wsFontName); + if (it != mFonts.end()) + wsFontPath = it->second; } if (wsFontPath.empty()) return false; diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h index 66bf114465..d2e8ac8181 100644 --- a/PdfFile/PdfEditor.h +++ b/PdfFile/PdfEditor.h @@ -72,7 +72,7 @@ public: BYTE* SplitPages(const int* arrPageIndex, unsigned int unLength); bool SplitPages(const int* arrPageIndex, unsigned int unLength, PDFDoc* _pDoc); - bool MergePages(PDFDoc* pDoc, const int* arrPageIndex, unsigned int unLength); + bool MergePages(const int* arrPageIndex, unsigned int unLength); private: void GetPageTree(XRef* xref, Object* pPagesRefObj, PdfWriter::CPageTree* pPageParent = NULL); diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 5ed2f52c69..d26eb57446 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -140,9 +140,8 @@ bool CPdfFile::MergePages(const std::wstring& wsPath, const std::wstring& wsPass { if (!m_pInternal->pEditor) return false; - if (m_pInternal->pReader->MergePages(wsPath, wsPassword)) - return m_pInternal->pEditor->MergePages(m_pInternal->pReader->GetLastPDFDocument(), arrPageIndex, unLength); + return m_pInternal->pEditor->MergePages(arrPageIndex, unLength); return false; } bool CPdfFile::MovePage(int nPageIndex, int nPos) @@ -174,28 +173,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) @@ -487,21 +481,18 @@ 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) { @@ -855,28 +846,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); } diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index a1cafa426f..6b6ee3dfde 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -412,6 +412,28 @@ void CPdfReader::SetParams(COfficeDrawingPageParams* pParams) globalParams->setDrawAnnotations(bDraw); } +int CPdfReader::FindRefNum(int nObjID, PDFDoc** _pDoc, int* _nStartRefID) +{ + int nStartRefID = 0; + for (CPdfReaderContext* pPDFContext : m_vPDFContext) + { + if (!pPDFContext || !pPDFContext->m_pDocument) + continue; + PDFDoc* pDoc = pPDFContext->m_pDocument; + + int nLastRefID = pDoc->getXRef()->getNumObjects(); + if (nObjID < nStartRefID + nLastRefID) + { + if (_pDoc) + *_pDoc = pDoc; + if (_nStartRefID) + *_nStartRefID = nStartRefID; + return nObjID - nStartRefID; + } + nStartRefID += nLastRefID; + } + return -1; +} int CPdfReader::GetPageIndex(int nAbsPageIndex, PDFDoc** _pDoc, PdfReader::CPdfFontList** pFontList, int* nStartRefID) { int nTotalPages = 0; diff --git a/PdfFile/PdfReader.h b/PdfFile/PdfReader.h index 360437a3ad..cda066abc3 100644 --- a/PdfFile/PdfReader.h +++ b/PdfFile/PdfReader.h @@ -88,6 +88,7 @@ public: NSFonts::IFontManager* GetFontManager() { return m_pFontManager; } PDFDoc* GetLastPDFDocument(); PDFDoc* GetPDFDocument(int PDFIndex); + 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(); diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 3db57e3013..95ebcae8a9 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -3709,7 +3709,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); @@ -3739,7 +3739,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)); diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 87191ab749..763001ccb5 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -1508,9 +1508,7 @@ namespace PdfWriter { if (!pParent || !EditXref(pXref)) return false; - m_mParents[nID] = pParent; - return true; } bool CDocument::EditXref(CXref* pXref) @@ -1551,10 +1549,6 @@ namespace PdfWriter return p->second; return NULL; } - CPage* CDocument::CreateFakePage() - { - return new CPage(this, NULL); - } bool CDocument::EditCO(const std::vector& arrCO) { if (arrCO.empty()) @@ -1627,6 +1621,8 @@ namespace PdfWriter CObjectBase* pObj = m_pPageTree->RemovePage(nPageIndex); if (pObj->GetType() == object_type_DICT && ((CDictObject*)pObj)->GetDictType() == dict_type_PAGE) return m_pPageTree->InsertPage(nPos, (CPage*)pObj); + else + delete pObj; } return false; } diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index 991a9d0ad9..62e232549f 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -209,7 +209,6 @@ namespace PdfWriter CDictObject* GetParent(int nID); CPage* GetCurPage() { return m_pCurPage; } void SetCurPage(CPage* pPage) { m_pCurPage = pPage; } - CPage* CreateFakePage(); bool EditCO(const std::vector& arrCO); const std::map& GetAnnots() { return m_mAnnotations; } void AddShapeXML(const std::string& sXML); diff --git a/PdfFile/SrcWriter/Objects.cpp b/PdfFile/SrcWriter/Objects.cpp index 3610ba6334..dd178ac5ac 100644 --- a/PdfFile/SrcWriter/Objects.cpp +++ b/PdfFile/SrcWriter/Objects.cpp @@ -546,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) @@ -619,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) { diff --git a/PdfFile/SrcWriter/Pages.cpp b/PdfFile/SrcWriter/Pages.cpp index 8b470e79f9..df7cc5241e 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() { 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(); From cf91b46ea705df5e84c5ec2e7f01b397e3684bd8 Mon Sep 17 00:00:00 2001 From: Elena Subbotina Date: Fri, 21 Mar 2025 15:27:18 +0300 Subject: [PATCH 116/186] . --- OOXML/XlsxFormat/Workbook/CustomsXml.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Workbook/CustomsXml.cpp b/OOXML/XlsxFormat/Workbook/CustomsXml.cpp index 1c35da1572..e90a857e99 100644 --- a/OOXML/XlsxFormat/Workbook/CustomsXml.cpp +++ b/OOXML/XlsxFormat/Workbook/CustomsXml.cpp @@ -29,7 +29,7 @@ * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode * */ -#include "CustomsXML.h" +#include "CustomsXml.h" #include "../FileTypes_Spreadsheet.h" From b67ed51103ac56a9a656570ac202df7ddf81003f Mon Sep 17 00:00:00 2001 From: Dmitry Okunev Date: Fri, 21 Mar 2025 16:04:03 +0300 Subject: [PATCH 117/186] AddTest --- .../TestSMCustomShape/TestSMCustomShape.pro | 18 ++ .../TestSMCustomShape/main.cpp | 163 ++++++++++++++++++ .../SMCustomShape2OOXML/smcustomshapepars.cpp | 113 ++++++++---- .../SMCustomShape2OOXML/smcustomshapepars.h | 4 + 4 files changed, 264 insertions(+), 34 deletions(-) create mode 100644 OdfFile/Reader/Converter/SMCustomShape2OOXML/TestSMCustomShape/TestSMCustomShape.pro create mode 100644 OdfFile/Reader/Converter/SMCustomShape2OOXML/TestSMCustomShape/main.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 index 20afdf7f13..adb91e402e 100644 --- a/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.cpp +++ b/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.cpp @@ -42,6 +42,20 @@ namespace StarMathCustomShape 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() { @@ -65,6 +79,8 @@ namespace StarMathCustomShape 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) @@ -145,7 +161,10 @@ namespace StarMathCustomShape 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); @@ -177,10 +196,7 @@ namespace StarMathCustomShape void CElementArithmeticOperations::ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter, const std::wstring &wsName) { if(wsName != L"") - { SetNameFormula(wsName); -// m_wsNumberFormula = SMCustomShapeConversion::ParsFormulaName(wsName,m_wsNameFormula); - } if(m_pSecondSign != nullptr) { CElementArithmeticOperations* pTemp = dynamic_cast(m_pSecondSign); @@ -190,7 +206,7 @@ namespace StarMathCustomShape if(m_pFirstValue != nullptr) wsNameFirstValue = ConversionValueSign(pXmlWriter,m_pFirstValue); if(m_pSecondValue != nullptr) - wsNameSecondValue = ConversionValueSign(pXmlWriter,m_pFirstValue); + wsNameSecondValue = ConversionValueSign(pXmlWriter,m_pSecondValue); pXmlWriter->WriteNodeBegin(L"a:gd",true); if(!GetNameFormula().empty()) pXmlWriter->WriteAttribute(L"name",GetNameFormula()); @@ -205,6 +221,7 @@ namespace StarMathCustomShape pXmlWriter->WriteString(wsNameValueSecondSign + L" "); else if(pTemp->GetSecondValue() != nullptr) pTemp->GetSecondValue()->ConversionOOXml(pXmlWriter); + pXmlWriter->WriteString(L"\""); pXmlWriter->WriteNodeEnd(L"",true,true); } else @@ -252,6 +269,7 @@ namespace StarMathCustomShape pXmlWriter->WriteString(L"0 "); RecordingTheValuesSign(pXmlWriter,wsNameFirstValue,wsNameSecondValue); } + pXmlWriter->WriteString(L"\""); pXmlWriter->WriteNodeEnd(L"",true,true); } } @@ -404,6 +422,8 @@ namespace StarMathCustomShape } bool CSMReader::ReadingNextElement() { + if(!m_wsElement.empty()) + return true; m_wsElement = GetElement(m_itStart,m_itEnd); if(!m_wsElement.empty()) return true; @@ -428,21 +448,35 @@ namespace StarMathCustomShape void CSMReader::FindingTheEndOfTheBrackets() { std::wstring::iterator itStartTemp = m_itStart; + unsigned int uiOpenBracket{0}; for(;m_itStart !=m_itEnd;m_itStart++) { - if(*m_itStart == L')') + if(*m_itStart == L')' && uiOpenBracket == 0) { - m_itEndForBrecket = m_itEnd; + // 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_itEndForBrecket != m_itEnd) - m_itEnd = m_itEndForBrecket; + 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) { @@ -470,10 +504,12 @@ namespace StarMathCustomShape } 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); + pElement->ConversionOOXml(pXmlWriter,wsName); } } @@ -482,11 +518,11 @@ namespace StarMathCustomShape return m_arElements; } //CElementFunction - CElementFunction::CElementFunction():m_enTypeFunction(TypeElement::empty),m_pValue(nullptr) + CElementFunction::CElementFunction():m_enTypeFunction(TypeElement::empty),m_pValue(nullptr),m_uiNumberFormula(1) { SetBaseType(TypeElement::Function); } - CElementFunction::CElementFunction(const TypeElement& enType):m_pValue(nullptr) + CElementFunction::CElementFunction(const TypeElement& enType):m_pValue(nullptr),m_uiNumberFormula(1) { SetBaseType(TypeElement::Function); m_enTypeFunction = enType; @@ -513,22 +549,15 @@ namespace StarMathCustomShape return TypeElement::max; // else if(wsFunction == L"atan2") // return TypeElement::atan2; - // else if(wsFunction == L"atan") - // return TypeElement::atan; + else if(wsFunction == L"atan") + return TypeElement::atan; else return TypeElement::empty; } void CElementFunction::Parse(CSMReader* pReader) { + pReader->ClearElement(); m_pValue = SMCustomShapePars::ParseElement(pReader); - pReader->ReadingNextElement(); - if(CElementArithmeticOperations::CheckArithmeticOperators(pReader->GetElement())) - { - CElement* pSign = SMCustomShapePars::ParseElement(pReader); - CElementArithmeticOperations* pTempSign = dynamic_cast(pSign); - pTempSign->SetFirstValue(m_pValue); - m_pValue = pTempSign; - } } void CElementFunction::ConversionOOXml(XmlUtils::CXmlWriter* pXmlWriter, const std::wstring &wsName) { @@ -612,24 +641,21 @@ namespace StarMathCustomShape } 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 + else if(m_enTypeFunction == TypeElement::cos) wsFormula = L"cos 1 "; - 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 if(m_enTypeFunction == TypeElement::tan) + wsFormula = L"tan 1 "; else - wsFormula += L"1 "; + wsFormula = L"at2 1 "; + ConvertBracketsForTrigonometry(pXmlWriter,wsFormula); SMCustomShapeConversion::WritingFormulaXml(pXmlWriter,GetNameFormula(),wsFormula); + break; } default: break; @@ -646,11 +672,26 @@ namespace StarMathCustomShape } else { - std::wstring wsNewNameFormula = GetNameFormula() + L".1"; + 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);} @@ -678,10 +719,14 @@ namespace StarMathCustomShape if(arElements.size() == 1 && arElements[0]->GetBaseType() == TypeElement::NumberOrName) { m_pXmlWriter->WriteNodeBegin(L"a:gd",true); - m_pXmlWriter->WriteAttribute(L"name",L"Text"); + 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 { diff --git a/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.h b/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.h index e9784f5b70..35b1663884 100644 --- a/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.h +++ b/OdfFile/Reader/Converter/SMCustomShape2OOXML/smcustomshapepars.h @@ -5,6 +5,7 @@ #include #include #include +#include #include "../../../../DesktopEditor/xml/include/xmlwriter.h" namespace StarMathCustomShape @@ -54,6 +55,7 @@ namespace StarMathCustomShape 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; @@ -157,9 +159,11 @@ namespace StarMathCustomShape 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 { From caa34c540ad9f8589475cd9f7ab51f9fcff4143e Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 21 Mar 2025 16:58:43 +0300 Subject: [PATCH 118/186] Add CObjectsManager --- PdfFile/PdfEditor.cpp | 138 +++++++++++++++++++++++++----------------- PdfFile/PdfEditor.h | 25 +++++++- PdfFile/PdfReader.cpp | 14 +++++ 3 files changed, 120 insertions(+), 57 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index ba04b17841..259a857339 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -150,7 +150,7 @@ void DictToCDictObject(Object* obj, PdfWriter::CObjectBase* pObj, const std::str break; } } -bool SplitSkipDict(Object* obj, std::map& mUniqueRef) +bool SplitSkipDict(Object* obj, CObjectsManager* pManager, int nStartRefID) { Object oTemp, oTemp2; if (obj->dictLookup("Type", &oTemp)->isName("Page")) @@ -160,8 +160,8 @@ bool SplitSkipDict(Object* obj, std::map& mUniqueR } else if (oTemp.isName("Annot") && obj->dictLookupNF("P", &oTemp2)->isRef()) { - std::map::iterator it = mUniqueRef.find(oTemp2.getRefNum()); - if (it == mUniqueRef.end()) + PdfWriter::CObjectBase* pObj = pManager->GetObj(oTemp2.getRefNum() + nStartRefID); + if (!pObj) { oTemp.free(); oTemp2.free(); return true; @@ -174,8 +174,8 @@ bool SplitSkipDict(Object* obj, std::map& mUniqueR oTemp.free(); if (obj->dictLookup("D", &oTemp)->isArray() && oTemp.arrayGetLength() > 1 && oTemp.arrayGetNF(0, &oTemp2)->isRef()) { - std::map::iterator it = mUniqueRef.find(oTemp2.getRefNum()); - if (it == mUniqueRef.end()) + PdfWriter::CObjectBase* pObj = pManager->GetObj(oTemp2.getRefNum() + nStartRefID); + if (!pObj) { oTemp.free(); oTemp2.free(); return true; @@ -187,7 +187,7 @@ bool SplitSkipDict(Object* obj, std::map& mUniqueR return false; } -PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CDocument* pDoc, XRef* xref, std::map& mUniqueRef, int nAddObjToXRef = 0) +PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CDocument* pDoc, XRef* xref, CObjectsManager* pManager, int nStartRefID, int nAddObjToXRef = 0) { PdfWriter::CObjectBase* pBase = NULL; Object oTemp; @@ -244,13 +244,13 @@ PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CDocument* pD if (nAddObjToXRef > 0) { pDoc->AddObject(pArray); - mUniqueRef[nAddObjToXRef] = 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, mUniqueRef); + pBase = DictToCDictObject2(&oTemp, pDoc, xref, pManager, nStartRefID); pArray->Add(pBase); oTemp.free(); } @@ -259,20 +259,20 @@ PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CDocument* pD } case objDict: { - if (SplitSkipDict(obj, mUniqueRef)) + if (SplitSkipDict(obj, pManager, nStartRefID)) return NULL; PdfWriter::CDictObject* pDict = new PdfWriter::CDictObject(); if (nAddObjToXRef > 0) { pDoc->AddObject(pDict); - mUniqueRef[nAddObjToXRef] = 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, mUniqueRef); + pBase = DictToCDictObject2(&oTemp, pDoc, xref, pManager, nStartRefID); pDict->Add(chKey, pBase); oTemp.free(); } @@ -282,12 +282,15 @@ PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CDocument* pD case objRef: { int nObjNum = obj->getRefNum(); - std::map::iterator it = mUniqueRef.find(nObjNum); - if (it != mUniqueRef.end()) - return it->second; + PdfWriter::CObjectBase* pObj = pManager->GetObj(nObjNum + nStartRefID); + if (pObj) + { + pManager->IncRefCount(nObjNum + nStartRefID); + return pObj; + } obj->fetch(xref, &oTemp); - pBase = DictToCDictObject2(&oTemp, pDoc, xref, mUniqueRef, nObjNum); + pBase = DictToCDictObject2(&oTemp, pDoc, xref, pManager, nStartRefID, nObjNum); oTemp.free(); break; } @@ -302,7 +305,7 @@ PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CDocument* pD if (nAddObjToXRef > 0) { pDoc->AddObject(pDict); - mUniqueRef[nAddObjToXRef] = pDict; + pManager->AddObj(nAddObjToXRef + nStartRefID, pDict); nAddObjToXRef = 0; } @@ -318,7 +321,7 @@ PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CDocument* pD oTemp.free(); } pODict->getValNF(nIndex, &oTemp); - pBase = DictToCDictObject2(&oTemp, pDoc, xref, mUniqueRef); + pBase = DictToCDictObject2(&oTemp, pDoc, xref, pManager, nStartRefID); pDict->Add(chKey, pBase); oTemp.free(); } @@ -344,7 +347,7 @@ PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CDocument* pD if (nAddObjToXRef > 0) { pDoc->AddObject(pBase); - mUniqueRef[nAddObjToXRef] = pBase; + pManager->AddObj(nAddObjToXRef + nStartRefID, pBase); } return pBase; @@ -648,6 +651,27 @@ void GetCTM(XRef* pXref, Object* oPage, double* dCTM) oContents.free(); } +void CObjectsManager::AddObj(int nID, PdfWriter::CObjectBase* pObj) +{ + 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; +} +void CObjectsManager::IncRefCount(int nID) +{ + if (m_mUniqueRef.find(nID) != m_mUniqueRef.end()) + m_mUniqueRef[nID].nRefCount++; +} +void CObjectsManager::DecRefCount(int nID) +{ + +} + CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPassword, const std::wstring& _wsDstFile, CPdfReader* _pReader, CPdfWriter* _pWriter) { m_wsSrcFile = _wsSrcFile; @@ -1261,7 +1285,7 @@ bool CPdfEditor::EditPage(int _nPageIndex, bool bSet) RELEASEOBJECT(pXref); return false; } -bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFDoc* _pDoc) +bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFDoc* _pDoc, int nStartRefID) { if (m_nMode == Mode::WriteNew) return false; @@ -1294,7 +1318,7 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFD pageObj.free(); pageRefObj.free(); return false; } - m_mSplitUniqueRef[pPageRef->num] = pPage; + m_mObjManager.AddObj(pPageRef->num + nStartRefID, pPage); pageObj.free(); pageRefObj.free(); } @@ -1305,7 +1329,7 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFD return false; // Получение объекта страницы - PdfWriter::CPage* pPage = (PdfWriter::CPage*)m_mSplitUniqueRef[pPageRef->num]; + 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()) @@ -1328,10 +1352,11 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFD oResourcesRef = oTemp.getRef(); oTemp.free(); - std::map::iterator it = m_mSplitUniqueRef.find(oResourcesRef.num); - if (oResourcesRef.num > 0 && it != m_mSplitUniqueRef.end()) + PdfWriter::CObjectBase* pObj = oResourcesRef.num > 0 ? m_mObjManager.GetObj(oResourcesRef.num + nStartRefID) : NULL; + if (pObj) { - pPage->Add(chKey, it->second); + pPage->Add(chKey, pObj); + m_mObjManager.IncRefCount(oResourcesRef.num + nStartRefID); continue; } @@ -1339,14 +1364,14 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFD { PdfWriter::CResourcesDict* pDict = pDoc->CreateResourcesDict(oResourcesRef.num < 0, false); if (oResourcesRef.num > 0) - m_mSplitUniqueRef[oResourcesRef.num] = pDict; + 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_mSplitUniqueRef); + PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oRes, pDoc, xref, &m_mObjManager, nStartRefID); pDict->Add(chKey2, pBase); oRes.free(); } @@ -1360,14 +1385,14 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFD pageObj.dictGetValNF(nIndex, &oTemp); } } - else if (strcmp("Parent", chKey) == 0) + else if (strcmp("Parent", chKey) == 0) // TODO может ли родитель страницы обладать важными для неё полями { oTemp.free(); continue; } else pageObj.dictGetValNF(nIndex, &oTemp); - PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp, pDoc, xref, m_mSplitUniqueRef); + PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp, pDoc, xref, &m_mObjManager, nStartRefID); pPage->Add(chKey, pBase); oTemp.free(); } @@ -1400,9 +1425,7 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFD pDoc->SetAcroForm(pAcroForm); } else - { pAcroForm->Remove("NeedAppearances"); - } if (oAcroForm.isRef()) { @@ -1428,16 +1451,17 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFD PdfWriter::CArrayObject* pFields = dynamic_cast(pAcroForm->Get("Fields")); if (!pFields) { - std::map::iterator it = m_mSplitUniqueRef.find(oFieldsRef.num); - if (oFieldsRef.num > 0 && it != m_mSplitUniqueRef.end()) + PdfWriter::CObjectBase* pObj = oFieldsRef.num > 0 ? m_mObjManager.GetObj(oFieldsRef.num + nStartRefID) : NULL; + if (pObj) { - pAcroForm->Add(chKey, it->second); + pAcroForm->Add(chKey, pObj); + m_mObjManager.IncRefCount(oFieldsRef.num + nStartRefID); continue; } } // TODO нужна проверка полных имён - // Если имя совпадает, то: + // Если имя совпадает, то: переименование с удалением действий или преобразование типа // Если другие поля - тип, флаг и т.д. совпадает, то выносим общее в общего родителя // Иначе переименовываем, action обрубаем @@ -1449,7 +1473,7 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFD if (oFieldsRef.num > 0) { pDoc->AddObject(pFields); - m_mSplitUniqueRef[oFieldsRef.num] = pFields; + m_mObjManager.AddObj(oFieldsRef.num + nStartRefID, pFields); } pAcroForm->Add(chKey, pFields); } @@ -1459,9 +1483,13 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFD Object oRes; if (oTemp.arrayGetNF(nIndex, &oRes)->isRef()) { - std::map::iterator it = m_mSplitUniqueRef.find(oRes.getRefNum()); - if (it != m_mSplitUniqueRef.end()) - pFields->Add(it->second); + PdfWriter::CObjectBase* pObj = m_mObjManager.GetObj(oRes.getRefNum() + nStartRefID); + if (pObj) + { + pFields->Add(pObj); + m_mObjManager.IncRefCount(oRes.getRefNum() + nStartRefID); + continue; + } } oRes.free(); } @@ -1519,15 +1547,16 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFD Object oTempRef; if (oTemp.dictGetValNF(nIndex2, &oTempRef)->isRef()) { - std::map::iterator it = m_mSplitUniqueRef.find(oTempRef.getRefNum()); - if (it != m_mSplitUniqueRef.end()) + PdfWriter::CObjectBase* pObj = m_mObjManager.GetObj(oTempRef.getRefNum() + nStartRefID); + if (pObj) { - pDR->Add(chKey2, it->second); + pDR->Add(chKey2, pObj); + m_mObjManager.IncRefCount(oTempRef.getRefNum() + nStartRefID); oTemp2.free(); oTempRef.free(); continue; } } - PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp2, pDoc, xref, m_mSplitUniqueRef); + PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp2, pDoc, xref, &m_mObjManager, nStartRefID); if (oTempRef.isRef()) pDoc->AddObject(pBase); pDR->Add(chKey2, pBase); @@ -1544,15 +1573,16 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFD Object oTempRef; if (oTemp2.dictGetValNF(nIndex3, &oTempRef)->isRef()) { - std::map::iterator it = m_mSplitUniqueRef.find(oTempRef.getRefNum()); - if (it != m_mSplitUniqueRef.end()) + PdfWriter::CObjectBase* pObj = m_mObjManager.GetObj(oTempRef.getRefNum() + nStartRefID); + if (pObj) { - pDict->Add(chKey3, it->second); + pDict->Add(chKey3, pObj); + m_mObjManager.IncRefCount(oTempRef.getRefNum() + nStartRefID); oTemp2.free(); oTempRef.free(); continue; } } - PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp2, pDoc, xref, m_mSplitUniqueRef); + PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp2, pDoc, xref, &m_mObjManager, nStartRefID); if (oTempRef.isRef()) pDoc->AddObject(pBase); pDict->Add(chKey3, pBase); @@ -1572,7 +1602,7 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFD } else oAcroForm.dictGetValNF(nIndex, &oTemp); - PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp, pDoc, xref, m_mSplitUniqueRef); + PdfWriter::CObjectBase* pBase = DictToCDictObject2(&oTemp, pDoc, xref, &m_mObjManager, nStartRefID); pAcroForm->Add(chKey, pBase); oTemp.free(); } @@ -1604,6 +1634,7 @@ BYTE* CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength) pPDFDocument = m_pReader->GetPDFDocument(nPDFIndex); if (!pPDFDocument) break; + nTotalPages += nPages; nPages = pPDFDocument->getNumPages(); } } @@ -1611,7 +1642,7 @@ BYTE* CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength) for (const std::pair>& it : mFileToPages) { pPDFDocument = m_pReader->GetPDFDocument(it.first); - if (!SplitPages(it.second.data(), it.second.size(), pPDFDocument)) + if (!SplitPages(it.second.data(), it.second.size(), pPDFDocument, m_pReader->GetStartRefID(pPDFDocument))) return NULL; } @@ -1639,12 +1670,10 @@ bool CPdfEditor::MergePages(const int* arrPageIndex, unsigned int unLength) return false; PDFDoc* pDocument = m_pReader->GetLastPDFDocument(); int nPagesBefore = m_pReader->GetNumPages() - pDocument->getNumPages(); - bool bRes = SplitPages(arrPageIndex, unLength, pDocument); + int nStartRefID = m_pReader->GetStartRefID(pDocument); + bool bRes = SplitPages(arrPageIndex, unLength, pDocument, nStartRefID); if (!bRes) - { - m_mSplitUniqueRef.clear(); return false; - } // Добавление merge страниц в редактируемые PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); @@ -1652,12 +1681,11 @@ bool CPdfEditor::MergePages(const int* arrPageIndex, unsigned int unLength) for (int i = 0, nPages = unLength == 0 ? pDocument->getNumPages() : unLength; i < nPages; ++i) { Ref* pPageRef = pCatalog->getPageRef((arrPageIndex ? arrPageIndex[i] : i) + 1); - PdfWriter::CObjectBase* pObj = m_mSplitUniqueRef[pPageRef->num]; - if (pObj->GetType() == PdfWriter::object_type_DICT && ((PdfWriter::CDictObject*)pObj)->GetDictType() == PdfWriter::dict_type_PAGE) + PdfWriter::CObjectBase* pObj = m_mObjManager.GetObj(pPageRef->num + nStartRefID); + if (pObj && pObj->GetType() == PdfWriter::object_type_DICT && ((PdfWriter::CDictObject*)pObj)->GetDictType() == PdfWriter::dict_type_PAGE) pDoc->AddEditPage((PdfWriter::CPage*)pObj, nPagesBefore + i); } - m_mSplitUniqueRef.clear(); return bRes; } bool CPdfEditor::DeletePage(int nPageIndex) diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h index d2e8ac8181..d8428e7125 100644 --- a/PdfFile/PdfEditor.h +++ b/PdfFile/PdfEditor.h @@ -37,6 +37,27 @@ 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); + void IncRefCount(int nID); + void DecRefCount(int nID); + +private: + std::map m_mUniqueRef; // map уникальных объектов +}; + class CPdfEditor { public: @@ -71,17 +92,17 @@ public: bool IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bItalic, std::wstring& wsFontPath); BYTE* SplitPages(const int* arrPageIndex, unsigned int unLength); - bool SplitPages(const int* arrPageIndex, unsigned int unLength, PDFDoc* _pDoc); bool MergePages(const int* arrPageIndex, unsigned int unLength); 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 m_wsSrcFile; std::wstring m_wsDstFile; std::wstring m_wsPassword; std::map m_mFonts; - std::map m_mSplitUniqueRef; // map уникальных объектов для Split + CObjectsManager m_mObjManager; CPdfReader* m_pReader; CPdfWriter* m_pWriter; diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 6b6ee3dfde..c2cabea6bd 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -412,6 +412,20 @@ void CPdfReader::SetParams(COfficeDrawingPageParams* pParams) globalParams->setDrawAnnotations(bDraw); } +int CPdfReader::GetStartRefID(PDFDoc* _pDoc) +{ + int nStartRefID = 0; + for (CPdfReaderContext* pPDFContext : m_vPDFContext) + { + if (!pPDFContext || !pPDFContext->m_pDocument) + continue; + PDFDoc* pDoc = pPDFContext->m_pDocument; + if (_pDoc == pDoc) + return nStartRefID; + nStartRefID += pDoc->getXRef()->getNumObjects(); + } + return -1; +} int CPdfReader::FindRefNum(int nObjID, PDFDoc** _pDoc, int* _nStartRefID) { int nStartRefID = 0; From 96a7e3ac36cde038693b7adaddedca8b6b1a1f4e Mon Sep 17 00:00:00 2001 From: "Oleg.Korshul" Date: Mon, 24 Mar 2025 09:05:21 +0300 Subject: [PATCH 119/186] Fix bug 73514 --- DesktopEditor/doctrenderer/embed/GraphicsEmbed.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) 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) { From aed320e57aa104851ceb55a27477157f0c20cb92 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 24 Mar 2025 09:12:42 +0300 Subject: [PATCH 120/186] Fix build --- PdfFile/PdfReader.h | 1 + 1 file changed, 1 insertion(+) diff --git a/PdfFile/PdfReader.h b/PdfFile/PdfReader.h index cda066abc3..f4b1f40194 100644 --- a/PdfFile/PdfReader.h +++ b/PdfFile/PdfReader.h @@ -88,6 +88,7 @@ public: NSFonts::IFontManager* GetFontManager() { return m_pFontManager; } 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); From fedf33e2c2e592afa8d2ae3cf3c6ff5b9c57b0cf Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 24 Mar 2025 13:11:12 +0300 Subject: [PATCH 121/186] Fix AP_N_Yes for radiobutton --- PdfFile/SrcWriter/Annotation.cpp | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index 7cd9861e23..66f8d0d2ff 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -2117,27 +2117,24 @@ namespace PdfWriter { 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) + CArrayObject* pArr = (CArrayObject*)pObj; + for (int i = 0; i < pArr->GetCount(); ++i) { - 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; } } } From 352289767081fda3c8d723d862d5f4a0e088390f Mon Sep 17 00:00:00 2001 From: Elena Subbotina Date: Mon, 24 Mar 2025 13:21:24 +0300 Subject: [PATCH 122/186] . --- OOXML/Binary/Document/DocWrapper/XlsxSerializer.cpp | 7 ------- OOXML/Binary/Document/DocWrapper/XlsxSerializer.h | 1 - OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h | 2 -- X2tConverter/src/lib/xlsx.h | 5 ----- 4 files changed, 15 deletions(-) diff --git a/OOXML/Binary/Document/DocWrapper/XlsxSerializer.cpp b/OOXML/Binary/Document/DocWrapper/XlsxSerializer.cpp index 094ea2468e..3ffd53923c 100644 --- a/OOXML/Binary/Document/DocWrapper/XlsxSerializer.cpp +++ b/OOXML/Binary/Document/DocWrapper/XlsxSerializer.cpp @@ -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/Sheets/Common/BinReaderWriterDefines.h b/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h index a342586b57..20ec0466f5 100644 --- a/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h +++ b/OOXML/Binary/Sheets/Common/BinReaderWriterDefines.h @@ -240,7 +240,6 @@ namespace BinXlsxRW TimelineCache = 28, Metadata = 29, XmlMap = 30 - PivotCachesTmp = 107 };} namespace c_oSerWorkbookProtection {enum c_oSerWorkbookProtection{ AlgorithmName = 0, @@ -459,7 +458,6 @@ namespace BinXlsxRW Timelines = 49, Timeline = 50, TableSingleCells = 51 - PivotTableTmp = 126, };} namespace c_oSerWorksheetProtection {enum c_oSerWorksheetPropTypes { diff --git a/X2tConverter/src/lib/xlsx.h b/X2tConverter/src/lib/xlsx.h index a616be2ecd..72eb0fe4b2 100644 --- a/X2tConverter/src/lib/xlsx.h +++ b/X2tConverter/src/lib/xlsx.h @@ -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()); From b6741a504fe71bbf45281256feacd8c24e74f69c Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 24 Mar 2025 17:41:26 +0300 Subject: [PATCH 123/186] Fix delete indirect objects --- PdfFile/PdfEditor.cpp | 37 +++++++++++++++++++++++++++++++--- PdfFile/PdfEditor.h | 1 + PdfFile/SrcWriter/Document.cpp | 4 +++- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 259a857339..3b7a5c633c 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -367,9 +367,13 @@ 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 (nStartRefID == 0) + { + pXref = new PdfWriter::CXref(pDoc, pParentRef->getRefNum()); + pXref->Add(pParent, pParentRef->getRefGen()); + } if (!pDoc->EditParent(pXref, pParent, pParentRef->getRefNum() + nStartRefID)) { RELEASEOBJECT(pXref); @@ -671,6 +675,13 @@ void CObjectsManager::DecRefCount(int nID) { } +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; +} CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPassword, const std::wstring& _wsDstFile, CPdfReader* _pReader, CPdfWriter* _pWriter) { @@ -1693,7 +1704,13 @@ bool CPdfEditor::DeletePage(int nPageIndex) if (m_nMode != Mode::WriteAppend && !IncrementalUpdates()) return false; - return m_pWriter->GetDocument()->DeletePage(nPageIndex); + PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); + PdfWriter::CPage* pPage = pDoc->GetPage(nPageIndex); + int nObjID = m_mObjManager.FindObj(pPage); + if (nObjID > 0) + pPage->SetHidden(); + + return pDoc->DeletePage(nPageIndex); } bool CPdfEditor::AddPage(int nPageIndex) { @@ -1726,6 +1743,13 @@ bool CPdfEditor::MovePage(int nPageIndex, int nPos) } bool CPdfEditor::EditAnnot(int _nPageIndex, int nID) { + PdfWriter::CObjectBase* pObj = m_mObjManager.GetObj(nID); + if (pObj) + { + pObj->SetHidden(); + return true; + } + PDFDoc* pPDFDocument = NULL; PdfReader::CPdfFontList* pFontList = NULL; int nStartRefID = 0; @@ -1982,6 +2006,13 @@ bool CPdfEditor::EditAnnot(int _nPageIndex, int nID) } bool CPdfEditor::DeleteAnnot(int nID, Object* oAnnots) { + PdfWriter::CObjectBase* pObj = m_mObjManager.GetObj(nID); + if (pObj) + { + pObj->SetHidden(); + return true; + } + PDFDoc* pPDFDocument = NULL; int nPageIndex = m_pReader->GetPageIndex(m_nEditPage, &pPDFDocument); PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h index d8428e7125..60439d28c9 100644 --- a/PdfFile/PdfEditor.h +++ b/PdfFile/PdfEditor.h @@ -53,6 +53,7 @@ public: PdfWriter::CObjectBase* GetObj(int nID); void IncRefCount(int nID); void DecRefCount(int nID); + int FindObj(PdfWriter::CObjectBase* pObj); private: std::map m_mUniqueRef; // map уникальных объектов diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 763001ccb5..1f4d6a980d 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -1514,7 +1514,7 @@ namespace PdfWriter bool CDocument::EditXref(CXref* pXref) { if (!pXref) - return false; + return true; pXref->SetPrev(m_pLastXref); m_pLastXref = pXref; @@ -1603,6 +1603,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) From eebe3f321a370ecf61a8deb2440548426120a8be Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 25 Mar 2025 17:24:33 +0300 Subject: [PATCH 124/186] Delete merged object --- PdfFile/PdfEditor.cpp | 102 ++++++++++++++++++++++++++++++++++++++++-- PdfFile/PdfEditor.h | 5 ++- 2 files changed, 102 insertions(+), 5 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 3b7a5c633c..2aa2d3b816 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -666,14 +666,25 @@ PdfWriter::CObjectBase* CObjectsManager::GetObj(int nID) return m_mUniqueRef[nID].pObj; return NULL; } -void CObjectsManager::IncRefCount(int nID) +bool CObjectsManager::IncRefCount(int nID) { if (m_mUniqueRef.find(nID) != m_mUniqueRef.end()) + { m_mUniqueRef[nID].nRefCount++; + return true; + } + return false; } -void CObjectsManager::DecRefCount(int nID) +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) { @@ -682,6 +693,69 @@ int CObjectsManager::FindObj(PdfWriter::CObjectBase* pObj) 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; + + 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) { @@ -1708,7 +1782,19 @@ bool CPdfEditor::DeletePage(int nPageIndex) 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) + { + Object oRef; + // TODO узнать gen + oRef.initRef(nRefID, 0); + m_mObjManager.DeleteObjTree(&oRef, pPDFDocument->getXRef(), nStartRefID); + } pPage->SetHidden(); + } return pDoc->DeletePage(nPageIndex); } @@ -2009,6 +2095,16 @@ bool CPdfEditor::DeleteAnnot(int nID, Object* oAnnots) 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) + { + Object oRef; + // TODO узнать gen + oRef.initRef(nRefID, 0); + m_mObjManager.DeleteObjTree(&oRef, pPDFDocument->getXRef(), nStartRefID); + } pObj->SetHidden(); return true; } diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h index 60439d28c9..74d828cec9 100644 --- a/PdfFile/PdfEditor.h +++ b/PdfFile/PdfEditor.h @@ -51,9 +51,10 @@ class CObjectsManager public: void AddObj(int nID, PdfWriter::CObjectBase* pObj); PdfWriter::CObjectBase* GetObj(int nID); - void IncRefCount(int nID); - void DecRefCount(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 уникальных объектов From 716cbd42b2b050bc8cfd7da5091f28eb777dc692 Mon Sep 17 00:00:00 2001 From: Alexey Nagaev Date: Wed, 26 Mar 2025 13:50:27 +0300 Subject: [PATCH 125/186] Fix missing header --- Common/OfficeFileFormatChecker2.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Common/OfficeFileFormatChecker2.cpp b/Common/OfficeFileFormatChecker2.cpp index 6183e11aa2..d1c39c5f6a 100644 --- a/Common/OfficeFileFormatChecker2.cpp +++ b/Common/OfficeFileFormatChecker2.cpp @@ -44,6 +44,7 @@ #include "3dParty/pole/pole.h" #include +#include #include "OfficeFileFormatDefines.h" From c5e6fb69c8a1e7d79076bc7d2afa7983a3d8ee6f Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 26 Mar 2025 14:06:29 +0300 Subject: [PATCH 126/186] Edit merged annots --- PdfFile/PdfEditor.cpp | 163 ++++++++++++++++++++++++++++----- PdfFile/PdfWriter.cpp | 1 + PdfFile/SrcWriter/Document.cpp | 5 +- PdfFile/SrcWriter/Document.h | 1 + 4 files changed, 147 insertions(+), 23 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 2aa2d3b816..a63b2068cf 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -187,6 +187,104 @@ bool SplitSkipDict(Object* obj, CObjectsManager* pManager, int nStartRefID) 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; @@ -261,7 +359,19 @@ PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CDocument* pD { if (SplitSkipDict(obj, pManager, nStartRefID)) return NULL; - PdfWriter::CDictObject* pDict = new PdfWriter::CDictObject(); + + 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); + pDoc->AddAnnotation(nAddObjToXRef + nStartRefID, pAnnot); + pDict = pAnnot; + } + oType.free(); oSubtype.free(); + + if (!pDict) + pDict = new PdfWriter::CDictObject(); if (nAddObjToXRef > 0) { pDoc->AddObject(pDict); @@ -352,6 +462,27 @@ PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CDocument* pD return pBase; } +void AddWidgetParent(PdfWriter::CDocument* pDoc, CObjectsManager* pManager, PdfWriter::CObjectBase* pObj) +{ + if (pObj->GetType() != PdfWriter::object_type_DICT) + return; + PdfWriter::CDictObject* pDict = (PdfWriter::CDictObject*)pObj; + if (pDict->GetDictType() != PdfWriter::dict_type_UNKNOWN) + return; + + int nID = pManager->FindObj(pObj); + if (pDoc->GetParent(nID)) + return; + pDoc->AddParent(nID, pDict); + + 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) @@ -1379,6 +1510,7 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFD 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(); @@ -1394,6 +1526,7 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFD PdfWriter::CPage* pPage = new PdfWriter::CPage(pDoc); pDoc->AddObject(pPage); pDoc->AddPage(pDoc->GetPagesCount(), pPage); + pDoc->AddEditPage(pPage, nPagesBefore + i); // Получение объекта страницы Object pageRefObj, pageObj; @@ -1573,6 +1706,7 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFD { pFields->Add(pObj); m_mObjManager.IncRefCount(oRes.getRefNum() + nStartRefID); + AddWidgetParent(pDoc, &m_mObjManager, pObj); continue; } } @@ -1754,23 +1888,11 @@ bool CPdfEditor::MergePages(const int* arrPageIndex, unsigned int unLength) if (m_nMode != Mode::WriteAppend && !IncrementalUpdates()) return false; PDFDoc* pDocument = m_pReader->GetLastPDFDocument(); - int nPagesBefore = m_pReader->GetNumPages() - pDocument->getNumPages(); int nStartRefID = m_pReader->GetStartRefID(pDocument); bool bRes = SplitPages(arrPageIndex, unLength, pDocument, nStartRefID); if (!bRes) return false; - // Добавление merge страниц в редактируемые - PdfWriter::CDocument* pDoc = m_pWriter->GetDocument(); - Catalog* pCatalog = pDocument->getCatalog(); - for (int i = 0, nPages = unLength == 0 ? pDocument->getNumPages() : unLength; i < nPages; ++i) - { - Ref* pPageRef = pCatalog->getPageRef((arrPageIndex ? arrPageIndex[i] : i) + 1); - PdfWriter::CObjectBase* pObj = m_mObjManager.GetObj(pPageRef->num + nStartRefID); - if (pObj && pObj->GetType() == PdfWriter::object_type_DICT && ((PdfWriter::CDictObject*)pObj)->GetDictType() == PdfWriter::dict_type_PAGE) - pDoc->AddEditPage((PdfWriter::CPage*)pObj, nPagesBefore + i); - } - return bRes; } bool CPdfEditor::DeletePage(int nPageIndex) @@ -1788,9 +1910,9 @@ bool CPdfEditor::DeletePage(int nPageIndex) int nRefID = m_pReader->FindRefNum(nObjID, &pPDFDocument, &nStartRefID); if (nRefID > 0) { + XRefEntry* pEntry = pPDFDocument->getXRef()->getEntry(nRefID); Object oRef; - // TODO узнать gen - oRef.initRef(nRefID, 0); + oRef.initRef(nRefID, pEntry->gen); m_mObjManager.DeleteObjTree(&oRef, pPDFDocument->getXRef(), nStartRefID); } pPage->SetHidden(); @@ -1831,10 +1953,7 @@ bool CPdfEditor::EditAnnot(int _nPageIndex, int nID) { PdfWriter::CObjectBase* pObj = m_mObjManager.GetObj(nID); if (pObj) - { - pObj->SetHidden(); return true; - } PDFDoc* pPDFDocument = NULL; PdfReader::CPdfFontList* pFontList = NULL; @@ -2100,9 +2219,9 @@ bool CPdfEditor::DeleteAnnot(int nID, Object* oAnnots) int nRefID = m_pReader->FindRefNum(nID, &pPDFDocument, &nStartRefID); if (nRefID > 0) { + XRefEntry* pEntry = pPDFDocument->getXRef()->getEntry(nRefID); Object oRef; - // TODO узнать gen - oRef.initRef(nRefID, 0); + oRef.initRef(nRefID, pEntry->gen); m_mObjManager.DeleteObjTree(&oRef, pPDFDocument->getXRef(), nStartRefID); } pObj->SetHidden(); @@ -2193,9 +2312,9 @@ bool CPdfEditor::EditWidgets(IAdvancedCommand* pCommand) if (nRefID < 0) continue; + XRefEntry* pEntry = pPDFDocument->getXRef()->getEntry(nRefID); Object oParentRef; - // TODO узнать gen родителя - oParentRef.initRef(nRefID, 0); + oParentRef.initRef(nRefID, pEntry->gen); GetWidgetParent(pPDFDocument, pDoc, &oParentRef, nStartRefID); // TODO перевыставить детей oParentRef.free(); diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 95ebcae8a9..0a6b706da6 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -1779,6 +1779,7 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF if (pAnnot) { + m_pDocument->AddObject(pAnnot); m_pDocument->AddAnnotation(nID, pAnnot); pPage->AddAnnotation(pAnnot); } diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 1f4d6a980d..36912c6c53 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -732,7 +732,6 @@ namespace PdfWriter } void CDocument::AddAnnotation(const int& nID, CAnnotation* pAnnot) { - m_pXref->Add(pAnnot); m_mAnnotations[nID] = pAnnot; } CImageDict* CDocument::CreateImage() @@ -1504,6 +1503,10 @@ namespace PdfWriter return true; } + void CDocument::AddParent(int nID, CDictObject* pParent) + { + m_mParents[nID] = pParent; + } bool CDocument::EditParent(CXref* pXref, CDictObject* pParent, int nID) { if (!pParent || !EditXref(pXref)) diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index 62e232549f..88b3ea79f7 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -203,6 +203,7 @@ namespace PdfWriter bool MovePage(int nPageIndex, int nPos); void Sign(const TRect& oRect, CImageDict* pImage, ICertificate* pCert); bool EditAnnot (CXref* pXref, CAnnotation* pAnnot, int nID); + void AddParent(int nID, CDictObject* pParent); bool EditParent(CXref* pXref, CDictObject* pParent, int nID); bool DeleteAnnot(int nObjNum, int nObjGen); CAnnotation* GetAnnot(int nID); From 4b611b304b466c5441693459a64a44a8cea05396 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 27 Mar 2025 11:36:43 +0300 Subject: [PATCH 127/186] Read/Write parent field actions --- .../graphics/commands/AnnotField.cpp | 15 ++ DesktopEditor/graphics/commands/AnnotField.h | 1 + .../graphics/pro/js/wasm/js/drawingfile.js | 12 + .../pro/js/wasm/src/drawingfile_test.cpp | 18 +- PdfFile/PdfWriter.cpp | 243 ++++++++++-------- PdfFile/SrcReader/PdfAnnot.cpp | 97 +++---- PdfFile/SrcReader/PdfAnnot.h | 3 +- PdfFile/SrcWriter/Annotation.cpp | 22 ++ 8 files changed, 259 insertions(+), 152 deletions(-) diff --git a/DesktopEditor/graphics/commands/AnnotField.cpp b/DesktopEditor/graphics/commands/AnnotField.cpp index 355e5041c4..f08a0276a3 100644 --- a/DesktopEditor/graphics/commands/AnnotField.cpp +++ b/DesktopEditor/graphics/commands/AnnotField.cpp @@ -1117,6 +1117,21 @@ bool CWidgetsInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafil } 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); + } + } + } m_arrParents.push_back(pParent); } diff --git a/DesktopEditor/graphics/commands/AnnotField.h b/DesktopEditor/graphics/commands/AnnotField.h index 1212805aee..9276b06560 100644 --- a/DesktopEditor/graphics/commands/AnnotField.h +++ b/DesktopEditor/graphics/commands/AnnotField.h @@ -574,6 +574,7 @@ public: std::wstring sDV; std::vector arrI; std::vector arrV; + std::vector arrAction; std::vector< std::pair > arrOpt; }; diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js index 35afdc4498..5ad30a6dcc 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js @@ -607,6 +607,18 @@ CFile.prototype["getInteractiveFormsInfo"] = function() rec["multipleSelection"] = (rec["flag"] >> 21) & 1; // MultiSelect rec["commitOnSelChange"] = (rec["flag"] >> 26) & 1; // CommitOnSelChange } + if (flags & (1 << 8)) + { + 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]); + } + } res["Parents"].push(rec); } diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp index 7f3d08c7e7..7f2519e95b 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp @@ -389,6 +389,22 @@ void ReadInteractiveForms(BYTE* pWidgets, int& 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; + } std::cout << std::endl; } @@ -682,7 +698,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; diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 1cc6e2aecc..5de28f656a 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -1669,6 +1669,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) @@ -2181,110 +2296,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); } @@ -2743,6 +2755,29 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi } 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(), pAction); + 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(), pAction); + } + } + } } std::vector arrBI = pFieldInfo->GetButtonImg(); diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index 9ab50ae928..b1c3978320 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -1510,7 +1510,7 @@ CAnnotWidget::CAnnotWidget(PDFDoc* pdfDoc, AcroFormField* pField) : CAnnot(pdfDo // 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); @@ -1524,11 +1524,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) @@ -1536,8 +1531,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) { @@ -1550,39 +1543,6 @@ 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() @@ -2526,7 +2486,7 @@ CAnnots::CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontLi // Родители Object oParentRefObj; if (oField.dictLookupNF("Parent", &oParentRefObj)->isRef()) - getParents(xref, &oParentRefObj); + getParents(pdfDoc, &oParentRefObj); oParentRefObj.free(); oField.free(); oFieldRef.free(); @@ -2580,15 +2540,15 @@ 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) { - if (!oFieldRef || !xref || !oFieldRef->isRef() || + if (!oFieldRef || !pdfDoc || !oFieldRef->isRef() || std::find_if(m_arrParents.begin(), m_arrParents.end(), [oFieldRef] (CAnnotParent* pAP) { return oFieldRef->getRefNum() == 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); @@ -2712,6 +2672,42 @@ void CAnnots::getParents(XRef* xref, Object* oFieldRef) } 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(); + m_arrParents.push_back(pAnnotParent); Object oParentRefObj; @@ -2719,7 +2715,7 @@ void CAnnots::getParents(XRef* xref, Object* oFieldRef) { pAnnotParent->unFlags |= (1 << 4); pAnnotParent->unRefNumParent = oParentRefObj.getRefNum(); - getParents(xref, &oParentRefObj); + getParents(pdfDoc, &oParentRefObj); } oParentRefObj.free(); @@ -3677,6 +3673,15 @@ void CAnnots::CAnnotParent::ToWASM(NSWasm::CData& oRes) } 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); + } + } } void CAnnot::ToWASM(NSWasm::CData& oRes) { diff --git a/PdfFile/SrcReader/PdfAnnot.h b/PdfFile/SrcReader/PdfAnnot.h index 34515efe5a..20c98f3ded 100644 --- a/PdfFile/SrcReader/PdfAnnot.h +++ b/PdfFile/SrcReader/PdfAnnot.h @@ -616,12 +616,13 @@ private: std::vector arrI; std::vector arrV; std::vector< std::pair > arrOpt; + std::vector arrAction; // Действия std::string sT; std::string sV; std::string sDV; }; - void getParents(XRef* xref, Object* oFieldRef); + void getParents(PDFDoc* pdfDoc, Object* oFieldRef); std::vector m_arrCO; // Порядок вычислений - CO std::vector m_arrParents; // Родительские Fields diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index 66f8d0d2ff..96670e8011 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -1655,6 +1655,22 @@ namespace PdfWriter if (!pAction) return; + if (pAction->m_sType == "A") + { + Add(pAction->m_sType.c_str(), pAction); + return; + } + + CDictObject* pAA = (CDictObject*)Get("AA"); + if (!pAA) + { + pAA = new CDictObject(); + Add("AA", pAA); + } + + pAA->Add(pAction->m_sType.c_str(), pAction); + + /* if (pAction->m_sType == "A") { CDictObject* pOwner = GetObjOwnValue(pAction->m_sType); @@ -1691,6 +1707,7 @@ namespace PdfWriter if (pAA) pAA->Add(sAA.c_str(), pAction); + */ } std::string CWidgetAnnotation::GetDAforAP(CFontDict* pFont) { @@ -2382,6 +2399,11 @@ namespace PdfWriter void CAction::SetType(const std::wstring& wsType) { m_sType = U_TO_UTF8(wsType); + Add("S", m_sType.c_str()); + } + void CAction::SetNext(CAction* pNext) + { + Add("Next", pNext); } //---------------------------------------------------------------------------------------- CActionResetForm::CActionResetForm(CXref* pXref) : CAction(pXref) From eb37cabb4e8f82823faa8872e48908ebf4aa60b9 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 27 Mar 2025 12:43:02 +0300 Subject: [PATCH 128/186] Fix write Action --- DesktopEditor/graphics/commands/AnnotField.cpp | 2 +- PdfFile/PdfWriter.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/DesktopEditor/graphics/commands/AnnotField.cpp b/DesktopEditor/graphics/commands/AnnotField.cpp index f08a0276a3..324ec84322 100644 --- a/DesktopEditor/graphics/commands/AnnotField.cpp +++ b/DesktopEditor/graphics/commands/AnnotField.cpp @@ -985,7 +985,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(); diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 5de28f656a..15421831f5 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -2765,7 +2765,7 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi continue; if (pA->m_sType == "A") - pParentObj->Add(pA->m_sType.c_str(), pAction); + pParentObj->Add(pA->m_sType.c_str(), pA); else { PdfWriter::CDictObject* pAA = (PdfWriter::CDictObject*)pParentObj->Get("AA"); @@ -2774,7 +2774,7 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi pAA = new PdfWriter::CDictObject(); pParentObj->Add("AA", pAA); } - pAA->Add(pA->m_sType.c_str(), pAction); + pAA->Add(pA->m_sType.c_str(), pA); } } } From 0e09d4ab7afbd09907980b9839559852e3234541 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 27 Mar 2025 16:23:39 +0600 Subject: [PATCH 129/186] Fix bug #73694 --- .../XlsFile/Format/Logic/Biff_records/XF.h | 8 ++-- OOXML/Binary/Sheets/Writer/BinaryReaderS.cpp | 37 +++++++++++++++++-- OOXML/XlsxFormat/Styles/CellStyles.cpp | 4 +- 3 files changed, 39 insertions(+), 10 deletions(-) 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/OOXML/Binary/Sheets/Writer/BinaryReaderS.cpp b/OOXML/Binary/Sheets/Writer/BinaryReaderS.cpp index 044f12478b..fe0953c673 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReaderS.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReaderS.cpp @@ -6762,14 +6762,43 @@ int BinaryWorksheetsTableReader::ReadPos(BYTE type, long length, void* poResult) int BinaryWorksheetsTableReader::ReadSheetData(BYTE type, long length, void* poResult) { int res = c_oSerConstants::ReadOk; - if (c_oSerWorksheetsTypes::XlsbPos == type) + 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); + } - OOX::Spreadsheet::CSheetData oSheetData; - oSheetData.fromXLSB(m_oBufferedStream, m_oBufferedStream.XlsbReadRecordType(), m_oSaveParams.pCSVWriter, *m_pCurStreamWriter); - + } + 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; } 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; From 723e4713fdb9365707ef6bc4a1062292b6093cc3 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 28 Mar 2025 14:02:01 +0300 Subject: [PATCH 130/186] Crate parents for widget --- .../pro/js/wasm/src/drawingfile_test.cpp | 5 + PdfFile/PdfWriter.cpp | 143 +++++++++++------- PdfFile/SrcWriter/Annotation.cpp | 5 + PdfFile/SrcWriter/Annotation.h | 3 + PdfFile/SrcWriter/Document.cpp | 100 ++++++++++-- PdfFile/SrcWriter/Document.h | 3 + 6 files changed, 197 insertions(+), 62 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp index 7f2519e95b..edcde6d46c 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp @@ -380,6 +380,11 @@ 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 << " ], "; } diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 15421831f5..21f307f793 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -2288,6 +2288,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)) @@ -2631,51 +2633,55 @@ 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 << 0)) + pParentObj->Add("T", new PdfWriter::CStringObject((U_TO_UTF8(pParent->sName)).c_str())); + + m_pDocument->SetParentKids(pParent->nID); + PdfWriter::CArrayObject* pKids = dynamic_cast(pParentObj->Get("Kids")); + if (!pKids) + { + pKids = new PdfWriter::CArrayObject(); + pParentObj->Add("Kids", pKids); + } + if (nFlags & (1 << 1)) { 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) + 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::WidgetCheckbox || nType == PdfWriter::WidgetRadiobutton) { - 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; - } + 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; } } @@ -2698,6 +2704,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); } @@ -2707,24 +2715,20 @@ 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); - 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::CChoiceWidget* pKid = dynamic_cast(pObj); - if (!pKid->HaveAPV()) - DrawChoiceWidget(pAppFonts, pKid, pParent->arrV); - } + PdfWriter::CChoiceWidget* pKid = dynamic_cast(pObj); + if (!pKid->HaveAPV()) + DrawChoiceWidget(pAppFonts, pKid, pParent->arrV); } } } @@ -2800,14 +2804,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; @@ -2839,6 +2844,38 @@ 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() diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index 96670e8011..acdeef640c 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -1456,6 +1456,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; @@ -1596,6 +1597,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); diff --git a/PdfFile/SrcWriter/Annotation.h b/PdfFile/SrcWriter/Annotation.h index e1bb6a46ec..15725c5dc1 100644 --- a/PdfFile/SrcWriter/Annotation.h +++ b/PdfFile/SrcWriter/Annotation.h @@ -418,6 +418,7 @@ namespace PdfWriter double m_dFontSizeAP; std::vector m_arrTC; BYTE m_nQ; + int m_nParentID; void CheckMK(); @@ -443,6 +444,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); @@ -457,6 +459,7 @@ namespace PdfWriter 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(); diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 3a8727a72c..c4bd90466f 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -672,8 +672,7 @@ namespace PdfWriter return NULL; CWidgetAnnotation* pWidget = new CWidgetAnnotation(m_pXref, EAnnotType::AnnotWidget); - if (!pWidget) - return NULL; + m_pXref->Add(pWidget); CArrayObject* ppFields = (CArrayObject*)m_pAcroForm->Get("Fields"); ppFields->Add(pWidget); @@ -682,21 +681,52 @@ namespace PdfWriter } CAnnotation* CDocument::CreatePushButtonWidget() { - return new CPushButtonWidget(m_pXref); + if (!CheckAcroForm()) + return NULL; + + CWidgetAnnotation* pWidget = new CPushButtonWidget(m_pXref); + m_pXref->Add(pWidget); + CArrayObject* ppFields = (CArrayObject*)m_pAcroForm->Get("Fields"); + ppFields->Add(pWidget); + + return pWidget; } CAnnotation* CDocument::CreateCheckBoxWidget() { - return new CCheckBoxWidget(m_pXref); + if (!CheckAcroForm()) + return NULL; + + CWidgetAnnotation* pWidget = new CCheckBoxWidget(m_pXref); + m_pXref->Add(pWidget); + CArrayObject* ppFields = (CArrayObject*)m_pAcroForm->Get("Fields"); + ppFields->Add(pWidget); + + return pWidget; } CAnnotation* CDocument::CreateTextWidget() { - CAnnotation* pNew = new CTextWidget(m_pXref); - pNew->Add("FT", "Tx"); - return pNew; + if (!CheckAcroForm()) + return NULL; + + CAnnotation* pWidget = new CTextWidget(m_pXref); + m_pXref->Add(pWidget); + pWidget->Add("FT", "Tx"); + CArrayObject* ppFields = (CArrayObject*)m_pAcroForm->Get("Fields"); + ppFields->Add(pWidget); + + return pWidget; } CAnnotation* CDocument::CreateChoiceWidget() { - return new CChoiceWidget(m_pXref); + if (!CheckAcroForm()) + return NULL; + + CAnnotation* pWidget = new CChoiceWidget(m_pXref); + m_pXref->Add(pWidget); + CArrayObject* ppFields = (CArrayObject*)m_pAcroForm->Get("Fields"); + ppFields->Add(pWidget); + + return pWidget; } CAnnotation* CDocument::CreateSignatureWidget() { @@ -718,7 +748,6 @@ namespace PdfWriter } void CDocument::AddAnnotation(const int& nID, CAnnotation* pAnnot) { - m_pXref->Add(pAnnot); m_mAnnotations[nID] = pAnnot; } CImageDict* CDocument::CreateImage() @@ -1472,6 +1501,13 @@ namespace PdfWriter return true; } + 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)) @@ -1519,6 +1555,52 @@ namespace PdfWriter return p->second; return NULL; } + void CDocument::SetParentKids(int nParentID) + { + 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); + } + } CPage* CDocument::CreateFakePage() { return new CPage(this, NULL); diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index 9bbb4045b6..2d825b31d8 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -200,6 +200,7 @@ namespace PdfWriter void Sign(const TRect& oRect, CImageDict* pImage, ICertificate* pCert); std::wstring GetEditPdfPath() { return m_wsFilePath; } bool EditAnnot (CXref* pXref, CAnnotation* pAnnot, int nID); + CDictObject* CreateParent(int nID); bool EditParent(CXref* pXref, CDictObject* pParent, int nID); bool DeleteAnnot(int nObjNum, int nObjGen); CAnnotation* GetAnnot(int nID); @@ -208,7 +209,9 @@ namespace PdfWriter void SetCurPage(CPage* pPage) { m_pCurPage = pPage; } CPage* CreateFakePage(); bool EditCO(const std::vector& arrCO); + void 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(); From 29c8e185ca5f02ea7759bc2ed6f32f83187ea72f Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 28 Mar 2025 17:31:56 +0300 Subject: [PATCH 131/186] Fix ExportValue from parent --- PdfFile/SrcReader/PdfAnnot.cpp | 32 +------------------------------- PdfFile/SrcWriter/Document.cpp | 3 +++ PdfFile/SrcWriter/Field.h | 2 ++ 3 files changed, 6 insertions(+), 31 deletions(-) diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index b1c3978320..cb8f90cc5c 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -1180,7 +1180,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,36 +1189,6 @@ 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; } } diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index c4bd90466f..4d6322d906 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -686,6 +686,7 @@ namespace PdfWriter CWidgetAnnotation* pWidget = new CPushButtonWidget(m_pXref); m_pXref->Add(pWidget); + pWidget->Add("FT", "Btn"); CArrayObject* ppFields = (CArrayObject*)m_pAcroForm->Get("Fields"); ppFields->Add(pWidget); @@ -698,6 +699,7 @@ namespace PdfWriter CWidgetAnnotation* pWidget = new CCheckBoxWidget(m_pXref); m_pXref->Add(pWidget); + pWidget->Add("FT", "Btn"); CArrayObject* ppFields = (CArrayObject*)m_pAcroForm->Get("Fields"); ppFields->Add(pWidget); @@ -723,6 +725,7 @@ namespace PdfWriter CAnnotation* pWidget = new CChoiceWidget(m_pXref); m_pXref->Add(pWidget); + pWidget->Add("FT", "Ch"); CArrayObject* ppFields = (CArrayObject*)m_pAcroForm->Get("Fields"); ppFields->Add(pWidget); diff --git a/PdfFile/SrcWriter/Field.h b/PdfFile/SrcWriter/Field.h index 5c11b57be4..ca2750a156 100644 --- a/PdfFile/SrcWriter/Field.h +++ b/PdfFile/SrcWriter/Field.h @@ -418,6 +418,8 @@ namespace PdfWriter void DrawTextUpArrow(const std::string& sColor); void DrawTextUpLeftArrow(const std::string& sColor); + void DrawRadiobuttonCircle(); + CStream* GetStream() const { return m_pStream; } CFontDict* GetFont() { return m_pFont; } From d2b5299b9929f6c5d00e35ef3aed7db8600fcc02 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 31 Mar 2025 11:41:11 +0300 Subject: [PATCH 132/186] Fix ResetTextFormField --- PdfFile/SrcReader/Adaptors.cpp | 4 ++++ PdfFile/SrcReader/Adaptors.h | 1 + PdfFile/SrcReader/PdfAnnot.cpp | 2 ++ 3 files changed, 7 insertions(+) diff --git a/PdfFile/SrcReader/Adaptors.cpp b/PdfFile/SrcReader/Adaptors.cpp index 62ac8e8001..1d240b14d2 100644 --- a/PdfFile/SrcReader/Adaptors.cpp +++ b/PdfFile/SrcReader/Adaptors.cpp @@ -185,6 +185,10 @@ bool GlobalParamsAdaptor::GetCMap(const char* sName, char*& pData, unsigned int& return false; } +void GlobalParamsAdaptor::ResetTextFormField() +{ + m_sTextFormField.clear(); +} void GlobalParamsAdaptor::AddTextFormField(const std::wstring& sText) { m_sTextFormField += sText; diff --git a/PdfFile/SrcReader/Adaptors.h b/PdfFile/SrcReader/Adaptors.h index ca27ed5f15..58bff7e978 100644 --- a/PdfFile/SrcReader/Adaptors.h +++ b/PdfFile/SrcReader/Adaptors.h @@ -91,6 +91,7 @@ public: void SetCMapMemory(BYTE* pData, DWORD nSizeData); bool GetCMap(const char* sName, char*& pData, unsigned int& nSize); + void ResetTextFormField(); void AddTextFormField(const std::wstring& sText); std::string GetTextFormField(); void setDrawFormField(bool bDrawFormField) { m_bDrawFormField = bDrawFormField; } diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index cb8f90cc5c..7bca8e18f6 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -3440,6 +3440,7 @@ void CAnnotAP::Draw(PDFDoc* pdfDoc, Object* oAP, int nRasterH, int nBackgroundCo // Отрисовка внешних видов аннотации AcroFormFieldType oType = pField->getAcroFormFieldType(); ((GlobalParamsAdaptor*)globalParams)->setDrawFormField(true); + ((GlobalParamsAdaptor*)globalParams)->ResetTextFormField(); 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; @@ -3493,6 +3494,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); + ((GlobalParamsAdaptor*)globalParams)->ResetTextFormField(); // Отрисовка внешних видов аннотации Object oAnnot; XRef* xref = pdfDoc->getXRef(); From 1d9230b731b8de697491eee8edec33b76d16a995 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 31 Mar 2025 15:27:17 +0300 Subject: [PATCH 133/186] Create DrawCheckBoxCircle --- PdfFile/PdfWriter.cpp | 5 +- PdfFile/SrcWriter/Annotation.cpp | 336 ++------------------- PdfFile/SrcWriter/Annotation.h | 26 +- PdfFile/SrcWriter/Field.cpp | 482 ++++++++++++++++++++++++++++++- PdfFile/SrcWriter/Field.h | 11 +- 5 files changed, 538 insertions(+), 322 deletions(-) diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 21f307f793..a226e9c773 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -2387,7 +2387,7 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF pButtonWidget->SetV(wsValue); } - std::wstring wsStyleValue = pButtonWidget->SetStyle(pPrB->GetStyle()); + pButtonWidget->SetStyle(pPrB->GetStyle()); // ВНЕШНИЙ ВИД // Если изменился текущий внешний вид @@ -2398,6 +2398,8 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF return S_OK; } + pButtonWidget->SetAP(); + /* put_FontName(wsFontName); put_FontStyle(nStyle); put_FontSize(dFontSize); @@ -2415,6 +2417,7 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF double dBaseLine = dY2 - dY1 - dFontSize - dMargin; pButtonWidget->SetAP(wsStyleValue, NULL, 0, 0, dBaseLine, NULL, NULL); } + */ } } else if (oInfo.IsTextWidget()) diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index acdeef640c..d2761319f7 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -71,6 +71,10 @@ 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", "8", "u", "l", "H", "n" + }; void AddToVectorD(CDictObject* pObj, const std::string& sName, const std::vector& arrV) { @@ -168,6 +172,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]); @@ -766,299 +771,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 @@ -2091,6 +1809,7 @@ namespace PdfWriter CCheckBoxWidget::CCheckBoxWidget(CXref* pXref) : CWidgetAnnotation(pXref, AnnotWidget) { m_nSubtype = WidgetRadiobutton; + m_nStyle = ECheckBoxStyle::Circle; } void CCheckBoxWidget::SetV(const std::wstring& wsV) { @@ -2104,37 +1823,34 @@ 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; } + void CCheckBoxWidget::SetAP() + { + if (Get("AP")) + return; + + CCheckBoxAnnotAppearance* pAP = new CCheckBoxAnnotAppearance(m_pXref, this, m_sAP_N_Yes.empty() ? NULL : m_sAP_N_Yes.c_str()); + Add("AP", pAP); + + if (m_nStyle == ECheckBoxStyle::Circle) + { + pAP->GetYesN()->DrawCheckBoxCircle(true); + pAP->GetOffN()->DrawCheckBoxCircle(false); + pAP->GetYesD()->DrawCheckBoxCircle(true); + pAP->GetOffD()->DrawCheckBoxCircle(false); + } + } void CCheckBoxWidget::SwitchAP(const std::string& sV) { CObjectBase* pAP, *pAPN; diff --git a/PdfFile/SrcWriter/Annotation.h b/PdfFile/SrcWriter/Annotation.h index 15725c5dc1..88bc1e5fd0 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 { @@ -284,10 +293,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 { @@ -519,15 +528,16 @@ namespace PdfWriter { private: std::string m_sAP_N_Yes; + ECheckBoxStyle m_nStyle; public: CCheckBoxWidget(CXref* pXref); void SetV(const std::wstring& wsV); - std::wstring SetStyle(BYTE nStyle); + void SetStyle(BYTE nStyle); void SetAP_N_Yes(const std::wstring& wsAP_N_Yes); virtual void SetFlag (const int& nFlag); - + void SetAP(); void SwitchAP(const std::string& sV); }; class CTextWidget : public CWidgetAnnotation diff --git a/PdfFile/SrcWriter/Field.cpp b/PdfFile/SrcWriter/Field.cpp index ba50565fb4..e0f25963f4 100644 --- a/PdfFile/SrcWriter/Field.cpp +++ b/PdfFile/SrcWriter/Field.cpp @@ -53,6 +53,286 @@ 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); + } + std::string GetColor(CArrayObject* pArr, bool bCAPS, float dDiff = 0) + { + std::string sDA; + if (!pArr) + return sDA; + + int nSize = pArr->GetCount(); + for (int i = 0; i < nSize; ++i) + { + CObjectBase* pColor = pArr->Get(i); + float fColor = pColor->GetType() == object_type_REAL ? ((CRealObject*)pColor)->Get() : ((CNumberObject*)pColor)->Get(); + + sDA.append(std::to_string(fColor + dDiff)); + sDA.append(" "); + } + + if (nSize == 3) + sDA.append(bCAPS ? "RG" : "rg"); + else if (nSize == 4) + sDA.append(bCAPS ? "K" : "k"); + else if (nSize == 1) + sDA.append(bCAPS ? "G" : "g"); + + return sDA; + } + //---------------------------------------------------------------------------------------- // CFieldBase //---------------------------------------------------------------------------------------- @@ -1591,7 +1871,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 +1887,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; @@ -2844,4 +3142,186 @@ 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"); + + CObjectBase* pObj = m_pAnnot->Get("IC"); + if (pObj && pObj->GetType() == object_type_ARRAY) + { + m_pStream->WriteStr(GetColor(dynamic_cast(pObj), false).c_str()); + m_pStream->WriteStr("\012"); + } + + m_pStream->WriteStr(GetColor(dynamic_cast(Get("C")), true).c_str()); + m_pStream->WriteStr("\012"); + + 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::DrawCheckBoxCheck(bool bSet, bool bN) + { + + } + void CAnnotAppearanceObject::DrawCheckBoxCross(bool bSet, bool bN) + { + + } + void CAnnotAppearanceObject::DrawCheckBoxDiamond(bool bSet, bool bN) + { + + } + void CAnnotAppearanceObject::DrawCheckBoxCircle(bool bSet, bool bN) + { + CCheckBoxWidget* pAnnot = dynamic_cast(m_pAnnot); + if (!pAnnot) + return; + + std::string sBC = pAnnot->GetBCforAP(); + std::string sBG = pAnnot->GetBGforAP(bN ? 0 : -0.250977); + + double dW = m_pAnnot->GetRect().fRight - m_pAnnot->GetRect().fLeft; + double dH = 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; + + // Задний фон + m_pStream->WriteStr(sBG.c_str()); + m_pStream->WriteStr("q\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"); + + // Граница + double dBorder = 1; + EBorderType nBorderType = EBorderType::Inset; + if (m_pAnnot->HaveBorder()) + { + dBorder = m_pAnnot->GetBorderWidth(); + nBorderType = m_pAnnot->GetBorderType(); + } + 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(sBC.c_str()); + m_pStream->WriteStr("q\012"); + m_pStream->WriteStr("1 0 0 1 "); + m_pStream->WriteReal(dCX); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dCY); + m_pStream->WriteStr(" cm\012"); + switch (nBorderType) { + case EBorderType::Solid: + case EBorderType::Dashed: + { + StreamWriteCircle(m_pStream, 0, 0, dR - dBorder / 2.0); + m_pStream->WriteStr("s\012Q\012"); + break; + } + case EBorderType::Beveled: + { + break; + } + case EBorderType::Inset: + { + StreamWriteCircle(m_pStream, 0, 0, dR - dBorder / 2.0); + m_pStream->WriteStr("s\012Q\012"); + + 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 (bN) + m_pStream->WriteStr("0 G\012"); + else + m_pStream->WriteStr("0.501953 G\012"); + m_pStream->WriteStr("q\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 (bN) + m_pStream->WriteStr("1 G\012"); + else + m_pStream->WriteStr("0.75293 G\012"); + m_pStream->WriteStr("q\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"); + + break; + } + case EBorderType::Underline: + { + break; + } + } + + // Установлен + if (!bSet) + return; + 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 - dBorder); + m_pStream->WriteStr("f\012Q\012"); + } + void CAnnotAppearanceObject::DrawCheckBoxStar(bool bSet, bool bN) + { + + } + void CAnnotAppearanceObject::DrawCheckBoxSquare(bool bSet, bool bN) + { + + } } diff --git a/PdfFile/SrcWriter/Field.h b/PdfFile/SrcWriter/Field.h index ca2750a156..9498a76e9b 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,7 +418,14 @@ namespace PdfWriter void DrawTextUpArrow(const std::string& sColor); void DrawTextUpLeftArrow(const std::string& sColor); - void DrawRadiobuttonCircle(); + void DrawLine(); + + void DrawCheckBoxCheck(bool bSet, bool bN); + void DrawCheckBoxCross(bool bSet, bool bN); + void DrawCheckBoxDiamond(bool bSet, bool bN); + void DrawCheckBoxCircle(bool bSet, bool bN); + void DrawCheckBoxStar(bool bSet, bool bN); + void DrawCheckBoxSquare(bool bSet, bool bN); CStream* GetStream() const { return m_pStream; } CFontDict* GetFont() { return m_pFont; } From a92bf23081199edfdd339a44c261b4a22ca791ea Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 31 Mar 2025 15:42:54 +0300 Subject: [PATCH 134/186] Fix EBorderType --- PdfFile/PdfWriter.cpp | 12 +++--- PdfFile/SrcWriter/Annotation.cpp | 21 ++++++++--- PdfFile/SrcWriter/Annotation.h | 1 + PdfFile/SrcWriter/Field.cpp | 65 +++++++++----------------------- 4 files changed, 40 insertions(+), 59 deletions(-) diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index a226e9c773..8e6eee82e7 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -3862,8 +3862,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; // Коды, шрифты, количество @@ -4024,8 +4024,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()) @@ -4200,8 +4200,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/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index d2761319f7..fe3cb7f2c3 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -308,6 +308,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); @@ -1738,7 +1749,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; @@ -1845,10 +1856,10 @@ namespace PdfWriter if (m_nStyle == ECheckBoxStyle::Circle) { - pAP->GetYesN()->DrawCheckBoxCircle(true); - pAP->GetOffN()->DrawCheckBoxCircle(false); - pAP->GetYesD()->DrawCheckBoxCircle(true); - pAP->GetOffD()->DrawCheckBoxCircle(false); + pAP->GetYesN()->DrawCheckBoxCircle(true, true); + pAP->GetOffN()->DrawCheckBoxCircle(false, true); + pAP->GetYesD()->DrawCheckBoxCircle(true, false); + pAP->GetOffD()->DrawCheckBoxCircle(false, false); } } void CCheckBoxWidget::SwitchAP(const std::string& sV) diff --git a/PdfFile/SrcWriter/Annotation.h b/PdfFile/SrcWriter/Annotation.h index 88bc1e5fd0..328d10213b 100644 --- a/PdfFile/SrcWriter/Annotation.h +++ b/PdfFile/SrcWriter/Annotation.h @@ -202,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; } diff --git a/PdfFile/SrcWriter/Field.cpp b/PdfFile/SrcWriter/Field.cpp index e0f25963f4..054983f65f 100644 --- a/PdfFile/SrcWriter/Field.cpp +++ b/PdfFile/SrcWriter/Field.cpp @@ -307,31 +307,6 @@ namespace PdfWriter DrawArrow(pStream, nLE1, tx1, ty1, dDX, dDY, dBorderSize); DrawArrow(pStream, nLE2, tx2, ty2, -dDX, -dDY, dBorderSize); } - std::string GetColor(CArrayObject* pArr, bool bCAPS, float dDiff = 0) - { - std::string sDA; - if (!pArr) - return sDA; - - int nSize = pArr->GetCount(); - for (int i = 0; i < nSize; ++i) - { - CObjectBase* pColor = pArr->Get(i); - float fColor = pColor->GetType() == object_type_REAL ? ((CRealObject*)pColor)->Get() : ((CNumberObject*)pColor)->Get(); - - sDA.append(std::to_string(fColor + dDiff)); - sDA.append(" "); - } - - if (nSize == 3) - sDA.append(bCAPS ? "RG" : "rg"); - else if (nSize == 4) - sDA.append(bCAPS ? "K" : "k"); - else if (nSize == 1) - sDA.append(bCAPS ? "G" : "g"); - - return sDA; - } //---------------------------------------------------------------------------------------- // CFieldBase @@ -2055,7 +2030,7 @@ namespace PdfWriter BYTE nType = 0; if (pAnnot) { - nType = pAnnot->GetBorderType(); + nType = (BYTE)pAnnot->GetBorderType(); switch (nType) { case 1: // Beveled @@ -2277,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; } @@ -2291,7 +2266,7 @@ namespace PdfWriter BYTE nType = 0; if (pAnnot) { - nType = pAnnot->GetBorderType(); + nType = (BYTE)pAnnot->GetBorderType(); switch (nType) { case 1: // Beveled @@ -2540,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()) @@ -2607,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); @@ -2669,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(' '); @@ -2710,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"); @@ -2751,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; @@ -2764,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(' '); @@ -3154,17 +3129,11 @@ namespace PdfWriter m_pStream->WriteReal(dBorderSize); m_pStream->WriteStr(" w\012"); - CObjectBase* pObj = m_pAnnot->Get("IC"); - if (pObj && pObj->GetType() == object_type_ARRAY) - { - m_pStream->WriteStr(GetColor(dynamic_cast(pObj), false).c_str()); - m_pStream->WriteStr("\012"); - } + m_pStream->WriteStr(m_pAnnot->GetColorName("IC", false).c_str()); - m_pStream->WriteStr(GetColor(dynamic_cast(Get("C")), true).c_str()); - m_pStream->WriteStr("\012"); + m_pStream->WriteStr(m_pAnnot->GetColorName("C", true).c_str()); - pObj = m_pAnnot->Get("CA"); + CObjectBase* pObj = m_pAnnot->Get("CA"); if (pObj && pObj->GetType() == object_type_REAL) { float dAlpha = ((CRealObject*)pObj)->Get(); From e4188148ba14e4e5a6a062e057900e70c0700d82 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 31 Mar 2025 18:00:10 +0300 Subject: [PATCH 135/186] Create DrawCheckBoxSquare --- PdfFile/SrcWriter/Annotation.cpp | 18 ++- PdfFile/SrcWriter/Annotation.h | 3 +- PdfFile/SrcWriter/Field.cpp | 190 +++++++++++++++++++++---------- PdfFile/SrcWriter/Field.h | 4 - 4 files changed, 145 insertions(+), 70 deletions(-) diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index fe3cb7f2c3..ea82665efb 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -73,7 +73,12 @@ namespace PdfWriter }; const static char* c_sCheckBoxStyleNames[] = { - "4", "8", "u", "l", "H", "n" + "4", // Check + "8", // Cross + "u", // Diamond + "l", // Circle + "H", // Star + "n" // Square }; void AddToVectorD(CDictObject* pObj, const std::string& sName, const std::vector& arrV) @@ -1461,10 +1466,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() @@ -1861,6 +1866,13 @@ namespace PdfWriter pAP->GetYesD()->DrawCheckBoxCircle(true, false); pAP->GetOffD()->DrawCheckBoxCircle(false, false); } + else + { + pAP->GetYesN()->DrawCheckBoxSquare(true, true); + pAP->GetOffN()->DrawCheckBoxSquare(false, true); + pAP->GetYesD()->DrawCheckBoxSquare(true, false); + pAP->GetOffD()->DrawCheckBoxSquare(false, false); + } } void CCheckBoxWidget::SwitchAP(const std::string& sV) { diff --git a/PdfFile/SrcWriter/Annotation.h b/PdfFile/SrcWriter/Annotation.h index 328d10213b..4ce0925b6b 100644 --- a/PdfFile/SrcWriter/Annotation.h +++ b/PdfFile/SrcWriter/Annotation.h @@ -465,7 +465,7 @@ 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; } @@ -536,6 +536,7 @@ namespace PdfWriter void SetV(const std::wstring& wsV); void SetStyle(BYTE nStyle); + ECheckBoxStyle GetStyle() { return m_nStyle; } void SetAP_N_Yes(const std::wstring& wsAP_N_Yes); virtual void SetFlag (const int& nFlag); void SetAP(); diff --git a/PdfFile/SrcWriter/Field.cpp b/PdfFile/SrcWriter/Field.cpp index 054983f65f..c7c1ab0027 100644 --- a/PdfFile/SrcWriter/Field.cpp +++ b/PdfFile/SrcWriter/Field.cpp @@ -3162,18 +3162,6 @@ namespace PdfWriter 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::DrawCheckBoxCheck(bool bSet, bool bN) - { - - } - void CAnnotAppearanceObject::DrawCheckBoxCross(bool bSet, bool bN) - { - - } - void CAnnotAppearanceObject::DrawCheckBoxDiamond(bool bSet, bool bN) - { - } void CAnnotAppearanceObject::DrawCheckBoxCircle(bool bSet, bool bN) { @@ -3181,17 +3169,21 @@ namespace PdfWriter if (!pAnnot) return; - std::string sBC = pAnnot->GetBCforAP(); - std::string sBG = pAnnot->GetBGforAP(bN ? 0 : -0.250977); - + 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 = 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; // Задний фон - m_pStream->WriteStr(sBG.c_str()); - m_pStream->WriteStr("q\012"); + m_pStream->WriteStr(pAnnot->GetBGforAP(!bN && nBorderType != EBorderType::Beveled ? -0.250977 : 0).c_str()); + m_pStream->WriteStr("\012q\012"); m_pStream->WriteStr("1 0 0 1 "); m_pStream->WriteReal(dCX); m_pStream->WriteChar(' '); @@ -3201,13 +3193,6 @@ namespace PdfWriter m_pStream->WriteStr("f\012Q\012"); // Граница - double dBorder = 1; - EBorderType nBorderType = EBorderType::Inset; - if (m_pAnnot->HaveBorder()) - { - dBorder = m_pAnnot->GetBorderWidth(); - nBorderType = m_pAnnot->GetBorderType(); - } if (dBorder != 1) { m_pStream->WriteReal(dBorder); @@ -3215,62 +3200,46 @@ namespace PdfWriter } if (nBorderType == EBorderType::Dashed) m_pStream->WriteStr(m_pAnnot->GetBorderDash().c_str()); - m_pStream->WriteStr(sBC.c_str()); + m_pStream->WriteStr(pAnnot->GetBCforAP().c_str()); m_pStream->WriteStr("q\012"); m_pStream->WriteStr("1 0 0 1 "); m_pStream->WriteReal(dCX); m_pStream->WriteChar(' '); m_pStream->WriteReal(dCY); m_pStream->WriteStr(" cm\012"); - switch (nBorderType) { - case EBorderType::Solid: - case EBorderType::Dashed: - { - StreamWriteCircle(m_pStream, 0, 0, dR - dBorder / 2.0); - m_pStream->WriteStr("s\012Q\012"); - break; - } - case EBorderType::Beveled: - { - break; - } - case EBorderType::Inset: - { - StreamWriteCircle(m_pStream, 0, 0, dR - dBorder / 2.0); - m_pStream->WriteStr("s\012Q\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 (bN) - m_pStream->WriteStr("0 G\012"); - else - m_pStream->WriteStr("0.501953 G\012"); - m_pStream->WriteStr("q\012"); + 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 (bN) - m_pStream->WriteStr("1 G\012"); - else - m_pStream->WriteStr("0.75293 G\012"); - m_pStream->WriteStr("q\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"); - - break; - } - case EBorderType::Underline: - { - break; - } } // Установлен @@ -3284,13 +3253,110 @@ namespace PdfWriter m_pStream->WriteStr(" cm\012"); StreamWriteCircle(m_pStream, 0, 0, dR / 2.0 - dBorder); m_pStream->WriteStr("f\012Q\012"); - } - void CAnnotAppearanceObject::DrawCheckBoxStar(bool bSet, bool bN) - { - } 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 = m_pAnnot->GetRect().fBottom - m_pAnnot->GetRect().fTop; + + // Задний фон + 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"); + + 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()); + + StreamWriteRect(m_pStream, dBorder / 2.0, dBorder / 2.0, dW - dBorder, dH - dBorder); + m_pStream->WriteStr("s\012"); + + // Установлен + if (!bSet) + return; + ECheckBoxStyle nStyle = pAnnot->GetStyle(); + switch (nStyle) + { + case ECheckBoxStyle::Check: + { + break; + } + case ECheckBoxStyle::Cross: + { + break; + } + case ECheckBoxStyle::Diamond: + { + break; + } + case ECheckBoxStyle::Circle: + { + m_pStream->WriteStr("0 g\012q\012"); + m_pStream->WriteStr("1 0 0 1 "); + m_pStream->WriteReal(dW / 2.0); + m_pStream->WriteChar(' '); + m_pStream->WriteReal(dH / 2.0); + m_pStream->WriteStr(" cm\012"); + StreamWriteCircle(m_pStream, 0, 0, std::min(dW, dH) / 2.0 - dBorder); + m_pStream->WriteStr("f\012Q\012"); + break; + } + case ECheckBoxStyle::Star: + { + break; + } + case ECheckBoxStyle::Square: + { + break; + } + } } } diff --git a/PdfFile/SrcWriter/Field.h b/PdfFile/SrcWriter/Field.h index 9498a76e9b..2ba79b83df 100644 --- a/PdfFile/SrcWriter/Field.h +++ b/PdfFile/SrcWriter/Field.h @@ -420,11 +420,7 @@ namespace PdfWriter void DrawLine(); - void DrawCheckBoxCheck(bool bSet, bool bN); - void DrawCheckBoxCross(bool bSet, bool bN); - void DrawCheckBoxDiamond(bool bSet, bool bN); void DrawCheckBoxCircle(bool bSet, bool bN); - void DrawCheckBoxStar(bool bSet, bool bN); void DrawCheckBoxSquare(bool bSet, bool bN); CStream* GetStream() const { return m_pStream; } From 34f36cefc3d780930eb8cc3f9ff646da5ae41f99 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 1 Apr 2025 10:07:16 +0300 Subject: [PATCH 136/186] Delete apValue --- .../graphics/pro/js/wasm/src/drawingfile_test.cpp | 12 +----------- PdfFile/SrcReader/Adaptors.cpp | 12 ------------ PdfFile/SrcReader/Adaptors.h | 6 +----- PdfFile/SrcReader/PdfAnnot.cpp | 12 +----------- PdfFile/SrcReader/PdfAnnot.h | 1 - PdfFile/SrcReader/RendererOutputDev.cpp | 2 -- 6 files changed, 3 insertions(+), 42 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp index edcde6d46c..6324203b62 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp @@ -840,17 +840,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; } diff --git a/PdfFile/SrcReader/Adaptors.cpp b/PdfFile/SrcReader/Adaptors.cpp index 1d240b14d2..ad8da8382c 100644 --- a/PdfFile/SrcReader/Adaptors.cpp +++ b/PdfFile/SrcReader/Adaptors.cpp @@ -185,18 +185,6 @@ bool GlobalParamsAdaptor::GetCMap(const char* sName, char*& pData, unsigned int& return false; } -void GlobalParamsAdaptor::ResetTextFormField() -{ - m_sTextFormField.clear(); -} -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 58bff7e978..3eb1247410 100644 --- a/PdfFile/SrcReader/Adaptors.h +++ b/PdfFile/SrcReader/Adaptors.h @@ -59,7 +59,6 @@ class GlobalParamsAdaptor : public GlobalParams BYTE* m_bCMapData; DWORD m_nCMapDataLength; - std::wstring m_sTextFormField; bool m_bDrawFormField; public: @@ -91,10 +90,7 @@ public: void SetCMapMemory(BYTE* pData, DWORD nSizeData); bool GetCMap(const char* sName, char*& pData, unsigned int& nSize); - void ResetTextFormField(); - 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 7bca8e18f6..e5f3ffb6b6 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -3440,7 +3440,6 @@ void CAnnotAP::Draw(PDFDoc* pdfDoc, Object* oAP, int nRasterH, int nBackgroundCo // Отрисовка внешних видов аннотации AcroFormFieldType oType = pField->getAcroFormFieldType(); ((GlobalParamsAdaptor*)globalParams)->setDrawFormField(true); - ((GlobalParamsAdaptor*)globalParams)->ResetTextFormField(); 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; @@ -3494,7 +3493,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); - ((GlobalParamsAdaptor*)globalParams)->ResetTextFormField(); + // Отрисовка внешних видов аннотации Object oAnnot; XRef* xref = pdfDoc->getXRef(); @@ -3551,7 +3550,6 @@ void CAnnotAP::WriteAppearance(unsigned int nColor, CAnnotAPView* pView) } pView->pAP = pSubMatrix; - pView->sText = ((GlobalParamsAdaptor*)globalParams)->GetTextFormField(); } BYTE CAnnotAP::GetBlendMode() { @@ -3584,14 +3582,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) diff --git a/PdfFile/SrcReader/PdfAnnot.h b/PdfFile/SrcReader/PdfAnnot.h index 20c98f3ded..5d176ef7a2 100644 --- a/PdfFile/SrcReader/PdfAnnot.h +++ b/PdfFile/SrcReader/PdfAnnot.h @@ -129,7 +129,6 @@ private: BYTE nBlendMode; std::string sAPName; std::string sASName; - std::string sText; BYTE* pAP; }; diff --git a/PdfFile/SrcReader/RendererOutputDev.cpp b/PdfFile/SrcReader/RendererOutputDev.cpp index e16063c6de..a6fced6987 100644 --- a/PdfFile/SrcReader/RendererOutputDev.cpp +++ b/PdfFile/SrcReader/RendererOutputDev.cpp @@ -2525,8 +2525,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) From 5b8549db9db7c86b8a7365538c67b15e9cafa219 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 1 Apr 2025 12:08:10 +0300 Subject: [PATCH 137/186] Write style checked symbol --- .../graphics/pro/js/wasm/js/drawingfile.js | 3 - PdfFile/SrcWriter/Annotation.cpp | 8 +- PdfFile/SrcWriter/Field.cpp | 77 +++++++++++++++++-- 3 files changed, 73 insertions(+), 15 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js index 5ad30a6dcc..2d9ac49213 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js @@ -519,9 +519,6 @@ 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(); } } diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index ea82665efb..e6ae0e5b13 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -1824,7 +1824,7 @@ namespace PdfWriter //---------------------------------------------------------------------------------------- CCheckBoxWidget::CCheckBoxWidget(CXref* pXref) : CWidgetAnnotation(pXref, AnnotWidget) { - m_nSubtype = WidgetRadiobutton; + m_nSubtype = WidgetCheckbox; m_nStyle = ECheckBoxStyle::Circle; } void CCheckBoxWidget::SetV(const std::wstring& wsV) @@ -1859,7 +1859,7 @@ namespace PdfWriter CCheckBoxAnnotAppearance* pAP = new CCheckBoxAnnotAppearance(m_pXref, this, m_sAP_N_Yes.empty() ? NULL : m_sAP_N_Yes.c_str()); Add("AP", pAP); - if (m_nStyle == ECheckBoxStyle::Circle) + if (m_nStyle == ECheckBoxStyle::Circle && m_nSubtype == WidgetRadiobutton) { pAP->GetYesN()->DrawCheckBoxCircle(true, true); pAP->GetOffN()->DrawCheckBoxCircle(false, true); @@ -1909,8 +1909,8 @@ namespace PdfWriter if (nFlag < 0) return; int nFlags = nFlag; - if (m_nSubtype == WidgetRadiobutton) - nFlags |= (1 << 15); + if (nFlags & (1 << 15)) + m_nSubtype = WidgetRadiobutton; CWidgetAnnotation::SetFlag(nFlags); } //---------------------------------------------------------------------------------------- diff --git a/PdfFile/SrcWriter/Field.cpp b/PdfFile/SrcWriter/Field.cpp index c7c1ab0027..2563e860d5 100644 --- a/PdfFile/SrcWriter/Field.cpp +++ b/PdfFile/SrcWriter/Field.cpp @@ -3316,45 +3316,106 @@ namespace PdfWriter m_pStream->WriteStr(m_pAnnot->GetBorderDash().c_str()); m_pStream->WriteStr(pAnnot->GetBCforAP().c_str()); - StreamWriteRect(m_pStream, dBorder / 2.0, dBorder / 2.0, dW - dBorder, dH - dBorder); + 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\012"); // Установлен if (!bSet) return; + double dDiff = std::abs(dW - dH) / 2.0; + double dShift = dBorder; + if (nBorderType == EBorderType::Beveled || nBorderType == EBorderType::Inset) + dShift *= 2; + dShift += 1; + 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: - { - break; - } case ECheckBoxStyle::Cross: { + m_pStream->WriteStr("q\012"); + StreamWriteRect(m_pStream, dBorder * 2.0, dBorder * 2.0, dW - dBorder * 4.0, dH - dBorder * 4.0); + m_pStream->WriteStr("W\012n\0120 G\0121 w\012"); + + double x1 = dShift + (bW ? dDiff : 0); + double y1 = dShift + (bW ? 0 : dDiff); + double x2 = dW - dShift - (bW ? dDiff : 0); + double y2 = dH - dShift - (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; + double ca = cos(45.0 / 180.0 * M_PI); + + m_pStream->WriteStr("0 g\012q\012"); + StreamWriteCM(m_pStream, ca, ca, -ca, ca, dCX, dCY); + StreamWriteRect(m_pStream, -dSq / 2.0, -dSq / 2.0, dSq / 2.0, dSq / 2.0); + m_pStream->WriteStr("f\012Q\012"); break; } + case ECheckBoxStyle::Check: case ECheckBoxStyle::Circle: { + double dR = dC - dShift; + m_pStream->WriteStr("0 g\012q\012"); m_pStream->WriteStr("1 0 0 1 "); - m_pStream->WriteReal(dW / 2.0); + m_pStream->WriteReal(dCX); m_pStream->WriteChar(' '); - m_pStream->WriteReal(dH / 2.0); + m_pStream->WriteReal(dCY); m_pStream->WriteStr(" cm\012"); - StreamWriteCircle(m_pStream, 0, 0, std::min(dW, dH) / 2.0 - dBorder); + StreamWriteCircle(m_pStream, 0, 0, dR); m_pStream->WriteStr("f\012Q\012"); break; } case ECheckBoxStyle::Star: { + double dROuter = dC - dShift; + 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 = dC - dShift; + double x1 = dCX - dSq / 2.0; + double y1 = dCY - dSq / 2.0; + double x2 = x1 + dSq; + double y2 = y1 + dSq; + + m_pStream->WriteStr("0 g\012q\012"); + StreamWriteRect(m_pStream, x1, y1, x2, y2); + m_pStream->WriteStr("f\012Q\012"); break; } } From 266425e817f1ee2784d7183e59d5d25c9c3b0b76 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 1 Apr 2025 15:42:39 +0300 Subject: [PATCH 138/186] Fix radiobutton AP --- PdfFile/SrcWriter/Annotation.cpp | 9 ++-- PdfFile/SrcWriter/Field.cpp | 77 +++++++++++++++++++++----------- 2 files changed, 57 insertions(+), 29 deletions(-) diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index e6ae0e5b13..1281503240 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -95,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; @@ -704,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; @@ -719,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; diff --git a/PdfFile/SrcWriter/Field.cpp b/PdfFile/SrcWriter/Field.cpp index 2563e860d5..d352954c3d 100644 --- a/PdfFile/SrcWriter/Field.cpp +++ b/PdfFile/SrcWriter/Field.cpp @@ -3177,7 +3177,7 @@ namespace PdfWriter nBorderType = m_pAnnot->GetBorderType(); } double dW = m_pAnnot->GetRect().fRight - m_pAnnot->GetRect().fLeft; - double dH = m_pAnnot->GetRect().fBottom - m_pAnnot->GetRect().fTop; + 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; @@ -3201,7 +3201,7 @@ namespace PdfWriter if (nBorderType == EBorderType::Dashed) m_pStream->WriteStr(m_pAnnot->GetBorderDash().c_str()); m_pStream->WriteStr(pAnnot->GetBCforAP().c_str()); - m_pStream->WriteStr("q\012"); + m_pStream->WriteStr("\012q\012"); m_pStream->WriteStr("1 0 0 1 "); m_pStream->WriteReal(dCX); m_pStream->WriteChar(' '); @@ -3268,9 +3268,10 @@ namespace PdfWriter nBorderType = m_pAnnot->GetBorderType(); } double dW = m_pAnnot->GetRect().fRight - m_pAnnot->GetRect().fLeft; - double dH = m_pAnnot->GetRect().fBottom - m_pAnnot->GetRect().fTop; + 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); @@ -3297,6 +3298,7 @@ namespace PdfWriter 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); @@ -3315,6 +3317,7 @@ namespace PdfWriter 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) { @@ -3323,7 +3326,7 @@ namespace PdfWriter } else StreamWriteRect(m_pStream, dBorder / 2.0, dBorder / 2.0, dW - dBorder, dH - dBorder); - m_pStream->WriteStr("s\012"); + m_pStream->WriteStr("s\012Q\012"); // Установлен if (!bSet) @@ -3332,7 +3335,6 @@ namespace PdfWriter double dShift = dBorder; if (nBorderType == EBorderType::Beveled || nBorderType == EBorderType::Inset) dShift *= 2; - dShift += 1; bool bW = dW > dH; double dCX = dW / 2.0, dCY = dH / 2.0; double dC = std::min(dW, dH) / 2.0; @@ -3340,16 +3342,39 @@ namespace PdfWriter 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, dBorder * 2.0, dBorder * 2.0, dW - dBorder * 4.0, dH - dBorder * 4.0); + StreamWriteRect(m_pStream, dCross, dCross, dW - dCross, dH - dCross); m_pStream->WriteStr("W\012n\0120 G\0121 w\012"); - double x1 = dShift + (bW ? dDiff : 0); - double y1 = dShift + (bW ? 0 : dDiff); - double x2 = dW - dShift - (bW ? dDiff : 0); - double y2 = dH - dShift - (bW ? 0 : dDiff); + 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); @@ -3360,19 +3385,23 @@ namespace PdfWriter } case ECheckBoxStyle::Diamond: { - double dSq = dC - dShift; - double ca = cos(45.0 / 180.0 * M_PI); - + double dSq = dC - dShift * 2.0 - 1; m_pStream->WriteStr("0 g\012q\012"); - StreamWriteCM(m_pStream, ca, ca, -ca, ca, dCX, dCY); - StreamWriteRect(m_pStream, -dSq / 2.0, -dSq / 2.0, dSq / 2.0, dSq / 2.0); + 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::Check: case ECheckBoxStyle::Circle: { - double dR = dC - dShift; + double dR = dC - dShift * 2.0 - 1; m_pStream->WriteStr("0 g\012q\012"); m_pStream->WriteStr("1 0 0 1 "); @@ -3386,7 +3415,7 @@ namespace PdfWriter } case ECheckBoxStyle::Star: { - double dROuter = dC - dShift; + double dROuter = dC - dShift * 2.0 - 1; double dRInner = dROuter / 2.5; int nPoints = 5; @@ -3395,8 +3424,8 @@ namespace PdfWriter { 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); + double dX = dCX - dR * std::sin(dAngle); + double dY = dCY + dR * std::cos(dAngle); if (i == 0) StreamWriteXYMove(m_pStream, dX, dY); else @@ -3407,14 +3436,10 @@ namespace PdfWriter } case ECheckBoxStyle::Square: { - double dSq = dC - dShift; - double x1 = dCX - dSq / 2.0; - double y1 = dCY - dSq / 2.0; - double x2 = x1 + dSq; - double y2 = y1 + dSq; + double dSq = std::min(dW, dH) * 2.0 / 3.0 - dShift * 2.0 - 1; m_pStream->WriteStr("0 g\012q\012"); - StreamWriteRect(m_pStream, x1, y1, x2, y2); + StreamWriteRect(m_pStream, dCX - dSq / 2.0, dCY - dSq / 2.0, dSq, dSq); m_pStream->WriteStr("f\012Q\012"); break; } From 1aaec18152669adeb697ac7e77e401088012cb8c Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 1 Apr 2025 16:06:20 +0300 Subject: [PATCH 139/186] Fix Cirle radiobutton --- PdfFile/SrcWriter/Field.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/PdfFile/SrcWriter/Field.cpp b/PdfFile/SrcWriter/Field.cpp index d352954c3d..ba198ab069 100644 --- a/PdfFile/SrcWriter/Field.cpp +++ b/PdfFile/SrcWriter/Field.cpp @@ -3245,13 +3245,16 @@ namespace PdfWriter // Установлен 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 - dBorder); + StreamWriteCircle(m_pStream, 0, 0, dR / 2.0 - dShift); m_pStream->WriteStr("f\012Q\012"); } void CAnnotAppearanceObject::DrawCheckBoxSquare(bool bSet, bool bN) From 5692732901670e986a73a35d82703f6b0ce5f6d2 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 1 Apr 2025 18:03:16 +0300 Subject: [PATCH 140/186] Rename Yes AP --- PdfFile/PdfWriter.cpp | 2 +- PdfFile/SrcWriter/Annotation.cpp | 52 +++++++++++++++++++++++--------- PdfFile/SrcWriter/Annotation.h | 3 +- 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 8e6eee82e7..a66eb2e115 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -2670,7 +2670,7 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi { PdfWriter::CCheckBoxWidget* pKid = dynamic_cast(pObj); if (pKid) - pKid->SwitchAP(sV); + pKid->SwitchAP(sV, i); } if (nType == PdfWriter::WidgetCombobox || nType == PdfWriter::WidgetListbox) { diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index 1281503240..fb390d5d43 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -1829,6 +1829,7 @@ namespace PdfWriter { m_nSubtype = WidgetCheckbox; m_nStyle = ECheckBoxStyle::Circle; + m_pAP = NULL; } void CCheckBoxWidget::SetV(const std::wstring& wsV) { @@ -1856,34 +1857,41 @@ namespace PdfWriter } void CCheckBoxWidget::SetAP() { - if (Get("AP")) - return; - - CCheckBoxAnnotAppearance* pAP = new CCheckBoxAnnotAppearance(m_pXref, this, m_sAP_N_Yes.empty() ? NULL : m_sAP_N_Yes.c_str()); - Add("AP", pAP); + 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) { - pAP->GetYesN()->DrawCheckBoxCircle(true, true); - pAP->GetOffN()->DrawCheckBoxCircle(false, true); - pAP->GetYesD()->DrawCheckBoxCircle(true, false); - pAP->GetOffD()->DrawCheckBoxCircle(false, false); + 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 { - pAP->GetYesN()->DrawCheckBoxSquare(true, true); - pAP->GetOffN()->DrawCheckBoxSquare(false, true); - pAP->GetYesD()->DrawCheckBoxSquare(true, false); - pAP->GetOffD()->DrawCheckBoxSquare(false, false); + m_pAP->GetYesN()->DrawCheckBoxSquare(true, true); + m_pAP->GetOffN()->DrawCheckBoxSquare(false, true); + m_pAP->GetYesD()->DrawCheckBoxSquare(true, false); + m_pAP->GetOffD()->DrawCheckBoxSquare(false, false); } } - void CCheckBoxWidget::SwitchAP(const std::string& sV) + void CCheckBoxWidget::SwitchAP(const std::string& sV, int nI) { CObjectBase* pAP, *pAPN; Add("AS", "Off"); CObjectBase* pObj = GetObjValue("Opt"); if (!m_sAP_N_Yes.empty() && pObj && pObj->GetType() == object_type_ARRAY) { + if (m_pAP) + { + 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) { @@ -1903,9 +1911,25 @@ namespace PdfWriter } } 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) { diff --git a/PdfFile/SrcWriter/Annotation.h b/PdfFile/SrcWriter/Annotation.h index 4ce0925b6b..3ec35f7969 100644 --- a/PdfFile/SrcWriter/Annotation.h +++ b/PdfFile/SrcWriter/Annotation.h @@ -530,6 +530,7 @@ namespace PdfWriter private: std::string m_sAP_N_Yes; ECheckBoxStyle m_nStyle; + CCheckBoxAnnotAppearance* m_pAP; public: CCheckBoxWidget(CXref* pXref); @@ -540,7 +541,7 @@ namespace PdfWriter void SetAP_N_Yes(const std::wstring& wsAP_N_Yes); virtual void SetFlag (const int& nFlag); void SetAP(); - void SwitchAP(const std::string& sV); + void SwitchAP(const std::string& sV, int nI = -1); }; class CTextWidget : public CWidgetAnnotation { From 744d90e655267304588910bd392e609e9fe6ee1c Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Wed, 2 Apr 2025 16:38:15 +0300 Subject: [PATCH 141/186] [x2t] Fix typo --- OOXML/VsdxFormat/VisioConnections.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OOXML/VsdxFormat/VisioConnections.cpp b/OOXML/VsdxFormat/VisioConnections.cpp index 25345409fd..d4a4e886e4 100644 --- a/OOXML/VsdxFormat/VisioConnections.cpp +++ b/OOXML/VsdxFormat/VisioConnections.cpp @@ -1250,8 +1250,8 @@ namespace Draw { pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeStart); pWriter->WriteUInt2(0, RowID); - pWriter->WriteUInt2(0, PageID); - pWriter->WriteUInt2(0, ShapeID); + pWriter->WriteUInt2(1, PageID); + pWriter->WriteUInt2(2, ShapeID); pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); } void CRowMap::fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader) From fee4394d3f3dcb14b92e3af587e130f6d7f54a8b Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 2 Apr 2025 18:13:18 +0300 Subject: [PATCH 142/186] Update radiobutton Opt choice --- PdfFile/PdfEditor.cpp | 23 ++++ PdfFile/PdfWriter.cpp | 189 ++++++++++++++++++------------- PdfFile/SrcWriter/Annotation.cpp | 24 ++++ PdfFile/SrcWriter/Annotation.h | 5 + PdfFile/SrcWriter/Document.cpp | 9 +- PdfFile/SrcWriter/Document.h | 2 +- 6 files changed, 172 insertions(+), 80 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index ed34386b31..83f520f4b2 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -1288,9 +1288,32 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID) } } oParentRef.free(); + continue; } else if (!strcmp("Opt", chKey)) bUnicode = true; + 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; + } + } + } + } + } Object oTemp; oAnnot.dictGetValNF(nIndex, &oTemp); DictToCDictObject(&oTemp, pAnnot, false, chKey, bUnicode); diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index a66eb2e115..9e39fec54c 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -2378,46 +2378,14 @@ 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); - } pButtonWidget->SetStyle(pPrB->GetStyle()); // ВНЕШНИЙ ВИД - // Если изменился текущий внешний вид - if (pButtonWidget->Get("AP")) - { - if (!wsValue.empty()) - pButtonWidget->SwitchAP(U_TO_UTF8(wsValue)); - return S_OK; - } - - pButtonWidget->SetAP(); - /* - 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); - } - */ + if (!pButtonWidget->Get("AP")) + pButtonWidget->SetAP(); } } else if (oInfo.IsTextWidget()) @@ -2645,7 +2613,7 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi if (nFlags & (1 << 0)) pParentObj->Add("T", new PdfWriter::CStringObject((U_TO_UTF8(pParent->sName)).c_str())); - m_pDocument->SetParentKids(pParent->nID); + std::string sFT = m_pDocument->SetParentKids(pParent->nID); PdfWriter::CArrayObject* pKids = dynamic_cast(pParentObj->Get("Kids")); if (!pKids) { @@ -2653,46 +2621,6 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi pParentObj->Add("Kids", pKids); } - if (nFlags & (1 << 1)) - { - std::string sV = U_TO_UTF8(pParent->sV); - bool bName = !sV.empty() && (iswdigit(pParent->sV[0]) || sV == "Off"); - - 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) - { - PdfWriter::CCheckBoxWidget* pKid = dynamic_cast(pObj); - if (pKid) - pKid->SwitchAP(sV, i); - } - 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)); - } if (nFlags & (1 << 2)) pParentObj->Add("DV", new PdfWriter::CStringObject((U_TO_UTF8(pParent->sDV)).c_str(), true)); if (nFlags & (1 << 3)) @@ -2735,6 +2663,8 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi } } } + int nIndexName = 0; + std::map mNameAP_N_Yes; if (nFlags & (1 << 6)) { PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject(); @@ -2742,24 +2672,129 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi for (const std::pair& PV : pParent->arrOpt) { + std::string sValue; if (PV.first.empty()) { - std::string sValue = U_TO_UTF8(PV.second); + 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(nIndexName++); } else { PdfWriter::CArrayObject* pArray2 = new PdfWriter::CArrayObject(); pArray->Add(pArray2); - std::string sValue = U_TO_UTF8(PV.first); + 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(nIndexName++); + 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 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(mNameAP_N_Yes[sOptI]); + + if (sOptI == sOpt) + 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) + continue; + PdfWriter::EWidgetType nType = ((PdfWriter::CWidgetAnnotation*)pObj)->GetWidgetType(); + if (nType == PdfWriter::WidgetCombobox || nType == PdfWriter::WidgetListbox) + { + PdfWriter::CChoiceWidget* pKid = dynamic_cast(pObj); + if (!pKid->HaveAPV()) + 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)) diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index fb390d5d43..274aa2160e 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -1854,6 +1854,20 @@ namespace PdfWriter { 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"); + } + } + bool CCheckBoxWidget::NeedAP_N_Yes() + { + return m_sAP_N_Yes.empty(); } void CCheckBoxWidget::SetAP() { @@ -1878,6 +1892,16 @@ namespace PdfWriter 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; diff --git a/PdfFile/SrcWriter/Annotation.h b/PdfFile/SrcWriter/Annotation.h index 3ec35f7969..5b17d2c1eb 100644 --- a/PdfFile/SrcWriter/Annotation.h +++ b/PdfFile/SrcWriter/Annotation.h @@ -539,9 +539,14 @@ namespace PdfWriter 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(); virtual void SetFlag (const int& nFlag); void SetAP(); void SwitchAP(const std::string& sV, int nI = -1); + + std::string Yes(); + void Off(); }; class CTextWidget : public CWidgetAnnotation { diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 4d6322d906..9cf53fee48 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -1558,11 +1558,11 @@ namespace PdfWriter return p->second; return NULL; } - void CDocument::SetParentKids(int nParentID) + std::string CDocument::SetParentKids(int nParentID) { CDictObject* pParent = GetParent(nParentID); if (!pParent) - return; + return ""; for (auto it = m_mAnnotations.begin(); it != m_mAnnotations.end(); it++) { @@ -1603,6 +1603,11 @@ namespace PdfWriter if (!bReplase) pKids->Add(pWidget); } + + CObjectBase* pFT = pParent->Get("FT"); + if (pFT && pFT->GetType() == object_type_NAME) + return ((CNameObject*)pFT)->Get(); + return ""; } CPage* CDocument::CreateFakePage() { diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index 2d825b31d8..fc511360d1 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -209,7 +209,7 @@ namespace PdfWriter void SetCurPage(CPage* pPage) { m_pCurPage = pPage; } CPage* CreateFakePage(); bool EditCO(const std::vector& arrCO); - void SetParentKids(int nParentID); + 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); From e8bb81b88ec85909d7b13d1ef525e21096e5052e Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 3 Apr 2025 15:21:38 +0600 Subject: [PATCH 143/186] fix bug #73815 --- OOXML/Binary/Sheets/Writer/BinaryReaderS.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OOXML/Binary/Sheets/Writer/BinaryReaderS.h b/OOXML/Binary/Sheets/Writer/BinaryReaderS.h index 04e3a91ef0..9239105d73 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReaderS.h +++ b/OOXML/Binary/Sheets/Writer/BinaryReaderS.h @@ -280,7 +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; + OOX::Spreadsheet::CXlsb* m_pXlsb = NULL; }; class BinaryCommentReader : public Binary_CommonReader { From d7a8c30461f4c3ba591bac0578fcb8affba977db Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 3 Apr 2025 17:33:47 +0300 Subject: [PATCH 144/186] Fix name of AP.N.Yes --- PdfFile/PdfEditor.cpp | 116 +++++++++++++++++++++++++++++-- PdfFile/PdfWriter.cpp | 25 +++++-- PdfFile/SrcWriter/Annotation.cpp | 3 +- PdfFile/SrcWriter/Pages.cpp | 4 +- 4 files changed, 134 insertions(+), 14 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 83f520f4b2..2cf0690232 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -1401,14 +1401,120 @@ 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); + if (!bPushButton) + { + oFT.free(); + bNeed = oAnnot.dictLookup("Opt", &oFT)->isArray(); + 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(); + + // TODO у родителя убрать аннотацию из Kids и Opt. У всех детей переименовать AP.N.Yes + + 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()) { diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 9e39fec54c..e84a1f04f8 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -2386,6 +2386,15 @@ HRESULT CPdfWriter::AddAnnotField(NSFonts::IApplicationFonts* pAppFonts, CAnnotF // ВНЕШНИЙ ВИД if (!pButtonWidget->Get("AP")) pButtonWidget->SetAP(); + + if (nFlags & (1 << 9)) + { + std::wstring sValue = pPrB->GetV(); + if (sValue != L"Off") + pButtonWidget->Yes(); + else + pButtonWidget->Off(); + } } } else if (oInfo.IsTextWidget()) @@ -2663,15 +2672,15 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi } } } - int nIndexName = 0; std::map mNameAP_N_Yes; if (nFlags & (1 << 6)) { PdfWriter::CArrayObject* pArray = new PdfWriter::CArrayObject(); pParentObj->Add("Opt", pArray); - for (const std::pair& PV : pParent->arrOpt) + for (int i = 0; i < pParent->arrOpt.size(); ++i) { + std::pair PV = pParent->arrOpt[i]; std::string sValue; if (PV.first.empty()) { @@ -2679,7 +2688,7 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi 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(nIndexName++); + mNameAP_N_Yes[PV.second] = std::to_wstring(i); } else { @@ -2690,7 +2699,7 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi 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(nIndexName++); + mNameAP_N_Yes[PV.first] = std::to_wstring(i); sValue = U_TO_UTF8(PV.second); pArray2->Add(new PdfWriter::CStringObject(sValue.c_str(), true)); @@ -2702,6 +2711,10 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi std::string sV = U_TO_UTF8(pParent->sV); if (sFT == "Btn") { + int nFf = 0; + if (nFlags & (1 << 7)) + nFf = pParent->nFieldFlag; + bool bRadiosInUnison = nFf & (1 << 25); int nOptIndex = -1; if (isdigit(sV[0])) nOptIndex = std::stoi(sV); @@ -2730,9 +2743,9 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi PV = pParent->arrOpt[i]; std::wstring sOptI = PV.first.empty() ? PV.second : PV.first; if (pKid->NeedAP_N_Yes()) - pKid->SetAP_N_Yes(mNameAP_N_Yes[sOptI]); + pKid->SetAP_N_Yes((bRadiosInUnison || nType == PdfWriter::WidgetCheckbox) ? mNameAP_N_Yes[sOptI] : std::to_wstring(i)); - if (sOptI == sOpt) + if (((bRadiosInUnison || nType == PdfWriter::WidgetCheckbox) && sOptI == sOpt) || (!bRadiosInUnison && i == nOptIndex)) sV = pKid->Yes(); else pKid->Off(); diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index 274aa2160e..f4ce5d61c2 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -1853,7 +1853,8 @@ namespace PdfWriter 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) { diff --git a/PdfFile/SrcWriter/Pages.cpp b/PdfFile/SrcWriter/Pages.cpp index 8b470e79f9..9510430064 100644 --- a/PdfFile/SrcWriter/Pages.cpp +++ b/PdfFile/SrcWriter/Pages.cpp @@ -1123,8 +1123,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); From f441ec5c3570ad92fa8fa50dda45381c7b1926cc Mon Sep 17 00:00:00 2001 From: Alexey Nagaev Date: Thu, 3 Apr 2025 03:02:37 +0300 Subject: [PATCH 145/186] Testing clang build --- Common/3dParty/boost/boost.pri | 5 +++ Common/base.pri | 33 ++++++++++++++++++- DesktopEditor/graphics/pro/raster.pri | 4 +++ .../raster/Metafile/Common/MetaFileTypes.h | 1 + DesktopEditor/xml/build/qt/libxml2.pri | 4 +++ OfficeUtils/OfficeUtils.pri | 3 ++ 6 files changed, 49 insertions(+), 1 deletion(-) diff --git a/Common/3dParty/boost/boost.pri b/Common/3dParty/boost/boost.pri index 7a0278cea4..1e6a683ad5 100644 --- a/Common/3dParty/boost/boost.pri +++ b/Common/3dParty/boost/boost.pri @@ -4,6 +4,11 @@ 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_linux_clang { + DEFINES += _LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION +} core_android { INCLUDEPATH += $$PWD/build/android/include diff --git a/Common/base.pri b/Common/base.pri index e8dc81b132..1a0473e98a 100644 --- a/Common/base.pri +++ b/Common/base.pri @@ -109,6 +109,35 @@ 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") +} + +core_linux_clang { + CONFIG += c++1z +} + linux-g++ { CONFIG += core_linux linux-g++:contains(QMAKE_HOST.arch, x86_64): { @@ -246,9 +275,11 @@ core_linux { } core_linux { +!core_linux_clang { equals(TEMPLATE, app):CONFIG += core_static_link_libstd plugin:CONFIG += core_static_link_libstd } +} core_win_32 { CORE_BUILDS_PLATFORM_PREFIX = win_32 @@ -414,7 +445,7 @@ core_windows:CONFIG += no_batch message($$CORE_BUILDS_PLATFORM_PREFIX/$$CORE_BUILDS_CONFIGURATION_PREFIX) # COMPILER -CONFIG += c++11 +# CONFIG += c++11 !core_windows { QMAKE_CXXFLAGS += -Wno-register 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/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/xml/build/qt/libxml2.pri b/DesktopEditor/xml/build/qt/libxml2.pri index 960bacfa1a..1cfa7555a9 100644 --- a/DesktopEditor/xml/build/qt/libxml2.pri +++ b/DesktopEditor/xml/build/qt/libxml2.pri @@ -1,3 +1,7 @@ +core_linux_clang { + QMAKE_CFLAGS += -std=c99 +} + DEFINES += HAVE_VA_COPY core_static_link_xml_full { diff --git a/OfficeUtils/OfficeUtils.pri b/OfficeUtils/OfficeUtils.pri index b4e1f497a8..232efd8f4e 100644 --- a/OfficeUtils/OfficeUtils.pri +++ b/OfficeUtils/OfficeUtils.pri @@ -5,6 +5,9 @@ core_mac { QMAKE_CXXFLAGS += -Wall -Wno-ignored-qualifiers DEFINES += unix } +core_linux_clang { + QMAKE_CFLAGS += -Wno-implicit-function-declaration +} build_zlib_as_sources { DEFINES += BUILD_ZLIB_AS_SOURCES From ddb544ce343fe21e2d6df9b2ab1ac739007949ec Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 4 Apr 2025 11:48:45 +0300 Subject: [PATCH 146/186] Chenges all AP.N.Yes when delete annot --- PdfFile/PdfEditor.cpp | 62 ++++++++++++++++++++++++++++++-- PdfFile/PdfWriter.cpp | 2 +- PdfFile/SrcWriter/Annotation.cpp | 38 ++++++++++++++++++++ PdfFile/SrcWriter/Annotation.h | 1 + PdfFile/SrcWriter/Objects.h | 1 + 5 files changed, 101 insertions(+), 3 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 2cf0690232..c3f5465d2b 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -1087,6 +1087,9 @@ bool CPdfEditor::EditAnnot(int nPageIndex, int nID) if (!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) @@ -1458,10 +1461,11 @@ bool CPdfEditor::DeleteAnnot(int nID, Object* oAnnots) } bPushButton = (bool)((nFf >> 16) & 1); + bool bRadiosInUnison = (bool)(nFf & (1 << 25)); if (!bPushButton) { oFT.free(); - bNeed = oAnnot.dictLookup("Opt", &oFT)->isArray(); + bNeed = oAnnot.dictLookup("Opt", &oFT)->isArray() == gTrue; if (!bNeed) { Object oParent, oParent2; @@ -1487,7 +1491,61 @@ bool CPdfEditor::DeleteAnnot(int nID, Object* oAnnots) { pAnnot->SetHidden(); - // TODO у родителя убрать аннотацию из Kids и Opt. У всех детей переименовать AP.N.Yes + 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 = 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); + if (pObj == pAnnot) + { + pKids->Remove(i); + pOpt->Remove(i); + --i; + } + else + { + Object oAnnot, oSubtype, oPageRef; + if (xref->fetch(pObj->GetObjId(), pObj->GetGenNo(), &oAnnot)->isDict("Annot") && oAnnot.dictLookup("Sybtype", &oSubtype)->isName("Widget") && + oAnnot.dictLookupNF("P", &oPageRef)->isRef()) + { + int nPage = pPDFDocument->findPage(oPageRef.getRefNum(), oPageRef.getRefGen()); + PdfWriter::CCheckBoxWidget* pKidAnnot = NULL; + if (nPage > 0 && EditAnnot(nPage, pObj->GetObjId())) + pKidAnnot = dynamic_cast(pDoc->GetAnnot(pObj->GetObjId())); + 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()) diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index e84a1f04f8..4ebb429c99 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -2714,7 +2714,7 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi int nFf = 0; if (nFlags & (1 << 7)) nFf = pParent->nFieldFlag; - bool bRadiosInUnison = nFf & (1 << 25); + bool bRadiosInUnison = (bool)(nFf & (1 << 25)); int nOptIndex = -1; if (isdigit(sV[0])) nOptIndex = std::stoi(sV); diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index f4ce5d61c2..69ec98491f 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -1866,6 +1866,44 @@ namespace PdfWriter pDict->Remove("Yes"); } } + 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") + { + CObjectBase* pObject = it.second; + if (pObject && object_type_PROXY == pObject->GetType()) + pObject = ((CProxyObject*)pObject)->Get(); + pDictAPN->Add(m_sAP_N_Yes, pObject); + pDictAPN->Remove(it.first); + break; + } + } + } + } + } bool CCheckBoxWidget::NeedAP_N_Yes() { return m_sAP_N_Yes.empty(); diff --git a/PdfFile/SrcWriter/Annotation.h b/PdfFile/SrcWriter/Annotation.h index 5b17d2c1eb..23d00c5aee 100644 --- a/PdfFile/SrcWriter/Annotation.h +++ b/PdfFile/SrcWriter/Annotation.h @@ -541,6 +541,7 @@ namespace PdfWriter 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); diff --git a/PdfFile/SrcWriter/Objects.h b/PdfFile/SrcWriter/Objects.h index cac33259bc..e8e3beadb0 100644 --- a/PdfFile/SrcWriter/Objects.h +++ b/PdfFile/SrcWriter/Objects.h @@ -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: From f2bda6c81a27c31baf2d195c3b27d9d1733d7f9c Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 4 Apr 2025 17:23:50 +0300 Subject: [PATCH 147/186] Fix Adobe bug radiobutton BG --- PdfFile/PdfEditor.cpp | 36 +++++++------- PdfFile/SrcWriter/Annotation.cpp | 80 +++++++++++++------------------- PdfFile/SrcWriter/Annotation.h | 2 +- PdfFile/SrcWriter/Field.cpp | 34 ++++++++++---- 4 files changed, 77 insertions(+), 75 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index c3f5465d2b..8ec4f1f1db 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -1218,10 +1218,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); @@ -1510,18 +1511,6 @@ bool CPdfEditor::DeleteAnnot(int nID, Object* oAnnots) { for (int i = 0; i < pKids->GetCount(); ++i) { - 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); if (pObj == pAnnot) { @@ -1531,14 +1520,27 @@ bool CPdfEditor::DeleteAnnot(int nID, Object* oAnnots) } 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("Sybtype", &oSubtype)->isName("Widget") && + 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()); + int nPage = pPDFDocument->findPage(oPageRef.getRefNum(), oPageRef.getRefGen()) - 1; PdfWriter::CCheckBoxWidget* pKidAnnot = NULL; - if (nPage > 0 && EditAnnot(nPage, pObj->GetObjId())) - pKidAnnot = dynamic_cast(pDoc->GetAnnot(pObj->GetObjId())); + 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)); } diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index 69ec98491f..d680bfabcb 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -1411,45 +1411,6 @@ namespace PdfWriter } pAA->Add(pAction->m_sType.c_str(), pAction); - - /* - if (pAction->m_sType == "A") - { - CDictObject* pOwner = GetObjOwnValue(pAction->m_sType); - if (!pOwner) - pOwner = this; - - pOwner->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); - } - } - - if (!pAA) - { - pAA = (CDictObject*)GetObjValue("AA"); - if (!pAA) - { - pAA = new CDictObject(); - Add("AA", pAA); - } - } - - if (pAA) - pAA->Add(sAA.c_str(), pAction); - */ } std::string CWidgetAnnotation::GetDAforAP(CFontDict* pFont) { @@ -1825,9 +1786,9 @@ namespace PdfWriter //---------------------------------------------------------------------------------------- // CCheckBoxWidget //---------------------------------------------------------------------------------------- - CCheckBoxWidget::CCheckBoxWidget(CXref* pXref) : CWidgetAnnotation(pXref, AnnotWidget) + CCheckBoxWidget::CCheckBoxWidget(CXref* pXref, EWidgetType nSubtype) : CWidgetAnnotation(pXref, AnnotWidget) { - m_nSubtype = WidgetCheckbox; + m_nSubtype = nSubtype; m_nStyle = ECheckBoxStyle::Circle; m_pAP = NULL; } @@ -1891,12 +1852,28 @@ namespace PdfWriter std::map mDict = pDictAPN->GetDict(); for (std::pair it : mDict) { - if (it.first != "Off") + if (it.first != "Off" && it.first != m_sAP_N_Yes) { CObjectBase* pObject = it.second; - if (pObject && object_type_PROXY == pObject->GetType()) - pObject = ((CProxyObject*)pObject)->Get(); - pDictAPN->Add(m_sAP_N_Yes, pObject); + 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; } @@ -2038,12 +2015,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() @@ -2233,7 +2216,8 @@ namespace PdfWriter void CAction::SetType(const std::wstring& wsType) { m_sType = U_TO_UTF8(wsType); - Add("S", m_sType.c_str()); + if (wsType != L"A") + Add("S", m_sType.c_str()); } void CAction::SetNext(CAction* pNext) { diff --git a/PdfFile/SrcWriter/Annotation.h b/PdfFile/SrcWriter/Annotation.h index 23d00c5aee..1312d77729 100644 --- a/PdfFile/SrcWriter/Annotation.h +++ b/PdfFile/SrcWriter/Annotation.h @@ -533,7 +533,7 @@ namespace PdfWriter CCheckBoxAnnotAppearance* m_pAP; public: - CCheckBoxWidget(CXref* pXref); + CCheckBoxWidget(CXref* pXref, EWidgetType nSubtype = WidgetCheckbox); void SetV(const std::wstring& wsV); void SetStyle(BYTE nStyle); diff --git a/PdfFile/SrcWriter/Field.cpp b/PdfFile/SrcWriter/Field.cpp index ba198ab069..9b78b7c1cd 100644 --- a/PdfFile/SrcWriter/Field.cpp +++ b/PdfFile/SrcWriter/Field.cpp @@ -3182,15 +3182,31 @@ namespace PdfWriter double dR = std::min(dW, dH) / 2.0; // Задний фон - m_pStream->WriteStr(pAnnot->GetBGforAP(!bN && nBorderType != EBorderType::Beveled ? -0.250977 : 0).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"); + 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) From e5c7a043be805c2dcf37866b1cf7c16b74dfd96e Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Sun, 6 Apr 2025 13:22:47 +0300 Subject: [PATCH 148/186] Refactoring --- Common/3dParty/boost/boost.pri | 4 ---- Common/base.pri | 17 ++++++++++++----- DesktopEditor/xml/build/qt/libxml2.pri | 4 ---- OfficeUtils/OfficeUtils.pri | 3 --- 4 files changed, 12 insertions(+), 16 deletions(-) diff --git a/Common/3dParty/boost/boost.pri b/Common/3dParty/boost/boost.pri index 1e6a683ad5..7d6f30de2d 100644 --- a/Common/3dParty/boost/boost.pri +++ b/Common/3dParty/boost/boost.pri @@ -6,10 +6,6 @@ core_android:CONFIG += disable_enum_constexpr_conversion core_mac:CONFIG += disable_enum_constexpr_conversion core_linux_clang:CONFIG += disable_enum_constexpr_conversion -core_linux_clang { - DEFINES += _LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION -} - core_android { INCLUDEPATH += $$PWD/build/android/include CORE_BOOST_LIBS = $$PWD/build/android/lib/$$CORE_BUILDS_PLATFORM_PREFIX diff --git a/Common/base.pri b/Common/base.pri index 1a0473e98a..7c615ec884 100644 --- a/Common/base.pri +++ b/Common/base.pri @@ -134,10 +134,6 @@ linux-clang-32 { message("linux-32-clang") } -core_linux_clang { - CONFIG += c++1z -} - linux-g++ { CONFIG += core_linux linux-g++:contains(QMAKE_HOST.arch, x86_64): { @@ -225,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 @@ -445,7 +445,14 @@ core_windows:CONFIG += no_batch message($$CORE_BUILDS_PLATFORM_PREFIX/$$CORE_BUILDS_CONFIGURATION_PREFIX) # COMPILER -# CONFIG += c++11 +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 diff --git a/DesktopEditor/xml/build/qt/libxml2.pri b/DesktopEditor/xml/build/qt/libxml2.pri index 1cfa7555a9..960bacfa1a 100644 --- a/DesktopEditor/xml/build/qt/libxml2.pri +++ b/DesktopEditor/xml/build/qt/libxml2.pri @@ -1,7 +1,3 @@ -core_linux_clang { - QMAKE_CFLAGS += -std=c99 -} - DEFINES += HAVE_VA_COPY core_static_link_xml_full { diff --git a/OfficeUtils/OfficeUtils.pri b/OfficeUtils/OfficeUtils.pri index 232efd8f4e..b4e1f497a8 100644 --- a/OfficeUtils/OfficeUtils.pri +++ b/OfficeUtils/OfficeUtils.pri @@ -5,9 +5,6 @@ core_mac { QMAKE_CXXFLAGS += -Wall -Wno-ignored-qualifiers DEFINES += unix } -core_linux_clang { - QMAKE_CFLAGS += -Wno-implicit-function-declaration -} build_zlib_as_sources { DEFINES += BUILD_ZLIB_AS_SOURCES From 2cb34822cd6b2b02260a188c2a639bd63e8fa0a0 Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Sun, 6 Apr 2025 13:26:49 +0300 Subject: [PATCH 149/186] Rename config value with code style --- Common/base.pri | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Common/base.pri b/Common/base.pri index 7c615ec884..aa18db65cd 100644 --- a/Common/base.pri +++ b/Common/base.pri @@ -447,9 +447,8 @@ message($$CORE_BUILDS_PLATFORM_PREFIX/$$CORE_BUILDS_CONFIGURATION_PREFIX) # COMPILER CONFIG += c++11 -#CONFIG += ENABLE_CPP_17 - -ENABLE_CPP_17 { +#CONFIG += enable_cpp_17 +enable_cpp_17 { CONFIG += c++1z DEFINES += _LIBCPP_ENABLE_CXX17_REMOVED_UNARY_BINARY_FUNCTION } From 75c0dde6d219b19c33ea25331da4e065ea600518 Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Sun, 6 Apr 2025 13:36:24 +0300 Subject: [PATCH 150/186] Refactoring --- Common/base.pri | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Common/base.pri b/Common/base.pri index aa18db65cd..8e240dfcf5 100644 --- a/Common/base.pri +++ b/Common/base.pri @@ -275,11 +275,9 @@ core_linux { } core_linux { -!core_linux_clang { equals(TEMPLATE, app):CONFIG += core_static_link_libstd plugin:CONFIG += core_static_link_libstd } -} core_win_32 { CORE_BUILDS_PLATFORM_PREFIX = win_32 @@ -460,7 +458,11 @@ enable_cpp_17 { 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 { From 21ec043636b6ddaf36c6b323f9d559dc64b6790b Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 7 Apr 2025 13:24:33 +0300 Subject: [PATCH 151/186] Fix merge Fields AcroForm --- .../pro/js/wasm/src/drawingfile_test.cpp | 1 - PdfFile/PdfEditor.cpp | 37 +++++++++++++------ PdfFile/SrcReader/PdfAnnot.cpp | 8 ++-- PdfFile/SrcReader/PdfAnnot.h | 2 +- PdfFile/SrcWriter/Document.cpp | 4 -- 5 files changed, 30 insertions(+), 22 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp index ceba41e746..bb2036d67a 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)) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 7e7cc8604a..177dd732b0 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -466,14 +466,27 @@ void AddWidgetParent(PdfWriter::CDocument* pDoc, CObjectsManager* pManager, PdfW { if (pObj->GetType() != PdfWriter::object_type_DICT) return; - PdfWriter::CDictObject* pDict = (PdfWriter::CDictObject*)pObj; - if (pDict->GetDictType() != PdfWriter::dict_type_UNKNOWN) + PdfWriter::CDictObject* pDict = dynamic_cast(pObj); + if (!pDict) return; int nID = pManager->FindObj(pObj); - if (pDoc->GetParent(nID)) + 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; - pDoc->AddParent(nID, pDict); PdfWriter::CObjectBase* pObjKids = pDict->Get("Kids"); if (!pObjKids || pObjKids->GetType() != PdfWriter::object_type_ARRAY) @@ -1697,16 +1710,16 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFD 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) { - PdfWriter::CObjectBase* pObj = m_mObjManager.GetObj(oRes.getRefNum() + nStartRefID); - if (pObj) - { - pFields->Add(pObj); - m_mObjManager.IncRefCount(oRes.getRefNum() + nStartRefID); - AddWidgetParent(pDoc, &m_mObjManager, pObj); - continue; - } + pFields->Add(pObj); + m_mObjManager.IncRefCount(oRes.getRefNum() + nStartRefID); + AddWidgetParent(pDoc, &m_mObjManager, pObj); + oRes.free(); + continue; } oRes.free(); } diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index e2a477f930..eb517821ed 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -2442,7 +2442,7 @@ CAnnots::CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontLi // Родители Object oParentRefObj; if (oField.dictLookupNF("Parent", &oParentRefObj)->isRef()) - getParents(xref, &oParentRefObj, nStartRefID); + getParents(pdfDoc, &oParentRefObj, nStartRefID); oParentRefObj.free(); oField.free(); oFieldRef.free(); @@ -2497,9 +2497,9 @@ CAnnots::~CAnnots() for (int i = 0; i < m_arrAnnots.size(); ++i) RELEASEOBJECT(m_arrAnnots[i]); } -void CAnnots::getParents(XRef* xref, Object* oFieldRef, int nStartRefID) +void CAnnots::getParents(PDFDoc* pdfDoc, Object* oFieldRef, int nStartRefID) { - if (!oFieldRef || !xref || !oFieldRef->isRef() || + 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; @@ -2672,7 +2672,7 @@ void CAnnots::getParents(XRef* xref, Object* oFieldRef, int nStartRefID) { pAnnotParent->unFlags |= (1 << 4); pAnnotParent->unRefNumParent = oParentRefObj.getRefNum() + nStartRefID; - getParents(xref, &oParentRefObj, nStartRefID); + getParents(pdfDoc, &oParentRefObj, nStartRefID); } oParentRefObj.free(); diff --git a/PdfFile/SrcReader/PdfAnnot.h b/PdfFile/SrcReader/PdfAnnot.h index 1cedfdfd09..2b57ca5a95 100644 --- a/PdfFile/SrcReader/PdfAnnot.h +++ b/PdfFile/SrcReader/PdfAnnot.h @@ -621,7 +621,7 @@ private: std::string sDV; }; - void getParents(XRef* xref, Object* oFieldRef, int nStartRefID); + void getParents(PDFDoc* pdfDoc, Object* oFieldRef, int nStartRefID); std::vector m_arrCO; // Порядок вычислений - CO std::vector m_arrParents; // Родительские Fields diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index d0e04c5540..2e4d48bb17 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -1643,10 +1643,6 @@ namespace PdfWriter return ((CNameObject*)pFT)->Get(); return ""; } - CPage* CDocument::CreateFakePage() - { - return new CPage(this, NULL); - } bool CDocument::EditCO(const std::vector& arrCO) { if (arrCO.empty()) From 21451d83e48c027a101ad586f013004340424fdf Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Mon, 7 Apr 2025 14:01:59 +0300 Subject: [PATCH 152/186] add to binary --- .../Document/BinReader/BinaryReaderD.cpp | 58 ++++++++++--------- .../Document/BinReader/ReaderClasses.cpp | 37 ++---------- .../Binary/Document/BinReader/ReaderClasses.h | 15 +---- .../BinWriter/BinReaderWriterDefines.h | 6 +- .../Document/BinWriter/BinaryWriterD.cpp | 15 ++++- 5 files changed, 54 insertions(+), 77 deletions(-) diff --git a/OOXML/Binary/Document/BinReader/BinaryReaderD.cpp b/OOXML/Binary/Document/BinReader/BinaryReaderD.cpp index 3a3a43bba4..1a6f8955b3 100644 --- a/OOXML/Binary/Document/BinReader/BinaryReaderD.cpp +++ b/OOXML/Binary/Document/BinReader/BinaryReaderD.cpp @@ -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::docGrid == 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/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/BinaryWriterD.cpp b/OOXML/Binary/Document/BinWriter/BinaryWriterD.cpp index 4608e092e6..83696f9c85 100644 --- a/OOXML/Binary/Document/BinWriter/BinaryWriterD.cpp +++ b/OOXML/Binary/Document/BinWriter/BinaryWriterD.cpp @@ -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; From c84f2a11d55f8208686a15acf4461b978d93361b Mon Sep 17 00:00:00 2001 From: "Oleg.Korshul" Date: Mon, 7 Apr 2025 14:51:15 +0300 Subject: [PATCH 153/186] Fix build with MacOS.sdk 15.4 --- DesktopEditor/cximage/png/pngpriv.h | 1 + MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h | 3 +-- OfficeUtils/src/zlib-1.2.11/zutil.h | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) 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/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h index bf9abf6a92..3ec58d9b48 100644 --- a/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h +++ b/MsBinaryFile/XlsFile/Format/Auxiliary/HelpFunc.h @@ -87,8 +87,7 @@ 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); 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 From 44684c462edea7e55cfdd7cb740f33397b90d7a9 Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Mon, 7 Apr 2025 18:11:00 +0300 Subject: [PATCH 154/186] fix vsdx binary --- .../Document/BinReader/BinaryReaderD.cpp | 2 +- OOXML/DocxFormat/WritingElement.h | 8 + .../DocxFormatLib.vcxproj.filters | 5 +- OOXML/VsdxFormat/Shapes.cpp | 19 ++ OOXML/VsdxFormat/Shapes.h | 2 + OOXML/VsdxFormat/VisioConnections.cpp | 143 ++++++++ OOXML/VsdxFormat/VisioConnections.h | 52 +++ OOXML/VsdxFormat/VisioDocument.cpp | 314 +++++++++++++++++- OOXML/VsdxFormat/VisioDocument.h | 114 ++++++- 9 files changed, 644 insertions(+), 15 deletions(-) diff --git a/OOXML/Binary/Document/BinReader/BinaryReaderD.cpp b/OOXML/Binary/Document/BinReader/BinaryReaderD.cpp index 1a6f8955b3..4aa058d45c 100644 --- a/OOXML/Binary/Document/BinReader/BinaryReaderD.cpp +++ b/OOXML/Binary/Document/BinReader/BinaryReaderD.cpp @@ -1570,7 +1570,7 @@ 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::docGrid == type) + else if (c_oSerProp_secPrType::bidi == type) { pSectPr->m_oBidi.Init(); pSectPr->m_oBidi->m_oVal.FromBool(m_oBufferedStream.GetBool()); diff --git a/OOXML/DocxFormat/WritingElement.h b/OOXML/DocxFormat/WritingElement.h index 557892b20b..7ccdc774ae 100644 --- a/OOXML/DocxFormat/WritingElement.h +++ b/OOXML/DocxFormat/WritingElement.h @@ -1597,8 +1597,16 @@ namespace OOX 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, diff --git a/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj.filters b/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj.filters index 3bd5d412b1..af6da32519 100644 --- a/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj.filters +++ b/OOXML/Projects/Windows/DocxFormatLib/DocxFormatLib.vcxproj.filters @@ -582,6 +582,7 @@ VsdxFormat + XlsxFormat\Workbook @@ -1007,7 +1008,6 @@ XlsxFormat\Pivots -<<<<<<< HEAD VsdxFormat @@ -1034,10 +1034,9 @@ VsdxFormat -======= + XlsxFormat\Workbook ->>>>>>> origin/release/v9.0.0 \ No newline at end of file diff --git a/OOXML/VsdxFormat/Shapes.cpp b/OOXML/VsdxFormat/Shapes.cpp index 3cc8a41308..aeeef80410 100644 --- a/OOXML/VsdxFormat/Shapes.cpp +++ b/OOXML/VsdxFormat/Shapes.cpp @@ -1039,9 +1039,12 @@ namespace OOX void CCell::fromXML(XmlUtils::CXmlLiteReader& oReader) { ReadAttributes(oReader); + if (oReader.IsEmptyNode()) return; + content = oReader.GetText2(); + int nParentDepth = oReader.GetDepth(); while (oReader.ReadNextSiblingNode(nParentDepth)) { @@ -1064,6 +1067,13 @@ namespace OOX 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) { @@ -1108,6 +1118,10 @@ namespace OOX RefBy.Init(); RefBy->fromPPTY(pReader); }break; + case 1: + { + content = pReader->GetString2(); + }break; default: { pReader->SkipRecord(); @@ -1130,6 +1144,11 @@ namespace OOX if (RefBy.IsInit()) RefBy->toXmlWriter(pWriter); + if (false == content.empty()) + { + pWriter->WriteStringXML(content); + } + pWriter->WriteNodeEnd(L"Cell"); } EElementType CTrigger::getType() const diff --git a/OOXML/VsdxFormat/Shapes.h b/OOXML/VsdxFormat/Shapes.h index 502895a382..71cb600f72 100644 --- a/OOXML/VsdxFormat/Shapes.h +++ b/OOXML/VsdxFormat/Shapes.h @@ -360,6 +360,8 @@ namespace OOX nullable_string V; nullable RefBy; + + std::wstring content; }; class CTrigger : public WritingElement { diff --git a/OOXML/VsdxFormat/VisioConnections.cpp b/OOXML/VsdxFormat/VisioConnections.cpp index d4a4e886e4..152e3d0345 100644 --- a/OOXML/VsdxFormat/VisioConnections.cpp +++ b/OOXML/VsdxFormat/VisioConnections.cpp @@ -550,8 +550,13 @@ namespace Draw } 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) @@ -588,6 +593,8 @@ namespace Draw { 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])); @@ -689,6 +696,16 @@ namespace Draw 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); @@ -1291,5 +1308,131 @@ namespace Draw 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 index cede0c7966..d3183e1062 100644 --- a/OOXML/VsdxFormat/VisioConnections.h +++ b/OOXML/VsdxFormat/VisioConnections.h @@ -42,6 +42,58 @@ namespace OOX { 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: diff --git a/OOXML/VsdxFormat/VisioDocument.cpp b/OOXML/VsdxFormat/VisioDocument.cpp index 1bd4ffe0a6..c21785dd67 100644 --- a/OOXML/VsdxFormat/VisioDocument.cpp +++ b/OOXML/VsdxFormat/VisioDocument.cpp @@ -43,6 +43,185 @@ 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; @@ -1573,6 +1752,107 @@ namespace Draw 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 { @@ -1645,7 +1925,7 @@ namespace Draw } else if (L"SnapAngles" == sName) { - SnapAngles = oReader.GetText2(); + SnapAngles = oReader; } else if (L"DynamicGridEnabled" == sName) { @@ -1694,12 +1974,13 @@ namespace Draw pWriter->WriteUInt2(22, GlueSettings); pWriter->WriteUInt2(23, SnapSettings); pWriter->WriteUInt2(24, SnapExtensions); - pWriter->WriteBool2(25, SnapAngles); 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) @@ -1727,11 +2008,11 @@ namespace Draw }break; case 3: { - WindowLeft = pReader->GetULong(); + WindowLeft = pReader->GetLong(); }break; case 4: { - WindowTop = pReader->GetULong(); + WindowTop = pReader->GetLong(); }break; case 5: { @@ -1813,10 +2094,6 @@ namespace Draw { SnapExtensions = pReader->GetULong(); }break; - case 25: - { - SnapAngles = pReader->GetBool(); - }break; case 26: { DynamicGridEnabled = pReader->GetBool(); @@ -1835,6 +2112,23 @@ namespace Draw }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 @@ -1870,12 +2164,14 @@ namespace Draw pWriter->WriteNodeValue(L"GlueSettings", GlueSettings); pWriter->WriteNodeValue(L"SnapSettings", SnapSettings); pWriter->WriteNodeValue(L"SnapExtensions", SnapExtensions); - pWriter->WriteNodeValue(L"SnapAngles", SnapAngles); 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"); } //----------------------------------------------------------------------------------------------------------------------------- diff --git a/OOXML/VsdxFormat/VisioDocument.h b/OOXML/VsdxFormat/VisioDocument.h index 5891f354e4..e977d3a8af 100644 --- a/OOXML/VsdxFormat/VisioDocument.h +++ b/OOXML/VsdxFormat/VisioDocument.h @@ -41,6 +41,75 @@ 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: @@ -327,6 +396,46 @@ namespace OOX 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: @@ -372,11 +481,12 @@ namespace OOX nullable_uint GlueSettings; nullable_uint SnapSettings; nullable_uint SnapExtensions; - nullable_bool SnapAngles; nullable_bool DynamicGridEnabled; nullable_double TabSplitterPos; nullable_uint StencilGroup; nullable_uint StencilGroupPos; + + nullable SnapAngles; }; class CWindows : public WritingElementWithChilds { @@ -431,7 +541,7 @@ namespace OOX nullable DocumentSheet; nullable EventList; nullable HeaderFooter; - //nullable PublishSettings; + nullable PublishSettings; }; class CWindowsFile : public OOX::File { From e9162eb230fc467422d6f019c88c6b282eadb107 Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Tue, 8 Apr 2025 13:34:48 +0300 Subject: [PATCH 155/186] add ansi to vsdx binary --- DesktopEditor/common/StringBuilder.cpp | 5 +- DesktopEditor/common/StringBuilder.h | 2 + OOXML/Base/Nullable.h | 83 +++++++++++++++++++ .../Presentation/BinaryFileReaderWriter.cpp | 50 ++++++++++- .../Presentation/BinaryFileReaderWriter.h | 8 +- OOXML/Binary/Presentation/XmlWriter.cpp | 14 ++++ OOXML/Binary/Presentation/XmlWriter.h | 6 +- OOXML/DocxFormat/WritingElement.h | 10 ++- OOXML/VsdxFormat/Shapes.cpp | 40 ++++----- OOXML/VsdxFormat/Shapes.h | 20 ++--- 10 files changed, 201 insertions(+), 37 deletions(-) diff --git a/DesktopEditor/common/StringBuilder.cpp b/DesktopEditor/common/StringBuilder.cpp index 99f4eb626b..9f67ec6921 100644 --- a/DesktopEditor/common/StringBuilder.cpp +++ b/DesktopEditor/common/StringBuilder.cpp @@ -319,7 +319,10 @@ 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::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..99f8dfe99e 100644 --- a/DesktopEditor/common/StringBuilder.h +++ b/DesktopEditor/common/StringBuilder.h @@ -110,6 +110,8 @@ namespace NSStringUtils void WriteEncodeXmlString(const std::wstring& sString); void WriteEncodeXmlString(const wchar_t* pString, int nCount = -1); + void WriteEncodeXmlString(const std::string& sString); + void WriteEncodeXmlStringHHHH(const std::wstring& sString); void WriteEncodeXmlStringHHHH(const wchar_t* pString, int nCount = -1); 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/Presentation/BinaryFileReaderWriter.cpp b/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp index 97055bc20b..016ced31b0 100644 --- a/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp +++ b/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp @@ -1058,7 +1058,6 @@ namespace NSBinPptxRW pData += 4; } } - void CBinaryFileWriter::WriteString1(int type, const std::wstring& val) { BYTE bType = (BYTE)type; @@ -1067,6 +1066,14 @@ 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()) @@ -1077,7 +1084,11 @@ namespace NSBinPptxRW 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); @@ -1281,6 +1292,18 @@ namespace NSBinPptxRW m_pStreamCur += lSizeMem; return lSizeMem; } + _INT32 CBinaryFileWriter::_WriteString(const char* sBuffer, _UINT32 lCount) + { + _UINT32 lSizeMem = lCount * sizeof(char); + + CheckBufferSize(UINT32_SIZEOF + lSizeMem); + + memcpy(m_pStreamCur, sBuffer, lSizeMem); + + 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 +1341,29 @@ 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; + } CStreamBinaryWriter::CStreamBinaryWriter(size_t bufferSize) { diff --git a/OOXML/Binary/Presentation/BinaryFileReaderWriter.h b/OOXML/Binary/Presentation/BinaryFileReaderWriter.h index a00e32ecdb..445528d978 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 { @@ -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,10 @@ 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 WriteString1Data(int type, const WCHAR* pData, _UINT32 len); void WriteBool1(int type, const bool& val); @@ -439,7 +443,9 @@ namespace NSBinPptxRW bool GetSafearray(BYTE **ppArray, size_t& szCount); private: _INT32 _WriteString(const WCHAR* sBuffer, _UINT32 lCount); + _INT32 _WriteString(const char* sBuffer, _UINT32 lCount); void _WriteStringWithLength(const WCHAR* sBuffer, _UINT32 lCount, bool bByte); + void _WriteStringWithLength(const char* sBuffer, _UINT32 lCount); }; class CStreamBinaryWriter : public NSFile::CFileBinary, public CBinaryFileWriter diff --git a/OOXML/Binary/Presentation/XmlWriter.cpp b/OOXML/Binary/Presentation/XmlWriter.cpp index 33c616155b..8e4df526f1 100644 --- a/OOXML/Binary/Presentation/XmlWriter.cpp +++ b/OOXML/Binary/Presentation/XmlWriter.cpp @@ -199,6 +199,15 @@ 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::WriteAttribute(const std::wstring& strAttributeName, const double& val) { m_oWriter.WriteString(g_bstr_node_space); @@ -428,6 +437,11 @@ 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::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..b49748a863 100644 --- a/OOXML/Binary/Presentation/XmlWriter.h +++ b/OOXML/Binary/Presentation/XmlWriter.h @@ -124,7 +124,8 @@ 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 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 +161,9 @@ 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); template void WriteAttribute(const std::wstring& strName, const nullable_limit& value) diff --git a/OOXML/DocxFormat/WritingElement.h b/OOXML/DocxFormat/WritingElement.h index 7ccdc774ae..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 )\ {\ diff --git a/OOXML/VsdxFormat/Shapes.cpp b/OOXML/VsdxFormat/Shapes.cpp index aeeef80410..b915a945a7 100644 --- a/OOXML/VsdxFormat/Shapes.cpp +++ b/OOXML/VsdxFormat/Shapes.cpp @@ -708,9 +708,9 @@ namespace OOX WritingElement_ReadAttributes_StartChar_No_NS(oReader) WritingElement_ReadAttributes_Read_ifChar(oReader, "IX", IX) WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Del", Del) - WritingElement_ReadAttributes_Read_else_ifChar(oReader, "N", N) + WritingElement_ReadAttributesA_Read_else_ifChar(oReader, "N", N) WritingElement_ReadAttributes_Read_else_ifChar(oReader, "LocalName", LocalName) - WritingElement_ReadAttributes_Read_else_ifChar(oReader, "T", T) + WritingElement_ReadAttributesA_Read_else_ifChar(oReader, "T", T) WritingElement_ReadAttributes_EndChar_No_NS(oReader) } void CRow::fromXML(XmlUtils::CXmlLiteReader& oReader) @@ -779,7 +779,7 @@ namespace OOX }break; case 1: { - N = pReader->GetString2(); + N = pReader->GetString2A(); }break; case 2: { @@ -787,7 +787,7 @@ namespace OOX }break; case 3: { - T = pReader->GetString2(); + T = pReader->GetString2A(); }break; case 4: { @@ -843,7 +843,7 @@ namespace OOX WritingElement_ReadAttributes_StartChar_No_NS(oReader) WritingElement_ReadAttributes_Read_ifChar(oReader, "IX", IX) WritingElement_ReadAttributes_Read_else_ifChar(oReader, "Del", Del) - WritingElement_ReadAttributes_Read_else_ifChar(oReader, "N", N) + WritingElement_ReadAttributesA_Read_else_ifChar(oReader, "N", N) WritingElement_ReadAttributes_EndChar_No_NS(oReader) } void CSection::fromXML(XmlUtils::CXmlLiteReader& oReader) @@ -915,7 +915,7 @@ namespace OOX }break; case 1: { - N = pReader->GetString2(); + N = pReader->GetString2A(); }break; case 2: { @@ -1029,10 +1029,10 @@ namespace OOX void CCell::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_StartChar_No_NS(oReader) - WritingElement_ReadAttributes_Read_ifChar(oReader, "N", N) - WritingElement_ReadAttributes_Read_else_ifChar(oReader, "U", U) - WritingElement_ReadAttributes_Read_else_ifChar(oReader, "E", E) - WritingElement_ReadAttributes_Read_else_ifChar(oReader, "F", F) + 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_ReadAttributes_Read_else_ifChar(oReader, "V", V) WritingElement_ReadAttributes_EndChar_No_NS(oReader) } @@ -1088,19 +1088,19 @@ namespace OOX { case 0: { - N = pReader->GetString2(); + N = pReader->GetString2A(); }break; case 1: { - U = pReader->GetString2(); + U = pReader->GetString2A(); }break; case 2: { - E = pReader->GetString2(); + E = pReader->GetString2A(); }break; case 3: { - F = pReader->GetString2(); + F = pReader->GetString2A(); }break; case 4: { @@ -1158,7 +1158,7 @@ namespace OOX void CTrigger::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_StartChar_No_NS(oReader) - WritingElement_ReadAttributes_Read_ifChar(oReader, "N", N) + WritingElement_ReadAttributesA_Read_ifChar(oReader, "N", N) WritingElement_ReadAttributes_EndChar_No_NS(oReader) } void CTrigger::fromXML(XmlUtils::CXmlLiteReader& oReader) @@ -1199,7 +1199,7 @@ namespace OOX { case 0: { - N = pReader->GetString2(); + N = pReader->GetString2A(); }break; } } @@ -1539,10 +1539,10 @@ namespace OOX { WritingElement_ReadAttributes_StartChar_No_NS(oReader) WritingElement_ReadAttributes_Read_ifChar(oReader, "FromSheet", FromSheet) - WritingElement_ReadAttributes_Read_else_ifChar(oReader, "FromCell", FromCell) + 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_ReadAttributes_Read_else_ifChar(oReader, "ToCell", ToCell) + WritingElement_ReadAttributesA_Read_else_ifChar(oReader, "ToCell", ToCell) WritingElement_ReadAttributes_Read_else_ifChar(oReader, "ToPart", ToPart) WritingElement_ReadAttributes_EndChar_No_NS(oReader) } @@ -1580,7 +1580,7 @@ namespace OOX }break; case 1: { - FromCell = pReader->GetString2(); + FromCell = pReader->GetString2A(); }break; case 2: { @@ -1592,7 +1592,7 @@ namespace OOX }break; case 4: { - ToCell = pReader->GetString2(); + ToCell = pReader->GetString2A(); }break; case 5: { diff --git a/OOXML/VsdxFormat/Shapes.h b/OOXML/VsdxFormat/Shapes.h index 71cb600f72..f74a3e0a9f 100644 --- a/OOXML/VsdxFormat/Shapes.h +++ b/OOXML/VsdxFormat/Shapes.h @@ -275,10 +275,10 @@ namespace OOX virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); virtual EElementType getType() const; - nullable_string N; + nullable_astring N; nullable_string LocalName; nullable_uint IX; - nullable_string T; // todooo GeometryRowTypes + nullable_astring T; // todooo GeometryRowTypes nullable_bool Del; }; class CSection : public WritingElementWithChilds<> @@ -300,7 +300,7 @@ namespace OOX virtual void fromPPTY(NSBinPptxRW::CBinaryFileReader* pReader); virtual EElementType getType() const; - nullable_string N; + nullable_astring N; nullable_bool Del; nullable_uint IX; }; @@ -353,10 +353,10 @@ namespace OOX void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); public: - nullable_string N; - nullable_string U; //todooo type - nullable_string E; //todooo err - nullable_string F; + nullable_astring N; + nullable_astring U; //todooo type + nullable_astring E; //todooo err + nullable_astring F; nullable_string V; nullable RefBy; @@ -386,7 +386,7 @@ namespace OOX void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); public: - nullable_string N; + nullable_astring N; nullable RefBy; }; @@ -466,10 +466,10 @@ namespace OOX public: nullable_uint FromSheet; - nullable_string FromCell; + nullable_astring FromCell; nullable_int FromPart; nullable_uint ToSheet; - nullable_string ToCell; + nullable_astring ToCell; nullable_int ToPart; }; class CConnects : public WritingElementWithChilds From 3f426789326bc6045f0bea4bf2a570ef46f94abd Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 8 Apr 2025 20:57:25 +0600 Subject: [PATCH 156/186] fix bug #73914 --- .../XlsxFormat/Pivot/PivotCacheChildOther.cpp | 139 +++++++++++++++++- OOXML/XlsxFormat/Pivot/PivotCacheChildOther.h | 54 ++++++- OOXML/XlsxFormat/Pivot/PivotCacheDefinition.h | 1 + OOXML/XlsxFormat/Pivot/Pivots.cpp | 10 +- 4 files changed, 201 insertions(+), 3 deletions(-) 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 554a8bb607..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 diff --git a/OOXML/XlsxFormat/Pivot/Pivots.cpp b/OOXML/XlsxFormat/Pivot/Pivots.cpp index 4fa54109bc..6c40d35ac7 100644 --- a/OOXML/XlsxFormat/Pivot/Pivots.cpp +++ b/OOXML/XlsxFormat/Pivot/Pivots.cpp @@ -3889,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()) @@ -3917,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() @@ -3934,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()) @@ -4047,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; From 66bed0e286a9ec154a0bd85c9d83a6e0d20b93f3 Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Wed, 9 Apr 2025 11:54:08 +0300 Subject: [PATCH 157/186] fix vsdt_bin --- .../Presentation/BinaryFileReaderWriter.cpp | 84 ++++++++++++++++++- .../Presentation/BinaryFileReaderWriter.h | 6 ++ OOXML/VsdxFormat/Shapes.cpp | 10 +-- OOXML/VsdxFormat/Shapes.h | 2 +- X2tConverter/src/ASCConverters.cpp | 56 +++++++++++++ X2tConverter/src/ASCConverters.h | 1 + X2tConverter/src/cextracttools.h | 3 + 7 files changed, 154 insertions(+), 8 deletions(-) diff --git a/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp b/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp index 016ced31b0..942f32c804 100644 --- a/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp +++ b/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp @@ -1079,6 +1079,16 @@ namespace NSBinPptxRW if (val.is_init()) WriteString1(type, *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::WriteString(const std::wstring& val) { std::wstring* s = const_cast(&val); @@ -1275,6 +1285,8 @@ namespace NSBinPptxRW } _INT32 CBinaryFileWriter::_WriteString(const WCHAR* sBuffer, _UINT32 lCount) { + if (lCount < 1) return 0; + _INT32 lSizeMem = 0; if (sizeof(wchar_t) == 4) { @@ -1294,6 +1306,8 @@ namespace NSBinPptxRW } _INT32 CBinaryFileWriter::_WriteString(const char* sBuffer, _UINT32 lCount) { + if (lCount < 1) return 0; + _UINT32 lSizeMem = lCount * sizeof(char); CheckBufferSize(UINT32_SIZEOF + lSizeMem); @@ -1304,6 +1318,21 @@ namespace NSBinPptxRW 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) @@ -1364,6 +1393,36 @@ namespace NSBinPptxRW 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) { @@ -2128,7 +2187,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""; @@ -2224,7 +2300,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 445528d978..b22521c3a6 100644 --- a/OOXML/Binary/Presentation/BinaryFileReaderWriter.h +++ b/OOXML/Binary/Presentation/BinaryFileReaderWriter.h @@ -347,6 +347,8 @@ namespace NSBinPptxRW void WriteString2 (int type, const NSCommon::nullable_astring& val); void WriteStringA (std::string& val); + void WriteStringUtf8(int type, const NSCommon::nullable_string& val); + void WriteString1Data(int type, const WCHAR* pData, _UINT32 len); void WriteBool1(int type, const bool& val); @@ -444,8 +446,10 @@ namespace NSBinPptxRW 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 @@ -591,9 +595,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/VsdxFormat/Shapes.cpp b/OOXML/VsdxFormat/Shapes.cpp index b915a945a7..9bebd2be74 100644 --- a/OOXML/VsdxFormat/Shapes.cpp +++ b/OOXML/VsdxFormat/Shapes.cpp @@ -1032,7 +1032,7 @@ namespace OOX 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_ReadAttributes_Read_else_ifChar(oReader, "F", F) WritingElement_ReadAttributes_Read_else_ifChar(oReader, "V", V) WritingElement_ReadAttributes_EndChar_No_NS(oReader) } @@ -1062,8 +1062,8 @@ namespace OOX pWriter->WriteString2(0, N); pWriter->WriteString2(1, U); pWriter->WriteString2(2, E); - pWriter->WriteString2(3, F); - pWriter->WriteString2(4, V); + pWriter->WriteStringUtf8(3, F); + pWriter->WriteStringUtf8(4, V); pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); pWriter->WriteRecord2(0, RefBy); @@ -1100,11 +1100,11 @@ namespace OOX }break; case 3: { - F = pReader->GetString2A(); + F = pReader->GetStringUtf8(); }break; case 4: { - V = pReader->GetString2(); + V = pReader->GetStringUtf8(); }break; } } diff --git a/OOXML/VsdxFormat/Shapes.h b/OOXML/VsdxFormat/Shapes.h index f74a3e0a9f..f1adfb0a59 100644 --- a/OOXML/VsdxFormat/Shapes.h +++ b/OOXML/VsdxFormat/Shapes.h @@ -356,7 +356,7 @@ namespace OOX nullable_astring N; nullable_astring U; //todooo type nullable_astring E; //todooo err - nullable_astring F; + nullable_string F; nullable_string V; nullable RefBy; diff --git a/X2tConverter/src/ASCConverters.cpp b/X2tConverter/src/ASCConverters.cpp index 4b3ceedfd5..fada4c3fee 100644 --- a/X2tConverter/src/ASCConverters.cpp +++ b/X2tConverter/src/ASCConverters.cpp @@ -1450,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) { @@ -2109,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 d6a4c24356..d83cd9d412 100644 --- a/X2tConverter/src/ASCConverters.h +++ b/X2tConverter/src/ASCConverters.h @@ -312,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.h b/X2tConverter/src/cextracttools.h index 876bb6edc7..c1a9853121 100644 --- a/X2tConverter/src/cextracttools.h +++ b/X2tConverter/src/cextracttools.h @@ -229,6 +229,7 @@ namespace NExtractTools TCD_DOCT_BIN2, TCD_XLST_BIN2, TCD_PPTT_BIN2, + TCD_VSDT_BIN2, TCD_DOCUMENT2, TCD_SPREADSHEET2, TCD_PRESENTATION2, @@ -1004,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) From 69880099710fb3ba3d9a0da23eef3762ad94750f Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Wed, 9 Apr 2025 15:05:34 +0300 Subject: [PATCH 158/186] fix bug #73902 --- OOXML/Binary/Document/BinWriter/BinaryWriterD.cpp | 2 +- OOXML/Binary/Document/BinWriter/BinaryWriterD.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/OOXML/Binary/Document/BinWriter/BinaryWriterD.cpp b/OOXML/Binary/Document/BinWriter/BinaryWriterD.cpp index 83696f9c85..0e50ddb243 100644 --- a/OOXML/Binary/Document/BinWriter/BinaryWriterD.cpp +++ b/OOXML/Binary/Document/BinWriter/BinaryWriterD.cpp @@ -9883,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/BinaryWriterD.h b/OOXML/Binary/Document/BinWriter/BinaryWriterD.h index 4bc17e52f7..38d742f38f 100644 --- a/OOXML/Binary/Document/BinWriter/BinaryWriterD.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, From 160e99ab905a66e86f2cae649bde28a0db08f38c Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Wed, 9 Apr 2025 15:06:00 +0300 Subject: [PATCH 159/186] . --- DesktopEditor/common/StringBuilder.cpp | 4 ++++ DesktopEditor/common/StringBuilder.h | 1 + .../Binary/Presentation/BinaryFileReaderWriter.h | 1 + OOXML/Binary/Presentation/XmlWriter.cpp | 14 ++++++++++++++ OOXML/Binary/Presentation/XmlWriter.h | 2 ++ OOXML/VsdxFormat/Shapes.cpp | 16 ++++++++-------- OOXML/VsdxFormat/Shapes.h | 4 ++-- 7 files changed, 32 insertions(+), 10 deletions(-) diff --git a/DesktopEditor/common/StringBuilder.cpp b/DesktopEditor/common/StringBuilder.cpp index 9f67ec6921..e86786565d 100644 --- a/DesktopEditor/common/StringBuilder.cpp +++ b/DesktopEditor/common/StringBuilder.cpp @@ -323,6 +323,10 @@ namespace NSStringUtils { 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 99f8dfe99e..f822a8b801 100644 --- a/DesktopEditor/common/StringBuilder.h +++ b/DesktopEditor/common/StringBuilder.h @@ -111,6 +111,7 @@ namespace NSStringUtils 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/OOXML/Binary/Presentation/BinaryFileReaderWriter.h b/OOXML/Binary/Presentation/BinaryFileReaderWriter.h index b22521c3a6..3218d9832f 100644 --- a/OOXML/Binary/Presentation/BinaryFileReaderWriter.h +++ b/OOXML/Binary/Presentation/BinaryFileReaderWriter.h @@ -348,6 +348,7 @@ namespace NSBinPptxRW 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); diff --git a/OOXML/Binary/Presentation/XmlWriter.cpp b/OOXML/Binary/Presentation/XmlWriter.cpp index 8e4df526f1..d398abe007 100644 --- a/OOXML/Binary/Presentation/XmlWriter.cpp +++ b/OOXML/Binary/Presentation/XmlWriter.cpp @@ -208,6 +208,15 @@ void CXmlWriter::WriteAttribute2(const std::wstring& strAttributeName, const std 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); @@ -442,6 +451,11 @@ void CXmlWriter::WriteAttribute2(const std::wstring& strName, const nullable_ast 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 b49748a863..e6480d6022 100644 --- a/OOXML/Binary/Presentation/XmlWriter.h +++ b/OOXML/Binary/Presentation/XmlWriter.h @@ -126,6 +126,7 @@ namespace NSBinPptxRW void WriteAttribute(const std::wstring& strAttributeName, const wchar_t* 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); @@ -164,6 +165,7 @@ namespace NSBinPptxRW 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/VsdxFormat/Shapes.cpp b/OOXML/VsdxFormat/Shapes.cpp index 9bebd2be74..82dbc27327 100644 --- a/OOXML/VsdxFormat/Shapes.cpp +++ b/OOXML/VsdxFormat/Shapes.cpp @@ -1032,8 +1032,8 @@ namespace OOX WritingElement_ReadAttributesA_Read_ifChar(oReader, "N", N) WritingElement_ReadAttributesA_Read_else_ifChar(oReader, "U", U) WritingElement_ReadAttributesA_Read_else_ifChar(oReader, "E", E) - WritingElement_ReadAttributes_Read_else_ifChar(oReader, "F", F) - WritingElement_ReadAttributes_Read_else_ifChar(oReader, "V", V) + 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) @@ -1062,8 +1062,8 @@ namespace OOX pWriter->WriteString2(0, N); pWriter->WriteString2(1, U); pWriter->WriteString2(2, E); - pWriter->WriteStringUtf8(3, F); - pWriter->WriteStringUtf8(4, V); + pWriter->WriteString2(3, F); + pWriter->WriteString2(4, V); pWriter->WriteBYTE(NSBinPptxRW::g_nodeAttributeEnd); pWriter->WriteRecord2(0, RefBy); @@ -1100,11 +1100,11 @@ namespace OOX }break; case 3: { - F = pReader->GetStringUtf8(); + F = pReader->GetString2A(); }break; case 4: { - V = pReader->GetStringUtf8(); + V = pReader->GetString2A(); }break; } } @@ -1135,10 +1135,10 @@ namespace OOX pWriter->StartNode(L"Cell"); pWriter->StartAttributes(); pWriter->WriteAttribute2(L"N", N); - pWriter->WriteAttribute2(L"V", V); + pWriter->WriteAttributeUtf8(L"V", V); pWriter->WriteAttribute2(L"U", U); pWriter->WriteAttribute2(L"E", E); - pWriter->WriteAttribute2(L"F", F); + pWriter->WriteAttributeUtf8(L"F", F); pWriter->EndAttributes(); if (RefBy.IsInit()) diff --git a/OOXML/VsdxFormat/Shapes.h b/OOXML/VsdxFormat/Shapes.h index f1adfb0a59..070d8c209e 100644 --- a/OOXML/VsdxFormat/Shapes.h +++ b/OOXML/VsdxFormat/Shapes.h @@ -356,8 +356,8 @@ namespace OOX nullable_astring N; nullable_astring U; //todooo type nullable_astring E; //todooo err - nullable_string F; - nullable_string V; + nullable_astring F; + nullable_astring V; nullable RefBy; From 7b264e940df4753a4e5ada4472a155e6ca831c26 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 9 Apr 2025 15:38:21 +0300 Subject: [PATCH 160/186] Merge Outlines two files --- PdfFile/PdfEditor.cpp | 142 +++++++++++++++++++++++++++++- PdfFile/PdfEditor.h | 2 +- PdfFile/PdfFile.cpp | 5 +- PdfFile/PdfFile.h | 2 +- PdfFile/PdfReader.cpp | 4 +- PdfFile/SrcWriter/Destination.cpp | 26 +++--- PdfFile/SrcWriter/Destination.h | 4 +- PdfFile/SrcWriter/Document.cpp | 2 +- PdfFile/SrcWriter/Document.h | 3 +- PdfFile/test/test.cpp | 36 ++++++-- 10 files changed, 192 insertions(+), 34 deletions(-) diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 177dd732b0..6d65e41b29 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -40,12 +40,16 @@ #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)\ {\ @@ -929,7 +933,7 @@ CPdfEditor::CPdfEditor(const std::wstring& _wsSrcFile, const std::wstring& _wsPa } bool CPdfEditor::IncrementalUpdates() { - if (m_nMode == Mode::Unknown) + if (m_nMode != Mode::Unknown) return true; m_nMode = Mode::WriteAppend; @@ -1157,7 +1161,7 @@ void CPdfEditor::Close() if (m_wsDstFile.empty()) return; - if (m_nMode == Mode::WriteAppend) + if (m_nMode != Mode::WriteAppend) { m_pWriter->SaveToFile(m_wsDstFile); return; @@ -1894,7 +1898,106 @@ BYTE* CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength) RELEASEARRAYOBJECTS(pRes); return NULL; } -bool CPdfEditor::MergePages(const int* arrPageIndex, unsigned int unLength) +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 int* arrPageIndex, unsigned int unLength) { if (m_nMode != Mode::WriteAppend && !IncrementalUpdates()) return false; @@ -1904,6 +2007,39 @@ bool CPdfEditor::MergePages(const int* arrPageIndex, unsigned int unLength) 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) diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h index aefb3f68a8..e548a75668 100644 --- a/PdfFile/PdfEditor.h +++ b/PdfFile/PdfEditor.h @@ -94,7 +94,7 @@ public: bool IsBase14(const std::wstring& wsFontName, bool& bBold, bool& bItalic, std::wstring& wsFontPath); BYTE* SplitPages(const int* arrPageIndex, unsigned int unLength); - bool MergePages(const int* arrPageIndex, unsigned int unLength); + bool MergePages(const std::wstring& wsPath, const int* arrPageIndex, unsigned int unLength); private: void GetPageTree(XRef* xref, Object* pPagesRefObj, PdfWriter::CPageTree* pPageParent = NULL); diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index d26eb57446..27e0cb68c5 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -32,13 +32,12 @@ #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" -#include "PdfEditor.h" #include "OnlineOfficeBinToPdf.h" #include "SrcWriter/Document.h" @@ -141,7 +140,7 @@ bool CPdfFile::MergePages(const std::wstring& wsPath, const std::wstring& wsPass if (!m_pInternal->pEditor) return false; if (m_pInternal->pReader->MergePages(wsPath, wsPassword)) - return m_pInternal->pEditor->MergePages(arrPageIndex, unLength); + return m_pInternal->pEditor->MergePages(wsPath, arrPageIndex, unLength); return false; } bool CPdfFile::MovePage(int nPageIndex, int nPos) diff --git a/PdfFile/PdfFile.h b/PdfFile/PdfFile.h index 8e2f3b2cca..0985f3eed9 100644 --- a/PdfFile/PdfFile.h +++ b/PdfFile/PdfFile.h @@ -126,8 +126,8 @@ public: virtual BYTE* GetStructure(); virtual BYTE* GetLinks(int nPageIndex); - bool MergePages(BYTE* data, DWORD length); bool ValidMetaData(); + bool MergePages(BYTE* data, DWORD length); int GetRotate(int nPageIndex); int GetMaxRefID(); BYTE* GetWidgets(); diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index c2cabea6bd..644cc73a11 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -961,13 +961,13 @@ BYTE* CPdfReader::GetStructure() for (int iPDF = 0; iPDF < m_vPDFContext.size(); ++iPDF) { PDFDoc* pDoc = m_vPDFContext[iPDF]->m_pDocument; - if (!pDoc->getOutline()) + Outline* pOutline = pDoc->getOutline(); + if (!pOutline) { nStartPage += pDoc->getNumPages(); continue; } - Outline* pOutline = pDoc->getOutline(); GList* pList = pOutline->getItems(); if (!pList) { 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 2e4d48bb17..4219c8cb8f 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -527,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); diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index ffa26461ef..fb0fee9841 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -130,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); diff --git a/PdfFile/test/test.cpp b/PdfFile/test/test.cpp index 9e4d71a908..3b539e26ee 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,21 +350,39 @@ TEST_F(CPdfFileTest, VerifySign) RELEASEOBJECT(pCertificate); } -TEST_F(CPdfFileTest, MergePdf) +TEST_F(CPdfFileTest, SplitPdf) { GTEST_SKIP(); LoadFromFile(); - std::vector arrPages = { 0, 1 }; + 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)); - pdfFile->MergePages(wsDstFile); + std::wstring wsSplitFile = NSFile::GetProcessDirectory() + L"/test_split.pdf"; + pdfFile->MergePages(wsSplitFile); pdfFile->Close(); - - RELEASEARRAYOBJECTS(pFile); } TEST_F(CPdfFileTest, EditPdf) @@ -389,7 +407,7 @@ TEST_F(CPdfFileTest, EditPdf) TEST_F(CPdfFileTest, EditPdfFromBase64) { - // GTEST_SKIP(); + GTEST_SKIP(); NSFonts::NSApplicationFontStream::SetGlobalMemoryStorage(NSFonts::NSApplicationFontStream::CreateDefaultGlobalMemoryStorage()); From 776569ca81dbaf62eaae620181741d4e87bfad16 Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Wed, 9 Apr 2025 20:03:25 +0300 Subject: [PATCH 161/186] fix xfrm --- .../ASCOfficeDrawingConverter.cpp | 54 ++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) 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""); From 3fe4c2ac21c12889ea3015ad004ea3c5719127a1 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 10 Apr 2025 10:48:05 +0300 Subject: [PATCH 162/186] Add getPagesInfo --- .../graphics/pro/js/wasm/js/drawingfile.js | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js index 080051f59e..74517269b4 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js @@ -212,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 []; + + // skip 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() { From 7cd7b03b891e80853f2d7b3cfaa5ac0e8e2a8127 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 10 Apr 2025 15:50:01 +0300 Subject: [PATCH 163/186] Add nMaxID --- DesktopEditor/doctrenderer/drawingfile.h | 4 +- .../graphics/pro/js/wasm/js/drawingfile.js | 8 +-- .../graphics/pro/js/wasm/src/drawingfile.cpp | 4 +- .../pro/js/wasm/src/drawingfile_test.cpp | 2 +- PdfFile/OnlineOfficeBinToPdf.cpp | 24 +++++---- PdfFile/PdfEditor.cpp | 4 +- PdfFile/PdfEditor.h | 2 +- PdfFile/PdfFile.cpp | 10 ++-- PdfFile/PdfFile.h | 4 +- PdfFile/PdfReader.cpp | 54 ++++++++----------- PdfFile/PdfReader.h | 9 ++-- 11 files changed, 61 insertions(+), 64 deletions(-) diff --git a/DesktopEditor/doctrenderer/drawingfile.h b/DesktopEditor/doctrenderer/drawingfile.h index b8f08d28ca..d497161f9b 100644 --- a/DesktopEditor/doctrenderer/drawingfile.h +++ b/DesktopEditor/doctrenderer/drawingfile.h @@ -289,10 +289,10 @@ public: return ((CPdfFile*)m_pFile)->SplitPages(arrPageIndex, nLength); return NULL; } - bool MergePages(BYTE* data, LONG size) + bool MergePages(BYTE* data, LONG size, int nMaxID) { if (m_nType == 0) - return ((CPdfFile*)m_pFile)->MergePages(data, size); + return ((CPdfFile*)m_pFile)->MergePages(data, size, nMaxID); return false; } diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js index 74517269b4..632b59dd88 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js @@ -172,9 +172,9 @@ CFile.prototype["SplitPages"] = function(arrPageIndex) Module["_free"](ptr); return buffer; }; -CFile.prototype["MergePages"] = function(arrayBuffer) +CFile.prototype["MergePages"] = function(arrayBuffer, maxID) { - return this._MergePages(arrayBuffer); + return this._MergePages(arrayBuffer, maxID); }; // INFO DOCUMENT @@ -221,8 +221,8 @@ CFile.prototype.getPagesInfo = function() let reader = ptr.getReader(); if (!reader) return []; - // skip StartID - reader.readInt(); + // change StartID + this.StartID = reader.readInt(); let _pages = []; let nPages = reader.readInt(); diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp index b28b296052..88f718c2aa 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp @@ -181,9 +181,9 @@ 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) +WASM_EXPORT int MergePages(CDrawingFile* pFile, BYTE* data, LONG size, int nMaxID) { - return pFile->MergePages(data, size) ? 1 : 0; + return pFile->MergePages(data, size, nMaxID) ? 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 bb2036d67a..55aea64cb4 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp @@ -1002,7 +1002,7 @@ int main(int argc, char* argv[]) oFile.WriteFile(pSplitPages + 4, nLength - 4); oFile.CloseFile(); - if (MergePages(pGrFile, pSplitPages + 4, nLength - 4) == 0) + if (MergePages(pGrFile, pSplitPages + 4, nLength - 4, 0) == 0) RELEASEARRAYOBJECTS(pSplitPages); } } diff --git a/PdfFile/OnlineOfficeBinToPdf.cpp b/PdfFile/OnlineOfficeBinToPdf.cpp index 33e9cb24cd..8cafd76ee5 100644 --- a/PdfFile/OnlineOfficeBinToPdf.cpp +++ b/PdfFile/OnlineOfficeBinToPdf.cpp @@ -213,16 +213,22 @@ namespace NSOnlineOfficeBinToPdf } case AddCommandType::MergePages: { - std::wstring wsPath = oReader.ReadString(); - std::wstring wsPassword = oReader.ReadString(); + std::wstring wsPath = NSFile::CFileBinary::CreateTempFileWithUniqueName(pPdf->GetTempDirectory(), L"PDF"); int nLength = oReader.ReadInt(); - int* pPageIndex = NULL; - if (nLength > 0) - pPageIndex = new int[nLength]; - for (int i = 0; i < nLength; ++i) - pPageIndex[i] = oReader.ReadInt(); - pPdf->MergePages(wsPath, wsPassword, pPageIndex, nLength); - RELEASEARRAYOBJECTS(pPageIndex); + 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); + RELEASEARRAYOBJECTS(pFile); break; } case AddCommandType::WidgetInfo: diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 6d65e41b29..93588003c7 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -1997,13 +1997,13 @@ void CreateOutlines(PDFDoc* pdfDoc, PdfWriter::CDocument* pDoc, OutlineItem* pOu } pOutlineItem->close(); } -bool CPdfEditor::MergePages(const std::wstring& wsPath, const int* arrPageIndex, unsigned int unLength) +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(arrPageIndex, unLength, pDocument, nStartRefID); + bool bRes = SplitPages(NULL, 0, pDocument, nStartRefID); if (!bRes) return false; diff --git a/PdfFile/PdfEditor.h b/PdfFile/PdfEditor.h index e548a75668..937697e15d 100644 --- a/PdfFile/PdfEditor.h +++ b/PdfFile/PdfEditor.h @@ -94,7 +94,7 @@ public: 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 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); diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 27e0cb68c5..205c90cd77 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -135,12 +135,12 @@ bool CPdfFile::AddPage(int nPageIndex) return false; return m_pInternal->pEditor->AddPage(nPageIndex); } -bool CPdfFile::MergePages(const std::wstring& wsPath, const std::wstring& wsPassword, const int* arrPageIndex, unsigned int unLength) +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, wsPassword)) - return m_pInternal->pEditor->MergePages(wsPath, arrPageIndex, unLength); + if (m_pInternal->pReader->MergePages(wsPath, L"", nMaxID)) + return m_pInternal->pEditor->MergePages(wsPath, wsPrefixForm); return false; } bool CPdfFile::MovePage(int nPageIndex, int nPos) @@ -336,11 +336,11 @@ 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) +bool CPdfFile::MergePages(BYTE* data, DWORD length, int nMaxID) { if (!m_pInternal->pReader) return false; - return m_pInternal->pReader->MergePages(data, length) && (m_pInternal->pReader->GetError() == 0); + return m_pInternal->pReader->MergePages(data, length, L"", nMaxID) && (m_pInternal->pReader->GetError() == 0); } int CPdfFile::GetRotate(int nPageIndex) { diff --git a/PdfFile/PdfFile.h b/PdfFile/PdfFile.h index 0985f3eed9..543a74775f 100644 --- a/PdfFile/PdfFile.h +++ b/PdfFile/PdfFile.h @@ -97,7 +97,7 @@ public: bool DeletePage(int nPageIndex); bool AddPage (int nPageIndex); bool MovePage (int nPageIndex, int nPos); - bool MergePages(const std::wstring& wsPath, const std::wstring& wsPassword = L"", const int* arrPageIndex = NULL, unsigned int unLength = 0); + 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""); // --- READER --- @@ -127,7 +127,7 @@ public: virtual BYTE* GetLinks(int nPageIndex); bool ValidMetaData(); - bool MergePages(BYTE* data, DWORD length); + bool MergePages(BYTE* data, DWORD length, int nMaxID = 0); int GetRotate(int nPageIndex); int GetMaxRefID(); BYTE* GetWidgets(); diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 644cc73a11..0ae6ebe140 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -414,45 +414,37 @@ void CPdfReader::SetParams(COfficeDrawingPageParams* pParams) int CPdfReader::GetStartRefID(PDFDoc* _pDoc) { - int nStartRefID = 0; for (CPdfReaderContext* pPDFContext : m_vPDFContext) { if (!pPDFContext || !pPDFContext->m_pDocument) continue; PDFDoc* pDoc = pPDFContext->m_pDocument; if (_pDoc == pDoc) - return nStartRefID; - nStartRefID += pDoc->getXRef()->getNumObjects(); + return pPDFContext->m_nStartID; } return -1; } int CPdfReader::FindRefNum(int nObjID, PDFDoc** _pDoc, int* _nStartRefID) { - int nStartRefID = 0; for (CPdfReaderContext* pPDFContext : m_vPDFContext) { if (!pPDFContext || !pPDFContext->m_pDocument) continue; PDFDoc* pDoc = pPDFContext->m_pDocument; - - int nLastRefID = pDoc->getXRef()->getNumObjects(); - if (nObjID < nStartRefID + nLastRefID) + if (nObjID < pPDFContext->m_nStartID + pDoc->getXRef()->getNumObjects()) { if (_pDoc) *_pDoc = pDoc; if (_nStartRefID) - *_nStartRefID = nStartRefID; - return nObjID - nStartRefID; + *_nStartRefID = pPDFContext->m_nStartID; + return nObjID - pPDFContext->m_nStartID; } - nStartRefID += nLastRefID; } return -1; } int CPdfReader::GetPageIndex(int nAbsPageIndex, PDFDoc** _pDoc, PdfReader::CPdfFontList** pFontList, int* nStartRefID) { int nTotalPages = 0; - if (nStartRefID) - *nStartRefID = 0; for (CPdfReaderContext* pPDFContext : m_vPDFContext) { if (!pPDFContext || !pPDFContext->m_pDocument) @@ -466,10 +458,10 @@ int CPdfReader::GetPageIndex(int nAbsPageIndex, PDFDoc** _pDoc, PdfReader::CPdfF *_pDoc = pDoc; if (pFontList) *pFontList = pPDFContext->m_pFontList; + if (nStartRefID) + *nStartRefID = pPDFContext->m_nStartID; return nAbsPageIndex - nTotalPages + 1; } - if (nStartRefID) - *nStartRefID += pDoc->getXRef()->getNumObjects(); nTotalPages += nPages; } return -1; @@ -527,14 +519,9 @@ int CPdfReader::GetRotate(int _nPageIndex) } int CPdfReader::GetMaxRefID() { - int nSumRefID = 0; - for (CPdfReaderContext* pPDFContext : m_vPDFContext) - { - if (!pPDFContext || !pPDFContext->m_pDocument || !pPDFContext->m_pDocument->getXRef()) - continue; - nSumRefID += pPDFContext->m_pDocument->getXRef()->getNumObjects(); - } - return nSumRefID; + if (!m_vPDFContext.empty()) + return m_vPDFContext.back()->m_nStartID + m_vPDFContext.back()->m_pDocument->getXRef()->getNumObjects(); + return 0; } int CPdfReader::GetNumPages() { @@ -578,7 +565,7 @@ bool CPdfReader::ValidMetaData() oID.free(); oID2.free(); return bRes; } -bool CPdfReader::MergePages(BYTE* pData, DWORD nLength, const std::wstring& wsPassword) +bool CPdfReader::MergePages(BYTE* pData, DWORD nLength, const std::wstring& wsPassword, int nMaxID) { if (m_eError) return false; @@ -591,8 +578,12 @@ bool CPdfReader::MergePages(BYTE* pData, DWORD nLength, const std::wstring& wsPa // будет освобожден в деструкторе PDFDoc BaseStream *str = new MemStream((char*)pData, 0, nLength, &obj); CPdfReaderContext* pContext = new CPdfReaderContext(); - pContext->m_pDocument = new PDFDoc(str, NULL, NULL); + pContext->m_pDocument = new PDFDoc(str, owner_pswd, user_pswd); pContext->m_pFontList = new PdfReader::CPdfFontList(); + 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); @@ -612,7 +603,7 @@ bool CPdfReader::MergePages(BYTE* pData, DWORD nLength, const std::wstring& wsPa return true; } -bool CPdfReader::MergePages(const std::wstring& wsFile, const std::wstring& wsPassword) +bool CPdfReader::MergePages(const std::wstring& wsFile, const std::wstring& wsPassword, int nMaxID) { if (m_eError) return false; @@ -624,6 +615,10 @@ bool CPdfReader::MergePages(const std::wstring& wsFile, const std::wstring& wsPa CPdfReaderContext* pContext = new CPdfReaderContext(); pContext->m_pDocument = new PDFDoc((char*)sPathUtf8.c_str(), owner_pswd, user_pswd); pContext->m_pFontList = new PdfReader::CPdfFontList(); + if (nMaxID != 0) + pContext->m_nStartID = nMaxID; + 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); @@ -1137,7 +1132,6 @@ BYTE* CPdfReader::GetWidgets() oRes.SkipLen(); int nStartPage = 0; - int nStartRefID = 0; for (CPdfReaderContext* pPDFContext : m_vPDFContext) { PDFDoc* pDoc = pPDFContext->m_pDocument; @@ -1146,16 +1140,14 @@ BYTE* CPdfReader::GetWidgets() if (!pDoc->getCatalog()->getForm() || !pDoc->getXRef()) { nStartPage += pDoc->getNumPages(); - nStartRefID += pDoc->getXRef()->getNumObjects(); continue; } - PdfReader::CAnnots* pAnnots = new PdfReader::CAnnots(pDoc, m_pFontManager, pPDFContext->m_pFontList, nStartPage, nStartRefID); + PdfReader::CAnnots* pAnnots = new PdfReader::CAnnots(pDoc, m_pFontManager, pPDFContext->m_pFontList, nStartPage, pPDFContext->m_nStartID); if (pAnnots) pAnnots->ToWASM(oRes); RELEASEOBJECT(pAnnots); nStartPage += pDoc->getNumPages(); - nStartRefID += pDoc->getXRef()->getNumObjects(); } oRes.WriteLen(); @@ -1733,7 +1725,6 @@ BYTE* CPdfReader::GetAnnots(int _nPageIndex) else { int nStartPage = 0; - int nStartRefID = 0; for (CPdfReaderContext* pPDFContext : m_vPDFContext) { PDFDoc* pDoc = pPDFContext->m_pDocument; @@ -1744,11 +1735,10 @@ BYTE* CPdfReader::GetAnnots(int _nPageIndex) oRes.AddInt(nAnnots); for (int nPage = 1, nPages = pDoc->getNumPages(); nPage <= nPages; ++nPage) - nAnnots += GetPageAnnots(pDoc, m_pFontManager, pPDFContext->m_pFontList, oRes, nPage, nStartPage, nStartRefID); + nAnnots += GetPageAnnots(pDoc, m_pFontManager, pPDFContext->m_pFontList, oRes, nPage, nStartPage, pPDFContext->m_nStartID); oRes.AddInt(nAnnots, nPosAnnots); nStartPage += pDoc->getNumPages(); - nStartRefID += pDoc->getXRef()->getNumObjects(); } } diff --git a/PdfFile/PdfReader.h b/PdfFile/PdfReader.h index f4b1f40194..b1bb4392d3 100644 --- a/PdfFile/PdfReader.h +++ b/PdfFile/PdfReader.h @@ -45,9 +45,10 @@ struct CPdfReaderContext { PDFDoc* m_pDocument; PdfReader::CPdfFontList* m_pFontList; + unsigned int m_nStartID; - CPdfReaderContext() : m_pDocument(NULL), m_pFontList(NULL) {} - CPdfReaderContext(PDFDoc* pDocument, PdfReader::CPdfFontList* pFontList) : m_pDocument(pDocument), m_pFontList(pFontList) {} + CPdfReaderContext() : m_pDocument(NULL), m_pFontList(NULL), m_nStartID(0) {} + CPdfReaderContext(PDFDoc* pDocument, PdfReader::CPdfFontList* pFontList, unsigned int nStartID) : m_pDocument(pDocument), m_pFontList(pFontList), m_nStartID(nStartID) {} ~CPdfReaderContext(); }; @@ -76,8 +77,8 @@ public: int GetMaxRefID(); int GetNumPages(); bool ValidMetaData(); - bool MergePages(BYTE* pData, DWORD nLength, const std::wstring& wsPassword = L""); - bool MergePages(const std::wstring& wsFile, const std::wstring& wsPassword = L""); + bool MergePages(BYTE* pData, DWORD nLength, const std::wstring& wsPassword = L"", int nMaxID = 0); + bool MergePages(const std::wstring& wsFile, const std::wstring& wsPassword = L"", int nMaxID = 0); void GetPageInfo(int nPageIndex, double* pdWidth, double* pdHeight, double* pdDpiX, double* pdDpiY); void DrawPageOnRenderer(IRenderer* pRenderer, int nPageIndex, bool* pBreak); std::wstring GetInfo(); From 185be63b2729aaa711f708e9ae78f7e293c90dba Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Thu, 10 Apr 2025 16:50:50 +0300 Subject: [PATCH 164/186] Add STREAM_FILTER_ALREADY_DECODE --- .../pro/js/wasm/js/drawingfile_wasm.js | 7 +++-- PdfFile/PdfEditor.cpp | 27 ++++++++++++++++--- PdfFile/SrcWriter/Document.cpp | 12 +++++++++ PdfFile/SrcWriter/Document.h | 1 + PdfFile/SrcWriter/Objects.h | 2 +- PdfFile/SrcWriter/Pages.cpp | 6 +++++ PdfFile/SrcWriter/Streams.cpp | 2 +- PdfFile/SrcWriter/Streams.h | 1 + 8 files changed, 51 insertions(+), 7 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_wasm.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_wasm.js index e3186f8f51..dba0a4f203 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_wasm.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_wasm.js @@ -130,7 +130,7 @@ CFile.prototype._SplitPages = function(memoryBuffer) return ptr; }; -CFile.prototype._MergePages = function(buffer) +CFile.prototype._MergePages = function(buffer, maxID) { if (!buffer) return false; @@ -139,7 +139,10 @@ CFile.prototype._MergePages = function(buffer) let stream2 = Module["_malloc"](data.length); Module["HEAP8"].set(data, stream2); - let bRes = Module["_MergePages"](this.nativeFile, stream2, data.length); + if (!maxID) + maxID = 0; + + let bRes = Module["_MergePages"](this.nativeFile, stream2, data.length, maxID); if (bRes == 1) this.stream.push(stream2); else diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 93588003c7..86ac2033f3 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -1627,13 +1627,34 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFD 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) - { - // pPage->AddContents(); // TODO pPage->AddContents чтобы можно было дописать изменения, если понадобится - } + pDoc->FixEditPage(pPage); else m_pWriter->SetNeedAddHelvetica(false); // TODO дописывает шрифт для адекватного редактирования Adobe pdf без текст. Убрать при реализации map шрифтов pageObj.free(); diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 4219c8cb8f..e0aea9f13d 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -1522,6 +1522,18 @@ 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; diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index fb0fee9841..5a04aa21e1 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -196,6 +196,7 @@ namespace PdfWriter bool EditResources(CXref* pXref, CResourcesDict* pResources); std::pair GetPageRef(int nPageIndex); bool EditPage(CXref* pXref, CPage* pPage, 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); diff --git a/PdfFile/SrcWriter/Objects.h b/PdfFile/SrcWriter/Objects.h index 78e5d3a296..1c5d9de08a 100644 --- a/PdfFile/SrcWriter/Objects.h +++ b/PdfFile/SrcWriter/Objects.h @@ -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); diff --git a/PdfFile/SrcWriter/Pages.cpp b/PdfFile/SrcWriter/Pages.cpp index cf53785f28..4c4883735c 100644 --- a/PdfFile/SrcWriter/Pages.cpp +++ b/PdfFile/SrcWriter/Pages.cpp @@ -366,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 { diff --git a/PdfFile/SrcWriter/Streams.cpp b/PdfFile/SrcWriter/Streams.cpp index 6a3ab108ff..dd4cb297df 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 diff --git a/PdfFile/SrcWriter/Streams.h b/PdfFile/SrcWriter/Streams.h index 18c585da32..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 From 888f67dab23ec4f51434b3a3c2e577134b571252 Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Fri, 11 Apr 2025 10:18:06 +0300 Subject: [PATCH 165/186] fix bug #70741 --- .../Presentation/BinaryFileReaderWriter.cpp | 436 ++++++++++-------- .../Presentation/BinaryFileReaderWriter.h | 8 +- OOXML/Binary/Sheets/Writer/BinaryReaderS.cpp | 8 +- OOXML/PPTXFormat/Logic/Fills/Blip.cpp | 4 +- OOXML/PPTXFormat/Logic/Fills/BlipFill.cpp | 4 +- OOXML/PPTXFormat/Logic/Fills/BlipFill.h | 4 +- OOXML/PPTXFormat/Logic/Pic.cpp | 152 +++--- OOXML/PPTXFormat/Logic/SpTreeElem.cpp | 6 +- OOXML/PPTXFormat/Logic/UniFill.cpp | 2 +- 9 files changed, 334 insertions(+), 290 deletions(-) diff --git a/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp b/OOXML/Binary/Presentation/BinaryFileReaderWriter.cpp index 942f32c804..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); } @@ -1089,7 +1108,16 @@ namespace NSBinPptxRW _WriteStringUtf8WithLength(val->c_str(), (_UINT32)val->length()); } } - void CBinaryFileWriter::WriteString(const std::wstring& val) + 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); @@ -1762,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; @@ -1793,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"/>"); + } } } } diff --git a/OOXML/Binary/Presentation/BinaryFileReaderWriter.h b/OOXML/Binary/Presentation/BinaryFileReaderWriter.h index 3218d9832f..17d99beb4c 100644 --- a/OOXML/Binary/Presentation/BinaryFileReaderWriter.h +++ b/OOXML/Binary/Presentation/BinaryFileReaderWriter.h @@ -101,7 +101,7 @@ namespace NSBinPptxRW struct _imageManager2Info { - std::wstring sFilepathAdditional; + std::vector sFilepathAdditionals; std::wstring sFilepathImage; }; @@ -220,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); @@ -519,7 +519,7 @@ 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); }; diff --git a/OOXML/Binary/Sheets/Writer/BinaryReaderS.cpp b/OOXML/Binary/Sheets/Writer/BinaryReaderS.cpp index fe0953c673..4ea9ce69b6 100644 --- a/OOXML/Binary/Sheets/Writer/BinaryReaderS.cpp +++ b/OOXML/Binary/Sheets/Writer/BinaryReaderS.cpp @@ -4638,8 +4638,8 @@ int BinaryWorksheetsTableReader::ReadWorksheet(boost::unordered_mapm_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""); + 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); @@ -5002,8 +5002,8 @@ int BinaryWorksheetsTableReader::ReadWorksheet(boost::unordered_mapm_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""); + 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); 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/Pic.cpp b/OOXML/PPTXFormat/Logic/Pic.cpp index 93b08c1baf..2af168399d 100644 --- a/OOXML/PPTXFormat/Logic/Pic.cpp +++ b/OOXML/PPTXFormat/Logic/Pic.cpp @@ -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); @@ -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,8 @@ namespace PPTX else break; } - smart_ptr mediaFile = blipFill.additionalFile.smart_dynamic_cast(); + blipFill.additionalFiles.emplace_back(); + smart_ptr mediaFile = blipFill.additionalFiles.back().smart_dynamic_cast(); if (mediaFile.IsInit()) { mediaFile->set_filename(strMediaFileMask, isExternal); @@ -1137,73 +1142,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); + } } } } 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/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()) From 7a9c57038e19bf9d99240b0f2a94090f1ba749dd Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Fri, 11 Apr 2025 10:18:19 +0300 Subject: [PATCH 166/186] . --- OOXML/VsdxFormat/Shapes.cpp | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/OOXML/VsdxFormat/Shapes.cpp b/OOXML/VsdxFormat/Shapes.cpp index 82dbc27327..239d024ffa 100644 --- a/OOXML/VsdxFormat/Shapes.cpp +++ b/OOXML/VsdxFormat/Shapes.cpp @@ -1043,16 +1043,33 @@ namespace OOX if (oReader.IsEmptyNode()) return; - content = oReader.GetText2(); + int nDepth = oReader.GetDepth(); + XmlUtils::XmlNodeType eNodeType = XmlUtils::XmlNodeType_EndElement; - int nParentDepth = oReader.GetDepth(); - while (oReader.ReadNextSiblingNode(nParentDepth)) + while (oReader.Read(eNodeType) && oReader.GetDepth() >= nDepth && XmlUtils::XmlNodeType_EndElement != eNodeType) { - std::wstring sName = oReader.GetName(); - - if (L"RefBy" == sName) + if (eNodeType == XmlUtils::XmlNodeType_Text + || eNodeType == XmlUtils::XmlNodeType_Whitespace + || eNodeType == XmlUtils::XmlNodeType_SIGNIFICANT_WHITESPACE + || eNodeType == XmlUtils::XmlNodeType_CDATA) { - RefBy = oReader; + 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; + } } } } From 85c60f172c36d98ffbbd21ed5468f5b12df9e100 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 11 Apr 2025 11:19:22 +0300 Subject: [PATCH 167/186] Fix add not supported annots --- PdfFile/OnlineOfficeBinToPdf.cpp | 1 - PdfFile/PdfEditor.cpp | 22 ++++++++++++++++++++-- PdfFile/test/test.cpp | 6 +++--- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/PdfFile/OnlineOfficeBinToPdf.cpp b/PdfFile/OnlineOfficeBinToPdf.cpp index 8cafd76ee5..ae93dd2330 100644 --- a/PdfFile/OnlineOfficeBinToPdf.cpp +++ b/PdfFile/OnlineOfficeBinToPdf.cpp @@ -228,7 +228,6 @@ namespace NSOnlineOfficeBinToPdf int nMaxID = oReader.ReadInt(); std::wstring wsPrefix = oReader.ReadString(); pPdf->MergePages(wsPath, nMaxID, wsPrefix); - RELEASEARRAYOBJECTS(pFile); break; } case AddCommandType::WidgetInfo: diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 86ac2033f3..7372142085 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -369,8 +369,11 @@ PdfWriter::CObjectBase* DictToCDictObject2(Object* obj, PdfWriter::CDocument* pD if (obj->dictLookup("Type", &oType)->isName("Annot") && obj->dictLookup("Subtype", &oSubtype)->isName()) { PdfWriter::CAnnotation* pAnnot = CreateAnnot(obj, &oSubtype, NULL); - pDoc->AddAnnotation(nAddObjToXRef + nStartRefID, pAnnot); - pDict = pAnnot; + if (pAnnot) + { + pDoc->AddAnnotation(nAddObjToXRef + nStartRefID, pAnnot); + pDict = pAnnot; + } } oType.free(); oSubtype.free(); @@ -1649,12 +1652,27 @@ bool CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength, PDFD 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(); diff --git a/PdfFile/test/test.cpp b/PdfFile/test/test.cpp index 3b539e26ee..0b16d4a4de 100644 --- a/PdfFile/test/test.cpp +++ b/PdfFile/test/test.cpp @@ -373,14 +373,14 @@ TEST_F(CPdfFileTest, SplitPdf) TEST_F(CPdfFileTest, MergePdf) { - // GTEST_SKIP(); + GTEST_SKIP(); LoadFromFile(); ASSERT_TRUE(pdfFile->EditPdf(wsDstFile)); std::wstring wsSplitFile = NSFile::GetProcessDirectory() + L"/test_split.pdf"; - pdfFile->MergePages(wsSplitFile); + pdfFile->MergePages(wsSplitFile, 0, L""); pdfFile->Close(); } @@ -407,7 +407,7 @@ TEST_F(CPdfFileTest, EditPdf) TEST_F(CPdfFileTest, EditPdfFromBase64) { - GTEST_SKIP(); + //GTEST_SKIP(); NSFonts::NSApplicationFontStream::SetGlobalMemoryStorage(NSFonts::NSApplicationFontStream::CreateDefaultGlobalMemoryStorage()); From 0a85051119d8635ac335e7ecdad7ec016971ca9e Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 11 Apr 2025 12:32:04 +0300 Subject: [PATCH 168/186] Fix bug 73997 --- PdfFile/SrcWriter/Annotation.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/PdfFile/SrcWriter/Annotation.cpp b/PdfFile/SrcWriter/Annotation.cpp index d680bfabcb..a66c8d3249 100644 --- a/PdfFile/SrcWriter/Annotation.cpp +++ b/PdfFile/SrcWriter/Annotation.cpp @@ -2216,8 +2216,6 @@ namespace PdfWriter void CAction::SetType(const std::wstring& wsType) { m_sType = U_TO_UTF8(wsType); - if (wsType != L"A") - Add("S", m_sType.c_str()); } void CAction::SetNext(CAction* pNext) { From aaeb745ad3b0d681cb61b279c85ea6bcec12012e Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 11 Apr 2025 13:05:43 +0300 Subject: [PATCH 169/186] Fix create Annot not as ref --- PdfFile/PdfWriter.cpp | 62 +---------- PdfFile/SrcWriter/Document.cpp | 193 ++++++++++++++------------------- PdfFile/SrcWriter/Document.h | 17 +-- 3 files changed, 88 insertions(+), 184 deletions(-) diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 4ebb429c99..2a7592fe5a 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -1816,65 +1816,9 @@ 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) { diff --git a/PdfFile/SrcWriter/Document.cpp b/PdfFile/SrcWriter/Document.cpp index 9cf53fee48..77b93838a7 100644 --- a/PdfFile/SrcWriter/Document.cpp +++ b/PdfFile/SrcWriter/Document.cpp @@ -610,11 +610,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,111 +710,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); - m_pXref->Add(pWidget); - - CArrayObject* ppFields = (CArrayObject*)m_pAcroForm->Get("Fields"); - ppFields->Add(pWidget); - - return pWidget; - } - CAnnotation* CDocument::CreatePushButtonWidget() - { - if (!CheckAcroForm()) - return NULL; - - CWidgetAnnotation* pWidget = new CPushButtonWidget(m_pXref); - m_pXref->Add(pWidget); - pWidget->Add("FT", "Btn"); - CArrayObject* ppFields = (CArrayObject*)m_pAcroForm->Get("Fields"); - ppFields->Add(pWidget); - - return pWidget; - } - CAnnotation* CDocument::CreateCheckBoxWidget() - { - if (!CheckAcroForm()) - return NULL; - - CWidgetAnnotation* pWidget = new CCheckBoxWidget(m_pXref); - m_pXref->Add(pWidget); - pWidget->Add("FT", "Btn"); - CArrayObject* ppFields = (CArrayObject*)m_pAcroForm->Get("Fields"); - ppFields->Add(pWidget); - - return pWidget; - } - CAnnotation* CDocument::CreateTextWidget() - { - if (!CheckAcroForm()) - return NULL; - - CAnnotation* pWidget = new CTextWidget(m_pXref); - m_pXref->Add(pWidget); - pWidget->Add("FT", "Tx"); - CArrayObject* ppFields = (CArrayObject*)m_pAcroForm->Get("Fields"); - ppFields->Add(pWidget); - - return pWidget; - } - CAnnotation* CDocument::CreateChoiceWidget() - { - if (!CheckAcroForm()) - return NULL; - - CAnnotation* pWidget = new CChoiceWidget(m_pXref); - m_pXref->Add(pWidget); - pWidget->Add("FT", "Ch"); - CArrayObject* ppFields = (CArrayObject*)m_pAcroForm->Get("Fields"); - ppFields->Add(pWidget); - - return pWidget; - } - CAnnotation* CDocument::CreateSignatureWidget() - { - return new CSignatureWidget(m_pXref); - } CAction* CDocument::CreateAction(BYTE nType) { switch (nType) diff --git a/PdfFile/SrcWriter/Document.h b/PdfFile/SrcWriter/Document.h index fc511360d1..5272bda048 100644 --- a/PdfFile/SrcWriter/Document.h +++ b/PdfFile/SrcWriter/Document.h @@ -136,24 +136,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); From c7a4edec03d66b5e43c71098a1d987be3e0a4066 Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Fri, 11 Apr 2025 15:02:03 +0300 Subject: [PATCH 170/186] . --- OOXML/Binary/Presentation/imagemanager.cpp | 3 --- OOXML/PPTXFormat/Logic/Pic.cpp | 1 - 2 files changed, 4 deletions(-) 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/PPTXFormat/Logic/Pic.cpp b/OOXML/PPTXFormat/Logic/Pic.cpp index 2af168399d..44a231160f 100644 --- a/OOXML/PPTXFormat/Logic/Pic.cpp +++ b/OOXML/PPTXFormat/Logic/Pic.cpp @@ -1123,7 +1123,6 @@ namespace PPTX else break; } - blipFill.additionalFiles.emplace_back(); smart_ptr mediaFile = blipFill.additionalFiles.back().smart_dynamic_cast(); if (mediaFile.IsInit()) { From ac300f57a6d12d0c533162a667a7246f32ed6a6d Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 11 Apr 2025 16:09:29 +0300 Subject: [PATCH 171/186] MaxLen separately for field and parent --- DesktopEditor/graphics/commands/AnnotField.cpp | 2 ++ DesktopEditor/graphics/commands/AnnotField.h | 1 + .../graphics/pro/js/wasm/js/drawingfile.js | 2 ++ .../pro/js/wasm/src/drawingfile_test.cpp | 10 ++++++++-- PdfFile/PdfWriter.cpp | 2 ++ PdfFile/SrcReader/PdfAnnot.cpp | 16 +++++++++++++--- PdfFile/SrcReader/PdfAnnot.h | 1 + 7 files changed, 29 insertions(+), 5 deletions(-) diff --git a/DesktopEditor/graphics/commands/AnnotField.cpp b/DesktopEditor/graphics/commands/AnnotField.cpp index 324ec84322..1821e6e371 100644 --- a/DesktopEditor/graphics/commands/AnnotField.cpp +++ b/DesktopEditor/graphics/commands/AnnotField.cpp @@ -1132,6 +1132,8 @@ bool CWidgetsInfo::Read(NSOnlineOfficeBinToPdf::CBufferReader* pReader, IMetafil } } } + 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 9276b06560..078d0e5d60 100644 --- a/DesktopEditor/graphics/commands/AnnotField.h +++ b/DesktopEditor/graphics/commands/AnnotField.h @@ -567,6 +567,7 @@ public: { int nID; int nFlags; + int nMaxLen; int nParentID; int nFieldFlag; std::wstring sName; diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js index 2d9ac49213..095138c629 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js @@ -616,6 +616,8 @@ CFile.prototype["getInteractiveFormsInfo"] = function() readAction(reader, rec["AA"][AAType]); } } + if (flags & (1 << 9)) + rec["maxLen"] = reader.readInt(); res["Parents"].push(rec); } diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp index 6324203b62..f7e1044f19 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp @@ -351,7 +351,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)) { @@ -392,7 +392,7 @@ void ReadInteractiveForms(BYTE* pWidgets, int& i) { nPathLength = READ_INT(pWidgets + i); i += 4; - std::cout << "Ff " << nPathLength; + std::cout << "Ff " << nPathLength << ", "; } if (nFlags & (1 << 8)) { @@ -410,6 +410,12 @@ void ReadInteractiveForms(BYTE* pWidgets, int& i) } std::cout << std::endl; } + if (nFlags & (1 << 9)) + { + nPathLength = READ_INT(pWidgets + i); + i += 4; + std::cout << "MaxLen " << nPathLength << ", "; + } std::cout << std::endl; } diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 2a7592fe5a..7ea98f6a71 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -2777,6 +2777,8 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi } } } + if (nFlags & (1 << 9)) + pParentObj->Add("MaxLen", pParent->nMaxLen); } std::vector arrBI = pFieldInfo->GetButtonImg(); diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index e5f3ffb6b6..e722698622 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -1214,12 +1214,12 @@ 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)) @@ -2678,6 +2678,14 @@ void CAnnots::getParents(PDFDoc* pdfDoc, Object* oFieldRef) } 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; @@ -3644,6 +3652,8 @@ void CAnnots::CAnnotParent::ToWASM(NSWasm::CData& oRes) arrAction[i]->ToWASM(oRes); } } + if (unFlags & (1 << 9)) + oRes.AddInt(unMaxLen); } void CAnnot::ToWASM(NSWasm::CData& oRes) { diff --git a/PdfFile/SrcReader/PdfAnnot.h b/PdfFile/SrcReader/PdfAnnot.h index 5d176ef7a2..ed8782e739 100644 --- a/PdfFile/SrcReader/PdfAnnot.h +++ b/PdfFile/SrcReader/PdfAnnot.h @@ -610,6 +610,7 @@ private: unsigned int unFlags; unsigned int unRefNum; // Номер ссылки на объект + unsigned int unMaxLen; // Ограничение на максимальную длину text field unsigned int unFieldFlag; // Флаг Ff unsigned int unRefNumParent; // Номер ссылки на объект родителя std::vector arrI; From 4bef318bd66ee9e4aea437118a3924c1d0f6bc22 Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Fri, 11 Apr 2025 16:29:23 +0300 Subject: [PATCH 172/186] . --- .../Document/DocWrapper/DocxSerializer.cpp | 1 - OOXML/VsdxFormat/Shapes.cpp | 56 ++++++++++++++----- 2 files changed, 43 insertions(+), 14 deletions(-) diff --git a/OOXML/Binary/Document/DocWrapper/DocxSerializer.cpp b/OOXML/Binary/Document/DocWrapper/DocxSerializer.cpp index ecc17bccc8..7f28384ea2 100644 --- a/OOXML/Binary/Document/DocWrapper/DocxSerializer.cpp +++ b/OOXML/Binary/Document/DocWrapper/DocxSerializer.cpp @@ -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/VsdxFormat/Shapes.cpp b/OOXML/VsdxFormat/Shapes.cpp index 239d024ffa..d3a9099198 100644 --- a/OOXML/VsdxFormat/Shapes.cpp +++ b/OOXML/VsdxFormat/Shapes.cpp @@ -33,9 +33,12 @@ #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" @@ -154,20 +157,16 @@ namespace OOX smart_ptr pFile = pWriter->GetRels()->Find(Rel->Rid->GetValue()); OOX::OleObject* pOleObject = dynamic_cast(pFile.GetPointer()); + + CPath image_path; if (pOleObject) { - CPath cache = pOleObject->filename_cache(); + image_path = pOleObject->filename_cache(); CPath ole = pOleObject->filename(); //todooo check correct path inside container - - NSFile::CFileBinary::Copy(cache.GetPath(), out.GetPath() + FILE_SEPARATOR_STR + cache.GetFilename()); NSFile::CFileBinary::Copy(ole.GetPath(), out.GetPath() + FILE_SEPARATOR_STR + ole.GetFilename()); - pWriter->StartRecord(1); - pWriter->WriteString(cache.GetFilename()); - pWriter->EndRecord(); - pWriter->StartRecord(2); pWriter->WriteString(ole.GetFilename()); pWriter->EndRecord(); @@ -177,12 +176,43 @@ namespace OOX OOX::Media* pMedia = dynamic_cast(pFile.GetPointer()); if (pMedia) { - CPath media = pMedia->filename(); - pMedia->copy_to(out.GetPath()); - - pWriter->StartRecord(1); - pWriter->WriteString(media.GetFilename()); - pWriter->EndRecord(); + 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); + } } } } From c503044fc9ffd1da6d5fbb496c5736f0b0d333d0 Mon Sep 17 00:00:00 2001 From: michael-efremov Date: Thu, 10 Apr 2025 13:06:06 +0300 Subject: [PATCH 173/186] [android] Add support ODG --- X2tConverter/build/Android/libx2t/src/main/cpp/jni/X2t.cpp | 1 + 1 file changed, 1 insertion(+) 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); From fa5fa35a3495db3389cf85268e245c87747db0af Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Sat, 12 Apr 2025 14:34:01 +0300 Subject: [PATCH 174/186] Fix bug 73788 --- DesktopEditor/doctrenderer/app_builder/main.cpp | 2 ++ .../doctrenderer/docbuilder.python/src/docbuilder.py | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/DesktopEditor/doctrenderer/app_builder/main.cpp b/DesktopEditor/doctrenderer/app_builder/main.cpp index 2b3a2ffe12..c05bfc26a2 100644 --- a/DesktopEditor/doctrenderer/app_builder/main.cpp +++ b/DesktopEditor/doctrenderer/app_builder/main.cpp @@ -81,6 +81,8 @@ 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); diff --git a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py index b097c55a2e..e557ff6385 100644 --- a/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py +++ b/DesktopEditor/doctrenderer/docbuilder.python/src/docbuilder.py @@ -618,6 +618,8 @@ 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) + 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) From 95476fc99885c8fac8c4c1da0364d1457dc8a5ed Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Sun, 13 Apr 2025 10:20:21 +0300 Subject: [PATCH 175/186] Fix build --- DesktopEditor/raster/ImageFileFormatChecker.cpp | 12 ++++++------ DesktopEditor/raster/ImageFileFormatChecker.h | 14 +++++++------- 2 files changed, 13 insertions(+), 13 deletions(-) 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); From 68992278ce9c2ffa828c832ff79cd4a435057a6e Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 14 Apr 2025 15:49:07 +0600 Subject: [PATCH 176/186] fix bug #73391 --- HwpFile/HWPFile.pro | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 \ From f5f3d2572ed914921784cdd76e2f85c2eaae5321 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Mon, 14 Apr 2025 15:53:51 +0300 Subject: [PATCH 177/186] Add PrefixForm for rename same full names --- DesktopEditor/doctrenderer/drawingfile.h | 4 +- .../graphics/pro/js/wasm/js/drawingfile.js | 4 +- .../pro/js/wasm/js/drawingfile_wasm.js | 15 ++- .../graphics/pro/js/wasm/src/drawingfile.cpp | 4 +- .../pro/js/wasm/src/drawingfile_test.cpp | 15 ++- PdfFile/PdfEditor.cpp | 10 +- PdfFile/PdfFile.cpp | 4 +- PdfFile/PdfFile.h | 2 +- PdfFile/PdfReader.cpp | 41 +++++-- PdfFile/PdfReader.h | 7 +- PdfFile/SrcReader/PdfAnnot.cpp | 102 +++++++++++++++++- PdfFile/SrcReader/PdfAnnot.h | 25 ++++- 12 files changed, 202 insertions(+), 31 deletions(-) diff --git a/DesktopEditor/doctrenderer/drawingfile.h b/DesktopEditor/doctrenderer/drawingfile.h index d497161f9b..b6433c67cd 100644 --- a/DesktopEditor/doctrenderer/drawingfile.h +++ b/DesktopEditor/doctrenderer/drawingfile.h @@ -289,10 +289,10 @@ public: return ((CPdfFile*)m_pFile)->SplitPages(arrPageIndex, nLength); return NULL; } - bool MergePages(BYTE* data, LONG size, int nMaxID) + bool MergePages(BYTE* data, LONG size, int nMaxID, const std::string& sPrefixForm) { if (m_nType == 0) - return ((CPdfFile*)m_pFile)->MergePages(data, size, nMaxID); + return ((CPdfFile*)m_pFile)->MergePages(data, size, nMaxID, sPrefixForm); return false; } diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js index 632b59dd88..fce8234176 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js @@ -172,9 +172,9 @@ CFile.prototype["SplitPages"] = function(arrPageIndex) Module["_free"](ptr); return buffer; }; -CFile.prototype["MergePages"] = function(arrayBuffer, maxID) +CFile.prototype["MergePages"] = function(arrayBuffer, maxID, prefixForm) { - return this._MergePages(arrayBuffer, maxID); + return this._MergePages(arrayBuffer, maxID, prefixForm); }; // INFO DOCUMENT diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_wasm.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_wasm.js index dba0a4f203..f3d5fd70bb 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_wasm.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile_wasm.js @@ -130,7 +130,7 @@ CFile.prototype._SplitPages = function(memoryBuffer) return ptr; }; -CFile.prototype._MergePages = function(buffer, maxID) +CFile.prototype._MergePages = function(buffer, maxID, prefixForm) { if (!buffer) return false; @@ -142,12 +142,23 @@ CFile.prototype._MergePages = function(buffer, maxID) if (!maxID) maxID = 0; - let bRes = Module["_MergePages"](this.nativeFile, stream2, data.length, maxID); + 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; }; diff --git a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp index 88f718c2aa..7d8b199539 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile.cpp @@ -181,9 +181,9 @@ 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) +WASM_EXPORT int MergePages(CDrawingFile* pFile, BYTE* data, LONG size, int nMaxID, const char* sPrefixForm) { - return pFile->MergePages(data, size, nMaxID) ? 1 : 0; + 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 55aea64cb4..1651a15d0d 100644 --- a/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp +++ b/DesktopEditor/graphics/pro/js/wasm/src/drawingfile_test.cpp @@ -987,7 +987,7 @@ int main(int argc, char* argv[]) // SPLIT & MERGE BYTE* pSplitPages = NULL; - if (true) + if (false) { std::vector arrPages = { 0 }; for (int i = 0; i < 3; i++) @@ -1002,11 +1002,21 @@ int main(int argc, char* argv[]) oFile.WriteFile(pSplitPages + 4, nLength - 4); oFile.CloseFile(); - if (MergePages(pGrFile, pSplitPages + 4, nLength - 4, 0) == 0) + 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); @@ -2002,6 +2012,7 @@ int main(int argc, char* argv[]) Close(pGrFile); RELEASEARRAYOBJECTS(pFileData); RELEASEARRAYOBJECTS(pSplitPages); + RELEASEARRAYOBJECTS(pFileMerge); RELEASEARRAYOBJECTS(pCMapData); return 0; diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 7372142085..26beddbcb3 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -2782,15 +2782,15 @@ void CPdfEditor::EndMarkedContent() } 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 = m_pReader->GetFonts(); - it = mFonts.find(wsFontName); - if (it != mFonts.end()) - wsFontPath = it->second; + const std::map& mFonts = m_pReader->GetFonts(); + std::map::const_iterator it2 = mFonts.find(wsFontName); + if (it2 != mFonts.end()) + wsFontPath = it2->second; } if (wsFontPath.empty()) return false; diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 205c90cd77..1d7c4940e1 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -336,11 +336,11 @@ 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) +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) && (m_pInternal->pReader->GetError() == 0); + return m_pInternal->pReader->MergePages(data, length, L"", nMaxID, sPrefixForm) && (m_pInternal->pReader->GetError() == 0); } int CPdfFile::GetRotate(int nPageIndex) { diff --git a/PdfFile/PdfFile.h b/PdfFile/PdfFile.h index 543a74775f..8187bfdbea 100644 --- a/PdfFile/PdfFile.h +++ b/PdfFile/PdfFile.h @@ -127,7 +127,7 @@ public: virtual BYTE* GetLinks(int nPageIndex); bool ValidMetaData(); - bool MergePages(BYTE* data, DWORD length, int nMaxID = 0); + bool MergePages(BYTE* data, DWORD length, int nMaxID = 0, const std::string& sPrefixForm = ""); int GetRotate(int nPageIndex); int GetMaxRefID(); BYTE* GetWidgets(); diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 0ae6ebe140..f5fe6eb7ce 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -565,7 +565,7 @@ bool CPdfReader::ValidMetaData() oID.free(); oID2.free(); return bRes; } -bool CPdfReader::MergePages(BYTE* pData, DWORD nLength, const std::wstring& wsPassword, int nMaxID) +bool CPdfReader::MergePages(BYTE* pData, DWORD nLength, const std::wstring& wsPassword, int nMaxID, const std::string& sPrefixForm) { if (m_eError) return false; @@ -580,6 +580,7 @@ bool CPdfReader::MergePages(BYTE* pData, DWORD nLength, const std::wstring& wsPa CPdfReaderContext* pContext = new CPdfReaderContext(); pContext->m_pDocument = new PDFDoc(str, owner_pswd, user_pswd); pContext->m_pFontList = new PdfReader::CPdfFontList(); + pContext->sPrefixForm = sPrefixForm; if (nMaxID != 0) pContext->m_nStartID = nMaxID; else if (!m_vPDFContext.empty()) @@ -603,7 +604,7 @@ bool CPdfReader::MergePages(BYTE* pData, DWORD nLength, const std::wstring& wsPa return true; } -bool CPdfReader::MergePages(const std::wstring& wsFile, const std::wstring& wsPassword, int nMaxID) +bool CPdfReader::MergePages(const std::wstring& wsFile, const std::wstring& wsPassword, int nMaxID, const std::string& sPrefixForm) { if (m_eError) return false; @@ -615,9 +616,10 @@ bool CPdfReader::MergePages(const std::wstring& wsFile, const std::wstring& wsPa CPdfReaderContext* pContext = new CPdfReaderContext(); pContext->m_pDocument = new PDFDoc((char*)sPathUtf8.c_str(), owner_pswd, user_pswd); pContext->m_pFontList = new PdfReader::CPdfFontList(); + pContext->sPrefixForm = sPrefixForm; if (nMaxID != 0) pContext->m_nStartID = nMaxID; - if (!m_vPDFContext.empty()) + 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); @@ -1131,10 +1133,11 @@ BYTE* CPdfReader::GetWidgets() NSWasm::CData oRes; oRes.SkipLen(); + std::map mForms; int nStartPage = 0; - for (CPdfReaderContext* pPDFContext : m_vPDFContext) + for (int iPDF = 0; iPDF < m_vPDFContext.size(); ++iPDF) { - PDFDoc* pDoc = pPDFContext->m_pDocument; + PDFDoc* pDoc = m_vPDFContext[iPDF]->m_pDocument; if (!pDoc || !pDoc->getCatalog()) continue; if (!pDoc->getCatalog()->getForm() || !pDoc->getXRef()) @@ -1143,9 +1146,35 @@ BYTE* CPdfReader::GetWidgets() continue; } - PdfReader::CAnnots* pAnnots = new PdfReader::CAnnots(pDoc, m_pFontManager, pPDFContext->m_pFontList, nStartPage, pPDFContext->m_nStartID); + 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]->sPrefixForm + "_" + std::to_string(nPrefix); + while (!pAnnots->ChangeFullNameAnnot(i, sPrefix)) + sPrefix = m_vPDFContext[iPDF]->sPrefixForm + "_" + std::to_string(++nPrefix); + } + } + } + pAnnots->ToWASM(oRes); + } RELEASEOBJECT(pAnnots); nStartPage += pDoc->getNumPages(); } diff --git a/PdfFile/PdfReader.h b/PdfFile/PdfReader.h index b1bb4392d3..67c6a04055 100644 --- a/PdfFile/PdfReader.h +++ b/PdfFile/PdfReader.h @@ -46,6 +46,7 @@ struct CPdfReaderContext PDFDoc* m_pDocument; PdfReader::CPdfFontList* m_pFontList; unsigned int m_nStartID; + std::string sPrefixForm; CPdfReaderContext() : m_pDocument(NULL), m_pFontList(NULL), m_nStartID(0) {} CPdfReaderContext(PDFDoc* pDocument, PdfReader::CPdfFontList* pFontList, unsigned int nStartID) : m_pDocument(pDocument), m_pFontList(pFontList), m_nStartID(nStartID) {} @@ -77,8 +78,8 @@ public: int GetMaxRefID(); int GetNumPages(); bool ValidMetaData(); - bool MergePages(BYTE* pData, DWORD nLength, const std::wstring& wsPassword = L"", int nMaxID = 0); - bool MergePages(const std::wstring& wsFile, const std::wstring& wsPassword = L"", int nMaxID = 0); + 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(); @@ -102,7 +103,7 @@ public: 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 GetFonts() { return m_mFonts; } + const std::map& GetFonts() { return m_mFonts; } private: void Clear(); diff --git a/PdfFile/SrcReader/PdfAnnot.cpp b/PdfFile/SrcReader/PdfAnnot.cpp index eb517821ed..c542067237 100644 --- a/PdfFile/SrcReader/PdfAnnot.cpp +++ b/PdfFile/SrcReader/PdfAnnot.cpp @@ -1458,6 +1458,7 @@ CAnnotWidget::CAnnotWidget(PDFDoc* pdfDoc, AcroFormField* pField, int nStartRefI oObj.free(); // 17 - Родитель - Parent + m_unRefNumParent = 0; if (oField.dictLookupNF("Parent", &oObj)->isRef()) { m_unRefNumParent = oObj.getRefNum() + nStartRefID; @@ -1467,6 +1468,7 @@ CAnnotWidget::CAnnotWidget(PDFDoc* pdfDoc, AcroFormField* pField, int nStartRefI // 18 - Частичное имя поля - T m_sT = DictLookupString(&oField, "T", 18); + m_sFullName = m_sT; // 20 - OO метаданные форм - OMetadata m_sOMetadata = DictLookupString(&oField, "OMetadata", 20); @@ -1510,8 +1512,7 @@ CAnnotWidget::CAnnotWidget(PDFDoc* pdfDoc, AcroFormField* pField, int nStartRefI } 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) { @@ -1580,6 +1581,23 @@ 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 @@ -2485,6 +2503,21 @@ CAnnots::CAnnots(PDFDoc* pdfDoc, NSFonts::IFontManager* pFontManager, CPdfFontLi 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); } } @@ -2521,6 +2554,7 @@ void CAnnots::getParents(PDFDoc* pdfDoc, Object* oFieldRef, int nStartRefID) std::string sStr = NSStringExt::CConverter::GetUtf8FromUTF32(s->getUnicode(), s->getLength()); pAnnotParent->unFlags |= (1 << 0); pAnnotParent->sT = sStr; + pAnnotParent->sFullName = sStr; delete s; } oObj.free(); @@ -2673,11 +2707,75 @@ void CAnnots::getParents(PDFDoc* pdfDoc, Object* oFieldRef, int nStartRefID) pAnnotParent->unFlags |= (1 << 4); 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 diff --git a/PdfFile/SrcReader/PdfAnnot.h b/PdfFile/SrcReader/PdfAnnot.h index 2b57ca5a95..867b623c7a 100644 --- a/PdfFile/SrcReader/PdfAnnot.h +++ b/PdfFile/SrcReader/PdfAnnot.h @@ -219,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, 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 @@ -245,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,6 +263,7 @@ class CAnnotWidgetBtn final : public CAnnotWidget { public: CAnnotWidgetBtn(PDFDoc* pdfDoc, AcroFormField* pField, int nStartRefID); + virtual std::string GetType() override { return "Btn"; } void ToWASM(NSWasm::CData& oRes) override; private: @@ -275,6 +284,7 @@ class CAnnotWidgetTx final : public CAnnotWidget { public: CAnnotWidgetTx(PDFDoc* pdfDoc, AcroFormField* pField, int nStartRefID); + virtual std::string GetType() override { return "Tx"; } void ToWASM(NSWasm::CData& oRes) override; private: @@ -287,6 +297,7 @@ class CAnnotWidgetCh final : public CAnnotWidget { public: CAnnotWidgetCh(PDFDoc* pdfDoc, AcroFormField* pField, int nStartRefID); + virtual std::string GetType() override { return "Ch"; } void ToWASM(NSWasm::CData& oRes) override; private: @@ -301,6 +312,7 @@ class CAnnotWidgetSig final : public CAnnotWidget { public: CAnnotWidgetSig(PDFDoc* pdfDoc, AcroFormField* pField, int nStartRefID); + virtual std::string GetType() override { return "Sig"; } void ToWASM(NSWasm::CData& oRes) override; }; @@ -595,6 +607,9 @@ public: ~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 @@ -605,6 +620,11 @@ private: unRefNum = 0; unRefNumParent = 0; } + ~CAnnotParent() + { + ClearActions(); + } + void ClearActions(); void ToWASM(NSWasm::CData& oRes); @@ -619,13 +639,14 @@ private: std::string sT; std::string sV; std::string sDV; + std::string sFullName; }; 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; }; //------------------------------------------------------------------------ From 809effa5df22a28a035531b26c366ec6ca7c3221 Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Tue, 15 Apr 2025 10:46:03 +0300 Subject: [PATCH 178/186] fix bug #73705 --- OOXML/PPTXFormat/Logic/CxnSp.cpp | 93 ++++++++++++++++++++++- OOXML/PPTXFormat/Logic/CxnSp.h | 99 +------------------------ OOXML/PPTXFormat/Logic/GraphicFrame.cpp | 7 +- OOXML/PPTXFormat/Logic/Pic.cpp | 4 +- OOXML/PPTXFormat/Logic/Shape.cpp | 4 +- OOXML/XML/XmlSimple.cpp | 6 ++ OOXML/XML/XmlSimple.h | 6 +- 7 files changed, 110 insertions(+), 109 deletions(-) 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/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/Pic.cpp b/OOXML/PPTXFormat/Logic/Pic.cpp index 44a231160f..bff40e7383 100644 --- a/OOXML/PPTXFormat/Logic/Pic.cpp +++ b/OOXML/PPTXFormat/Logic/Pic.cpp @@ -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); @@ -1010,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); 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/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 From c7fa85602d36c260f197c248763603f0da3bab2c Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 15 Apr 2025 14:35:49 +0300 Subject: [PATCH 179/186] Fix bugs --- .../graphics/pro/js/wasm/js/drawingfile.js | 2 +- PdfFile/PdfEditor.cpp | 4 ++-- PdfFile/PdfFile.cpp | 1 - PdfFile/PdfReader.cpp | 14 +++++++------- PdfFile/PdfReader.h | 3 +-- PdfFile/PdfWriter.cpp | 11 +++-------- PdfFile/PdfWriter.h | 4 ++-- PdfFile/SrcWriter/Streams.cpp | 2 +- 8 files changed, 17 insertions(+), 24 deletions(-) diff --git a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js index fce8234176..4f435388aa 100644 --- a/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js +++ b/DesktopEditor/graphics/pro/js/wasm/js/drawingfile.js @@ -1142,7 +1142,7 @@ function readWidgetType(reader, rec, readDoubleFunc, readDouble2Func, readString rec["value"] = readStringFunc.call(reader); if (flags & (1 << 10)) rec["maxLen"] = reader.readInt(); - if (rec["flag"] & (1 << 25)) + if (flags & (1 << 11)) rec["richValue"] = readStringFunc.call(reader); if (isRead) { diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index 26beddbcb3..a214c48cf0 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -1903,12 +1903,12 @@ BYTE* CPdfEditor::SplitPages(const int* arrPageIndex, unsigned int unLength) mFileToPages[nPDFIndex].push_back(arrPageIndex[i] - nTotalPages); else { - ++nPDFIndex; - pPDFDocument = m_pReader->GetPDFDocument(nPDFIndex); + pPDFDocument = m_pReader->GetPDFDocument(++nPDFIndex); if (!pPDFDocument) break; nTotalPages += nPages; nPages = pPDFDocument->getNumPages(); + --i; } } diff --git a/PdfFile/PdfFile.cpp b/PdfFile/PdfFile.cpp index 1d7c4940e1..b63f38e503 100644 --- a/PdfFile/PdfFile.cpp +++ b/PdfFile/PdfFile.cpp @@ -102,7 +102,6 @@ void CPdfFile::RotatePage(int nRotate) { if (!m_pInternal->pWriter) return; - // Применение поворота страницы для writer m_pInternal->pWriter->PageRotate(nRotate); } bool CPdfFile::EditPdf(const std::wstring& wsDstFile) diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index f5fe6eb7ce..a691d9f6ad 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -580,7 +580,7 @@ bool CPdfReader::MergePages(BYTE* pData, DWORD nLength, const std::wstring& wsPa CPdfReaderContext* pContext = new CPdfReaderContext(); pContext->m_pDocument = new PDFDoc(str, owner_pswd, user_pswd); pContext->m_pFontList = new PdfReader::CPdfFontList(); - pContext->sPrefixForm = sPrefixForm; + pContext->m_sPrefixForm = sPrefixForm; if (nMaxID != 0) pContext->m_nStartID = nMaxID; else if (!m_vPDFContext.empty()) @@ -616,7 +616,7 @@ bool CPdfReader::MergePages(const std::wstring& wsFile, const std::wstring& wsPa CPdfReaderContext* pContext = new CPdfReaderContext(); pContext->m_pDocument = new PDFDoc((char*)sPathUtf8.c_str(), owner_pswd, user_pswd); pContext->m_pFontList = new PdfReader::CPdfFontList(); - pContext->sPrefixForm = sPrefixForm; + pContext->m_sPrefixForm = sPrefixForm; if (nMaxID != 0) pContext->m_nStartID = nMaxID; else if (!m_vPDFContext.empty()) @@ -1133,7 +1133,7 @@ BYTE* CPdfReader::GetWidgets() NSWasm::CData oRes; oRes.SkipLen(); - std::map mForms; + std::map mForms; int nStartPage = 0; for (int iPDF = 0; iPDF < m_vPDFContext.size(); ++iPDF) { @@ -1166,9 +1166,9 @@ BYTE* CPdfReader::GetWidgets() else { int nPrefix = 0; - std::string sPrefix = m_vPDFContext[iPDF]->sPrefixForm + "_" + std::to_string(nPrefix); + std::string sPrefix = m_vPDFContext[iPDF]->m_sPrefixForm + "_" + std::to_string(nPrefix); while (!pAnnots->ChangeFullNameAnnot(i, sPrefix)) - sPrefix = m_vPDFContext[iPDF]->sPrefixForm + "_" + std::to_string(++nPrefix); + sPrefix = m_vPDFContext[iPDF]->m_sPrefixForm + "_" + std::to_string(++nPrefix); } } } @@ -1193,7 +1193,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)) { @@ -1818,7 +1818,7 @@ BYTE* CPdfReader::GetAPAnnots(int nRasterW, int nRasterH, int nBackgroundColor, continue; } - PdfReader::CAnnotAP* pAP = new PdfReader::CAnnotAP(pDoc, m_pFontManager, pFontList, nRasterW, nRasterH, nBackgroundColor, nPageIndex - 1, sView, &oAnnotRef, nStartRefID); + PdfReader::CAnnotAP* pAP = new PdfReader::CAnnotAP(pDoc, m_pFontManager, pFontList, nRasterW, nRasterH, nBackgroundColor, nPageIndex, sView, &oAnnotRef, nStartRefID); if (pAP) pAP->ToWASM(oRes); RELEASEOBJECT(pAP); diff --git a/PdfFile/PdfReader.h b/PdfFile/PdfReader.h index 67c6a04055..e02874cc50 100644 --- a/PdfFile/PdfReader.h +++ b/PdfFile/PdfReader.h @@ -46,10 +46,9 @@ struct CPdfReaderContext PDFDoc* m_pDocument; PdfReader::CPdfFontList* m_pFontList; unsigned int m_nStartID; - std::string sPrefixForm; + std::string m_sPrefixForm; CPdfReaderContext() : m_pDocument(NULL), m_pFontList(NULL), m_nStartID(0) {} - CPdfReaderContext(PDFDoc* pDocument, PdfReader::CPdfFontList* pFontList, unsigned int nStartID) : m_pDocument(pDocument), m_pFontList(pFontList), m_nStartID(nStartID) {} ~CPdfReaderContext(); }; diff --git a/PdfFile/PdfWriter.cpp b/PdfFile/PdfWriter.cpp index 4b4bb33fa9..736dd99256 100644 --- a/PdfFile/PdfWriter.cpp +++ b/PdfFile/PdfWriter.cpp @@ -2572,6 +2572,7 @@ void CPdfWriter::SetHeadings(CHeadings* pCommand) CreateOutlines(m_pDocument, pCommand->GetHeading(), NULL); } +void CPdfWriter::SetNeedAddHelvetica(bool bNeedAddHelvetica) { m_bNeedAddHelvetica = bNeedAddHelvetica; } //---------------------------------------------------------------------------------------- // Дополнительные функции Pdf рендерера //---------------------------------------------------------------------------------------- @@ -2957,14 +2958,8 @@ HRESULT CPdfWriter::EditWidgetParents(NSFonts::IApplicationFonts* pAppFonts, CWi 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()) diff --git a/PdfFile/PdfWriter.h b/PdfFile/PdfWriter.h index 445f7c63c1..98f4ba015a 100644 --- a/PdfFile/PdfWriter.h +++ b/PdfFile/PdfWriter.h @@ -210,17 +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) { m_bNeedAddHelvetica = bNeedAddHelvetica; } + void SetNeedAddHelvetica(bool bNeedAddHelvetica); private: PdfWriter::CImageDict* LoadImage(Aggplus::CImage* pImage, BYTE nAlpha); diff --git a/PdfFile/SrcWriter/Streams.cpp b/PdfFile/SrcWriter/Streams.cpp index dd4cb297df..3cf2f4da74 100644 --- a/PdfFile/SrcWriter/Streams.cpp +++ b/PdfFile/SrcWriter/Streams.cpp @@ -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); From bd7914e7c73ef97ca3a3b0ad78aeb2d6bb3785c0 Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Tue, 15 Apr 2025 14:42:26 +0300 Subject: [PATCH 180/186] fix bug #70716 --- OOXML/PPTXFormat/Logic/BgPr.cpp | 30 ++++- OOXML/PPTXFormat/Logic/EffectLst.cpp | 14 ++- OOXML/PPTXFormat/Logic/EffectLst.h | 8 -- OOXML/PPTXFormat/Logic/EffectProperties.cpp | 90 +++++++++++++++ OOXML/PPTXFormat/Logic/EffectProperties.h | 106 ++---------------- OOXML/PPTXFormat/Logic/EffectStyle.cpp | 81 ++++++++++++- OOXML/PPTXFormat/Logic/EffectStyle.h | 26 +---- OOXML/PPTXFormat/Logic/GrpSpPr.cpp | 29 +++-- OOXML/PPTXFormat/Logic/Ln.cpp | 16 ++- OOXML/PPTXFormat/Logic/RunProperties.cpp | 17 ++- OOXML/PPTXFormat/Logic/SpPr.cpp | 75 +++++++------ .../Logic/Table/TableProperties.cpp | 37 ++++-- OOXML/PPTXFormat/Theme/FmtScheme.cpp | 57 +++++----- OdfFile/Writer/Converter/ConvertDrawing.cpp | 10 +- 14 files changed, 375 insertions(+), 221 deletions(-) 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/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/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/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/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/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/Theme/FmtScheme.cpp b/OOXML/PPTXFormat/Theme/FmtScheme.cpp index 217dcaac1e..064a188278 100644 --- a/OOXML/PPTXFormat/Theme/FmtScheme.cpp +++ b/OOXML/PPTXFormat/Theme/FmtScheme.cpp @@ -58,19 +58,19 @@ namespace PPTX 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 +78,45 @@ namespace PPTX std::wstring FmtScheme::toXML() const { XmlUtils::CAttribute oAttr; - oAttr.Write(_T("name"), name); + oAttr.Write(L"name", name); 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(L"a:fmtScheme", oAttr, oValue); } void FmtScheme::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const { - pWriter->StartNode(_T("a:fmtScheme")); + pWriter->StartNode(L"a:fmtScheme"); pWriter->StartAttributes(); - pWriter->WriteAttribute2(_T("name"), name); + pWriter->WriteAttribute2(L"name", name); 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(L"a:fmtScheme"); } void FmtScheme::GetLineStyle(int number, Logic::Ln& lnStyle) const { 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()) From bd60a20b91d45473e736b6e0ca95aeb212ca1502 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 15 Apr 2025 19:52:26 +0600 Subject: [PATCH 181/186] fix bug #74037 --- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index f898cee414..a7bf7f46cb 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -2692,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()) From 4dd15a8e800b63162b9a6c87e1f83f126580d50a Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Tue, 15 Apr 2025 17:23:00 +0300 Subject: [PATCH 182/186] Add IsNeedCMap --- PdfFile/PdfReader.cpp | 3 +++ PdfFile/SrcReader/Adaptors.h | 1 + 2 files changed, 4 insertions(+) diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index a691d9f6ad..170042ee7e 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -247,6 +247,9 @@ void CPdfReader::Clear() bool CPdfReader::IsNeedCMap() { + if (!((GlobalParamsAdaptor*)globalParams)->IsNeedCMap()) + return false; + if (m_vPDFContext.empty()) return false; diff --git a/PdfFile/SrcReader/Adaptors.h b/PdfFile/SrcReader/Adaptors.h index be3894e6e1..fc61d913fa 100644 --- a/PdfFile/SrcReader/Adaptors.h +++ b/PdfFile/SrcReader/Adaptors.h @@ -84,6 +84,7 @@ 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); From 48c9a001ddb45c9f73dc8d3bbf63331677a657ca Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Wed, 16 Apr 2025 12:10:40 +0300 Subject: [PATCH 183/186] Fix button icon in AP --- PdfFile/PdfReader.cpp | 66 ++++++++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 17 deletions(-) diff --git a/PdfFile/PdfReader.cpp b/PdfFile/PdfReader.cpp index 170042ee7e..3ba5a28968 100644 --- a/PdfFile/PdfReader.cpp +++ b/PdfFile/PdfReader.cpp @@ -1378,18 +1378,60 @@ BYTE* CPdfReader::GetButtonIcon(int nBackgroundColor, int _nPageIndex, bool bBas 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; @@ -1409,25 +1451,15 @@ BYTE* CPdfReader::GetButtonIcon(int nBackgroundColor, int _nPageIndex, bool bBas 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; @@ -1618,7 +1650,7 @@ BYTE* CPdfReader::GetButtonIcon(int nBackgroundColor, int _nPageIndex, bool bBas oIm.free(); } - oMK.free(); + oMK.free(); oAP.free(); if (nMKPos > 0) oRes.AddInt(nMKLength, nMKPos); From 8871c785dd1f81c9f53f0a265c19da067ee7acd9 Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Wed, 16 Apr 2025 16:51:51 +0300 Subject: [PATCH 184/186] new odf math semantic --- OdfFile/Writer/Converter/MathConverter.cpp | 52 +++++++++---------- OdfFile/Writer/Format/math_elements.cpp | 22 +++++--- OdfFile/Writer/Format/math_elements.h | 3 +- .../Writer/Format/odf_conversion_context.cpp | 2 +- OdfFile/Writer/Format/odf_math_context.cpp | 22 ++++---- OdfFile/Writer/Format/odf_math_context.h | 8 ++- 6 files changed, 60 insertions(+), 49 deletions(-) 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; From 0979902167d716d49dd1a24798288861bb507ed5 Mon Sep 17 00:00:00 2001 From: Svetlana Kulikova Date: Fri, 18 Apr 2025 11:35:24 +0300 Subject: [PATCH 185/186] Fix bug 74090 --- PdfFile/OnlineOfficeBinToPdf.cpp | 3 ++- PdfFile/PdfEditor.cpp | 16 ++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/PdfFile/OnlineOfficeBinToPdf.cpp b/PdfFile/OnlineOfficeBinToPdf.cpp index ae93dd2330..29d1a2380e 100644 --- a/PdfFile/OnlineOfficeBinToPdf.cpp +++ b/PdfFile/OnlineOfficeBinToPdf.cpp @@ -186,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); diff --git a/PdfFile/PdfEditor.cpp b/PdfFile/PdfEditor.cpp index a214c48cf0..12022ecf12 100644 --- a/PdfFile/PdfEditor.cpp +++ b/PdfFile/PdfEditor.cpp @@ -1385,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(); @@ -1401,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(); @@ -1414,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; @@ -2153,13 +2153,13 @@ bool CPdfEditor::EditAnnot(int _nPageIndex, int 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(); From df66cbbca94d50879188e8cdd4563c024fc6b725 Mon Sep 17 00:00:00 2001 From: ElenaSubbotina Date: Fri, 18 Apr 2025 18:19:39 +0300 Subject: [PATCH 186/186] add visio theme elements --- OOXML/PPTXFormat/Logic/Runs/Run.h | 5 - OOXML/PPTXFormat/Logic/TcTxStyle.cpp | 10 +- OOXML/PPTXFormat/Logic/TextSpacing.cpp | 6 +- OOXML/PPTXFormat/Logic/UniColor.h | 4 - OOXML/PPTXFormat/Theme.cpp | 3 +- OOXML/PPTXFormat/Theme/ClrScheme.h | 4 - OOXML/PPTXFormat/Theme/ExtraClrScheme.h | 4 +- OOXML/PPTXFormat/Theme/FmtScheme.cpp | 35 +- OOXML/PPTXFormat/Theme/FmtScheme.h | 12 +- OOXML/PPTXFormat/Theme/FontScheme.h | 6 +- OOXML/PPTXFormat/Theme/ThemeElements.cpp | 208 ++- OOXML/PPTXFormat/Theme/ThemeElements.h | 12 +- OOXML/PPTXFormat/Theme/VisioThemeElements.cpp | 1179 +++++++++++++++++ OOXML/PPTXFormat/Theme/VisioThemeElements.h | 289 ++++ .../Linux/PPTXFormatLib/PPTXFormatLib.pro | 4 +- .../Windows/PPTXFormatLib/PPTXFormat.vcxproj | 2 + .../PPTXFormatLib/PPTXFormat.vcxproj.filters | 10 +- 17 files changed, 1716 insertions(+), 77 deletions(-) create mode 100644 OOXML/PPTXFormat/Theme/VisioThemeElements.cpp create mode 100644 OOXML/PPTXFormat/Theme/VisioThemeElements.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/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/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/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 064a188278..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,6 +54,8 @@ namespace PPTX } void FmtScheme::fromXML(XmlUtils::CXmlNode& node) { + nameNode = node.GetName(); + fillStyleLst.clear(); lnStyleLst.clear(); effectStyleLst.clear(); @@ -79,6 +82,7 @@ namespace PPTX { XmlUtils::CAttribute oAttr; oAttr.Write(L"name", name); + oAttr.m_strValue += xmlns_attr; XmlUtils::CNodeValue oValue; oValue.WriteArray(L"a:fillStyleLst", fillStyleLst); @@ -86,14 +90,15 @@ namespace PPTX oValue.WriteArray(L"a:effectStyleLst", effectStyleLst); oValue.WriteArray(L"a:bgFillStyleLst", bgFillStyleLst); - return XmlUtils::CreateNode(L"a:fmtScheme", oAttr, oValue); + return XmlUtils::CreateNode(nameNode, oAttr, oValue); } void FmtScheme::toXmlWriter(NSBinPptxRW::CXmlWriter* pWriter) const { - pWriter->StartNode(L"a:fmtScheme"); + pWriter->StartNode(nameNode); pWriter->StartAttributes(); pWriter->WriteAttribute2(L"name", name); + pWriter->WriteString(xmlns_attr); pWriter->EndAttributes(); pWriter->WriteArray(L"a:fillStyleLst", fillStyleLst); @@ -116,7 +121,7 @@ namespace PPTX pWriter->WriteArray(L"a:bgFillStyleLst", bgFillStyleLst); - pWriter->EndNode(L"a:fmtScheme"); + pWriter->EndNode(nameNode); } void FmtScheme::GetLineStyle(int number, Logic::Ln& lnStyle) const { @@ -358,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/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/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 +