コード例 #1
0
ファイル: BiblioDupDialog.cs プロジェクト: pxmarc/dp2
        private void toolStripButton_mergeTo_Click(object sender, EventArgs e)
        {
            // TODO: 出现合并对话框,选择保留源和目标中哪一条书目记录
            GetMergeStyleDialog merge_dlg = new GetMergeStyleDialog();

            MainForm.SetControlFont(merge_dlg, this.Font, false);
            merge_dlg.EnableSubRecord = false;
            merge_dlg.SourceRecPath   = this.OriginRecPath;
            merge_dlg.TargetRecPath   = this.SelectedRecPath;
            merge_dlg.MessageText     = "请指定源书目记录(左侧)和目标书目记录(右侧)合并的方法";

            merge_dlg.UiState = Program.MainForm.AppInfo.GetString(
                "BiblioDupDialog",
                "GetMergeStyleDialog_uiState",
                "");
            {
                MergeStyle style = merge_dlg.GetMergeStyle();
                // 去掉和 Subrecord 有关的 bit
                style = (style & (dp2Circulation.MergeStyle.ReserveSourceBiblio | dp2Circulation.MergeStyle.ReserveTargetBiblio));
                // 设置为 合并下级记录
                style |= dp2Circulation.MergeStyle.CombineSubrecord;
                merge_dlg.SetMergeStyle(style);
            }
            Program.MainForm.AppInfo.LinkFormState(merge_dlg, "entityform_GetMergeStyleDialog_state");
            merge_dlg.ShowDialog(this);
            Program.MainForm.AppInfo.SetString(
                "BiblioDupDialog",
                "GetMergeStyleDialog_uiState",
                merge_dlg.UiState);

            if (merge_dlg.DialogResult == System.Windows.Forms.DialogResult.Cancel)
            {
                return;
            }

            this.MergeStyle = merge_dlg.GetMergeStyle();

            if ((this.MergeStyle & dp2Circulation.MergeStyle.ReserveTargetBiblio) == dp2Circulation.MergeStyle.ReserveTargetBiblio)
            {
                this.Action = "mergeTo";    // useTargetBiblio
            }
            else
            {
                this.Action = "mergeToUseSourceBiblio";
            }
            this.Close();
        }
コード例 #2
0
ファイル: EntityForm.cs プロジェクト: renyh1013/dp2
        // (复制)另存书目记录为。注:包括下属的册、订购、期、评注记录和对象资源
        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);
        }
コード例 #3
0
ファイル: EntityForm.cs プロジェクト: renyh1013/dp2
        // 移动书目记录
        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);
        }