Update reader.
@@ -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)
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
816
DataUtils/Calendar.cs
Normal file
@@ -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<string> _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<Calendar, DateTime, int> fieldGetter)
|
||||
{
|
||||
return fieldGetter (_calendar, _localDateTime);
|
||||
}
|
||||
|
||||
// 辅助:日历字段的设置(返回新的本地时间)
|
||||
private DateTime SetCalendarField (DateTime currentLocal, Func<Calendar, DateTime, int, DateTime> 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<object> JsArrayToList (object jsArray)
|
||||
{
|
||||
var result = new List<object> ();
|
||||
|
||||
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<string> { 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<string> () : new List<string> (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<string> (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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,6 +45,8 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Calendar.cs" />
|
||||
<Compile Include="DateTimeFormat.cs" />
|
||||
<Compile Include="Download.cs" />
|
||||
<Compile Include="Enumerable.cs" />
|
||||
<Compile Include="HResult.cs" />
|
||||
|
||||
494
DataUtils/DateTimeFormat.cs
Normal file
@@ -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<string> _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<string> ();
|
||||
// 日期部分
|
||||
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<string> ();
|
||||
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<string> languages)
|
||||
: this (formatTemplate, languages, null, null, null)
|
||||
{
|
||||
}
|
||||
|
||||
public _I_DateTimeFormatter (string formatTemplate, IEnumerable<string> languages, string geographicRegion, string calendar, string clock)
|
||||
{
|
||||
_formatTemplate = formatTemplate;
|
||||
_languages = languages == null ? new List<string> () : new List<string> (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<string> 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<string> 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<string> () : new List<string> (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<string> { _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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<object> _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];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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> ();
|
||||
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<string> languageTags)
|
||||
{
|
||||
var result = new List<string> ();
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<string, string> _params = new Dictionary<string, string> ();
|
||||
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<string> languages = JsArrayToStringList (languagesArray);
|
||||
return new _I_DateTimeFormatter (formatTemplate, languages);
|
||||
}
|
||||
public _I_DateTimeFormatter CreateDateTimeFormatterFromTemplateFull (string formatTemplate, object languagesArray,
|
||||
string geographicRegion, string calendar, string clock)
|
||||
{
|
||||
List<string> 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<string> 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<string> 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<string> JsArrayToStringList (object jsArray)
|
||||
{
|
||||
var result = new List<string> ();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
try
|
||||
{
|
||||
JsUtils.Call (pfResolve, Send (sBody, encoding));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
JsUtils.Call (pfReject, new _I_Exception (ex));
|
||||
}
|
||||
});
|
||||
}
|
||||
public void Dispose () { }
|
||||
|
||||
17
LICENSE.SharpZipLib
Normal file
@@ -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.
|
||||
@@ -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);
|
||||
|
||||
BIN
Reader/Project2.ico
Normal file
|
After Width: | Height: | Size: 359 KiB |
@@ -71,6 +71,9 @@
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<ApplicationIcon>Project2.ico</ApplicationIcon>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.13.0.3\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||
@@ -170,6 +173,9 @@
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="Project2.ico" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
|
||||
4
Reader/ReaderShell.Designer.cs
generated
@@ -31,14 +31,14 @@
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ReaderShell));
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// ManagerShell
|
||||
// ReaderShell
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(657, 414);
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.Location = new System.Drawing.Point(0, 0);
|
||||
this.Name = "ManagerShell";
|
||||
this.Name = "ReaderShell";
|
||||
this.PageScale = 125;
|
||||
this.Text = "Form1";
|
||||
this.WindowIcon = ((System.Drawing.Icon)(resources.GetObject("$this.WindowIcon")));
|
||||
|
||||
21141
Reader/ReaderShell.resx
@@ -71,6 +71,45 @@ Original Project:
|
||||
License: MIT License
|
||||
License File: LICENSE.WinJS
|
||||
|
||||
----------------------------------------------------------------------
|
||||
CodeMirror
|
||||
----------------------------------------------------------------------
|
||||
|
||||
This product includes CodeMirror, which is licensed under the MIT License.
|
||||
|
||||
Original Project:
|
||||
Name: CodeMirror
|
||||
Author: Marijn Haverbeke and contributors
|
||||
Project Homepage: https://codemirror.net/
|
||||
License: MIT License
|
||||
License File: LICENSE.CodeMirror
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Json.NET (Newtonsoft.Json)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
This product includes Json.NET (also known as Newtonsoft.Json), which is licensed under the MIT License.
|
||||
|
||||
Original Project:
|
||||
Name: Json.NET
|
||||
Author: James Newton-King
|
||||
Project Homepage: https://www.newtonsoft.com/json
|
||||
License: MIT License
|
||||
License File: LICENSE.Newtonsoft.Json
|
||||
|
||||
----------------------------------------------------------------------
|
||||
SharpZipLib
|
||||
----------------------------------------------------------------------
|
||||
|
||||
This product includes SharpZipLib, which is licensed under the MIT License.
|
||||
|
||||
Original Project:
|
||||
Name: SharpZipLib
|
||||
Author: SharpZipLib Contributors
|
||||
Project Homepage: https://icsharpcode.github.io/SharpZipLib/
|
||||
License: MIT License
|
||||
License File: LICENSE.SharpZipLib
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
End of notices.
|
||||
|
||||
@@ -502,6 +502,7 @@ namespace Win32
|
||||
using namespace System;
|
||||
using namespace System::Runtime::InteropServices;
|
||||
[ComVisible (true)]
|
||||
[ClassInterface (ClassInterfaceType::AutoDual)]
|
||||
public ref class Key
|
||||
{
|
||||
private:
|
||||
@@ -523,6 +524,7 @@ namespace Win32
|
||||
);
|
||||
return CStringToMPString (res);
|
||||
}
|
||||
Object ^GetWithDefault (Object ^dflt) { return Get (dflt); }
|
||||
Object ^Get ()
|
||||
{
|
||||
auto res = GetPrivateProfileStringW (
|
||||
|
||||
4
shared/Reader.VisualElementsManifest.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" GeneratedByTileIconifier="true">
|
||||
<VisualElements ShowNameOnSquare150x150Logo="on" Square150x150Logo="VisualElements\MediumIconReader.png" Square70x70Logo="VisualElements\SmallIconReader.png" ForegroundText="light" BackgroundColor="#004fe2" TileIconifierColorSelection="Default" TileIconifierCreatedWithUpgrade="true" />
|
||||
</Application>
|
||||
BIN
shared/VisualElements/MediumIconReader.png
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
9
shared/VisualElements/MediumIconReader_Metadata.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0"?>
|
||||
<ShortcutItemImage xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<OriginalBytes>iVBORw0KGgoAAAANSUhEUgAAANIAAADSCAYAAAA/mZ5CAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAnoSURBVHhe7d17qKR1HcdxsbKLS2WWsFBiEUoRGRUZUVhBEOZ1ddW8oKbrHyJUEkkKuRRhRekfUeHSvUgpoljX3dpatXUttYzoQkGEZkpRoNAfQSC7vX/zfGc958yZM7/nPJf5PWfeL/gyc+b53c6Z78f13OYcIUmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJG0whw4d2n7w4MHL4k1JdRGgzxKkEe7/lbo0LknDRjNvo/5GPR0PdYL1vxgZWobH/0JdFMOkYaF5r6GeiH4e4e0n43KrWPfW2GIqxvyZuiCmSGWjWT9ELQvQUlx7NIa2giW3VyvnYf8/UufFdKksNOdH1wrQUoz7XUxrhHWuiyVrY+7vqS2xlDRfNOONVFaAlmLOgVhiXZi/LZZqhHV+S50Vy0r9of+eTaUvM9cO0FLM3x1L1sK8C2KJ1rDmw9TpsYXUHfrtBVTjAC3FWnfE8lmYsrWa2Q3O85CBUiforxdTrQZoKdbdEVutiaGdhmgpzvSAgVIraKSX0VOdBWgp9vh8bLsqhvQWoqU41/0GSutC42ymh3oJ0FLsd1McYRkuzSVES3G2/QZK2eiZ3gO0FHt/OI4ywkNzD9EK9xoorYkGuT6aZa44x5XpPNwtLUSHccZ9BkpT0RyfjF6ZK85xS9wtGufca6C0KhrjE9EnvWPvndy8Kc7xWuqe6krZOOceykBpOXqj1s+wNZUCNK0RuXw1135VjSwb57zLQGkZ+qLzMK0VoJUYdxX1UEwtWp33SwuAnugkTE0ajXlXUg/GUkVr8n5qg6EfWgtTm43FOh+gHoili9bm+60BoxcahanLRmLdK6hfxFZF6/LjoIGgAdLnKE9HT2Tps3HY7nL2ur/auWx9flxUIHrgGBrg0aodpptno7DvZdSBOErR5vlxUgF48lf9/k5JjcE5LqXui6MVraSPm3rEc38CT/zfqzYouxE41yXU/jhq0dLHkZsj4+haBDzp6YVOHqEG8YKMnPNi6udVy5aJ8x0dx9Ui4Yl/jNpBD4x+rGcIOO9FVIk/evTSOKIWDQ359WiC9F/T27gZUqDeT91dnX6+OMcr4lhaRPTAxPeXBhioC6l91en7x94nxlG0qOiDqd+oHWCgzqd+Vp2+H+x3cmyvRUYj3Bw9MdXQAsVZt3Lmn44O3yH2eGtsqUVHM3w5+mKmoQWK855H7a1O3y7WfVdsI42a7fbojWwDDNS51I+r0zfHWqfF0lKFptgT/VHbAAO1pcn7mzD/3FhOegaN0fj7MQMM1DnU7ur0tWyNJaTl2gjS2AADdRZ1V3X6mQyRpmszSGMDDNSZ1K7q9KsyRFpbF0EaG2CgzqDurE5/mCHSbF0GaWyAgfog9SRnTi9w+c42KpbWRtVHkMZKDxRnO5Izfpyq9VvE07DOdyh/fGgR8ET3FqQx9iwqUJzlKM50A/W/0QEbYp0UoFNieS0CnvDegzTG3nMNFPs/n0p/O/e/1YmaYR0DtKh44ucWpDHO0Gug2GsTe15H/Wd0gIZYxwAtOhpg7kEa4yydBoq1X8QeH6GeGm3YEOt8lTJAKitIY5yp1UCx3rHU9dS/qx2aSeejDJCeQUMUF6Sx1LDcrDtQzD+OupH6R7ViM+k8lAHSJBqj2CCNpQbmJjtQjN9MpS9jH36VpCbS/pQB0nQ0SPFBGuOsN8exp2LMtdRjMaUR1jFAykOjDCZI4dNx9Am8LxfHmEYiQG+JZaXZhhYkzrszjj6Ba4/EsHVJAeKmty/DawMZYJDuiaNPWE+QmPMvA6TGNliQ0hcYPkal7xWlHzy9htrGtPRXLtL/9qUfQj2b+++j3sN9f5hU7aChNkyQpLkxSFILNlKQuHx53JX6tVqQeOxH3KTPJ4qzVpDSNSp9wcFAqV8rg8Tb6fXfnhOX03/lizIrSDEsjfsTNwZK/VjRfOn+prg0wtvPGl0sRG6QxnjsYW5qB4o5fkVP+cbNx+0vqZfEw8tw+ag0pgTpvHGsCeP3ZTVc209dGENXxfXxL/o9zhSDpHw0Tfq84jfU5nhoVTTW80YdOWfpvHGkCelaDJuKMXuoM2LKCA8fT23n8SdGgyoGSfmi+U6IN9fE2KOrHpufdN44zoR4X7Iw9p/Ut7j7veqRCQZJ+Wimk+JuFsa/MBptLlJY4igT0rUY1gaDpG7RZMdUvdY/g6QNhaY9NhquVwZJg0IjzXypXhr3uKrn+mOQNBg05B3RTDlh2hxje2GQNAg043ejkcZywvTyGNs5g6Ti0YjfjiZaaWaYGJO+F9M5g6Si0YTfjAaaJudfplfG2M4YJBWLBvxaNM8sOWF6dYzthEFSkWi+r0Tj5MoJ00kxtnUGScWh8XZE09SVE6bXxNhWGSQVhaar+y/RSjlhel2MbY1BUjFokm9UvdJYTphOjrGtMEgqAs027Uvc65UTpjfG2MYMkuaORrs9mqRtOWF6c4xtxCBprmiy70eDdCUnTKfE2HUzSJobGuyH0RxdywnT22LsuhgkzQXNtTMaoy85YXpHjK3NIKl3NNbuaIq+5YTp1Bhbi0FSr2iqvdEQ85ITpmtjbDaDpN7QUHdHM8zbmmHinCfGuGwGSZ3jyT+eZvpD1QfFWDNMMSabQVLnePLfnhqgTtF86/nXa9W11qo44gSu1WKQVCSar/bnUjG1FbFkNoOkItF8e6JxssXUVsSS2QySikTz7YrGyRZTWxFLZjNIKhLNl/4WUi0xtRWxZDaDpCLRfD+IxskWU1sRS2YzSCoSDTPtReSniqkTuLSJZr6pTlUr5mNOX0F6VSwrzUbzrXwdu5li6qq4fDX169HADvQRJNZJf6niubGsNBsNU/sX/WLqmhjWSaB6CtItsaSUh76p/WvnMTULw1sNVNdBYo3HqdfHklIemqb2i6DE1FqY1kqgugwS85+iTovlpHw0zm3RR9li6rowvVGgugoSc9MvP74hlpLqoYG+VLVSvpjaCPtexVK1A9V2kJizmzozlpDWhyb6QvRUtpjaCva/giWzA5XCElMnpGsxbCbG/oTaElOlZmimW6O3ssXUVnGOS1h6ZqBSWGLKhHQthk3FmH3UeTFFagdN9bnosWwxtROc53y2mBqoFJYYOiFdi2GruZc6O4ZK7aL5PlP1Wb6Y2inOdQ5bTQSqbpB47D7q9BgidYMm+1T0XLaY2osUAurB2Do7SNw/QL03LkndotluoNL3T7IrpvaKfd9N7aXujIcmpGvULurUeEiSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJEmSJKmuI474P9M94UzlaHRYAAAAAElFTkSuQmCC</OriginalBytes>
|
||||
<OriginalPath>E:\Profiles\Bruce\Desktop\tilesassets\medium.scale-140.png</OriginalPath>
|
||||
<Height>100</Height>
|
||||
<Width>100</Width>
|
||||
<X>0</X>
|
||||
<Y>0</Y>
|
||||
</ShortcutItemImage>
|
||||
BIN
shared/VisualElements/SmallIconReader.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
9
shared/VisualElements/SmallIconReader_Metadata.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0"?>
|
||||
<ShortcutItemImage xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<OriginalBytes>iVBORw0KGgoAAAANSUhEUgAAAGIAAABiCAYAAACrpQYOAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAYaSURBVHhe7ZxrqFRVFMclSqKIqLAyMope2DuCoiJIiAj80osoKgr6Zh/K3m8lJKwsRCw0sJBQ1Ii+BPUlIoqIiiCSoAdJZIlaiGWZlff22+f8z25mzpyZPTNn3+7ss37w59yzznrctZZ35p6Z8c4wDMMwDMMwDMMwDMMwDMMwDMMwDMMIY3Jy8na0eGJiYrZMxjC4IaIrdDoQDH8u2kL8JMcfbSFDoAV4GOB8XQqmWEIrtpBA3JCyiXWB4V0nt77g+67CumILqcANJZtQHxjczQqppN8SWrGFCAbwbD6ScIi5Q+ElBllCK41dCA2vykcwHJ3L4PxQNNQSWiFHMxZCg+vzlkeHXLcq52z0vsy1QL50F0JTF+Vt1gc5F6LPdVo7yS6Epi7POqwBhrPa5eS4QAOLRpILoaGRlsEw1qALlS7DDQg9gX6QWxTIn9ZCaGbgZdD8WtS2gE64fgx6DG1VWBTIn85CaCRoGTS7Dp2vsCDwn4UeQT8pTRTIn8ZCaGBO3lIZrm1EZ8l1KIg/ilQPcdyeZ40D+cd/IRqWh/NX0Wm6XAukPYKcD6CdeZU4kH+8F8I3fht6GZ0kUxQY0uHUuB/9kk0uAuSe4DBTJccPDcf9azpOpmhQ4zB0L9qVTa8myLfP5VaZ8YQGvlAz29CT6HhdigY13Esj96Bfs0mOADn2oFlKPb7QxIfqKYPz7WgJX54gl2hQ4xBq3Yf2ZMUHhLhdaI7SjTc0Unojx4F9J3oKRX3+cFDuYOo8iP7Iq/cH3x3oFKUYf2hmn3rrCtfdc8hSjicrJBrUmUmdh9GfWfEKuL4VjfQr9rRDvfWFxt3DwDPoVIVGg3IHUudR9Fde/T+wuZ/gC+SaDnl74TCI3WgZOl0pokG5A6jzONqv2l+js3U5LVyDw8BAfkPPo7lKFRXqrKCse2s3VCcqdDzgGx4JBvQ7Wo7OVMraIL17znA/EaWHqG7g9wYa+JMn0wL1MDIMYC9agUZ+6CCHu89wd+JBv9bi9zq6SuHjiXqpDQbi7nJXonNVIhjC3WtT7r4i6M4bv9c4DPVBuGlH3lL9MKS/0Yuo70vp+ByN3MvnOxTeE/zcQ9A8haeBeosGA9uPVqFzVLIN7ItQ0Dt8+L2JLlNoWqjHKUElPQz1Y13qCX5vo0sUlibqdUpQSY/MlTD8d9Clck8b9TwlqKQHk3vbtlJyawY0PGWopNENzahgEw8F7m3HKKikh1pL0JE6bTaakWOTzs9jOJtzU71kBVuQ2T0XvIB6vrqL20H6Mk3yUeRLKGAoZ8RYhtJ7ZPZQczWHtldWOT8W+9McF8uUJjTYtoSCGMtQao/MJaj7CrqWL9176cVNXtqL6EXdy1Baj8yhNHcRjjqXoZQemUNpziJcs27wOvXUtQyl88gcSjMWwaDdJzfc4/PmWMtQKo/MoaS/CJpcmveaE2sZSuOROZS0F8Fgl6nRNmIsQyk8MoeS7iIY6HI12ZW6l6Fwj8yhpLkIBrlSDfakzmUo1CNzKOktggG6O9hg6lqGwjwyh5LWIhjcGjU2EHUsQyEemUNJZxEMbK2aGopRlyF3j8yhpLEIBrVODY1Ej2VcLJdK5OqROZTxXgQNuI+obMx7qYcey+j5IQC5eWQOZbwXwXDuQu6TElX6R42W4Jr7OxvdPs6Yietty+D8LeyVyM0jcyhpPVl3wvD2qtESbhFyCwL/DQrtitw8MoeS/CJ2q9ESQyziJYV2RW4emUNJfhE/q9ESQyziOYV2RW4emUNJfhHb1GiJzkVwPg9z5/PEog5bJUrjkTkI6lyjsDShwe/Va4nORRRgvxIN/LeaFO6ROQjqRf+vY/8rNPitei1RtYgCrs9HH8m9LwrzyNwXatytkHShyS/Vb4l+iyjA9Wr0aRbUA7l7ZK6E+p+hm+SeNjRa+ZfIQhdRgP/1vfLJzSNzCXK4G8Y75dYMaPgT9V+CawMtooC4G1HpJ02XPTJ7iPkKLdTlZkHjbX95oBWuDbWIAuJvQd8oXeUi8NmCFsjcTBjABvRdhdbLbSTI4x6yPtCpB9t76AadGoZhGIZhGIZhGIZhGIZhGIZhGIbRcGbM+BeN+q7PrwKDyAAAAABJRU5ErkJggg==</OriginalBytes>
|
||||
<OriginalPath>E:\Profiles\Bruce\Desktop\tilesassets\small.scale-140.png</OriginalPath>
|
||||
<Height>50</Height>
|
||||
<Width>50</Width>
|
||||
<X>0</X>
|
||||
<Y>0</Y>
|
||||
</ShortcutItemImage>
|
||||
@@ -34,4 +34,11 @@
|
||||
<scale dpi="180">splash\manager\splash.scale-180.png</scale>
|
||||
<scale dpi="default">splash\manager\splash.png</scale>
|
||||
</resource>
|
||||
<resource id="reader">
|
||||
<scale dpi="80">splash\reader\splash.scale-80.png</scale>
|
||||
<scale dpi="100">splash\reader\splash.scale-100.png</scale>
|
||||
<scale dpi="140">splash\reader\splash.scale-140.png</scale>
|
||||
<scale dpi="180">splash\reader\splash.scale-180.png</scale>
|
||||
<scale dpi="default">splash\reader\splash.png</scale>
|
||||
</resource>
|
||||
</resources>
|
||||
BIN
shared/VisualElements/splash/reader/splash.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
shared/VisualElements/splash/reader/splash.scale-100.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
shared/VisualElements/splash/reader/splash.scale-140.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
shared/VisualElements/splash/reader/splash.scale-180.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
shared/VisualElements/splash/reader/splash.scale-80.png
Normal file
|
After Width: | Height: | Size: 8.6 KiB |
@@ -32,7 +32,7 @@
|
||||
ForegroundText='light'
|
||||
BackgroundColor='#004fe2'>
|
||||
<DefaultTile ShowName='allLogos' />
|
||||
<SplashScreen Image="VisualElements\splash\manager\splash.png"
|
||||
<SplashScreen Image="VisualElements\splash\reader\splash.png"
|
||||
BackgroundColor="#004fe2" DarkModeBackgroundColor='#002770' />
|
||||
</VisualElements>
|
||||
</Application>
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
try {
|
||||
inst.sendAsync(body, encoding, function(resp) {
|
||||
if (c) c(resp);
|
||||
}, function(err) {
|
||||
if (e) e(err);
|
||||
});
|
||||
} catch (ex) { if (e) e(ex); }
|
||||
});
|
||||
|
||||
285
shared/html/js/polyfill-winrt.js
Normal file
@@ -0,0 +1,285 @@
|
||||
(function(global) {
|
||||
function isString(obj) {
|
||||
return typeof obj === "string" || obj instanceof String;
|
||||
}
|
||||
|
||||
function isFunction(obj) {
|
||||
return typeof obj === "function";
|
||||
}
|
||||
|
||||
function isBool(obj) {
|
||||
return typeof obj === "boolean" || obj instanceof Boolean;
|
||||
}
|
||||
|
||||
function isNumber(obj) {
|
||||
return typeof obj === "number" || obj instanceof Number;
|
||||
}
|
||||
|
||||
function isDate(obj) {
|
||||
return obj instanceof Date;
|
||||
}
|
||||
|
||||
function isDevToolsOpen() {
|
||||
if (window.__IE_DEVTOOLBAR_CONSOLE_COMMAND_LINE) {
|
||||
return true; // IE10 或更早版本
|
||||
}
|
||||
if (window.__BROWSERTOOLS_CONSOLE) {
|
||||
return true; // IE11
|
||||
}
|
||||
if (window.__BROWSERTOOLS_DOMEXPLORER_ADDED) {
|
||||
return true; // IE11
|
||||
}
|
||||
return false;
|
||||
}
|
||||
var APIs = [
|
||||
"Windows.ApplicationModel.DesignMode.designModeEnabled",
|
||||
"Windows.ApplicationModel.Resources.Core.ResourceContext",
|
||||
"Windows.ApplicationModel.Resources.Core.ResourceManager",
|
||||
"Windows.ApplicationModel.Search.Core.SearchSuggestionManager",
|
||||
"Windows.ApplicationModel.Search.SearchQueryLinguisticDetails",
|
||||
"Windows.Data.Text.SemanticTextQuery",
|
||||
"Windows.Foundation.Collections.CollectionChange",
|
||||
"Windows.Foundation.Uri",
|
||||
"Windows.Globalization.ApplicationLanguages",
|
||||
"Windows.Globalization.Calendar",
|
||||
"Windows.Globalization.DateTimeFormatting",
|
||||
"Windows.Globalization.Language",
|
||||
"Windows.Phone.UI.Input.HardwareButtons",
|
||||
"Windows.Storage.ApplicationData",
|
||||
"Windows.Storage.CreationCollisionOption",
|
||||
"Windows.Storage.BulkAccess.FileInformationFactory",
|
||||
"Windows.Storage.FileIO",
|
||||
"Windows.Storage.FileProperties.ThumbnailType",
|
||||
"Windows.Storage.FileProperties.ThumbnailMode",
|
||||
"Windows.Storage.FileProperties.ThumbnailOptions",
|
||||
"Windows.Storage.KnownFolders",
|
||||
"Windows.Storage.Search.FolderDepth",
|
||||
"Windows.Storage.Search.IndexerOption",
|
||||
"Windows.Storage.Streams.RandomAccessStreamReference",
|
||||
"Windows.UI.ApplicationSettings.SettingsEdgeLocation",
|
||||
"Windows.UI.ApplicationSettings.SettingsCommand",
|
||||
"Windows.UI.ApplicationSettings.SettingsPane",
|
||||
"Windows.UI.Core.AnimationMetrics",
|
||||
"Windows.UI.Input.EdgeGesture",
|
||||
"Windows.UI.Input.EdgeGestureKind",
|
||||
"Windows.UI.Input.PointerPoint",
|
||||
"Windows.UI.ViewManagement.HandPreference",
|
||||
"Windows.UI.ViewManagement.InputPane",
|
||||
"Windows.UI.ViewManagement.UISettings",
|
||||
"Windows.UI.WebUI.Core.WebUICommandBar",
|
||||
"Windows.UI.WebUI.Core.WebUICommandBarBitmapIcon",
|
||||
"Windows.UI.WebUI.Core.WebUICommandBarClosedDisplayMode",
|
||||
"Windows.UI.WebUI.Core.WebUICommandBarIconButton",
|
||||
"Windows.UI.WebUI.Core.WebUICommandBarSymbolIcon",
|
||||
"Windows.UI.WebUI.WebUIApplication",
|
||||
];
|
||||
for (var i = 0; i < APIs.length; i++) {
|
||||
var api = APIs[i];
|
||||
apiNs = api.split(".");
|
||||
var lastNs = global;
|
||||
for (var j = 0; j < apiNs.length - 1; j++) {
|
||||
var ns = apiNs[j];
|
||||
if (typeof lastNs[ns] === "undefined") lastNs[ns] = {};
|
||||
lastNs = lastNs[ns];
|
||||
}
|
||||
var leaf = apiNs[apiNs.length - 1];
|
||||
if ("abcdefghijklmnopqrstuvwxyz".indexOf(leaf[0]) < 0) {
|
||||
lastNs[leaf] = {};
|
||||
Object.defineProperty(lastNs[leaf], "current", {
|
||||
get: function() { return null; },
|
||||
enumerable: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
Object.defineProperty(Windows.ApplicationModel.DesignMode, "designModeEnabled", {
|
||||
get: isDevToolsOpen,
|
||||
enumerable: true,
|
||||
});
|
||||
Windows.Foundation.Collections.CollectionChange = {
|
||||
reset: 0,
|
||||
itemInserted: 1,
|
||||
itemRemoved: 2,
|
||||
itemChanged: 3
|
||||
};
|
||||
Windows.Foundation.Uri = function(uri) {
|
||||
var inst = null;
|
||||
if (arguments.length === 2) {
|
||||
inst = external.Utilities.createUri2(uri, arguments[1]);
|
||||
} else {
|
||||
inst = external.Utilities.createUri(uri);
|
||||
}
|
||||
inst.jsType = this;
|
||||
return inst;
|
||||
};
|
||||
Windows.Globalization.ApplicationLanguages = {};
|
||||
Object.defineProperty(Windows.Globalization.ApplicationLanguages, "languages", {
|
||||
get: function() {
|
||||
try {
|
||||
var list = [];
|
||||
var langs = external.System.Locale.recommendLocaleNames;
|
||||
langs.forEach(function(item) {
|
||||
list.push(item);
|
||||
});
|
||||
return list;
|
||||
} catch (e) {
|
||||
return navigator.languages;
|
||||
}
|
||||
},
|
||||
enumerable: true,
|
||||
});
|
||||
Object.defineProperty(Windows.Globalization.ApplicationLanguages, "Languages", {
|
||||
get: function() {
|
||||
return Windows.Globalization.ApplicationLanguages.languages;
|
||||
},
|
||||
enumerable: true,
|
||||
});
|
||||
Windows.Globalization.LanguageLayoutDirection = {
|
||||
ltr: 0,
|
||||
rtl: 1,
|
||||
ttbLtr: 2,
|
||||
ttbRtl: 3
|
||||
};
|
||||
Windows.Globalization.Language = function(languageTag) {
|
||||
var inst = external.System.Locale.createLanguage(languageTag);
|
||||
inst.jsType = this;
|
||||
return inst;
|
||||
};
|
||||
Object.defineProperty(Windows.Globalization.Language, "currentInputMethodLanguageTag", {
|
||||
get: function() {
|
||||
return external.System.Locale.currentInputMethodLanguageTag;
|
||||
},
|
||||
enumerable: true,
|
||||
});
|
||||
Windows.Globalization.Language.isWellFormed = external.System.Locale.isWellFormed;
|
||||
Windows.Globalization.Language.getMuiCompatibleLanguageListFromLanguageTags = external.System.Locale.getMuiCompatibleLanguageListFromLanguageTags;
|
||||
Windows.Globalization.Calendar = function(args) {
|
||||
var inst = null;
|
||||
if (arguments.length === 0) {
|
||||
inst = external.Utilities.createCalendar(args);
|
||||
} else if (arguments.length === 1) {
|
||||
inst = external.Utilities.createCalendar2(args);
|
||||
} else if (arguments.length === 3) {
|
||||
inst = external.Utilities.createCalendar3(args, arguments[1], arguments[2], arguments[3]);
|
||||
} else if (arguments.length === 4) {
|
||||
inst = external.Utilities.createCalendar4(args, arguments[1], arguments[2], arguments[3], arguments[4]);
|
||||
}
|
||||
return inst;
|
||||
};
|
||||
Windows.Globalization.DateTimeFormatting = {};
|
||||
Windows.Globalization.DateTimeFormatting.DayFormat = {
|
||||
default: 1,
|
||||
none: 0
|
||||
};
|
||||
Windows.Globalization.DateTimeFormatting.DayOfWeekFormat = {
|
||||
none: 0,
|
||||
default: 1,
|
||||
abberviated: 2,
|
||||
full: 3
|
||||
};
|
||||
Windows.Globalization.DateTimeFormatting.HourFormat = {
|
||||
none: 0,
|
||||
default: 1
|
||||
};
|
||||
Windows.Globalization.DateTimeFormatting.MinuteFormat = {
|
||||
none: 0,
|
||||
default: 1
|
||||
};
|
||||
Windows.Globalization.DateTimeFormatting.MonthFormat = {
|
||||
none: 0,
|
||||
default: 1,
|
||||
abberviated: 2,
|
||||
full: 3,
|
||||
numeric: 4
|
||||
};
|
||||
Windows.Globalization.DateTimeFormatting.SecondFormat = {
|
||||
default: 1,
|
||||
none: 0
|
||||
};
|
||||
Windows.Globalization.DateTimeFormatting.YearFormat = {
|
||||
default: 1,
|
||||
none: 0,
|
||||
abberviated: 2,
|
||||
full: 3,
|
||||
};
|
||||
Windows.Globalization.DateTimeFormatting.DateTimeFormatter = function() {
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
var inst = null;
|
||||
if (args.length === 1) inst = external.Utilities.createDateTimeFormatterFromTemplate(args[0]);
|
||||
else if (args.length === 2) inst = external.Utilities.CreateDateTimeFormatterFromTemplateAndLanguages(args[0], args[1]);
|
||||
else if (args.length === 3) inst = external.Utilities.CreateDateTimeFormatterFromTimeEnums(args[0], args[1], args[2]);
|
||||
else if (args.length === 4) inst = external.Utilities.CreateDateTimeFormatterFromDateEnums(args[0], args[1], args[2], args[3]);
|
||||
else if (args.length === 5) inst = external.Utilities.CreateDateTimeFormatterFromTemplateFull(args[0], args[1], args[2], args[3], args[4]);
|
||||
else if (args.length === 8) inst = external.Utilities.CreateDateTimeFormatterFromDateTimeEnums(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
|
||||
else if (args.length === 11) inst = external.Utilities.CreateDateTimeFormatterFromDateTimeEnumsFull(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9], args[10]);
|
||||
return inst;
|
||||
};
|
||||
Windows.Storage.CreationCollisionOption = {
|
||||
generateUniqueName: 0,
|
||||
replaceExisting: 1,
|
||||
failIfExists: 2,
|
||||
openIfExists: 3
|
||||
};
|
||||
Windows.Storage.FileProperties = {
|
||||
ThumbnailType: {
|
||||
image: 0,
|
||||
icon: 1
|
||||
},
|
||||
ThumbnailMode: {
|
||||
pictureView: 0,
|
||||
videosView: 1,
|
||||
musicView: 2,
|
||||
documentsView: 3,
|
||||
listView: 4,
|
||||
singleItem: 5
|
||||
},
|
||||
ThumbnailType: {
|
||||
image: 0,
|
||||
icon: 1
|
||||
},
|
||||
VideoOrientation: {
|
||||
normal: 0,
|
||||
rotate90: 90,
|
||||
rotate180: 180,
|
||||
rotate270: 270
|
||||
},
|
||||
PhotoOrientation: {
|
||||
unspecified: 0,
|
||||
normal: 1,
|
||||
flipHorizontal: 2,
|
||||
rotate180: 3,
|
||||
flipVertical: 4,
|
||||
transpose: 5,
|
||||
rotate270: 6,
|
||||
transverse: 7,
|
||||
rotate90: 8
|
||||
},
|
||||
};
|
||||
Windows.Storage.Search = {
|
||||
FolderDepth: function() {},
|
||||
IndexerOption: function() {}
|
||||
};
|
||||
Windows.Storage.Search.FolderDepth.deep = 1;
|
||||
Windows.Storage.Search.FolderDepth.shallow = 0;
|
||||
Windows.Storage.Search.IndexerOption.useIndexerWhenAvailable = 0;
|
||||
Windows.Storage.Search.IndexerOption.onlyUseIndexer = 1;
|
||||
Windows.Storage.Search.IndexerOption.doNotUseIndexer = 2;
|
||||
Windows.Storage.Search.IndexerOption.onlyUseIndexerAndOptimizeForIndexedProperties = 3;
|
||||
Windows.UI.ApplicationSettings.SettingsEdgeLocation = {
|
||||
right: 0,
|
||||
left: 1
|
||||
};
|
||||
Windows.UI.Input.EdgeGestureKind = {
|
||||
touch: 0,
|
||||
keyboard: 1,
|
||||
mouse: 2
|
||||
};
|
||||
Windows.UI.ViewManagement.HandPreference = {
|
||||
leftHanded: 0,
|
||||
rightHanded: 1
|
||||
};
|
||||
Windows.UI.WebUI.Core.WebUICommandBarClosedDisplayMode = {
|
||||
default: 0,
|
||||
minimal: 1,
|
||||
compact: 2
|
||||
};
|
||||
})(this);
|
||||
@@ -2,6 +2,7 @@
|
||||
var strres = external.StringResources;
|
||||
var conf = external.Config.current;
|
||||
var set = conf.getSection("Settings");
|
||||
var metadata = conf.getSection("PackageReader:AppMetadatas");
|
||||
|
||||
function createLocalizedCompare(locale) {
|
||||
return function(a, b) {
|
||||
@@ -15,6 +16,26 @@
|
||||
};
|
||||
}
|
||||
var pagemgr = new PageManager();
|
||||
(function() {
|
||||
var nstrutil = Bridge.NString;
|
||||
var boolTrue = ["true", "1", "yes", "on", "y", "t", "zhen", "真"];
|
||||
var boolFalse = ["false", "0", "no", "off", "n", "f", "jia", "假"];
|
||||
global.parseBool = function(str) {
|
||||
if (typeof str === "boolean") return str;
|
||||
str = "" + str;
|
||||
for (var i = 0; i < boolTrue.length; i++) {
|
||||
if (nstrutil.equals(str, boolTrue[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < boolFalse.length; i++) {
|
||||
if (nstrutil.equals(str, boolFalse[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
})();
|
||||
OnLoad.add(function() {
|
||||
var mgr = Package.manager;
|
||||
var nstr = Bridge.NString;
|
||||
@@ -24,8 +45,59 @@
|
||||
return Bridge.String.tolower(Bridge.String.trim(item.Identity.FullName));
|
||||
});
|
||||
var themeColor = Bridge.UI.themeColor;
|
||||
var reader = Package.reader;
|
||||
var appitems = [
|
||||
"Id",
|
||||
"StartPage",
|
||||
"EntryPoint",
|
||||
"Executable",
|
||||
"BackgroundColor",
|
||||
"DisplayName",
|
||||
"Description",
|
||||
"ShortName",
|
||||
"ForegroundText",
|
||||
"SmallLogo",
|
||||
"Square30x30Logo",
|
||||
"Square44x44Logo",
|
||||
"Square70x70Logo",
|
||||
"Square71x71Logo",
|
||||
"Logo",
|
||||
"Square150x150Logo",
|
||||
"WideLogo",
|
||||
"Wide310x150Logo",
|
||||
"Square310x310Logo",
|
||||
"Tall150x310Logo",
|
||||
"LockScreenLogo",
|
||||
"LockScreenNotification",
|
||||
"DefaultSize",
|
||||
"AppListEntry",
|
||||
"VisualGroup",
|
||||
"MinWidth",
|
||||
];
|
||||
var defaultItems = [
|
||||
"Id",
|
||||
"DisplayName",
|
||||
"BackgroundColor",
|
||||
"ForegroundText",
|
||||
"ShortName",
|
||||
"Square44x44Logo",
|
||||
"SmallLogo"
|
||||
];
|
||||
var metaitemlist = [];
|
||||
for (var i = 0; i < appitems.length; i++) {
|
||||
var item = appitems[i];
|
||||
var isenable = metadata.getKey(item).value;
|
||||
if (isenable === null || isenable === void 0 || isenable === "") {
|
||||
isenable = defaultItems.indexOf(item) >= 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);
|
||||
@@ -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);
|
||||
|
||||
@@ -8,10 +8,13 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script type="text/javascript" src="js/module.js"></script>
|
||||
<script type="text/javascript" src="js/polyfill-ie.js"></script>
|
||||
<script type="text/javascript" src="js/polyfill-winrt.js"></script>
|
||||
<link rel="stylesheet" href="libs/winjs/1.0/css/ui-light.css" id="winjs-style-1">
|
||||
<link rel="stylesheet" href="libs/winjs/2.0/css/ui-light.css" id="winjs-style">
|
||||
<script type="text/javascript" src="libs/winjs/1.0/js/base.js"></script>
|
||||
<script type="text/javascript" src="libs/winjs/1.0/js/ui.js"></script>
|
||||
<script type="text/javascript" src="libs/winjs/1.0/js/en-us/base.strings.js"></script>
|
||||
<script type="text/javascript" src="libs/winjs/1.0/js/en-us/ui.strings.js"></script>
|
||||
<script type="text/javascript" src="js/color.js"></script>
|
||||
<script type="text/javascript" src="js/promise.js"></script>
|
||||
<script type="text/javascript" src="js/bridge.js"></script>
|
||||
@@ -60,13 +63,13 @@
|
||||
<div class="page full guide fold">
|
||||
<main class="main">
|
||||
<div id="page-reader" style="display: none;" class="ispage padding">
|
||||
<h2>读取</h2>
|
||||
<p>请选择一个包,获取其信息。</p>
|
||||
<h2 data-res-resxml="READER_READER_TITLE"></h2>
|
||||
<p data-res-resxml="READER_READER_DESC"></p>
|
||||
<div>
|
||||
<label for="read-pkgpath">文件路径</label>
|
||||
<label for="read-pkgpath" data-res-resxml="READER_READER_FILEPATH"></label>
|
||||
<div class="itemrow">
|
||||
<input type="text" id="read-pkgpath" style="margin-right: 10px;">
|
||||
<button id="read-browse">浏览</button>
|
||||
<button id="read-browse" data-res-resxml="READER_READER_BROWSER"></button>
|
||||
</div>
|
||||
<script>
|
||||
(function() {
|
||||
@@ -76,7 +79,9 @@
|
||||
readBrowse.onclick = function() {
|
||||
var explorer = external.Storage.Explorer;
|
||||
explorer.file(
|
||||
"{appxpkg}|*.appx;*.appxbundle;*.msix;*.msixbundle|{allfiles}|*.*",
|
||||
"{appxpkg}|*.appx;*.appxbundle;*.msix;*.msixbundle|{allfiles}|*.*"
|
||||
.replace("{appxpkg}", stringRes("READER_READER_APPXFILE"))
|
||||
.replace("{allfiles}", stringRes("READER_READER_ALLFILES")),
|
||||
lastDir,
|
||||
function(result) {
|
||||
if (!result) return;
|
||||
@@ -90,20 +95,20 @@
|
||||
</div>
|
||||
<div class="itemrow">
|
||||
<input type="checkbox" id="read-usepri" style="margin-left: 0;">
|
||||
<label for="read-usepri">需要解析 PRI 资源文件</label>
|
||||
<label for="read-usepri" data-res-resxml="READER_READER_USEPRI"></label>
|
||||
</div>
|
||||
<style>
|
||||
.part-read-button {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
</style>
|
||||
<button id="read-btn" class="part-read-button">读取</button>
|
||||
<button id="read-result-save" class="part-read-button">将读取结果保存为文件</button>
|
||||
<button id="read-result-xml" class="part-read-button">保存为 XML 文件</button>
|
||||
<button id="read-result-json" class="part-read-button">保存为 JSON 文件</button>
|
||||
<button id="read-btn" class="part-read-button" data-res-resxml="READER_READER_READ"></button>
|
||||
<button id="read-result-save" class="part-read-button" data-res-resxml="READER_READER_SAVEFILE"></button>
|
||||
<button id="read-result-xml" class="part-read-button" data-res-resxml="READER_READER_SAVEXML"></button>
|
||||
<button id="read-result-json" class="part-read-button" data-res-resxml="READER_READER_SAVEJSON"></button>
|
||||
<br>
|
||||
<progress id="read-loading" style="display: none;"></progress>
|
||||
<p style="margin-bottom: 2px; margin-top: 5px;">读取结果:</p>
|
||||
<p style="margin-bottom: 2px; margin-top: 5px;" data-res-resxml="READER_READER_RESULT"></p>
|
||||
<iframe id="read-result" width="100%" frameborder="0" src="report.html"></iframe>
|
||||
<script>
|
||||
(function() {
|
||||
@@ -112,7 +117,7 @@
|
||||
|
||||
function readResultResizeEvent(e) {
|
||||
var parent = readResult.parentElement.parentElement;
|
||||
var newHeight = parent.getBoundingClientRect().height - readResult.getBoundingClientRect().top - 24;
|
||||
var newHeight = parent.getBoundingClientRect().height - readResult.getBoundingClientRect().top - 60;
|
||||
//console.log(e, parent.getBoundingClientRect().height, readResult.getBoundingClientRect().top, newHeight);
|
||||
readResult.style.height = parseInt(newHeight) + "px";
|
||||
}
|
||||
@@ -123,6 +128,8 @@
|
||||
</script>
|
||||
<script>
|
||||
(function(global) {
|
||||
var conf = external.Config.current;
|
||||
var set = conf.getSection("Settings");
|
||||
var readBtn = document.getElementById("read-btn");
|
||||
var readResult = document.getElementById("read-result");
|
||||
var readPkgpath = document.getElementById("read-pkgpath");
|
||||
@@ -132,6 +139,7 @@
|
||||
var readSave = document.getElementById("read-result-save");
|
||||
var readToXml = document.getElementById("read-result-xml");
|
||||
var readToJson = document.getElementById("read-result-json");
|
||||
readUsepri.checked = set.getKey("PackageReader:DefaultParsingPriFile").readBool();
|
||||
readResult.style.display = "none";
|
||||
readBtn.onclick = function() {
|
||||
var self = this;
|
||||
@@ -160,7 +168,7 @@
|
||||
onCompleted();
|
||||
readResult.contentWindow.setReport({
|
||||
status: false,
|
||||
message: "请选择一个有效文件"
|
||||
message: stringRes("READER_READER_PLEASESELECT")
|
||||
});
|
||||
self.disabled = false;
|
||||
return;
|
||||
@@ -187,7 +195,7 @@
|
||||
progress.classList.add("win-ring");
|
||||
progress.style.color = "white";
|
||||
var span = document.createElement("span");
|
||||
span.textContent = "正在保存文件";
|
||||
span.textContent = stringRes("READER_READER_SAVINGHTML");
|
||||
progress.style.marginRight = "10px";
|
||||
cont.setAttribute("style", "display: flex; flex-direction: row; align-items: center; display: -ms-flexbox; -ms-flex-direction: row; -ms-align-items: center;")
|
||||
cont.appendChild(progress);
|
||||
@@ -199,7 +207,7 @@
|
||||
return dlg.show().then(function(id) {
|
||||
return new Promise(function(c, e) {
|
||||
external.Storage.save(
|
||||
"{htmlfile}|*.html;*.htm",
|
||||
"{htmlfile}|*.html;*.htm".replace("{htmlfile}", stringRes("READER_READER_HTMLFILE")),
|
||||
lastDir,
|
||||
"report-" + new Date().getTime(),
|
||||
c
|
||||
@@ -216,7 +224,7 @@
|
||||
});
|
||||
}).then(null, function(err) {
|
||||
dlg.hide().then(function() {
|
||||
dlg.title = "保存时发生问题";
|
||||
dlg.title = stringRes("READER_READER_SAVEERR");
|
||||
dlg.content = err.message || err;
|
||||
dlg.commands.push(new WinJS.UI.ContentDialogCommand(
|
||||
getPublicRes(800)
|
||||
@@ -238,7 +246,7 @@
|
||||
progress.classList.add("win-ring");
|
||||
progress.style.color = "white";
|
||||
var span = document.createElement("span");
|
||||
span.textContent = "正在生成 JSON 文件,请稍候... \n这可能需要比较长的时间。";
|
||||
span.textContent = stringRes("READER_READER_SAVEINGJSON");
|
||||
progress.style.marginRight = "10px";
|
||||
cont.setAttribute("style", "display: flex; flex-direction: row; align-items: center; display: -ms-flexbox; -ms-flex-direction: row; -ms-align-items: center;")
|
||||
cont.appendChild(progress);
|
||||
@@ -250,7 +258,7 @@
|
||||
return dlg.show().then(function(id) {
|
||||
return new Promise(function(c, e) {
|
||||
external.Storage.save(
|
||||
"{jsonzipfile}|*.zip",
|
||||
"{jsonzipfile}|*.zip".replace("{jsonzipfile}", stringRes("READER_READER_JSONFILE")),
|
||||
lastDir,
|
||||
"report-" + new Date().getTime(),
|
||||
c
|
||||
@@ -259,7 +267,7 @@
|
||||
}).then(function(filepath) {
|
||||
return new Promise(function(c, e) {
|
||||
if (!readPkgpath.value) {
|
||||
e(new Error("请选择一个有效文件"));
|
||||
e(new Error(stringRes("READER_READER_PLEASESELECT")));
|
||||
return;
|
||||
}
|
||||
try {
|
||||
@@ -284,7 +292,7 @@
|
||||
});
|
||||
}).then(null, function(err) {
|
||||
dlg.hide().then(function() {
|
||||
dlg.title = "保存时发生问题";
|
||||
dlg.title = stringRes("READER_READER_SAVEERR");
|
||||
dlg.content = err.message || err;
|
||||
dlg.commands.push(new WinJS.UI.ContentDialogCommand(
|
||||
getPublicRes(800)
|
||||
@@ -307,7 +315,7 @@
|
||||
progress.classList.add("win-ring");
|
||||
progress.style.color = "white";
|
||||
var span = document.createElement("span");
|
||||
span.textContent = "正在生成 XML 文件,请稍候... \n这可能需要比较长的时间。";
|
||||
span.textContent = stringRes("READER_READER_SAVEINGXML");
|
||||
progress.style.marginRight = "10px";
|
||||
cont.setAttribute("style", "display: flex; flex-direction: row; align-items: center; display: -ms-flexbox; -ms-flex-direction: row; -ms-align-items: center;")
|
||||
cont.appendChild(progress);
|
||||
@@ -319,7 +327,7 @@
|
||||
return dlg.show().then(function(id) {
|
||||
return new Promise(function(c, e) {
|
||||
external.Storage.save(
|
||||
"{xmlzipfile}|*.zip",
|
||||
"{xmlzipfile}|*.zip".replace("{xmlzipfile}", stringRes("READER_READER_XMLFILE")),
|
||||
lastDir,
|
||||
"report-" + new Date().getTime(),
|
||||
c
|
||||
@@ -329,7 +337,7 @@
|
||||
return new Promise(function(c, e) {
|
||||
try {
|
||||
if (!readPkgpath.value) {
|
||||
e(new Error("请选择一个有效文件"));
|
||||
e(new Error(stringRes("READER_READER_PLEASESELECT")));
|
||||
return;
|
||||
}
|
||||
var pkg = Package.reader.package(readPkgpath.value);
|
||||
@@ -353,7 +361,7 @@
|
||||
});
|
||||
}).then(null, function(err) {
|
||||
dlg.hide().then(function() {
|
||||
dlg.title = "保存时发生问题";
|
||||
dlg.title = stringRes("READER_READER_SAVEERR");
|
||||
dlg.content = err.message || err;
|
||||
dlg.commands.push(new WinJS.UI.ContentDialogCommand(
|
||||
getPublicRes(800)
|
||||
@@ -369,35 +377,35 @@
|
||||
</script>
|
||||
</div>
|
||||
<div id="page-acquire" style="display: none;" class="ispage padding">
|
||||
<h2>获取</h2>
|
||||
<h2 data-res-resxml="READER_ACQUIRE_TITLE"></h2>
|
||||
<div id="acquire-forbidden" style="width: 100%;">
|
||||
<p>由于来自 store.rg-adguard.net 的限制,现在暂时无法实现对包的获取。请自行打开下面 URL 进行访问。</p>
|
||||
<p data-res-resxml="READER_ACQUIRE_PROHIBIT"></p>
|
||||
<a onclick="external.Process.open ('https://store.rg-adguard.net')">store.rg-adguard.net</a>
|
||||
</div>
|
||||
<div id="acquire-enable" style="width: 100%;">
|
||||
<p>请在下面的输入框中输入要查询的内容,设置好参数后将进行查询。</p>
|
||||
<p data-res-resxml="READER_ACQUIRE_DESC"></p>
|
||||
<div>
|
||||
<div>
|
||||
<input type="text" id="acquire-input">
|
||||
<select id="acquire-valuetype" name="type">
|
||||
<option value="url">分享链接</option>
|
||||
<option value="ProductId">产品 ID</option>
|
||||
<option value="PackageFamilyName">包系列名</option>
|
||||
<option value="CategoryId">类别 ID</option>
|
||||
<select id="acquire-valuetype" name="type" value="url">
|
||||
<option value="url" data-res-resxml="READER_ACQUIRE_SHAREDURL"></option>
|
||||
<option value="ProductId" data-res-resxml="READER_ACQUIRE_PRODUCTID"></option>
|
||||
<option value="PackageFamilyName" data-res-resxml="READER_ACQUIRE_PFN"></option>
|
||||
<option value="CategoryId" data-res-resxml="READER_ACQUIRE_CATEGORYID"></option>
|
||||
</select>
|
||||
<select id="acquire-channel" name="ring">
|
||||
<option title="Windows Insider Fast" value="WIF">快速</option>
|
||||
<option title="Windows Insider Slow" value="WIS">慢速</option>
|
||||
<option title="Release Preview" value="RP" selected>发布预览</option>
|
||||
<option title="Default OS" value="Retail">正式</option>
|
||||
<select id="acquire-channel" name="ring" value="RP">
|
||||
<option title="Windows Insider Fast" value="WIF" data-res-resxml="READER_ACQUIRE_WIF"></option>
|
||||
<option title="Windows Insider Slow" value="WIS" data-res-resxml="READER_ACQUIRE_WIS"></option>
|
||||
<option title="Release Preview" value="RP" data-res-resxml="READER_ACQUIRE_RP"></option>
|
||||
<option title="Default OS" value="Retail" data-res-resxml="READER_ACQUIRE_RETAIL"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<div class="itemrow">
|
||||
<input type="checkbox" id="acquire-smartquery" style="margin-left: 0px;">
|
||||
<label for="acquire-smartquery">自动查询</label>
|
||||
<label for="acquire-smartquery" data-res-resxml="READER_ACQUIRE_SMARTQUERY"></label>
|
||||
</div>
|
||||
<button id="acquire-query">查询</button>
|
||||
<button id="acquire-query" data-res-resxml="READER_ACQUIRE_QUERY"></button>
|
||||
</div>
|
||||
</div>
|
||||
<style>
|
||||
@@ -492,17 +500,19 @@
|
||||
}
|
||||
</style>
|
||||
<div id="acquire-template" class="acquire-item" style="display: none;">
|
||||
<div id="name" class="top" title="Identity Name">Identity Name</div>
|
||||
<div id="name" class="top" title="Identity Name"></div>
|
||||
<div class="medium">
|
||||
<div id="ext" title="File Type">Appx</div>
|
||||
<div id="version" title="Version">1.0.0.0</div>
|
||||
<div id="architecture" title="Processor Architecture">neutral</div>
|
||||
<div id="ext" title="File Type"></div>
|
||||
<div id="version" title="Version"></div>
|
||||
<div id="architecture" title="Processor Architecture"></div>
|
||||
<div id="publisherId" title="Identity Publisher Id"></div>
|
||||
<div id="size" title="File Size"></div>
|
||||
</div>
|
||||
<div class="bottom">
|
||||
<div id="hashpart"><span>SHA-1: </span><span id="hash"></span></div>
|
||||
<div><a download id="download" href="">点击下载</a></div>
|
||||
<div>
|
||||
<a download id="download" href="" data-res-resxml="READER_ACQUIRE_CLICKDOWNLOAD"></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="acquire-loading">
|
||||
@@ -514,17 +524,17 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="acquire-result" style="width: 100%;">
|
||||
<p style="font-weight: normal;" title="Category ID"><span>类别 ID</span>: <span id="acquire-categoryid" style="user-select: text; -ms-user-select: element;"></span></p>
|
||||
<h3>以下可能为检索到的应用</h3>
|
||||
<p style="font-weight: normal;" title="Category ID"><span data-res-resxml="READER_ACQUIRE_CATEGORYID"></span>: <span id="acquire-categoryid" style="user-select: text; -ms-user-select: element;"></span></p>
|
||||
<h3 data-res-resxml="READER_ACQUIRE_RESULTAPPS"></h3>
|
||||
<div id="acquire-list-app" style="width: 100%;"></div>
|
||||
<h3>以下可能为检索到的依赖项</h3>
|
||||
<h3 data-res-resxml="READER_ACQUIRE_RESULTDEPS"></h3>
|
||||
<div id="acquire-list-dep" style="width: 100%;"></div>
|
||||
</div>
|
||||
<script>
|
||||
(function(global) {
|
||||
var conf = external.Config.current;
|
||||
var set = conf.getSection("Settings");
|
||||
var isForbidden = !set.getKey("EnableAcquire").readBool(false);
|
||||
var isForbidden = !set.getKey("PackageReader:EnableAcquire").readBool(false);
|
||||
var acquireInput = document.getElementById("acquire-input");
|
||||
var acquireValuetype = document.getElementById("acquire-valuetype");
|
||||
var acquireChannel = document.getElementById("acquire-channel");
|
||||
@@ -578,7 +588,7 @@
|
||||
keys.forEach(function(k, i) {
|
||||
var listview = listView[k];
|
||||
var p = document.createElement("p");
|
||||
p.textContent = "还没有内容...";
|
||||
p.textContent = stringRes("READER_ACQUIRE_NOCONTENT");
|
||||
listview.emptyView = p;
|
||||
});
|
||||
acquireLoading.statusBar = new TransitionPanel(acquireLoading, {
|
||||
@@ -607,7 +617,7 @@
|
||||
acquireValuetype.disabled =
|
||||
acquireChannel.disabled = true;
|
||||
queryFunc = StoreRG.test;
|
||||
acquireLoadingLabel.textContent = "正在查询...";
|
||||
acquireLoadingLabel.textContent = stringRes("READER_ACQUIRE_QUERYING");
|
||||
queryFunc(acquireInput.value, acquireValuetype.value, acquireChannel.value).then(function(result) {
|
||||
acquireCategoryid.textContent = result.categoryId;
|
||||
var applist = [];
|
||||
@@ -628,7 +638,7 @@
|
||||
return item.file;
|
||||
});
|
||||
listView.deps.refresh();
|
||||
acquireLoadingLabel.textContent = "已获取到 {0} 个信息"
|
||||
acquireLoadingLabel.textContent = stringRes("READER_ACQUIRE_RESULTCNT")
|
||||
.replace("{0}", applist.length + deplist.length);
|
||||
}, function(err) {
|
||||
dataSrc.apps.clear();
|
||||
@@ -654,6 +664,13 @@
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
<div id="page-search" style="display: none;" class="ispage padding">
|
||||
<h2 data-res-resxml="READER_SEARCH_TITLE"></h2>
|
||||
<div id="search-forbidden" style="width: 100%;">
|
||||
<p data-res-resxml="READER_SEARCH_PROHIBIT"></p>
|
||||
<a onclick="external.Process.open ('https://dbox.tools')">dbox.tools</a>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<aside class="win-ui-dark">
|
||||
<nav class="container">
|
||||
@@ -677,15 +694,19 @@
|
||||
<ul class="list">
|
||||
<li id="tag-reader">
|
||||
<div role="img"></div>
|
||||
<span class="win-type-base" data-res-resxml="MANAGER_MANAGE"></span>
|
||||
<span class="win-type-base" data-res-resxml="READER_READER_TITLE"></span>
|
||||
</li>
|
||||
<li id="tag-acquire">
|
||||
<div role="img"></div>
|
||||
<span class="win-type-base" data-res-resxml="MANAGER_MANAGE"></span>
|
||||
<span class="win-type-base" data-res-resxml="READER_ACQUIRE_TITLE"></span>
|
||||
</li>
|
||||
<li id="tag-search">
|
||||
<div role="img"></div>
|
||||
<span class="win-type-base" data-res-resxml="READER_SEARCH_TITLE"></span>
|
||||
</li>
|
||||
<li id="tag-settings">
|
||||
<div role="img"></div>
|
||||
<span class="win-type-base" data-res-resxml="MANAGER_SETTINGS"></span>
|
||||
<span class="win-type-base" data-res-resxml="READER_SETTINGS_TITLE"></span>
|
||||
</li>
|
||||
<script>
|
||||
(function(global) {
|
||||
|
||||
@@ -195,6 +195,42 @@
|
||||
</table>
|
||||
<script>
|
||||
(function(global) {
|
||||
var imageItem = [
|
||||
"LockScreenLogo",
|
||||
"Logo",
|
||||
"SmallLogo",
|
||||
"Square150x150Logo",
|
||||
"Square30x30Logo",
|
||||
"Square310x310Logo",
|
||||
"Square44x44Logo",
|
||||
"Square70x70Logo",
|
||||
"Square71x71Logo",
|
||||
"Tall150x310Logo",
|
||||
"WideLogo",
|
||||
"Wide310x150Logo"
|
||||
];
|
||||
|
||||
function toLowerCase(str) {
|
||||
if (typeof str !== "string") return "";
|
||||
return str.replace(/[A-Z]/g, function(ch) {
|
||||
return String.fromCharCode(ch.charCodeAt(0) + 32);
|
||||
});
|
||||
}
|
||||
|
||||
function trim(str) {
|
||||
return str.replace(/^\s+|\s+$/g, "");
|
||||
}
|
||||
|
||||
function isImageItem(item) {
|
||||
var tl = trim(toLowerCase(item));
|
||||
for (var i = 0; i < imageItem.length; i++) {
|
||||
var lower = trim(toLowerCase(imageItem[i]));
|
||||
if (lower == tl) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (typeof Array.prototype.forEach !== "function") {
|
||||
Array.prototype.forEach = function(callback, thisArg) {
|
||||
var T, k;
|
||||
@@ -317,7 +353,7 @@
|
||||
var tdv = document.createElement("td");
|
||||
tdk.textContent = key;
|
||||
tdv.textContent = t[key];
|
||||
if (typeof t[key + "_Base64"] !== "undefined") {
|
||||
if (typeof t[key + "_Base64"] !== "undefined" && isImageItem(key)) {
|
||||
tdv.innerHTML = "";
|
||||
var img = document.createElement("img");
|
||||
img.src = t[key + "_Base64"];
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
var settingItems = {
|
||||
appinstaller: getSettingsItem("appinstaller.html", getLibRes("appinstaller.exe", 300)),
|
||||
manager: getSettingsItem("manager.html", getStringRes("MANAGER_APPTITLE")),
|
||||
reader: getSettingsItem("reader.html", getStringRes("READER_APPTITLE")),
|
||||
settings: getSettingsItem("settings.html", getLibRes("settings.exe", 200)),
|
||||
};
|
||||
Object.defineProperty(global, "settingPages", {
|
||||
|
||||
56
shared/html/settings/reader.html
Normal file
@@ -0,0 +1,56 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Package Manager Settings</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script type="text/javascript" src="../js/module.js"></script>
|
||||
<script type="text/javascript" src="../js/polyfill-ie.js"></script>
|
||||
<link rel="stylesheet" href="../libs/winjs/2.0/css/ui-light.css" id="winjs-style">
|
||||
<script type="text/javascript" src="../libs/winjs/1.0/js/base.js"></script>
|
||||
<script type="text/javascript" src="../libs/winjs/1.0/js/ui.js"></script>
|
||||
<script type="text/javascript" src="../js/color.js"></script>
|
||||
<script type="text/javascript" src="../js/promise.js"></script>
|
||||
<script type="text/javascript" src="../js/bridge.js"></script>
|
||||
<script type="text/javascript" src="../js/dpimodes.js"></script>
|
||||
<script type="text/javascript" src="../js/resources.js"></script>
|
||||
<script type="text/javascript" src="../js/animation.js"></script>
|
||||
<link rel="stylesheet" href="../fonts/fonts.css">
|
||||
<script type="text/javascript" src="../js/event.js"></script>
|
||||
<script type="text/javascript" src="../js/tileback.js"></script>
|
||||
<script type="text/javascript" src="../js/load.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../libs/msgbox/contentdlg.css">
|
||||
<script type="text/javascript" src="../libs/msgbox/contentdlg.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../libs/msgbox/msgbox.css">
|
||||
<script type="text/javascript" src="../libs/msgbox/msgbox.js"></script>
|
||||
<script type="text/javascript" src="../js/init.js"></script>
|
||||
<script type="text/javascript" src="initsame.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="page.css">
|
||||
<script type="text/javascript" src="reader/preinit.js"></script>
|
||||
<script type="text/javascript" src="reader/items.js"></script>
|
||||
<script type="text/javascript" src="reader/init.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="settingpage" class="pagecontainer full">
|
||||
<div class="page full guide">
|
||||
<aside class="left win-ui-dark">
|
||||
<header aria-label="Header content" role="banner" class="titlebanner" id="pagebanner" style="height: 120px;">
|
||||
<button id="back" class="win-backbutton pagetitlewb-backbutton" onclick="Bridge.Frame.callEvent ('InvokeBackPage')" style="margin-left: 20px; transform: scale(0.72);"></button>
|
||||
<h2 class="titlearea win-type-ellipsis" id="apptitle" style="">
|
||||
<span class="pagetitlewb-title" id="apptitlestr" style="margin-left: 10px; margin-right: 20px;" data-res-resxml="READER_APPTITLE"></span>
|
||||
</h2>
|
||||
</header>
|
||||
<nav class="container">
|
||||
<ul class="list">
|
||||
</ul>
|
||||
</nav>
|
||||
</aside>
|
||||
<iframe class="main right" defer loading="lazy" async></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
158
shared/html/settings/reader/appitems.html
Normal file
@@ -0,0 +1,158 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>App Installer Settings</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script type="text/javascript" src="../../js/module.js"></script>
|
||||
<script type="text/javascript" src="../../js/polyfill-ie.js"></script>
|
||||
<link rel="stylesheet" href="../../libs/winjs/2.0/css/ui-light.css" id="winjs-style">
|
||||
<script type="text/javascript" src="../../libs/winjs/1.0/js/base.js"></script>
|
||||
<script type="text/javascript" src="../../libs/winjs/1.0/js/ui.js"></script>
|
||||
<script type="text/javascript" src="../../js/color.js"></script>
|
||||
<script type="text/javascript" src="../../js/promise.js"></script>
|
||||
<script type="text/javascript" src="../../js/bridge.js"></script>
|
||||
<script type="text/javascript" src="../../js/dpimodes.js"></script>
|
||||
<script type="text/javascript" src="../../js/resources.js"></script>
|
||||
<script type="text/javascript" src="../../js/animation.js"></script>
|
||||
<link rel="stylesheet" href="../../fonts/fonts.css">
|
||||
<script type="text/javascript" src="../../js/event.js"></script>
|
||||
<script type="text/javascript" src="../../js/tileback.js"></script>
|
||||
<script type="text/javascript" src="../../js/load.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../../libs/msgbox/contentdlg.css">
|
||||
<script type="text/javascript" src="../../libs/msgbox/contentdlg.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../../libs/msgbox/msgbox.css">
|
||||
<script type="text/javascript" src="../../libs/msgbox/msgbox.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../../libs/toggle/toggle.css">
|
||||
<script type="text/javascript" src="../../libs/toggle/toggle.js"></script>
|
||||
<script type="text/javascript" src="../../js/init.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../page.css">
|
||||
<link rel="stylesheet" type="text/css" href="../subpage.css">
|
||||
<script type="text/javascript" src="preinit.js"></script>
|
||||
<script type="text/javascript" src="initsame.js"></script>
|
||||
<script>
|
||||
try {
|
||||
window.parent.setItemHighlight("appitems");
|
||||
} catch (e) {}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="pagecontainer full pagesection">
|
||||
<div class="section padding">
|
||||
<div class="bottom-compensate">
|
||||
<h2 id="page-title" data-res-resxml="READER_SETTINGS_APPITEMS"></h2>
|
||||
<div class="win-settings-section">
|
||||
<p data-res-resxml="READER_SETTINGS_APPITEMS_DESC"></p>
|
||||
<style>
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
table th,
|
||||
table td {
|
||||
border: 1px solid #ccc;
|
||||
padding: 5px;
|
||||
}
|
||||
</style>
|
||||
<table style="max-width: 100%;">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th data-res-resxml="READER_SETTINGS_APPITEMS_ITEM"></th>
|
||||
<th data-res-resxml="READER_SETTINGS_APPITEMS_DESCRIPTION"></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="appitem-list"></tbody>
|
||||
</table>
|
||||
<script>
|
||||
(function() {
|
||||
"use strict";
|
||||
var appItemList = document.getElementById("appitem-list");
|
||||
var ini = Bridge.External.Config.GetConfig();
|
||||
var appitemset = ini.getSection("PackageReader:AppMetadatas");
|
||||
var appitems = [
|
||||
"Id",
|
||||
"StartPage",
|
||||
"EntryPoint",
|
||||
"Executable",
|
||||
"BackgroundColor",
|
||||
"DisplayName",
|
||||
"Description",
|
||||
"ShortName",
|
||||
"ForegroundText",
|
||||
"SmallLogo",
|
||||
"Square30x30Logo",
|
||||
"Square44x44Logo",
|
||||
"Square70x70Logo",
|
||||
"Square71x71Logo",
|
||||
"Logo",
|
||||
"Square150x150Logo",
|
||||
"WideLogo",
|
||||
"Wide310x150Logo",
|
||||
"Square310x310Logo",
|
||||
"Tall150x310Logo",
|
||||
"LockScreenLogo",
|
||||
"LockScreenNotification",
|
||||
"DefaultSize",
|
||||
"AppListEntry",
|
||||
"VisualGroup",
|
||||
"MinWidth",
|
||||
];
|
||||
var defaultItems = [
|
||||
"Id",
|
||||
"DisplayName",
|
||||
"BackgroundColor",
|
||||
"ForegroundText",
|
||||
"ShortName",
|
||||
"Square44x44Logo",
|
||||
"SmallLogo"
|
||||
];
|
||||
for (var i = 0; i < appitems.length; i++) {
|
||||
var item = appitems[i];
|
||||
var isenable = appitemset.getKey(item).value;
|
||||
if (isenable === null || isenable === void 0 || isenable === "") {
|
||||
isenable = defaultItems.indexOf(item) >= 0;
|
||||
}
|
||||
var dispItem = stringRes("APPMETADATA_" + item);
|
||||
var tr = document.createElement("tr");
|
||||
var tdCheck = document.createElement("td");
|
||||
var tdItem = document.createElement("td");
|
||||
var tdDesc = document.createElement("td");
|
||||
tr.appendChild(tdCheck);
|
||||
tr.appendChild(tdItem);
|
||||
tr.appendChild(tdDesc);
|
||||
var checkbox = document.createElement("input");
|
||||
tdCheck.appendChild(checkbox);
|
||||
checkbox.type = "checkbox";
|
||||
checkbox.checked = isenable;
|
||||
checkbox.id = "appitem_" + item;
|
||||
checkbox.setAttribute("data-metadata", item);
|
||||
var label = document.createElement("label");
|
||||
tdItem.appendChild(label);
|
||||
label.setAttribute("for", checkbox.id);
|
||||
label.style.fontWeight = "normal";
|
||||
label.textContent = item;
|
||||
label.title = item;
|
||||
var labelDesc = document.createElement("label");
|
||||
tdDesc.appendChild(labelDesc);
|
||||
labelDesc.textContent = dispItem;
|
||||
labelDesc.title = dispItem;
|
||||
labelDesc.setAttribute("for", checkbox.id);
|
||||
labelDesc.style.fontWeight = "normal";
|
||||
appItemList.appendChild(tr);
|
||||
checkbox.onchange = function() {
|
||||
appitemset.getKey(this.getAttribute("data-metadata")).value = this.checked;
|
||||
}
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
192
shared/html/settings/reader/general.html
Normal file
@@ -0,0 +1,192 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>App Installer Settings</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script type="text/javascript" src="../../js/module.js"></script>
|
||||
<script type="text/javascript" src="../../js/polyfill-ie.js"></script>
|
||||
<link rel="stylesheet" href="../../libs/winjs/2.0/css/ui-light.css" id="winjs-style">
|
||||
<script type="text/javascript" src="../../libs/winjs/1.0/js/base.js"></script>
|
||||
<script type="text/javascript" src="../../libs/winjs/1.0/js/ui.js"></script>
|
||||
<script type="text/javascript" src="../../js/color.js"></script>
|
||||
<script type="text/javascript" src="../../js/promise.js"></script>
|
||||
<script type="text/javascript" src="../../js/bridge.js"></script>
|
||||
<script type="text/javascript" src="../../js/dpimodes.js"></script>
|
||||
<script type="text/javascript" src="../../js/resources.js"></script>
|
||||
<script type="text/javascript" src="../../js/animation.js"></script>
|
||||
<link rel="stylesheet" href="../../fonts/fonts.css">
|
||||
<script type="text/javascript" src="../../js/event.js"></script>
|
||||
<script type="text/javascript" src="../../js/tileback.js"></script>
|
||||
<script type="text/javascript" src="../../js/load.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../../libs/msgbox/contentdlg.css">
|
||||
<script type="text/javascript" src="../../libs/msgbox/contentdlg.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../../libs/msgbox/msgbox.css">
|
||||
<script type="text/javascript" src="../../libs/msgbox/msgbox.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../../libs/toggle/toggle.css">
|
||||
<script type="text/javascript" src="../../libs/toggle/toggle.js"></script>
|
||||
<script type="text/javascript" src="../../js/init.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../page.css">
|
||||
<link rel="stylesheet" type="text/css" href="../subpage.css">
|
||||
<script type="text/javascript" src="preinit.js"></script>
|
||||
<script type="text/javascript" src="initsame.js"></script>
|
||||
<script>
|
||||
try {
|
||||
window.parent.setItemHighlight("general");
|
||||
} catch (e) {}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="pagecontainer full pagesection">
|
||||
<div class="section padding">
|
||||
<div class="bottom-compensate">
|
||||
<h2 id="page-title" data-res-fromfile="publicRes (101)"></h2>
|
||||
<div class="win-settings-section">
|
||||
<br>
|
||||
<label class="win-label" for="save-wnd-size" id="save-wnd-size-label" data-res-fromfile="publicRes (125)"></label>
|
||||
<script>
|
||||
(function() {
|
||||
"use strict";
|
||||
var label = document.getElementById("save-wnd-size-label");
|
||||
var toggle = new Toggle();
|
||||
toggle.create();
|
||||
toggle.parent = label.parentNode;
|
||||
toggle.showlabel = true;
|
||||
var winjsres = Bridge.External.WinJsStringRes;
|
||||
toggle.setStatusText(winjsres.getString("ms-resource://Microsoft.WinJS.1.0/ui/on"), winjsres.getString("ms-resource://Microsoft.WinJS.1.0/ui/off"));
|
||||
toggle.inputId = "save-wnd-size";
|
||||
var ini = Bridge.External.Config.GetConfig();
|
||||
toggle.addEventListener("change", function() {
|
||||
ini.set("Settings", "PackageReader:SavePosAndSizeBeforeCancel", toggle.checked);
|
||||
});
|
||||
toggle.checked = parseBool(ini.getSection("Settings").getKey("PackageReader:SavePosAndSizeBeforeCancel").value);
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
<div class="win-settings-section">
|
||||
<br>
|
||||
<label class="win-label" for="default-wndwidth" data-res-fromfile="publicRes(126)"></label><br>
|
||||
<input type="number" id="default-wndwidth" inputmode="numeric"><br><br>
|
||||
<label class="win-label" for="default-wndheight" data-res-fromfile="publicRes(127)"></label><br>
|
||||
<input type="number" id="default-wndheight" inputmode="numeric">
|
||||
<script>
|
||||
(function() {
|
||||
"use strict";
|
||||
var ini = Bridge.External.Config.GetConfig();
|
||||
var defWndWInput = document.getElementById("default-wndwidth");
|
||||
var defWndHInput = document.getElementById("default-wndheight");
|
||||
var setsect = ini.getSection("Settings");
|
||||
var defwk = setsect.getKey("PackageReader:DefaultWidth");
|
||||
var defhk = setsect.getKey("PackageReader:DefaultHeight");
|
||||
defWndWInput.value = defwk.value;
|
||||
defWndHInput.value = defhk.value;
|
||||
var eventutil = Windows.UI.Event.Util;
|
||||
|
||||
function inputDefaultWidthChangeEvent(e) {
|
||||
defwk.value = parseInt(defWndWInput.value);
|
||||
}
|
||||
|
||||
function inputDefaultHeightChangeEvent(e) {
|
||||
defhk.value = parseInt(defWndHInput.value);
|
||||
}
|
||||
var debounced_idwc = debounce(inputDefaultWidthChangeEvent, 500);
|
||||
var debounced_idhc = debounce(inputDefaultHeightChangeEvent, 500);
|
||||
eventutil.addEvent(defWndWInput, "input", debounced_idwc);
|
||||
eventutil.addEvent(defWndWInput, "propertychange", debounced_idwc);
|
||||
eventutil.addEvent(defWndWInput, "change", debounced_idwc);
|
||||
eventutil.addEvent(defWndHInput, "input", debounced_idhc);
|
||||
eventutil.addEvent(defWndHInput, "propertychange", debounced_idhc);
|
||||
eventutil.addEvent(defWndHInput, "change", debounced_idhc);
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
<div class="win-settings-section">
|
||||
<br>
|
||||
<label class="win-label" for="min-wndwidth" data-res-fromfile="publicRes (128)"></label><br>
|
||||
<input type="number" id="min-wndwidth" inputmode="numeric"><br><br>
|
||||
<label class="win-label" for="min-wndheight" data-res-fromfile="publicRes (129)"></label><br>
|
||||
<input type="number" id="min-wndheight" inputmode="numeric">
|
||||
<script>
|
||||
(function() {
|
||||
"use strict";
|
||||
var ini = Bridge.External.Config.GetConfig();
|
||||
var minWndWInput = document.getElementById("min-wndwidth");
|
||||
var minWndHInput = document.getElementById("min-wndheight");
|
||||
var setsect = ini.getSection("Settings");
|
||||
var minwk = setsect.getKey("PackageReader:MinimumWidth");
|
||||
var minhk = setsect.getKey("PackageReader:MinimumHeight");
|
||||
minWndWInput.value = minwk.value;
|
||||
minWndHInput.value = minhk.value;
|
||||
var eventutil = Windows.UI.Event.Util;
|
||||
|
||||
function inputDefaultWidthChangeEvent(e) {
|
||||
minwk.value = parseInt(minWndWInput.value);
|
||||
}
|
||||
|
||||
function inputDefaultHeightChangeEvent(e) {
|
||||
minhk.value = parseInt(minWndHInput.value);
|
||||
}
|
||||
var debounced_idwc = debounce(inputDefaultWidthChangeEvent, 500);
|
||||
var debounced_idhc = debounce(inputDefaultHeightChangeEvent, 500);
|
||||
eventutil.addEvent(minWndWInput, "input", debounced_idwc);
|
||||
eventutil.addEvent(minWndWInput, "propertychange", debounced_idwc);
|
||||
eventutil.addEvent(minWndWInput, "change", debounced_idwc);
|
||||
eventutil.addEvent(minWndHInput, "input", debounced_idhc);
|
||||
eventutil.addEvent(minWndHInput, "propertychange", debounced_idhc);
|
||||
eventutil.addEvent(minWndHInput, "change", debounced_idhc);
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
<div class="win-settings-section">
|
||||
<br>
|
||||
<label class="win-label" for="enable-usepri" id="enable-usepri-label" data-res-resxml="READER_SETTINGS_USEPRI"></label>
|
||||
<script>
|
||||
(function() {
|
||||
"use strict";
|
||||
var label = document.getElementById("enable-usepri-label");
|
||||
var toggle = new Toggle();
|
||||
toggle.create();
|
||||
toggle.parent = label.parentNode;
|
||||
toggle.showlabel = true;
|
||||
var winjsres = Bridge.External.WinJsStringRes;
|
||||
toggle.setStatusText(winjsres.getString("ms-resource://Microsoft.WinJS.1.0/ui/on"), winjsres.getString("ms-resource://Microsoft.WinJS.1.0/ui/off"));
|
||||
toggle.inputId = "enable-usepri";
|
||||
var ini = Bridge.External.Config.GetConfig();
|
||||
toggle.addEventListener("change", function() {
|
||||
ini.set("Settings", "PackageReader:DefaultParsingPriFile", toggle.checked);
|
||||
});
|
||||
toggle.checked = parseBool(ini.getSection("Settings").getKey("PackageReader:DefaultParsingPriFile").value);
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
<div class="win-settings-section">
|
||||
<br>
|
||||
<label class="win-label" for="enable-acquire" id="enable-acquire-label" data-res-resxml="READER_SETTINGS_ENABLEACQUIRE"></label>
|
||||
<script>
|
||||
(function() {
|
||||
"use strict";
|
||||
var label = document.getElementById("enable-acquire-label");
|
||||
var toggle = new Toggle();
|
||||
toggle.create();
|
||||
toggle.parent = label.parentNode;
|
||||
toggle.showlabel = true;
|
||||
var winjsres = Bridge.External.WinJsStringRes;
|
||||
toggle.setStatusText(winjsres.getString("ms-resource://Microsoft.WinJS.1.0/ui/on"), winjsres.getString("ms-resource://Microsoft.WinJS.1.0/ui/off"));
|
||||
toggle.inputId = "enable-acquire";
|
||||
var ini = Bridge.External.Config.GetConfig();
|
||||
toggle.addEventListener("change", function() {
|
||||
ini.set("Settings", "PackageReader:EnableAcquire", toggle.checked);
|
||||
});
|
||||
toggle.checked = parseBool(ini.getSection("Settings").getKey("PackageReader:EnableAcquire").value);
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
62
shared/html/settings/reader/guide.html
Normal file
@@ -0,0 +1,62 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>App Installer Settings</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<script type="text/javascript" src="../../js/module.js"></script>
|
||||
<script type="text/javascript" src="../../js/polyfill-ie.js"></script>
|
||||
<link rel="stylesheet" href="../../libs/winjs/2.0/css/ui-light.css" id="winjs-style">
|
||||
<script type="text/javascript" src="../../libs/winjs/1.0/js/base.js"></script>
|
||||
<script type="text/javascript" src="../../libs/winjs/1.0/js/ui.js"></script>
|
||||
<script type="text/javascript" src="../../js/color.js"></script>
|
||||
<script type="text/javascript" src="../../js/promise.js"></script>
|
||||
<script type="text/javascript" src="../../js/bridge.js"></script>
|
||||
<script type="text/javascript" src="../../js/dpimodes.js"></script>
|
||||
<script type="text/javascript" src="../../js/resources.js"></script>
|
||||
<script type="text/javascript" src="../../js/animation.js"></script>
|
||||
<link rel="stylesheet" href="../../fonts/fonts.css">
|
||||
<script type="text/javascript" src="../../js/event.js"></script>
|
||||
<script type="text/javascript" src="../../js/tileback.js"></script>
|
||||
<script type="text/javascript" src="../../js/load.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../../libs/msgbox/contentdlg.css">
|
||||
<script type="text/javascript" src="../../libs/msgbox/contentdlg.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../../libs/msgbox/msgbox.css">
|
||||
<script type="text/javascript" src="../../libs/msgbox/msgbox.js"></script>
|
||||
<script type="text/javascript" src="../../js/init.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="../page.css">
|
||||
<link rel="stylesheet" type="text/css" href="../subpage.css">
|
||||
<script type="text/javascript" src="preinit.js"></script>
|
||||
<script type="text/javascript" src="initsame.js"></script>
|
||||
<script>
|
||||
try {
|
||||
window.parent.setItemHighlight("guide");
|
||||
} catch (e) {}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="pagecontainer full pagesection">
|
||||
<div class="section padding">
|
||||
<div class="bottom-compensate">
|
||||
<h2 id="guide-title"></h2>
|
||||
<p id="guide-desc" style="white-space: pre-wrap;"></p>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
(function() {
|
||||
"use strict";
|
||||
var res = Bridge.Resources;
|
||||
var stru = Bridge.String;
|
||||
var title = document.getElementById("guide-title");
|
||||
title.textContent = stru.format(res.byname("IDS_TITLEFORMAT"), stringRes("READER_APPTITLE"));
|
||||
var text = document.getElementById("guide-desc");
|
||||
text.textContent = res.byname("IDS_GUIDETEXT_COMMON");
|
||||
})();
|
||||
</script>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
96
shared/html/settings/reader/init.js
Normal file
@@ -0,0 +1,96 @@
|
||||
(function(global) {
|
||||
"use strict";
|
||||
|
||||
function ready(e) {
|
||||
var page = document.querySelector("#settingpage");
|
||||
var guide = page.querySelector(".page.guide");
|
||||
var slide = guide.querySelector("aside");
|
||||
setTimeout(function() {
|
||||
var barcolor = visual["BackgroundColor"];
|
||||
slide.style.backgroundColor = barcolor;
|
||||
slide.style.color = Color.getSuitableForegroundTextColor(Color.parse(barcolor), [Color.Const.white, Color.Const.black]).stringify();
|
||||
}, 50);
|
||||
var content = guide.querySelector(".main");
|
||||
var list = slide.querySelector("ul");
|
||||
var backbtn = slide.querySelector("#back");
|
||||
var title = slide.querySelector("#apptitle");
|
||||
list.innerHTML = "";
|
||||
var items = pages;
|
||||
var tags = Object.keys(items);
|
||||
var eventutil = Windows.UI.Event.Util;
|
||||
for (var i = 0; i < tags.length; i++) {
|
||||
var tag = tags[i];
|
||||
var item = items[tag];
|
||||
var li = document.createElement("li");
|
||||
li.setAttribute("data-page", item.page);
|
||||
li.setAttribute("data-tag", item.tag);
|
||||
li.innerHTML = item.title;
|
||||
eventutil.addEvent(li, "click", function() {
|
||||
if (li.hasAttribute("data-require-disabled")) return;
|
||||
content.style.display = "none";
|
||||
for (var j = 0; j < list.children.length; j++) {
|
||||
var child = list.children[j];
|
||||
if (child.classList.contains("selected"))
|
||||
child.classList.remove("selected");
|
||||
}
|
||||
content.src = this.getAttribute("data-page");
|
||||
setTimeout(function() {
|
||||
content.style.display = "";
|
||||
Windows.UI.Animation.runAsync(content, [Windows.UI.Animation.Keyframes.Flyout.toLeft, Windows.UI.Animation.Keyframes.Opacity.visible]);
|
||||
}, 0);
|
||||
this.classList.add("selected");
|
||||
});
|
||||
list.appendChild(li);
|
||||
}
|
||||
content.src = guidePage.page;
|
||||
/*for (var i = 0; i < list.children.length; i++) {
|
||||
var child = list.children[i];
|
||||
child.click();
|
||||
break;
|
||||
}*/
|
||||
var jumppage = "";
|
||||
try { var args = cmdargs; if (args.length > 1) jumppage = args[1]; } catch (e) {}
|
||||
if (jumppage && jumppage.length > 0 && !Bridge.External.jump2) {
|
||||
for (var i = 0; i < list.children.length; i++) {
|
||||
var child = list.children[i];
|
||||
if (Bridge.NString.equals(child.getAttribute("data-tag"), jumppage)) {
|
||||
Bridge.External.jump2 = true;
|
||||
setTimeout(function(thisnode) {
|
||||
thisnode.click();
|
||||
}, 0, child)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
global.setDisabledForOperation = function(disabled) {
|
||||
var list = document.querySelector("#settingpage .guide aside ul");
|
||||
for (var i = 0; i < list.children.length; i++) {
|
||||
var child = list.children[i];
|
||||
if (disabled) {
|
||||
child.setAttribute("data-require-disabled", "true");
|
||||
} else {
|
||||
child.removeAttribute("data-require-disabled");
|
||||
}
|
||||
}
|
||||
if (disabled) {
|
||||
backbtn.disabled = true;
|
||||
title.style.marginLeft = backbtn.style.marginLeft;
|
||||
} else {
|
||||
backbtn.disabled = false;
|
||||
title.style.marginLeft = "";
|
||||
}
|
||||
}
|
||||
global.setItemHighlight = function(tag) {
|
||||
var list = document.querySelector("#settingpage .guide aside ul");
|
||||
for (var i = 0; i < list.children.length; i++) {
|
||||
var child = list.children[i];
|
||||
if (Bridge.NString.equals(child.getAttribute("data-tag"), tag)) {
|
||||
if (!child.classList.contains("selected")) child.classList.add("selected");
|
||||
} else {
|
||||
if (child.classList.contains("selected")) child.classList.remove("selected");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
OnLoad.add(ready);
|
||||
})(this);
|
||||
21
shared/html/settings/reader/initsame.js
Normal file
@@ -0,0 +1,21 @@
|
||||
(function(global) {
|
||||
"use strict";
|
||||
|
||||
function ready(e) {
|
||||
Windows.UI.DPI.mode = 1
|
||||
var pagesection = document.querySelector(".pagesection");
|
||||
if (pagesection) {
|
||||
var backcolor = slideback;
|
||||
setTimeout(function() {
|
||||
var h2style = document.getElementById("h2-style");
|
||||
if (!h2style) {
|
||||
h2style = document.createElement("style");
|
||||
h2style.id = "h2-style";
|
||||
}
|
||||
h2style.innerHTML = ".main h2 { color: " + Color.getSuitableForegroundTextColor(Color.parse("#F3F3F3"), [Color.parse(backcolor), Color.Const.black]).RGBA.stringify() + " }";
|
||||
document.head.appendChild(h2style);
|
||||
}, 0);
|
||||
}
|
||||
}
|
||||
OnLoad.add(ready);
|
||||
})(this);
|
||||
25
shared/html/settings/reader/items.js
Normal file
@@ -0,0 +1,25 @@
|
||||
(function(global) {
|
||||
"use strict";
|
||||
|
||||
function getPage(tag, page, display) {
|
||||
return {
|
||||
tag: tag,
|
||||
page: page,
|
||||
title: display
|
||||
};
|
||||
}
|
||||
var pages = {
|
||||
general: getPage("general", "reader/general.html", getPublicRes(101)),
|
||||
appitems: getPage("appitems", "reader/appitems.html", stringRes("READER_SETTINGS_APPITEMS")),
|
||||
};
|
||||
Object.defineProperty(global, "pages", {
|
||||
get: function() {
|
||||
return pages;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(global, "guidePage", {
|
||||
get: function() {
|
||||
return getPage("guide", "reader/guide.html", "guide");
|
||||
}
|
||||
});
|
||||
})(this);
|
||||
30
shared/html/settings/reader/preinit.js
Normal file
@@ -0,0 +1,30 @@
|
||||
(function(global) {
|
||||
var storage = Bridge.External.Storage;
|
||||
var path = storage.path;
|
||||
var root = path.getDir(path.program);
|
||||
var exepath = path.combine(root, "settings.exe");
|
||||
var id = "Reader";
|
||||
var ve = Bridge.External.VisualElements.get(id);
|
||||
var slideback = ve["BackgroundColor"];
|
||||
global.slideback = slideback;
|
||||
global.exepath = exepath;
|
||||
global.visual = ve;
|
||||
var strutil = Bridge.External.String;
|
||||
var nstrutil = Bridge.NString;
|
||||
var boolTrue = ["true", "1", "yes", "on", "y", "t", "zhen", "真"];
|
||||
var boolFalse = ["false", "0", "no", "off", "n", "f", "jia", "假"];
|
||||
global.parseBool = function(str) {
|
||||
str = "" + str;
|
||||
for (var i = 0; i < boolTrue.length; i++) {
|
||||
if (nstrutil.equals(str, boolTrue[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < boolFalse.length; i++) {
|
||||
if (nstrutil.equals(str, boolFalse[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
})(this);
|
||||
BIN
shared/icons/32_reader.ico
Normal file
|
After Width: | Height: | Size: 358 KiB |
17
shared/license/LICENSE.SharpZipLib
Normal file
@@ -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.
|
||||
@@ -1,76 +0,0 @@
|
||||
NOTICE
|
||||
|
||||
This product includes software developed by third parties.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
PriTools (PriFormat)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
This product includes code derived from the PriTools project
|
||||
developed by chausner.
|
||||
|
||||
Original Project:
|
||||
Name: PriTools
|
||||
Author: chausner
|
||||
Project Homepage: https://github.com/chausner/PriTools
|
||||
Source Repository: https://github.com/chausner/PriTools/tree/master
|
||||
License: Apache License, Version 2.0
|
||||
License File: LICENSE.PriTools.chausner
|
||||
|
||||
The original PriFormat project has been modified in this product, including:
|
||||
- Renamed from "PriFormat" to "PriFileFormat"
|
||||
- Adapted to support Microsoft .NET Framework 4.6
|
||||
- Added support for the COM IStream interface
|
||||
- Modified resource cleanup and disposal logic
|
||||
- Changed namespaces and internal structure
|
||||
|
||||
These modifications were made by the authors of this product.
|
||||
The original copyright and license notices
|
||||
are retained in accordance with the Apache License, Version 2.0.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
pugixml
|
||||
----------------------------------------------------------------------
|
||||
|
||||
This product includes pugixml, which is licensed under the MIT License.
|
||||
|
||||
License File:
|
||||
LICENSE.pugixml
|
||||
|
||||
----------------------------------------------------------------------
|
||||
RapidJSON
|
||||
----------------------------------------------------------------------
|
||||
|
||||
This product includes RapidJSON, which is licensed under the MIT License.
|
||||
|
||||
License File:
|
||||
LICENSE.RapidJSON
|
||||
|
||||
----------------------------------------------------------------------
|
||||
markdown.js
|
||||
----------------------------------------------------------------------
|
||||
|
||||
This product includes markdown.js (also known as markdown-js).
|
||||
|
||||
Original Project:
|
||||
Name: markdown.js
|
||||
Source Repository: https://github.com/evilstreak/markdown-js
|
||||
License: MIT License
|
||||
License File: LICENSE.markdown.js
|
||||
|
||||
----------------------------------------------------------------------
|
||||
WinJS
|
||||
----------------------------------------------------------------------
|
||||
|
||||
This product includes Microsoft WinJS (Windows Library for JavaScript).
|
||||
|
||||
Original Project:
|
||||
Name: WinJS
|
||||
Author: Microsoft Corporation
|
||||
Project Homepage: https://github.com/winjs/winjs
|
||||
License: MIT License
|
||||
License File: LICENSE.WinJS
|
||||
|
||||
----------------------------------------------------------------------
|
||||
|
||||
End of notices.
|
||||
@@ -77,6 +77,7 @@ text-align: center;
|
||||
<li>markdown.js (MIT License) - <a href="https://github.com/evilstreak/markdown-js" target="_blank">https://github.com/evilstreak/markdown-js</a></li>
|
||||
<li>CodeMirror (MIT License) - <a href="https://codemirror.net/" target="_blank">https://codemirror.net/</a></li>
|
||||
<li>Json.NET (MIT License) - <a href="https://www.newtonsoft.com/json" target="_blank">https://www.newtonsoft.com/json</a></li>
|
||||
<li>SharpZipLib (MIT License) - <a href="https://icsharpcode.github.io/SharpZipLib/" target="_blank">https://icsharpcode.github.io/SharpZipLib/</a></li>
|
||||
</ul>
|
||||
|
||||
<h2>四、免责声明</h2>
|
||||
|
||||
@@ -79,6 +79,7 @@ text-align: center;
|
||||
<li>markdown.js (MIT License) - <a href="https://github.com/evilstreak/markdown-js" target="_blank">https://github.com/evilstreak/markdown-js</a></li>
|
||||
<li>CodeMirror (MIT License) - <a href="https://codemirror.net/" target="_blank">https://codemirror.net/</a></li>
|
||||
<li>Json.NET (MIT License) - <a href="https://www.newtonsoft.com/json" target="_blank">https://www.newtonsoft.com/json</a></li>
|
||||
<li>SharpZipLib (MIT License) - <a href="https://icsharpcode.github.io/SharpZipLib/" target="_blank">https://icsharpcode.github.io/SharpZipLib/</a></li>
|
||||
</ul>
|
||||
|
||||
<h2>4. Disclaimer</h2>
|
||||
|
||||
BIN
shared/locale/ResXmlEditor.exe
Normal file
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<resource id="ms-resource://Microsoft.WinJS.1.0/ui/off">
|
||||
<lang name="zh-CN">关</lang>
|
||||
@@ -338,10 +338,6 @@
|
||||
<lang name="zh-CN">下面是包具有的应用。现在可以直接在这里启动程序,或者创建桌面快捷方式。</lang>
|
||||
<lang name="en-US">Below are the apps that are included in this package. You can launch the apps directly from here, or create desktop shortcuts.</lang>
|
||||
</resource>
|
||||
<resource id="MANAGER_APP_UNINSTALL_DESC">
|
||||
<lang name="zh-CN">卸载此应用及其设置。</lang>
|
||||
<lang name="en-US">Uninstall this app and its settings.</lang>
|
||||
</resource>
|
||||
<resource id="MANAGER_APP_UNINSTALL_DESC">
|
||||
<lang name="zh-CN">将从这台电脑中卸载此应用及其相关信息。</lang>
|
||||
<lang name="en-US">This app and its related information will be uninstalled from this computer.</lang>
|
||||
@@ -618,4 +614,300 @@
|
||||
<lang name="zh-CN">Package Reader</lang>
|
||||
<lang name="en-US">Package Reader</lang>
|
||||
</resource>
|
||||
<resource id="READER_READER_TITLE">
|
||||
<lang name="zh-CN">读取</lang>
|
||||
<lang name="en-US">Read</lang>
|
||||
</resource>
|
||||
<resource id="READER_READER_DESC">
|
||||
<lang name="zh-CN">读取一个包,然后获取其信息。</lang>
|
||||
<lang name="en-US">Read a package and then retrieve its information.</lang>
|
||||
</resource>
|
||||
<resource id="READER_READER_FILEPATH">
|
||||
<lang name="zh-CN">文件路径</lang>
|
||||
<lang name="en-US">File Path</lang>
|
||||
</resource>
|
||||
<resource id="READER_READER_BROWSER">
|
||||
<lang name="zh-CN">浏览...</lang>
|
||||
<lang name="en-US">Browse...</lang>
|
||||
</resource>
|
||||
<resource id="READER_READER_USEPRI">
|
||||
<lang name="zh-CN">解析 PRI 文件</lang>
|
||||
<lang name="en-US">Parsing PRI file</lang>
|
||||
</resource>
|
||||
<resource id="READER_READER_READ">
|
||||
<lang name="zh-CN">读取</lang>
|
||||
<lang name="en-US">Read</lang>
|
||||
</resource>
|
||||
<resource id="READER_READER_SAVEFILE">
|
||||
<lang name="zh-CN">将 HTML 报告保存为文件</lang>
|
||||
<lang name="en-US">Save the HTML report as a file</lang>
|
||||
</resource>
|
||||
<resource id="READER_READER_SAVEJSON">
|
||||
<lang name="zh-CN">生成 JSON 文件报告</lang>
|
||||
<lang name="en-US">Generate JSON file report</lang>
|
||||
</resource>
|
||||
<resource id="READER_READER_SAVEXML">
|
||||
<lang name="zh-CN">生成 XML 文件报告</lang>
|
||||
<lang name="en-US">Generate XML file report</lang>
|
||||
</resource>
|
||||
<resource id="READER_READER_RESULT">
|
||||
<lang name="zh-CN">读取结果:</lang>
|
||||
<lang name="en-US">Read result:</lang>
|
||||
</resource>
|
||||
<resource id="READER_READER_PLEASESELECT">
|
||||
<lang name="zh-CN">请选择一个有效文件</lang>
|
||||
<lang name="en-US">Please select a valid file.</lang>
|
||||
</resource>
|
||||
<resource id="READER_READER_SAVINGHTML">
|
||||
<lang name="zh-CN">正在保存文件...</lang>
|
||||
<lang name="en-US">Saving file...</lang>
|
||||
</resource>
|
||||
<resource id="READER_READER_HTMLFILE">
|
||||
<lang name="zh-CN">HTML 报告文件</lang>
|
||||
<lang name="en-US">HTML Report File</lang>
|
||||
</resource>
|
||||
<resource id="READER_READER_SAVEERR">
|
||||
<lang name="zh-CN">保存时发生问题</lang>
|
||||
<lang name="en-US">Problem occurred during saving</lang>
|
||||
</resource>
|
||||
<resource id="READER_READER_SAVEINGJSON">
|
||||
<lang name="zh-CN">正在生成 JSON 文件,请稍候... \n这可能需要比较长的时间。</lang>
|
||||
<lang name="en-US">Generating JSON file, please wait... \nThis may take a long time.</lang>
|
||||
</resource>
|
||||
<resource id="READER_READER_JSONFILE">
|
||||
<lang name="zh-CN">包含 JSON 报告的 ZIP 文件</lang>
|
||||
<lang name="en-US">ZIP file containing JSON report</lang>
|
||||
</resource>
|
||||
<resource id="READER_READER_XMLFILE">
|
||||
<lang name="zh-CN">包含 XML 报告的 ZIP 文件</lang>
|
||||
<lang name="en-US">ZIP file containing XML report</lang>
|
||||
</resource>
|
||||
<resource id="READER_READER_SAVEINGXML">
|
||||
<lang name="zh-CN">正在生成 XML 文件,请稍候... \n这可能需要比较长的时间。</lang>
|
||||
<lang name="en-US">Generating XML file, please wait... \nThis may take a long time.</lang>
|
||||
</resource>
|
||||
<resource id="READER_ACQUIRE_TITLE">
|
||||
<lang name="zh-CN">获取</lang>
|
||||
<lang name="en-US">Acquire</lang>
|
||||
</resource>
|
||||
<resource id="READER_ACQUIRE_PROHIBIT">
|
||||
<lang name="zh-CN">由于来自 store.rg-adguard.net 的限制,现在暂时无法实现对包的获取。请自行打开下面 URL 进行访问。</lang>
|
||||
<lang name="en-US">Due to limitations from store.rg-adguard.net, package retrieval is temporarily unavailable. Please access the following URL yourself.</lang>
|
||||
</resource>
|
||||
<resource id="READER_ACQUIRE_DESC">
|
||||
<lang name="zh-CN">请在下面的输入框中输入要查询的内容,设置好参数后将进行查询。</lang>
|
||||
<lang name="en-US">Please enter the content you want to query in the input box below. After setting the parameters, the query will be performed.</lang>
|
||||
</resource>
|
||||
<resource id="READER_ACQUIRE_SHAREDURL">
|
||||
<lang name="zh-CN">分享链接</lang>
|
||||
<lang name="en-US">Shared link</lang>
|
||||
</resource>
|
||||
<resource id="READER_ACQUIRE_PRODUCTID">
|
||||
<lang name="zh-CN">产品 ID</lang>
|
||||
<lang name="en-US">Product ID</lang>
|
||||
</resource>
|
||||
<resource id="READER_ACQUIRE_PFN">
|
||||
<lang name="zh-CN">包系列名</lang>
|
||||
<lang name="en-US">Package Family Name</lang>
|
||||
</resource>
|
||||
<resource id="READER_ACQUIRE_CATEGORYID">
|
||||
<lang name="zh-CN">类别 ID</lang>
|
||||
<lang name="en-US">Category ID</lang>
|
||||
</resource>
|
||||
<resource id="READER_ACQUIRE_WIF">
|
||||
<lang name="zh-CN">快速</lang>
|
||||
<lang name="en-US">Fast</lang>
|
||||
</resource>
|
||||
<resource id="READER_ACQUIRE_WIS">
|
||||
<lang name="zh-CN">慢速</lang>
|
||||
<lang name="en-US">Slow</lang>
|
||||
</resource>
|
||||
<resource id="READER_ACQUIRE_RP">
|
||||
<lang name="zh-CN">发布预览</lang>
|
||||
<lang name="en-US">Release Preview</lang>
|
||||
</resource>
|
||||
<resource id="READER_ACQUIRE_RETAIL">
|
||||
<lang name="zh-CN">正式</lang>
|
||||
<lang name="en-US">Retail</lang>
|
||||
</resource>
|
||||
<resource id="READER_ACQUIRE_SMARTQUERY">
|
||||
<lang name="zh-CN">自动查询</lang>
|
||||
<lang name="en-US">Automatic query</lang>
|
||||
</resource>
|
||||
<resource id="READER_ACQUIRE_QUERY">
|
||||
<lang name="zh-CN">查询</lang>
|
||||
<lang name="en-US">Query</lang>
|
||||
</resource>
|
||||
<resource id="READER_ACQUIRE_CLICKDOWNLOAD">
|
||||
<lang name="zh-CN">点击下载</lang>
|
||||
<lang name="en-US">Click to download</lang>
|
||||
</resource>
|
||||
<resource id="READER_ACQUIRE_RESULTAPPS">
|
||||
<lang name="zh-CN">以下可能为检索到的应用</lang>
|
||||
<lang name="en-US">The following may be the applications retrieved:</lang>
|
||||
</resource>
|
||||
<resource id="READER_ACQUIRE_RESULTDEPS">
|
||||
<lang name="zh-CN">以下可能为检索到的依赖项</lang>
|
||||
<lang name="en-US">The following may be the retrieved dependencies: </lang>
|
||||
</resource>
|
||||
<resource id="READER_ACQUIRE_NOCONTENT">
|
||||
<lang name="zh-CN">还没有内容...</lang>
|
||||
<lang name="en-US">There is no content yet...</lang>
|
||||
</resource>
|
||||
<resource id="READER_ACQUIRE_QUERYING">
|
||||
<lang name="zh-CN">正在查询...</lang>
|
||||
<lang name="en-US">Querying...</lang>
|
||||
</resource>
|
||||
<resource id="READER_ACQUIRE_RESULTCNT">
|
||||
<lang name="zh-CN">已获取到 {0} 个信息</lang>
|
||||
<lang name="en-US">{0} piece(-s) of information have been retrieved.</lang>
|
||||
</resource>
|
||||
<resource id="READER_SEARCH_TITLE">
|
||||
<lang name="zh-CN">搜索</lang>
|
||||
<lang name="en-US">Search</lang>
|
||||
</resource>
|
||||
<resource id="READER_SEARCH_PROHIBIT">
|
||||
<lang name="zh-CN">由于来自 dbox.tools 的限制,现在暂时无法实现信息检索。请自行打开下面 URL 进行访问。</lang>
|
||||
<lang name="en-US">Information retrieval is temporarily unavailable due to limitations imposed by dbox.tools. Please access the information via the URL below.</lang>
|
||||
</resource>
|
||||
<resource id="READER_SETTINGS_TITLE">
|
||||
<lang name="zh-CN">设置</lang>
|
||||
<lang name="en-US">Settings</lang>
|
||||
</resource>
|
||||
<resource id="READER_SETTINGS_ENABLEACQUIRE">
|
||||
<lang name="zh-CN">启用获取</lang>
|
||||
<lang name="en-US">Enable Acquire</lang>
|
||||
</resource>
|
||||
<resource id="READER_SETTINGS_USEPRI">
|
||||
<lang name="zh-CN">默认读取时解析 PRI 文件</lang>
|
||||
<lang name="en-US">PRI files are parsed by default when reading</lang>
|
||||
</resource>
|
||||
<resource id="READER_SETTINGS_APPITEMS">
|
||||
<lang name="zh-CN">应用部分元数据</lang>
|
||||
<lang name="en-US">App Metadata</lang>
|
||||
</resource>
|
||||
<resource id="READER_SETTINGS_APPITEMS_DESC">
|
||||
<lang name="zh-CN">应用元数据对应应用清单中 Application 节点的一些元素和属性。注意:一些应用元数据会因为各个系统中包读取 API 的差异支持程度也不同。若是要读取某些项的话请勾选下列项目。该设置作用于 Package Reader 全局,且在重新启动应用后生效。</lang>
|
||||
<lang name="en-US">Application metadata corresponds to certain elements and attributes of the Application node in the application manifest. Note: The level of support for some application metadata may vary depending on the package reading API used by different systems. To read specific items, please select the following options. This setting applies globally to the Package Reader and takes effect after restarting the application.</lang>
|
||||
</resource>
|
||||
<resource id="READER_SETTINGS_APPITEMS_ITEM">
|
||||
<lang name="zh-CN">项</lang>
|
||||
<lang name="en-US">Item</lang>
|
||||
</resource>
|
||||
<resource id="READER_SETTINGS_APPITEMS_DESCRIPTION">
|
||||
<lang name="zh-CN">描述</lang>
|
||||
<lang name="en-US">Description</lang>
|
||||
</resource>
|
||||
<resource id="APPMETADATA_AppListEntry">
|
||||
<lang name="zh-CN">显示应用列表入口</lang>
|
||||
<lang name="en-US">Show App List Entry</lang>
|
||||
</resource>
|
||||
<resource id="APPMETADATA_BackgroundColor">
|
||||
<lang name="zh-CN">磁贴背景颜色</lang>
|
||||
<lang name="en-US">Tile Background Color</lang>
|
||||
</resource>
|
||||
<resource id="APPMETADATA_DefaultSize">
|
||||
<lang name="zh-CN">磁贴默认尺寸</lang>
|
||||
<lang name="en-US">Tile Default Size</lang>
|
||||
</resource>
|
||||
<resource id="APPMETADATA_Description">
|
||||
<lang name="zh-CN">应用描述</lang>
|
||||
<lang name="en-US">App Description</lang>
|
||||
</resource>
|
||||
<resource id="APPMETADATA_DisplayName">
|
||||
<lang name="zh-CN">应用显示名称</lang>
|
||||
<lang name="en-US">App Display Name</lang>
|
||||
</resource>
|
||||
<resource id="APPMETADATA_EntryPoint">
|
||||
<lang name="zh-CN">应用进入点</lang>
|
||||
<lang name="en-US">App Entry Point</lang>
|
||||
</resource>
|
||||
<resource id="APPMETADATA_Executable">
|
||||
<lang name="zh-CN">可执行文件</lang>
|
||||
<lang name="en-US">Executable File</lang>
|
||||
</resource>
|
||||
<resource id="APPMETADATA_ForegroundText">
|
||||
<lang name="zh-CN">磁贴前景颜色</lang>
|
||||
<lang name="en-US">Tile Foreground Text</lang>
|
||||
</resource>
|
||||
<resource id="APPMETADATA_ID">
|
||||
<lang name="zh-CN">应用 ID</lang>
|
||||
<lang name="en-US">ID</lang>
|
||||
</resource>
|
||||
<resource id="APPMETADATA_LockScreenLogo">
|
||||
<lang name="zh-CN">锁屏图标</lang>
|
||||
<lang name="en-US">Lock Screen Logo</lang>
|
||||
</resource>
|
||||
<resource id="APPMETADATA_LockScreenNotification">
|
||||
<lang name="zh-CN">锁屏通知类型</lang>
|
||||
<lang name="en-US">Lock Screen Notification Types</lang>
|
||||
</resource>
|
||||
<resource id="APPMETADATA_Logo">
|
||||
<lang name="zh-CN">中磁贴图标 (Windows 8)</lang>
|
||||
<lang name="en-US">Medium Tile Logo (Windows 8)</lang>
|
||||
</resource>
|
||||
<resource id="APPMETADATA_MinWidth">
|
||||
<lang name="zh-CN">窗口最小宽度</lang>
|
||||
<lang name="en-US">Window Minimum Width</lang>
|
||||
</resource>
|
||||
<resource id="APPMETADATA_ShortName">
|
||||
<lang name="zh-CN">短名称</lang>
|
||||
<lang name="en-US">Short Name</lang>
|
||||
</resource>
|
||||
<resource id="APPMETADATA_SmallLogo">
|
||||
<lang name="zh-CN">应用列表图标 (Windows 8)</lang>
|
||||
<lang name="en-US">App List Logo (Windows 8)</lang>
|
||||
</resource>
|
||||
<resource id="APPMETADATA_Square150x150Logo">
|
||||
<lang name="zh-CN">中磁贴图标</lang>
|
||||
<lang name="en-US">Medium Tile Logo</lang>
|
||||
</resource>
|
||||
<resource id="APPMETADATA_Square30x30Logo">
|
||||
<lang name="zh-CN">应用列表图标 (Windows 8.1)</lang>
|
||||
<lang name="en-US">App List Logo (Windows 8.1)</lang>
|
||||
</resource>
|
||||
<resource id="APPMETADATA_Square310x310Logo">
|
||||
<lang name="zh-CN">大磁贴图标</lang>
|
||||
<lang name="en-US">Large Tile Logo</lang>
|
||||
</resource>
|
||||
<resource id="APPMETADATA_Square44x44Logo">
|
||||
<lang name="zh-CN">应用列表图标 (Windows Phone 或 UWP)</lang>
|
||||
<lang name="en-US">App List Logo (Windows Phone 或 UWP)</lang>
|
||||
</resource>
|
||||
<resource id="APPMETADATA_Square70x70Logo">
|
||||
<lang name="zh-CN">小磁贴图标 (Windows 8.1)</lang>
|
||||
<lang name="en-US">Small Tile Logo (Windows 8.1)</lang>
|
||||
</resource>
|
||||
<resource id="APPMETADATA_Square71x71Logo">
|
||||
<lang name="zh-CN">小磁贴图标 (Windows Phone 或 UWP)</lang>
|
||||
<lang name="en-US">Small Tile Logo (Windows Phone or UWP)</lang>
|
||||
</resource>
|
||||
<resource id="APPMETADATA_StartPage">
|
||||
<lang name="zh-CN">起始页</lang>
|
||||
<lang name="en-US">Start Page</lang>
|
||||
</resource>
|
||||
<resource id="APPMETADATA_Tall150x310Logo">
|
||||
<lang name="zh-CN">高磁贴图标 (已废弃)</lang>
|
||||
<lang name="en-US">Tall Tile Logo (Deprecated)</lang>
|
||||
</resource>
|
||||
<resource id="APPMETADATA_VisualGroup">
|
||||
<lang name="zh-CN">开始菜单应用组</lang>
|
||||
<lang name="en-US">Visual Group in Start Menu</lang>
|
||||
</resource>
|
||||
<resource id="APPMETADATA_WideLogo">
|
||||
<lang name="zh-CN">宽磁贴图标 (Windows 8)</lang>
|
||||
<lang name="en-US">Wide Tile Logo (Windows 8)</lang>
|
||||
</resource>
|
||||
<resource id="APPMETADATA_Wide310x150Logo">
|
||||
<lang name="zh-CN">宽磁贴图标</lang>
|
||||
<lang name="en-US">Wide Tile Logo</lang>
|
||||
</resource>
|
||||
<resource id="READER_READER_APPXFILE">
|
||||
<lang name="zh-CN">Windows 商店应用包</lang>
|
||||
<lang name="en-US">Windows Store App Package</lang>
|
||||
</resource>
|
||||
<resource id="READER_READER_ALLFILES">
|
||||
<lang name="zh-CN">所有文件</lang>
|
||||
<lang name="en-US">All Files</lang>
|
||||
</resource>
|
||||
</resources>
|
||||