mirror of
https://github.com/xiaoqidun/ofdgo.git
synced 2026-10-29 08:46:55 +08:00
1 parent
986295ae57
commit
2cec0b17d3
9 files changed
+277
-136
No files matched your search
+44
-8
@@ -489,10 +489,21 @@
|
|||||||
<dialog id="infoPanel" class="form-dialog">
|
<dialog id="infoPanel" class="form-dialog">
|
||||||
<form id="infoForm">
|
<form id="infoForm">
|
||||||
<h2 id="infoPanelTitle" class="form-title">文档信息</h2>
|
<h2 id="infoPanelTitle" class="form-title">文档信息</h2>
|
||||||
<label class="form-row"><span>标题</span><input id="infoTitle" type="text" autofocus></label>
|
<label class="form-row"><span>标题</span><textarea id="infoTitle" rows="1" autofocus></textarea></label>
|
||||||
<label class="form-row"><span>主题</span><input id="infoSubject" type="text"></label>
|
<label class="form-row"><span>主题</span><textarea id="infoSubject" rows="1"></textarea></label>
|
||||||
<label class="form-row"><span>作者</span><input id="infoAuthor" type="text"></label>
|
<label class="form-row"><span>作者</span><textarea id="infoAuthor" rows="1"></textarea></label>
|
||||||
<details class="info-custom"><summary>扩展</summary><div id="infoCustomRows"></div><button id="infoCustomAdd" class="icon-button" type="button" title="添加字段">+</button></details>
|
<label class="form-row"><span>摘要</span><textarea id="infoAbstract" rows="2"></textarea></label>
|
||||||
|
<details><summary>关键词</summary><div id="infoKeywordRows" class="info-rows"></div><button id="infoKeywordAdd" class="icon-button" type="button" title="添加词条">+</button></details>
|
||||||
|
<details><summary>更多信息</summary>
|
||||||
|
<label class="form-row"><span>标识</span><input id="infoDocId" type="text"></label>
|
||||||
|
<label class="form-row"><span>用途</span><input id="infoDocUsage" type="text"></label>
|
||||||
|
<label class="form-row"><span>封面路径</span><input id="infoCover" type="text"></label>
|
||||||
|
<label class="form-row"><span>创建日期</span><input id="infoCreationDate" type="text"></label>
|
||||||
|
<label class="form-row"><span>修改日期</span><input id="infoModDate" type="text"></label>
|
||||||
|
<label class="form-row"><span>制作软件</span><input id="infoCreator" type="text"></label>
|
||||||
|
<label class="form-row"><span>软件版本</span><input id="infoCreatorVersion" type="text"></label>
|
||||||
|
</details>
|
||||||
|
<details><summary>自定义</summary><div id="infoCustomRows" class="info-rows"></div><button id="infoCustomAdd" class="icon-button" type="button" title="添加字段">+</button></details>
|
||||||
<div class="form-actions"><div id="infoStatus" class="form-status"></div><button id="infoCancel" class="button" type="button">取消</button><button class="button" type="submit">确定</button></div>
|
<div class="form-actions"><div id="infoStatus" class="form-status"></div><button id="infoCancel" class="button" type="button">取消</button><button class="button" type="submit">确定</button></div>
|
||||||
</form>
|
</form>
|
||||||
</dialog>
|
</dialog>
|
||||||
@@ -823,23 +834,47 @@
|
|||||||
<dd id="metaAuthor">-</dd>
|
<dd id="metaAuthor">-</dd>
|
||||||
</div>
|
</div>
|
||||||
<div hidden>
|
<div hidden>
|
||||||
<dt>创建</dt>
|
<dt>摘要</dt>
|
||||||
|
<dd id="metaAbstract"></dd>
|
||||||
|
</div>
|
||||||
|
<div hidden>
|
||||||
|
<dt>关键词</dt>
|
||||||
|
<dd id="metaKeywords"></dd>
|
||||||
|
</div>
|
||||||
|
<div hidden>
|
||||||
|
<dt>标识</dt>
|
||||||
|
<dd id="metaDocId"></dd>
|
||||||
|
</div>
|
||||||
|
<div hidden>
|
||||||
|
<dt>用途</dt>
|
||||||
|
<dd id="metaDocUsage"></dd>
|
||||||
|
</div>
|
||||||
|
<div hidden>
|
||||||
|
<dt>封面路径</dt>
|
||||||
|
<dd id="metaCover"></dd>
|
||||||
|
</div>
|
||||||
|
<div hidden>
|
||||||
|
<dt>创建日期</dt>
|
||||||
<dd id="metaCreationDate"></dd>
|
<dd id="metaCreationDate"></dd>
|
||||||
</div>
|
</div>
|
||||||
<div hidden>
|
<div hidden>
|
||||||
<dt>修改</dt>
|
<dt>修改日期</dt>
|
||||||
<dd id="metaModDate"></dd>
|
<dd id="metaModDate"></dd>
|
||||||
</div>
|
</div>
|
||||||
<div hidden>
|
<div hidden>
|
||||||
<dt>软件</dt>
|
<dt>制作软件</dt>
|
||||||
<dd id="metaCreator"></dd>
|
<dd id="metaCreator"></dd>
|
||||||
</div>
|
</div>
|
||||||
|
<div hidden>
|
||||||
|
<dt>软件版本</dt>
|
||||||
|
<dd id="metaCreatorVersion"></dd>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<dt>类型</dt>
|
<dt>类型</dt>
|
||||||
<dd id="metaType">-</dd>
|
<dd id="metaType">-</dd>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<dt>版本</dt>
|
<dt>格式版本</dt>
|
||||||
<dd id="metaVersion">-</dd>
|
<dd id="metaVersion">-</dd>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@@ -851,6 +886,7 @@
|
|||||||
<dd id="metaFonts">0</dd>
|
<dd id="metaFonts">0</dd>
|
||||||
</div>
|
</div>
|
||||||
</dl>
|
</dl>
|
||||||
|
<dl id="metaCustomData" class="meta-list" hidden></dl>
|
||||||
<details id="conversionNotice" class="conversion-notice" hidden>
|
<details id="conversionNotice" class="conversion-notice" hidden>
|
||||||
<summary>提示</summary>
|
<summary>提示</summary>
|
||||||
<div id="conversionWarnings" class="panel-detail"></div>
|
<div id="conversionWarnings" class="panel-detail"></div>
|
||||||
|
|||||||
+47
-11
@@ -1521,7 +1521,7 @@ button:not(:disabled):hover {
|
|||||||
outline-offset: 2px;
|
outline-offset: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-custom-row input,
|
.info-rows textarea,
|
||||||
.gradient-stop-row input[type="number"],
|
.gradient-stop-row input[type="number"],
|
||||||
.structure-attribute > input,
|
.structure-attribute > input,
|
||||||
.print-options select,
|
.print-options select,
|
||||||
@@ -1530,7 +1530,8 @@ button:not(:disabled):hover {
|
|||||||
.form-row input[type="number"],
|
.form-row input[type="number"],
|
||||||
.form-row input[type="file"],
|
.form-row input[type="file"],
|
||||||
.form-row select,
|
.form-row select,
|
||||||
.form-row textarea {
|
.form-row textarea,
|
||||||
|
.info-rows textarea {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
height: var(--control-height);
|
height: var(--control-height);
|
||||||
@@ -1567,19 +1568,37 @@ button:not(:disabled):hover {
|
|||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#infoCustomRows {
|
#infoPanel {
|
||||||
|
width: 480px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#infoPanel .form-row {
|
||||||
|
grid-template-columns: 4em minmax(0, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
#infoPanel .form-row > span {
|
||||||
|
text-align-last: justify;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-rows {
|
||||||
max-height: 240px;
|
max-height: 240px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.info-custom-row {
|
.info-custom-row,
|
||||||
|
.info-keyword-row {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: minmax(0, 1fr) minmax(0, 2fr) var(--control-height);
|
grid-template-columns: minmax(0, 1fr) minmax(0, 2fr) var(--control-height);
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
margin: 8px 0;
|
margin: 8px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#infoCustomRows > :first-child {
|
.info-keyword-row {
|
||||||
|
grid-template-columns: minmax(0, 1fr) var(--control-height);
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-rows > :first-child {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1618,7 +1637,7 @@ button:not(:disabled):hover {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
#infoCustomRows :focus-visible,
|
.info-rows :focus-visible,
|
||||||
#gradientStops :focus-visible {
|
#gradientStops :focus-visible {
|
||||||
outline-offset: -2px;
|
outline-offset: -2px;
|
||||||
}
|
}
|
||||||
@@ -3744,24 +3763,41 @@ audio.page-media {
|
|||||||
|
|
||||||
.meta-list {
|
.meta-list {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 12px;
|
gap: 7px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
.meta-list div {
|
.meta-list > div {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 3px;
|
grid-template-columns: 4em minmax(0, 1fr);
|
||||||
|
align-items: start;
|
||||||
|
gap: 7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.meta-list dt {
|
.meta-list dt {
|
||||||
font-size: 12px;
|
|
||||||
color: var(--text-muted);
|
color: var(--text-muted);
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
|
|
||||||
|
.meta-list:not(#metaCustomData) dt {
|
||||||
|
text-align-last: justify;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.meta-list dd {
|
.meta-list dd {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
overflow-wrap: anywhere;
|
overflow-wrap: anywhere;
|
||||||
line-height: 1.35;
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#metaCustomData:not([hidden]) {
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#metaKeywords > span {
|
||||||
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.font-panel,
|
.font-panel,
|
||||||
|
|||||||
+69
-20
@@ -15,6 +15,7 @@ const SCROLL_SEGMENT_SIZE = 1000000;
|
|||||||
const OBJECT_CLIPBOARD_TYPE = "application/x-ofdgo-objects";
|
const OBJECT_CLIPBOARD_TYPE = "application/x-ofdgo-objects";
|
||||||
const RESOURCE_KINDS = [["Font", "字体"], ["Image", "图片"], ["Audio", "音频"], ["Video", "视频"], ["Attachment", "附件"], ["ColorSpace", "色彩"], ["DrawParam", "样式"]];
|
const RESOURCE_KINDS = [["Font", "字体"], ["Image", "图片"], ["Audio", "音频"], ["Video", "视频"], ["Attachment", "附件"], ["ColorSpace", "色彩"], ["DrawParam", "样式"]];
|
||||||
const SETTINGS_KINDS = [["bookmarks", "书签"], ["actions", "动作"], ["templates", "模板"], ["layers", "图层"], ["extensions", "扩展"]];
|
const SETTINGS_KINDS = [["bookmarks", "书签"], ["actions", "动作"], ["templates", "模板"], ["layers", "图层"], ["extensions", "扩展"]];
|
||||||
|
const INFO_FIELDS = ["title", "author", "subject", "abstract", "docId", "docUsage", "cover", "creationDate", "modDate", "creator", "creatorVersion"];
|
||||||
const STATUS = {
|
const STATUS = {
|
||||||
ready: "选择 OFD、PDF 文件",
|
ready: "选择 OFD、PDF 文件",
|
||||||
opening: "正在打开文档",
|
opening: "正在打开文档",
|
||||||
@@ -346,6 +347,16 @@ const el = {
|
|||||||
infoCustomAdd: document.querySelector("#infoCustomAdd"),
|
infoCustomAdd: document.querySelector("#infoCustomAdd"),
|
||||||
infoAuthor: document.querySelector("#infoAuthor"),
|
infoAuthor: document.querySelector("#infoAuthor"),
|
||||||
infoSubject: document.querySelector("#infoSubject"),
|
infoSubject: document.querySelector("#infoSubject"),
|
||||||
|
infoAbstract: document.querySelector("#infoAbstract"),
|
||||||
|
infoDocId: document.querySelector("#infoDocId"),
|
||||||
|
infoDocUsage: document.querySelector("#infoDocUsage"),
|
||||||
|
infoCover: document.querySelector("#infoCover"),
|
||||||
|
infoCreationDate: document.querySelector("#infoCreationDate"),
|
||||||
|
infoModDate: document.querySelector("#infoModDate"),
|
||||||
|
infoCreator: document.querySelector("#infoCreator"),
|
||||||
|
infoCreatorVersion: document.querySelector("#infoCreatorVersion"),
|
||||||
|
infoKeywordRows: document.querySelector("#infoKeywordRows"),
|
||||||
|
infoKeywordAdd: document.querySelector("#infoKeywordAdd"),
|
||||||
infoCancel: document.querySelector("#infoCancel"),
|
infoCancel: document.querySelector("#infoCancel"),
|
||||||
infoStatus: document.querySelector("#infoStatus"),
|
infoStatus: document.querySelector("#infoStatus"),
|
||||||
paragraphPanel: document.querySelector("#paragraphPanel"),
|
paragraphPanel: document.querySelector("#paragraphPanel"),
|
||||||
@@ -589,10 +600,17 @@ const el = {
|
|||||||
conversionNotice: document.querySelector("#conversionNotice"),
|
conversionNotice: document.querySelector("#conversionNotice"),
|
||||||
conversionWarnings: document.querySelector("#conversionWarnings"),
|
conversionWarnings: document.querySelector("#conversionWarnings"),
|
||||||
metaSubject: document.querySelector("#metaSubject"),
|
metaSubject: document.querySelector("#metaSubject"),
|
||||||
|
metaAbstract: document.querySelector("#metaAbstract"),
|
||||||
|
metaDocId: document.querySelector("#metaDocId"),
|
||||||
|
metaDocUsage: document.querySelector("#metaDocUsage"),
|
||||||
|
metaCover: document.querySelector("#metaCover"),
|
||||||
|
metaKeywords: document.querySelector("#metaKeywords"),
|
||||||
|
metaCustomData: document.querySelector("#metaCustomData"),
|
||||||
metaAuthor: document.querySelector("#metaAuthor"),
|
metaAuthor: document.querySelector("#metaAuthor"),
|
||||||
metaCreationDate: document.querySelector("#metaCreationDate"),
|
metaCreationDate: document.querySelector("#metaCreationDate"),
|
||||||
metaModDate: document.querySelector("#metaModDate"),
|
metaModDate: document.querySelector("#metaModDate"),
|
||||||
metaCreator: document.querySelector("#metaCreator"),
|
metaCreator: document.querySelector("#metaCreator"),
|
||||||
|
metaCreatorVersion: document.querySelector("#metaCreatorVersion"),
|
||||||
metaType: document.querySelector("#metaType"),
|
metaType: document.querySelector("#metaType"),
|
||||||
metaVersion: document.querySelector("#metaVersion"),
|
metaVersion: document.querySelector("#metaVersion"),
|
||||||
metaSignatures: document.querySelector("#metaSignatures"),
|
metaSignatures: document.querySelector("#metaSignatures"),
|
||||||
@@ -1004,43 +1022,56 @@ editorClick(el.documentDownButton, () => {
|
|||||||
editorClick(el.infoButton, () => {
|
editorClick(el.infoButton, () => {
|
||||||
state.infoDocumentIndex = managedDocumentIndex();
|
state.infoDocumentIndex = managedDocumentIndex();
|
||||||
const info = state.documentManagement?.entries?.[state.infoDocumentIndex] || state.doc;
|
const info = state.documentManagement?.entries?.[state.infoDocumentIndex] || state.doc;
|
||||||
for (const key of ["Title", "Author", "Subject"]) el[`info${key}`].value = info[key.toLowerCase()] || "";
|
for (const key of INFO_FIELDS) setInfoInput(el[`info${key[0].toUpperCase()}${key.slice(1)}`], info[key] || "");
|
||||||
|
el.infoKeywordRows.replaceChildren();
|
||||||
|
for (const keyword of info.keywords || []) addInfoRow(el.infoKeywordRows, [keyword]);
|
||||||
el.infoCustomRows.replaceChildren();
|
el.infoCustomRows.replaceChildren();
|
||||||
for (const [index, field] of (info.customData || []).entries()) addCustomDataRow(field, index);
|
for (const [index, field] of (info.customData || []).entries()) addInfoRow(el.infoCustomRows, [field.Name, field.Value], index);
|
||||||
el.infoStatus.textContent = "";
|
el.infoStatus.textContent = "";
|
||||||
el.infoPanel.showModal();
|
el.infoPanel.showModal();
|
||||||
});
|
});
|
||||||
el.infoCancel.addEventListener("click", () => el.infoPanel.close());
|
el.infoCancel.addEventListener("click", () => el.infoPanel.close());
|
||||||
el.infoPanel.addEventListener("cancel", event => { if (el.infoForm.inert) event.preventDefault(); });
|
el.infoPanel.addEventListener("cancel", event => { if (el.infoForm.inert) event.preventDefault(); });
|
||||||
el.infoPanel.addEventListener("close", () => { if (!el.infoPanel.open) state.infoDocumentIndex = null; });
|
el.infoPanel.addEventListener("close", () => { if (!el.infoPanel.open) state.infoDocumentIndex = null; });
|
||||||
el.infoCustomAdd.addEventListener("click", () => addCustomDataRow());
|
el.infoKeywordAdd.addEventListener("click", () => addInfoRow(el.infoKeywordRows, [""]));
|
||||||
|
el.infoCustomAdd.addEventListener("click", () => addInfoRow(el.infoCustomRows, ["", ""]));
|
||||||
el.infoForm.addEventListener("submit", async event => {
|
el.infoForm.addEventListener("submit", async event => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const fields = [...el.infoCustomRows.children].map(row => ({Name: row.children[0].value, Value: row.children[1].value, Source: row.sourceIndex}));
|
const info = Object.fromEntries(INFO_FIELDS.map(key => [key, infoInputValue(el[`info${key[0].toUpperCase()}${key.slice(1)}`])]));
|
||||||
const args = [el.infoTitle.value, el.infoAuthor.value, el.infoSubject.value, JSON.stringify(fields)];
|
info.keywords = [...el.infoKeywordRows.children].map(row => infoInputValue(row.children[0]));
|
||||||
if (state.infoDocumentIndex !== null) args.push(state.infoDocumentIndex);
|
info.customData = [...el.infoCustomRows.children].map(row => ({Name: infoInputValue(row.children[0]), Value: infoInputValue(row.children[1]), Source: row.sourceIndex}));
|
||||||
if (await changeDocument("ofdgoUpdateInfo", null, ...args)) el.infoPanel.close();
|
if (await changeDocument("ofdgoUpdateInfo", null, JSON.stringify(info), state.infoDocumentIndex)) el.infoPanel.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
function addCustomDataRow(field = {Name: "", Value: ""}, sourceIndex) {
|
function setInfoInput(input, value) {
|
||||||
|
input.defaultValue = value;
|
||||||
|
input.value = value;
|
||||||
|
input.dataset.initialValue = input.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function infoInputValue(input) {
|
||||||
|
return input.value === input.dataset.initialValue ? input.defaultValue : input.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function addInfoRow(container, values, sourceIndex) {
|
||||||
const row = document.createElement("div");
|
const row = document.createElement("div");
|
||||||
row.sourceIndex = sourceIndex;
|
row.sourceIndex = sourceIndex;
|
||||||
row.className = "info-custom-row";
|
row.className = values.length === 1 ? "info-keyword-row" : "info-custom-row";
|
||||||
for (const [key, label] of [["Name", "名称"], ["Value", "内容"]]) {
|
for (const [index, value] of values.entries()) {
|
||||||
const input = document.createElement("input");
|
const input = document.createElement("textarea");
|
||||||
input.type = "text";
|
input.rows = 1;
|
||||||
input.value = field[key];
|
setInfoInput(input, value);
|
||||||
input.placeholder = label;
|
input.placeholder = values.length === 1 ? "关键词" : index === 0 ? "名称" : "内容";
|
||||||
row.append(input);
|
row.append(input);
|
||||||
}
|
}
|
||||||
const remove = document.createElement("button");
|
const remove = document.createElement("button");
|
||||||
remove.type = "button";
|
remove.type = "button";
|
||||||
remove.className = "icon-button";
|
remove.className = "icon-button";
|
||||||
remove.textContent = "×";
|
remove.textContent = "×";
|
||||||
remove.title = "删除字段";
|
remove.title = values.length === 1 ? "删除词条" : "删除字段";
|
||||||
remove.addEventListener("click", () => row.remove());
|
remove.addEventListener("click", () => row.remove());
|
||||||
row.append(remove);
|
row.append(remove);
|
||||||
el.infoCustomRows.append(row);
|
container.append(row);
|
||||||
}
|
}
|
||||||
el.annotationClose.addEventListener("click", () => el.annotationNote.close());
|
el.annotationClose.addEventListener("click", () => el.annotationNote.close());
|
||||||
el.annotationNote.addEventListener("close", () => { state.annotationEdit = null; });
|
el.annotationNote.addEventListener("close", () => { state.annotationEdit = null; });
|
||||||
@@ -4761,8 +4792,7 @@ async function changeDocument(name, item, ...args) {
|
|||||||
}
|
}
|
||||||
setEditorInfo(doc);
|
setEditorInfo(doc);
|
||||||
if (name === "ofdgoUpdateInfo") {
|
if (name === "ofdgoUpdateInfo") {
|
||||||
Object.assign(state.doc, { title: doc.title, author: doc.author, subject: doc.subject, customData: doc.customData,
|
for (const key of [...INFO_FIELDS, "keywords", "customData", "documents", "documentIndex"]) state.doc[key] = doc[key];
|
||||||
documents: doc.documents, documentIndex: doc.documentIndex });
|
|
||||||
renderMeta();
|
renderMeta();
|
||||||
updateControls();
|
updateControls();
|
||||||
rememberEditorView(before, revision);
|
rememberEditorView(before, revision);
|
||||||
@@ -12610,14 +12640,33 @@ function renderMeta(keepDetails = false) {
|
|||||||
el.metaTitle.textContent = doc.title || "-";
|
el.metaTitle.textContent = doc.title || "-";
|
||||||
el.metaAuthor.textContent = doc.author || "-";
|
el.metaAuthor.textContent = doc.author || "-";
|
||||||
for (const [field, value] of [
|
for (const [field, value] of [
|
||||||
[el.metaSubject, (doc.subject || "").trim()],
|
[el.metaSubject, doc.subject || ""],
|
||||||
|
[el.metaAbstract, doc.abstract || ""],
|
||||||
|
[el.metaDocId, doc.docId || ""],
|
||||||
|
[el.metaDocUsage, doc.docUsage || ""],
|
||||||
|
[el.metaCover, doc.cover || ""],
|
||||||
[el.metaCreationDate, formatDocumentTime(doc.creationDate)],
|
[el.metaCreationDate, formatDocumentTime(doc.creationDate)],
|
||||||
[el.metaModDate, formatDocumentTime(doc.modDate)],
|
[el.metaModDate, formatDocumentTime(doc.modDate)],
|
||||||
[el.metaCreator, [doc.creator, doc.creatorVersion].filter(Boolean).join(" ")],
|
[el.metaCreator, doc.creator || ""],
|
||||||
|
[el.metaCreatorVersion, doc.creatorVersion || ""],
|
||||||
]) {
|
]) {
|
||||||
field.textContent = value;
|
field.textContent = value;
|
||||||
field.parentElement.hidden = !value;
|
field.parentElement.hidden = !value;
|
||||||
}
|
}
|
||||||
|
el.metaKeywords.replaceChildren(...(doc.keywords || []).map(keyword => {
|
||||||
|
const item = document.createElement("span");
|
||||||
|
item.textContent = keyword || "-";
|
||||||
|
return item;
|
||||||
|
}));
|
||||||
|
el.metaKeywords.parentElement.hidden = !doc.keywords?.length;
|
||||||
|
el.metaCustomData.replaceChildren(...(doc.customData || []).map(field => {
|
||||||
|
const row = document.createElement("div"), name = document.createElement("dt"), value = document.createElement("dd");
|
||||||
|
name.textContent = field.Name || "-";
|
||||||
|
value.textContent = field.Value || "-";
|
||||||
|
row.append(name, value);
|
||||||
|
return row;
|
||||||
|
}));
|
||||||
|
el.metaCustomData.hidden = !doc.customData?.length;
|
||||||
el.metaType.textContent = doc.docType || "-";
|
el.metaType.textContent = doc.docType || "-";
|
||||||
el.metaVersion.textContent = doc.version || "-";
|
el.metaVersion.textContent = doc.version || "-";
|
||||||
el.metaFonts.textContent = String(doc.fontCount || 0);
|
el.metaFonts.textContent = String(doc.fontCount || 0);
|
||||||
|
|||||||
+95
-83
@@ -82,36 +82,61 @@ type pageBoxInfo struct {
|
|||||||
valid bool
|
valid bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DocumentMetadata 文档描述,供信息展示与包内文档管理共用
|
||||||
|
type DocumentMetadata struct {
|
||||||
|
DocID string `json:"docId"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Author string `json:"author"`
|
||||||
|
Subject string `json:"subject"`
|
||||||
|
Abstract string `json:"abstract"`
|
||||||
|
CreationDate string `json:"creationDate"`
|
||||||
|
ModDate string `json:"modDate"`
|
||||||
|
DocUsage string `json:"docUsage"`
|
||||||
|
Cover string `json:"cover"`
|
||||||
|
Keywords []string `json:"keywords,omitempty"`
|
||||||
|
Creator string `json:"creator"`
|
||||||
|
CreatorVersion string `json:"creatorVersion"`
|
||||||
|
CustomData []ofdgo.CustomData `json:"customData,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// documentMetadata 复制文档描述,集合字段与读取器及编辑器互不影响
|
||||||
|
// 入参: info 文档描述
|
||||||
|
// 返回: DocumentMetadata 界面元数据
|
||||||
|
func documentMetadata(info ofdgo.DocInfo) DocumentMetadata {
|
||||||
|
metadata := DocumentMetadata{
|
||||||
|
DocID: info.DocID, Title: info.Title, Author: info.Author, Subject: info.Subject, Abstract: info.Abstract,
|
||||||
|
CreationDate: info.CreationDate, ModDate: info.ModDate, DocUsage: info.DocUsage, Cover: info.Cover,
|
||||||
|
Keywords: slices.Clone(info.Keywords), Creator: info.Creator, CreatorVersion: info.CreatorVersion,
|
||||||
|
}
|
||||||
|
if info.CustomDatas != nil {
|
||||||
|
metadata.CustomData = slices.Clone(info.CustomDatas.CustomData)
|
||||||
|
}
|
||||||
|
return metadata
|
||||||
|
}
|
||||||
|
|
||||||
// DocumentInfo 文档信息
|
// DocumentInfo 文档信息
|
||||||
type DocumentInfo struct {
|
type DocumentInfo struct {
|
||||||
DocumentIndex int `json:"documentIndex"`
|
DocumentMetadata
|
||||||
DocumentVersion string `json:"documentVersion"`
|
DocumentIndex int `json:"documentIndex"`
|
||||||
VersionCount int `json:"versionCount"`
|
DocumentVersion string `json:"documentVersion"`
|
||||||
Documents []DocumentEntry `json:"documents,omitempty"`
|
VersionCount int `json:"versionCount"`
|
||||||
Encryption EncryptionInfo `json:"encryption"`
|
Documents []DocumentEntry `json:"documents,omitempty"`
|
||||||
Version string `json:"version"`
|
Encryption EncryptionInfo `json:"encryption"`
|
||||||
DocType string `json:"docType"`
|
Version string `json:"version"`
|
||||||
Title string `json:"title"`
|
DocType string `json:"docType"`
|
||||||
Author string `json:"author"`
|
PageCount int `json:"pageCount"`
|
||||||
Subject string `json:"subject"`
|
FontCount int `json:"fontCount"`
|
||||||
CustomData []ofdgo.CustomData `json:"customData,omitempty"`
|
SignatureCount int `json:"signatureCount"`
|
||||||
CreationDate string `json:"creationDate"`
|
SignatureError string `json:"signatureError,omitempty"`
|
||||||
ModDate string `json:"modDate"`
|
AttachmentError string `json:"attachmentError,omitempty"`
|
||||||
Creator string `json:"creator"`
|
Attachments []AttachmentInfo `json:"attachments,omitempty"`
|
||||||
CreatorVersion string `json:"creatorVersion,omitempty"`
|
Fonts []FontInfo `json:"fonts"`
|
||||||
PageCount int `json:"pageCount"`
|
Signatures []SignatureInfo `json:"signatures"`
|
||||||
FontCount int `json:"fontCount"`
|
Pages []PageInfo `json:"pages"`
|
||||||
SignatureCount int `json:"signatureCount"`
|
Outlines []OutlineInfo `json:"outlines,omitempty"`
|
||||||
SignatureError string `json:"signatureError,omitempty"`
|
Structures []ofdgo.Structure `json:"structures,omitempty"`
|
||||||
AttachmentError string `json:"attachmentError,omitempty"`
|
StructureError string `json:"structureError,omitempty"`
|
||||||
Attachments []AttachmentInfo `json:"attachments,omitempty"`
|
DetailsPending bool `json:"detailsPending,omitempty"`
|
||||||
Fonts []FontInfo `json:"fonts"`
|
|
||||||
Signatures []SignatureInfo `json:"signatures"`
|
|
||||||
Pages []PageInfo `json:"pages"`
|
|
||||||
Outlines []OutlineInfo `json:"outlines,omitempty"`
|
|
||||||
Structures []ofdgo.Structure `json:"structures,omitempty"`
|
|
||||||
StructureError string `json:"structureError,omitempty"`
|
|
||||||
DetailsPending bool `json:"detailsPending,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// VersionEntry 版本管理列表中的入口,空ID表示主文档
|
// VersionEntry 版本管理列表中的入口,空ID表示主文档
|
||||||
@@ -124,14 +149,11 @@ type VersionEntry struct {
|
|||||||
|
|
||||||
// DocumentEntry 包内文档入口,管理列表按需补充元数据和页数
|
// DocumentEntry 包内文档入口,管理列表按需补充元数据和页数
|
||||||
type DocumentEntry struct {
|
type DocumentEntry struct {
|
||||||
Index int `json:"index"`
|
DocumentMetadata
|
||||||
Title string `json:"title"`
|
Index int `json:"index"`
|
||||||
Root string `json:"root"`
|
Root string `json:"root"`
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Author string `json:"author,omitempty"`
|
PageCount *int `json:"pageCount,omitempty"`
|
||||||
Subject string `json:"subject,omitempty"`
|
|
||||||
CustomData []ofdgo.CustomData `json:"customData,omitempty"`
|
|
||||||
PageCount *int `json:"pageCount,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DocumentDetails 不含页面数组的文档补充信息
|
// DocumentDetails 不含页面数组的文档补充信息
|
||||||
@@ -647,19 +669,10 @@ func (s *Session) Summary() DocumentInfo {
|
|||||||
info.DocumentVersion, _ = s.Reader.DocumentVersionID()
|
info.DocumentVersion, _ = s.Reader.DocumentVersionID()
|
||||||
info.VersionCount, _ = s.Reader.DocumentVersionCount()
|
info.VersionCount, _ = s.Reader.DocumentVersionCount()
|
||||||
for index, body := range s.Reader.OFD.DocBody {
|
for index, body := range s.Reader.OFD.DocBody {
|
||||||
info.Documents = append(info.Documents, DocumentEntry{Index: index, Title: body.DocInfo.Title, Root: body.DocRoot, ID: body.DocInfo.DocID})
|
info.Documents = append(info.Documents, DocumentEntry{Index: index, DocumentMetadata: DocumentMetadata{Title: body.DocInfo.Title}, Root: body.DocRoot, ID: body.DocInfo.DocID})
|
||||||
}
|
}
|
||||||
if docInfo, err := s.Reader.DocInfo(); err == nil && docInfo != nil {
|
if docInfo, err := s.Reader.DocInfo(); err == nil && docInfo != nil {
|
||||||
info.Title = docInfo.Title
|
info.DocumentMetadata = documentMetadata(*docInfo)
|
||||||
info.Author = docInfo.Author
|
|
||||||
info.Subject = docInfo.Subject
|
|
||||||
if docInfo.CustomDatas != nil {
|
|
||||||
info.CustomData = append([]ofdgo.CustomData(nil), docInfo.CustomDatas.CustomData...)
|
|
||||||
}
|
|
||||||
info.CreationDate = docInfo.CreationDate
|
|
||||||
info.ModDate = docInfo.ModDate
|
|
||||||
info.Creator = docInfo.Creator
|
|
||||||
info.CreatorVersion = docInfo.CreatorVersion
|
|
||||||
}
|
}
|
||||||
if fonts, err := s.Reader.Fonts(); err == nil {
|
if fonts, err := s.Reader.Fonts(); err == nil {
|
||||||
for _, font := range fonts {
|
for _, font := range fonts {
|
||||||
@@ -5599,7 +5612,7 @@ func (e *businessEngine) loadImport(args []platformValue) (any, error) {
|
|||||||
entries := make([]DocumentEntry, reader.DocumentCount())
|
entries := make([]DocumentEntry, reader.DocumentCount())
|
||||||
signed := doc.Signatures != ""
|
signed := doc.Signatures != ""
|
||||||
for index, body := range reader.OFD.DocBody {
|
for index, body := range reader.OFD.DocBody {
|
||||||
entries[index] = DocumentEntry{Index: index, Title: body.DocInfo.Title, Root: body.DocRoot, ID: body.DocInfo.DocID}
|
entries[index] = DocumentEntry{Index: index, DocumentMetadata: DocumentMetadata{Title: body.DocInfo.Title}, Root: body.DocRoot, ID: body.DocInfo.DocID}
|
||||||
signed = signed || body.Signatures != ""
|
signed = signed || body.Signatures != ""
|
||||||
}
|
}
|
||||||
return map[string]any{"pageCount": len(doc.Pages.Page), "signed": doc.Signatures != "", "documentsSigned": signed, "encrypted": reader.Encryption().Encrypted, "documents": entries, "documentCount": len(entries)}, nil
|
return map[string]any{"pageCount": len(doc.Pages.Page), "signed": doc.Signatures != "", "documentsSigned": signed, "encrypted": reader.Encryption().Encrypted, "documents": entries, "documentCount": len(entries)}, nil
|
||||||
@@ -5735,50 +5748,52 @@ func (e *businessEngine) createDocument(args []platformValue) (any, error) {
|
|||||||
return e.previewEditor(editor, args[3].Bool())
|
return e.previewEditor(editor, args[3].Bool())
|
||||||
}
|
}
|
||||||
|
|
||||||
// updateInfo 修改文档信息和自定义字段,保留其他元数据及创建程序标识
|
// updateInfo 修改完整文档描述,按字段来源保留自定义内容的扩展属性
|
||||||
// 入参: args 标题、作者、主题、可选自定义字段JSON及文档索引
|
// 入参: args 文档描述JSON及文档索引,未提交字段保持原值
|
||||||
// 返回: any 编辑状态, error 错误信息
|
// 返回: any 编辑状态, error 错误信息
|
||||||
func (e *businessEngine) updateInfo(args []platformValue) (any, error) {
|
func (e *businessEngine) updateInfo(args []platformValue) (any, error) {
|
||||||
return e.changeObjects(func() error {
|
return e.changeObjects(func() error {
|
||||||
if len(args) < 3 || len(args) > 5 {
|
if len(args) != 2 {
|
||||||
return fmt.Errorf("invalid document info arguments")
|
return fmt.Errorf("invalid document info arguments")
|
||||||
}
|
}
|
||||||
index := e.currentEditor.DocumentIndex()
|
index := args[1].Int()
|
||||||
if len(args) > 4 {
|
|
||||||
index = args[4].Int()
|
|
||||||
}
|
|
||||||
info, err := e.currentEditor.DocumentInfo(index)
|
info, err := e.currentEditor.DocumentInfo(index)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
info.Title, info.Author, info.Subject = args[0].String(), args[1].String(), args[2].String()
|
var submitted struct {
|
||||||
if len(args) > 3 {
|
ofdgo.DocInfo
|
||||||
var submitted []struct {
|
CustomData []struct {
|
||||||
ofdgo.CustomData
|
ofdgo.CustomData
|
||||||
Source *int
|
Source *int
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal([]byte(args[3].String()), &submitted); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
var previous []ofdgo.CustomData
|
|
||||||
if info.CustomDatas != nil {
|
|
||||||
previous = info.CustomDatas.CustomData
|
|
||||||
}
|
|
||||||
fields := make([]ofdgo.CustomData, len(submitted))
|
|
||||||
for i, field := range submitted {
|
|
||||||
if field.Source != nil {
|
|
||||||
if *field.Source < 0 || *field.Source >= len(previous) {
|
|
||||||
return fmt.Errorf("invalid custom data source")
|
|
||||||
}
|
|
||||||
fields[i] = previous[*field.Source]
|
|
||||||
}
|
|
||||||
fields[i].Name, fields[i].Value = field.Name, field.Value
|
|
||||||
}
|
|
||||||
if !slices.Equal(previous, fields) {
|
|
||||||
info.CustomDatas = &ofdgo.CustomDatas{CustomData: fields}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return e.currentEditor.SetDocumentInfo(index, info)
|
submitted.DocInfo = info
|
||||||
|
if err := json.Unmarshal([]byte(args[0].String()), &submitted); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
var previous []ofdgo.CustomData
|
||||||
|
if info.CustomDatas != nil {
|
||||||
|
previous = info.CustomDatas.CustomData
|
||||||
|
}
|
||||||
|
fields := make([]ofdgo.CustomData, len(submitted.CustomData))
|
||||||
|
for i, field := range submitted.CustomData {
|
||||||
|
if field.Source != nil {
|
||||||
|
if *field.Source < 0 || *field.Source >= len(previous) {
|
||||||
|
return fmt.Errorf("invalid custom data source")
|
||||||
|
}
|
||||||
|
fields[i] = previous[*field.Source]
|
||||||
|
}
|
||||||
|
fields[i].Name, fields[i].Value = field.Name, field.Value
|
||||||
|
}
|
||||||
|
submitted.CustomDatas = info.CustomDatas
|
||||||
|
if submitted.CustomData != nil && !slices.Equal(previous, fields) {
|
||||||
|
submitted.CustomDatas = &ofdgo.CustomDatas{CustomData: fields}
|
||||||
|
}
|
||||||
|
if slices.Equal(info.Keywords, submitted.Keywords) {
|
||||||
|
submitted.Keywords = info.Keywords
|
||||||
|
}
|
||||||
|
return e.currentEditor.SetDocumentInfo(index, submitted.DocInfo)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5798,10 +5813,7 @@ func (e *businessEngine) packageDocuments(args []platformValue) (any, error) {
|
|||||||
entry := &entries[i]
|
entry := &entries[i]
|
||||||
body := e.currentSession.Reader.OFD.DocBody[i]
|
body := e.currentSession.Reader.OFD.DocBody[i]
|
||||||
entry.Index, entry.Root, entry.ID = i, body.DocRoot, info.DocID
|
entry.Index, entry.Root, entry.ID = i, body.DocRoot, info.DocID
|
||||||
entry.Title, entry.Author, entry.Subject = info.Title, info.Author, info.Subject
|
entry.DocumentMetadata = documentMetadata(info)
|
||||||
if info.CustomDatas != nil {
|
|
||||||
entry.CustomData = info.CustomDatas.CustomData
|
|
||||||
}
|
|
||||||
if i == e.currentEditor.DocumentIndex() {
|
if i == e.currentEditor.DocumentIndex() {
|
||||||
count := e.currentEditor.PageCount()
|
count := e.currentEditor.PageCount()
|
||||||
entry.PageCount = &count
|
entry.PageCount = &count
|
||||||
|
|||||||
@@ -415,7 +415,7 @@ func (e *Editor) editDocumentSnapshot(ctx context.Context, reader *Reader, edit
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// adoptDocumentReader 接入已加载的编辑入口,跨文档或版本时重建页面与资源状态
|
// adoptDocumentReader 接入已加载的编辑入口,同文档重建自定义字段来源,跨文档或版本时重建页面与资源状态
|
||||||
// 入参: ctx 取消上下文, reader 不拥有输入文件的独立阅读器
|
// 入参: ctx 取消上下文, reader 不拥有输入文件的独立阅读器
|
||||||
// 返回: error 编辑器初始化错误
|
// 返回: error 编辑器初始化错误
|
||||||
func (e *Editor) adoptDocumentReader(ctx context.Context, reader *Reader) error {
|
func (e *Editor) adoptDocumentReader(ctx context.Context, reader *Reader) error {
|
||||||
@@ -441,6 +441,13 @@ func (e *Editor) adoptDocumentReader(ctx context.Context, reader *Reader) error
|
|||||||
source.structureStarts[index] = starts
|
source.structureStarts[index] = starts
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
source.info.CustomDatas = cloneEditorData(reader.OFD.DocBody[reader.documentIndex].DocInfo.CustomDatas)
|
||||||
|
if source.info.CustomDatas != nil {
|
||||||
|
for i := range source.info.CustomDatas.CustomData {
|
||||||
|
source.info.CustomDatas.CustomData[i].sourceIndex = i + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
e.Info.CustomDatas = cloneEditorData(source.info.CustomDatas)
|
||||||
e.source = &source
|
e.source = &source
|
||||||
} else {
|
} else {
|
||||||
next, err := reader.EditorContext(ctx)
|
next, err := reader.EditorContext(ctx)
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ func editorUpdateInfoXML(data []byte, docID string, index int, before, after Doc
|
|||||||
{"DocID", before.DocID, after.DocID}, {"Title", before.Title, after.Title}, {"Author", before.Author, after.Author},
|
{"DocID", before.DocID, after.DocID}, {"Title", before.Title, after.Title}, {"Author", before.Author, after.Author},
|
||||||
{"Subject", before.Subject, after.Subject}, {"Abstract", before.Abstract, after.Abstract},
|
{"Subject", before.Subject, after.Subject}, {"Abstract", before.Abstract, after.Abstract},
|
||||||
{"CreationDate", before.CreationDate, after.CreationDate}, {"ModDate", before.ModDate, after.ModDate},
|
{"CreationDate", before.CreationDate, after.CreationDate}, {"ModDate", before.ModDate, after.ModDate},
|
||||||
|
{"DocUsage", before.DocUsage, after.DocUsage}, {"Cover", before.Cover, after.Cover},
|
||||||
{"Creator", before.Creator, after.Creator}, {"CreatorVersion", before.CreatorVersion, after.CreatorVersion},
|
{"Creator", before.Creator, after.Creator}, {"CreatorVersion", before.CreatorVersion, after.CreatorVersion},
|
||||||
} {
|
} {
|
||||||
if field[1] != field[2] {
|
if field[1] != field[2] {
|
||||||
@@ -138,17 +139,6 @@ func editorKeywords(data []byte, info *editorXML, values []string) ([]byte, erro
|
|||||||
return editorPatchXML(data, patches), nil
|
return editorPatchXML(data, patches), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// editorCreatorXML 更新指定文档的制作软件,移除原软件版本,保留其余根索引内容
|
|
||||||
// 入参: data 当前根索引XML, docID 缺少文档描述时使用的标识, index 文档索引
|
|
||||||
// 返回: []byte 修改后的XML, error 解析错误
|
|
||||||
func editorCreatorXML(data []byte, docID string, index int) ([]byte, error) {
|
|
||||||
data, info, err := editorDocInfoXML(data, docID, index)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return editorXMLSetText(data, info, [][2]string{{"Creator", ofdCreator}, {"CreatorVersion", ""}})
|
|
||||||
}
|
|
||||||
|
|
||||||
// editorDocInfoXML 获取文档描述,修改缺少描述的源文件时补建标准容器及标识
|
// editorDocInfoXML 获取文档描述,修改缺少描述的源文件时补建标准容器及标识
|
||||||
// 入参: data 根索引XML, docID 缺少文档描述时使用的标识, index 文档索引
|
// 入参: data 根索引XML, docID 缺少文档描述时使用的标识, index 文档索引
|
||||||
// 返回: []byte 根索引XML, *editorXML 描述节点, error 解析错误
|
// 返回: []byte 根索引XML, *editorXML 描述节点, error 解析错误
|
||||||
|
|||||||
@@ -688,7 +688,7 @@ func (e *Editor) writeSource(writer io.Writer, fonts map[string][]byte, progress
|
|||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data, err = editorCreatorXML(data, e.source.fallbackDocID, reader.documentIndex)
|
data, _, err = editorDocInfoXML(data, e.source.fallbackDocID, reader.documentIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ type DocInfo struct {
|
|||||||
Abstract string `xml:"Abstract"`
|
Abstract string `xml:"Abstract"`
|
||||||
CreationDate string `xml:"CreationDate"`
|
CreationDate string `xml:"CreationDate"`
|
||||||
ModDate string `xml:"ModDate"`
|
ModDate string `xml:"ModDate"`
|
||||||
|
DocUsage string `xml:"DocUsage"`
|
||||||
|
Cover string `xml:"Cover"`
|
||||||
Keywords Keywords `xml:"Keywords,omitempty"`
|
Keywords Keywords `xml:"Keywords,omitempty"`
|
||||||
Creator string `xml:"Creator"`
|
Creator string `xml:"Creator"`
|
||||||
CreatorVersion string `xml:"CreatorVersion"`
|
CreatorVersion string `xml:"CreatorVersion"`
|
||||||
@@ -133,6 +135,10 @@ func (info *DocInfo) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error
|
|||||||
target = &info.CreationDate
|
target = &info.CreationDate
|
||||||
case "ModDate":
|
case "ModDate":
|
||||||
target = &info.ModDate
|
target = &info.ModDate
|
||||||
|
case "DocUsage":
|
||||||
|
target = &info.DocUsage
|
||||||
|
case "Cover":
|
||||||
|
target = &info.Cover
|
||||||
case "Keywords":
|
case "Keywords":
|
||||||
target = &info.Keywords
|
target = &info.Keywords
|
||||||
case "Creator":
|
case "Creator":
|
||||||
|
|||||||
+6
-1
@@ -680,6 +680,7 @@ func (e *Editor) writePartsWithPages(ctx context.Context, write func(string, []b
|
|||||||
{"DocID", e.Info.DocID}, {"Title", e.Info.Title}, {"Author", e.Info.Author},
|
{"DocID", e.Info.DocID}, {"Title", e.Info.Title}, {"Author", e.Info.Author},
|
||||||
{"Subject", e.Info.Subject}, {"Abstract", e.Info.Abstract},
|
{"Subject", e.Info.Subject}, {"Abstract", e.Info.Abstract},
|
||||||
{"CreationDate", e.Info.CreationDate}, {"ModDate", e.Info.ModDate},
|
{"CreationDate", e.Info.CreationDate}, {"ModDate", e.Info.ModDate},
|
||||||
|
{"DocUsage", e.Info.DocUsage}, {"Cover", e.Info.Cover},
|
||||||
} {
|
} {
|
||||||
if field[1] != "" {
|
if field[1] != "" {
|
||||||
x.text(field[0], field[1])
|
x.text(field[0], field[1])
|
||||||
@@ -692,7 +693,11 @@ func (e *Editor) writePartsWithPages(ctx context.Context, write func(string, []b
|
|||||||
}
|
}
|
||||||
x.end("Keywords")
|
x.end("Keywords")
|
||||||
}
|
}
|
||||||
x.text("Creator", ofdCreator)
|
for _, field := range [][2]string{{"Creator", e.Info.Creator}, {"CreatorVersion", e.Info.CreatorVersion}} {
|
||||||
|
if field[1] != "" {
|
||||||
|
x.text(field[0], field[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
if e.Info.CustomDatas != nil && len(e.Info.CustomDatas.CustomData) != 0 {
|
if e.Info.CustomDatas != nil && len(e.Info.CustomDatas.CustomData) != 0 {
|
||||||
x.start("CustomDatas", nil)
|
x.start("CustomDatas", nil)
|
||||||
for _, item := range e.Info.CustomDatas.CustomData {
|
for _, item := range e.Info.CustomDatas.CustomData {
|
||||||
|
|||||||
Reference in new issue
Block a user