From 129cc9aac3649882f93069f66ea9b2085a71ecf4 Mon Sep 17 00:00:00 2001 From: xietao Date: Fri, 16 Nov 2018 17:40:10 +0800 Subject: [PATCH 01/22] =?UTF-8?q?=E6=95=B4=E7=90=86=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LocationCanBorrowDialog.cs | 1 - .../FloatingMessageForm.cs | 23 +- DigitalPlatform.IO/DigitalPlatform.IO.csproj | 1 + DigitalPlatform.IO/FileUtil.cs | 19 +- DigitalPlatform.IO/TextEncodingDetect.cs | 408 +++++++++++++ DigitalPlatform.Interfaces/IFingerprint.cs | 4 + DigitalPlatform.LibraryServer/AppBiblio.cs | 4 +- .../LibraryApplication.cs | 142 ++++- DigitalPlatform.LibraryServer/MarcTable.cs | 4 +- DigitalPlatform.OPAC.Server/CacheBuilder.cs | 4 +- DigitalPlatform.OPAC.Web/TreeControl.cs | 2 +- DigitalPlatform.Script/ScriptUtil.cs | 59 +- .../DigitalPlatform.Text.csproj | 1 + DigitalPlatform.Text/ShortGuid.cs | 269 +++++++++ FingerprintCenter/App.config | 15 +- FingerprintCenter/FingerPrint.cs | 571 ++++++++++++++++-- FingerprintCenter/FingerprintCenter.csproj | 8 + FingerprintCenter/FingerprintServer.cs | 16 +- FingerprintCenter/MainForm.Designer.cs | 55 +- FingerprintCenter/MainForm.cs | 213 ++++++- FingerprintCenter/MainForm.resx | 3 - .../Properties/Settings.Designer.cs | 12 + .../Properties/Settings.settings | 3 + FingerprintCenter/packages.config | 4 + ZkFingerPrint/FingerprintServer.cs | 12 +- .../Entity/EntityEditControl.Designer.cs | 32 +- dp2Circulation/Entity/EntityEditControl.cs | 8 + dp2Circulation/FontSetting/MyForm.cs | 49 ++ .../IO/ImportExportForm.Designer.cs | 212 ++++--- dp2Circulation/IO/ImportExportForm.cs | 73 ++- .../ItemHandOver/ItemHandoverForm.cs | 22 + dp2Circulation/Label/LabelPrintForm.cs | 67 +- .../BiblioDatabaseDialog.Designer.cs | 10 +- .../ManageDatabase/BiblioDatabaseDialog.cs | 5 +- dp2Circulation/ManageDatabase/ManagerForm.cs | 122 ++-- .../ManageDatabase/ReaderDatabaseDialog.cs | 3 - dp2Circulation/Order/PrintAcceptForm.cs | 101 +++- .../ChangeEntityActionDialog.Designer.cs | 164 +++-- .../ChangeEntityActionDialog.resx | 2 +- .../QuickChangeEntityForm.cs | 5 +- dp2Circulation/Reader/AmerceForm.cs | 133 ++-- dp2Circulation/Reader/ReaderInfoForm.cs | 51 +- dp2Circulation/Reader/ReaderSearchForm.cs | 65 +- dp2Circulation/Statis/ReportForm.cs | 3 +- dp2Circulation/UserForm.cs | 30 +- dp2Circulation/dp2Circulation.csproj | 2 +- dp2Installer/dp2Installer.csproj | 4 +- dp2LibraryXE/dp2LibraryXE.csproj | 2 +- .../library_data/templates/item/browse | 3 + dp2OPAC/Browse.aspx.cs | 4 +- dp2OPAC/GetObject.aspx.cs | 4 +- dp2OPAC/ResetPassword.aspx.cs | 13 +- 52 files changed, 2478 insertions(+), 564 deletions(-) create mode 100644 DigitalPlatform.IO/TextEncodingDetect.cs create mode 100644 DigitalPlatform.Text/ShortGuid.cs create mode 100644 FingerprintCenter/packages.config diff --git a/DigitalPlatform.CirculationClient/LocationCanBorrowDialog.cs b/DigitalPlatform.CirculationClient/LocationCanBorrowDialog.cs index c2ca7e5ce..4c68ba27a 100644 --- a/DigitalPlatform.CirculationClient/LocationCanBorrowDialog.cs +++ b/DigitalPlatform.CirculationClient/LocationCanBorrowDialog.cs @@ -143,7 +143,6 @@ int FillList(string strXml, private void toolStripButton_location_new_Click(object sender, EventArgs e) { LocationItemDialog dlg = new LocationItemDialog(); - dlg.CreateMode = true; dlg.StartPosition = FormStartPosition.CenterScreen; dlg.ShowDialog(this); diff --git a/DigitalPlatform.CommonControl/FloatingMessageForm.cs b/DigitalPlatform.CommonControl/FloatingMessageForm.cs index 15aeb5e0a..d526ebaba 100644 --- a/DigitalPlatform.CommonControl/FloatingMessageForm.cs +++ b/DigitalPlatform.CommonControl/FloatingMessageForm.cs @@ -102,14 +102,21 @@ public bool Clickable } set { - this._clickable = value; + try + { + this._clickable = value; + + int windowLong = API.GetWindowLong(this.Handle, API.GWL_EXSTYLE); + if (value) + windowLong &= ~0x20; + else + windowLong |= 0x20; + API.SetWindowLong(this.Handle, API.GWL_EXSTYLE, windowLong); + } + catch(ObjectDisposedException) + { - int windowLong = API.GetWindowLong(this.Handle, API.GWL_EXSTYLE); - if (value) - windowLong &= ~0x20; - else - windowLong |= 0x20; - API.SetWindowLong(this.Handle, API.GWL_EXSTYLE, windowLong); + } } } @@ -352,7 +359,7 @@ public void SetMessage(string strText, Color rectColor, bool bClickClose) base.Text = strText; this._rectColor = rectColor; this.Closeable = bClickClose; - + this.Clickable = bClickClose; // 2018/11/6 try { if (bClickClose) diff --git a/DigitalPlatform.IO/DigitalPlatform.IO.csproj b/DigitalPlatform.IO/DigitalPlatform.IO.csproj index af08bfc4a..7c8948f09 100644 --- a/DigitalPlatform.IO/DigitalPlatform.IO.csproj +++ b/DigitalPlatform.IO/DigitalPlatform.IO.csproj @@ -174,6 +174,7 @@ + diff --git a/DigitalPlatform.IO/FileUtil.cs b/DigitalPlatform.IO/FileUtil.cs index 8e54c5686..143ba87b4 100644 --- a/DigitalPlatform.IO/FileUtil.cs +++ b/DigitalPlatform.IO/FileUtil.cs @@ -1,4 +1,5 @@ -using System; +using AutoIt.Common; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -572,6 +573,22 @@ public static Encoding DetectTextFileEncoding(string strFilename, return Encoding.GetEncoding(65006); // UTF-32 big-endian } } + + // 2018/11/6 + // 检测是不是没有 BOM 的 UTF-8 + { + byte[] temp_buffer = new byte[4096]; + file.Seek(0, SeekOrigin.Begin); + int length = file.Read(temp_buffer, 0, temp_buffer.Length); + TextEncodingDetect detector = new TextEncodingDetect(); + TextEncodingDetect.Encoding encoding = detector.DetectEncoding(temp_buffer, length); + switch(encoding) + { + case TextEncodingDetect.Encoding.Utf8Bom: + case TextEncodingDetect.Encoding.Utf8Nobom: + return Encoding.UTF8; + } + } } } catch diff --git a/DigitalPlatform.IO/TextEncodingDetect.cs b/DigitalPlatform.IO/TextEncodingDetect.cs new file mode 100644 index 000000000..7d8f4829a --- /dev/null +++ b/DigitalPlatform.IO/TextEncodingDetect.cs @@ -0,0 +1,408 @@ +// Copyright 2015-2016 Jonathan Bennett +// +// https://www.autoitscript.com +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// https://github.com/AutoItConsulting/text-encoding-detect +namespace AutoIt.Common +{ + public class TextEncodingDetect + { + private readonly byte[] _utf16BeBom = + { + 0xFE, + 0xFF + }; + + private readonly byte[] _utf16LeBom = + { + 0xFF, + 0xFE + }; + + private readonly byte[] _utf8Bom = + { + 0xEF, + 0xBB, + 0xBF + }; + + private bool _nullSuggestsBinary = true; + private double _utf16ExpectedNullPercent = 70; + private double _utf16UnexpectedNullPercent = 10; + + public enum Encoding + { + None, // Unknown or binary + Ansi, // 0-255 + Ascii, // 0-127 + Utf8Bom, // UTF8 with BOM + Utf8Nobom, // UTF8 without BOM + Utf16LeBom, // UTF16 LE with BOM + Utf16LeNoBom, // UTF16 LE without BOM + Utf16BeBom, // UTF16-BE with BOM + Utf16BeNoBom // UTF16-BE without BOM + } + + /// + /// Sets if the presence of nulls in a buffer indicate the buffer is binary data rather than text. + /// + public bool NullSuggestsBinary + { + set + { + _nullSuggestsBinary = value; + } + } + + public double Utf16ExpectedNullPercent + { + set + { + if (value > 0 && value < 100) + { + _utf16ExpectedNullPercent = value; + } + } + } + + public double Utf16UnexpectedNullPercent + { + set + { + if (value > 0 && value < 100) + { + _utf16UnexpectedNullPercent = value; + } + } + } + + /// + /// Gets the BOM length for a given Encoding mode. + /// + /// + /// The BOM length. + public static int GetBomLengthFromEncodingMode(Encoding encoding) + { + int length; + + switch (encoding) + { + case Encoding.Utf16BeBom: + case Encoding.Utf16LeBom: + length = 2; + break; + + case Encoding.Utf8Bom: + length = 3; + break; + + default: + length = 0; + break; + } + + return length; + } + + /// + /// Checks for a BOM sequence in a byte buffer. + /// + /// + /// + /// Encoding type or Encoding.None if no BOM. + public Encoding CheckBom(byte[] buffer, int size) + { + // Check for BOM + if (size >= 2 && buffer[0] == _utf16LeBom[0] && buffer[1] == _utf16LeBom[1]) + { + return Encoding.Utf16LeBom; + } + + if (size >= 2 && buffer[0] == _utf16BeBom[0] && buffer[1] == _utf16BeBom[1]) + { + return Encoding.Utf16BeBom; + } + + if (size >= 3 && buffer[0] == _utf8Bom[0] && buffer[1] == _utf8Bom[1] && buffer[2] == _utf8Bom[2]) + { + return Encoding.Utf8Bom; + } + + return Encoding.None; + } + + /// + /// Automatically detects the Encoding type of a given byte buffer. + /// + /// The byte buffer. + /// The size of the byte buffer. + /// The Encoding type or Encoding.None if unknown. + public Encoding DetectEncoding(byte[] buffer, int size) + { + // First check if we have a BOM and return that if so + Encoding encoding = CheckBom(buffer, size); + if (encoding != Encoding.None) + { + return encoding; + } + + // Now check for valid UTF8 + encoding = CheckUtf8(buffer, size); + if (encoding != Encoding.None) + { + return encoding; + } + + // Now try UTF16 + encoding = CheckUtf16NewlineChars(buffer, size); + if (encoding != Encoding.None) + { + return encoding; + } + + encoding = CheckUtf16Ascii(buffer, size); + if (encoding != Encoding.None) + { + return encoding; + } + + // ANSI or None (binary) then + if (!DoesContainNulls(buffer, size)) + { + return Encoding.Ansi; + } + + // Found a null, return based on the preference in null_suggests_binary_ + return _nullSuggestsBinary ? Encoding.None : Encoding.Ansi; + } + + /// + /// Checks if a buffer contains text that looks like utf16 by scanning for + /// newline chars that would be present even in non-english text. + /// + /// The byte buffer. + /// The size of the byte buffer. + /// Encoding.none, Encoding.Utf16LeNoBom or Encoding.Utf16BeNoBom. + private static Encoding CheckUtf16NewlineChars(byte[] buffer, int size) + { + if (size < 2) + { + return Encoding.None; + } + + // Reduce size by 1 so we don't need to worry about bounds checking for pairs of bytes + size--; + + var leControlChars = 0; + var beControlChars = 0; + + uint pos = 0; + while (pos < size) + { + byte ch1 = buffer[pos++]; + byte ch2 = buffer[pos++]; + + if (ch1 == 0) + { + if (ch2 == 0x0a || ch2 == 0x0d) + { + ++beControlChars; + } + } + else if (ch2 == 0) + { + if (ch1 == 0x0a || ch1 == 0x0d) + { + ++leControlChars; + } + } + + // If we are getting both LE and BE control chars then this file is not utf16 + if (leControlChars > 0 && beControlChars > 0) + { + return Encoding.None; + } + } + + if (leControlChars > 0) + { + return Encoding.Utf16LeNoBom; + } + + return beControlChars > 0 ? Encoding.Utf16BeNoBom : Encoding.None; + } + + /// + /// Checks if a buffer contains any nulls. Used to check for binary vs text data. + /// + /// The byte buffer. + /// The size of the byte buffer. + private static bool DoesContainNulls(byte[] buffer, int size) + { + uint pos = 0; + while (pos < size) + { + if (buffer[pos++] == 0) + { + return true; + } + } + + return false; + } + + /// + /// Checks if a buffer contains text that looks like utf16. This is done based + /// on the use of nulls which in ASCII/script like text can be useful to identify. + /// + /// The byte buffer. + /// The size of the byte buffer. + /// Encoding.none, Encoding.Utf16LeNoBom or Encoding.Utf16BeNoBom. + private Encoding CheckUtf16Ascii(byte[] buffer, int size) + { + var numOddNulls = 0; + var numEvenNulls = 0; + + // Get even nulls + uint pos = 0; + while (pos < size) + { + if (buffer[pos] == 0) + { + numEvenNulls++; + } + + pos += 2; + } + + // Get odd nulls + pos = 1; + while (pos < size) + { + if (buffer[pos] == 0) + { + numOddNulls++; + } + + pos += 2; + } + + double evenNullThreshold = numEvenNulls * 2.0 / size; + double oddNullThreshold = numOddNulls * 2.0 / size; + double expectedNullThreshold = _utf16ExpectedNullPercent / 100.0; + double unexpectedNullThreshold = _utf16UnexpectedNullPercent / 100.0; + + // Lots of odd nulls, low number of even nulls + if (evenNullThreshold < unexpectedNullThreshold && oddNullThreshold > expectedNullThreshold) + { + return Encoding.Utf16LeNoBom; + } + + // Lots of even nulls, low number of odd nulls + if (oddNullThreshold < unexpectedNullThreshold && evenNullThreshold > expectedNullThreshold) + { + return Encoding.Utf16BeNoBom; + } + + // Don't know + return Encoding.None; + } + + /// + /// Checks if a buffer contains valid utf8. + /// + /// The byte buffer. + /// The size of the byte buffer. + /// + /// Encoding type of Encoding.None (invalid UTF8), Encoding.Utf8NoBom (valid utf8 multibyte strings) or + /// Encoding.ASCII (data in 0.127 range). + /// + /// 2 + private Encoding CheckUtf8(byte[] buffer, int size) + { + // UTF8 Valid sequences + // 0xxxxxxx ASCII + // 110xxxxx 10xxxxxx 2-byte + // 1110xxxx 10xxxxxx 10xxxxxx 3-byte + // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 4-byte + // + // Width in UTF8 + // Decimal Width + // 0-127 1 byte + // 194-223 2 bytes + // 224-239 3 bytes + // 240-244 4 bytes + // + // Subsequent chars are in the range 128-191 + var onlySawAsciiRange = true; + uint pos = 0; + + while (pos < size) + { + byte ch = buffer[pos++]; + + if (ch == 0 && _nullSuggestsBinary) + { + return Encoding.None; + } + + int moreChars; + if (ch <= 127) + { + // 1 byte + moreChars = 0; + } + else if (ch >= 194 && ch <= 223) + { + // 2 Byte + moreChars = 1; + } + else if (ch >= 224 && ch <= 239) + { + // 3 Byte + moreChars = 2; + } + else if (ch >= 240 && ch <= 244) + { + // 4 Byte + moreChars = 3; + } + else + { + return Encoding.None; // Not utf8 + } + + // Check secondary chars are in range if we are expecting any + while (moreChars > 0 && pos < size) + { + onlySawAsciiRange = false; // Seen non-ascii chars now + + ch = buffer[pos++]; + if (ch < 128 || ch > 191) + { + return Encoding.None; // Not utf8 + } + + --moreChars; + } + } + + // If we get to here then only valid UTF-8 sequences have been processed + + // If we only saw chars in the range 0-127 then we can't assume UTF8 (the caller will need to decide) + return onlySawAsciiRange ? Encoding.Ascii : Encoding.Utf8Nobom; + } + } +} diff --git a/DigitalPlatform.Interfaces/IFingerprint.cs b/DigitalPlatform.Interfaces/IFingerprint.cs index 18305f220..6173061c5 100644 --- a/DigitalPlatform.Interfaces/IFingerprint.cs +++ b/DigitalPlatform.Interfaces/IFingerprint.cs @@ -14,6 +14,10 @@ public interface IFingerprint int Close(); + int GetVersion(out string strVersion, + out string strCfgInfo, + out string strError); + // 添加高速缓存事项 // 如果items == null 或者 items.Count == 0,表示要清除当前的全部缓存内容 // 如果一个item对象的FingerprintString为空,表示要删除这个缓存事项 diff --git a/DigitalPlatform.LibraryServer/AppBiblio.cs b/DigitalPlatform.LibraryServer/AppBiblio.cs index 0ef2bbffa..cab90bcdf 100644 --- a/DigitalPlatform.LibraryServer/AppBiblio.cs +++ b/DigitalPlatform.LibraryServer/AppBiblio.cs @@ -2490,9 +2490,9 @@ int MergeOldNewBiblioRec( if (string.IsNullOrEmpty(strComment) == false) strComment += "; "; if (string.IsNullOrEmpty(strAcceptedFragments) && string.IsNullOrEmpty(strRequstFragments) == false) - strComment += "创建 dprms:file (数字对象)元素被拒绝"; + strComment += "因不具备 writeobject 权限, 创建 dprms:file (数字对象)元素被拒绝"; else - strComment += "修改 dprms:file (数字对象)元素被拒绝"; + strComment += "因不具备 writeobject 权限, 修改 dprms:file (数字对象)元素被拒绝"; } } diff --git a/DigitalPlatform.LibraryServer/LibraryApplication.cs b/DigitalPlatform.LibraryServer/LibraryApplication.cs index 740c09167..fafef80a1 100644 --- a/DigitalPlatform.LibraryServer/LibraryApplication.cs +++ b/DigitalPlatform.LibraryServer/LibraryApplication.cs @@ -67,7 +67,7 @@ public static string FullVersion public DailyItemCountTable DailyItemCountTable = new DailyItemCountTable(); - internal static DateTime _expire = new DateTime(2018, 11, 15); // 上一个版本是 2018/9/15 2018/7/15 2018/5/15 2018/3/15 2017/1/15 2017/12/1 2017/9/1 2017/6/1 2017/3/1 2016/11/1 + internal static DateTime _expire = new DateTime(2019, 2, 15); // 上一个版本是 2018/11/15 2018/9/15 2018/7/15 2018/5/15 2018/3/15 2017/1/15 2017/12/1 2017/9/1 2017/6/1 2017/3/1 2016/11/1 #if NO int m_nRefCount = 0; @@ -2980,16 +2980,77 @@ public int Verify(out string strError) List errors = new List(); if (this.WsUrl == "") - errors.Add( "root/@wsurl 属性未定义"); + errors.Add("root/@wsurl 属性未定义"); if (this.ManagerUserName == "") errors.Add("root/@managerusername 属性未定义"); // 2018/10/26 // 检查 unique 元素是否多于一个 - XmlNodeList nodes = this.LibraryCfgDom.DocumentElement.SelectNodes("unique"); - if (nodes.Count > 1) - errors.Add("根元素下 unique 元素定义超过一个。请删除多余的,只保留一个即可"); + //XmlNodeList nodes = this.LibraryCfgDom.DocumentElement.SelectNodes("unique"); + //if (nodes.Count > 1) + // errors.Add("根元素下 unique 元素定义超过一个。请删除多余的,只保留一个即可"); + + // 2018/11/5 + // 检查 unique 元素是否多于一个 + // 检查 maps_856u 元素是否多于一个 + string[] unique_containers = new string[]{ + "rightsTable", + "locationTypes", + "accounts", + "browseformats", + "foregift", + "virtualDatabases", + "valueTables", + "calendars", + "traceDTLP", + "zhengyuan", + "dkyw", + "patronReplication", + "clientFineInterface", + "yczb", + "script", + "mailTemplates", + "smtpServer", + "externalMessageInterface", + "zhongcihao", + "callNumber", + "monitors", + "dup", + "unique", + "utilDb", + "libraryInfo", + "login", + "circulation", + "channel", + "cataloging", + "serverReplication", + "authdbgroup", + "maps_856u", + }; + + foreach (string element_name in unique_containers) + { + XmlNodeList nodes = this.LibraryCfgDom.DocumentElement.SelectNodes(element_name); + if (nodes.Count > 1) + errors.Add("根元素下 " + element_name + " 元素定义超过一个。请删除多余的,只保留一个即可"); + } + + // 对 maps_856u 的特殊检查 + // 序列号允许的功能如果不含有 maps856u,则 maps_856u/item@type 属性值不允许重复 + if (StringUtil.IsInList("maps856u", this.Function) == false) + { + List types = new List(); + XmlNodeList nodes = this.LibraryCfgDom.DocumentElement.SelectNodes("maps_856u/item"); + foreach (XmlElement item in nodes) + { + string type = item.GetAttribute("type"); + if (types.IndexOf(type) != -1) + errors.Add("序列号未许可 maps856u 功能的情况下,maps_856u/item@type 属性值不允许重复(出现了重复值'" + type + "')"); + + types.Add(type); + } + } if (errors.Count > 0) { @@ -9628,9 +9689,9 @@ public int ResetPassword( } else { - if (external_interface == null) + if (string.IsNullOrEmpty(this.OutgoingQueue) == true && external_interface == null) { - strError = "当前系统尚未配置短消息 (sms) 接口,无法进行重设密码的操作"; + strError = "当前系统尚未配置短消息 (sms) 接口,也没有配置 MSMQ 消息队列,无法进行重设密码的操作"; return -1; } } @@ -9669,8 +9730,6 @@ public int ResetPassword( return -1; } - List records = null; - // 获得读者记录 // return: // -2 当前没有配置任何读者库,或者可以操作的读者库 @@ -9684,7 +9743,7 @@ public int ResetPassword( strQueryWord, nMaxHitCount, "id,xml,timestamp", - out records, + out List records, out strError); if (nRet == -1 || nRet == -2) { @@ -9703,7 +9762,6 @@ public int ResetPassword( return 0; } #endif - List results = null; // 筛选读者记录 // return: @@ -9714,7 +9772,7 @@ public int ResetPassword( strNameParam, strPatronBarcodeParam, strTelParam, - out results, + out List results, out strError); if (nRet == -1) return -1; @@ -9736,14 +9794,13 @@ public int ResetPassword( foreach (KernelRecord record in results) { - string strLibraryCode = ""; // 获得读者库的馆代码 // return: // -1 出错 // 0 成功 nRet = GetLibraryCode( record.RecPath, - out strLibraryCode, + out string strLibraryCode, out strError); if (nRet == -1) return -1; @@ -9759,7 +9816,6 @@ public int ResetPassword( } // 观察 password 元素的 lastResetTime 属性,需在规定的时间长度以外才能再次进行重设 - DateTime end; #if NO // 观察在 password 元素 tempPasswordExpire 属性中残留的失效期,必须在这个时间以后才能进行本次操作 // parameters: @@ -9780,7 +9836,7 @@ public int ResetPassword( // 1 还在重试禁止期以内 nRet = CheckRetryStartTime(readerdom, DateTime.Now, - out end, + out DateTime end, out strError); if (nRet == -1) return -1; @@ -9833,6 +9889,45 @@ public int ResetPassword( ); // string strBody = "读者(证条码号) " + strBarcode + " 的帐户密码已经被重设为 " + strReaderNewPassword + ""; + if (string.IsNullOrEmpty(this.OutgoingQueue) == false) + { + // 2018/11/8 + // 通过 MSMQ 发送手机短信 + // parameters: + // strUserName 账户名,或者读者证件条码号,或者 "@refID:xxxx" + nRet = SendSms( + sessioninfo.Account == null ? "[none]" : sessioninfo.Account.UserID, + strTelParam, + strBody, + out strError); + if (nRet == -1) + { + strError = "向读者 '" + strBarcode + "' 发送 SMS 时出错: " + strError; + if (this.Statis != null) + this.Statis.IncreaseEntryValue( + strLibraryCode, + "重设密码通知", + "SMS message 重设密码通知消息发送错误数", + 1); + this.WriteErrorLog(strError); + return -1; + } + else + { + if (this.Statis != null) + this.Statis.IncreaseEntryValue( + strLibraryCode, + "重设密码通知", + "SMS message 重设密码通知消息发送数", + nRet); // 短信条数可能多于次数 + if (this.Statis != null) + this.Statis.IncreaseEntryValue(strLibraryCode, + "重设密码通知", + "SMS message 重设密码通知人数", + 1); + } + } + else // 向手机号码发送短信 { // 发送消息 @@ -9889,7 +9984,6 @@ public int ResetPassword( } } - byte[] output_timestamp = null; nRet = ChangeReaderTempPassword( sessioninfo, record.RecPath, @@ -9897,7 +9991,7 @@ public int ResetPassword( strReaderTempPassword, // strExpireTime, record.Timestamp, - out output_timestamp, + out byte[] output_timestamp, out strError); if (nRet == -1) return -1; // 此时短信已经发出,但临时密码并未修改成功 @@ -11462,7 +11556,7 @@ public static int ChangeReaderTempPassword( return 0; } -#region 实用功能 + #region 实用功能 // 通过册条码号得知从属的种记录路径 // parameters: @@ -11977,7 +12071,7 @@ public int GetBiblioRecPathByItemRecPath( return 1; } -#endregion + #endregion // 包装版本 // 检查路径中的库名,是不是实体库名 @@ -12054,7 +12148,7 @@ public int CheckRecPath(string strItemRecPath, return 0; } -#region APIs + #region APIs @@ -12607,7 +12701,7 @@ int ChangeReaderTempPassword( return -1; } -#endregion + #endregion // 展开权限字符串为原始权限定义形态 public static string ExpandRightString(string strOriginRight) @@ -15292,7 +15386,7 @@ public QuickList RightsOriginList private bool readerDomChanged = false; public bool ReaderDomChanged { get => readerDomChanged; set => readerDomChanged = value; } -#region 手机短信验证码 + #region 手机短信验证码 // 竖线间隔的手机号码列表 // return: @@ -15425,7 +15519,7 @@ public bool MatchTempPassword( return true; } -#endregion + #endregion public Account() { diff --git a/DigitalPlatform.LibraryServer/MarcTable.cs b/DigitalPlatform.LibraryServer/MarcTable.cs index 9fe38157e..541023d1c 100644 --- a/DigitalPlatform.LibraryServer/MarcTable.cs +++ b/DigitalPlatform.LibraryServer/MarcTable.cs @@ -429,7 +429,7 @@ public static int ScriptUnimarc( { string objectTable = ScriptUtil.BuildObjectXmlTable(strMARC, - StringUtil.IsInList("object_template", strStyle) ? BuildObjectHtmlTableStyle.Template : BuildObjectHtmlTableStyle.None, + StringUtil.IsInList("object_template", strStyle) ? BuildObjectHtmlTableStyle.Template | BuildObjectHtmlTableStyle.TemplateMultiHit: BuildObjectHtmlTableStyle.None, "unimarc", strRecPath, maps_container); @@ -1535,7 +1535,7 @@ public static int ScriptMarc21( if (fields.count > 0) { string strXml = ScriptUtil.BuildObjectXmlTable(strMARC, - StringUtil.IsInList("object_template", strStyle) ? BuildObjectHtmlTableStyle.Template : BuildObjectHtmlTableStyle.None, + StringUtil.IsInList("object_template", strStyle) ? BuildObjectHtmlTableStyle.Template | BuildObjectHtmlTableStyle.TemplateMultiHit: BuildObjectHtmlTableStyle.None, "usmarc", strRecPath, maps_container); diff --git a/DigitalPlatform.OPAC.Server/CacheBuilder.cs b/DigitalPlatform.OPAC.Server/CacheBuilder.cs index fd1ebbc04..f28cb423e 100644 --- a/DigitalPlatform.OPAC.Server/CacheBuilder.cs +++ b/DigitalPlatform.OPAC.Server/CacheBuilder.cs @@ -640,7 +640,7 @@ int BuildOneCache( // 2014/12/2 // 兑现宏 nRet = CacheBuilder.MacroDom(dom, - new List { "name", "date" }, + new List { "name", "command" }, out strError); if (nRet == -1) return -1; @@ -1063,7 +1063,7 @@ public static int RefreshAll(OpacApplication app, // 2014/12/2 // 兑现宏 int nRet = CacheBuilder.MacroDom(dom, - new List { "name", "date" }, + new List { "name", "command" }, out strError); if (nRet == -1) return -1; diff --git a/DigitalPlatform.OPAC.Web/TreeControl.cs b/DigitalPlatform.OPAC.Web/TreeControl.cs index dbb698465..dc810df6a 100644 --- a/DigitalPlatform.OPAC.Web/TreeControl.cs +++ b/DigitalPlatform.OPAC.Web/TreeControl.cs @@ -137,7 +137,7 @@ protected override void Render(HtmlTextWriter writer) // 2014/12/2 // 兑现宏 nRet = CacheBuilder.MacroDom(dom, - new List { "name", "date" }, + new List { "name", "command" }, out strError); if (nRet == -1) goto ERROR1; diff --git a/DigitalPlatform.Script/ScriptUtil.cs b/DigitalPlatform.Script/ScriptUtil.cs index 8880ea7d0..d0917c47f 100644 --- a/DigitalPlatform.Script/ScriptUtil.cs +++ b/DigitalPlatform.Script/ScriptUtil.cs @@ -10,6 +10,7 @@ using DigitalPlatform.Text; using DigitalPlatform.LibraryClient; using DigitalPlatform.LibraryClient.localhost; +using DigitalPlatform.Xml; namespace DigitalPlatform.Script { @@ -244,6 +245,7 @@ public enum BuildObjectHtmlTableStyle HttpUrlHitCount = 0x01, // 是否对 http:// 地址进行访问计数 FrontCover = 0x02, // 是否包含封面图像事项 Template = 0x04, // 是否利用模板机制对 $u 进行自动处理 2017/12/19 + TemplateMultiHit = 0x08, // 使用模板功能时候,是否允许多重匹配命中 item 元素。如果不允许,则命中第一个时候就停止了 } // 兼容以前的版本 @@ -334,6 +336,7 @@ public static string BuildObjectHtmlTable(string strMARC, strRecPath, maps_container, // parameters, + style, out u_list, // strUri, out string strError); //if (nRet == -1) @@ -367,25 +370,33 @@ public static string BuildObjectHtmlTable(string strMARC, string strObjectUrl = strUri; string strPdfUrl = ""; string strThumbnailUrl = ""; - if (StringUtil.IsHttpUrl(strUri) == false) + if (result.WrapUrl == true) { - // 内部对象 - strObjectUrl = "./getobject.aspx?uri=" + HttpUtility.UrlEncode(strUri) + strSaveAs; - strHitCountImage = "hitcount"; - if (s_q == "application/pdf") + if (StringUtil.IsHttpUrl(strUri) == false) { - strPdfUrl = "./viewpdf.aspx?uri=" + HttpUtility.UrlEncode(strUri); - strThumbnailUrl = "./getobject.aspx?uri=" + HttpUtility.UrlEncode(strUri + "/page:1,format=jpeg,dpi:24"); + // 内部对象 + strObjectUrl = "./getobject.aspx?uri=" + HttpUtility.UrlEncode(strUri) + strSaveAs; + strHitCountImage = "hitcount"; + if (s_q == "application/pdf") + { + strPdfUrl = "./viewpdf.aspx?uri=" + HttpUtility.UrlEncode(strUri); + strThumbnailUrl = "./getobject.aspx?uri=" + HttpUtility.UrlEncode(strUri + "/page:1,format=jpeg,dpi:24"); + } + } + else + { + // http: 或 https: 的情形,即外部 URL + if ((style & BuildObjectHtmlTableStyle.HttpUrlHitCount) != 0) + { + strObjectUrl = "./getobject.aspx?uri=" + HttpUtility.UrlEncode(strUri) + strSaveAs + "&biblioRecPath=" + HttpUtility.UrlEncode(strRecPath); + strHitCountImage = "hitcount"; + } } } else { - // http: 或 https: 的情形,即外部 URL - if ((style & BuildObjectHtmlTableStyle.HttpUrlHitCount) != 0) - { - strObjectUrl = "./getobject.aspx?uri=" + HttpUtility.UrlEncode(strUri) + strSaveAs + "&biblioRecPath=" + HttpUtility.UrlEncode(strRecPath); - strHitCountImage = "hitcount"; - } + strObjectUrl = strUri; + strHitCountImage = ""; } string linkText = ""; @@ -504,6 +515,8 @@ public class Map856uResult // 锚点文字附加部分 public string AnchorText { get; set; } + public bool WrapUrl { get; set; } + public static string MacroAnchorText(string template, string old_text) { if (template == null) @@ -528,6 +541,7 @@ public static int Map856u(string u, string strBiblioRecPath, XmlElement container, // Hashtable parameters, + BuildObjectHtmlTableStyle style, out List results, out string strError) { @@ -596,12 +610,24 @@ public static int Map856u(string u, string object_path = MakeObjectUrl(strBiblioRecPath, uri); - string result = template.Replace("{object_path}", HttpUtility.UrlEncode(object_path)); - result = result.Replace("{uri}", HttpUtility.UrlEncode(uri)); + string result = template.Replace("{encoded_object_path}", HttpUtility.UrlEncode(object_path)); + result = result.Replace("{encoded_uri}", HttpUtility.UrlEncode(uri)); + result = result.Replace("{object_path}", object_path); + result = result.Replace("{uri}", uri); result = result.Replace("{getobject_module}", "./getobject.aspx"); string anchorText = item.HasAttribute("anchorText") ? item.GetAttribute("anchorText") : null; - results.Add(new Map856uResult { Result = result, Parameters = parameters, AnchorText = anchorText }); + bool wrapUrl = DomUtil.IsBooleanTrue(item.GetAttribute("wrapUrl"), true); + results.Add(new Map856uResult + { + Result = result, + Parameters = parameters, + AnchorText = anchorText, + WrapUrl = wrapUrl + }); + + if ((style & BuildObjectHtmlTableStyle.TemplateMultiHit) == 0) + break; } return 1; @@ -749,6 +775,7 @@ public static string BuildObjectXmlTable(string strMARC, int nRet = Map856u(u, strRecPath, maps_container, + style, // parameters, out u_list, out string strError); diff --git a/DigitalPlatform.Text/DigitalPlatform.Text.csproj b/DigitalPlatform.Text/DigitalPlatform.Text.csproj index b9fb047bd..d862db473 100644 --- a/DigitalPlatform.Text/DigitalPlatform.Text.csproj +++ b/DigitalPlatform.Text/DigitalPlatform.Text.csproj @@ -169,6 +169,7 @@ + diff --git a/DigitalPlatform.Text/ShortGuid.cs b/DigitalPlatform.Text/ShortGuid.cs new file mode 100644 index 000000000..4d5ee8f1e --- /dev/null +++ b/DigitalPlatform.Text/ShortGuid.cs @@ -0,0 +1,269 @@ +using System; + +namespace DigitalPlatform.Text +{ + // https://www.singular.co.nz/2007/12/shortguid-a-shorter-and-url-friendly-guid-in-c-sharp/ + // https://stackoverflow.com/questions/9278909/net-short-unique-identifier + /// + /// Represents a globally unique identifier (GUID) with a + /// shorter string value. Sguid + /// + public struct ShortGuid + { + #region Static + + /// + /// A read-only instance of the ShortGuid class whose value + /// is guaranteed to be all zeroes. + /// + public static readonly ShortGuid Empty = new ShortGuid(Guid.Empty); + + #endregion + + #region Fields + + Guid _guid; + string _value; + + #endregion + + #region Contructors + + /// + /// Creates a ShortGuid from a base64 encoded string + /// + /// The encoded guid as a + /// base64 string + public ShortGuid(string value) + { + _value = value; + _guid = Decode(value); + } + + /// + /// Creates a ShortGuid from a Guid + /// + /// The Guid to encode + public ShortGuid(Guid guid) + { + _value = Encode(guid); + _guid = guid; + } + + #endregion + + #region Properties + + /// + /// Gets/sets the underlying Guid + /// + public Guid Guid + { + get { return _guid; } + set + { + if (value != _guid) + { + _guid = value; + _value = Encode(value); + } + } + } + + /// + /// Gets/sets the underlying base64 encoded string + /// + public string Value + { + get { return _value; } + set + { + if (value != _value) + { + _value = value; + _guid = Decode(value); + } + } + } + + #endregion + + #region ToString + + /// + /// Returns the base64 encoded guid as a string + /// + /// + public override string ToString() + { + return _value; + } + + #endregion + + #region Equals + + /// + /// Returns a value indicating whether this instance and a + /// specified Object represent the same type and value. + /// + /// The object to compare + /// + public override bool Equals(object obj) + { + if (obj is ShortGuid) + return _guid.Equals(((ShortGuid)obj)._guid); + if (obj is Guid) + return _guid.Equals((Guid)obj); + if (obj is string) + return _guid.Equals(((ShortGuid)obj)._guid); + return false; + } + + #endregion + + #region GetHashCode + + /// + /// Returns the HashCode for underlying Guid. + /// + /// + public override int GetHashCode() + { + return _guid.GetHashCode(); + } + + #endregion + + #region NewGuid + + /// + /// Initialises a new instance of the ShortGuid class + /// + /// + public static ShortGuid NewGuid() + { + return new ShortGuid(Guid.NewGuid()); + } + + #endregion + + #region Encode + + /// + /// Creates a new instance of a Guid using the string value, + /// then returns the base64 encoded version of the Guid. + /// + /// An actual Guid string (i.e. not a ShortGuid) + /// + public static string Encode(string value) + { + Guid guid = new Guid(value); + return Encode(guid); + } + + /// + /// Encodes the given Guid as a base64 string that is 22 + /// characters long. + /// + /// The Guid to encode + /// + public static string Encode(Guid guid) + { + string encoded = Convert.ToBase64String(guid.ToByteArray()); + encoded = encoded + .Replace("/", "_") + .Replace("+", "-"); + return encoded.Substring(0, 22); + } + + #endregion + + #region Decode + + /// + /// Decodes the given base64 string + /// + /// The base64 encoded string of a Guid + /// A new Guid + public static Guid Decode(string value) + { + value = value + .Replace("_", "/") + .Replace("-", "+"); + byte[] buffer = Convert.FromBase64String(value + "=="); + return new Guid(buffer); + } + + #endregion + + #region Operators + + /// + /// Determines if both ShortGuids have the same underlying + /// Guid value. + /// + /// + /// + /// + public static bool operator ==(ShortGuid x, ShortGuid y) + { + if ((object)x == null) return (object)y == null; + return x._guid == y._guid; + } + + /// + /// Determines if both ShortGuids do not have the + /// same underlying Guid value. + /// + /// + /// + /// + public static bool operator !=(ShortGuid x, ShortGuid y) + { + return !(x == y); + } + + /// + /// Implicitly converts the ShortGuid to it's string equivilent + /// + /// + /// + public static implicit operator string(ShortGuid shortGuid) + { + return shortGuid._value; + } + + /// + /// Implicitly converts the ShortGuid to it's Guid equivilent + /// + /// + /// + public static implicit operator Guid(ShortGuid shortGuid) + { + return shortGuid._guid; + } + + /// + /// Implicitly converts the string to a ShortGuid + /// + /// + /// + public static implicit operator ShortGuid(string shortGuid) + { + return new ShortGuid(shortGuid); + } + + /// + /// Implicitly converts the Guid to a ShortGuid + /// + /// + /// + public static implicit operator ShortGuid(Guid guid) + { + return new ShortGuid(guid); + } + + #endregion + } +} diff --git a/FingerprintCenter/App.config b/FingerprintCenter/App.config index 1f98f6c64..3dad6ba7c 100644 --- a/FingerprintCenter/App.config +++ b/FingerprintCenter/App.config @@ -1,7 +1,7 @@ - + - +
@@ -13,6 +13,17 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/FingerprintCenter/FingerPrint.cs b/FingerprintCenter/FingerPrint.cs index b83d72495..da64e164f 100644 --- a/FingerprintCenter/FingerPrint.cs +++ b/FingerprintCenter/FingerPrint.cs @@ -17,6 +17,7 @@ using DigitalPlatform.Text; using DigitalPlatform.Interfaces; using DigitalPlatform; +using DigitalPlatform.Xml; namespace FingerprintCenter { @@ -53,8 +54,10 @@ public static class FingerPrint // 注册过程完成 static AutoResetEvent _eventRegisterFinished = new AutoResetEvent(false); - public static bool Init() + public static NormalResult Init() { + Free(); + List dev_list = new List(); int ret = zkfperrdef.ZKFP_ERR_OK; if ((ret = zkfp2.Init()) == zkfperrdef.ZKFP_ERR_OK) @@ -72,15 +75,15 @@ public static bool Init() { zkfp2.Terminate(); // MessageBox.Show("No device connected!"); - return false; + return new NormalResult { Value = -1, ErrorInfo = "尚未连接指纹阅读器" }; } - return true; + return new NormalResult(); } else { // MessageBox.Show("Initialize fail, ret=" + ret + " !"); - return false; + return new NormalResult { Value = -1, ErrorInfo = "初始化失败,错误码: " + ret }; } } @@ -89,28 +92,39 @@ public static void Free() zkfp2.Terminate(); } - public static bool OpenZK() + public static NormalResult OpenZK() { + CloseZK(); + int ret = zkfp.ZKFP_ERR_OK; if (IntPtr.Zero == (_devHandle = zkfp2.OpenDevice(0 //cmbIdx.SelectedIndex ))) { // MessageBox.Show("OpenDevice fail"); - return false; + return new NormalResult { Value = -1, ErrorInfo = "打开设备失败" }; } if (IntPtr.Zero == (_dBHandle = zkfp2.DBInit())) { // MessageBox.Show("Init DB fail"); - zkfp2.CloseDevice(_devHandle); - _devHandle = IntPtr.Zero; - return false; + //zkfp2.CloseDevice(_devHandle); + //_devHandle = IntPtr.Zero; + CloseZK(); + return new NormalResult { Value = -1, ErrorInfo = "初始化高速缓存失败" }; } _id_barcode_table.Clear(); _barcode_id_table.Clear(); - return true; +#if NO + int old_value = GetIntParameter(3); + + byte[] value = new byte[4]; + bool bRet = zkfp2.Int2ByteArray(500, value); + ret = zkfp2.SetParameters(_devHandle, 3, value, 4); +#endif + + return new NormalResult(); #if NO bnInit.Enabled = false; bnFree.Enabled = true; @@ -152,6 +166,12 @@ public static void CloseZK() zkfp2.DBFree(_dBHandle); _dBHandle = IntPtr.Zero; } + + if (_devHandle != IntPtr.Zero) + { + zkfp2.CloseDevice(_devHandle); + _devHandle = IntPtr.Zero; + } } public static void ClearDB() @@ -183,6 +203,11 @@ public static int AddItems( return -1; } #endif + if (_dBHandle == IntPtr.Zero) + { + strError = "指纹设备尚未初始化"; + return -1; + } // 清除已有的全部缓存内容 if (items == null || items.Count == 0) @@ -291,64 +316,73 @@ public static int InitFingerprintCache( { strError = ""; - // 清空以前的全部缓存内容,以便重新建立 - // return: - // -2 remoting服务器连接失败。驱动程序尚未启动 - // -1 出错 - // >=0 实际发送给接口程序的事项数目 - int nRet = CreateFingerprintCache(null, - out strError); - if (nRet == -1 || nRet == -2) - return nRet; - - // this.Prompt("正在初始化指纹缓存 ...\r\n请不要关闭本窗口\r\n\r\n(在此过程中,与指纹识别无关的窗口和功能不受影响,可前往使用)\r\n"); - - List readerdbnames = null; - nRet = GetCurrentOwnerReaderNameList( - channel, - out readerdbnames, - out strError); - if (nRet == -1) - return -1; - if (readerdbnames.Count == 0) - { - strError = "因当前用户没有管辖任何读者库,初始化指纹缓存的操作无法完成"; - return -1; - } - - SetProgress(0, readerdbnames.Count); - - int nCount = 0; - // 对这些读者库逐个进行高速缓存的初始化 - // 使用 特殊的 browse 格式,以便获得读者记录中的 fingerprint timestamp字符串,或者兼获得 fingerprint string - // - int i = 0; - foreach (string strReaderDbName in readerdbnames) + try { - // 初始化一个读者库的指纹缓存 + // 清空以前的全部缓存内容,以便重新建立 // return: + // -2 remoting服务器连接失败。驱动程序尚未启动 // -1 出错 // >=0 实际发送给接口程序的事项数目 - nRet = BuildOneDbCache( + int nRet = CreateFingerprintCache(null, + out strError); + if (nRet == -1 || nRet == -2) + return nRet; + + // this.Prompt("正在初始化指纹缓存 ...\r\n请不要关闭本窗口\r\n\r\n(在此过程中,与指纹识别无关的窗口和功能不受影响,可前往使用)\r\n"); + + List readerdbnames = null; + nRet = GetCurrentOwnerReaderNameList( channel, - strDir, - strReaderDbName, - token, + out readerdbnames, out strError); if (nRet == -1) return -1; - nCount += nRet; - i++; - SetProgress(i, readerdbnames.Count); - } + if (readerdbnames.Count == 0) + { + strError = "因当前用户没有管辖任何读者库,初始化指纹缓存的操作无法完成"; + return -1; + } - if (nCount == 0) + SetProgress(0, readerdbnames.Count); + + int nCount = 0; + // 对这些读者库逐个进行高速缓存的初始化 + // 使用 特殊的 browse 格式,以便获得读者记录中的 fingerprint timestamp字符串,或者兼获得 fingerprint string + // + int i = 0; + foreach (string strReaderDbName in readerdbnames) + { + // 初始化一个读者库的指纹缓存 + // return: + // -1 出错 + // >=0 实际发送给接口程序的事项数目 + nRet = BuildOneDbCache( + channel, + strDir, + strReaderDbName, + token, + out strError); + if (nRet == -1) + return -1; + nCount += nRet; + i++; + SetProgress(i, readerdbnames.Count); + } + + if (nCount == 0) + { + strError = "因当前用户管辖的读者库 " + StringUtil.MakePathList(readerdbnames) + " 中没有任何具有指纹信息的读者记录,初始化指纹缓存的操作没有完成"; + return -1; + } + + ShowMessage("指纹缓存初始化成功"); + return 0; + } + catch (Exception ex) { - strError = "因当前用户管辖的读者库 " + StringUtil.MakePathList(readerdbnames) + " 中没有任何具有指纹信息的读者记录,初始化指纹缓存的操作没有完成"; + strError = ex.Message; return -1; } - - return 0; } @@ -1132,7 +1166,7 @@ public static void StartCapture(CancellationToken token) _register_template_list.Clear(); Thread captureThread = new Thread(new ThreadStart(CaptureThreadMain)); - captureThread.IsBackground = true; + // captureThread.IsBackground = true; captureThread.Start(); _captureData._cancelToken = token; } @@ -1153,7 +1187,7 @@ static void CaptureThreadMain() { // SendMessage(FormHandle, MESSAGE_CAPTURED_OK, IntPtr.Zero, IntPtr.Zero); ProcessCaptureData(image_buffer, - template_buffer, + template_buffer, template_buffer_length); } Thread.Sleep(200); @@ -1229,7 +1263,10 @@ static void ProcessCaptureData( int ret = zkfp.ZKFP_ERR_OK; int fid = 0, score = 0; ret = zkfp2.DBIdentify(_dBHandle, template_buffer, ref fid, ref score); - if (zkfp.ZKFP_ERR_OK == ret) + Debug.WriteLine(string.Format("ret={0}, fid={1}, score={2}", ret, fid, score)); + if (score > 10 + // zkfp.ZKFP_ERR_OK == ret + ) { //textRes.Text = "Identify succ, fid= " + fid + ",score=" + score + "!"; //return; @@ -1256,6 +1293,7 @@ static void ProcessCaptureData( //return; CapturedEventArgs e1 = new CapturedEventArgs { + Score = score, ErrorInfo = "Identify fail, ret= " + ret }; Captured(null, e1); @@ -1311,8 +1349,423 @@ public static TextResult GetRegisterString() } } + public class ReplicationPlan : NormalResult + { + public string StartDate { get; set; } + } + + // 获得同步计划信息 + // 也就是第一次同步开始的位置信息 + public static ReplicationPlan GetReplicationPlan(LibraryChannel channel) + { + // 开始处理时的日期 + string strEndDate = DateTimeUtil.DateTimeToString8(DateTime.Now); + + // 获得日志文件中记录的总数 + // parameters: + // strDate 日志文件的日期,8 字符 + // return: + // -2 此类型的日志在 dp2library 端尚未启用 + // -1 出错 + // 0 日志文件不存在,或者记录数为 0 + // >0 记录数 + long lCount = OperLogLoader.GetOperLogCount( + null, + channel, + strEndDate, + LogType.OperLog, + out string strError); + if (lCount < 0) + return new ReplicationPlan{ Value = -1, ErrorInfo = strError }; + + return new ReplicationPlan { StartDate = strEndDate + ":0-" + (lCount - 1).ToString() }; + } + + class ReplicationResult : NormalResult + { + public string LastDate { get; set; } + public long LastIndex { get; set; } + } + + // 同步 + // 注:中途遇到异常(例如 Loader 抛出异常),可能会丢失 INSERT_BATCH 条以内的日志记录写入 operlog 表 + // parameters: + // strLastDate 处理中断或者结束时返回最后处理过的日期 + // last_index 处理或中断返回时最后处理过的位置。以后继续处理的时候可以从这个偏移开始 + // return: + // -1 出错 + // 0 中断 + // 1 完成 + static ReplicationResult DoReplication( + LibraryChannel channel, + string strStartDate, + string strEndDate, + LogType logType, + CancellationToken token) + { + string strLastDate = ""; + long last_index = -1; // -1 表示尚未处理 + + bool bUserChanged = false; + // strStartDate 里面可能会包含 ":1-100" 这样的附加成分 + StringUtil.ParseTwoPart(strStartDate, + ":", + out string strLeft, + out string strRight); + strStartDate = strLeft; + if (string.IsNullOrEmpty(strStartDate) == true) + { + return new ReplicationResult + { + Value = -1, + ErrorInfo = "DoReplication() 出错: strStartDate 参数值不应为空" + }; + } + + try + { + List dates = null; + int nRet = OperLogLoader.MakeLogFileNames(strStartDate, + strEndDate, + true, // 是否包含扩展名 ".log" + out dates, + out string strWarning, + out string strError); + if (nRet == -1) + { + return new ReplicationResult + { + Value = -1, + ErrorInfo = strError + }; + } + + if (dates.Count > 0 && string.IsNullOrEmpty(strRight) == false) + { + dates[0] = dates[0] + ":" + strRight; + } + + channel.Timeout = new TimeSpan(0, 1, 0); // 一分钟 + + + // using (SQLiteConnection connection = new SQLiteConnection(this._connectionString)) + { + ProgressEstimate estimate = new ProgressEstimate(); + + OperLogLoader loader = new OperLogLoader(); + loader.Channel = channel; + loader.Stop = null; // this.Progress; + // loader.owner = this; + loader.Estimate = estimate; + loader.Dates = dates; + loader.Level = 2; // Program.MainForm.OperLogLevel; + loader.AutoCache = false; + loader.CacheDir = ""; + loader.LogType = logType; + loader.Filter = "setReaderInfo"; + + loader.Prompt -= Loader_Prompt; + loader.Prompt += Loader_Prompt; + + int nRecCount = 0; + + string strLastItemDate = ""; + long lLastItemIndex = -1; + foreach (OperLogItem item in loader) + { + token.ThrowIfCancellationRequested(); + + //if (stop != null) + // stop.SetMessage("正在同步 " + item.Date + " " + item.Index.ToString() + " " + estimate.Text + "..."); + + if (string.IsNullOrEmpty(item.Xml) == true) + goto CONTINUE; + + XmlDocument dom = new XmlDocument(); + try + { + dom.LoadXml(item.Xml); + } + catch (Exception ex) + { +#if NO + DialogResult result = System.Windows.Forms.DialogResult.No; + strError = logType.ToString() + "日志记录 " + item.Date + " " + item.Index.ToString() + " XML 装入 DOM 的时候发生错误: " + ex.Message; + string strText = strError; + + this.Invoke((Action)(() => + { + result = MessageBox.Show(this, + strText + "\r\n\r\n是否跳过此条记录继续处理?", + "ReportForm", + MessageBoxButtons.YesNo, + MessageBoxIcon.Question, + MessageBoxDefaultButton.Button1); + })); + + if (result == System.Windows.Forms.DialogResult.No) + return -1; + + // 记入日志,继续处理 + this.GetErrorInfoForm().WriteHtml(strError + "\r\n"); + continue; +#endif + + if (Prompt != null) + { + strError = logType.ToString() + "日志记录 " + item.Date + " " + item.Index.ToString() + " XML 装入 DOM 的时候发生错误: " + ex.Message; + MessagePromptEventArgs e = new MessagePromptEventArgs + { + MessageText = strError + "\r\n\r\n是否跳过此条继续处理?", + Actions = "yes,no,cancel" + }; + Prompt(channel, e); + if (e.ResultAction == "cancel") + throw new ChannelException(channel.ErrorCode, strError); + else if (e.ResultAction == "yes") + continue; + else + { + // no 也是抛出异常。因为继续下一批代价太大 + throw new ChannelException(channel.ErrorCode, strError); + } + } + else + throw new ChannelException(channel.ErrorCode, strError); + + } + + string strOperation = dom.DocumentElement.GetAttribute("operation"); + if (strOperation == "setReaderInfo") + { + nRet = TraceSetReaderInfo( + dom, + out strError); + } + else + continue; + + if (nRet == -1) + { + strError = "同步 " + item.Date + " " + item.Index.ToString() + " 时出错: " + strError; + + if (Prompt != null) + { + MessagePromptEventArgs e = new MessagePromptEventArgs + { + MessageText = strError + "\r\n\r\n是否跳过此条继续处理?", + Actions = "yes,no,cancel" + }; + Prompt(channel, e); + if (e.ResultAction == "cancel") + throw new Exception(strError); + else if (e.ResultAction == "yes") + continue; + else + { + // no 也是抛出异常。因为继续下一批代价太大 + throw new Exception(strError); + } + } + else + throw new ChannelException(channel.ErrorCode, strError); + } + + // lProcessCount++; + CONTINUE: + // 便于循环外获得这些值 + strLastItemDate = item.Date; + lLastItemIndex = item.Index + 1; + + // index = 0; // 第一个日志文件后面的,都从头开始了 + } + + // 记忆 + strLastDate = strLastItemDate; + last_index = lLastItemIndex; + } + + return new ReplicationResult { LastDate = strLastDate, LastIndex = last_index }; + } + catch (Exception ex) + { + string strError = "ReportForm DoReplication() exception: " + ExceptionUtil.GetDebugText(ex); + return new ReplicationResult { Value = -1, ErrorInfo = strError }; + } + } + + // SetReaderInfo() API 恢复动作 + /* + + setReaderInfo 操作类型 + ... 具体动作。有new change delete move 4种 + ... 新记录 + ... 被覆盖或者删除的记录 动作为change和delete时具备此元素 + 若干个元素。表示连带发生修改的册记录 + test 操作者 + Fri, 08 Dec 2006 09:01:38 GMT 操作时间 + + +注: new 的时候只有元素,delete的时候只有元素,change的时候两者都有 + + * */ + static int TraceSetReaderInfo( +XmlDocument domLog, +out string strError) + { + strError = ""; + + string strAction = domLog.DocumentElement.GetAttribute("action"); + + if (strAction == "new" + || strAction == "change" + || strAction == "move") + { + string strRecord = DomUtil.GetElementText(domLog.DocumentElement, + "record", + out XmlNode node); + if (node == null) + { + strError = "日志记录中缺元素"; + return -1; + } + string strNewRecPath = DomUtil.GetAttr(node, "recPath"); + + string strOldRecord = ""; + string strOldRecPath = ""; + if (strAction == "move") + { + strOldRecord = DomUtil.GetElementText(domLog.DocumentElement, + "oldRecord", + out node); + if (node == null) + { + strError = "日志记录中缺元素"; + return -1; + } + + strOldRecPath = DomUtil.GetAttr(node, "recPath"); + if (string.IsNullOrEmpty(strOldRecPath) == true) + { + strError = "日志记录中元素内缺recPath属性值"; + return -1; + } + + // 如果移动过程中没有修改,则要用旧的记录内容写入目标 + if (string.IsNullOrEmpty(strRecord) == true) + strRecord = strOldRecord; + } + + // 删除旧记录对应的指纹缓存 + if (strAction == "move" + && string.IsNullOrEmpty(strOldRecord) == false) + { + if (DeleteFingerPrint(strOldRecord, out strError) == -1) + return -1; + } + + if (AddFingerPrint(strRecord, out strError) == -1) + return -1; + } + else if (strAction == "delete") + { + string strOldRecord = DomUtil.GetElementText(domLog.DocumentElement, + "oldRecord", + out XmlNode node); + if (node == null) + { + strError = "日志记录中缺元素"; + return -1; + } + string strRecPath = DomUtil.GetAttr(node, "recPath"); + + if (string.IsNullOrEmpty(strOldRecord) == false) + { + if (DeleteFingerPrint(strOldRecord, out strError) == -1) + return -1; + } + } + else + { + strError = "无法识别的内容 '" + strAction + "'"; + return -1; + } + + return 0; + } + + // 写入新记录的指纹缓存 + static int AddFingerPrint(string strRecord, out string strError) + { + strError = ""; + + XmlDocument new_dom = new XmlDocument(); + new_dom.LoadXml(strRecord); + + string strReaderBarcode = GetReaderBarcode(new_dom); + if (string.IsNullOrEmpty(strReaderBarcode)) + return 0; + string strFingerPrintString = DomUtil.GetElementText(new_dom.DocumentElement, "fingerprint"); + + // TODO: 看新旧记录之间 fingerprint 之间的差异。有差异才需要覆盖进入高速缓存 + FingerprintItem item = new FingerprintItem + { + FingerprintString = strFingerPrintString, + ReaderBarcode = strReaderBarcode + }; + // return: + // -1 出错 + // 0 成功 + int nRet = AddItems( + new List { item }, + out strError); + if (nRet == -1) + return -1; + + return 1; + } + + static int DeleteFingerPrint(string strOldRecord, out string strError) + { + strError = ""; + XmlDocument old_dom = new XmlDocument(); + old_dom.LoadXml(strOldRecord); + + string strReaderBarcode = GetReaderBarcode(old_dom); + if (string.IsNullOrEmpty(strReaderBarcode) == false) + { + FingerprintItem item = new FingerprintItem + { + FingerprintString = "", + ReaderBarcode = strReaderBarcode + }; + // return: + // -1 出错 + // 0 成功 + int nRet = AddItems( + new List { item }, + out strError); + if (nRet == -1) + return -1; + } + + return 0; + } + + static string GetReaderBarcode(XmlDocument dom) + { + string strReaderBarcode = DomUtil.GetElementText(dom.DocumentElement, + "barcode"); + if (string.IsNullOrEmpty(strReaderBarcode) == false) + return strReaderBarcode; + + string strRefID = DomUtil.GetElementText(dom.DocumentElement, "refID"); + if (string.IsNullOrEmpty(strRefID)) + return ""; + return "@refID:" + strRefID; + } #if NO public static bool Identify() { diff --git a/FingerprintCenter/FingerprintCenter.csproj b/FingerprintCenter/FingerprintCenter.csproj index e92382421..46665d609 100644 --- a/FingerprintCenter/FingerprintCenter.csproj +++ b/FingerprintCenter/FingerprintCenter.csproj @@ -36,6 +36,9 @@ ..\..\zksdk5\ZKFinger SDK 5.0.0.20_20170424\C#\lib\x86\libzkfpcsharp.dll + + ..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll + @@ -76,6 +79,7 @@ True Resources.resx + SettingsSingleFileGenerator Settings.Designer.cs @@ -118,6 +122,10 @@ {26F96CC3-A4A9-4BC4-A10A-BC7E25581FF6} DigitalPlatform.Text + + {E6489E89-1349-4EE7-A00B-AC96B9912587} + DigitalPlatform.Xml + {BDD43275-EAA0-4670-8BA3-0DB5CD7598DD} DigitalPlatform diff --git a/FingerprintCenter/FingerprintServer.cs b/FingerprintCenter/FingerprintServer.cs index e773b05db..73b37de16 100644 --- a/FingerprintCenter/FingerprintServer.cs +++ b/FingerprintCenter/FingerprintServer.cs @@ -4,16 +4,24 @@ using System.Text; using System.Threading.Tasks; using System.Speech.Synthesis; +using System.Threading; -using DigitalPlatform.Interfaces; using DigitalPlatform; -using System.Threading; +using DigitalPlatform.Interfaces; namespace FingerprintCenter { public class FingerprintServer : MarshalByRefObject, IFingerprint, IDisposable { - + public int GetVersion(out string strVersion, + out string strCfgInfo, + out string strError) + { + strVersion = "2.0"; + strCfgInfo = "selfInitCache"; + strError = ""; + return 0; + } // return: // -1 出错 @@ -194,7 +202,7 @@ public int GetFingerprintString(out string strFingerprintString, strVersion = "10"; return 1; } - catch(Exception ex) + catch (Exception ex) { strError = ex.Message; return 0; diff --git a/FingerprintCenter/MainForm.Designer.cs b/FingerprintCenter/MainForm.Designer.cs index dd867b1b9..fadd5b2a4 100644 --- a/FingerprintCenter/MainForm.Designer.cs +++ b/FingerprintCenter/MainForm.Designer.cs @@ -31,8 +31,12 @@ private void InitializeComponent() System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); this.menuStrip1 = new System.Windows.Forms.MenuStrip(); this.MenuItem_file = new System.Windows.Forms.ToolStripMenuItem(); + this.ToolStripMenuItem_start = new System.Windows.Forms.ToolStripMenuItem(); + this.ToolStripMenuItem_reopen = new System.Windows.Forms.ToolStripMenuItem(); this.MenuItem_test = new System.Windows.Forms.ToolStripMenuItem(); this.MenuItem_clearFingerprintCache = new System.Windows.Forms.ToolStripMenuItem(); + this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); + this.ToolStripMenuItem_exit = new System.Windows.Forms.ToolStripMenuItem(); this.toolStrip1 = new System.Windows.Forms.ToolStrip(); this.toolButton_stop = new System.Windows.Forms.ToolStripButton(); this.toolStripDropDownButton_stopAll = new System.Windows.Forms.ToolStripDropDownButton(); @@ -62,8 +66,6 @@ private void InitializeComponent() this.toolStripButton_cfg_setXeServer = new System.Windows.Forms.ToolStripButton(); this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator(); this.toolStripButton_cfg_setHongnibaServer = new System.Windows.Forms.ToolStripButton(); - this.ToolStripMenuItem_exit = new System.Windows.Forms.ToolStripMenuItem(); - this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator(); this.menuStrip1.SuspendLayout(); this.toolStrip1.SuspendLayout(); this.statusStrip1.SuspendLayout(); @@ -92,6 +94,8 @@ private void InitializeComponent() // MenuItem_file // this.MenuItem_file.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.ToolStripMenuItem_start, + this.ToolStripMenuItem_reopen, this.MenuItem_test, this.MenuItem_clearFingerprintCache, this.toolStripSeparator3, @@ -100,20 +104,46 @@ private void InitializeComponent() this.MenuItem_file.Size = new System.Drawing.Size(58, 28); this.MenuItem_file.Text = "文件"; // + // ToolStripMenuItem_start + // + this.ToolStripMenuItem_start.Name = "ToolStripMenuItem_start"; + this.ToolStripMenuItem_start.Size = new System.Drawing.Size(200, 30); + this.ToolStripMenuItem_start.Text = "启动(&S)"; + this.ToolStripMenuItem_start.Click += new System.EventHandler(this.ToolStripMenuItem_start_Click); + // + // ToolStripMenuItem_reopen + // + this.ToolStripMenuItem_reopen.Name = "ToolStripMenuItem_reopen"; + this.ToolStripMenuItem_reopen.Size = new System.Drawing.Size(200, 30); + this.ToolStripMenuItem_reopen.Text = "重新启动(&R)"; + this.ToolStripMenuItem_reopen.Click += new System.EventHandler(this.ToolStripMenuItem_reopen_Click); + // // MenuItem_test // this.MenuItem_test.Name = "MenuItem_test"; - this.MenuItem_test.Size = new System.Drawing.Size(252, 30); + this.MenuItem_test.Size = new System.Drawing.Size(200, 30); this.MenuItem_test.Text = "test"; this.MenuItem_test.Click += new System.EventHandler(this.MenuItem_test_Click); // // MenuItem_clearFingerprintCache // this.MenuItem_clearFingerprintCache.Name = "MenuItem_clearFingerprintCache"; - this.MenuItem_clearFingerprintCache.Size = new System.Drawing.Size(252, 30); + this.MenuItem_clearFingerprintCache.Size = new System.Drawing.Size(200, 30); this.MenuItem_clearFingerprintCache.Text = "清除指纹缓存"; this.MenuItem_clearFingerprintCache.Click += new System.EventHandler(this.MenuItem_clearFingerprintCache_Click); // + // toolStripSeparator3 + // + this.toolStripSeparator3.Name = "toolStripSeparator3"; + this.toolStripSeparator3.Size = new System.Drawing.Size(197, 6); + // + // ToolStripMenuItem_exit + // + this.ToolStripMenuItem_exit.Name = "ToolStripMenuItem_exit"; + this.ToolStripMenuItem_exit.Size = new System.Drawing.Size(200, 30); + this.ToolStripMenuItem_exit.Text = "退出(&X)"; + this.ToolStripMenuItem_exit.Click += new System.EventHandler(this.ToolStripMenuItem_exit_Click); + // // toolStrip1 // this.toolStrip1.ImageScalingSize = new System.Drawing.Size(24, 24); @@ -335,6 +365,7 @@ private void InitializeComponent() this.textBox_cfg_password.PasswordChar = '*'; this.textBox_cfg_password.Size = new System.Drawing.Size(232, 28); this.textBox_cfg_password.TabIndex = 14; + this.textBox_cfg_password.TextChanged += new System.EventHandler(this.textBox_cfg_userName_TextChanged); // // textBox_cfg_userName // @@ -344,6 +375,7 @@ private void InitializeComponent() this.textBox_cfg_userName.Name = "textBox_cfg_userName"; this.textBox_cfg_userName.Size = new System.Drawing.Size(232, 28); this.textBox_cfg_userName.TabIndex = 11; + this.textBox_cfg_userName.TextChanged += new System.EventHandler(this.textBox_cfg_userName_TextChanged); // // label3 // @@ -372,6 +404,7 @@ private void InitializeComponent() this.textBox_cfg_dp2LibraryServerUrl.Name = "textBox_cfg_dp2LibraryServerUrl"; this.textBox_cfg_dp2LibraryServerUrl.Size = new System.Drawing.Size(754, 28); this.textBox_cfg_dp2LibraryServerUrl.TabIndex = 8; + this.textBox_cfg_dp2LibraryServerUrl.TextChanged += new System.EventHandler(this.textBox_cfg_userName_TextChanged); // // label1 // @@ -430,18 +463,6 @@ private void InitializeComponent() this.toolStripButton_cfg_setHongnibaServer.ToolTipText = "设为红泥巴.数字平台服务器"; this.toolStripButton_cfg_setHongnibaServer.Click += new System.EventHandler(this.toolStripButton_cfg_setHongnibaServer_Click); // - // ToolStripMenuItem_exit - // - this.ToolStripMenuItem_exit.Name = "ToolStripMenuItem_exit"; - this.ToolStripMenuItem_exit.Size = new System.Drawing.Size(252, 30); - this.ToolStripMenuItem_exit.Text = "退出(&X)"; - this.ToolStripMenuItem_exit.Click += new System.EventHandler(this.ToolStripMenuItem_exit_Click); - // - // toolStripSeparator3 - // - this.toolStripSeparator3.Name = "toolStripSeparator3"; - this.toolStripSeparator3.Size = new System.Drawing.Size(249, 6); - // // MainForm // this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 18F); @@ -516,6 +537,8 @@ private void InitializeComponent() private System.Windows.Forms.WebBrowser webBrowser1; private System.Windows.Forms.ToolStripSeparator toolStripSeparator3; private System.Windows.Forms.ToolStripMenuItem ToolStripMenuItem_exit; + private System.Windows.Forms.ToolStripMenuItem ToolStripMenuItem_start; + private System.Windows.Forms.ToolStripMenuItem ToolStripMenuItem_reopen; } } diff --git a/FingerprintCenter/MainForm.cs b/FingerprintCenter/MainForm.cs index 2ca4a5658..da21343d7 100644 --- a/FingerprintCenter/MainForm.cs +++ b/FingerprintCenter/MainForm.cs @@ -11,6 +11,7 @@ using System.Runtime.Remoting.Channels.Ipc; using System.Web; using System.Text; +using System.Runtime.InteropServices; using FingerprintCenter.Properties; using libzkfpcsharp; @@ -20,6 +21,9 @@ using DigitalPlatform.LibraryClient; using DigitalPlatform.IO; using DigitalPlatform.Interfaces; +using DigitalPlatform; +using static FingerprintCenter.FingerPrint; +using Newtonsoft.Json; namespace FingerprintCenter { @@ -86,9 +90,25 @@ public string UiState } } - public void ShowMessage(string text) + public void ShowMessage(string strMessage, +string strColor = "", +bool bClickClose = false) { - this._floatingMessage.Text = text; + if (this._floatingMessage == null) + return; + + Color color = Color.FromArgb(80, 80, 80); + + if (strColor == "red") // 出错 + color = Color.DarkRed; + else if (strColor == "yellow") // 成功,提醒 + color = Color.DarkGoldenrod; + else if (strColor == "green") // 成功 + color = Color.Green; + else if (strColor == "progress") // 处理过程 + color = Color.FromArgb(80, 80, 80); + + this._floatingMessage.SetMessage(strMessage, color, bClickClose); } public void ClearMessage() @@ -100,6 +120,11 @@ private void Form1_Load(object sender, EventArgs e) { this.UiState = Properties.Settings.Default.ui_state; + this._repPlan = JsonConvert.DeserializeObject(Properties.Settings.Default.repPlan); + if (this._repPlan == null) + this._repPlan = new ReplicationPlan(); + + ClearHtml(); this._channelPool.BeforeLogin += new DigitalPlatform.LibraryClient.BeforeLoginEventHandle(Channel_BeforeLogin); @@ -113,13 +138,67 @@ private void Form1_Load(object sender, EventArgs e) FingerPrint.Speak += FingerPrint_Speak; FingerPrint.ImageReady += FingerPrint_ImageReady; - FingerPrint.Init(); - FingerPrint.OpenZK(); + StartRemotingServer(); - FingerPrint.StartCapture(_cancel.Token); + BeginStart(); + } - StartRemotingServer(); - Speak("指纹中心启动成功"); + // 指纹功能是否初始化成功 + bool _initialized = false; + + void BeginStart() + { + this.ClearMessage(); + + if (_initialized == true) + return; + + Task.Run(() => + { + NormalResult result = StartFingerPrint(); + if (result.Value == -1) + { + string strError = "指纹功能启动失败: " + result.ErrorInfo; + Speak(strError); + this.ShowMessage(strError, "red", true); + } + else + { + _initialized = true; + Speak("指纹功能启动成功"); + } + }); + } + + NormalResult StartFingerPrint() + { + _cancel.Cancel(); + + _cancel = new CancellationTokenSource(); + + NormalResult result = FingerPrint.Init(); + if (result.Value == -1) + return result; + + result = FingerPrint.OpenZK(); + if (result.Value == -1) + return result; + + // 初始化指纹缓存 + // return: + // -1 出错 + // 0 没有获得任何数据 + // 1 获得了数据 + int nRet = InitFingerprintCache( + out string strError); + if (nRet == -1) + return new NormalResult { Value = -1, ErrorInfo = strError }; + if (nRet == 0) + this.ShowMessage(strError, "red", true); + + // 开始捕捉指纹 + FingerPrint.StartCapture(_cancel.Token); + return new NormalResult(); } private void FingerPrint_ImageReady(object sender, ImageReadyEventArgs e) @@ -208,6 +287,7 @@ private void Form1_FormClosed(object sender, FormClosedEventArgs e) this._channelPool.AfterLogin -= new AfterLoginEventHandle(Channel_AfterLogin); Properties.Settings.Default.ui_state = this.UiState; + Properties.Settings.Default.repPlan = JsonConvert.SerializeObject(this._repPlan); Properties.Settings.Default.Save(); } @@ -251,9 +331,14 @@ internal void Channel_BeforeLogin(object sender, if (String.IsNullOrEmpty(e.UserName) == false) return; // 立即返回, 以便作第一次 不出现 对话框的自动登录 + else + { + e.ErrorInfo = "尚未配置 dp2library 服务器用户名"; + e.Cancel = true; + } } - e.ErrorInfo = "尚未配置服务器参数"; + // e.ErrorInfo = "尚未配置 dp2library 服务器用户名"; e.Cancel = true; } @@ -359,27 +444,44 @@ void EnableControls(bool bEnable) })); } + FingerPrint.ReplicationPlan _repPlan = new FingerPrint.ReplicationPlan(); + // 注意,本函数不在界面线程执行 + // return: + // -1 出错 + // 0 没有获得任何数据 + // 1 获得了数据 int InitFingerprintCache( out string strError) { + strError = ""; + string strUrl = (string)this.Invoke((Func)(() => + { + return this.textBox_cfg_dp2LibraryServerUrl.Text; + })); + if (string.IsNullOrEmpty(strUrl)) + { + strError = "尚未配置 dp2library 服务器 URL,无法获得读者指纹信息"; + return 0; + } + this.ShowMessage("正在初始化指纹信息 ..."); EnableControls(false); LibraryChannel channel = this.GetChannel(); try { - string strDir = ""; - this.Invoke((Action)(() => - { - strDir = this.textBox_cfg_dp2LibraryServerUrl.Text; - })); - strDir = ClientInfo.FingerPrintCacheDir(strDir); + _repPlan = FingerPrint.GetReplicationPlan(channel); + + string strDir = ClientInfo.FingerPrintCacheDir(strUrl); PathUtil.TryCreateDir(strDir); - return FingerPrint.InitFingerprintCache(channel, + int nRet = FingerPrint.InitFingerprintCache(channel, strDir, _cancel.Token, out strError); + if (nRet == -1) + return -1; + return 1; } finally { @@ -393,6 +495,10 @@ private void MenuItem_test_Click(object sender, EventArgs e) { Task.Run(() => { + // return: + // -1 出错 + // 0 没有获得任何数据 + // 1 获得了数据 int nRet = InitFingerprintCache( out string strError); if (nRet == -1) @@ -742,7 +848,7 @@ public static void SetHtmlString(WebBrowser webBrowser, void DisplayText(string text) { // AppendHtml("
" +HttpUtility.HtmlEncode(text)+ "
"); - string html = string.Format("
{0}
", HttpUtility.HtmlEncode(text)); + string html = string.Format("
{0}
", HttpUtility.HtmlEncode(text)); SetHtmlString(this.webBrowser1, html); } @@ -769,5 +875,80 @@ private void MainForm_FormClosing(object sender, FormClosingEventArgs e) } } } + + protected override bool ProcessDialogKey( +Keys keyData) + { + if (keyData == Keys.Escape) + { + if (m_fingerprintObj != null) + { + m_fingerprintObj.CancelGetFingerprintString(); + } + return true; + } + + return base.ProcessDialogKey(keyData); + } + + #region device changed + + const int WM_DEVICECHANGE = 0x0219; //see msdn site + const int DBT_DEVNODES_CHANGED = 0x0007; + const int DBT_DEVICEARRIVAL = 0x8000; + const int DBT_DEVICEREMOVALCOMPLETE = 0x8004; + const int DBT_DEVTYPVOLUME = 0x00000002; + + protected override void WndProc(ref Message m) + { + + if (m.Msg == WM_DEVICECHANGE) + { + if (m.WParam.ToInt32() == DBT_DEVNODES_CHANGED) + { + BeginStart(); + } + + /* + if (m.WParam.ToInt32() == DBT_DEVICEARRIVAL) + { + MessageBox.Show(this, "in"); + } + if (m.WParam.ToInt32() == DBT_DEVICEREMOVALCOMPLETE) + { + MessageBox.Show(this, "usb out"); + } + * */ + } + base.WndProc(ref m); + } + + #endregion + + private void ToolStripMenuItem_start_Click(object sender, EventArgs e) + { + BeginStart(); + } + + private void ToolStripMenuItem_reopen_Click(object sender, EventArgs e) + { + // 警告关闭 + DialogResult result = MessageBox.Show(this, + "确实要重新启动 dp2-指纹中心?\r\n\r\n(会重新初始化指纹缓存)", + "dp2-指纹中心", + MessageBoxButtons.YesNo, + MessageBoxIcon.Question, + MessageBoxDefaultButton.Button2); + if (result != DialogResult.Yes) + return; + + _initialized = false; + BeginStart(); + } + + private void textBox_cfg_userName_TextChanged(object sender, EventArgs e) + { + _channelPool.Clear(); + } } } diff --git a/FingerprintCenter/MainForm.resx b/FingerprintCenter/MainForm.resx index caec730c1..d32e07b89 100644 --- a/FingerprintCenter/MainForm.resx +++ b/FingerprintCenter/MainForm.resx @@ -139,9 +139,6 @@ 497, 17 - - 497, 17 - 61 diff --git a/FingerprintCenter/Properties/Settings.Designer.cs b/FingerprintCenter/Properties/Settings.Designer.cs index 90b4b7e50..2ff9c03b7 100644 --- a/FingerprintCenter/Properties/Settings.Designer.cs +++ b/FingerprintCenter/Properties/Settings.Designer.cs @@ -34,5 +34,17 @@ public string ui_state { this["ui_state"] = value; } } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string repPlan { + get { + return ((string)(this["repPlan"])); + } + set { + this["repPlan"] = value; + } + } } } diff --git a/FingerprintCenter/Properties/Settings.settings b/FingerprintCenter/Properties/Settings.settings index d10a23719..7f7ff1246 100644 --- a/FingerprintCenter/Properties/Settings.settings +++ b/FingerprintCenter/Properties/Settings.settings @@ -5,5 +5,8 @@ + + + \ No newline at end of file diff --git a/FingerprintCenter/packages.config b/FingerprintCenter/packages.config new file mode 100644 index 000000000..576275417 --- /dev/null +++ b/FingerprintCenter/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/ZkFingerPrint/FingerprintServer.cs b/ZkFingerPrint/FingerprintServer.cs index b096afe77..91b02bcc0 100644 --- a/ZkFingerPrint/FingerprintServer.cs +++ b/ZkFingerPrint/FingerprintServer.cs @@ -37,7 +37,17 @@ public class FingerprintServer : MarshalByRefObject, IFingerprint, IDisposable Hashtable barcode_id_table = new Hashtable(); // barcode --> id internal AutoResetEvent eventClose = new AutoResetEvent(false); // true : initial state is signaled - internal AutoResetEvent eventFinished = new AutoResetEvent(false); // true : initial state is signaled + internal AutoResetEvent eventFinished = new AutoResetEvent(false); // true : initial state is signaled + + public int GetVersion(out string strVersion, + out string strCfgInfo, + out string strError) + { + strVersion = "1.0"; + strCfgInfo = ""; + strError = ""; + return 0; + } // return: // -1 出错 diff --git a/dp2Circulation/Entity/EntityEditControl.Designer.cs b/dp2Circulation/Entity/EntityEditControl.Designer.cs index 787a166e3..42317dfb5 100644 --- a/dp2Circulation/Entity/EntityEditControl.Designer.cs +++ b/dp2Circulation/Entity/EntityEditControl.Designer.cs @@ -403,7 +403,7 @@ private void InitializeComponent() this.textBox_comment.Multiline = true; this.textBox_comment.Name = "textBox_comment"; this.textBox_comment.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this.textBox_comment.Size = new System.Drawing.Size(348, 24); + this.textBox_comment.Size = new System.Drawing.Size(402, 24); this.textBox_comment.TabIndex = 36; this.textBox_comment.KeyDown += new System.Windows.Forms.KeyEventHandler(this.DoKeyDown); this.textBox_comment.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.DoKeyPress); @@ -429,7 +429,7 @@ private void InitializeComponent() this.textBox_borrowDate.Location = new System.Drawing.Point(137, 512); this.textBox_borrowDate.MinimumSize = new System.Drawing.Size(180, 0); this.textBox_borrowDate.Name = "textBox_borrowDate"; - this.textBox_borrowDate.Size = new System.Drawing.Size(348, 21); + this.textBox_borrowDate.Size = new System.Drawing.Size(402, 21); this.textBox_borrowDate.TabIndex = 48; this.textBox_borrowDate.KeyDown += new System.Windows.Forms.KeyEventHandler(this.DoKeyDown); this.textBox_borrowDate.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.DoKeyPress); @@ -464,9 +464,9 @@ private void InitializeComponent() this.textBox_registerNo.Dock = System.Windows.Forms.DockStyle.Fill; this.textBox_registerNo.ImeMode = System.Windows.Forms.ImeMode.Disable; this.textBox_registerNo.Location = new System.Drawing.Point(137, 371); - this.textBox_registerNo.MinimumSize = new System.Drawing.Size(135, 0); + this.textBox_registerNo.MinimumSize = new System.Drawing.Size(180, 0); this.textBox_registerNo.Name = "textBox_registerNo"; - this.textBox_registerNo.Size = new System.Drawing.Size(348, 21); + this.textBox_registerNo.Size = new System.Drawing.Size(402, 21); this.textBox_registerNo.TabIndex = 33; this.textBox_registerNo.KeyDown += new System.Windows.Forms.KeyEventHandler(this.DoKeyDown); this.textBox_registerNo.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.DoKeyPress); @@ -492,7 +492,7 @@ private void InitializeComponent() this.textBox_mergeComment.Multiline = true; this.textBox_mergeComment.Name = "textBox_mergeComment"; this.textBox_mergeComment.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this.textBox_mergeComment.Size = new System.Drawing.Size(348, 24); + this.textBox_mergeComment.Size = new System.Drawing.Size(402, 24); this.textBox_mergeComment.TabIndex = 39; this.textBox_mergeComment.KeyDown += new System.Windows.Forms.KeyEventHandler(this.DoKeyDown); this.textBox_mergeComment.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.DoKeyPress); @@ -541,7 +541,7 @@ private void InitializeComponent() this.comboBox_location.Location = new System.Drawing.Point(137, 114); this.comboBox_location.MinimumSize = new System.Drawing.Size(178, 0); this.comboBox_location.Name = "comboBox_location"; - this.comboBox_location.Size = new System.Drawing.Size(348, 26); + this.comboBox_location.Size = new System.Drawing.Size(402, 26); this.comboBox_location.TabIndex = 11; this.comboBox_location.DropDown += new System.EventHandler(this.comboBox_location_DropDown); this.comboBox_location.TextUpdate += new System.EventHandler(this.comboBox_location_TextUpdate); @@ -557,7 +557,7 @@ private void InitializeComponent() this.comboBox_bookType.Location = new System.Drawing.Point(137, 339); this.comboBox_bookType.MinimumSize = new System.Drawing.Size(178, 0); this.comboBox_bookType.Name = "comboBox_bookType"; - this.comboBox_bookType.Size = new System.Drawing.Size(348, 26); + this.comboBox_bookType.Size = new System.Drawing.Size(402, 26); this.comboBox_bookType.TabIndex = 30; this.comboBox_bookType.DropDown += new System.EventHandler(this.comboBox_bookType_DropDown); this.comboBox_bookType.SelectedIndexChanged += new System.EventHandler(this.comboBox_bookType_SelectedIndexChanged); @@ -756,7 +756,7 @@ private void InitializeComponent() this.comboBox_seller.Location = new System.Drawing.Point(137, 146); this.comboBox_seller.MinimumSize = new System.Drawing.Size(133, 0); this.comboBox_seller.Name = "comboBox_seller"; - this.comboBox_seller.Size = new System.Drawing.Size(348, 26); + this.comboBox_seller.Size = new System.Drawing.Size(402, 26); this.comboBox_seller.TabIndex = 14; this.comboBox_seller.DropDown += new System.EventHandler(this.comboBox_seller_DropDown); this.comboBox_seller.SelectedIndexChanged += new System.EventHandler(this.comboBox_seller_SelectedIndexChanged); @@ -804,7 +804,7 @@ private void InitializeComponent() this.comboBox_source.Location = new System.Drawing.Point(137, 178); this.comboBox_source.MinimumSize = new System.Drawing.Size(133, 0); this.comboBox_source.Name = "comboBox_source"; - this.comboBox_source.Size = new System.Drawing.Size(348, 26); + this.comboBox_source.Size = new System.Drawing.Size(402, 26); this.comboBox_source.TabIndex = 17; this.comboBox_source.DropDown += new System.EventHandler(this.comboBox_source_DropDown); this.comboBox_source.SelectedIndexChanged += new System.EventHandler(this.comboBox_source_SelectedIndexChanged); @@ -848,7 +848,7 @@ private void InitializeComponent() this.textBox_refID.Location = new System.Drawing.Point(137, 707); this.textBox_refID.MinimumSize = new System.Drawing.Size(180, 0); this.textBox_refID.Name = "textBox_refID"; - this.textBox_refID.Size = new System.Drawing.Size(348, 21); + this.textBox_refID.Size = new System.Drawing.Size(402, 21); this.textBox_refID.TabIndex = 66; this.textBox_refID.KeyDown += new System.Windows.Forms.KeyEventHandler(this.DoKeyDown); this.textBox_refID.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.DoKeyPress); @@ -890,10 +890,10 @@ private void InitializeComponent() // this.button_getAccessNo.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.button_getAccessNo.AutoSize = true; - this.button_getAccessNo.Location = new System.Drawing.Point(491, 237); - this.button_getAccessNo.MinimumSize = new System.Drawing.Size(22, 0); + this.button_getAccessNo.Location = new System.Drawing.Point(545, 237); + this.button_getAccessNo.MinimumSize = new System.Drawing.Size(10, 0); this.button_getAccessNo.Name = "button_getAccessNo"; - this.button_getAccessNo.Size = new System.Drawing.Size(162, 42); + this.button_getAccessNo.Size = new System.Drawing.Size(108, 42); this.button_getAccessNo.TabIndex = 24; this.button_getAccessNo.Text = "创建索取号"; this.button_getAccessNo.UseVisualStyleBackColor = true; @@ -962,7 +962,7 @@ private void InitializeComponent() this.textBox_binding.Multiline = true; this.textBox_binding.Name = "textBox_binding"; this.textBox_binding.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this.textBox_binding.Size = new System.Drawing.Size(348, 24); + this.textBox_binding.Size = new System.Drawing.Size(402, 24); this.textBox_binding.TabIndex = 57; this.textBox_binding.KeyDown += new System.Windows.Forms.KeyEventHandler(this.DoKeyDown); this.textBox_binding.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.DoKeyPress); @@ -977,7 +977,7 @@ private void InitializeComponent() this.checkedComboBox_state.MinimumSize = new System.Drawing.Size(135, 0); this.checkedComboBox_state.Name = "checkedComboBox_state"; this.checkedComboBox_state.Padding = new System.Windows.Forms.Padding(6); - this.checkedComboBox_state.Size = new System.Drawing.Size(350, 33); + this.checkedComboBox_state.Size = new System.Drawing.Size(404, 33); this.checkedComboBox_state.TabIndex = 5; this.checkedComboBox_state.DropDown += new System.EventHandler(this.comboBox_state_DropDown); this.checkedComboBox_state.TextChanged += new System.EventHandler(this.checkedComboBox_state_TextChanged); @@ -1015,7 +1015,7 @@ private void InitializeComponent() this.textBox_operations.Multiline = true; this.textBox_operations.Name = "textBox_operations"; this.textBox_operations.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this.textBox_operations.Size = new System.Drawing.Size(348, 24); + this.textBox_operations.Size = new System.Drawing.Size(402, 24); this.textBox_operations.TabIndex = 60; this.textBox_operations.KeyDown += new System.Windows.Forms.KeyEventHandler(this.DoKeyDown); this.textBox_operations.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.DoKeyPress); diff --git a/dp2Circulation/Entity/EntityEditControl.cs b/dp2Circulation/Entity/EntityEditControl.cs index 49ce51d1a..8ce09ae61 100644 --- a/dp2Circulation/Entity/EntityEditControl.cs +++ b/dp2Circulation/Entity/EntityEditControl.cs @@ -1272,6 +1272,14 @@ public void FocusField(string name, bool bSelectAll) this.comboBox_bookType.Focus(); } + + if (name == "registerNo") + { + if (bSelectAll == true) + this.textBox_registerNo.SelectAll(); + + this.textBox_registerNo.Focus(); + } } /// diff --git a/dp2Circulation/FontSetting/MyForm.cs b/dp2Circulation/FontSetting/MyForm.cs index 7c9375597..50b36fe3c 100644 --- a/dp2Circulation/FontSetting/MyForm.cs +++ b/dp2Circulation/FontSetting/MyForm.cs @@ -208,6 +208,9 @@ public virtual void OnMyFormLoad() if (Program.MainForm == null) return; + this.HelpRequested -= MyForm_HelpRequested; + this.HelpRequested += MyForm_HelpRequested; + this.Channel.Url = Program.MainForm.LibraryServerUrl; this.Channel.BeforeLogin -= new BeforeLoginEventHandle(Channel_BeforeLogin); @@ -237,6 +240,11 @@ public virtual void OnMyFormLoad() } } + private void MyForm_HelpRequested(object sender, HelpEventArgs hlpevent) + { + OnHelpTriggered(); + } + bool _channelDoEvents = true; public bool ChannelDoEvents { @@ -1941,6 +1949,47 @@ public void OnLoaderPrompt(object sender, MessagePromptEventArgs e) } #endregion + +#if NO + protected override bool ProcessDialogKey( +Keys keyData) + { + if (keyData == Keys.F1) + { + // MessageBox.Show(this, "MyForm Help"); + OnHelpTriggered(); + return true; + } + + return base.ProcessDialogKey(keyData); + } +#endif + + string _helpUrl = ""; + public string HelpUrl + { + get + { + return _helpUrl; + } + set + { + _helpUrl = value; + } + } + + public virtual void OnHelpTriggered() + { + // TODO: 如果是多个 URL,需要出现一个对话框让用户选择。每个 URL 需要跟一个小标题 + if (string.IsNullOrEmpty(this.HelpUrl) == false) + { + // Process.Start("IExplore.exe", this.HelpUrl); + Process.Start(this.HelpUrl); + return; + } + // TODO: 最好跳转到一个帮助目录页面 + MessageBox.Show(this, "当前没有帮助链接"); + } } public class FilterHost diff --git a/dp2Circulation/IO/ImportExportForm.Designer.cs b/dp2Circulation/IO/ImportExportForm.Designer.cs index 8d4e72c6b..4b6c8eef8 100644 --- a/dp2Circulation/IO/ImportExportForm.Designer.cs +++ b/dp2Circulation/IO/ImportExportForm.Designer.cs @@ -65,6 +65,7 @@ private void InitializeComponent() this.tabPage_run = new System.Windows.Forms.TabPage(); this.webBrowser1 = new System.Windows.Forms.WebBrowser(); this.button_next = new System.Windows.Forms.Button(); + this.checkBox_target_randomItemRegisterNo = new System.Windows.Forms.CheckBox(); this.tabControl_main.SuspendLayout(); this.tabPage_source.SuspendLayout(); this.tabPage_convert.SuspendLayout(); @@ -81,10 +82,11 @@ private void InitializeComponent() this.tabControl_main.Controls.Add(this.tabPage_convert); this.tabControl_main.Controls.Add(this.tabPage_target); this.tabControl_main.Controls.Add(this.tabPage_run); - this.tabControl_main.Location = new System.Drawing.Point(13, 13); + this.tabControl_main.Location = new System.Drawing.Point(20, 20); + this.tabControl_main.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.tabControl_main.Name = "tabControl_main"; this.tabControl_main.SelectedIndex = 0; - this.tabControl_main.Size = new System.Drawing.Size(443, 283); + this.tabControl_main.Size = new System.Drawing.Size(664, 424); this.tabControl_main.TabIndex = 0; this.tabControl_main.SelectedIndexChanged += new System.EventHandler(this.tabControl_main_SelectedIndexChanged); // @@ -104,10 +106,11 @@ private void InitializeComponent() this.tabPage_source.Controls.Add(this.checkBox_subRecords_issue); this.tabPage_source.Controls.Add(this.checkBox_subRecords_order); this.tabPage_source.Controls.Add(this.checkBox_subRecords_entity); - this.tabPage_source.Location = new System.Drawing.Point(4, 22); + this.tabPage_source.Location = new System.Drawing.Point(4, 28); + this.tabPage_source.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.tabPage_source.Name = "tabPage_source"; - this.tabPage_source.Padding = new System.Windows.Forms.Padding(3); - this.tabPage_source.Size = new System.Drawing.Size(435, 257); + this.tabPage_source.Padding = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.tabPage_source.Size = new System.Drawing.Size(656, 392); this.tabPage_source.TabIndex = 1; this.tabPage_source.Text = "源文件"; this.tabPage_source.UseVisualStyleBackColor = true; @@ -116,26 +119,29 @@ private void InitializeComponent() // this.textBox_source_range.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.textBox_source_range.Location = new System.Drawing.Point(125, 179); + this.textBox_source_range.Location = new System.Drawing.Point(188, 268); + this.textBox_source_range.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.textBox_source_range.Name = "textBox_source_range"; - this.textBox_source_range.Size = new System.Drawing.Size(258, 21); + this.textBox_source_range.Size = new System.Drawing.Size(385, 28); this.textBox_source_range.TabIndex = 15; // // label4 // this.label4.AutoSize = true; - this.label4.Location = new System.Drawing.Point(6, 182); + this.label4.Location = new System.Drawing.Point(9, 273); + this.label4.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.label4.Name = "label4"; - this.label4.Size = new System.Drawing.Size(101, 12); + this.label4.Size = new System.Drawing.Size(152, 18); this.label4.TabIndex = 14; this.label4.Text = "导入记录范围(&R):"; // // button_getObjectDirectoryName // this.button_getObjectDirectoryName.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.button_getObjectDirectoryName.Location = new System.Drawing.Point(389, 128); + this.button_getObjectDirectoryName.Location = new System.Drawing.Point(584, 192); + this.button_getObjectDirectoryName.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.button_getObjectDirectoryName.Name = "button_getObjectDirectoryName"; - this.button_getObjectDirectoryName.Size = new System.Drawing.Size(39, 23); + this.button_getObjectDirectoryName.Size = new System.Drawing.Size(58, 34); this.button_getObjectDirectoryName.TabIndex = 13; this.button_getObjectDirectoryName.Text = "..."; this.button_getObjectDirectoryName.UseVisualStyleBackColor = true; @@ -145,26 +151,29 @@ private void InitializeComponent() // this.textBox_objectDirectoryName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.textBox_objectDirectoryName.Location = new System.Drawing.Point(27, 130); + this.textBox_objectDirectoryName.Location = new System.Drawing.Point(40, 195); + this.textBox_objectDirectoryName.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.textBox_objectDirectoryName.Name = "textBox_objectDirectoryName"; - this.textBox_objectDirectoryName.Size = new System.Drawing.Size(356, 21); + this.textBox_objectDirectoryName.Size = new System.Drawing.Size(532, 28); this.textBox_objectDirectoryName.TabIndex = 12; // // label3 // this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(25, 115); + this.label3.Location = new System.Drawing.Point(38, 172); + this.label3.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(101, 12); + this.label3.Size = new System.Drawing.Size(152, 18); this.label3.TabIndex = 11; this.label3.Text = "对象文件目录(&O):"; // // button_source_findFileName // this.button_source_findFileName.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.button_source_findFileName.Location = new System.Drawing.Point(389, 19); + this.button_source_findFileName.Location = new System.Drawing.Point(584, 28); + this.button_source_findFileName.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.button_source_findFileName.Name = "button_source_findFileName"; - this.button_source_findFileName.Size = new System.Drawing.Size(39, 23); + this.button_source_findFileName.Size = new System.Drawing.Size(58, 34); this.button_source_findFileName.TabIndex = 7; this.button_source_findFileName.Text = "..."; this.button_source_findFileName.UseVisualStyleBackColor = true; @@ -174,17 +183,19 @@ private void InitializeComponent() // this.textBox_source_fileName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.textBox_source_fileName.Location = new System.Drawing.Point(125, 21); + this.textBox_source_fileName.Location = new System.Drawing.Point(188, 32); + this.textBox_source_fileName.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.textBox_source_fileName.Name = "textBox_source_fileName"; - this.textBox_source_fileName.Size = new System.Drawing.Size(258, 21); + this.textBox_source_fileName.Size = new System.Drawing.Size(385, 28); this.textBox_source_fileName.TabIndex = 6; // // label2 // this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(6, 24); + this.label2.Location = new System.Drawing.Point(9, 36); + this.label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(113, 12); + this.label2.Size = new System.Drawing.Size(170, 18); this.label2.TabIndex = 5; this.label2.Text = "书目转储文件名(&D):"; // @@ -193,9 +204,10 @@ private void InitializeComponent() this.checkBox_subRecords_object.AutoSize = true; this.checkBox_subRecords_object.Checked = true; this.checkBox_subRecords_object.CheckState = System.Windows.Forms.CheckState.Checked; - this.checkBox_subRecords_object.Location = new System.Drawing.Point(8, 96); + this.checkBox_subRecords_object.Location = new System.Drawing.Point(12, 144); + this.checkBox_subRecords_object.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.checkBox_subRecords_object.Name = "checkBox_subRecords_object"; - this.checkBox_subRecords_object.Size = new System.Drawing.Size(66, 16); + this.checkBox_subRecords_object.Size = new System.Drawing.Size(97, 22); this.checkBox_subRecords_object.TabIndex = 4; this.checkBox_subRecords_object.Text = "对象(&O)"; this.checkBox_subRecords_object.UseVisualStyleBackColor = true; @@ -206,9 +218,10 @@ private void InitializeComponent() this.checkBox_subRecords_comment.AutoSize = true; this.checkBox_subRecords_comment.Checked = true; this.checkBox_subRecords_comment.CheckState = System.Windows.Forms.CheckState.Checked; - this.checkBox_subRecords_comment.Location = new System.Drawing.Point(276, 54); + this.checkBox_subRecords_comment.Location = new System.Drawing.Point(414, 81); + this.checkBox_subRecords_comment.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.checkBox_subRecords_comment.Name = "checkBox_subRecords_comment"; - this.checkBox_subRecords_comment.Size = new System.Drawing.Size(66, 16); + this.checkBox_subRecords_comment.Size = new System.Drawing.Size(97, 22); this.checkBox_subRecords_comment.TabIndex = 3; this.checkBox_subRecords_comment.Text = "评注(&C)"; this.checkBox_subRecords_comment.UseVisualStyleBackColor = true; @@ -218,9 +231,10 @@ private void InitializeComponent() this.checkBox_subRecords_issue.AutoSize = true; this.checkBox_subRecords_issue.Checked = true; this.checkBox_subRecords_issue.CheckState = System.Windows.Forms.CheckState.Checked; - this.checkBox_subRecords_issue.Location = new System.Drawing.Point(194, 54); + this.checkBox_subRecords_issue.Location = new System.Drawing.Point(291, 81); + this.checkBox_subRecords_issue.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.checkBox_subRecords_issue.Name = "checkBox_subRecords_issue"; - this.checkBox_subRecords_issue.Size = new System.Drawing.Size(54, 16); + this.checkBox_subRecords_issue.Size = new System.Drawing.Size(79, 22); this.checkBox_subRecords_issue.TabIndex = 2; this.checkBox_subRecords_issue.Text = "期(&I)"; this.checkBox_subRecords_issue.UseVisualStyleBackColor = true; @@ -230,9 +244,10 @@ private void InitializeComponent() this.checkBox_subRecords_order.AutoSize = true; this.checkBox_subRecords_order.Checked = true; this.checkBox_subRecords_order.CheckState = System.Windows.Forms.CheckState.Checked; - this.checkBox_subRecords_order.Location = new System.Drawing.Point(98, 54); + this.checkBox_subRecords_order.Location = new System.Drawing.Point(147, 81); + this.checkBox_subRecords_order.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.checkBox_subRecords_order.Name = "checkBox_subRecords_order"; - this.checkBox_subRecords_order.Size = new System.Drawing.Size(66, 16); + this.checkBox_subRecords_order.Size = new System.Drawing.Size(97, 22); this.checkBox_subRecords_order.TabIndex = 1; this.checkBox_subRecords_order.Text = "订购(&O)"; this.checkBox_subRecords_order.UseVisualStyleBackColor = true; @@ -242,9 +257,10 @@ private void InitializeComponent() this.checkBox_subRecords_entity.AutoSize = true; this.checkBox_subRecords_entity.Checked = true; this.checkBox_subRecords_entity.CheckState = System.Windows.Forms.CheckState.Checked; - this.checkBox_subRecords_entity.Location = new System.Drawing.Point(8, 54); + this.checkBox_subRecords_entity.Location = new System.Drawing.Point(12, 81); + this.checkBox_subRecords_entity.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.checkBox_subRecords_entity.Name = "checkBox_subRecords_entity"; - this.checkBox_subRecords_entity.Size = new System.Drawing.Size(54, 16); + this.checkBox_subRecords_entity.Size = new System.Drawing.Size(79, 22); this.checkBox_subRecords_entity.TabIndex = 0; this.checkBox_subRecords_entity.Text = "册(&E)"; this.checkBox_subRecords_entity.UseVisualStyleBackColor = true; @@ -252,6 +268,7 @@ private void InitializeComponent() // tabPage_convert // this.tabPage_convert.AutoScroll = true; + this.tabPage_convert.Controls.Add(this.checkBox_target_randomItemRegisterNo); this.tabPage_convert.Controls.Add(this.checkBox_convert_addBiblioToItemOnMerging); this.tabPage_convert.Controls.Add(this.textBox_convert_itemBatchNo); this.tabPage_convert.Controls.Add(this.label5); @@ -260,9 +277,10 @@ private void InitializeComponent() this.tabPage_convert.Controls.Add(this.button_convert_initialMapString); this.tabPage_convert.Controls.Add(this.checkBox_convert_refreshRefID); this.tabPage_convert.Controls.Add(this.checkBox_target_randomItemBarcode); - this.tabPage_convert.Location = new System.Drawing.Point(4, 22); + this.tabPage_convert.Location = new System.Drawing.Point(4, 28); + this.tabPage_convert.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.tabPage_convert.Name = "tabPage_convert"; - this.tabPage_convert.Size = new System.Drawing.Size(435, 257); + this.tabPage_convert.Size = new System.Drawing.Size(656, 392); this.tabPage_convert.TabIndex = 3; this.tabPage_convert.Text = "转换"; this.tabPage_convert.UseVisualStyleBackColor = true; @@ -270,35 +288,39 @@ private void InitializeComponent() // checkBox_convert_addBiblioToItemOnMerging // this.checkBox_convert_addBiblioToItemOnMerging.AutoSize = true; - this.checkBox_convert_addBiblioToItemOnMerging.Location = new System.Drawing.Point(177, 38); + this.checkBox_convert_addBiblioToItemOnMerging.Location = new System.Drawing.Point(266, 86); + this.checkBox_convert_addBiblioToItemOnMerging.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.checkBox_convert_addBiblioToItemOnMerging.Name = "checkBox_convert_addBiblioToItemOnMerging"; - this.checkBox_convert_addBiblioToItemOnMerging.Size = new System.Drawing.Size(204, 16); + this.checkBox_convert_addBiblioToItemOnMerging.Size = new System.Drawing.Size(304, 22); this.checkBox_convert_addBiblioToItemOnMerging.TabIndex = 16; this.checkBox_convert_addBiblioToItemOnMerging.Text = "为合并的册记录添加书目信息元素"; this.checkBox_convert_addBiblioToItemOnMerging.UseVisualStyleBackColor = true; // // textBox_convert_itemBatchNo // - this.textBox_convert_itemBatchNo.Location = new System.Drawing.Point(103, 82); + this.textBox_convert_itemBatchNo.Location = new System.Drawing.Point(154, 152); + this.textBox_convert_itemBatchNo.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.textBox_convert_itemBatchNo.Name = "textBox_convert_itemBatchNo"; - this.textBox_convert_itemBatchNo.Size = new System.Drawing.Size(186, 21); + this.textBox_convert_itemBatchNo.Size = new System.Drawing.Size(277, 28); this.textBox_convert_itemBatchNo.TabIndex = 15; // // label5 // this.label5.AutoSize = true; - this.label5.Location = new System.Drawing.Point(3, 85); + this.label5.Location = new System.Drawing.Point(4, 157); + this.label5.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.label5.Name = "label5"; - this.label5.Size = new System.Drawing.Size(83, 12); + this.label5.Size = new System.Drawing.Size(125, 18); this.label5.TabIndex = 14; this.label5.Text = "册记录批次号:"; // // checkBox_convert_addBiblioToItem // this.checkBox_convert_addBiblioToItem.AutoSize = true; - this.checkBox_convert_addBiblioToItem.Location = new System.Drawing.Point(3, 38); + this.checkBox_convert_addBiblioToItem.Location = new System.Drawing.Point(4, 86); + this.checkBox_convert_addBiblioToItem.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.checkBox_convert_addBiblioToItem.Name = "checkBox_convert_addBiblioToItem"; - this.checkBox_convert_addBiblioToItem.Size = new System.Drawing.Size(168, 16); + this.checkBox_convert_addBiblioToItem.Size = new System.Drawing.Size(250, 22); this.checkBox_convert_addBiblioToItem.TabIndex = 13; this.checkBox_convert_addBiblioToItem.Text = "为册记录添加书目信息元素"; this.checkBox_convert_addBiblioToItem.UseVisualStyleBackColor = true; @@ -307,29 +329,32 @@ private void InitializeComponent() // this.panel_map.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.panel_map.Location = new System.Drawing.Point(3, 138); + this.panel_map.Location = new System.Drawing.Point(4, 236); + this.panel_map.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.panel_map.Name = "panel_map"; - this.panel_map.Size = new System.Drawing.Size(293, 122); + this.panel_map.Size = new System.Drawing.Size(687, 183); this.panel_map.TabIndex = 12; // // button_convert_initialMapString // - this.button_convert_initialMapString.Location = new System.Drawing.Point(3, 109); + this.button_convert_initialMapString.Location = new System.Drawing.Point(4, 193); + this.button_convert_initialMapString.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.button_convert_initialMapString.Name = "button_convert_initialMapString"; - this.button_convert_initialMapString.Size = new System.Drawing.Size(286, 23); + this.button_convert_initialMapString.Size = new System.Drawing.Size(429, 34); this.button_convert_initialMapString.TabIndex = 10; this.button_convert_initialMapString.Text = "从数据中获取馆藏地,初始化馆藏地转换表 ..."; this.button_convert_initialMapString.UseVisualStyleBackColor = true; this.button_convert_initialMapString.Click += new System.EventHandler(this.button_convert_initialMapString_Click); // - // checkBox_target_newRefID + // checkBox_convert_refreshRefID // this.checkBox_convert_refreshRefID.AutoSize = true; this.checkBox_convert_refreshRefID.Checked = true; this.checkBox_convert_refreshRefID.CheckState = System.Windows.Forms.CheckState.Checked; - this.checkBox_convert_refreshRefID.Location = new System.Drawing.Point(3, 60); - this.checkBox_convert_refreshRefID.Name = "checkBox_target_newRefID"; - this.checkBox_convert_refreshRefID.Size = new System.Drawing.Size(108, 16); + this.checkBox_convert_refreshRefID.Location = new System.Drawing.Point(4, 119); + this.checkBox_convert_refreshRefID.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.checkBox_convert_refreshRefID.Name = "checkBox_convert_refreshRefID"; + this.checkBox_convert_refreshRefID.Size = new System.Drawing.Size(160, 22); this.checkBox_convert_refreshRefID.TabIndex = 9; this.checkBox_convert_refreshRefID.Text = "重新生成参考ID"; this.checkBox_convert_refreshRefID.UseVisualStyleBackColor = true; @@ -337,9 +362,10 @@ private void InitializeComponent() // checkBox_target_randomItemBarcode // this.checkBox_target_randomItemBarcode.AutoSize = true; - this.checkBox_target_randomItemBarcode.Location = new System.Drawing.Point(3, 16); + this.checkBox_target_randomItemBarcode.Location = new System.Drawing.Point(4, 24); + this.checkBox_target_randomItemBarcode.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.checkBox_target_randomItemBarcode.Name = "checkBox_target_randomItemBarcode"; - this.checkBox_target_randomItemBarcode.Size = new System.Drawing.Size(360, 16); + this.checkBox_target_randomItemBarcode.Size = new System.Drawing.Size(538, 22); this.checkBox_target_randomItemBarcode.TabIndex = 8; this.checkBox_target_randomItemBarcode.Text = "为册条码号增加随机后缀(以避免转入的册条码号和系统内重复)"; this.checkBox_target_randomItemBarcode.UseVisualStyleBackColor = true; @@ -356,10 +382,11 @@ private void InitializeComponent() this.tabPage_target.Controls.Add(this.button_target_simulateImport); this.tabPage_target.Controls.Add(this.comboBox_target_targetBiblioDbName); this.tabPage_target.Controls.Add(this.label1); - this.tabPage_target.Location = new System.Drawing.Point(4, 22); + this.tabPage_target.Location = new System.Drawing.Point(4, 28); + this.tabPage_target.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.tabPage_target.Name = "tabPage_target"; - this.tabPage_target.Padding = new System.Windows.Forms.Padding(3); - this.tabPage_target.Size = new System.Drawing.Size(435, 257); + this.tabPage_target.Padding = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.tabPage_target.Size = new System.Drawing.Size(656, 392); this.tabPage_target.TabIndex = 0; this.tabPage_target.Text = "目标库"; this.tabPage_target.UseVisualStyleBackColor = true; @@ -367,28 +394,31 @@ private void InitializeComponent() // textBox_target_dbNameList // this.textBox_target_dbNameList.AcceptsReturn = true; - this.textBox_target_dbNameList.Location = new System.Drawing.Point(245, 83); + this.textBox_target_dbNameList.Location = new System.Drawing.Point(368, 124); + this.textBox_target_dbNameList.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.textBox_target_dbNameList.Multiline = true; this.textBox_target_dbNameList.Name = "textBox_target_dbNameList"; this.textBox_target_dbNameList.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; - this.textBox_target_dbNameList.Size = new System.Drawing.Size(176, 149); + this.textBox_target_dbNameList.Size = new System.Drawing.Size(262, 222); this.textBox_target_dbNameList.TabIndex = 11; // // label6 // this.label6.AutoSize = true; - this.label6.Location = new System.Drawing.Point(243, 67); + this.label6.Location = new System.Drawing.Point(364, 100); + this.label6.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.label6.Name = "label6"; - this.label6.Size = new System.Drawing.Size(143, 12); + this.label6.Size = new System.Drawing.Size(215, 18); this.label6.TabIndex = 10; this.label6.Text = "自动选择目标数据库顺序:"; // // checkBox_target_dontChangeOperations // this.checkBox_target_dontChangeOperations.AutoSize = true; - this.checkBox_target_dontChangeOperations.Location = new System.Drawing.Point(9, 144); + this.checkBox_target_dontChangeOperations.Location = new System.Drawing.Point(14, 216); + this.checkBox_target_dontChangeOperations.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.checkBox_target_dontChangeOperations.Name = "checkBox_target_dontChangeOperations"; - this.checkBox_target_dontChangeOperations.Size = new System.Drawing.Size(150, 16); + this.checkBox_target_dontChangeOperations.Size = new System.Drawing.Size(223, 22); this.checkBox_target_dontChangeOperations.TabIndex = 9; this.checkBox_target_dontChangeOperations.Text = "不修改 operation 元素"; this.checkBox_target_dontChangeOperations.UseVisualStyleBackColor = true; @@ -396,9 +426,10 @@ private void InitializeComponent() // checkBox_target_suppressOperLog // this.checkBox_target_suppressOperLog.AutoSize = true; - this.checkBox_target_suppressOperLog.Location = new System.Drawing.Point(9, 122); + this.checkBox_target_suppressOperLog.Location = new System.Drawing.Point(14, 183); + this.checkBox_target_suppressOperLog.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.checkBox_target_suppressOperLog.Name = "checkBox_target_suppressOperLog"; - this.checkBox_target_suppressOperLog.Size = new System.Drawing.Size(108, 16); + this.checkBox_target_suppressOperLog.Size = new System.Drawing.Size(160, 22); this.checkBox_target_suppressOperLog.TabIndex = 8; this.checkBox_target_suppressOperLog.Text = "不写入操作日志"; this.checkBox_target_suppressOperLog.UseVisualStyleBackColor = true; @@ -406,9 +437,10 @@ private void InitializeComponent() // checkBox_target_dontSearchDup // this.checkBox_target_dontSearchDup.AutoSize = true; - this.checkBox_target_dontSearchDup.Location = new System.Drawing.Point(9, 100); + this.checkBox_target_dontSearchDup.Location = new System.Drawing.Point(14, 150); + this.checkBox_target_dontSearchDup.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.checkBox_target_dontSearchDup.Name = "checkBox_target_dontSearchDup"; - this.checkBox_target_dontSearchDup.Size = new System.Drawing.Size(60, 16); + this.checkBox_target_dontSearchDup.Size = new System.Drawing.Size(88, 22); this.checkBox_target_dontSearchDup.TabIndex = 7; this.checkBox_target_dontSearchDup.Text = "不查重"; this.checkBox_target_dontSearchDup.UseVisualStyleBackColor = true; @@ -416,18 +448,20 @@ private void InitializeComponent() // checkBox_target_restoreOldID // this.checkBox_target_restoreOldID.AutoSize = true; - this.checkBox_target_restoreOldID.Location = new System.Drawing.Point(9, 64); + this.checkBox_target_restoreOldID.Location = new System.Drawing.Point(14, 96); + this.checkBox_target_restoreOldID.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.checkBox_target_restoreOldID.Name = "checkBox_target_restoreOldID"; - this.checkBox_target_restoreOldID.Size = new System.Drawing.Size(138, 16); + this.checkBox_target_restoreOldID.Size = new System.Drawing.Size(205, 22); this.checkBox_target_restoreOldID.TabIndex = 6; this.checkBox_target_restoreOldID.Text = "恢复到原先的记录 ID"; this.checkBox_target_restoreOldID.UseVisualStyleBackColor = true; // // button_target_simulateImport // - this.button_target_simulateImport.Location = new System.Drawing.Point(9, 209); + this.button_target_simulateImport.Location = new System.Drawing.Point(14, 314); + this.button_target_simulateImport.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.button_target_simulateImport.Name = "button_target_simulateImport"; - this.button_target_simulateImport.Size = new System.Drawing.Size(113, 23); + this.button_target_simulateImport.Size = new System.Drawing.Size(170, 34); this.button_target_simulateImport.TabIndex = 5; this.button_target_simulateImport.Text = "模拟导入"; this.button_target_simulateImport.UseVisualStyleBackColor = true; @@ -437,26 +471,29 @@ private void InitializeComponent() // this.comboBox_target_targetBiblioDbName.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.comboBox_target_targetBiblioDbName.FormattingEnabled = true; - this.comboBox_target_targetBiblioDbName.Location = new System.Drawing.Point(126, 22); + this.comboBox_target_targetBiblioDbName.Location = new System.Drawing.Point(189, 33); + this.comboBox_target_targetBiblioDbName.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.comboBox_target_targetBiblioDbName.Name = "comboBox_target_targetBiblioDbName"; - this.comboBox_target_targetBiblioDbName.Size = new System.Drawing.Size(182, 20); + this.comboBox_target_targetBiblioDbName.Size = new System.Drawing.Size(271, 26); this.comboBox_target_targetBiblioDbName.TabIndex = 1; // // label1 // this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(7, 25); + this.label1.Location = new System.Drawing.Point(10, 38); + this.label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(101, 12); + this.label1.Size = new System.Drawing.Size(152, 18); this.label1.TabIndex = 0; this.label1.Text = "目标书目库名(&B):"; // // tabPage_run // this.tabPage_run.Controls.Add(this.webBrowser1); - this.tabPage_run.Location = new System.Drawing.Point(4, 22); + this.tabPage_run.Location = new System.Drawing.Point(4, 28); + this.tabPage_run.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.tabPage_run.Name = "tabPage_run"; - this.tabPage_run.Size = new System.Drawing.Size(435, 257); + this.tabPage_run.Size = new System.Drawing.Size(656, 392); this.tabPage_run.TabIndex = 2; this.tabPage_run.Text = "导入"; this.tabPage_run.UseVisualStyleBackColor = true; @@ -465,31 +502,43 @@ private void InitializeComponent() // this.webBrowser1.Dock = System.Windows.Forms.DockStyle.Fill; this.webBrowser1.Location = new System.Drawing.Point(0, 0); - this.webBrowser1.MinimumSize = new System.Drawing.Size(20, 20); + this.webBrowser1.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.webBrowser1.MinimumSize = new System.Drawing.Size(30, 30); this.webBrowser1.Name = "webBrowser1"; - this.webBrowser1.Size = new System.Drawing.Size(435, 257); + this.webBrowser1.Size = new System.Drawing.Size(656, 392); this.webBrowser1.TabIndex = 0; // // button_next // this.button_next.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.button_next.Font = new System.Drawing.Font("宋体", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134))); - this.button_next.Location = new System.Drawing.Point(369, 301); - this.button_next.Margin = new System.Windows.Forms.Padding(2); + this.button_next.Location = new System.Drawing.Point(554, 452); this.button_next.Name = "button_next"; - this.button_next.Size = new System.Drawing.Size(83, 22); + this.button_next.Size = new System.Drawing.Size(124, 33); this.button_next.TabIndex = 2; this.button_next.Text = "下一步(&N)"; this.button_next.UseVisualStyleBackColor = true; this.button_next.Click += new System.EventHandler(this.button_next_Click); // + // checkBox_target_randomItemRegisterNo + // + this.checkBox_target_randomItemRegisterNo.AutoSize = true; + this.checkBox_target_randomItemRegisterNo.Location = new System.Drawing.Point(4, 54); + this.checkBox_target_randomItemRegisterNo.Margin = new System.Windows.Forms.Padding(4); + this.checkBox_target_randomItemRegisterNo.Name = "checkBox_target_randomItemRegisterNo"; + this.checkBox_target_randomItemRegisterNo.Size = new System.Drawing.Size(502, 22); + this.checkBox_target_randomItemRegisterNo.TabIndex = 17; + this.checkBox_target_randomItemRegisterNo.Text = "为登录号增加随机后缀(以避免转入的登录号和系统内重复)"; + this.checkBox_target_randomItemRegisterNo.UseVisualStyleBackColor = true; + // // ImportExportForm // - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 18F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(468, 334); + this.ClientSize = new System.Drawing.Size(702, 501); this.Controls.Add(this.button_next); this.Controls.Add(this.tabControl_main); + this.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); this.Name = "ImportExportForm"; this.ShowIcon = false; this.ShowInTaskbar = false; @@ -548,5 +597,6 @@ private void InitializeComponent() private System.Windows.Forms.TextBox textBox_target_dbNameList; private System.Windows.Forms.Label label6; private System.Windows.Forms.CheckBox checkBox_convert_addBiblioToItemOnMerging; + private System.Windows.Forms.CheckBox checkBox_target_randomItemRegisterNo; } } \ No newline at end of file diff --git a/dp2Circulation/IO/ImportExportForm.cs b/dp2Circulation/IO/ImportExportForm.cs index 81c791f74..08e7c8f02 100644 --- a/dp2Circulation/IO/ImportExportForm.cs +++ b/dp2Circulation/IO/ImportExportForm.cs @@ -253,6 +253,10 @@ void DoImport(string strStyle) { return checkBox_target_randomItemBarcode.Checked; })); + info.RandomItemRegisterNo = (bool)this.Invoke(new Func(() => + { + return checkBox_target_randomItemRegisterNo.Checked; + })); info.AddBiblioToItem = (bool)this.Invoke(new Func(() => { return this.checkBox_convert_addBiblioToItem.Checked; @@ -361,6 +365,7 @@ void DoImport(string strStyle) this._locationTable.Clear(); this._itemBarcodeTable.Clear(); + this._itemRegisterNoTable.Clear(); this.ClearHtml(); @@ -1072,7 +1077,7 @@ static int ModifyTitle(ref string strBiblioXml, if (strMarcSyntax == "unimarc") { string strValue = record.select("field[@name='200']/subfield[@name='a']").FirstContent; - strValue += "_" + Guid.NewGuid().ToString(); + strValue += "_" + NewGuid().ToString(); record.setFirstSubfield("200", "a", strValue); bChanged = true; } @@ -1080,7 +1085,7 @@ static int ModifyTitle(ref string strBiblioXml, { // TODO: 其实需要把子字段内容最末一个符号字符后移 string strValue = record.select("field[@name='245']/subfield[@name='a']").FirstContent; - strValue += "_" + Guid.NewGuid().ToString(); + strValue += "_" + NewGuid().ToString(); record.setFirstSubfield("245", "a", strValue); bChanged = true; } @@ -1292,19 +1297,24 @@ static bool FillEmptyRefID(ref string strRefID) { if (String.IsNullOrEmpty(strRefID) == true) { - strRefID = Guid.NewGuid().ToString(); + strRefID = NewGuid().ToString(); return true; } return false; } + static string NewGuid() + { + return ShortGuid.NewGuid(); + } + static void RefreshRefID(Hashtable table, ref string strRefID) { #if NO if (String.IsNullOrEmpty(strRefID) == true) { - strRefID = Guid.NewGuid().ToString(); + strRefID = NewGuid().ToString(); return; } #endif @@ -1322,7 +1332,7 @@ static void RefreshRefID(Hashtable table, ref string strRefID) } else { - strNewRefID = Guid.NewGuid().ToString(); + strNewRefID = NewGuid().ToString(); table[strRefID] = strNewRefID; strRefID = strNewRefID; } @@ -1335,7 +1345,17 @@ static void RandomItemBarcode(XmlDocument item_dom) if (string.IsNullOrEmpty(strItemBarcode) == false) DomUtil.SetElementText(item_dom.DocumentElement, "barcode", - strItemBarcode + "_" + Guid.NewGuid().ToString().ToUpper()); + strItemBarcode + "_" + NewGuid().ToString().ToUpper()); + } + + static void RandomItemRegisterNo(XmlDocument item_dom) + { + string strRegisterNo = DomUtil.GetElementText(item_dom.DocumentElement, + "registerNo"); + if (string.IsNullOrEmpty(strRegisterNo) == false) + DomUtil.SetElementText(item_dom.DocumentElement, + "registerNo", + strRegisterNo + "_" + NewGuid().ToString().ToUpper()); } static bool AddBiblioToItem(XmlDocument item_dom, string strBiblioXml) @@ -1433,7 +1453,15 @@ void DoItems(List item_xmls, ProcessInfo info) else { // 针对册条码号进行文件空间内查重 - SearchDupOnFileScope(item_dom, dupInfo); + SearchItemBarcodeDupOnFileScope(item_dom, dupInfo); + } + + if (info.RandomItemRegisterNo) + RandomItemRegisterNo(item_dom); + else + { + // 针对登录号进行文件空间内查重 + SearchItemRegisterNoDupOnFileScope(item_dom, dupInfo); } string strLocation1 = DomUtil.GetElementText(item_dom.DocumentElement, "location"); @@ -1794,7 +1822,7 @@ public override void OutputText(string strText, int nWarningLevel = 0) Hashtable _itemBarcodeTable = new Hashtable(); // itemBarcode --> count - void SearchDupOnFileScope(XmlDocument item_dom, StringBuilder errorInfo) + void SearchItemBarcodeDupOnFileScope(XmlDocument item_dom, StringBuilder errorInfo) { string strItemBarcode = DomUtil.GetElementText(item_dom.DocumentElement, "barcode"); if (string.IsNullOrEmpty(strItemBarcode) == true) @@ -1813,6 +1841,28 @@ void SearchDupOnFileScope(XmlDocument item_dom, StringBuilder errorInfo) errorInfo.Append("册条码号 '" + strItemBarcode + "' 在源文件中发生重复(出现 " + v + " 次)"); } + // 2018/11/16 + Hashtable _itemRegisterNoTable = new Hashtable(); // registerNo --> count + + void SearchItemRegisterNoDupOnFileScope(XmlDocument item_dom, StringBuilder errorInfo) + { + string strRegisterNo = DomUtil.GetElementText(item_dom.DocumentElement, "registerNo"); + if (string.IsNullOrEmpty(strRegisterNo) == true) + return; + object o = _itemRegisterNoTable[strRegisterNo]; + if (o == null) + { + _itemRegisterNoTable[strRegisterNo] = 1; + return; + } + + int v = (int)o; + v++; + _itemRegisterNoTable[strRegisterNo] = v; + + errorInfo.Append("登录号 '" + strRegisterNo + "' 在源文件中发生重复(出现 " + v + " 次)"); + } + static bool ConvertLocation(List table, ref string location) { foreach (TwoString s in table) @@ -1868,6 +1918,10 @@ class ProcessInfo // 是否为册条码号加上随机的后缀字符串 public bool RandomItemBarcode = false; + // 2018/11/16 + // 是否为登录号加上随机的后缀字符串 + public bool RandomItemRegisterNo = false; + // 是否为册记录自动添加书目元素。(注:如果册记录中本来有了这个元素就不添加了) public bool AddBiblioToItem = false; @@ -2039,7 +2093,7 @@ public string UiState controls.Add(this.checkBox_target_dontChangeOperations); controls.Add(this.textBox_target_dbNameList); - + controls.Add(this.checkBox_target_randomItemRegisterNo); return GuiState.GetUiState(controls); } set @@ -2070,6 +2124,7 @@ public string UiState controls.Add(this.checkBox_target_dontChangeOperations); controls.Add(this.textBox_target_dbNameList); + controls.Add(this.checkBox_target_randomItemRegisterNo); GuiState.SetUiState(controls, value); } } diff --git a/dp2Circulation/ItemHandOver/ItemHandoverForm.cs b/dp2Circulation/ItemHandOver/ItemHandoverForm.cs index ce1602373..9c284efca 100644 --- a/dp2Circulation/ItemHandOver/ItemHandoverForm.cs +++ b/dp2Circulation/ItemHandOver/ItemHandoverForm.cs @@ -6898,6 +6898,12 @@ internal void GetNewlyLines(out List items, foreach (ListViewItem item in this.listView_in.Items) { + // 2018/11/6 + // 已经有了出错信息的,不再列入 + string strErrorInfo = ListViewUtil.GetItemText(item, COLUMN_ERRORINFO); + if (string.IsNullOrEmpty(strErrorInfo) == false) + continue; + string strRecPath = ListViewUtil.GetItemText(item, COLUMN_RECPATH); if (string.IsNullOrEmpty(strRecPath) == false) continue; @@ -6981,7 +6987,21 @@ public override void Worker() out recpaths, out strError); if (nRet == -1) + { + // 为每一行加入错误信息,避免线程重复报错 + int i = 0; + foreach(ListViewItem item in items) + { + string barcode = barcodes[i]; + ListViewItem temp = item; + this.Container.SetError(item.ListView, + ref temp, + barcode, + strError); + i++; + } goto ERROR1; + } Debug.Assert(barcodes.Count == recpaths.Count, ""); @@ -7004,6 +7024,8 @@ public override void Worker() ERROR1: // Safe_setError(this.Container.listView_in, strError); + // 2018/11/6 + this.Container.ShowMessage(strError, "red", true); return; } diff --git a/dp2Circulation/Label/LabelPrintForm.cs b/dp2Circulation/Label/LabelPrintForm.cs index f3337a59a..ee980a19d 100644 --- a/dp2Circulation/Label/LabelPrintForm.cs +++ b/dp2Circulation/Label/LabelPrintForm.cs @@ -365,14 +365,22 @@ private void textBox_labelFile_labelFilename_TextChanged(object sender, EventArg return; } + int nRet = CheckBlankLabel(this.textBox_labelFile_labelFilename.Text, +out string strError); + if (nRet == -1 || nRet == 1) + this.Invoke((Action)(() => + { + MessageBox.Show(this, strError); + })); + // 能自动识别文件内容的编码方式的读入文本文件内容模块 // return: // -1 出错 // 0 文件不存在 // 1 文件存在 - int nRet = Global.ReadTextFileContent(this.textBox_labelFile_labelFilename.Text, + nRet = Global.ReadTextFileContent(this.textBox_labelFile_labelFilename.Text, out string strContent, - out string strError); + out strError); if (nRet == 1) this.textBox_labelFile_content.Text = strContent; else @@ -381,6 +389,59 @@ private void textBox_labelFile_labelFilename_TextChanged(object sender, EventArg BeginWatcher(); } + // 检查是否有空标签 + // return: + // -1 出错 + // 0 没有发现空标签 + // 1 发现有空标签 + public static int CheckBlankLabel(string strFilePath, + out string strError) + { + strError = ""; + + if (File.Exists(strFilePath) == false) + { + strError = "文件 '" + strFilePath + "' 不存在"; + return 0; + } + + Encoding encoding = FileUtil.DetectTextFileEncoding(strFilePath); + + try + { + using (FileStream file = File.Open( + strFilePath, + FileMode.Open, + FileAccess.Read, + FileShare.ReadWrite)) + using (StreamReader sr = new StreamReader(file, encoding)) + { + string prev_line = ""; + for (; ; ) + { + string strLine = sr.ReadLine(); + if (strLine == null) + break; + strLine = strLine.Trim(); + if (strLine == "***" && prev_line == "***") + { + strError = "文件中发现有紧邻的 *** 行"; + return 1; + } + + prev_line = strLine; + } + } + } + catch (Exception ex) + { + strError = "打开或读入文件 '" + strFilePath + "' 时出错: " + ex.Message; + return -1; + } + + return 0; + } + private void button_printPreview_Click(object sender, EventArgs e) { if (this.tabControl_main.SelectedTab == this.tabPage_labelFile) @@ -3327,7 +3388,7 @@ void BeginWatcher() _wather.EnableRaisingEvents = true; } - catch(Exception ex) + catch (Exception ex) { MessageBox.Show(this, "BeginWatcher() exception: " + ExceptionUtil.GetAutoText(ex)); } diff --git a/dp2Circulation/ManageDatabase/BiblioDatabaseDialog.Designer.cs b/dp2Circulation/ManageDatabase/BiblioDatabaseDialog.Designer.cs index 4c988da95..4dae20e2f 100644 --- a/dp2Circulation/ManageDatabase/BiblioDatabaseDialog.Designer.cs +++ b/dp2Circulation/ManageDatabase/BiblioDatabaseDialog.Designer.cs @@ -266,7 +266,7 @@ private void InitializeComponent() this.tabControl1.Controls.Add(this.tabPage_normal); this.tabControl1.Controls.Add(this.tabPage_replicate); this.tabControl1.Location = new System.Drawing.Point(18, 18); - this.tabControl1.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.tabControl1.Margin = new System.Windows.Forms.Padding(4); this.tabControl1.Name = "tabControl1"; this.tabControl1.SelectedIndex = 0; this.tabControl1.Size = new System.Drawing.Size(442, 450); @@ -293,9 +293,9 @@ private void InitializeComponent() this.tabPage_normal.Controls.Add(this.label_marcSyntax); this.tabPage_normal.Controls.Add(this.comboBox_syntax); this.tabPage_normal.Location = new System.Drawing.Point(4, 28); - this.tabPage_normal.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.tabPage_normal.Margin = new System.Windows.Forms.Padding(4); this.tabPage_normal.Name = "tabPage_normal"; - this.tabPage_normal.Padding = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.tabPage_normal.Padding = new System.Windows.Forms.Padding(4); this.tabPage_normal.Size = new System.Drawing.Size(434, 418); this.tabPage_normal.TabIndex = 0; this.tabPage_normal.Text = "一般定义"; @@ -309,9 +309,9 @@ private void InitializeComponent() this.tabPage_replicate.Controls.Add(this.label10); this.tabPage_replicate.Controls.Add(this.comboBox_replication_dbName); this.tabPage_replicate.Location = new System.Drawing.Point(4, 28); - this.tabPage_replicate.Margin = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.tabPage_replicate.Margin = new System.Windows.Forms.Padding(4); this.tabPage_replicate.Name = "tabPage_replicate"; - this.tabPage_replicate.Padding = new System.Windows.Forms.Padding(4, 4, 4, 4); + this.tabPage_replicate.Padding = new System.Windows.Forms.Padding(4); this.tabPage_replicate.Size = new System.Drawing.Size(434, 418); this.tabPage_replicate.TabIndex = 1; this.tabPage_replicate.Text = "同步"; diff --git a/dp2Circulation/ManageDatabase/BiblioDatabaseDialog.cs b/dp2Circulation/ManageDatabase/BiblioDatabaseDialog.cs index 2f544c026..7a9c623ac 100644 --- a/dp2Circulation/ManageDatabase/BiblioDatabaseDialog.cs +++ b/dp2Circulation/ManageDatabase/BiblioDatabaseDialog.cs @@ -1,9 +1,5 @@ using System; using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Text; using System.Windows.Forms; using System.Xml; using System.Diagnostics; @@ -1582,5 +1578,6 @@ private void comboBox_replication_dbName_DropDown(object sender, EventArgs e) ERROR1: MessageBox.Show(this, strError); } + } } \ No newline at end of file diff --git a/dp2Circulation/ManageDatabase/ManagerForm.cs b/dp2Circulation/ManageDatabase/ManagerForm.cs index 7d8994441..ce41f6657 100644 --- a/dp2Circulation/ManageDatabase/ManagerForm.cs +++ b/dp2Circulation/ManageDatabase/ManagerForm.cs @@ -313,6 +313,8 @@ void Initial() { MessageBox.Show(this, strError); } + + ActivateHelpUrl(); } #if NO @@ -880,7 +882,7 @@ private void ToolStripMenuItem_createBiblioDatabase_Click(object sender, EventAr { BiblioDatabaseDialog dlg = new BiblioDatabaseDialog(); MainForm.SetControlFont(dlg, this.Font, false); - + dlg.HelpRequested += Dlg_createBiblioDatabase_HelpRequested; dlg.Text = "创建新书目库"; dlg.ManagerForm = this; dlg.CreateMode = true; @@ -906,6 +908,11 @@ private void ToolStripMenuItem_createBiblioDatabase_Click(object sender, EventAr Program.MainForm.StartPrepareNames(false, false); } + private void Dlg_createBiblioDatabase_HelpRequested(object sender, HelpEventArgs hlpevent) + { + Process.Start("https://github.com/DigitalPlatform/dp2/wiki/%E5%A6%82%E4%BD%95%E5%88%9B%E5%BB%BA%E6%88%96%E5%88%A0%E9%99%A4%E4%B9%A6%E7%9B%AE%E5%BA%93"); + } + // 创建规范库 private void ToolStripMenuItem_createAuthorityDatabase_Click(object sender, EventArgs e) { @@ -1253,7 +1260,9 @@ private void toolStripButton_deleteDatabase_Click(object sender, EventArgs e) "ManagerForm", MessageBoxButtons.YesNo, MessageBoxIcon.Question, - MessageBoxDefaultButton.Button2); + MessageBoxDefaultButton.Button2, + 0, + "https://github.com/DigitalPlatform/dp2/wiki/%E5%A6%82%E4%BD%95%E5%88%9B%E5%BB%BA%E6%88%96%E5%88%A0%E9%99%A4%E4%B9%A6%E7%9B%AE%E5%BA%93"); // 最好是一个笼统介绍如何删除各种数据库的页面 if (result != DialogResult.Yes) return; @@ -1271,22 +1280,7 @@ private void toolStripButton_deleteDatabase_Click(object sender, EventArgs e) goto ERROR1; } - /* - // 为更新AllDatabaseInfoXml - XmlDocument dom = new XmlDocument(); - try - { - dom.LoadXml(this.AllDatabaseInfoXml); - } - catch (Exception ex) - { - strError = "AllDatabaseInfoXml装入XMLDOM时出错: " + ex.Message; - goto ERROR1; - } - * */ - EnableControls(false); - try { @@ -1298,9 +1292,8 @@ private void toolStripButton_deleteDatabase_Click(object sender, EventArgs e) string strDatabaseName = this.listView_databases.Items[index].Text; - string strOutputInfo = ""; nRet = DeleteDatabase(strDatabaseName, - out strOutputInfo, + out string strOutputInfo, out strError); if (nRet == -1) goto ERROR1; @@ -1498,7 +1491,7 @@ private void menu_recreateDatabase_Click(object sender, EventArgs e) { BiblioDatabaseDialog dlg = new BiblioDatabaseDialog(); MainForm.SetControlFont(dlg, this.Font, false); - + dlg.HelpRequested += Dlg_recreateBiblioDatabase_HelpRequested; dlg.Text = "重新创建书目库"; dlg.ManagerForm = this; dlg.CreateMode = true; @@ -1535,7 +1528,7 @@ private void menu_recreateDatabase_Click(object sender, EventArgs e) { ReaderDatabaseDialog dlg = new ReaderDatabaseDialog(); MainForm.SetControlFont(dlg, this.Font, false); - + dlg.HelpRequested += ReaderDatabaseDialog_HelpRequested; dlg.Text = "重新创建读者库"; dlg.ManagerForm = this; dlg.LibraryCodeList = this.GetLibraryCodeList(); @@ -1624,6 +1617,11 @@ private void menu_recreateDatabase_Click(object sender, EventArgs e) MessageBox.Show(this, strError); } + private void Dlg_recreateBiblioDatabase_HelpRequested(object sender, HelpEventArgs hlpevent) + { + Process.Start("https://github.com/DigitalPlatform/dp2/wiki/%E5%A6%82%E4%BD%95%E5%88%9B%E5%BB%BA%E6%88%96%E5%88%A0%E9%99%A4%E4%B9%A6%E7%9B%AE%E5%BA%93"); + } + // 修改数据库特性 private void toolStripButton_modifyDatabase_Click(object sender, EventArgs e) { @@ -1726,7 +1724,7 @@ private void toolStripButton_modifyDatabase_Click(object sender, EventArgs e) { ReaderDatabaseDialog dlg = new ReaderDatabaseDialog(); MainForm.SetControlFont(dlg, this.Font, false); - + dlg.HelpRequested += ReaderDatabaseDialog_HelpRequested; dlg.Text = "修改读者库特性"; dlg.ManagerForm = this; dlg.LibraryCodeList = this.GetLibraryCodeList(); @@ -2073,7 +2071,7 @@ private void ToolStripMenuItem_createReaderDatabase_Click(object sender, EventAr ReaderDatabaseDialog dlg = new ReaderDatabaseDialog(); MainForm.SetControlFont(dlg, this.Font, false); - + dlg.HelpRequested += ReaderDatabaseDialog_HelpRequested; dlg.Text = "创建新读者库"; dlg.ManagerForm = this; dlg.LibraryCodeList = this.GetLibraryCodeList(); @@ -2105,6 +2103,11 @@ private void ToolStripMenuItem_createReaderDatabase_Click(object sender, EventAr } + private void ReaderDatabaseDialog_HelpRequested(object sender, HelpEventArgs hlpevent) + { + Process.Start("https://github.com/DigitalPlatform/dp2/wiki/%E5%A6%82%E4%BD%95%E5%88%9B%E5%BB%BA%E6%88%96%E5%88%A0%E9%99%A4%E8%AF%BB%E8%80%85%E5%BA%93"); + } + // 创建违约金库 private void ToolStripMenuItem_createAmerceDatabase_Click(object sender, EventArgs e) { @@ -2129,7 +2132,7 @@ int CreateSimpleDatabase(string strType, { SimpleDatabaseDialog dlg = new SimpleDatabaseDialog(); MainForm.SetControlFont(dlg, this.Font, false); - + dlg.HelpRequested += SimpleDatabaseDialog_HelpRequested; string strTypeName = GetTypeName(strType); if (strTypeName == null) strTypeName = strType; @@ -2170,6 +2173,18 @@ int CreateSimpleDatabase(string strType, return 1; } + private void SimpleDatabaseDialog_HelpRequested(object sender, HelpEventArgs hlpevent) + { + SimpleDatabaseDialog dialog = (SimpleDatabaseDialog)sender; + switch (dialog.DatabaseType) + { + case "": + break; + } + + // Process.Start(""); + } + // 创建预约到书库 private void ToolStripMenuItem_createArrivedDatabase_Click(object sender, EventArgs e) { @@ -5485,7 +5500,7 @@ private void toolStripButton_location_new_Click(object sender, EventArgs e) { LocationItemDialog dlg = new LocationItemDialog(); MainForm.SetControlFont(dlg, this.Font, false); - + dlg.HelpRequested += DlgNewLocation_HelpRequested; dlg.CreateMode = true; dlg.LibraryCodeList = this.GetLibraryCodeList(); dlg.ItemBarcodeNullable = true; @@ -5525,6 +5540,11 @@ private void toolStripButton_location_new_Click(object sender, EventArgs e) this.LocationTypesDefChanged = true; } + private void DlgNewLocation_HelpRequested(object sender, HelpEventArgs hlpevent) + { + Process.Start("https://github.com/DigitalPlatform/dp2/wiki/%E5%A6%82%E4%BD%95%E6%96%B0%E5%A2%9E%E9%A6%86%E8%97%8F%E5%9C%B0%E5%B9%B6%E8%AE%BE%E7%BD%AE%E6%98%AF%E5%90%A6%E5%8F%82%E4%B8%8E%E6%B5%81%E9%80%9A"); + } + // 修改馆藏地点事项 private void toolStripButton_location_modify_Click(object sender, EventArgs e) { @@ -5538,7 +5558,7 @@ private void toolStripButton_location_modify_Click(object sender, EventArgs e) LocationItemDialog dlg = new LocationItemDialog(); MainForm.SetControlFont(dlg, this.Font, false); - + dlg.HelpRequested += DlgModifyLocation_HelpRequested; dlg.LibraryCodeList = this.GetLibraryCodeList(); dlg.LibraryCode = ListViewUtil.GetItemText(item, LOCATION_COLUMN_LIBRARYCODE); dlg.LocationString = ListViewUtil.GetItemText(item, LOCATION_COLUMN_ROOM); @@ -5580,6 +5600,11 @@ private void toolStripButton_location_modify_Click(object sender, EventArgs e) MessageBox.Show(this, strError); } + private void DlgModifyLocation_HelpRequested(object sender, HelpEventArgs hlpevent) + { + Process.Start("https://github.com/DigitalPlatform/dp2/wiki/%E5%A6%82%E4%BD%95%E6%96%B0%E5%A2%9E%E9%A6%86%E8%97%8F%E5%9C%B0%E5%B9%B6%E8%AE%BE%E7%BD%AE%E6%98%AF%E5%90%A6%E5%8F%82%E4%B8%8E%E6%B5%81%E9%80%9A"); + } + const int LOCATION_COLUMN_LIBRARYCODE = 0; const int LOCATION_COLUMN_ROOM = 1; const int LOCATION_COLUMN_CANBORROW = 2; @@ -5630,7 +5655,8 @@ private void toolStripButton_location_delete_Click(object sender, EventArgs e) "ManagerForm", MessageBoxButtons.YesNo, MessageBoxIcon.Question, - MessageBoxDefaultButton.Button2); + MessageBoxDefaultButton.Button2, + 0, "https://github.com/DigitalPlatform/dp2/wiki/%E5%A6%82%E4%BD%95%E6%96%B0%E5%A2%9E%E9%A6%86%E8%97%8F%E5%9C%B0%E5%B9%B6%E8%AE%BE%E7%BD%AE%E6%98%AF%E5%90%A6%E5%8F%82%E4%B8%8E%E6%B5%81%E9%80%9A"); if (result != DialogResult.Yes) return; @@ -5901,9 +5927,9 @@ private void toolStripButton_location_down_Click(object sender, EventArgs e) MoveLocationItemUpDown(false); } -#endregion + #endregion -#region 值列表 + #region 值列表 int ListValueTables(out string strError) { @@ -6134,9 +6160,9 @@ private void textBox_valueTables_TextChanged(object sender, EventArgs e) this.ValueTableChanged = true; } -#endregion + #endregion -#region 脚本 + #region 脚本 int ListScript(out string strError) { @@ -6437,9 +6463,9 @@ private void textBox_script_MouseUp(object sender, MouseEventArgs e) } -#endregion + #endregion -#region 种次号 + #region 种次号 private void treeView_zhongcihao_AfterSelect(object sender, TreeViewEventArgs e) { @@ -7399,9 +7425,9 @@ private void toolStripButton_zhongcihao_refresh_Click(object sender, EventArgs e } -#endregion // 种次号 + #endregion // 种次号 -#region 排架体系 + #region 排架体系 private void treeView_arrangement_AfterSelect(object sender, TreeViewEventArgs e) @@ -8097,10 +8123,10 @@ private void treeView_arrangement_MouseUp(object sender, MouseEventArgs e) } -#endregion // 排架体系 + #endregion // 排架体系 -#region 查重 + #region 查重 private void listView_dup_projects_SelectedIndexChanged(object sender, EventArgs e) { @@ -8684,7 +8710,7 @@ private void toolStripButton_newLoanPolicy_refresh_Click(object sender, EventArg } } -#region 日历有关功能 + #region 日历有关功能 private void listView_calendar_MouseUp(object sender, MouseEventArgs e) { @@ -9016,6 +9042,8 @@ private void listView_calendar_SelectedIndexChanged(object sender, EventArgs e) private void tabControl_main_SelectedIndexChanged(object sender, EventArgs e) { + ActivateHelpUrl(); + if (this.tabControl_main.SelectedTab == this.tabPage_kernel && _kernelInitialized == false) { @@ -9050,6 +9078,20 @@ private void tabControl_main_SelectedIndexChanged(object sender, EventArgs e) } } + void ActivateHelpUrl() + { + if (this.tabControl_main.SelectedTab == this.tabPage_databases) + this.HelpUrl = "https://github.com/DigitalPlatform/dp2/wiki/%E5%A6%82%E4%BD%95%E5%88%9B%E5%BB%BA%E6%88%96%E5%88%A0%E9%99%A4%E4%B9%A6%E7%9B%AE%E5%BA%93"; + else if (this.tabControl_main.SelectedTab == this.tabPage_locations) + this.HelpUrl = "https://github.com/DigitalPlatform/dp2/wiki/%E5%A6%82%E4%BD%95%E6%96%B0%E5%A2%9E%E9%A6%86%E8%97%8F%E5%9C%B0%E5%B9%B6%E8%AE%BE%E7%BD%AE%E6%98%AF%E5%90%A6%E5%8F%82%E4%B8%8E%E6%B5%81%E9%80%9A"; + else if (this.tabControl_main.SelectedTab == this.tabPage_bookshelf) + this.HelpUrl = "https://github.com/DigitalPlatform/dp2/wiki/%E5%9B%BE%E4%B9%A6%E9%A6%86%E6%8E%92%E6%9E%B6%E4%BD%93%E7%B3%BB"; + else if (this.tabControl_main.SelectedTab == this.tabPage_script) + this.HelpUrl = "https://github.com/DigitalPlatform/dp2/wiki/%E9%85%8D%E7%BD%AE%E6%9D%A1%E7%A0%81%E6%A0%A1%E9%AA%8C%E5%8A%9F%E8%83%BD"; + else + this.HelpUrl = ""; + } + // 参与排序的列号数组 SortColumns SortColumns = new SortColumns(); @@ -9077,7 +9119,7 @@ private void listView_calendar_ColumnClick(object sender, ColumnClickEventArgs e ListViewUtil.OnColumnClick(this.listView_calendar, e, false); } -#endregion + #endregion private void kernelResTree1_GetChannel(object sender, DigitalPlatform.LibraryClient.GetChannelEventArgs e) { @@ -9109,5 +9151,5 @@ private void kernelResTree1_ReturnChannel(object sender, DigitalPlatform.Library } -#endregion // 查重 + #endregion // 查重 } \ No newline at end of file diff --git a/dp2Circulation/ManageDatabase/ReaderDatabaseDialog.cs b/dp2Circulation/ManageDatabase/ReaderDatabaseDialog.cs index f56a25be0..1754ac9db 100644 --- a/dp2Circulation/ManageDatabase/ReaderDatabaseDialog.cs +++ b/dp2Circulation/ManageDatabase/ReaderDatabaseDialog.cs @@ -1,8 +1,5 @@ using System; using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; using System.Text; using System.Windows.Forms; using System.Xml; diff --git a/dp2Circulation/Order/PrintAcceptForm.cs b/dp2Circulation/Order/PrintAcceptForm.cs index 52acdd5fd..56cf59d82 100644 --- a/dp2Circulation/Order/PrintAcceptForm.cs +++ b/dp2Circulation/Order/PrintAcceptForm.cs @@ -15,7 +15,6 @@ using DigitalPlatform.GUI; using DigitalPlatform.Xml; using DigitalPlatform.IO; -using DigitalPlatform.CommonControl; using DigitalPlatform.Text; using DigitalPlatform.LibraryClient.localhost; using DigitalPlatform.dp2.Statis; @@ -304,34 +303,41 @@ public partial class PrintAcceptForm : BatchPrintFormBase /// 合并后数据列号: 实体(册)单价 /// public static int MERGED_COLUMN_ITEMPRICE = 21; // 实体(册)单价 + + // 2018/11/7 + /// + /// 合并后数据列号: 实体(册)总价 + /// + public static int MERGED_COLUMN_TOTAL_ITEMPRICE = 22; // 实体(册)单价 + /// /// 合并后数据列号: 订购时间 /// - public static int MERGED_COLUMN_ORDERTIME = 22; // 订购时间 + public static int MERGED_COLUMN_ORDERTIME = 23; // 订购时间 /// /// 合并后数据列号: 订单号 /// - public static int MERGED_COLUMN_ORDERID = 23; // 订单号 + public static int MERGED_COLUMN_ORDERID = 24; // 订单号 /// /// 合并后数据列号: 馆藏分配 /// - public static int MERGED_COLUMN_DISTRIBUTE = 24; // 馆藏分配 + public static int MERGED_COLUMN_DISTRIBUTE = 25; // 馆藏分配 /// /// 合并后数据列号: 类别 /// - public static int MERGED_COLUMN_CLASS = 25; // 类别 + public static int MERGED_COLUMN_CLASS = 26; // 类别 /// /// 合并后数据列号: 附注 /// - public static int MERGED_COLUMN_COMMENT = 26; // 附注 + public static int MERGED_COLUMN_COMMENT = 27; // 附注 /// /// 合并后数据列号: 渠道地址 /// - public static int MERGED_COLUMN_SELLERADDRESS = 27; // 渠道地址 + public static int MERGED_COLUMN_SELLERADDRESS = 28; // 渠道地址 /// /// 合并后数据列号: 种记录路径 /// - public static int MERGED_COLUMN_BIBLIORECPATH = 28; // 种记录路径 + public static int MERGED_COLUMN_BIBLIORECPATH = 29; // 种记录路径 #endregion @@ -1277,11 +1283,20 @@ void FillOrderColumns( // 如果期刊缺乏到书价 if (bSeries == true && string.IsNullOrEmpty(price.NewValue) == true) { +#if NO // 先取册价格 price.NewValue = ListViewUtil.GetItemText(item, ORIGIN_COLUMN_ITEMPRICE); // 然后取订购价 if (String.IsNullOrEmpty(price.NewValue) == true) price.NewValue = price.OldValue; +#endif + // 2018/11/7 改变取值顺序 + // 先取订购价格 + price.NewValue = price.OldValue; + // 然后取册价格 + if (String.IsNullOrEmpty(price.NewValue) == true) + price.NewValue = ListViewUtil.GetItemText(item, ORIGIN_COLUMN_ITEMPRICE); + } try @@ -2373,6 +2388,7 @@ void CreateMergedColumnHeader(ListView list) ColumnHeader columnHeader_acceptTotalFixedPrice = new ColumnHeader(); ColumnHeader columnHeader_itemPrice = new ColumnHeader(); + ColumnHeader columnHeader_totalItemPrice = new ColumnHeader(); ColumnHeader columnHeader_orderTime = new ColumnHeader(); ColumnHeader columnHeader_orderID = new ColumnHeader(); ColumnHeader columnHeader_distribute = new ColumnHeader(); @@ -2409,6 +2425,7 @@ void CreateMergedColumnHeader(ListView list) columnHeader_acceptTotalFixedPrice, columnHeader_itemPrice, + columnHeader_totalItemPrice, columnHeader_orderTime, columnHeader_orderID, columnHeader_distribute, @@ -2543,6 +2560,12 @@ void CreateMergedColumnHeader(ListView list) columnHeader_itemPrice.Width = 150; columnHeader_itemPrice.TextAlign = HorizontalAlignment.Right; // + // columnHeader_totalItemPrice + // + columnHeader_totalItemPrice.Text = "实体总价"; + columnHeader_totalItemPrice.Width = 150; + columnHeader_totalItemPrice.TextAlign = HorizontalAlignment.Right; + // // columnHeader_orderTime // columnHeader_orderTime.Text = "订购时间"; @@ -2702,9 +2725,8 @@ private void button_print_printAcceptList_Click(object sender, EventArgs e) { for (int i = 0; i < lists.Count; i++) { - List temp_filenames = null; int nRet = PrintMergedList(lists[i], - out temp_filenames, + out List temp_filenames, out strError); if (nRet == -1) goto ERROR1; @@ -2815,6 +2837,7 @@ private void button_print_Option_Click(object sender, EventArgs e) "acceptTotalFixedPrice -- 验收总码洋", "itemPrice -- 实体单价", + "totalItemPrice -- 实体总价", "orderTime -- 订购时间", "orderID -- 订单号", "distribute -- 馆藏分配", @@ -2992,6 +3015,7 @@ int BuildMergedHtml( string strAcceptTotalPrice = GetMergedTotalPrice("acceptPrice", items); string strAcceptTotalFixedPrice = GetMergedTotalPrice("acceptFixedPrice", items); // TODO: 还可以计算出平均折扣。不过要注意验收总价和码洋总价中包含多种货币的时候,除法会无法完成,需要在平均折扣位置显示警告语 + string strTotalItemPrice = GetMergedTotalPrice("itemPrice", items); macro_table["%itemcount%"] = nItemCount.ToString(); // 事项数 macro_table["%totalcopies%"] = nTotalCopies.ToString(); // 总册数(注意每套可以有多册) @@ -2999,6 +3023,7 @@ int BuildMergedHtml( macro_table["%bibliocount%"] = nBiblioCount.ToString(); // 种数 macro_table["%totalprice%"] = strAcceptTotalPrice; // 验收总价格 可能为多个币种的价格串联形态 macro_table["%totalfixedprice%"] = strAcceptTotalPrice; // 验收总码洋 + macro_table["%totalitemprice%"] = strTotalItemPrice; // 总册价格 macro_table["%pageno%"] = "1"; @@ -3029,6 +3054,7 @@ int BuildMergedHtml(
种数: %bibliocount%
总价: %totalprice%
总码洋: %totalfixedprice%
+
总册价: %totalitemprice%

批次号: %batchno%
记录路径文件: %recpathfilepath%
@@ -3074,9 +3100,11 @@ int BuildMergedHtml( StreamUtil.WriteText(strFileName, "
册数: " + nTotalCopies.ToString() + "
"); StreamUtil.WriteText(strFileName, - "
总价: " + strAcceptTotalPrice + "
"); + "
总验收价: " + strAcceptTotalPrice + "
"); StreamUtil.WriteText(strFileName, "
总码洋: " + strAcceptTotalFixedPrice + "
"); + StreamUtil.WriteText(strFileName, +"
总册价: " + strTotalItemPrice + "
"); BuildMergedPageBottom(option, macro_table, @@ -3473,6 +3501,7 @@ string GetMergedColumnContent(ListViewItem item, case "acceptTotalPrice": case "总价格": case "验收总价": + case "验收总价格": return ListViewUtil.GetItemText(item, MERGED_COLUMN_ACCEPT_TOTALPRICE); case "acceptTotalFixedPrice": @@ -3484,6 +3513,10 @@ string GetMergedColumnContent(ListViewItem item, case "实体单价": return ListViewUtil.GetItemText(item, MERGED_COLUMN_ITEMPRICE); + // 2018/11/7 + case "totalItemPrice": + case "实体总价": + return ListViewUtil.GetItemText(item, MERGED_COLUMN_TOTAL_ITEMPRICE); case "orderTime": case "订购时间": @@ -3745,14 +3778,22 @@ static int GetMergedTotalCopies(NamedListViewItems items) return total; } - + // 汇总各种价格 + // parameters: + // strFieldName 字段名称 + // acceptPrice 验收价 + // acceptFixedPrice 验收码洋 + // orderPrice 订购价 + // orderFiexedPrice 订购码洋 + // itemPrice 实体价(册记录价格) static string GetMergedTotalPrice(string strFieldName, NamedListViewItems items) { Debug.Assert(strFieldName == "acceptPrice" || strFieldName == "acceptFixedPrice" || strFieldName == "orderPrice" - || strFieldName == "orderFixedPrice", + || strFieldName == "orderFixedPrice" + || strFieldName == "itemPrice", ""); int nColumnIndex = 0; if (strFieldName == "acceptPrice") @@ -3763,6 +3804,8 @@ static string GetMergedTotalPrice(string strFieldName, nColumnIndex = MERGED_COLUMN_ORDER_TOTALPRICE; else if (strFieldName == "orderFixedPrice") nColumnIndex = MERGED_COLUMN_ORDER_TOTALFIXEDPRICE; + else if (strFieldName == "itemPrice") + nColumnIndex = MERGED_COLUMN_TOTAL_ITEMPRICE; else throw new ArgumentException("strFieldName 参数值必须为 acceptPrice/acceptFieldPrice/orderPrice/prderFieldPrice 之一"); @@ -4430,6 +4473,8 @@ public void LoadFromOrderBatchNo(string strDefaultBatchNo) ref nOrderRecCount, ref nItemRecCount, out strError); + if (nRet == -1) + goto ERROR1; // 2018/11/6 if (nRet == -2) nDupCount++; @@ -5541,7 +5586,6 @@ int FillMergedList(out string strError) // 先将原始数据列表按照 bibliorecpath/seller/price 列排序 SortOriginListForMerge(); - // 只提取一套一册的,和一套的第一册 List items = new List(); for (int i = 0; i < this.listView_origin.Items.Count; i++) @@ -5592,11 +5636,9 @@ int FillMergedList(out string strError) string strSubCopy = ""; if (String.IsNullOrEmpty(strSubCopyDetail) == false) { - string strNo = ""; - string strIndex = ""; nRet = ParseSubCopy(strSubCopyDetail, - out strNo, - out strIndex, + out string strNo, + out string strIndex, out strSubCopy, out strError); if (nRet == -1) @@ -5682,6 +5724,8 @@ int FillMergedList(out string strError) List total_acceptprices = new List(); // 累积的验收价格字符串 List total_acceptfixedprices = new List(); // 累积的验收码洋价格字符串 + List total_itemprices = new List(); // 累计的册价格 + List origin_items = new List(); string strComments = ""; // 原始注释(积累) @@ -5837,6 +5881,8 @@ int FillMergedList(out string strError) total_orderfixedprices.Add(strCurrentOrderFixedPrice); if (String.IsNullOrEmpty(strCurrentOrderPrice) == false) total_orderprices.Add(strCurrentOrderPrice); + if (String.IsNullOrEmpty(strItemPrice) == false) + total_itemprices.Add(strItemPrice); // 汇总注释 string strComment = ListViewUtil.GetItemText(current_source, ORIGIN_COLUMN_COMMENT); @@ -5855,11 +5901,10 @@ int FillMergedList(out string strError) strDistributes = strCurDistribute; else { - string strLocationString = ""; nRet = LocationCollection.MergeTwoLocationString(strDistributes, strCurDistribute, false, - out strLocationString, + out string strLocationString, out strError); if (nRet == -1) return -1; @@ -5997,6 +6042,14 @@ int FillMergedList(out string strError) strSumPrice); } + { + string strSumPrice = GetTotalPrice(total_itemprices, + "累计册价格字符串 '" + StringUtil.MakePathList(total_itemprices) + "' 时"); + // 总册价格 + ListViewUtil.ChangeItemText(target, MERGED_COLUMN_TOTAL_ITEMPRICE, + strSumPrice); + } + /* 打印验收单时间 // order time ListViewUtil.ChangeItemText(target, MERGED_COLUMN_ORDERTIME, @@ -6642,7 +6695,7 @@ int BuildOriginHtml(
%date% 原始验收数据
册数: %totalcopies%
种数: %bibliocount%
-
总价: %totalprice%
+
验收总价: %totalprice%

批次号: %batchno%
记录路径文件: %recpathfilepath%
@@ -8427,10 +8480,10 @@ public PrintAcceptPrintOption(string strDataDir, column.MaxChars = -1; this.Columns.Add(column); - // "totalPrice -- 总价格" + // "totalPrice -- 验收总价格" column = new Column(); - column.Name = "totalPrice -- 总价格"; - column.Caption = "总价格"; + column.Name = "totalPrice -- 验收总价格"; + column.Caption = "验收总价格"; column.MaxChars = -1; this.Columns.Add(column); } diff --git a/dp2Circulation/QuickChangeEntity/ChangeEntityActionDialog.Designer.cs b/dp2Circulation/QuickChangeEntity/ChangeEntityActionDialog.Designer.cs index a7ad7f1e4..91b3621a8 100644 --- a/dp2Circulation/QuickChangeEntity/ChangeEntityActionDialog.Designer.cs +++ b/dp2Circulation/QuickChangeEntity/ChangeEntityActionDialog.Designer.cs @@ -1,4 +1,4 @@ -namespace dp2Circulation +namespace dp2Circulation { partial class ChangeEntityActionDialog { @@ -56,12 +56,11 @@ private void InitializeComponent() // label1 // this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(9, 13); - this.label1.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.label1.Location = new System.Drawing.Point(14, 20); this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(77, 12); + this.label1.Size = new System.Drawing.Size(116, 18); this.label1.TabIndex = 0; - this.label1.Text = "ݲصص(&L):"; + this.label1.Text = "馆藏地点(&L):"; // // comboBox_location // @@ -69,12 +68,11 @@ private void InitializeComponent() | System.Windows.Forms.AnchorStyles.Right))); this.comboBox_location.FlatStyle = System.Windows.Forms.FlatStyle.Flat; this.comboBox_location.FormattingEnabled = true; - this.comboBox_location.Location = new System.Drawing.Point(104, 10); - this.comboBox_location.Margin = new System.Windows.Forms.Padding(2); + this.comboBox_location.Location = new System.Drawing.Point(156, 15); this.comboBox_location.Name = "comboBox_location"; - this.comboBox_location.Size = new System.Drawing.Size(164, 20); + this.comboBox_location.Size = new System.Drawing.Size(244, 26); this.comboBox_location.TabIndex = 1; - this.comboBox_location.Text = "<ı>"; + this.comboBox_location.Text = "<不改变>"; this.comboBox_location.DropDown += new System.EventHandler(this.comboBox_location_DropDown); this.comboBox_location.SizeChanged += new System.EventHandler(this.comboBox_location_SizeChanged); this.comboBox_location.TextChanged += new System.EventHandler(this.comboBox_location_TextChanged); @@ -82,12 +80,11 @@ private void InitializeComponent() // label2 // this.label2.AutoSize = true; - this.label2.Location = new System.Drawing.Point(9, 39); - this.label2.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.label2.Location = new System.Drawing.Point(14, 58); this.label2.Name = "label2"; - this.label2.Size = new System.Drawing.Size(65, 12); + this.label2.Size = new System.Drawing.Size(98, 18); this.label2.TabIndex = 2; - this.label2.Text = "(&B):"; + this.label2.Text = "册类型(&B):"; // // comboBox_bookType // @@ -95,12 +92,11 @@ private void InitializeComponent() | System.Windows.Forms.AnchorStyles.Right))); this.comboBox_bookType.FlatStyle = System.Windows.Forms.FlatStyle.Flat; this.comboBox_bookType.FormattingEnabled = true; - this.comboBox_bookType.Location = new System.Drawing.Point(104, 37); - this.comboBox_bookType.Margin = new System.Windows.Forms.Padding(2); + this.comboBox_bookType.Location = new System.Drawing.Point(156, 56); this.comboBox_bookType.Name = "comboBox_bookType"; - this.comboBox_bookType.Size = new System.Drawing.Size(164, 20); + this.comboBox_bookType.Size = new System.Drawing.Size(244, 26); this.comboBox_bookType.TabIndex = 3; - this.comboBox_bookType.Text = "<ı>"; + this.comboBox_bookType.Text = "<不改变>"; this.comboBox_bookType.DropDown += new System.EventHandler(this.comboBox_bookType_DropDown); this.comboBox_bookType.SelectedIndexChanged += new System.EventHandler(this.comboBox_bookType_SelectedIndexChanged); this.comboBox_bookType.SizeChanged += new System.EventHandler(this.comboBox_bookType_SizeChanged); @@ -112,12 +108,11 @@ private void InitializeComponent() | System.Windows.Forms.AnchorStyles.Right))); this.comboBox_state.FlatStyle = System.Windows.Forms.FlatStyle.Flat; this.comboBox_state.FormattingEnabled = true; - this.comboBox_state.Location = new System.Drawing.Point(104, 64); - this.comboBox_state.Margin = new System.Windows.Forms.Padding(2); + this.comboBox_state.Location = new System.Drawing.Point(156, 96); this.comboBox_state.Name = "comboBox_state"; - this.comboBox_state.Size = new System.Drawing.Size(164, 20); + this.comboBox_state.Size = new System.Drawing.Size(244, 26); this.comboBox_state.TabIndex = 5; - this.comboBox_state.Text = "<ı>"; + this.comboBox_state.Text = "<不改变>"; this.comboBox_state.DropDown += new System.EventHandler(this.comboBox_state_DropDown); this.comboBox_state.SelectedIndexChanged += new System.EventHandler(this.comboBox_state_SelectedIndexChanged); this.comboBox_state.SizeChanged += new System.EventHandler(this.comboBox_state_SizeChanged); @@ -126,22 +121,20 @@ private void InitializeComponent() // label3 // this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(9, 66); - this.label3.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.label3.Location = new System.Drawing.Point(14, 99); this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(53, 12); + this.label3.Size = new System.Drawing.Size(80, 18); this.label3.TabIndex = 4; - this.label3.Text = "״̬(&S):"; + this.label3.Text = "状态(&S):"; // // button_OK // this.button_OK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.button_OK.Location = new System.Drawing.Point(150, 302); - this.button_OK.Margin = new System.Windows.Forms.Padding(2); + this.button_OK.Location = new System.Drawing.Point(225, 453); this.button_OK.Name = "button_OK"; - this.button_OK.Size = new System.Drawing.Size(56, 22); + this.button_OK.Size = new System.Drawing.Size(84, 33); this.button_OK.TabIndex = 14; - this.button_OK.Text = "ȷ"; + this.button_OK.Text = "确定"; this.button_OK.UseVisualStyleBackColor = true; this.button_OK.Click += new System.EventHandler(this.button_OK_Click); // @@ -149,24 +142,22 @@ private void InitializeComponent() // this.button_Cancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.button_Cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.button_Cancel.Location = new System.Drawing.Point(211, 302); - this.button_Cancel.Margin = new System.Windows.Forms.Padding(2); + this.button_Cancel.Location = new System.Drawing.Point(316, 453); this.button_Cancel.Name = "button_Cancel"; - this.button_Cancel.Size = new System.Drawing.Size(56, 22); + this.button_Cancel.Size = new System.Drawing.Size(84, 33); this.button_Cancel.TabIndex = 15; - this.button_Cancel.Text = "ȡ"; + this.button_Cancel.Text = "取消"; this.button_Cancel.UseVisualStyleBackColor = true; this.button_Cancel.Click += new System.EventHandler(this.button_Cancel_Click); // // label4 // this.label4.AutoSize = true; - this.label4.Location = new System.Drawing.Point(9, 201); - this.label4.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.label4.Location = new System.Drawing.Point(14, 302); this.label4.Name = "label4"; - this.label4.Size = new System.Drawing.Size(173, 12); + this.label4.Size = new System.Drawing.Size(260, 18); this.label4.TabIndex = 12; - this.label4.Text = "װ뽹Զл(&F):"; + this.label4.Text = "装入后输入焦点自动切换到(&F):"; // // comboBox_focusAction // @@ -175,17 +166,17 @@ private void InitializeComponent() this.comboBox_focusAction.FlatStyle = System.Windows.Forms.FlatStyle.Flat; this.comboBox_focusAction.FormattingEnabled = true; this.comboBox_focusAction.Items.AddRange(new object[] { - "ţȫѡ", - "Ϣ༭-", - "Ϣ༭-״̬", - "Ϣ༭-ݲص", - "Ϣ༭-ͼ"}); - this.comboBox_focusAction.Location = new System.Drawing.Point(104, 216); - this.comboBox_focusAction.Margin = new System.Windows.Forms.Padding(2); + "册条码号,并全选", + "册信息编辑器-册条码号", + "册信息编辑器-状态", + "册信息编辑器-馆藏地", + "册信息编辑器-图书类型", + "册信息编辑器-登录号"}); + this.comboBox_focusAction.Location = new System.Drawing.Point(156, 324); this.comboBox_focusAction.Name = "comboBox_focusAction"; - this.comboBox_focusAction.Size = new System.Drawing.Size(164, 20); + this.comboBox_focusAction.Size = new System.Drawing.Size(244, 26); this.comboBox_focusAction.TabIndex = 13; - this.comboBox_focusAction.Text = "ţȫѡ"; + this.comboBox_focusAction.Text = "册条码号,并全选"; this.comboBox_focusAction.SizeChanged += new System.EventHandler(this.comboBox_focusAction_SizeChanged); // // comboBox_batchNo @@ -195,25 +186,23 @@ private void InitializeComponent() this.comboBox_batchNo.FlatStyle = System.Windows.Forms.FlatStyle.Flat; this.comboBox_batchNo.FormattingEnabled = true; this.comboBox_batchNo.Items.AddRange(new object[] { - "<ı>"}); - this.comboBox_batchNo.Location = new System.Drawing.Point(104, 141); - this.comboBox_batchNo.Margin = new System.Windows.Forms.Padding(2); + "<不改变>"}); + this.comboBox_batchNo.Location = new System.Drawing.Point(156, 212); this.comboBox_batchNo.Name = "comboBox_batchNo"; - this.comboBox_batchNo.Size = new System.Drawing.Size(164, 20); + this.comboBox_batchNo.Size = new System.Drawing.Size(244, 26); this.comboBox_batchNo.TabIndex = 11; - this.comboBox_batchNo.Text = "<ı>"; + this.comboBox_batchNo.Text = "<不改变>"; this.comboBox_batchNo.SizeChanged += new System.EventHandler(this.comboBox_batchNo_SizeChanged); this.comboBox_batchNo.TextChanged += new System.EventHandler(this.comboBox_batchNo_TextChanged); // // label5 // this.label5.AutoSize = true; - this.label5.Location = new System.Drawing.Point(9, 144); - this.label5.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.label5.Location = new System.Drawing.Point(14, 216); this.label5.Name = "label5"; - this.label5.Size = new System.Drawing.Size(65, 12); + this.label5.Size = new System.Drawing.Size(98, 18); this.label5.TabIndex = 10; - this.label5.Text = "κ(&N):"; + this.label5.Text = "批次号(&N):"; // // checkedComboBox_stateRemove // @@ -221,11 +210,11 @@ private void InitializeComponent() | System.Windows.Forms.AnchorStyles.Right))); this.checkedComboBox_stateRemove.BackColor = System.Drawing.SystemColors.Window; this.checkedComboBox_stateRemove.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.checkedComboBox_stateRemove.Location = new System.Drawing.Point(147, 108); + this.checkedComboBox_stateRemove.Location = new System.Drawing.Point(220, 162); this.checkedComboBox_stateRemove.Margin = new System.Windows.Forms.Padding(0); this.checkedComboBox_stateRemove.Name = "checkedComboBox_stateRemove"; this.checkedComboBox_stateRemove.Padding = new System.Windows.Forms.Padding(4); - this.checkedComboBox_stateRemove.Size = new System.Drawing.Size(120, 22); + this.checkedComboBox_stateRemove.Size = new System.Drawing.Size(180, 29); this.checkedComboBox_stateRemove.TabIndex = 9; this.checkedComboBox_stateRemove.DropDown += new System.EventHandler(this.checkedComboBox_stateRemove_DropDown); this.checkedComboBox_stateRemove.TextChanged += new System.EventHandler(this.checkedComboBox_stateRemove_TextChanged); @@ -233,12 +222,11 @@ private void InitializeComponent() // label6 // this.label6.AutoSize = true; - this.label6.Location = new System.Drawing.Point(101, 108); - this.label6.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.label6.Location = new System.Drawing.Point(152, 162); this.label6.Name = "label6"; - this.label6.Size = new System.Drawing.Size(41, 12); + this.label6.Size = new System.Drawing.Size(62, 18); this.label6.TabIndex = 8; - this.label6.Text = "(&R):"; + this.label6.Text = "减(&R):"; // // checkedComboBox_stateAdd // @@ -246,11 +234,11 @@ private void InitializeComponent() | System.Windows.Forms.AnchorStyles.Right))); this.checkedComboBox_stateAdd.BackColor = System.Drawing.SystemColors.Window; this.checkedComboBox_stateAdd.FlatStyle = System.Windows.Forms.FlatStyle.Flat; - this.checkedComboBox_stateAdd.Location = new System.Drawing.Point(147, 86); + this.checkedComboBox_stateAdd.Location = new System.Drawing.Point(220, 129); this.checkedComboBox_stateAdd.Margin = new System.Windows.Forms.Padding(0); this.checkedComboBox_stateAdd.Name = "checkedComboBox_stateAdd"; this.checkedComboBox_stateAdd.Padding = new System.Windows.Forms.Padding(4); - this.checkedComboBox_stateAdd.Size = new System.Drawing.Size(120, 22); + this.checkedComboBox_stateAdd.Size = new System.Drawing.Size(180, 29); this.checkedComboBox_stateAdd.TabIndex = 7; this.checkedComboBox_stateAdd.DropDown += new System.EventHandler(this.checkedComboBox_stateAdd_DropDown); this.checkedComboBox_stateAdd.TextChanged += new System.EventHandler(this.checkedComboBox_stateAdd_TextChanged); @@ -258,43 +246,42 @@ private void InitializeComponent() // label7 // this.label7.AutoSize = true; - this.label7.Location = new System.Drawing.Point(101, 86); - this.label7.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.label7.Location = new System.Drawing.Point(152, 129); this.label7.Name = "label7"; - this.label7.Size = new System.Drawing.Size(41, 12); + this.label7.Size = new System.Drawing.Size(62, 18); this.label7.TabIndex = 6; - this.label7.Text = "(&A):"; + this.label7.Text = "增(&A):"; // // label_state // - this.label_state.Location = new System.Drawing.Point(89, 64); + this.label_state.Location = new System.Drawing.Point(134, 96); this.label_state.Margin = new System.Windows.Forms.Padding(0); this.label_state.Name = "label_state"; - this.label_state.Size = new System.Drawing.Size(10, 66); + this.label_state.Size = new System.Drawing.Size(15, 99); this.label_state.TabIndex = 16; // // label_location // - this.label_location.Location = new System.Drawing.Point(89, 10); + this.label_location.Location = new System.Drawing.Point(134, 15); this.label_location.Margin = new System.Windows.Forms.Padding(0); this.label_location.Name = "label_location"; - this.label_location.Size = new System.Drawing.Size(10, 20); + this.label_location.Size = new System.Drawing.Size(15, 30); this.label_location.TabIndex = 17; // // label_bookType // - this.label_bookType.Location = new System.Drawing.Point(89, 37); + this.label_bookType.Location = new System.Drawing.Point(134, 56); this.label_bookType.Margin = new System.Windows.Forms.Padding(0); this.label_bookType.Name = "label_bookType"; - this.label_bookType.Size = new System.Drawing.Size(10, 20); + this.label_bookType.Size = new System.Drawing.Size(15, 30); this.label_bookType.TabIndex = 18; // // label_batchNo // - this.label_batchNo.Location = new System.Drawing.Point(89, 141); + this.label_batchNo.Location = new System.Drawing.Point(134, 212); this.label_batchNo.Margin = new System.Windows.Forms.Padding(0); this.label_batchNo.Name = "label_batchNo"; - this.label_batchNo.Size = new System.Drawing.Size(10, 20); + this.label_batchNo.Size = new System.Drawing.Size(15, 30); this.label_batchNo.TabIndex = 19; // // comboBox_returnInEdit @@ -304,33 +291,31 @@ private void InitializeComponent() this.comboBox_returnInEdit.FlatStyle = System.Windows.Forms.FlatStyle.Flat; this.comboBox_returnInEdit.FormattingEnabled = true; this.comboBox_returnInEdit.Items.AddRange(new object[] { - "<>", - "лı", - "浱ǰ¼"}); - this.comboBox_returnInEdit.Location = new System.Drawing.Point(104, 268); - this.comboBox_returnInEdit.Margin = new System.Windows.Forms.Padding(2); + "<无>", + "将焦点切换到条码号文本框", + "保存当前记录"}); + this.comboBox_returnInEdit.Location = new System.Drawing.Point(156, 402); this.comboBox_returnInEdit.Name = "comboBox_returnInEdit"; - this.comboBox_returnInEdit.Size = new System.Drawing.Size(164, 20); + this.comboBox_returnInEdit.Size = new System.Drawing.Size(244, 26); this.comboBox_returnInEdit.TabIndex = 21; - this.comboBox_returnInEdit.Text = "<>"; + this.comboBox_returnInEdit.Text = "<无>"; // // label8 // this.label8.AutoSize = true; - this.label8.Location = new System.Drawing.Point(9, 254); - this.label8.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); + this.label8.Location = new System.Drawing.Point(14, 381); this.label8.Name = "label8"; - this.label8.Size = new System.Drawing.Size(113, 12); + this.label8.Size = new System.Drawing.Size(170, 18); this.label8.TabIndex = 20; - this.label8.Text = "ڲϢس(&R):"; + this.label8.Text = "在册信息区回车(&R):"; // // ChangeEntityActionDialog // this.AcceptButton = this.button_OK; - this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); + this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 18F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this.button_Cancel; - this.ClientSize = new System.Drawing.Size(276, 334); + this.ClientSize = new System.Drawing.Size(414, 501); this.Controls.Add(this.comboBox_returnInEdit); this.Controls.Add(this.label8); this.Controls.Add(this.label_batchNo); @@ -354,11 +339,10 @@ private void InitializeComponent() this.Controls.Add(this.comboBox_location); this.Controls.Add(this.label1); this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); - this.Margin = new System.Windows.Forms.Padding(2); this.Name = "ChangeEntityActionDialog"; this.ShowInTaskbar = false; this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; - this.Text = ""; + this.Text = "动作参数"; this.Load += new System.EventHandler(this.ChangeParamDlg_Load); this.ResumeLayout(false); this.PerformLayout(); diff --git a/dp2Circulation/QuickChangeEntity/ChangeEntityActionDialog.resx b/dp2Circulation/QuickChangeEntity/ChangeEntityActionDialog.resx index f1c45b534..7133d2814 100644 --- a/dp2Circulation/QuickChangeEntity/ChangeEntityActionDialog.resx +++ b/dp2Circulation/QuickChangeEntity/ChangeEntityActionDialog.resx @@ -1,4 +1,4 @@ - + 98} z-hNN2kiLZ*pP;eA5(KGc&RU&0n?EpT`y9yV-Zy&Olj+M@S|)AZgmFDqH=ktZ>`5f9 zD$wHq#5owY_%nhACamW{a5jiKJy`%z7EXmT_JysQG#;8E8HmV2tm`lk5yqz{b+v+S z%waLnp^k@*&#kX{)I!)=CSzbs))v>EezFErfRN_yoyZCn_f=}Rc> zY=zpD8Z{VySR<6D)GSJQU-Yzpk|m)FGw>w5A8-J4zQ+F!_TapFL*l}|Ze$n=h&%qv z1*14m8}@wBX7QRkGsP}lWX9i}&nt@^A$z}zxXBd%p6~eRg6v19W{N*c+3@z7BDG@# zUD`8WH`P2q;el5N=#$Ppay!*IeLdyPDSfwHz?m|fSVfM3_MMb6;$!JUiCj<=X{;{< zMPWZp7BXcZ0O?GdhBf-MsFiNt+fsn3*iDM_Wwz$)SulHj^thMO;#7KBmLgJ zD^JU^x7m?gz)8~?NykM1TmRn}tVU6OFkpRzpMUn$yT}EN)&IpF@mx=5I17T*r zSclW|2X_qn<;28mtMAw+L~6#+{o3ep&sZO(&m7n=W56&Pi?dsNX193EAUGNtP)QYd z{YZ28n?rcmLVn?aYL@x8*EBH4dERYGZ{r}>aO$#p;aYqv?3cc8i2Jl~aW zK^5wnUvIzi*8>@U{#P5Qhj+g=3mj_P3v+=aqGnmx^@l8@Fn^A!wAVUyov6CVNh;l- zs`+ek>Gmh*SM}dT_lBUG(Z&`${gvSp=ovPF>4k&S_YV-x zrw8Vb4uf#gC*>f(OyI5-LBSw;cG=abf=Xtt$}Ik_VDhF4`|xfFF=2Oh*+2h=%8Tw~ z$+XebpJXm_m%2in2C7z$u|LxbO2Byc z_`I>|9gy!#9WZx-Z;Du-XIEWcf>T=5DyJ#58*HkT=gR-6B|D$ji?*LD+J5eFh+f1X zynjaY&KQc`n9@T`sX5)$+h4mya|1bcwo`R#&S(AJ74B6N`~=%G=S8DmOWx3cyCo3B z+pZOp!l?)`SyKz^?MuIB;P51@bQ;1$tpR*o^XkK{7wr1K9LVI~&S!<8#@j2BE9NL# zI1`s#QNsSiqjPkoD>=6+eR4Qe_&H(JdizH#tZO?F#X*_%`ExPiLreXX{h3|j>jpHh zi5#0X=m?1X@G=R0B!~!EBU2B68_P{T_=b$%higTV<1o?K7fs%<{!i``uw*l! z+6U!r5wxLDt@Z8FvGkAangsrcWB{fr^Zb&=FE%s5ibCCHW! z*_SO;dr@X!kDM{=8t(njt^)6#)u$((ptUE8Xpz?5UP;c|qgqQ(BQuYh`W^(4rpC~e z=}j7UjDF_fO}9J}7ZiCm_}z)V>D6sjWg}xN?Y>LZs>ie85=3ZyVpz)(uj%b<+~Mub zdh6X9o5ukSOXaObaAn{4>_@EVf);yji3|`Iv|zDZzevp{K3W!^uEU%?b+O9qCQF@T zpMY}4{xy(b?KgF3jZCvcI&*@(kmmRZF@xQyvJ^r`hJS*WrBet3&)RdiB1)l?xDwYN z)F1FM8u+))S5kYX1zsHEZ+)hi9I}|kB$-0yoUq$oi;1o@Z=Q}nvOqX&pJC*rxUD7Z zg6*~S(3{MCA8-bqhy4F5Bb4^O`%iAy0n5gv_Omh}VwrJ+GH03tH_GUJ-qb*9DeT6U zK<5=M`3?9-Y@cf!2fXjck&e~pwSGp1w)wG7neUCJK;P3GeaN%_{M?aDx)#fzeHg4- z`_uD>7qid8#W(GIn{C+rLe{@yG9p^eZ`n!sK9eAS1k<@itBiL?V1H(TFRKhd@*pFe zHX4;uK;k+n1J;?}ZyP$~>G-X=ThL%9mS7!XEoioHb1s(KUvVy4>}GRuR~tp`tDI|9 zX4g5_s?ZKN*V@*0g>$`L*JpE`xbR0C#X5!Ig64e0hId$}lO7gdgsVgkZ(*ITIArb} z)~SG-O!0U1#u}gbkRLw6RPsHZWKAXS;8I2~5y(aPQ}#9Xft=oA5Zz#D9~tUzET;pV zgzHHh>W(yKDX!Ju_Lwoi(s@5ce`KG8zG3`?hu=XCy$eg!Cv|dFT{@MY_y@-r=QTzs zf>9?)a!C1Z@CK4y2aG0%hS#w%C0pnsgok2olUSKl`OK~b0S2Txg^t^+cM=0&mA;ZZW+*}YVuxzYTyxo!1 zSKXdS59e@k@v=PpkJ|;<^RdlqYOu$@t3AASJ@4#%uH{Oi8x_o-h`(jca>Vy|I5}2c z2oYsG$fp2mn)au!=xygTeR}B57X^W$InWxl<`Wg=0Ld9(rCtg`=tP(fNlm$*;H3y-4M%7Ek+JFfvA9oVB%n*fmY2<|p#( z84<~3aRmu@LLXU6k;PQO56HrVr3)lCNn2rG$$bTDiku)i|l9pKY@ zb(t}CqWfoiBE9muDf(cKehN?7k=R!Z0#{tX$j4j6|KY9FC^OP)BE67 z(h>4q3<5sB;r)?VD?0YGaH#M3jQiZb@m=D=pZ!vp|0`LPf5xwv2ci7m@feif^p3fA zQ2s=2GR69UIt!^&AJt}x^Z6)UK_BlPX#Tt>oaQ|pt-y=K&#;ccoS-K;DveDwtz7NY z)%Bhl<1}`p$g@V~fx_X5TSS-&Dd7;N|5PD|FtwS_p5~mci_G}01N?wQ&6)lNZZgFq zotm4nA3>O|5UI!ZL8Jg6#dbm?An?crsmMwqO?-?Y zP8Sa96v=8f*~`gr8#H0{!J>!lw-<<~kBwFM_&@f4i`pI*lVNY0nR6ocw6__6yNIYl zXi|m40v4CV5tSM!$xGQlt>?KBPo?6e-tX<4fC;bD)p%A1rga zx6QChLppdDVrX>`*t+nT5B1$(S-sXIsU{GLRac^IFh5%Xw)%(FCcwkVR-^TX{QW*kK)xR~@V_ zY>S^~k9|eTL*hiv(#!ZvW4vQ{&aRIRId3MKH&~aL$6s8c92=&}s~n|;W2x}&F~au2 z^L9?3V-zlj(X%WMHC_sitSL$rjP-kcg{yozYA{--S!L@8;S@W86h3vaqNs(co8{PL|M`!oVkYR20T}8D zsuRi-#ZC>7EvO-WvR>6WX#eNP)Y%Lu{n4kUqfWeE5^)$y^Ii7iWFbPI)<7Vmc?F>x zcC(&=+OM+~^TPJZUeoE?dft;4jIQy%g8nV4Xr{G_FW1G21C`e=k9$xQ1uAcv z<7xjikcrj?WPLdc%t$q5^p%#-rRz3g^Bjs; zh~i(;{4{%SEo_Z>Z>w5)rh_f)`H6Qj#DRkQ-z{3wjI7>%2^GBSQ1bSY{?CAHh-!5) zVLNgX&J!eAR(=^5ra1GORZ32w`nbj3f33DA4rjyO+uG-qXOSe3f|&dZ6E!6I^2wdk zA+3Jcx(uebnm=45lNaNKP%|}*r-s5iwf|W&nAjl$_SC8};^4r8eDF*tbt?z=9{aAE zcQeFq5Ftw4IJ=CBX1$pB^Eo(k=ORFp_KmOgEjDkG;gArvEU6%?h;!-+Npc`r5W<}D zE)!%YLST?^YW^I18DZ`ibdaGfY#tu0gpZ%L3m7ZIBut5ayWB*e8Vrl`C_y=pQ0K!H z8}#>U-W{Cl&iAy(%vgKu|9BIYJ8McL*mrm)gZwy67umP*K9anlDE&W=k;bJ63zt&J;tmOE z)ycra$wS0^%LXLpS=F7R)QTF(`9G8IeJTf7IfYhBPQceXU9xr_@qk5(VU&d&!jbrWF}I5}^5=iJy) zRSr8R=5Cz*D~zYTt86cQhTa?qRh|_)i+xe#Z7E!Nsy(AQlM#mK*eaL+U6IO9SIHZi zP5N_TM2_9qyPHs5-rK8MuNIJNXS>|FSw7VWrG@s`yi6TUihh=&2CO@#n*Pj+`6AYpMRbDm$4>hocoV#GLKd$eRUK!4jpYQ7)w>QE z1S-tSB-;Pk&+OJg9pN?R`7s=s|@0SJF9beV16og7FvkK z4kC!MS#CG8z^D2!l7#%QMN`osNFce;+5I2_>J$bD2?Jd7nGfX`PcWHd5P&wM>kByq zK)Mpn-rEc0ilpr-BJ=*O@8GR%_VZ6)XTP(bWeWp>&@utk%?3Ceo+k$j`aM|f9uX_V z^tXHipqi{Mg zv;lqwF0UC$a)>k5a%ed^ZO3I;FB)Lgn{~*yGkG$;xJpGLGma=Tk&ky38mB_DmIbZt zW;5vqn!IdAi5=kpqJxm9sV%vGzDFIA21RD$?UWRbMg1+#n>ohjbS3i+VQXWBT=p= z>yXsu%*e-$mZ1C8D1lJ=ihnd*%2A^;UM|gm{U!;i=jic9Ts_0byE)w06>;^N@s>kH zqntq(hl!#STVMiN74BV-x^euGFwwYDQ+9-1FGA{`#R?96o*obc2lWDqM?C(w5f3or z*#wE7@~m-I>J4XlNS|E(T7NH7rl|rv3|v&_(~hS-&Cr;+DbBP7tlvAG>Hoe{{P_M{ zl%}7+`krj*6;A1on?=fN3I}VSo2~uh9K85Ib2-?60u^zWomT@%x%EGGevg8u?ELoc za)vqtNPfi=ttxs?<776>X>ACQh!LRN#|>`?kSzNbfu!mvAQ@u+ee8IS4=-WY?*%en z`x}1H@_{yjrYyR#Yd7WaN&6p+X`+KSWI`Z3B29Cj`OV@PVMY7qCfPxMdxpXlhpnyt zqvp!5N-iVJY(Qmr=v-#Vfj6Z5$ zaFJvdq~3NTttbUD?5V|)R>&vF(_YQf(8yi@ERE04(b{d?_^mr7IY8YKNd@b=`^Mrkf+;oM$Lo@DA3r^j#{G7rS<>JoI3xeTpZMDd z2a-LJJvjq7WX{ir8$Yt=d@UF3WH4@r33g&afSfUIAOuM0cp*UMub0GVr#)e0)+qcc zx+b@W#g2RI>E&HbUgN2`f^&dth>dlD`Ep)qdbXZ(o;!WW%QwHLYR3&T_4d-0P-^^? zzl?x>DdKc8*hNdZu(so@Z??0B$G7xeF!}vVGNJdwJ8_rVp|=>y5j+Ol^nmvVos^P+ z!_dxNZu&D1OT6xi<97JG<8=7n#+nW{zD0-U(_s_rZf^_;(?9I%4<;R_uZ5Z7*GYnq zF7PLwVp(?vlGoPR51)@-%>c=HfRPoH{;z$OAj(=|OY%!z$V0>iQLeB_2LrB58;&uV z9-^o--->^0-b{7mna945Hg*S+(ftwEmM9o-z$G@=3nHE9*mwo3XM))KZPex&j$nel zS*O@34?8%tH$YyQfYsf<&M7<`%TU~LjRna(lchvgAB$wNwNAU4V!c^HgbJ!Ri!fgk z>CMVBj>Rv%!|Bl$X9%WyL6I5sV9LN$FqH#rvV&d*Je#WXJ)64x`1vOKRtLs)`Hi1% zfz_S#x=z=^QXQ&90sbDYu-C!Vtc7nb3tBpBGe3p`cUvCsyW;V#s zq+dyEzSI759*XsU1vT{lr*{9xpoXW+%i*Y@WVG37hi!J+8?&Wu-w$@^QDfeJvfIw} z9A~%TjS@G_?6eopF(W$|o2VnHGNj_mCdqT8Ll*7VK z`*S_-b2}1AC-SzP_T%MhNK4B>*X>WFv`AP6weHa>$y0*VJ$N~w*`a54$pAI^BCl}u zaeF$h<|>@(5M4m%Wfrm)ok<9bi9CC{p{pWZIukhW?Ux?P5!;T_cuL|9u=Y%tvQw>E z4v7mY0)&)xTGXMn6oOe|$H}mfK7rm~B{ul3#9q>HB$HGPo(`GT`YVHZo_3+$9KVBx z*u-z!ZNK&(*`l&?QcvwVdcwz6bfdpATF^S0iHhw`kJOK1bq4Tyiln5-+3ueeETCCe zPcphuUw-vhib8O09be1X`Yek1uuiv~x!N8y*5USpI}c~{8c#uTBcOIl21@~YU$#U4 z`vt;E5r6-LV8yj%aU_tzQjFFJ>%ZG>It#kJ#HaArt*j6FrKPM?>qgoPZDMrVMeVZ> zF_FPXb#7eF6iy}nH}7}S;6`n`nhPmc92-N9mn|?VL>84U&Zs|! zKQi3PfPGg?@yF5pp%p7yJYeIUx^c!1ly-e|NM=V0>8itHD*9sf%owyV{Jr)k*qr== zc&_|xuy?+5fLUGgqOl(^M@F3vE2x~~BGFMeF>*j2a$-FB%YqlJu(BmE1Fs6rv|q#x zW-pmoiM9C4%>M>H)yewG&*WI1Pf!A^w1HAb;-?0@Z^lmq#lerbF(@F|&lrDd$#wl7 z(0StHr-P*U`f{Z4$A&2)Q)FH;*TJ@PZ3&=P|WC4u*NtKKO_; z#`ul;M#K0u5SCRa-a&m<@Kfj%aR&){Xc|dna5^P_G0>GK2(+k4iaid*{6YawPDB1* zVMm|S>f=rlFc%(s%}08$+n%F)7RvtFm9Vj?Z_nscD@2*SvMg+^07P#Og{{|f`r0L1 z*bhH4Bb{XhUuDKwt87PJbSB=JlK*MS&3+8}lk3a3==)EilCYbxRos^=w2(rk)-lYV zCl%lpJq4}ft-i}{_>{`^e}<=7Xng7^qwka1GVmyegUjWrfdnJ*Rzt|D3_^Gut8vW8 z%Bjn7M0WI!H?T_CugJ`Z~h1=54M5*1|=SJKRg1l5Erk*cufSjAK10)iLOG-MNY>%8ksf z?^i*~QHq(eL@{ytTD~_uvV1S*FBT19cXzXJDXe$_sWD&$|33QY}K z-5$m70F)2q#fl@9=O}9B!5A((C6#`6D{SXGCcRvuo1pVO@fRiY&exu?w%nI^&E?wM zeQ1Q$Q=JM_$f66!v(1&{OkeW~-3(c)imatG?5^3y0`haIP>KCRH?$G>B0R_4j=>8t zp57peBr^FBx-lXeB`Z)WlqT^rC5I>z7qI*CaD1@x<^KM2)chXI|q4u2|`@!FpDZCnSe z8ccdFBRZelVmbA(tQ?To`+SPV0C|_~eO08OPxwg(Uu0QjvJ&#~Es6k)iJUyzi+=FF zQ!I|Gc@%EX*+6OYBaLu>98 z<1Jb=`SmG|aM#%Gct4M*;pT3JGcxGi-RcU;x7vZa04gG~Kx9D=c&t!hpru8A?_WG? zzAd>S6r^6JQUYcZDg}6k8Z=~84_9tMy)yK6U^fnl|6Gz&%!RBo1sT>m)TCS#soUzk zOY2%Mk5pb)qAW)>i!_}Ln$9|d5Qq`Vj0)o$yRZh^e%V-%oWfi}e31|uO*zITLOCV& znE!eohe&L)N`c288U>hCVUn00s{k8dZN8EnbLqaq58?N=X4F zcN;`=xO}h4IBDHkVD8@`gw)1laJhA-d7n&4z?d{IF?4nw;`mI>&8W*g?Pq=pW8!+k zu#|97c{Ql^L@rVbi(zunBbz;R6+>HZ!j8l|$XXGdsP3zmUb#fTrV%8AOj!`r5(Kpb zOZWq!1le^#@Jxq~E#6k)zU375r%y_HA`+lvvDb`&!)+=g?(R~bX$!E~ZJ)+QFe<5?G(u_$0|?tYsnBF`rN zln?p9o}}y$&5O5=O=il}JY;YYKY58zp<6j#xtFm6I%Vq~bt~ITVFXOZE@sx5rHZAj zh(-y-~@!zc@@Z#d-$$vKxIRscNGQ2$Q|6J5kW|Yrz_M~0% zhnP4wblnUj@t6QMZ{U0NAPYca$lGBBH-;=(ec1~}V`*qDDPc2v+HXFc0Vg)y3s`cd zc;z$=-{@{`CAN0|BE1!EA{+(lSZ5Zq5*iYA8HGdc{Go)_H|%W*OS+s3ETvTRXD_JCl0E zh#q=flMED9F)=0fOAjm1M9Kkr+UEq+X9Xtma$-f(_F&(55(mCv_Pp(R$RLx>z{H3; zuO*2fj~({4b=5>h6zueD@Qo!m)ZFSsWMZhu3fjrQM4z>2B7NFrkE;71lUm4!yX>9! zyqoF2l1>J!1!%FLuMU6)k_+lfB<{Z1fG!Lw5-iYL==yBa@kk-I}GsJix}bFGRnW8@=h% zeCw*orDh(SrC<|{RV0F4_Oo}3)2}Jh_^Pc%ldH_&rn68W3NyA#Y6oEJM+C89c}`8fu;`;TU#o$)J{n%Znb|EW?8@p@7j3J~ z|1ej3Av2T={?KWQf(}tFj8D_}34>c;`pwv>+3e*Bru*!#GY@7S$x=Oyqhq5PpPAyO zWF54)*Se&IYf% zWZ7y`B<#rc9lUhCy{S}NdCC1&ud`(7vuXBH)S=m}Yydrw4D=L08GGDx1hBu#+056o zfD^3ETDn*vBAP+O=@-4D z!F%CiVy7X^K98+SmSJ}?)yV{Rc6^`zBc8yPNV21iOTZsH_7f-_pXi{n50-0_-lGnX ziz#G%M>s`vn{NB8>VO~f4K8zhq3E<35I8hDj?z%d)UD?w_UHmxT&7f?edUKx)zHZ> zv>4I}1xcY?&s-oT!kZ6<{UoAGotC5LnH^2ZsXQnp_20XG3u#^0jaz&%DjmxB@-jV5 zNj~Tv{N0L!qFE+2mte+M_U~2bGmW-Y19PWUY z-=1b#-u}Ql8HUX)Cmp^)ZF)T`zZtR~Gf>D3nx4r~_qaW~mGh?~AF=+gyXQZqdkdWI zl^(Zy6VyF8T&v@LGrL`}N+BP1PBg?{9e>UI`S`2nkAq&Si-NhSF|Rc%Pfo&nZE*$C z-~fk(;Mu_BB35Cogyo(M_h@|)rvd998J?5iS{qL}NNjJZCAIXyvZln7?xv(E8L|pV zV&X4hE$(MSdD^JNpLrj=I5Zp7#V1XFd zE{CAlUwBz$J<4G!Sn$XVW-g7Ocex>blYcQlxj8*ry|Ib1TUzc=ffw@8Z`T-7eOXoJ zNd-JUhE^Aw@(vZy92xwO_xE`j+FbDkB*4yh&J(%HbGPpHY zpvzv#GwX6JfTNvkl0}fRp!W1rMBOmlxP_E^ieW&Lms9C{sPJV~$zYqP!+>7 z>#?z-ZsI%|=Gjo(kEzmH{1o8aNktYQ|70pslz}0i4|yul1m5vK;#tkXH`tXsEtwHq zXWlG%P_rURXULlWgS}0sh{-Hty_;s{jc7{r_?nosQthJ>`?XJJ2_3k`kh$L;K!ds| zbe{SU+8(@rEFj@^$H#KuThi12H8ih=-T`b5Yndv3@$)WXuomXWMspZ_i5pt7Zz~qJ zzogSzT*5mSOU5$YFbz6Cg?*(NI%h45+djB+nh`8wibi} z*5wgxg8G2Bd$os0t^xORG#dj;0P9CGd~JyJV;oBzYSrZ93@^%^2XckS)&;C zLf@L6_O7^FyYTY*bm0*hvv<}`x0tIOh^wl4mZDCuehRRDclNmW$TjrTzJe|?Ep=(K zNDc*c!&ib_?sj0_92B$L=Nftszd6`Iut0U64AcYZkF2CxGx{S?W>fX7;Z!*14?3-nn19x^|Jy%vz#);NK0u|F0}eZcR?2TiL1mlBP~P z-xg^1KV1>`07CncSrMH~3|6xi=N2SN*nb_LA2~O-C|^{~pB}y-EJJ~{xZPRlp@{O_ zJgv~SU_OxX|FAD)?wUNXrmYTxE6iFr7>WA2f)hX`MkO zGyf4P0hirBfKIRz(upkIlW6V9Bg?_?>1-7c2!+=%r;pr14@CB~TE(z5Vgn#q$blN8 zJzyRfJvM>(s20!K_f27Bs7vlQl>NKrevkw$v4U-AT_3rc=b%M{#+<4jIT?okP97VK zU>afVvgAmVDYrcl=&&b2s6*)7EqVPoTA(?d64ruS^WA(%Q`-X15K6-OyjHXYBqjb=lc!x!7x1EZ zoJ7--`Yb20Ys}@(j0ot+ra@m;Rav)e_37ZEHWe=c%{=wUQZpyJ?4FYx0oHP>H+?Qe zp32hp?3g9DD$th$SY(i{FJ&7b)yj%2VxB1LWCRs&9C|O4zQ~+-KbGT}oICPrzu1?i zmAXqkcSn+!8aagc1@#|_UYEKgUnmckwH?By00bv?NX0ID4BbzkHGF>!tPx1xJ#2+0 z0YgEk{^dnT;3Y5;H35h0QSDS4MTP84P}?JyGC>li{)FuH%-EjvY-@2_wxJwtadz@k z$C;Z;%~npdw&kt5!eGaRR=h2XAhS4^{bKOsS^iW(+5cZOiGD|%tpn2mN6@1|5XCD> zl!M_c&l}{i&z4D_lN$moL3WLuQEYXlZ74pPU)Nbvmg#{Ta~N zan^vzJPy(Evj~HG5kB*HT-rIR_8e<**YIjhS7G))uCJB@GnpO9(2YVJ)@4;4J8pHQ zE{1+*1xxrtRN+%hBp_Mi75eCm8$+oczdXBAi|O2MyRk>Ieu+nyA{niB2>JR)<~ifW zmGmJq_BG_S6j-cBFnXmQO;vV6P4AEq6&P;rSa#UpyDM|EFob+Om?a;m2^^Y!mRh(4 z@OyChJUHVwa%IpEa6Y&z$^VX!Q`GW1{R5|xcn-xQCme?2E8qWk6rby07Ou=;L*SKT zrvWoF4IRaF@?7UIFua@Oaxt{-UxFreV`92lz+R|Qhx5!p=| zTt94+zCM|rut|@5zA{iG?Zi+h8oo)VXXl48W(SyC`=n|vKmOVe0O|3@ncHd=e}`-R zjw84+@_I6YJuHTUeF$B*-K#_em)x6`K+7(}$6v*O5Kr%8VZoiqtm}Wa;I%;QUHka=m9G2({q}&k!*V4{q93THJw{*oJ zvWjERaGbSER^Q0U!xgQNx0Zu)mfKDTbH`-JbrAVOZoW;&rqQvifU~~?`lHXeXWiwn=BT!CQ%mI;K-Zt;k*i&&}B2gzjpL5W+tRPC zQETb~tw?`cLU~wUQp>0&?3HzQZ<|YuKx}20D~v7jI?wl zURbue)G~thEXj0KL)V$T;;^qDd4$ut(%u2!9jc2QPCOw?&Kww^;a#EN<2shiXrN+6 zk056y0D85@p7K}tIlr_`qcPE`A{{u+N;%p&sBoI%C&H7_G?B=|W3So=Pd9FRb&;qb zs*87!wn)wxtIai0=&*~wd7J8I8>DtTJyy}6SZtQ6ghO;RRR*}g_Sv0m)fI_i2?Ks2 zd%$a?WwW-gO&CP>|N8N`k;xe3RAiw7_EUYJ_?zst)Hxt+7)tpK+jA_=yNO*Vd7gk! zOvc*>Icv;ka@c_t$ls0W$2POTY_+dzS+j-#G})rqO*hGUum$;Po;|Vd-Atz`iwRgL zTPFuS=%>B-1-SrqA<;K_^<=PjK;#*p4OF|^%o#4KrPj*F12Qk$)6l*6@yj7E|ItIGSKH)`SLGxT0gg5kY zoBbrsl!7W1B4`d*tLJlF_PC=m5`5~R#21CRdQXXE_14)-&q{WFd`P)^*Q@M zzdA$T={Byp%(SSAmyY9V48iWqVSN$o_TwUbf6{kjTkASkoEVhFJ8B#O;H~*6LKBa* zvD$gDn#5zO20{Bs^By^&ig^|=OTtN@}-VX{*pMI&@;F z(NV#E3?))L5~*nOJl{j2{2&+oFB6l^EC}W|{V(ap``tDm_2$#K=;UGrc9CCi;UbiD zW!5&Bi|^__O)lSp>!C0vK;1VV7-_f|oE=(t2%5|ke@Yjb@f-i!+&i|Ljof64|Ncci z8oxCA5pjSPQkK{Q`mE2qTwEpxcTpE(2bHzJiJdICIC3hw5!3&n24kF=%R=67ncmOl z!u0;kf!>dBdY}C+`7JZ1AtpqL3(uorCsOefKcj!b;+f)~n%>Z@D|C?=|L6OMjOHG0 zh<9X)j9-`i=(J362TzXI!DtzAnU4F8xOqeRGSpPhTnkiTKyvZv34StQ@VuNTtAOY^ zn0kg45ewwo|F~$Zw8@x@UshUU3W3l`D$~bNw6^tqtCqIDZ)s~=y8+@t0!o4i!5zgaT9+q|3ut9=Vg8@*{mf)R z+F!5#@4Eii-^(yF&vWm~xzByh_nd>3SpxTZ|JcyXV$tK%t~LN*T*upqZY^Ojtp4>Z z2i|Ijclg|^P@!{X$0teGFU}4EUTQ1tbe{jKwtpgViH&U#GNA^8igK>p`Ux(($jvez zUFb~ZXX*!n;NzU-e@*=k7P8<0Qg$eK7Q&MPXD+V{kdO0wRgbWjc^-fK8k%A0E}Egas1sTc zhuv^t^49{!7F50mCO_v(=JtK?mc~D>Yi!?aMy*_qq;~QZF9L)(Z9`>=n_N!M$eGgFImNn%l5tIT1-cB56?`=yT(4#_XxMdD~Tu47X#P2!DB_6 z3OxYn@uzUMiLCZK9|^2#`u?`?P9PF$CTR~7<4>||g0!=4!+f6Oe=C!=!dCs4eAL!e z1HG2gM=o}XXu0JLc5d;XilXk;;s-=l*qLg)2X|5n1M_>Bd$&I4{@0mV&5D8}de>PO zG7s}&H5ck;fW$U;ULfYXFckCUhRSadq%tz(p`SmyNGiI+M%|&D5GiZ;mm+LyK`Fry$Ti2GOC+kd|8H3)liZs zK#_Ca9sAvyapt$fDdfJYv5{zqxV{-iJai(f3p!=*h}Yg25cp5a>js*UI5&NP?7zM` zQoojHC-`dj|>X%OF~Tn`ZOmYPLw znsGx zuR4BfaV>KfY}p?HXUyH5b2}qA`qp9}Pn*js!r6hW>RhdNJ%Gym0gn`hPt;%y8=_X$ zz#>-_DcWE>Ct0XXmcNG&ENc|Mu+vZGHEfFNhQBkymVRoF^th+Ac%aRvI~B~FkV@_U z$f2rfR8?bV!|Oif(weXA|3qel;+S4sM9@!rWU=d?s~XrmJ7}(nz7i@d6o@BOT!5rY ztsH&({^b7P#N04g+Nz>Sb|4G5Pa~o1kDX#?XHn4vDiSH$^odyTpt?E7?WXhf!TZ@` zT0`*WP6pxo(qXl@(WE9NO}xW~(%Lf^4*b=&=Q`h?We(Wz=;r0nfEmrpFZD#GMmHL^ zZA;aRjAes6ZmDG`_}`PfrH+q8X*HxsM?-Y#m`tlYSQt6QDkl!QJ0aEHzybTX(N8;_ z&wiAQw&erSk@a6E`AzU8Swb|zd^GdG^;vMF^DsCN#Q$tOMy7Dav>x8W^;!_Jzf}N$ z5dRo(Ag-xZEVw=pyS@#NH<44F8~>@LxCh=FxT7d^oAV(yVq*QVj1IWeFt8-76@hGNRF<6aLtZ>OOvf(43x zqhZELXkg`aomq@SXEtYIC->9qT)OfL^5zu>%Dz1#oR6U>n0jaHYut5xs7CO^OO-uv z5VxGN>pD^W0SFwXD~d5seaboS8RWKisB93{(&0xPe7 zI=LwnyM9+}S{=}}(3)L`PDx{Cp+*-b2)=QM z^M@zI1`a_!fB))CkGmZ=w9rH6pWhd&r-MCQtSjH#8M=0z6tpXs2FfRvEYpR`ccQ4t zHm59Se{#h&c}cnIz=qry5rIovjH>v%1#{^r6Ak8B1d+%y@iftCc-dOMvo(i=+#JFZhcJI6# z(Y|;52PS5Fa#YkMSpKJVdg!YhZVucS^tePfqdfVj7IN48M0Ab@Xy}j zaTxngzQF30ZSd36mNwk(1)f}4Q>KC`&SZ8T{k5CRyS7rWh9SwyI(u?mtmg5A*F`o| zju?lDo%li1@?{gT*0eqp-U?UmsioC}BcJ_6pC!Vv)3Zo= zM3rAU4X1E2Uj#$R$`3l!NyMcs3!gIYyt> zyaWtJjTN_r!3f2pt0+ne#ut}<4L67A7r&Z@VN~{Fe4-_XE5Y~-@O1d|Nbfm387M|) z3X0L5?#_lLUTGJ&lj;=Ha5#C#k3TzC4{he=_UkYd3)$E2MFjJ>+-HvSuAMfj`P1A* zqmi7sEyB*AAEx9(?^>{EtTNi+VoESb`er)c***CTUbB2bUif%}esb|B5(oeWD#*1HOOfP8NuQ3fXraLTRbEk*0SA^N4m3~4)`^Zx)SjhQzj6&LO z;tKJ;9TXWN=;x)3Mw?RY&jrKP5L{1>8^7t-S}?o8=pd`@>|#UcdqC}Nn4>20%?!eQ z`BF@Cax!8)`yPhb1!cMZQVgErEW5I?-2eG9P&6(?>&w&kDc6THnYuJat3%fA?&%;~ zzXeB}tvzytUVr}moyynSxKXul1l+lw9a5TXtC3%Ahmh*{vW@v6h#%^9_ZTbY=v#2a-^CE`d+|9>s&gd{&?W31kY@dmc;Se)t_P-9ok zx9k&)8UTl=+m`^3+kv>^RH-Ex932akg$9>9|CI7TZXr^cc2olIc{g&p zcY)z2j*IiK=W}?wQ9-=ba@vmLMCY9=?Jsy=XG+(+K=}j3t0~JHm&Dci-cNP?Aus6> z6TpOb*}Jq4BxZLiHXKa$sF+jUBvCY@WZs>=9|g)5%m|+Z|N7#cIUcSaLv;v4#EGTNhBSzLJVcX9tg zR?rnJ6F0aV5|PnFqQRjPhH)ATiJq-MSva#Wf@%kB9#e-pPY~BY3`ormXIc&jMRR?7 zX^!qp>bC?6R15!sTZT-I33-n;*BNnDsSpLe{ZC|s1O5Xz3m>@K~b}j;8Ii zT^Amy9WPmz8_(OaFGFf}2z?WCXs*@UoX0R+jxHJJiG0KLi(H4-VT=>)Pz8|Jt>IDJ zt}5Cnyt%A2e2i0Y2Lss=sA%K~c3s06=cyElaLx9QBM71%(+py2_mG>X(($EUGJ3A+ zlxWcjQZW-;=qI|T|K9~%HSL%812^buHL;51E0A$zq2gzIpY!SeNJ?ey$*+CI7l_ z{knLBC{})1k=q#$Jb0rHDmZAjGxL5Co`YtKJx%4Vp9gi#7l_^M@I(PfmMyem5AHP` zL&CJmqL1J+34dv#5w=+|S@&;F1f_3F!$D$`UY+WV&Cw?c-ig9qyWlmU|-K zmHTGY$iyq3B}pX;@tnY^7?;E*_^{(gGiDzBDW#pm!lT2# zv;_pQu{8vW!`i8!3rS$z|PF7gopR7k2Xc>R9C(=eYai*gGuG9*-2SWT+E2 zD-H2<3!U%m)6FGV7z>W8vFi)D`-U%ZUDMX!FQ>HH{({YIoJptMR67Yp%~@Jp2oo0= zjYZo|fAqt1a8>)2Qt>(`rySebU-aZk3<=qZko~bD{(XiQTY?(W2z%n(*p>Aa9gBve zKg11*V(N7`KXko#;A_{!z>{ZO#lZVfGeOLj)tAr4XYfWcJI{O|Yw<`y+$wO^KCXM( zE*5ZPP)E>2cux%C0w2q=VwJh(Jh90Wij57#mgMmV^L{0_l_69*KfQw zJ{j~;a(|0)FhSI)Hr#Z_CKhq(C*tNdpE(WHYY|K= zNpJx$t8?_Pcn}})rYISXZr#;61v-CEaWhR~v-;9rYkH%M^wK9oU*JaNKZX;y|C%UO zDR--5h7CfjVS+U%Zb}ear)@#Io0zhAEZgs7|5kx1-1s{TOQ?KtedKJ*Ce~{Hx91>_ zz%jFcp3YMTAO-Q6^-y!kgzojqonk7Ry|_M5zL@d<3wtZn;Bk+yv*vx443z)X^rq?S z48gtNF1RtTEjRLwC4BfFdiTr>&qE{BU%G-nid#NScCX;4Aw)V3?=Lm}7(t4@sSun~ z<_D;?nG_rbI$WadWs<2CIoq%*M_C{92aFe!$e>X9pG1nV4cqAq-Jo?aG*EWq4BREH z_(i3@YX-fB3?r@tVI zvN^5;?|e=q>~ZO_z}B?FY09x3#uf)GE?W>Iq;V);J6?f{N2WSp6g!(uG#b~n%J&E= zVWJ&hq`Uh0(aCIBAzWUN1SKTo3mk=cX4EJG<#cQAgn+J zk?F=i8?xX==eNJ!*V~esBU8YM$+V;*zlq1U^8kgc+7#FXaF=<&S-S$i7i zA>yf+KJKy0S!DkBr6=Ld)Q@MtSfqpN1Ru+tFOHSRxma+qBs8DUrkaLZ4(en<()A$u zfxIp^&hGG(b-%f7I43rImL%0KQpKkMci!RT@VC zwIa&$720=w?gAFYRxrLo2SD5U`3im5yd2ukSEzR#%Rip)ps;YBeM2OFkE*F)OV~fr z{X}xVhcI;k%#YS~_=^lIbVyx@9>qVA}i_hV`x}Njq=f>CAeP~-;=V*5sT}%~sg`ch= zXSKcGvbonrUPSxyA)Od935DN<#@bzsNhCL3H?VuA$plju556dJfJ7Z+hbx8fBilu^ z=2D5%_X}FZJ<0j(2jZ^rCk0E5+}>>XnSV@8#6Uf8C*r1mGZ9lK{hNt6*SzdM5kL5w znTR<*Wg;fMP6J}lh$ChK67{8-xbM-U&%~?MIozisuho<Jrl~mBe}^r1qH9} zIdAVVb-ebU)N%g5sN-hp;6{rIB38p3&NyJ?8~%!^rQUc4QWUN=zChVHoNVZjiC-qN z2nyvS0+Si;76#I}?Lcv%;5s7ZL@&%(iZi^| zP%QAS)VPD=5YmsL8v6xhNn~RRMcNr%n!Z!1H)LPU>Ig2U^n{swe!RmL-iWvi5#*DM z(nfQ}@Fl_DJNzy8C#M&exXbQEv&w@I_^TI(8k&~dvp3@P4Wc=&4V27lR@Pp+1v7qe zb=FhW@oa((bhhr60-26%cKvT>BBa@h11ny+{asGGt{u5kzKyVVt6=z153m2#(B@wkX*+TGUdKKCizH(*sbspaFY z6qjFP-{^b;~9 zQ|ARy$H-Gip5duHd28e0bQY)id~~|T*!wWXCZb=>8w~?wZZ1ejEFO6x=WyS^q;6^v zqJ3E2oY=WyOb}DJyvT|2+6N>9P5yCPZc+XWoOX)0>2eN3-*o!jzLUpJ{l}jhkCa?0 ztd3jsNdKj-?r76>w9eVw`+L1oxDR_yB%g5rXdHVnQuP73s6`+v=YMgu;pQNkiNBxj zp#7oV)H*lka|9jK`Ew=Zg&JB9@}Uu)uiIX&d-^!{&-#ot-KymmpJ`5=J9(l>{mySw z#4g|DQ}`WRmzAXB!MW6LnM?g1JK8aHaq!^h(b$gl_#f z`!@F&x>>~UQ0f?(V4c>U$iLim$4|t+&4?*>Y6!0RjXMM_vcDE1Xjq{-y}Iu2TJj7gg8aZi%Z{6w zzG1YzY4(patx~Zmt~fINvA=^MI(W5x&>Q$7xrLsvAh$W&zlBC2>8^TT z+3&Pky)DfwvlUC~fhTw(i_5Q_d(%R#rLy?U<5*7Q(w;1H&K+XHgVx1oW(49@ERm%W zb9Oo3xm@d{%bBpo3{vDYv36a~w1s#GuB_Mn7hqjiM`gXXurvOZ&y$Ja8s;n_Q7hqD zdZICKd9mvhK#={*kn|I@q;^2hc)*n5q}7d2X0O;wN2F-wMooJ%WS=>9f3=NR`K3VoCg=bH-tftYHCpBVwag!i6d)9+jULQij?n%Ed}d_Y zFEC;LiWef|0``nrPNT+P#iph+$`|a7fF$GYxivhr{KisN$qQC_Y0w+oAy|L3t%N+` z=L8#+wX8g9ap)RzK|JGWhe8{!o(@j~16FZ$sTH4HAMn=fsc5QgItwR!++m&xA8!MB zn|#oC@!f7NR_`N&u=fftx4DER`m~ASfvPb!zOrOxNq`{kDmN0libkze#tLCdh)R(@6(34M^BaC zKh;e~PxTJ5vJsHdenI&}g*BRA-u#T2<}|&^UvfS`1?mG#2*Z*vOoQ>!f7HpK4c_n>_pQGM5c z>Z8w4xT9_7r!2hW#%c>Lya*9_6&3V1cmKUKIMNM5+%pPB*Sqd^&eW z6fOK$0+t{?@V3YqWT1Qr8lOM%4Jl8cyeapl3j$>i{f6WQXV{eEs^;%~3w0Wc?ZuG& zg|qr;)Rt}ELnbmJ!h5g|8l9V!gnedE8T0){9i(0TRRF6@O@F{Dp{#Plc{ptoU^Rg9 z=R<+DwXdrip2i-d$ZCHBKxiJysgOJt^1u#da-YdLjk}0sUG#Lp*fxLk5N^6c_|(0t zO}t7ikL$$`G&=8I?mB6dLjxhIl!=4v*l$TLa+d*Ure(!Ds>xR9?D}7jMH)e&T)nOG z=FVgb8D-hgIzF1qD^!_Jm0S2@Yl9zkA21W*^iW^;*toYZ%k+#!3xr|zlY~wS3`$Pe zpY6#A6GAOC2$wDaPNTJin@Vm?K55=W_Qna9$Vw*gt<}&emP|8;kiNKxPfv9glK!o! zs`Wht7F$X)v-l;2q+m_vdgl+S5OmM z)L9c-(uTYZ3G13*1=r!dOhpzzpH9mhU>a?wlt?yk5r9ygC&r--TRV9a7^0P~G_7T8 zWDwYefWQm+hqn@FZDr-CfY1vt>I5l%8Ve-wM|@ABx^Iw)xNxZkpJ9=zdQ25Me97}#qe$1_J?|F(~$?S6Y;vNM2Fuvo7KXgAq8@-yZ>U}Yv>OCvum20$(yaxZ^h45^^uV2#nU*w933yr^=sy?pm zs`|LLLrt%wWT7Ny#P1;*0Hod*K+5RqKSwm@diW81(Q2py_UwA5md;;zlIAB1R!;9s zbiZj@Qw64Urm>PQ5*>7Bb<2j+-KMGo&gz#T^*a+~5|x@QlJX5#1yZ&u?PMe@M~|`- z4TBu+09{G}a-7h4I$b`ppN~C6KV2*NnY}Qc0WK_8Z5!uGzT8GOq`v z`xVAe6Xn)$0xxxyYhxh+V1xbZaz5Y1_@w>6#QK#8Hc#N9{w3y9qNF=LCYuajdUkuQ zHmhWDTLrZG{bVPGo2I|_vP)AS6>oGEKm7Lg)My6E>+`}VnM28-R9u7$yC0ZJ_thko z;}jPO0JO`gBLZY7e)?|~=6D2=(0UA19F7zL0M>5N$kDYl4R?Ms7r4GuGVWL`9$&t| zI3?X`h*%f6qSJcPzW<^ODD1t7vsm>v5gG&xa=$@gxgxUdWY?rX?xz_xV71y{<6I1R z#)dMt0Zu6uyK;5s$G?!3)f_E+LBtI}eCl|xHCgc++0SO@g>$NHaAXE$Gu)>|4bnxi znN>KB;RWf9u-SrR{P7u(VwffqcDcyuXb?eszx#acTr=S_HTJ?ck0fAp2I=eF&bq+E zf%KA%IfgzOXN_O#A^R|wvS49Su*`bObvNViP~6=jF7Rp$CsyKY z6Yp9tmUO;u8w+%q=9qGESwy=`FI(a10s>eS9=UY;BCNnENwvwHGfZ@-mn^>0-Eia`}OlhX`G5R^mvF54XJu z_4b^SH0Hqm>#$C$!JGcDHa?R(T6Z@hpq+}8ui|5G2teA5j8H?HbJvc2@Wzb;BHoHu zn}(zsH?}SDBfILlKz#y1XBWF@#(~|zB{mGQ3AWBtMDz7K;Vsu+lX)o=c zw$)ARGqoy%)qbeRYIvIJc2>NE2uyV+kW0{>S4`_t?Xh1{lEedQpp|stRa-eVEqgI1 zmy5f(vQQUu_{)o;NZ87+9VhtBL|`gC@SCxXx&e(s8#=a)(p~t?9oT*tW`1nrmWjhN z5}CTUPJ~OFKQ3mCGm|mL)TFQ%l|85z054jB$2XSKhbY3_ptRmwRyfOw{2*RE{?RZ6^gKp+wBF-!|w{dTAI zb$t38hy(Nx3l3vzw4F9MpS{{!s}=nqFS+e|zZ3IU-=`@Bp^81;?>Dl$5>+94e+}kE z+Zr$E)0AHSpbD$X0Yfv`P-XKc+kt-;!I%zkvS@+fCruT*qD|wtDnCW<>^W9)8#