From 64f3958d7f50b8838b77aa95edd1d0939b7eae86 Mon Sep 17 00:00:00 2001 From: Bruce Date: Mon, 6 Apr 2026 13:09:20 +0800 Subject: [PATCH] Update reader. --- AppxPackage/PackageReader.cs | 31 +- Bridge/SysInit.cs | 1 + DataUtils/Calendar.cs | 816 + DataUtils/DataUtils.csproj | 2 + DataUtils/DateTimeFormat.cs | 494 + DataUtils/Enumerable.cs | 16 +- DataUtils/Locale.cs | 193 +- DataUtils/Utils.cs | 235 +- DataUtils/Web.cs | 11 +- LICENSE.SharpZipLib | 17 + Reader/Program.cs | 4 - Reader/Project2.ico | Bin 0 -> 368008 bytes Reader/Reader.csproj | 6 + Reader/ReaderShell.Designer.cs | 4 +- Reader/ReaderShell.resx | 21141 +++++++++------- THIRD_PARTY_NOTICES | 39 + appinstaller/initfile.h | 2 + shared/ArmInstaller.exe | Bin 133632 -> 133632 bytes shared/Reader.VisualElementsManifest.xml | 4 + shared/VisualElements/MediumIconReader.png | Bin 0 -> 7752 bytes .../MediumIconReader_Metadata.xml | 9 + shared/VisualElements/SmallIconReader.png | Bin 0 -> 5199 bytes .../SmallIconReader_Metadata.xml | 9 + shared/VisualElements/scale.xml | 7 + .../VisualElements/splash/reader/splash.png | Bin 0 -> 11492 bytes .../splash/reader/splash.scale-100.png | Bin 0 -> 11492 bytes .../splash/reader/splash.scale-140.png | Bin 0 -> 18327 bytes .../splash/reader/splash.scale-180.png | Bin 0 -> 26517 bytes .../splash/reader/splash.scale-80.png | Bin 0 -> 8789 bytes shared/VisualElementsManifest.xml | 2 +- shared/config.ini | Bin 2442 -> 2854 bytes shared/html/js/http.js | 2 + shared/html/js/polyfill-winrt.js | 285 + shared/html/js/rdinit.js | 72 + shared/html/js/resources.js | 1 + shared/html/reader.html | 129 +- shared/html/report.html | 38 +- shared/html/settings/items.js | 1 + shared/html/settings/reader.html | 56 + shared/html/settings/reader/appitems.html | 158 + shared/html/settings/reader/general.html | 192 + shared/html/settings/reader/guide.html | 62 + shared/html/settings/reader/init.js | 96 + shared/html/settings/reader/initsame.js | 21 + shared/html/settings/reader/items.js | 25 + shared/html/settings/reader/preinit.js | 30 + shared/icons/32_reader.ico | Bin 0 -> 366302 bytes shared/license/LICENSE.SharpZipLib | 17 + shared/license/THIRD_PARTY_NOTICES | 76 - shared/license/license_cn.html | 1 + shared/license/license_cn.rtf | Bin 5352 -> 0 bytes shared/license/license_en.html | 1 + shared/license/license_en.rtf | Bin 4021 -> 0 bytes shared/locale/ResXmlEditor.exe | Bin 0 -> 23552 bytes shared/locale/resources.xml | 1530 +- 55 files changed, 16056 insertions(+), 9780 deletions(-) create mode 100644 DataUtils/Calendar.cs create mode 100644 DataUtils/DateTimeFormat.cs create mode 100644 LICENSE.SharpZipLib create mode 100644 Reader/Project2.ico create mode 100644 shared/Reader.VisualElementsManifest.xml create mode 100644 shared/VisualElements/MediumIconReader.png create mode 100644 shared/VisualElements/MediumIconReader_Metadata.xml create mode 100644 shared/VisualElements/SmallIconReader.png create mode 100644 shared/VisualElements/SmallIconReader_Metadata.xml create mode 100644 shared/VisualElements/splash/reader/splash.png create mode 100644 shared/VisualElements/splash/reader/splash.scale-100.png create mode 100644 shared/VisualElements/splash/reader/splash.scale-140.png create mode 100644 shared/VisualElements/splash/reader/splash.scale-180.png create mode 100644 shared/VisualElements/splash/reader/splash.scale-80.png create mode 100644 shared/html/js/polyfill-winrt.js create mode 100644 shared/html/settings/reader.html create mode 100644 shared/html/settings/reader/appitems.html create mode 100644 shared/html/settings/reader/general.html create mode 100644 shared/html/settings/reader/guide.html create mode 100644 shared/html/settings/reader/init.js create mode 100644 shared/html/settings/reader/initsame.js create mode 100644 shared/html/settings/reader/items.js create mode 100644 shared/html/settings/reader/preinit.js create mode 100644 shared/icons/32_reader.ico create mode 100644 shared/license/LICENSE.SharpZipLib delete mode 100644 shared/license/THIRD_PARTY_NOTICES delete mode 100644 shared/license/license_cn.rtf delete mode 100644 shared/license/license_en.rtf create mode 100644 shared/locale/ResXmlEditor.exe diff --git a/AppxPackage/PackageReader.cs b/AppxPackage/PackageReader.cs index 6bf363e..fd41972 100644 --- a/AppxPackage/PackageReader.cs +++ b/AppxPackage/PackageReader.cs @@ -31,11 +31,25 @@ namespace AppxPackage "Square71x71Logo", "StartPage", "Tall150x310Logo", - "VisualGroup", "WideLogo", "Wide310x150Logo", "Executable" }; + public static readonly string [] ImageFilePathItems = new string [] + { + "LockScreenLogo", + "Logo", + "SmallLogo", + "Square150x150Logo", + "Square30x30Logo", + "Square310x310Logo", + "Square44x44Logo", + "Square70x70Logo", + "Square71x71Logo", + "Tall150x310Logo", + "WideLogo", + "Wide310x150Logo" + }; public static bool IsFilePathKey (string key) { foreach (var i in FilePathItems) @@ -293,7 +307,7 @@ namespace AppxPackage return obj.Trim ().ToLowerInvariant ().GetHashCode (); } } - private HashSet set = new HashSet (new TrimIgnoreCaseComparer ()); + private HashSet set = new HashSet (new TrimIgnoreCaseComparer ()); public Dictionary FileResourceAllValues (string resid, ZipOutputStream zos) { var comparer = new TrimIgnoreCaseComparer (); @@ -716,6 +730,13 @@ namespace AppxPackage return true; return false; } + protected bool IsImageFilePathKey (string key) + { + foreach (var i in ConstData.ImageFilePathItems) + if ((i?.Trim ()?.ToLower () ?? "") == (key?.Trim ()?.ToLower () ?? "")) + return true; + return false; + } public new string this [string key] { get @@ -767,7 +788,7 @@ namespace AppxPackage string pri = PriGetRes (value); return string.IsNullOrEmpty (pri) ? value : pri; } - if (IsFilePathKey (key) && !string.IsNullOrEmpty (value)) + if (IsImageFilePathKey (key) && !string.IsNullOrEmpty (value)) { string pri = PriGetRes (value); return string.IsNullOrEmpty (pri) ? value : pri; @@ -777,7 +798,7 @@ namespace AppxPackage public string NewAtBase64 (string key) { string value = NewAt (key, true); - if (!IsFilePathKey (key) || string.IsNullOrEmpty (value)) return ""; + if (!IsImageFilePathKey (key) || string.IsNullOrEmpty (value)) return ""; switch (PackageReadHelper.GetPackageType (m_hReader)) { case 1: // PKGTYPE_APPX @@ -2458,7 +2479,7 @@ namespace AppxPackage #endregion #region dependencies XmlElement nodeDependencies = xml.CreateElement ("Dependencies"); - var deps = Dependencies; + var deps = Dependencies; if (deps != null) { foreach (var dep in deps) diff --git a/Bridge/SysInit.cs b/Bridge/SysInit.cs index 1c91d0c..155b230 100644 --- a/Bridge/SysInit.cs +++ b/Bridge/SysInit.cs @@ -936,6 +936,7 @@ namespace Bridge public _I_Notice Notice => new _I_Notice (); public _I_Process Process => proc; public _I_Web Web => new _I_Web (); + public _I_Utilities Utilities => new _I_Utilities (); public string CmdArgs { get diff --git a/DataUtils/Calendar.cs b/DataUtils/Calendar.cs new file mode 100644 index 0000000..9b8177e --- /dev/null +++ b/DataUtils/Calendar.cs @@ -0,0 +1,816 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Runtime.InteropServices; +using System.Linq; +using System.Reflection; + +namespace DataUtils +{ + [ComVisible (true)] + [ClassInterface (ClassInterfaceType.AutoDual)] + public class _I_Calendar + { + private DateTime _utcDateTime; // 存储 UTC 时间(所有算术的基础) + private Calendar _calendar; // 当前日历系统 + private TimeZoneInfo _timeZone; // 当前时区 + private bool _is24HourClock; // true = 24小时制,false = 12小时制 + private List _languages; // 语言优先级列表 + private string _numeralSystem = "Latn"; // 数字系统(简化实现,仅存储) + private const long TicksPerNanosecond = 100; // 1 tick = 100 ns + + // 缓存的本地时间(根据时区从 _utcDateTime 转换得到) + private DateTime _localDateTime; + + // 更新本地时间(当 UTC 时间或时区改变时调用) + private void UpdateLocalDateTime () + { + _localDateTime = TimeZoneInfo.ConvertTimeFromUtc (_utcDateTime, _timeZone); + } + + // 当本地时间被修改后,同步回 UTC 时间 + private void UpdateUtcDateTime () + { + _utcDateTime = TimeZoneInfo.ConvertTimeToUtc (_localDateTime, _timeZone); + } + + // 辅助:日历字段的读取 + private int GetCalendarField (Func fieldGetter) + { + return fieldGetter (_calendar, _localDateTime); + } + + // 辅助:日历字段的设置(返回新的本地时间) + private DateTime SetCalendarField (DateTime currentLocal, Func fieldSetter, int value) + { + return fieldSetter (_calendar, currentLocal, value); + } + + // 根据日历标识符创建日历实例 + private static Calendar CreateCalendar (string calendarId) + { + switch (calendarId) + { + case "GregorianCalendar": + return new GregorianCalendar (); + case "HebrewCalendar": + return new HebrewCalendar (); + case "HijriCalendar": + return new HijriCalendar (); + case "JapaneseCalendar": + return new JapaneseCalendar (); + case "KoreanCalendar": + return new KoreanCalendar (); + case "TaiwanCalendar": + return new TaiwanCalendar (); + case "ThaiBuddhistCalendar": + return new ThaiBuddhistCalendar (); + case "UmAlQuraCalendar": + return new UmAlQuraCalendar (); + // 可根据需要增加更多日历 + default: + return new GregorianCalendar (); + } + } + + private _I_Language GetFormatCulture () + { + if (_languages == null || _languages.Count == 0) + return new _I_Language (CultureInfo.CurrentCulture.Name); + try + { + return new _I_Language (_languages [0]); + } + catch + { + return new _I_Language (CultureInfo.CurrentCulture.Name); + } + } + + private List JsArrayToList (object jsArray) + { + var result = new List (); + + if (jsArray == null) + return result; + + // JS Array 有 length 属性和数字索引器 + var type = jsArray.GetType (); + + int length = (int)type.InvokeMember ( + "length", + BindingFlags.GetProperty, + null, + jsArray, + null); + + for (int i = 0; i < length; i++) + { + object value = type.InvokeMember ( + i.ToString (), + BindingFlags.GetProperty, + null, + jsArray, + null); + + result.Add (value); + } + + return result; + } + + public _I_Calendar () + : this (new List { CultureInfo.CurrentCulture.Name }, + "GregorianCalendar", "24HourClock", TimeZoneInfo.Local.Id) + { + } + + public _I_Calendar (object languages) + : this (languages, "GregorianCalendar", "24HourClock", TimeZoneInfo.Local.Id) + { + } + + public _I_Calendar (object languages, string calendar, string clock) + : this (languages, calendar, clock, TimeZoneInfo.Local.Id) + { + } + + public _I_Calendar (object languages, string calendar, string clock, string timeZoneId) + { + _languages = languages == null ? new List () : new List (JsArrayToList (languages).Select (e => e as string)); + if (_languages.Count == 0) + _languages.Add (CultureInfo.CurrentCulture.Name); + + _calendar = CreateCalendar (calendar); + _is24HourClock = (clock == "24HourClock"); + _timeZone = TimeZoneInfo.FindSystemTimeZoneById (timeZoneId); + _utcDateTime = DateTime.UtcNow; + UpdateLocalDateTime (); + } + + public int Day + { + get + { + return _calendar.GetDayOfMonth (_localDateTime); + } + set + { + int currentDay = _calendar.GetDayOfMonth (_localDateTime); + if (value == currentDay) return; + // 通过加减天数来设置日期 + DateTime newLocal = _calendar.AddDays (_localDateTime, value - currentDay); + _localDateTime = newLocal; + UpdateUtcDateTime (); + } + } + + public int DayOfWeek + { + get + { + // 返回 0-6,0 表示星期日 + return (int)_calendar.GetDayOfWeek (_localDateTime); + } + } + + public int Era + { + get + { + return _calendar.GetEra (_localDateTime); + } + set + { + // 更改纪元较复杂,简化:仅当值不同时不做任何操作(可根据需求实现) + // 这里忽略设置,或者可以抛出 NotSupportedException + if (value != Era) + throw new NotSupportedException ("Setting Era directly is not supported in this implementation."); + } + } + + public int FirstDayInThisMonth + { + get { return 1; } + } + + public int FirstEra + { + get { return _calendar.GetEra (_calendar.MinSupportedDateTime); } + } + + public int FirstHourInThisPeriod + { + get + { + if (_is24HourClock) + return 0; + else + return (Period == 0) ? 1 : 13; + } + } + + public int FirstMinuteInThisHour + { + get { return 0; } + } + + public int FirstMonthInThisYear + { + get { return 1; } + } + + public int FirstPeriodInThisDay + { + get { return 0; } // 0 = AM + } + + public int FirstSecondInThisMinute + { + get { return 0; } + } + + public int FirstYearInThisEra + { + get + { + DateTime eraStart = _calendar.MinSupportedDateTime; + int targetEra = Era; + while (_calendar.GetEra (eraStart) != targetEra && eraStart < DateTime.MaxValue) + { + eraStart = _calendar.AddYears (eraStart, 1); + } + return _calendar.GetYear (eraStart); + } + } + + public int Hour + { + get + { + int hour24 = _calendar.GetHour (_localDateTime); + if (_is24HourClock) + return hour24; + int hour12 = hour24 % 12; + return (hour12 == 0) ? 12 : hour12; + } + set + { + if (_is24HourClock) + { + if (value < 0 || value > 23) + throw new ArgumentOutOfRangeException (nameof (value), "Hour must be between 0 and 23 for 24-hour clock."); + DateTime newLocal = _localDateTime.Date.AddHours (value).AddMinutes (Minute).AddSeconds (Second); + _localDateTime = newLocal; + } + else + { + if (value < 1 || value > 12) + throw new ArgumentOutOfRangeException (nameof (value), "Hour must be between 1 and 12 for 12-hour clock."); + int hour24 = value % 12; + if (Period == 1) hour24 += 12; + DateTime newLocal = _localDateTime.Date.AddHours (hour24).AddMinutes (Minute).AddSeconds (Second); + _localDateTime = newLocal; + } + UpdateUtcDateTime (); + } + } + + public bool IsDaylightSavingTime + { + get { return _timeZone.IsDaylightSavingTime (_localDateTime); } + } + + public _I_List Languages + { + get { return new _I_List (_languages.AsReadOnly ().Select (e => (object)e), true) ; } + } + + public int LastDayInThisMonth + { + get { return _calendar.GetDaysInMonth (_calendar.GetYear (_localDateTime), _calendar.GetMonth (_localDateTime)); } + } + + public int LastEra + { + get { return _calendar.GetEra (_calendar.MaxSupportedDateTime); } + } + + public int LastHourInThisPeriod + { + get + { + if (_is24HourClock) + return 23; + else + return (Period == 0) ? 11 : 23; + } + } + + public int LastMinuteInThisHour + { + get { return 59; } + } + + public int LastMonthInThisYear + { + get { return _calendar.GetMonthsInYear (_calendar.GetYear (_localDateTime)); } + } + + public int LastPeriodInThisDay + { + get { return 1; } // 1 = PM + } + + public int LastSecondInThisMinute + { + get { return 59; } + } + + public int LastYearInThisEra + { + get + { + DateTime eraEnd = _calendar.MaxSupportedDateTime; + int targetEra = Era; + while (_calendar.GetEra (eraEnd) != targetEra && eraEnd > DateTime.MinValue) + { + eraEnd = _calendar.AddYears (eraEnd, -1); + } + return _calendar.GetYear (eraEnd); + } + } + + public int Minute + { + get { return _calendar.GetMinute (_localDateTime); } + set + { + if (value < 0 || value > 59) + throw new ArgumentOutOfRangeException (nameof (value), "Minute must be between 0 and 59."); + DateTime newLocal = _localDateTime.AddMinutes (value - _calendar.GetMinute (_localDateTime)); + _localDateTime = newLocal; + UpdateUtcDateTime (); + } + } + + public int Month + { + get { return _calendar.GetMonth (_localDateTime); } + set + { + if (value < 1 || value > _calendar.GetMonthsInYear (_calendar.GetYear (_localDateTime))) + throw new ArgumentOutOfRangeException (nameof (value), "Month is out of range for current year."); + DateTime newLocal = SetCalendarField (_localDateTime, (cal, dt, val) => cal.AddMonths (dt, val - cal.GetMonth (dt)), value); + _localDateTime = newLocal; + UpdateUtcDateTime (); + } + } + + public int Nanosecond + { + get + { + long ticksInSecond = _localDateTime.Ticks % TimeSpan.TicksPerSecond; + return (int)(ticksInSecond * 100); // 1 tick = 100 ns + } + set + { + if (value < 0 || value > 999999999) + throw new ArgumentOutOfRangeException (nameof (value), "Nanosecond must be between 0 and 999,999,999."); + long ticks = (_localDateTime.Ticks / TimeSpan.TicksPerSecond) * TimeSpan.TicksPerSecond + (value / 100); + _localDateTime = new DateTime (ticks, _localDateTime.Kind); + UpdateUtcDateTime (); + } + } + + public int NumberOfDaysInThisMonth + { + get { return LastDayInThisMonth; } + } + + public int NumberOfEras + { + get { return _calendar.Eras.Length; } + } + + public int NumberOfHoursInThisPeriod + { + get { return _is24HourClock ? 24 : 12; } + } + + public int NumberOfMinutesInThisHour + { + get { return 60; } + } + + public int NumberOfMonthsInThisYear + { + get { return _calendar.GetMonthsInYear (_calendar.GetYear (_localDateTime)); } + } + + public int NumberOfPeriodsInThisDay + { + get { return 2; } + } + + public int NumberOfSecondsInThisMinute + { + get { return 60; } + } + + public int NumberOfYearsInThisEra + { + get { return LastYearInThisEra - FirstYearInThisEra + 1; } + } + + public string NumeralSystem + { + get { return _numeralSystem; } + set { _numeralSystem = value; } // 简化:未实现实际数字转换 + } + + public int Period + { + get + { + int hour24 = _calendar.GetHour (_localDateTime); + return (hour24 >= 12) ? 1 : 0; + } + set + { + if (value != 0 && value != 1) + throw new ArgumentOutOfRangeException (nameof (value), "Period must be 0 (AM) or 1 (PM)."); + int currentPeriod = Period; + if (currentPeriod == value) return; + // 切换 AM/PM:加减 12 小时 + DateTime newLocal = _localDateTime.AddHours (value == 0 ? -12 : 12); + _localDateTime = newLocal; + UpdateUtcDateTime (); + } + } + + public string ResolvedLanguage + { + get + { + if (_languages != null && _languages.Count > 0) + return _languages [0]; + return CultureInfo.CurrentCulture.Name; + } + } + + public int Second + { + get { return _calendar.GetSecond (_localDateTime); } + set + { + if (value < 0 || value > 59) + throw new ArgumentOutOfRangeException (nameof (value), "Second must be between 0 and 59."); + DateTime newLocal = _localDateTime.AddSeconds (value - _calendar.GetSecond (_localDateTime)); + _localDateTime = newLocal; + UpdateUtcDateTime (); + } + } + + public int Year + { + get { return _calendar.GetYear (_localDateTime); } + set + { + if (value < _calendar.GetYear (_calendar.MinSupportedDateTime) || value > _calendar.GetYear (_calendar.MaxSupportedDateTime)) + throw new ArgumentOutOfRangeException (nameof (value), "Year is out of range for this calendar."); + DateTime newLocal = SetCalendarField (_localDateTime, (cal, dt, val) => cal.AddYears (dt, val - cal.GetYear (dt)), value); + _localDateTime = newLocal; + UpdateUtcDateTime (); + } + } + + public void AddDays (int days) + { + _localDateTime = _calendar.AddDays (_localDateTime, days); + UpdateUtcDateTime (); + } + + public void AddEras (int eras) + { + // 简化:每个纪元按 1000 年估算(实际应基于日历的纪元范围) + // 大多数情况下不应频繁使用此方法 + _localDateTime = _calendar.AddYears (_localDateTime, eras * 1000); + UpdateUtcDateTime (); + } + + public void AddHours (int hours) + { + _localDateTime = _localDateTime.AddHours (hours); + UpdateUtcDateTime (); + } + + public void AddMinutes (int minutes) + { + _localDateTime = _localDateTime.AddMinutes (minutes); + UpdateUtcDateTime (); + } + + public void AddMonths (int months) + { + _localDateTime = _calendar.AddMonths (_localDateTime, months); + UpdateUtcDateTime (); + } + + public void AddNanoseconds (int nanoseconds) + { + long ticksToAdd = nanoseconds / 100; + _localDateTime = _localDateTime.AddTicks (ticksToAdd); + UpdateUtcDateTime (); + } + + public void AddPeriods (int periods) + { + _localDateTime = _localDateTime.AddHours (periods * 12); + UpdateUtcDateTime (); + } + + public void AddSeconds (int seconds) + { + _localDateTime = _localDateTime.AddSeconds (seconds); + UpdateUtcDateTime (); + } + + public void AddWeeks (int weeks) + { + AddDays (weeks * 7); + } + + public void AddYears (int years) + { + _localDateTime = _calendar.AddYears (_localDateTime, years); + UpdateUtcDateTime (); + } + + public void ChangeCalendarSystem (string calendarId) + { + Calendar newCalendar = CreateCalendar (calendarId); + // 注意:日历改变不会改变绝对时间,但会影响组件(年、月、日等) + // 只需替换日历实例,_localDateTime 保持不变(但解释方式变了) + _calendar = newCalendar; + } + + public void ChangeClock (string clock) + { + _is24HourClock = (clock == "24HourClock"); + } + + public void ChangeTimeZone (string timeZoneId) + { + _timeZone = TimeZoneInfo.FindSystemTimeZoneById (timeZoneId); + UpdateLocalDateTime (); // 重新计算本地时间(UTC 不变) + } + + public _I_Calendar Clone () + { + var clone = new _I_Calendar (_languages, GetCalendarSystem (), GetClock (), GetTimeZone ()); + clone.SetDateTime (GetDateTime ()); + return clone; + } + + public int Compare (_I_Calendar other) + { + if (other == null) return 1; + return DateTime.Compare (this.GetDateTime (), other.GetDateTime ()); + } + + public static DateTime JsDateToDateTime (object jsDate) + { + if (jsDate == null) + throw new ArgumentNullException (nameof (jsDate)); + Type type = jsDate.GetType (); + double milliseconds = (double)type.InvokeMember ( + "getTime", + BindingFlags.InvokeMethod, + null, + jsDate, + null); + DateTimeOffset epoch = new DateTimeOffset (1970, 1, 1, 0, 0, 0, TimeSpan.Zero); + DateTimeOffset dateTimeOffset = epoch.AddMilliseconds (milliseconds); + return dateTimeOffset.UtcDateTime; + } + public int CompareDateTime (object other) + { + return DateTime.Compare (this.GetDateTime (), JsDateToDateTime (other)); + } + + public void CopyTo (_I_Calendar other) + { + if (other == null) throw new ArgumentNullException (nameof (other)); + other._utcDateTime = this._utcDateTime; + other._localDateTime = this._localDateTime; + other._calendar = this._calendar; + other._timeZone = this._timeZone; + other._is24HourClock = this._is24HourClock; + other._languages = new List (this._languages); + other._numeralSystem = this._numeralSystem; + } + + public string DayAsPaddedString (int minDigits) + { + return Day.ToString ().PadLeft (minDigits, '0'); + } + + public string DayAsString () + { + return Day.ToString (); + } + + public string DayOfWeekAsSoloString () + { + return DayOfWeekAsString (); + } + + public string DayOfWeekAsSoloString (int idealLength) + { + // 简化:忽略 idealLength + return DayOfWeekAsString (); + } + + public string DayOfWeekAsString () + { + return _localDateTime.ToString ("dddd", GetFormatCulture ()); + } + + public string DayOfWeekAsString (int idealLength) + { + return DayOfWeekAsString (); + } + + public string EraAsString () + { + // 简化:返回纪元索引的字符串 + return Era.ToString (); + } + + public string EraAsString (int idealLength) + { + return EraAsString (); + } + + public string GetCalendarSystem () + { + if (_calendar is GregorianCalendar) return "GregorianCalendar"; + if (_calendar is HebrewCalendar) return "HebrewCalendar"; + if (_calendar is HijriCalendar) return "HijriCalendar"; + if (_calendar is JapaneseCalendar) return "JapaneseCalendar"; + if (_calendar is KoreanCalendar) return "KoreanCalendar"; + if (_calendar is TaiwanCalendar) return "TaiwanCalendar"; + if (_calendar is ThaiBuddhistCalendar) return "ThaiBuddhistCalendar"; + if (_calendar is UmAlQuraCalendar) return "UmAlQuraCalendar"; + return "GregorianCalendar"; + } + + public string GetClock () + { + return _is24HourClock ? "24HourClock" : "12HourClock"; + } + + public DateTime GetDateTime () + { + // 返回 UTC 时间 + return _utcDateTime; + } + + public string GetTimeZone () + { + return _timeZone.Id; + } + + public string HourAsPaddedString (int minDigits) + { + return Hour.ToString ().PadLeft (minDigits, '0'); + } + + public string HourAsString () + { + return Hour.ToString (); + } + + public string MinuteAsPaddedString (int minDigits) + { + return Minute.ToString ().PadLeft (minDigits, '0'); + } + + public string MinuteAsString () + { + return Minute.ToString (); + } + + public string MonthAsNumericString () + { + return Month.ToString (); + } + + public string MonthAsPaddedNumericString (int minDigits) + { + return Month.ToString ().PadLeft (minDigits, '0'); + } + + public string MonthAsSoloString () + { + return _localDateTime.ToString ("MMMM", GetFormatCulture ()); + } + + public string MonthAsSoloString (int idealLength) + { + return MonthAsSoloString (); + } + + public string MonthAsString () + { + return _localDateTime.ToString ("MMM", GetFormatCulture ()); + } + + public string MonthAsString (int idealLength) + { + return MonthAsString (); + } + + public string NanosecondAsPaddedString (int minDigits) + { + return Nanosecond.ToString ().PadLeft (minDigits, '0'); + } + + public string NanosecondAsString () + { + return Nanosecond.ToString (); + } + + public string PeriodAsString () + { + return PeriodAsString (0); + } + + public string PeriodAsString (int idealLength) + { + return _localDateTime.ToString ("tt", GetFormatCulture ()); + } + + public string SecondAsPaddedString (int minDigits) + { + return Second.ToString ().PadLeft (minDigits, '0'); + } + + public string SecondAsString () + { + return Second.ToString (); + } + + public void SetDateTime (DateTime value) + { + _utcDateTime = value.ToUniversalTime (); + UpdateLocalDateTime (); + } + + public void SetToMax () + { + SetDateTime (DateTime.MaxValue); + } + + public void SetToMin () + { + SetDateTime (DateTime.MinValue); + } + + public void SetToNow () + { + SetDateTime (DateTime.UtcNow); + } + + public string TimeZoneAsString () + { + return TimeZoneAsString (0); + } + + public string TimeZoneAsString (int idealLength) + { + // 简化:返回标准显示名称 + return _timeZone.DisplayName; + } + + public string YearAsPaddedString (int minDigits) + { + return Year.ToString ().PadLeft (minDigits, '0'); + } + + public string YearAsString () + { + return Year.ToString (); + } + + public string YearAsTruncatedString (int remainingDigits) + { + string yearStr = Year.ToString (); + if (yearStr.Length <= remainingDigits) + return yearStr; + return yearStr.Substring (yearStr.Length - remainingDigits); + } + } +} \ No newline at end of file diff --git a/DataUtils/DataUtils.csproj b/DataUtils/DataUtils.csproj index 328e189..cdd9b1a 100644 --- a/DataUtils/DataUtils.csproj +++ b/DataUtils/DataUtils.csproj @@ -45,6 +45,8 @@ + + diff --git a/DataUtils/DateTimeFormat.cs b/DataUtils/DateTimeFormat.cs new file mode 100644 index 0000000..bc5f156 --- /dev/null +++ b/DataUtils/DateTimeFormat.cs @@ -0,0 +1,494 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Text; + +namespace DataUtils +{ + public enum YearFormat + { + None = 0, + Default = 1, + Abbreviated = 2, + Full = 3, + } + + public enum MonthFormat + { + None = 0, + Default = 1, + Abbreviated = 2, + Full = 3, + Numeric = 4, + } + + public enum DayFormat + { + None = 0, + Default = 1, + } + + public enum DayOfWeekFormat + { + None = 0, + Default = 1, + Abbreviated = 2, + Full = 3, + } + + public enum HourFormat + { + None = 0, + Default = 1, + } + + public enum MinuteFormat + { + None = 0, + Default = 1, + } + + public enum SecondFormat + { + None = 0, + Default = 1, + } + + [ComVisible (true)] + [ClassInterface (ClassInterfaceType.AutoDual)] + public class _I_DateTimeFormatter + { + // ---------- 私有字段 ---------- + private string _formatTemplate; // 原始模板字符串 + private string _formatPattern; // 实际用于 .NET 格式化的模式 + private List _languages; // 语言优先级列表 + private string _geographicRegion; // 地理区域 + private string _calendar = "GregorianCalendar"; + private string _clock = "24HourClock"; + private string _numeralSystem = "Latn"; + private CultureInfo _culture; // 解析后的 CultureInfo + private string _resolvedLanguage; // 实际使用的语言 + private string _resolvedGeographicRegion; // 实际使用的区域 + + // 存储构造时传入的枚举值(用于 IncludeXXX 属性) + private YearFormat _yearFormat = YearFormat.None; + private MonthFormat _monthFormat = MonthFormat.None; + private DayFormat _dayFormat = DayFormat.None; + private DayOfWeekFormat _dayOfWeekFormat = DayOfWeekFormat.None; + private HourFormat _hourFormat = HourFormat.None; + private MinuteFormat _minuteFormat = MinuteFormat.None; + private SecondFormat _secondFormat = SecondFormat.None; + + // ---------- 辅助方法 ---------- + private static string MapTemplateToPattern (string template, CultureInfo culture, string clock) + { + if (string.IsNullOrEmpty (template)) + return string.Empty; + + switch (template.ToLowerInvariant ()) + { + case "longdate": + return culture.DateTimeFormat.LongDatePattern; + case "shortdate": + return culture.DateTimeFormat.ShortDatePattern; + case "longtime": + return culture.DateTimeFormat.LongTimePattern; + case "shorttime": + return culture.DateTimeFormat.ShortTimePattern; + case "dayofweek": + return culture.DateTimeFormat.ShortestDayNames? [0] ?? "dddd"; // 近似 + case "dayofweek.full": + return "dddd"; + case "dayofweek.abbreviated": + return "ddd"; + case "day": + return "dd"; + case "month": + return "MMMM"; + case "month.full": + return "MMMM"; + case "month.abbreviated": + return "MMM"; + case "month.numeric": + return "MM"; + case "year": + return "yyyy"; + case "year.full": + return "yyyy"; + case "year.abbreviated": + return "yy"; + case "hour": + return clock == "24HourClock" ? "HH" : "hh"; + case "minute": + return "mm"; + case "second": + return "ss"; + case "timezone": + return "zzz"; + default: + // 如果不是预定义模板,则当作自定义模式直接返回 + return template; + } + } + + // 根据枚举组合构建格式模式 + private static string BuildPatternFromEnums (YearFormat year, MonthFormat month, DayFormat day, DayOfWeekFormat dayOfWeek, + HourFormat hour, MinuteFormat minute, SecondFormat second, + string clock, CultureInfo culture) + { + var parts = new List (); + // 日期部分 + if (dayOfWeek != DayOfWeekFormat.None) + { + if (dayOfWeek == DayOfWeekFormat.Abbreviated) + parts.Add ("ddd"); + else // Full or Default + parts.Add ("dddd"); + } + if (year != YearFormat.None) + { + if (year == YearFormat.Abbreviated) + parts.Add ("yy"); + else + parts.Add ("yyyy"); + } + if (month != MonthFormat.None) + { + switch (month) + { + case MonthFormat.Numeric: + parts.Add ("MM"); + break; + case MonthFormat.Abbreviated: + parts.Add ("MMM"); + break; + case MonthFormat.Full: + parts.Add ("MMMM"); + break; + default: + parts.Add ("MM"); + break; + } + } + if (day != DayFormat.None) + { + parts.Add ("dd"); + } + string datePart = string.Join (" ", parts); + // 时间部分 + var timeParts = new List (); + if (hour != HourFormat.None) + { + if (clock == "24HourClock") + timeParts.Add ("HH"); + else + timeParts.Add ("hh"); + } + if (minute != MinuteFormat.None) + { + timeParts.Add ("mm"); + } + if (second != SecondFormat.None) + { + timeParts.Add ("ss"); + } + string timePart = timeParts.Count > 0 ? string.Join (":", timeParts) : ""; + if (!string.IsNullOrEmpty (datePart) && !string.IsNullOrEmpty (timePart)) + return datePart + " " + timePart; + if (!string.IsNullOrEmpty (datePart)) + return datePart; + return timePart; + } + + // 将 JS Date 对象转换为 DateTime + private DateTime ConvertJsDateToDateTime (object jsDate) + { + if (jsDate == null) + throw new ArgumentNullException (nameof (jsDate)); + + Type type = jsDate.GetType (); + // 调用 getTime() 获取毫秒数 (double) + double milliseconds = (double)type.InvokeMember ( + "getTime", + BindingFlags.InvokeMethod, + null, + jsDate, + null); + + // 手动计算 Unix 纪元转换(兼容低版本 .NET) + DateTime epoch = new DateTime (1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); + DateTime utcDateTime = epoch.AddMilliseconds (milliseconds); + // 返回本地时间(可根据需求调整) + return utcDateTime.ToLocalTime (); + } + + // 初始化文化信息 + private void InitializeCulture () + { + string lang = (_languages != null && _languages.Count > 0) ? _languages [0] : CultureInfo.CurrentCulture.Name; + try + { + _culture = new CultureInfo (lang); + _resolvedLanguage = _culture.Name; + } + catch + { + _culture = CultureInfo.CurrentCulture; + _resolvedLanguage = _culture.Name; + } + _resolvedGeographicRegion = _geographicRegion ?? _culture.Name; + // 根据区域和语言更新格式模式(如果使用模板) + if (!string.IsNullOrEmpty (_formatTemplate)) + { + _formatPattern = MapTemplateToPattern (_formatTemplate, _culture, _clock); + } + else if (_yearFormat != YearFormat.None || _monthFormat != MonthFormat.None || + _dayFormat != DayFormat.None || _dayOfWeekFormat != DayOfWeekFormat.None || + _hourFormat != HourFormat.None || _minuteFormat != MinuteFormat.None || + _secondFormat != SecondFormat.None) + { + _formatPattern = BuildPatternFromEnums (_yearFormat, _monthFormat, _dayFormat, _dayOfWeekFormat, + _hourFormat, _minuteFormat, _secondFormat, _clock, _culture); + } + } + + // ---------- 构造函数 ---------- + public _I_DateTimeFormatter (string formatTemplate) + : this (formatTemplate, null, null, null, null) + { + } + + public _I_DateTimeFormatter (string formatTemplate, IEnumerable languages) + : this (formatTemplate, languages, null, null, null) + { + } + + public _I_DateTimeFormatter (string formatTemplate, IEnumerable languages, string geographicRegion, string calendar, string clock) + { + _formatTemplate = formatTemplate; + _languages = languages == null ? new List () : new List (languages); + _geographicRegion = geographicRegion; + if (!string.IsNullOrEmpty (calendar)) + _calendar = calendar; + if (!string.IsNullOrEmpty (clock)) + _clock = clock; + InitializeCulture (); + } + + public _I_DateTimeFormatter (YearFormat year, MonthFormat month, DayFormat day, DayOfWeekFormat dayOfWeek) + : this (year, month, day, dayOfWeek, HourFormat.None, MinuteFormat.None, SecondFormat.None, null, null, null, null) + { + } + + public _I_DateTimeFormatter (HourFormat hour, MinuteFormat minute, SecondFormat second) + : this (YearFormat.None, MonthFormat.None, DayFormat.None, DayOfWeekFormat.None, hour, minute, second, null, null, null, null) + { + } + + public _I_DateTimeFormatter (YearFormat year, MonthFormat month, DayFormat day, DayOfWeekFormat dayOfWeek, + HourFormat hour, MinuteFormat minute, SecondFormat second, + IEnumerable languages) + : this (year, month, day, dayOfWeek, hour, minute, second, languages, null, null, null) + { + } + + public _I_DateTimeFormatter (YearFormat year, MonthFormat month, DayFormat day, DayOfWeekFormat dayOfWeek, + HourFormat hour, MinuteFormat minute, SecondFormat second, + IEnumerable languages, string geographicRegion, string calendar, string clock) + { + _yearFormat = year; + _monthFormat = month; + _dayFormat = day; + _dayOfWeekFormat = dayOfWeek; + _hourFormat = hour; + _minuteFormat = minute; + _secondFormat = second; + _languages = languages == null ? new List () : new List (languages); + _geographicRegion = geographicRegion; + if (!string.IsNullOrEmpty (calendar)) + _calendar = calendar; + if (!string.IsNullOrEmpty (clock)) + _clock = clock; + InitializeCulture (); + } + + // ---------- 属性 ---------- + public string Calendar + { + get { return _calendar; } + set + { + _calendar = value; + // 日历更改可能需要重新初始化模式,这里简化处理 + } + } + + public string Clock + { + get { return _clock; } + set + { + _clock = value; + InitializeCulture (); // 重新生成模式(因为小时格式可能变化) + } + } + + public string GeographicRegion + { + get { return _geographicRegion; } + set + { + _geographicRegion = value; + InitializeCulture (); + } + } + + public int IncludeDay + { + get { return (int)_dayFormat; } + } + + public int IncludeDayOfWeek + { + get { return (int)_dayOfWeekFormat; } + } + + public int IncludeHour + { + get { return (int)_hourFormat; } + } + + public int IncludeMinute + { + get { return (int)_minuteFormat; } + } + + public int IncludeMonth + { + get { return (int)_monthFormat; } + } + + public int IncludeSecond + { + get { return (int)_secondFormat; } + } + + public int IncludeYear + { + get { return (int)_yearFormat; } + } + + public _I_List Languages + { + get { return new _I_List (_languages.AsReadOnly ().Select (e => (object)e), true); } + } + + public static _I_DateTimeFormatter LongDate + { + get + { + return new _I_DateTimeFormatter ("longdate"); + } + } + + public static _I_DateTimeFormatter LongTime + { + get + { + return new _I_DateTimeFormatter ("longtime"); + } + } + + public string NumeralSystem + { + get { return _numeralSystem; } + set { _numeralSystem = value; } + } + + public _I_List Patterns + { + get + { + return new _I_List (new List { _formatPattern }.AsReadOnly ().Select (e => (object)e), true); + } + } + + public string ResolvedGeographicRegion + { + get { return _resolvedGeographicRegion; } + } + + public string ResolvedLanguage + { + get { return _resolvedLanguage; } + } + + public static _I_DateTimeFormatter ShortDate + { + get + { + return new _I_DateTimeFormatter ("shortdate"); + } + } + + public static _I_DateTimeFormatter ShortTime + { + get + { + return new _I_DateTimeFormatter ("shorttime"); + } + } + + public string Template + { + get + { + if (!string.IsNullOrEmpty (_formatTemplate)) + return _formatTemplate; + // 从枚举组合生成模板描述(简化) + return _formatPattern; + } + } + + // ---------- 方法 ---------- + public string FormatC (DateTime dateTime) + { + return dateTime.ToString (_formatPattern, _culture); + } + + public string FormatC (DateTime dateTime, string timeZoneId) + { + if (!string.IsNullOrEmpty (timeZoneId)) + { + try + { + TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById (timeZoneId); + DateTime targetTime = TimeZoneInfo.ConvertTime (dateTime, tzi); + return targetTime.ToString (_formatPattern, _culture); + } + catch + { + // 时区无效,回退到原始时间 + return dateTime.ToString (_formatPattern, _culture); + } + } + return dateTime.ToString (_formatPattern, _culture); + } + + // 为方便 JS 调用,提供接受 object 的重载(自动识别 JS Date) + public string Format (object jsDate) + { + DateTime dt = ConvertJsDateToDateTime (jsDate); + return FormatC (dt); + } + + public string FormatWithTimeZone (object jsDate, string timeZoneId) + { + DateTime dt = ConvertJsDateToDateTime (jsDate); + return FormatC (dt, timeZoneId); + } + } +} diff --git a/DataUtils/Enumerable.cs b/DataUtils/Enumerable.cs index a951823..844d40a 100644 --- a/DataUtils/Enumerable.cs +++ b/DataUtils/Enumerable.cs @@ -10,7 +10,7 @@ namespace DataUtils { [ComVisible (true)] [InterfaceType (ComInterfaceType.InterfaceIsDual)] - public interface _I_Enumerable + public interface _I_Enumerable: IDisposable { int Length { get; set; } object this [int index] { get; set; } @@ -33,6 +33,9 @@ namespace DataUtils int IndexOfKey (int key); // 按内部 key 查找 void Move (int index, int newIndex); // 移动元素 void PushAll (object [] items); // 一次性 push 多个 + object Get (int index); + object Set (int index, object value); + object At (int index); } public class _I_List: _I_Enumerable, IList { @@ -43,6 +46,9 @@ namespace DataUtils IsReadOnly = readOnly; IsSynchronized = sync; } + public _I_List (bool readOnly = false, bool fixedSize = false, bool sync = true) : + this (null, readOnly, fixedSize, sync) + { } protected List _list; protected object _lock = new object (); public object this [int index] { get { return _list [index]; } set { _list [index] = value; } } @@ -155,5 +161,13 @@ namespace DataUtils return first; } public void Unshift (object value) => _list.Insert (0, value); + public void Dispose () + { + _list?.Clear (); + _list = null; + } + public object Get (int index) => this [index]; + public object Set (int index, object value) => this [index] = value; + public object At (int index) => this [index]; } } diff --git a/DataUtils/Locale.cs b/DataUtils/Locale.cs index a5ce047..e641203 100644 --- a/DataUtils/Locale.cs +++ b/DataUtils/Locale.cs @@ -1,29 +1,116 @@ using System; +using System.Collections.Generic; using System.Globalization; +using System.Linq; using System.Runtime.InteropServices; using System.Text; +using System.Text.RegularExpressions; namespace DataUtils { internal static class NativeMethods { + public const int LOCALE_SSHORTESTSCRIPT = 0x0000004F; // 获取四字母脚本代码 + public const uint KLF_ACTIVATE = 0x00000001; // 激活键盘布局 // GetLocaleInfoW for LCID-based queries [DllImport ("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] public static extern int GetLocaleInfoW (int Locale, int LCType, [Out] StringBuilder lpLCData, int cchData); - // GetLocaleInfoEx for locale name based queries [DllImport ("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] public static extern int GetLocaleInfoEx (string lpLocaleName, int LCType, [Out] StringBuilder lpLCData, int cchData); - // LocaleNameToLCID - available on Vista+; fallback is to use CultureInfo [DllImport ("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] public static extern int LocaleNameToLCID (string lpName, uint dwFlags); - // LCIDToLocaleName (Vista+) [DllImport ("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)] public static extern int LCIDToLocaleName (int Locale, [Out] StringBuilder lpName, int cchName, uint dwFlags); + [DllImport ("user32.dll")] + public static extern IntPtr GetKeyboardLayout (uint dwLayout); + [DllImport ("user32.dll", CharSet = CharSet.Auto)] + public static extern IntPtr LoadKeyboardLayout (string pwszKLID, uint Flags); } + [ComVisible (true)] + [ClassInterface (ClassInterfaceType.AutoDual)] + public class _I_Language: System.Globalization.CultureInfo + { + public _I_Language (string localeName) : base (localeName) { } + public string AbbreviatedName => this.ThreeLetterISOLanguageName; + public string LanguageTag => this.IetfLanguageTag ?? this.Name; + public int LayoutDirection + { + get + { + if (base.TextInfo.IsRightToLeft) return 1; + string tag = this.LanguageTag; + bool isVerticalCandidate = false; + if (tag != null) + { + var scriptMatch = Regex.Match (tag, @"-([A-Za-z]{4})(?:-|$)"); + if (scriptMatch.Success) + { + string script = scriptMatch.Groups [1].Value; + if (script == "Hani" || script == "Hira" || script == "Kana" || script == "Jpan" || script == "Kore" || script == "Hans" || script == "Hant") + isVerticalCandidate = true; + } + if (!isVerticalCandidate) + { + var regionMatch = Regex.Match (tag, @"-([A-Za-z]{2})$"); + if (regionMatch.Success) + { + string region = regionMatch.Groups [1].Value.ToUpperInvariant (); + if (region == "JP" || region == "CN" || region == "TW" || region == "HK" || region == "MO" || region == "KR") + isVerticalCandidate = true; + } + } + } + if (isVerticalCandidate) + { + return 2; + } + return 0; + } + } + public string Script + { + get + { + StringBuilder sb = new StringBuilder (10); + if (NativeMethods.GetLocaleInfoEx (this.Name, NativeMethods.LOCALE_SSHORTESTSCRIPT, sb, sb.Capacity) > 0) + return sb.ToString (); + // 如果失败,尝试从语言标记中解析脚本子标记(如 "zh-Hans-CN" 中的 "Hans") + var match = Regex.Match (this.Name, @"-([A-Za-z]{4})(?:-|$)"); + if (match.Success) + return match.Groups [1].Value; + + return "Unknown"; + } + } + public _I_List GetExtensionSubtags (string singleton) + { + if (string.IsNullOrEmpty (singleton) || singleton.Length != 1) + throw new ArgumentException ("Singleton must be a single character", nameof (singleton)); + var subtags = new List (); + string tag = this.LanguageTag; + string pattern = $@"-{Regex.Escape (singleton)}-([a-zA-Z0-9](?:-[a-zA-Z0-9]+)*)"; + var match = Regex.Match (tag, pattern); + if (match.Success) + { + string extPart = match.Groups [1].Value; + subtags.AddRange (extPart.Split ('-')); + } + return new _I_List (subtags.Select (i => (object)i)); + } + public bool TrySetInputMethodLanguageTag (string languageTag) + { + int lcid = NativeMethods.LocaleNameToLCID (languageTag, 0); + if (lcid == 0) + return false; + string klid = $"{lcid:X8}"; + IntPtr hkl = NativeMethods.LoadKeyboardLayout (klid, NativeMethods.KLF_ACTIVATE); + return hkl != IntPtr.Zero; + } + } [ComVisible (true)] [ClassInterface (ClassInterfaceType.AutoDual)] public class _I_Locale @@ -47,7 +134,6 @@ namespace DataUtils } } } - // Current LCID (int) public int CurrentLCID { @@ -63,7 +149,6 @@ namespace DataUtils } } } - // Convert LCID -> locale name (e.g. 1033 -> "en-US") public string ToLocaleName (int lcid) { @@ -87,7 +172,6 @@ namespace DataUtils } return string.Empty; } - // Convert locale name -> LCID public int ToLCID (string localeName) { @@ -111,7 +195,6 @@ namespace DataUtils // fallback: invariant culture return CultureInfo.InvariantCulture.LCID; } - // Return a locale info string for given LCID and LCTYPE. LCTYPE is the Win32 LOCALE_* constant. // Returns a string (or empty string on failure). public object LocaleInfo (int lcid, int lctype) @@ -177,7 +260,6 @@ namespace DataUtils return string.Empty; } } - // LocaleInfoEx: query by locale name string and LCTYPE // Returns string if available; otherwise returns the integer result code (as int) if string empty (mimic C++ behavior). public object LocaleInfoEx (string localeName, int lctype) @@ -239,7 +321,6 @@ namespace DataUtils return 0; } } - // Helpers similar to the C++: restricted (language) and elaborated (region) codes public string GetLocaleRestrictedCode (string localeName) { @@ -257,7 +338,6 @@ namespace DataUtils return string.Empty; } } - public string GetLocaleElaboratedCode (string localeName) { if (string.IsNullOrEmpty (localeName)) localeName = CurrentLocale; @@ -284,7 +364,6 @@ namespace DataUtils } return string.Empty; } - // LCID -> combined code like "en-US" (with configurable separator) public string LcidToLocaleCode (int lcid) { @@ -304,7 +383,6 @@ namespace DataUtils } return string.Empty; } - // Get the user default locale name public string GetUserDefaultLocaleName () { @@ -317,7 +395,6 @@ namespace DataUtils catch { } return LcidToLocaleCode (CultureInfo.CurrentCulture.LCID); } - // Get system default locale name (machine) public string GetSystemDefaultLocaleName () { @@ -330,7 +407,6 @@ namespace DataUtils catch { } return LcidToLocaleCode (CultureInfo.InstalledUICulture.LCID); } - // Get computer locale code similar to C++ approach public string GetComputerLocaleCode () { @@ -350,7 +426,38 @@ namespace DataUtils // fallback to invariant return CultureInfo.InvariantCulture.Name ?? string.Empty; } - + public _I_List RecommendLocaleNames + { + get + { + var arr = new string [] { + System.Threading.Thread.CurrentThread.CurrentCulture.Name, + GetUserDefaultLocaleName (), + GetSystemDefaultLocaleName (), + LcidToLocaleCode (CurrentLCID), + GetLocaleRestrictedCode (System.Threading.Thread.CurrentThread.CurrentCulture.Name), + GetLocaleRestrictedCode (GetUserDefaultLocaleName ()), + GetLocaleRestrictedCode (GetSystemDefaultLocaleName ()), + "en-US", + "en" + }; + var list = new _I_List (); + foreach (var loc in arr) + { + var lloc = loc.Trim ().ToLowerInvariant (); + var isfind = false; + foreach (var item in list) + { + var str = item as string; + if (string.IsNullOrWhiteSpace (str)) isfind = true; + isfind = str.Trim ().ToLowerInvariant () == lloc; + if (isfind) break; + } + if (!isfind) list.Add (loc); + } + return list; + } + } // Compare two locale names; returns true if equal by name or LCID public bool LocaleNameCompare (string left, string right) { @@ -366,8 +473,62 @@ namespace DataUtils return false; } } - // Constants private const int LOCALE_NAME_MAX_LENGTH = 85; // defined by Windows + public _I_Language CreateLanguage (string localeName) => new _I_Language (localeName); + public static string CurrentInputMethodLanguageTag + { + get + { + IntPtr hkl = NativeMethods.GetKeyboardLayout (0); + int lcid = hkl.ToInt32 () & 0xFFFF; + + StringBuilder sb = new StringBuilder (85); + int result = NativeMethods.LCIDToLocaleName (lcid, sb, sb.Capacity, 0); + if (result > 0) + return sb.ToString (); + + return null; + } + } + public static bool IsWellFormed (string languageTag) + { + if (string.IsNullOrEmpty (languageTag)) + return false; + + try + { + var _ = new CultureInfo (languageTag); + return true; + } + catch + { + return false; + } + } + public static _I_List GetMuiCompatibleLanguageListFromLanguageTags (IEnumerable languageTags) + { + var result = new List (); + foreach (string tag in languageTags) + { + if (string.IsNullOrEmpty (tag)) + continue; + result.Add (tag); + try + { + var ci = new CultureInfo (tag); + string parent = ci.Parent.Name; + if (!string.IsNullOrEmpty (parent) && parent != tag && !result.Contains (parent)) + result.Add (parent); + } + catch { } + string neutral = Regex.Replace (tag, @"-.*$", ""); + if (neutral != tag && !result.Contains (neutral)) + result.Add (neutral); + } + if (!result.Contains ("neutral")) + result.Add ("neutral"); + return new _I_List (result.Select (t => (object)t)); + } } } diff --git a/DataUtils/Utils.cs b/DataUtils/Utils.cs index bf01c33..03b9692 100644 --- a/DataUtils/Utils.cs +++ b/DataUtils/Utils.cs @@ -1,9 +1,11 @@ using System; +using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; +using System.Runtime.Serialization; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -382,5 +384,236 @@ namespace DataUtils } [ComVisible (true)] [ClassInterface (ClassInterfaceType.AutoDual)] - public class _I_Exception: IExcep + public class _I_Exception: Exception, IDisposable + { + private Exception bex = null; + public _I_Exception (Exception ex) { bex = ex; } + public _I_Exception (string message) { bex = new Exception (message); } + public _I_Exception (string msg, Exception innerEx) { bex = new Exception (msg, innerEx); } + public override IDictionary Data => bex.Data; + public override Exception GetBaseException () => bex.GetBaseException (); + public override void GetObjectData (SerializationInfo info, StreamingContext context) => bex.GetObjectData (info, context); + public override string HelpLink + { + get { return bex.HelpLink; } + set { bex.HelpLink = value; } + } + public override string Message => bex.Message; + public override string Source + { + get { return bex.Source; } + set { bex.Source = value; } + } + public override string StackTrace => bex.StackTrace; + public override string ToString () => bex.ToString (); + public override int GetHashCode () => bex.GetHashCode (); + public override bool Equals (object obj) => bex.Equals (obj); + public void Dispose () { bex = null; } + } + [ComVisible (true)] + [ClassInterface (ClassInterfaceType.AutoDual)] + public class _I_KeyValuePair: IDisposable + { + object key = null; + object value = null; + public _I_KeyValuePair (object k, object v) + { + key = k; + value = v; + } + public object Key { get { return key; } set { key = value; } } + public object Value { get { return value; } set { this.value = value; } } + public void Dispose () + { + key = null; + value = null; + } + ~_I_KeyValuePair () + { + key = null; + value = null; + } + } + [ComVisible (true)] + [ClassInterface (ClassInterfaceType.AutoDual)] + public class _I_WwwFormUrlDecoder + { + private readonly Dictionary _params = new Dictionary (); + public _I_WwwFormUrlDecoder (string query) + { + if (string.IsNullOrEmpty (query)) return; + if (query.StartsWith ("?")) query = query.Substring (1); + foreach (var pair in query.Split ('&')) + { + var kv = pair.Split ('='); + if (kv.Length == 2) + _params [Uri.UnescapeDataString (kv [0])] = Uri.UnescapeDataString (kv [1]); + } + } + public string GetFirstValueByName (string name) + { + string value = null; + return _params.TryGetValue (name, out value) ? value : null; + } + public int Size => _params.Count; + public _I_KeyValuePair GetAt (uint index) + { + var pair = _params.ElementAt ((int)index); + return new _I_KeyValuePair (pair.Key, pair.Value); + } + } + [ComVisible (true)] + [ClassInterface (ClassInterfaceType.AutoDual)] + public class _I_Uri: Uri + { + public _I_Uri (string uri): base (uri) { } + public _I_Uri (string baseUri, string relativeUri) : base (new Uri (baseUri), relativeUri) { } + public string AbsoluteCanonicalUri => this.GetLeftPart (UriPartial.Authority) + this.PathAndQuery + this.Fragment; + public string DisplayIri => Uri.UnescapeDataString (this.OriginalString); + public string DisplayUri => Uri.UnescapeDataString (this.OriginalString); + public string Domain => ExtractDomain (this.Host); + public string Extension => System.IO.Path.GetExtension (this.AbsolutePath)?.TrimStart ('.') ?? ""; + public string Password => ExtractPassword (this.UserInfo); + public string Path => this.AbsolutePath; + public object QueryParsed => new _I_WwwFormUrlDecoder (this.Query); + public string RawUri => this.OriginalString; + public string SchemeName => this.Scheme; + public bool Suspicious => !Uri.IsWellFormedUriString (this.OriginalString, UriKind.Absolute); + public string UserName => ExtractUserName (this.UserInfo); + public _I_Uri CombineUri (string relativeUri) + { + return new _I_Uri (this.AbsoluteUri, relativeUri); + } + public static string EscapeComponent (string component) + { + return Uri.EscapeDataString (component); + } + public static string UnescapeComponent (string component) + { + return Uri.UnescapeDataString (component); + } + private static string ExtractDomain (string host) + { + var parts = host.Split ('.'); + if (parts.Length >= 2) + return string.Join (".", parts.Skip (1)); + return host; + } + private static string ExtractUserName (string userInfo) + { + if (string.IsNullOrEmpty (userInfo)) return ""; + var parts = userInfo.Split (':'); + return parts [0]; + } + private static string ExtractPassword (string userInfo) + { + if (string.IsNullOrEmpty (userInfo)) return ""; + var parts = userInfo.Split (':'); + return parts.Length > 1 ? parts [1] : ""; + } + } + [ComVisible (true)] + [ClassInterface (ClassInterfaceType.AutoDual)] + public class _I_Utilities + { + public _I_Uri CreateUri (string uri) => new _I_Uri (uri); + public _I_Uri CreateUri2 (string baseUri, string relaUri) => new _I_Uri (baseUri, relaUri); + public _I_Exception CreateException (string message) => new _I_Exception (message); + public _I_Exception CreateException2 (string message, _I_Exception innerEx) => new _I_Exception (message, innerEx); + public _I_Calendar CreateCalendar () => new _I_Calendar (); + public _I_Calendar CreateCalendar2 (object list) => new _I_Calendar (list); + public _I_Calendar CreateCalendar3 (object list, string arg1, string arg2) => new _I_Calendar (list, arg1, arg2); + public _I_Calendar CreateCalendar4 (object list, string arg1, string arg2, string arg3) => new _I_Calendar (list, arg1, arg2, arg3); + public _I_DateTimeFormatter CreateDateTimeFormatterFromTemplate (string formatTemplate) + { + return new _I_DateTimeFormatter (formatTemplate); + } + public _I_DateTimeFormatter CreateDateTimeFormatterFromTemplateAndLanguages (string formatTemplate, object languagesArray) + { + List languages = JsArrayToStringList (languagesArray); + return new _I_DateTimeFormatter (formatTemplate, languages); + } + public _I_DateTimeFormatter CreateDateTimeFormatterFromTemplateFull (string formatTemplate, object languagesArray, + string geographicRegion, string calendar, string clock) + { + List languages = JsArrayToStringList (languagesArray); + return new _I_DateTimeFormatter (formatTemplate, languages, geographicRegion, calendar, clock); + } + public _I_DateTimeFormatter CreateDateTimeFormatterFromDateEnums (int year, int month, int day, int dayOfWeek) + { + return new _I_DateTimeFormatter ( + (YearFormat)year, + (MonthFormat)month, + (DayFormat)day, + (DayOfWeekFormat)dayOfWeek + ); + } + public _I_DateTimeFormatter CreateDateTimeFormatterFromTimeEnums (int hour, int minute, int second) + { + return new _I_DateTimeFormatter ( + (HourFormat)hour, + (MinuteFormat)minute, + (SecondFormat)second + ); + } + public _I_DateTimeFormatter CreateDateTimeFormatterFromDateTimeEnums (int year, int month, int day, int dayOfWeek, + int hour, int minute, int second, object languagesArray) + { + List languages = JsArrayToStringList (languagesArray); + return new _I_DateTimeFormatter ( + (YearFormat)year, + (MonthFormat)month, + (DayFormat)day, + (DayOfWeekFormat)dayOfWeek, + (HourFormat)hour, + (MinuteFormat)minute, + (SecondFormat)second, + languages + ); + } + public _I_DateTimeFormatter CreateDateTimeFormatterFromDateTimeEnumsFull (int year, int month, int day, int dayOfWeek, + int hour, int minute, int second, object languagesArray, + string geographicRegion, string calendar, string clock) + { + List languages = JsArrayToStringList (languagesArray); + return new _I_DateTimeFormatter ( + (YearFormat)year, + (MonthFormat)month, + (DayFormat)day, + (DayOfWeekFormat)dayOfWeek, + (HourFormat)hour, + (MinuteFormat)minute, + (SecondFormat)second, + languages, + geographicRegion, + calendar, + clock + ); + } + private List JsArrayToStringList (object jsArray) + { + var result = new List (); + if (jsArray == null) return result; + + Type type = jsArray.GetType (); + try + { + int length = (int)type.InvokeMember ("length", BindingFlags.GetProperty, null, jsArray, null); + for (int i = 0; i < length; i++) + { + object value = type.InvokeMember (i.ToString (), BindingFlags.GetProperty, null, jsArray, null); + if (value != null) + result.Add (value.ToString ()); + } + } + catch + { + // 如果无法获取 length,则假设是单个字符串 + string single = jsArray.ToString (); + if (!string.IsNullOrEmpty (single)) + result.Add (single); + } + return result; + } + } } diff --git a/DataUtils/Web.cs b/DataUtils/Web.cs index 9d2af40..e2fbd50 100644 --- a/DataUtils/Web.cs +++ b/DataUtils/Web.cs @@ -297,11 +297,18 @@ namespace DataUtils return new HttpResponse (res); } } - public void SendAsync (string sBody, string encoding, object pfResolve) + public void SendAsync (string sBody, string encoding, object pfResolve, object pfReject) { System.Threading.ThreadPool.QueueUserWorkItem (delegate { - JsUtils.Call (pfResolve, Send (sBody, encoding)); + try + { + JsUtils.Call (pfResolve, Send (sBody, encoding)); + } + catch (Exception ex) + { + JsUtils.Call (pfReject, new _I_Exception (ex)); + } }); } public void Dispose () { } diff --git a/LICENSE.SharpZipLib b/LICENSE.SharpZipLib new file mode 100644 index 0000000..f4597ac --- /dev/null +++ b/LICENSE.SharpZipLib @@ -0,0 +1,17 @@ +Copyright © 2000-2018 SharpZipLib Contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or +substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/Reader/Program.cs b/Reader/Program.cs index ce137b7..3530406 100644 --- a/Reader/Program.cs +++ b/Reader/Program.cs @@ -18,10 +18,6 @@ namespace Reader static void Main () { Directory.SetCurrentDirectory (AppDomain.CurrentDomain.BaseDirectory); - AppxPackage.PackageReader.AddApplicationItem ("SmallLogo"); - AppxPackage.PackageReader.AddApplicationItem ("Square30x30Logo"); - AppxPackage.PackageReader.AddApplicationItem ("Logo"); - AppxPackage.PackageReader.AddApplicationItem ("Square44x44Logo"); DataUtils.BrowserEmulation.SetWebBrowserEmulation (); Application.EnableVisualStyles (); Application.SetCompatibleTextRenderingDefault (false); diff --git a/Reader/Project2.ico b/Reader/Project2.ico new file mode 100644 index 0000000000000000000000000000000000000000..605691282a0af5b9e9265c4dd6c8810bb989fe67 GIT binary patch literal 368008 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

fWS(ary@vNw~TzOLuZN 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 literal 0 HcmV?d00001 diff --git a/Reader/Reader.csproj b/Reader/Reader.csproj index 0595c06..a0c5701 100644 --- a/Reader/Reader.csproj +++ b/Reader/Reader.csproj @@ -71,6 +71,9 @@ prompt MinimumRecommendedRules.ruleset + + Project2.ico + ..\packages\Newtonsoft.Json.13.0.3\lib\net40\Newtonsoft.Json.dll @@ -170,6 +173,9 @@ false + + + 5RgadPXlcPHQ6t(cAh9Na=AHlvs^aHRFZaH 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 sBClMb>U)~+eB7rf9O(m&6rpgq1|U=?frtZ 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 literal 0 HcmV?d00001 diff --git a/shared/VisualElements/splash/reader/splash.scale-80.png b/shared/VisualElements/splash/reader/splash.scale-80.png new file mode 100644 index 0000000000000000000000000000000000000000..01f72897374ee8335b4b16058ff22684de316bc6 GIT binary patch literal 8789 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 YxW>M9j_Q?p@P$fG+gPhy!y)Q_0CqMVI{*Lx literal 0 HcmV?d00001 diff --git a/shared/VisualElementsManifest.xml b/shared/VisualElementsManifest.xml index c886cf6..488374f 100644 --- a/shared/VisualElementsManifest.xml +++ b/shared/VisualElementsManifest.xml @@ -32,7 +32,7 @@ ForegroundText='light' BackgroundColor='#004fe2'> - diff --git a/shared/config.ini b/shared/config.ini index 2de2667f15a2d71fe5072fa7bc6f923ea5b8d0d5..084b0f1f8ba03f5a979ecf5435ad96acdee96948 100644 GIT binary patch delta 136 zcmeAYUM99-9oyu4tbCIj*!Uz}8S)qs8Il-s7*ZJ=8Il6#-dpKn&CiQaw3<#Rz2P= 0; + } + if (parseBool(isenable) == true) { + metaitemlist.push(item); + } + } + reader.updateApplicationReadItems(metaitemlist); pagemgr.register("reader", document.getElementById("tag-reader"), document.getElementById("page-reader")); pagemgr.register("acquire", document.getElementById("tag-acquire"), document.getElementById("page-acquire")); + pagemgr.register("search", document.getElementById("tag-search"), document.getElementById("page-search")); pagemgr.go("reader"); }); })(this); \ No newline at end of file diff --git a/shared/html/js/resources.js b/shared/html/js/resources.js index b1c2c28..2333833 100644 --- a/shared/html/js/resources.js +++ b/shared/html/js/resources.js @@ -57,6 +57,7 @@ try { var obj = nodes[i].getAttribute('data-res-resxml'); var strres = external.StringResources; + if (!strres) strres = Bridge.External.WinJsStringRes; if (strres) { try { nodes[i].textContent = strres.get(obj); diff --git a/shared/html/reader.html b/shared/html/reader.html index f62be09..6bcc525 100644 --- a/shared/html/reader.html +++ b/shared/html/reader.html @@ -8,10 +8,13 @@ + + + @@ -60,13 +63,13 @@

+