// (复制)另存书目记录为。注:包括下属的册、订购、期、评注记录和对象资源 private void toolStripButton1_marcEditor_saveTo_Click(object sender, EventArgs e) { string strError = ""; int nRet = 0; if (StringUtil.CompareVersion(this.MainForm.ServerVersion, "2.39") < 0) { strError = "本功能需要配合 dp2library 2.39 或以上版本才能使用"; goto ERROR1; } string strTargetRecPath = this.m_marcEditor.Record.Fields.GetFirstSubfield("998", "t"); if (string.IsNullOrEmpty(strTargetRecPath) == false) { DialogResult result = MessageBox.Show(this, "当前窗口内的记录原本是从 '" + strTargetRecPath + "' 复制过来的。是否要复制回原有位置?\r\n\r\nYes: 是; No: 否,继续进行普通复制操作; Cancel: 放弃本次操作", "EntityForm", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (result == System.Windows.Forms.DialogResult.Cancel) return; if (result == System.Windows.Forms.DialogResult.Yes) { // strTargetRecPath会发生作用 } if (result == System.Windows.Forms.DialogResult.No) { strTargetRecPath = ""; } } bool bSaveAs = false; // 源记录ID就是'?',追加方式。这意味着数据库中没有源记录 // 源记录就是 ? if (Global.IsAppendRecPath(this.BiblioRecPath) == true) { bSaveAs = true; } MergeStyle merge_style = MergeStyle.CombinSubrecord | MergeStyle.ReserveSourceBiblio; BiblioSaveToDlg dlg = new BiblioSaveToDlg(); MainForm.SetControlFont(dlg, this.Font, false); dlg.MainForm = this.MainForm; // dlg.RecPath = this.BiblioRecPath; if (string.IsNullOrEmpty(strTargetRecPath) == false) dlg.RecPath = strTargetRecPath; else { dlg.RecPath = this.MainForm.AppInfo.GetString( "entity_form", "save_to_used_path", this.BiblioRecPath); dlg.RecID = "?"; } if (bSaveAs == false) dlg.MessageText = "(注:本功能*可选择*是否复制书目记录下属的册、期、订购、实体记录和对象资源)\r\n\r\n将当前窗口中的书目记录 " + this.BiblioRecPath + " 复制到:"; else { dlg.Text = "保存新书目记录到特定位置"; dlg.MessageText = "注:\r\n1) 当前执行的是保存而不是复制操作(因为数据库里面还没有这条记录);\r\n2) 书目记录下属的册、期、订购、实体记录和对象资源会被一并保存"; dlg.EnableCopyChildRecords = false; } if (string.IsNullOrEmpty(strTargetRecPath) == false) dlg.BuildLink = false; else { if (bSaveAs == false) dlg.BuildLink = this.MainForm.AppInfo.GetBoolean( "entity_form", "when_save_to_build_link", true); else dlg.BuildLink = false; } if (bSaveAs == false) dlg.CopyChildRecords = this.MainForm.AppInfo.GetBoolean( "entity_form", "when_save_to_copy_child_records", false); else dlg.CopyChildRecords = true; { string strMarcSyntax = this.GetCurrentMarcSyntax(); if (string.IsNullOrEmpty(strMarcSyntax) == true) strMarcSyntax = this.MarcSyntax; // 外来数据的 MARC 格式 dlg.MarcSyntax = strMarcSyntax; } dlg.CurrentBiblioRecPath = this.BiblioRecPath; this.MainForm.AppInfo.LinkFormState(dlg, "entityform_BiblioSaveToDlg_state"); dlg.ShowDialog(this); // this.MainForm.AppInfo.UnlinkFormState(dlg); if (dlg.DialogResult != DialogResult.OK) return; if (this.BiblioRecPath == dlg.RecPath) { strError = "要保存到的位置 '" + dlg.RecPath + "' 和当前记录本来的位置 '" + this.BiblioRecPath + "' 相同,复制操作被拒绝。若确实要这样保存记录,请直接使用保存功能。"; goto ERROR1; } if (bSaveAs == false) { this.MainForm.AppInfo.SetBoolean( "entity_form", "when_save_to_build_link", dlg.BuildLink); this.MainForm.AppInfo.SetBoolean( "entity_form", "when_save_to_copy_child_records", dlg.CopyChildRecords); } this.MainForm.AppInfo.SetString( "entity_form", "save_to_used_path", dlg.RecPath); // 源记录就是 ? if (bSaveAs == true) { this.BiblioRecPath = dlg.RecPath; // 提交所有保存请求 // return: // -1 有错。此时不排除有些信息保存成功。 // 0 成功。 nRet = DoSaveAll(); if (nRet == -1) { strError = "保存操作出错"; goto ERROR1; } return; } // if (dlg.CopyChildRecords == true) { // 如果当前记录没有保存,则先保存 if (this.EntitiesChanged == true || this.IssuesChanged == true || this.BiblioChanged == true || this.ObjectChanged == true || this.OrdersChanged == true || this.CommentsChanged == true) { // 警告尚未保存 DialogResult result = MessageBox.Show(this, "当前窗口内有 " + GetCurrentChangedPartName() + " 被修改后尚未保存。复制操作前必须先保存当前记录。\r\n\r\n请问要立即保存么?", "EntityForm", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); if (result == DialogResult.OK) { // 提交所有保存请求 // return: // -1 有错。此时不排除有些信息保存成功。 // 0 成功。 nRet = DoSaveAll(); if (nRet == -1) { strError = "因为保存操作出错,所以后续的复制操作被放弃"; goto ERROR1; } } else { strError = "复制操作被放弃"; goto ERROR1; } } } // 看看要另存的位置,记录是否已经存在? // TODO: 需要改造为合并,或者覆盖。覆盖是先删除目标位置的记录。 if (dlg.RecID != "?") { byte[] timestamp = null; // 检测特定位置书目记录是否已经存在 // parameters: // return: // -1 error // 0 not found // 1 found nRet = DetectBiblioRecord(dlg.RecPath, out timestamp, out strError); if (nRet == 1) { if (dlg.RecPath != strTargetRecPath) { #if NO // 提醒覆盖? DialogResult result = MessageBox.Show(this, "书目记录 " + dlg.RecPath + " 已经存在。\r\n\r\n要用当前窗口中的书目记录覆盖此记录么? ", "EntityForm", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); if (result != DialogResult.Yes) return; #endif GetMergeStyleDialog merge_dlg = new GetMergeStyleDialog(); MainForm.SetControlFont(merge_dlg, this.Font, false); merge_dlg.SourceRecPath = this.BiblioRecPath; merge_dlg.TargetRecPath = dlg.RecPath; merge_dlg.MessageText = "目标书目记录 " + dlg.RecPath + " 已经存在。\r\n\r\n请指定当前窗口中的书目记录(源)和此目标记录合并的方法"; merge_dlg.UiState = this.MainForm.AppInfo.GetString( "entity_form", "GetMergeStyleDialog_copy_uiState", ""); merge_dlg.EnableSubRecord = dlg.CopyChildRecords; this.MainForm.AppInfo.LinkFormState(merge_dlg, "entityform_GetMergeStyleDialog_copy_state"); merge_dlg.ShowDialog(this); this.MainForm.AppInfo.UnlinkFormState(merge_dlg); this.MainForm.AppInfo.SetString( "entity_form", "GetMergeStyleDialog_copy_uiState", merge_dlg.UiState); if (merge_dlg.DialogResult == System.Windows.Forms.DialogResult.Cancel) return; merge_style = merge_dlg.GetMergeStyle(); } // this.BiblioTimestamp = timestamp; // 为了顺利覆盖 // TODO: 预先检查操作者权限,确保删除书目记录和下级记录都能成功,否则就警告 #if NO // 删除目标位置的书目记录,但保留其下属的实体等记录 nRet = DeleteBiblioRecordFromDatabase(dlg.RecPath, "onlydeletebiblio", timestamp, out strError); if (nRet == -1) goto ERROR1; #endif if ((merge_style & MergeStyle.OverwriteSubrecord) != 0) { // 删除目标记录整个,或者删除目标位置的下级记录 // TODO: 测试的时候,注意不用下述调用而测试保留目标书目记录中对象的可能性 nRet = DeleteBiblioRecordFromDatabase(dlg.RecPath, (merge_style & MergeStyle.ReserveSourceBiblio) != 0 ? "delete" : "onlydeletesubrecord", timestamp, out strError); if (nRet == -1) { if ((merge_style & MergeStyle.ReserveSourceBiblio) != 0) strError = "删除目标位置的书目记录 '" + dlg.RecPath + "' 时出错: " + strError; else strError = "删除目标位置的书目记录 '" + dlg.RecPath + "' 的全部子记录时出错: " + strError; goto ERROR1; } } } } string strOutputBiblioRecPath = ""; byte[] baOutputTimestamp = null; string strXml = ""; string strOldBiblioRecPath = this.BiblioRecPath; string strOldMarc = this.GetMarc(); // this.m_marcEditor.Marc; bool bOldChanged = this.GetMarcChanged(); // this.m_marcEditor.Changed; try { // 保存原来的记录路径 bool bOldReadOnly = this.m_marcEditor.ReadOnly; Field old_998 = null; // bool bOldChanged = this.BiblioChanged; if (dlg.BuildLink == true) { nRet = this.MainForm.CheckBuildLinkCondition( dlg.RecPath, // 即将创建/保存的记录 strOldBiblioRecPath, // 保存前的记录 false, out strError); if (nRet == -1 || nRet == 0) { // strError = "无法为记录 '" + this.BiblioRecPath + "' 建立指向 '" + strOldBiblioRecPath + "' 的目标关系:" + strError; MessageBox.Show(this, strError); } else { // 保存当前记录的998字段 old_998 = this.m_marcEditor.Record.Fields.GetOneField("998", 0); this.m_marcEditor.Record.Fields.SetFirstSubfield("998", "t", strOldBiblioRecPath); /* if (bOldReadOnly == false) this.MarcEditor.ReadOnly = true; */ } } else { // 保存当前记录的998字段 old_998 = this.m_marcEditor.Record.Fields.GetOneField("998", 0); // 清除可能存在的998$t if (old_998 != null) { SubfieldCollection subfields = old_998.Subfields; Subfield old_t = subfields["t"]; if (old_t != null) { old_998.Subfields = subfields.Remove(old_t); // 如果998内一个子字段也没有了,是否这个字段要删除? } else old_998 = null; // 表示(既然没有删除$t,就)不用恢复 } } string strMergeStyle = ""; if ((merge_style & MergeStyle.ReserveSourceBiblio) != 0) strMergeStyle = "reserve_source"; else strMergeStyle = "reserve_target"; if ((merge_style & MergeStyle.MissingSourceSubrecord) != 0) strMergeStyle += ",missing_source_subrecord"; else if ((merge_style & MergeStyle.OverwriteSubrecord) != 0) { // dp2library 尚未实现这个功能,不过本函数前面已经用 SetBiblioInfo() API 主动删除了目标位置下属的子记录,效果是一样的。(当然,这样实现起来原子性不是那么好) // strMergeStyle += ",overwrite_target_subrecord"; } if (dlg.CopyChildRecords == false) { nRet = CopyBiblio( "onlycopybiblio", dlg.RecPath, strMergeStyle, out strXml, out strOutputBiblioRecPath, out baOutputTimestamp, out strError); if (nRet == -1) MessageBox.Show(this, strError); } else { nRet = CopyBiblio( "copy", dlg.RecPath, strMergeStyle, out strXml, out strOutputBiblioRecPath, out baOutputTimestamp, out strError); if (nRet == -1) MessageBox.Show(this, strError); } } finally { #if NO // 复原当前窗口的记录 if (this.m_marcEditor.Marc != strOldMarc) this.m_marcEditor.Marc = strOldMarc; if (this.m_marcEditor.Changed != bOldChanged) this.m_marcEditor.Changed = bOldChanged; #endif if (this.GetMarc() /*this.m_marcEditor.Marc*/ != strOldMarc) { // this.m_marcEditor.Marc = strOldMarc; this.SetMarc(strOldMarc); } if (this.GetMarcChanged() /*this.m_marcEditor.Changed*/ != bOldChanged) { // this.m_marcEditor.Changed = bOldChanged; this.SetMarcChanged(bOldChanged); } } if (nRet == -1) { this.BiblioRecPath = strOldBiblioRecPath; #if NO if (old_998 != null) { // 恢复先前的998字段内容 for (int i = 0; i < this.MarcEditor.Record.Fields.Count; i++) { Field temp = this.MarcEditor.Record.Fields[i]; if (temp.Name == "998") { this.MarcEditor.Record.Fields.RemoveAt(i); i--; } } if (old_998 != null) { this.MarcEditor.Record.Fields.Insert(this.MarcEditor.Record.Fields.Count, old_998.Name, old_998.Indicator, old_998.Value); } // 恢复操作前的ReadOnly if (this.MarcEditor.ReadOnly != bOldReadOnly) this.MarcEditor.ReadOnly = bOldReadOnly; if (this.BiblioChanged != bOldChanged) this.BiblioChanged = bOldChanged; } #endif return; } // TODO: 询问是否要立即装载目标记录到当前窗口,还是装入新的一个种册窗,还是不装入? { DialogResult result = MessageBox.Show(this, "复制操作已经成功。\r\n\r\n请问是否立即将目标记录 '" + strOutputBiblioRecPath + "' 装入一个新的种册窗以便进行观察? \r\n\r\n是(Yes): 装入一个新的种册窗;\r\n否(No): 装入当前窗口;\r\n取消(Cancel): 不装入目标记录到任何窗口", "EntityForm", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (result == System.Windows.Forms.DialogResult.Yes) { EntityForm form = new EntityForm(); form.MdiParent = this.MainForm; form.MainForm = this.MainForm; form.Show(); Debug.Assert(form != null, ""); form.LoadRecordOld(strOutputBiblioRecPath, "", true); return; } if (result == System.Windows.Forms.DialogResult.Cancel) return; } // 将目标记录装入当前窗口 this.LoadRecordOld(strOutputBiblioRecPath, "", false); #if NO // 将目标记录装入当前窗口 this.BiblioTimestamp = baOutputTimestamp; this.BiblioRecPath = strOutputBiblioRecPath; string strBiblioDbName = Global.GetDbName(this.BiblioRecPath); // bool bError = false; // 装载新记录的entities部分 // 接着装入相关的所有册 string strItemDbName = this.MainForm.GetItemDbName(strBiblioDbName); if (String.IsNullOrEmpty(strItemDbName) == false) // 仅在当前书目库有对应的实体库时,才装入册记录 { this.EnableItemsPage(true); nRet = this.entityControl1.LoadEntityRecords(this.BiblioRecPath, out strError); if (nRet == -1) { MessageBox.Show(this, strError); // bError = true; } } else { this.EnableItemsPage(false); this.entityControl1.ClearEntities(); } // 接着装入相关的所有期 string strIssueDbName = this.MainForm.GetIssueDbName(strBiblioDbName); if (String.IsNullOrEmpty(strIssueDbName) == false) // 仅在当前书目库有对应的期库时,才装入期记录 { this.EnableIssuesPage(true); nRet = this.issueControl1.LoadIssueRecords(this.BiblioRecPath, out strError); if (nRet == -1) { MessageBox.Show(this, strError); // bError = true; } } else { this.EnableIssuesPage(false); this.issueControl1.ClearIssues(); } // 接着装入相关的所有订购信息 string strOrderDbName = this.MainForm.GetOrderDbName(strBiblioDbName); if (String.IsNullOrEmpty(strOrderDbName) == false) // 仅在当前书目库有对应的采购库时,才装入采购记录 { if (String.IsNullOrEmpty(strIssueDbName) == false) this.orderControl1.SeriesMode = true; else this.orderControl1.SeriesMode = false; this.EnableOrdersPage(true); nRet = this.orderControl1.LoadOrderRecords(this.BiblioRecPath, out strError); if (nRet == -1) { MessageBox.Show(this, strError); // bError = true; } } else { this.EnableOrdersPage(false); this.orderControl1.ClearOrders(); } // 接着装入相关的所有评注信息 string strCommentDbName = this.MainForm.GetCommentDbName(strBiblioDbName); if (String.IsNullOrEmpty(strCommentDbName) == false) // 仅在当前书目库有对应的评注库时,才装入评注记录 { this.EnableCommentsPage(true); nRet = this.commentControl1.LoadCommentRecords(this.BiblioRecPath, out strError); if (nRet == -1) { MessageBox.Show(this, strError); // bError = true; } } else { this.EnableCommentsPage(false); this.commentControl1.ClearComments(); } // 接着装入对象资源 if (dlg.CopyChildRecords == true) { nRet = this.binaryResControl1.LoadObject(this.BiblioRecPath, // 2008/11/2 changed strXml, out strError); if (nRet == -1) { MessageBox.Show(this, strError); // bError = true; // return -1; } } // 装载书目和<dprms:file>以外的其它XML片断 { nRet = LoadXmlFragment(strXml, out strError); if (nRet == -1) { MessageBox.Show(this, strError); } } /* // 没有对象资源 if (this.binaryResControl1 != null) { this.binaryResControl1.Clear(); } * */ // TODO: 装载HTML? Global.SetHtmlString(this.webBrowser_biblioRecord, "(空白)"); // 暂时刷新为空白 #endif return; ERROR1: MessageBox.Show(this, strError); }
// 移动书目记录 private void toolStripButton_marcEditor_moveTo_Click(object sender, EventArgs e) { string strError = ""; int nRet = 0; if (StringUtil.CompareVersion(this.MainForm.ServerVersion, "2.39") < 0) { strError = "本功能需要配合 dp2library 2.39 或以上版本才能使用"; goto ERROR1; } string strTargetRecPath = this.m_marcEditor.Record.Fields.GetFirstSubfield("998", "t"); if (string.IsNullOrEmpty(strTargetRecPath) == false) { DialogResult result = MessageBox.Show(this, "当前窗口内的记录原本是从 '" + strTargetRecPath + "' 复制过来的。是否要移动回原有位置?\r\n\r\nYes: 是; No: 否,继续进行普通移动操作; Cancel: 放弃本次操作", "EntityForm", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (result == System.Windows.Forms.DialogResult.Cancel) return; if (result == System.Windows.Forms.DialogResult.Yes) { // strTargetRecPath会发生作用 } if (result == System.Windows.Forms.DialogResult.No) { strTargetRecPath = ""; } } // 源记录就是 ? if (Global.IsAppendRecPath(this.BiblioRecPath) == true) { strError = "源记录尚未建立,无法执行移动操作"; goto ERROR1; } // string strMergeStyle = ""; MergeStyle merge_style = MergeStyle.CombinSubrecord | MergeStyle.ReserveSourceBiblio; BiblioSaveToDlg dlg = new BiblioSaveToDlg(); MainForm.SetControlFont(dlg, this.Font, false); dlg.Text = "移动书目记录到 ..."; dlg.MainForm = this.MainForm; if (string.IsNullOrEmpty(strTargetRecPath) == false) dlg.RecPath = strTargetRecPath; else { dlg.RecPath = this.MainForm.AppInfo.GetString( "entity_form", "move_to_used_path", this.BiblioRecPath); dlg.RecID = "?"; } dlg.MessageText = "将当前窗口中的书目记录 " + this.BiblioRecPath + " (连同下属的册、期、订购、实体记录和对象资源)移动到:"; dlg.CopyChildRecords = true; dlg.EnableCopyChildRecords = false; dlg.BuildLink = false; { string strMarcSyntax = this.GetCurrentMarcSyntax(); if (string.IsNullOrEmpty(strMarcSyntax) == true) strMarcSyntax = this.MarcSyntax; // 外来数据的 MARC 格式 dlg.MarcSyntax = strMarcSyntax; } // dlg.CurrentBiblioRecPath = this.BiblioRecPath; this.MainForm.AppInfo.LinkFormState(dlg, "entityform_BiblioMoveToDlg_state"); dlg.ShowDialog(this); // this.MainForm.AppInfo.UnlinkFormState(dlg); if (dlg.DialogResult != DialogResult.OK) return; if (this.BiblioRecPath == dlg.RecPath) { strError = "要移动到的位置 '" + dlg.RecPath + "' 和当前记录本来的位置 '" + this.BiblioRecPath + "' 相同,移动操作被拒绝。若确实要这样保存记录,请直接使用保存功能。"; goto ERROR1; } this.MainForm.AppInfo.SetString( "entity_form", "move_to_used_path", dlg.RecPath); // if (dlg.CopyChildRecords == true) { // 如果当前记录没有保存,则先保存 if (this.EntitiesChanged == true || this.IssuesChanged == true || this.BiblioChanged == true || this.ObjectChanged == true || this.OrdersChanged == true || this.CommentsChanged == true) { // 警告尚未保存 DialogResult result = MessageBox.Show(this, "当前窗口内有 " + GetCurrentChangedPartName() + " 被修改后尚未保存。移动操作前必须先保存当前记录。\r\n\r\n请问要立即保存么?", "EntityForm", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); if (result == DialogResult.OK) { // 提交所有保存请求 // return: // -1 有错。此时不排除有些信息保存成功。 // 0 成功。 nRet = DoSaveAll(); if (nRet == -1) { strError = "因为保存操作出错,所以后续的移动操作被放弃"; goto ERROR1; } } else { strError = "移动操作被放弃"; goto ERROR1; } } } // 看看要另存的位置,记录是否已经存在? if (dlg.RecID != "?") { byte[] timestamp = null; // 检测特定位置书目记录是否已经存在 // parameters: // return: // -1 error // 0 not found // 1 found nRet = DetectBiblioRecord(dlg.RecPath, out timestamp, out strError); if (nRet == 1) { //bool bOverwrite = false; if (dlg.RecPath != strTargetRecPath) // 移动回998$t情况就不询问是否覆盖了,直接选用归并方式 { #if NO // TODO: 用专用对话框实现 // 提醒覆盖? DialogResult result = MessageBox.Show(this, "目标书目记录 " + dlg.RecPath + " 已经存在。\r\n\r\n要用当前窗口中的书目记录(连同数字对象和下属的子记录)覆盖此记录,还是归并到此记录? \r\n\r\nYes: 覆盖; No: 归并; Cancel: 放弃本次移动操作", "EntityForm", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); if (result == DialogResult.Cancel) return; if (result == System.Windows.Forms.DialogResult.Yes) bOverwrite = true; else bOverwrite = false; #endif GetMergeStyleDialog merge_dlg = new GetMergeStyleDialog(); MainForm.SetControlFont(merge_dlg, this.Font, false); merge_dlg.SourceRecPath = this.BiblioRecPath; merge_dlg.TargetRecPath = dlg.RecPath; merge_dlg.MessageText = "目标书目记录 " + dlg.RecPath + " 已经存在。\r\n\r\n请指定当前窗口中的书目记录(源)和此目标记录合并的方法"; merge_dlg.UiState = this.MainForm.AppInfo.GetString( "entity_form", "GetMergeStyleDialog_uiState", ""); this.MainForm.AppInfo.LinkFormState(merge_dlg, "entityform_GetMergeStyleDialog_state"); merge_dlg.ShowDialog(this); this.MainForm.AppInfo.UnlinkFormState(merge_dlg); this.MainForm.AppInfo.SetString( "entity_form", "GetMergeStyleDialog_uiState", merge_dlg.UiState); if (merge_dlg.DialogResult == System.Windows.Forms.DialogResult.Cancel) return; merge_style = merge_dlg.GetMergeStyle(); } // this.BiblioTimestamp = timestamp; // 为了顺利覆盖 // TODO: 预先检查操作者权限,确保删除书目记录和下级记录都能成功,否则就警告 #if NO if (bOverwrite == true) { // 删除目标位置的书目记录 // 如果为归并模式,则保留其下属的实体等记录 nRet = DeleteBiblioRecordFromDatabase(dlg.RecPath, bOverwrite == true ? "delete" : "onlydeletebiblio", timestamp, out strError); if (nRet == -1) goto ERROR1; } #endif if ((merge_style & MergeStyle.OverwriteSubrecord) != 0) { // 删除目标记录整个,或者删除目标位置的下级记录 // TODO: 测试的时候,注意不用下述调用而测试保留目标书目记录中对象的可能性 nRet = DeleteBiblioRecordFromDatabase(dlg.RecPath, (merge_style & MergeStyle.ReserveSourceBiblio) != 0 ? "delete" : "onlydeletesubrecord", timestamp, out strError); if (nRet == -1) { if ((merge_style & MergeStyle.ReserveSourceBiblio) != 0) strError = "删除目标位置的书目记录 '" + dlg.RecPath + "' 时出错: " + strError; else strError = "删除目标位置的书目记录 '" + dlg.RecPath + "' 的全部子记录时出错: " + strError; goto ERROR1; } } } } string strOutputBiblioRecPath = ""; byte[] baOutputTimestamp = null; string strXml = ""; string strOldBiblioRecPath = this.BiblioRecPath; string strOldMarc = this.GetMarc(); // this.m_marcEditor.Marc; bool bOldChanged = this.GetMarcChanged(); // this.m_marcEditor.Changed; try { // 保存原来的记录路径 bool bOldReadOnly = this.m_marcEditor.ReadOnly; Field old_998 = null; string strDlgTargetDbName = Global.GetDbName(dlg.RecPath); string str998TargetDbName = Global.GetDbName(strTargetRecPath); // 如果移动目标和strTargetRecPath同数据库,则要去掉记录中可能存在的998$t if (strDlgTargetDbName == str998TargetDbName) { // 保存当前记录的998字段 old_998 = this.m_marcEditor.Record.Fields.GetOneField("998", 0); // 清除可能存在的998$t if (old_998 != null) { SubfieldCollection subfields = old_998.Subfields; Subfield old_t = subfields["t"]; if (old_t != null) { old_998.Subfields = subfields.Remove(old_t); // 如果998内一个子字段也没有了,是否这个字段要删除? } else old_998 = null; // 表示(既然没有删除$t,就)不用恢复 } } string strMergeStyle = ""; if ((merge_style & MergeStyle.ReserveSourceBiblio) != 0) strMergeStyle = "reserve_source"; else strMergeStyle = "reserve_target"; if ((merge_style & MergeStyle.MissingSourceSubrecord) != 0) strMergeStyle += ",missing_source_subrecord"; else if ((merge_style & MergeStyle.OverwriteSubrecord) != 0) { // dp2library 尚未实现这个功能,不过本函数前面已经用 SetBiblioInfo() API 主动删除了目标位置下属的子记录,效果是一样的。(当然,这样实现起来原子性不是那么好) // strMergeStyle += ",overwrite_target_subrecord"; } // combine 情况时缺省的,不用声明 nRet = CopyBiblio( "move", dlg.RecPath, strMergeStyle, out strXml, out strOutputBiblioRecPath, out baOutputTimestamp, out strError); if (nRet == -1) MessageBox.Show(this, strError); } finally { #if NO // 复原当前窗口的记录 if (this.m_marcEditor.Marc != strOldMarc) this.m_marcEditor.Marc = strOldMarc; if (this.m_marcEditor.Changed != bOldChanged) this.m_marcEditor.Changed = bOldChanged; #endif if (this.GetMarc() /*this.m_marcEditor.Marc*/ != strOldMarc) { // this.m_marcEditor.Marc = strOldMarc; this.SetMarc(strOldMarc); } if (this.GetMarcChanged() /*this.m_marcEditor.Changed*/ != bOldChanged) { // this.m_marcEditor.Changed = bOldChanged; this.SetMarcChanged(bOldChanged); } } if (nRet == -1) { this.BiblioRecPath = strOldBiblioRecPath; return; } // 将目标记录装入当前窗口 this.LoadRecordOld(strOutputBiblioRecPath, "", false); return; ERROR1: MessageBox.Show(this, strError); }
// 保存书目记录到数据库 // parameters: // bIncludeFileID (书目记录XML)是否要根据当前rescontrol内容合成<dprms:file>元素? // return: // -1 出错 // 0 没有保存 // 1 已经保存 /// <summary> /// 保存书目记录到数据库 /// </summary> /// <param name="channel_param">通讯通道。如果为 null,表示函数内使用自动获得的通道</param> /// <param name="bIncludeFileID">(书目记录XML)是否要根据当前对象控件内容合成<dprms:file>元素?</param> /// <param name="strHtml">返回新记录的 OPAC 格式内容</param> /// <param name="strStyle">风格。由 displaysuccess / searchdup 之一或者逗号间隔组合而成。displaysuccess 显示最后的成功消息在框架窗口的状态条; searchdup 保存成功后发送查重消息</param> /// <returns> /// <para>-1 出错</para> /// <para>0 没有保存</para> /// <para>1 已经保存</para> /// </returns> public int SaveBiblioToDatabase( LibraryChannel channel_param, bool bIncludeFileID, out string strHtml, string strStyle = "displaysuccess,searchdup") { string strError = ""; strHtml = ""; int nRet = 0; bool bDisplaySuccess = StringUtil.IsInList("displaysuccess", strStyle); bool bSearchDup = StringUtil.IsInList("searchdup", strStyle); if (this.Cataloging == false) { strError = "当前不允许编目功能,因此也不允许保存书目信息的功能"; return -1; } // 如果刚才在删除后模式,现在取消这个模式 2007/10/15 if (this.DeletedMode == true) { // TODO: 除了册信息,也要考虑期、采购信息 int nEntityCount = this.entityControl1.ItemCount; if (nEntityCount > 0) { DialogResult result = MessageBox.Show(this, "如果您用本功能将刚删除的书目记录保存回数据库,那么书目记录下属的 " + nEntityCount.ToString() + " 条实体记录将不会被保存回实体库。\r\n\r\n如果要在保存书目数据的同时也完整保存这些被删除的实体记录,请先在种册窗工具条上选择“.../使能编辑保存”功能,然后再使用“全部保存”按钮" + "\r\n\r\n是否要在不保存实体记录的情况下单独保存书目记录? (Yes 是 / No 放弃单独保存书目记录的操作)", "EntityForm", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2); if (result == DialogResult.No) { strError = "放弃保存书目记录"; goto ERROR1; } } } string strTargetPath = this.BiblioRecPath; if (string.IsNullOrEmpty(strTargetPath) == true) { // 需要询问保存的路径 BiblioSaveToDlg dlg = new BiblioSaveToDlg(); MainForm.SetControlFont(dlg, this.Font, false); dlg.MainForm = this.MainForm; dlg.Text = "仅保存书目记录"; dlg.MessageText = "请指定新书目记录要保存到的位置"; dlg.EnableCopyChildRecords = false; dlg.BuildLink = false; dlg.CopyChildRecords = false; { string strMarcSyntax = this.GetCurrentMarcSyntax(); if (string.IsNullOrEmpty(strMarcSyntax) == true) strMarcSyntax = this.MarcSyntax; // 外来数据的 MARC 格式 dlg.MarcSyntax = strMarcSyntax; } dlg.CurrentBiblioRecPath = this.BiblioRecPath; this.MainForm.AppInfo.LinkFormState(dlg, "entityform_BiblioSaveToDlg_state"); dlg.ShowDialog(this); // this.MainForm.AppInfo.UnlinkFormState(dlg); if (dlg.DialogResult != DialogResult.OK) return 0; strTargetPath = dlg.RecPath; } // 保存前的准备工作 { // 初始化 dp2circulation_marc_autogen.cs 的 Assembly,并new DetailHost对象 // return: // -1 error // 0 没有重新初始化Assembly,而是直接用以前Cache的Assembly // 1 重新(或者首次)初始化了Assembly nRet = this._genData.InitialAutogenAssembly(strTargetPath, out strError); if (nRet == -1) goto ERROR1; if (this._genData.DetailHostObj != null) { BeforeSaveRecordEventArgs e = new BeforeSaveRecordEventArgs(); // this._genData.DetailHostObj.BeforeSaveRecord(this.m_marcEditor, e); this._genData.DetailHostObj.Invoke("BeforeSaveRecord", this.m_marcEditor, e); if (string.IsNullOrEmpty(e.ErrorInfo) == false) { MessageBox.Show(this, "保存前的准备工作失败: " + e.ErrorInfo + "\r\n\r\n但保存操作仍将继续"); } } } // 获得书目记录XML格式 string strXmlBody = ""; nRet = this.GetBiblioXml( "", // 迫使从记录路径中看marc格式 bIncludeFileID, out strXmlBody, out strError); if (nRet == -1) goto ERROR1; LibraryChannel channel = channel_param; if (channel == null) channel = this.MainForm.GetChannel(); try { bool bPartialDenied = false; string strOutputPath = ""; byte[] baNewTimestamp = null; string strWarning = ""; nRet = SaveXmlBiblioRecordToDatabase( channel, strTargetPath, this.DeletedMode == true, strXmlBody, this.BiblioTimestamp, out strOutputPath, out baNewTimestamp, out strWarning, out strError); if (nRet == -1) goto ERROR1; if (string.IsNullOrEmpty(strWarning) == false) MessageBox.Show(this, strWarning); if (channel.ErrorCode == ErrorCode.PartialDenied) bPartialDenied = true; this.BiblioTimestamp = baNewTimestamp; this.BiblioRecPath = strOutputPath; this.BiblioOriginPath = strOutputPath; this.BiblioChanged = false; // 如果刚才在删除后模式,现在取消这个模式 2007/10/15 if (this.DeletedMode == true) { this.DeletedMode = false; // 重新装载实体记录,以便反映其listview变空的事实 // 接着装入相关的所有册 nRet = this.entityControl1.LoadItemRecords( channel, this.BiblioRecPath, null, // this.DisplayOtherLibraryItem, this.DisplayOtherLibraryItem == true ? "getotherlibraryitem" : "", out strError); if (nRet == -1) goto ERROR1; } // 清除ReadOnly状态,如果998$t已经消失 if (this.m_marcEditor.ReadOnly == true) { string strTargetBiblioRecPath = this.m_marcEditor.Record.Fields.GetFirstSubfield("998", "t"); if (String.IsNullOrEmpty(strTargetBiblioRecPath) == true) this.m_marcEditor.ReadOnly = false; } if (bDisplaySuccess == true) { this.MainForm.StatusBarMessage = "书目记录 '" + this.BiblioRecPath + "' 保存成功"; // MessageBox.Show(this, "书目记录保存成功。"); } if (bSearchDup == true) { if (this.AutoSearchDup == true) API.PostMessage(this.Handle, WM_SEARCH_DUP, 0, 0); } // if (bPartialDenied == true) { // 获得实际保存的书目记录 string[] results = null; string[] formats = null; if (bPartialDenied == true) { formats = new string[2]; formats[0] = "html"; formats[1] = "xml"; } else { formats = new string[1]; formats[0] = "html"; } long lRet = channel.GetBiblioInfos( Progress, strOutputPath, "", formats, out results, out baNewTimestamp, out strError); if (lRet == 0) { strError = "重新装载时,路径为 '" + strOutputPath + "' 的书目记录没有找到 ..."; goto ERROR1; } if (results == null) { strError = "重新装载书目记录时出错: result == null {6C619D72-73B0-48E0-8248-AB9348297D4F}"; goto ERROR1; } { // 重新显示 OPAC 书目信息 // TODO: 需要在对象保存完以后发出这个指令 Debug.Assert(results.Length >= 1, ""); if (results.Length > 0) { strHtml = results[0]; #if NO this.m_webExternalHost_biblio.SetHtmlString(strHtml, "entityform_biblio"); #endif } } DoViewComment(false); // 重新显示固定面板区的属性 XML 2015/7/11 if (bPartialDenied == true) { if (results.Length < 2) { strError = "重新装载书目记录时出错: result.Length[" + results.Length.ToString() + "] 小于 2"; goto ERROR1; } PartialDeniedDialog dlg = new PartialDeniedDialog(); MainForm.SetControlFont(dlg, this.Font, false); dlg.SavingXml = strXmlBody; Debug.Assert(results.Length >= 2, ""); dlg.SavedXml = results[1]; dlg.MainForm = this.MainForm; this.MainForm.AppInfo.LinkFormState(dlg, "PartialDeniedDialog_state"); dlg.ShowDialog(this); this.MainForm.AppInfo.UnlinkFormState(dlg); if (dlg.DialogResult == System.Windows.Forms.DialogResult.OK) { string strOutputBiblioRecPath = ""; string strXml = ""; string strSubRecords = ""; // 将实际保存的记录装入 MARC 编辑器 // return: // -1 error // 0 not found // 1 found nRet = LoadBiblioRecord( channel, strOutputPath, "", false, false, out strOutputBiblioRecPath, out strXml, out strSubRecords, out strError); if (nRet == -1) { strError = "重新装载书目记录时出错: " + strError; goto ERROR1; } } } } return 1; } finally { if (channel_param == null) this.MainForm.ReturnChannel(channel); } ERROR1: MessageBox.Show(this, strError); return -1; }
// 保存到其它书目库 // parameters: // bCopy 是否为复制。如果是 false,表示移动 // return: // -1 出错 // 0 放弃 // 1 成功 int CopyToAnotherDatabase( bool bCopy, out string strError) { strError = ""; // int nRet = 0; string strActionName = ""; if (bCopy) strActionName = "复制"; else strActionName = "移动"; // 选择目标库名,还有选定是否要将下属记录也保存过去 // 需要询问保存的路径 BiblioSaveToDlg dlg = new BiblioSaveToDlg(); MainForm.SetControlFont(dlg, this.Font, false); dlg.MainForm = this.MainForm; dlg.Text = strActionName + "书目记录到数据库"; dlg.MessageText = "请指定书目记录要追加" + strActionName + "到的位置"; dlg.EnableCopyChildRecords = true; dlg.BuildLink = false; if (bCopy) dlg.CopyChildRecords = false; else dlg.CopyChildRecords = true; if (bCopy) dlg.MessageText += "\r\n\r\n(注:本功能*可选择*是否复制书目记录下属的册、期、订购、实体记录和对象资源)\r\n\r\n将选定的书目记录复制到:"; else { dlg.MessageText += "\r\n\r\n注:\r\n1) 当前执行的是移动而不是复制操作;\r\n2) 书目记录下属的册、期、订购、实体记录和对象资源会被一并移动到目标位置"; dlg.EnableCopyChildRecords = false; } // TODO: 要让记录ID为问号,并且不可改动 dlg.CurrentBiblioRecPath = ""; // 源记录路径? 但是批处理情况下源记录路径并不确定阿 this.MainForm.AppInfo.LinkFormState(dlg, "BiblioSearchform_BiblioSaveToDlg_state"); dlg.ShowDialog(this); this.MainForm.AppInfo.UnlinkFormState(dlg); if (dlg.DialogResult != DialogResult.OK) return 0; if (Global.IsAppendRecPath(dlg.RecPath) == false) { strError = "目标记录路径 '" + dlg.RecPath + "' 不合法。必须是追加方式的路径,也就是说 ID 部分必须为问号"; goto ERROR1; } // TODO: 如果源和目标库名相同,要警告 string strAction = ""; if (bCopy) { if (dlg.CopyChildRecords == false) strAction = "onlycopybiblio"; else strAction = "copy"; } else { if (dlg.CopyChildRecords == false) strAction = "onlymovebiblio"; else strAction = "move"; } LibraryChannel channel = this.GetChannel(); stop.Style = StopStyle.EnableHalfStop; stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在" + strActionName + "书目记录到数据库 ..."); stop.BeginLoop(); this.EnableControlsInSearching(false); this.listView_records.Enabled = false; try { stop.SetProgressRange(0, this.listView_records.SelectedItems.Count); List<ListViewItem> moved_items = new List<ListViewItem>(); int i = 0; foreach (ListViewItem item in this.listView_records.SelectedItems) { Application.DoEvents(); // 出让界面控制权 if (stop != null && stop.State != 0) { strError = "用户中断"; goto ERROR1; } string strRecPath = ListViewUtil.GetItemText(item, 0); if (string.IsNullOrEmpty(strRecPath) == true) continue; // 观察源记录是否有998$t ? // 是否要自动创建998字段内容? string strOutputBiblioRecPath = ""; byte[] baOutputTimestamp = null; string strOutputBiblio = ""; stop.SetMessage("正在" + strActionName + "书目记录 '" + strRecPath + "' 到 '" + dlg.RecPath + "' ..."); // 2016/3/23 channel.Timeout = new TimeSpan(0, 40, 0); // 复制的时候可能需要复制对象,所需时间一般很长 REDO: // result.Value: // -1 出错 // 0 成功,没有警告信息。 // 1 成功,有警告信息。警告信息在 result.ErrorInfo 中 long lRet = channel.CopyBiblioInfo( this.stop, strAction, strRecPath, "xml", null, null, // this.BiblioTimestamp, dlg.RecPath, null, // strXml, "", out strOutputBiblio, out strOutputBiblioRecPath, out baOutputTimestamp, out strError); if (lRet == -1) { DialogResult result = MessageBox.Show(this, "复制或移动书目记录 '" + strRecPath + " --> " + dlg.RecPath + "' 时出现错误: " + strError + "。\r\n\r\n是否重试? (Yes 重试;No 跳过此条、继续后面处理;Cancel 放弃未完成的操作)", "BiblioSearchForm", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (result == System.Windows.Forms.DialogResult.Yes) goto REDO; if (result == System.Windows.Forms.DialogResult.No) goto CONTINUE; goto ERROR1; } if (bCopy == false) moved_items.Add(item); CONTINUE: stop.SetProgressValue(++i); } foreach (ListViewItem item in moved_items) { item.Remove(); } } finally { stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); stop.HideProgress(); stop.Style = StopStyle.None; this.ReturnChannel(channel); this.EnableControlsInSearching(true); this.listView_records.Enabled = true; } return 1; ERROR1: // MessageBox.Show(this, strError); return -1; }