Better TimeZone entry in System Settings (#1254)
* Better timezone labels in System TimeZone Replace with GtkEntry with auto-complete Also removed async task as now loading is fast Address Thog's comments self-nit: Remove string alias Address AcK's comments * Improve parsing * Optimize and fix string matching Address jD's comments * Also, make abbreviations searchable * Optimize EntryCompletion's MatchFunc * nit: Result.IsFailure() * Fix potential crash on opening Settings window w/o FW installed
This commit is contained in:
parent
21dfa4974a
commit
4aa47a66c6
3 changed files with 190 additions and 68 deletions
|
@ -10,6 +10,7 @@ using Ryujinx.HLE.FileSystem;
|
|||
using Ryujinx.HLE.FileSystem.Content;
|
||||
using Ryujinx.HLE.HOS.Services.Time.Clock;
|
||||
using Ryujinx.HLE.Utilities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
|
||||
|
@ -117,6 +118,73 @@ namespace Ryujinx.HLE.HOS.Services.Time.TimeZone
|
|||
}
|
||||
}
|
||||
|
||||
public IEnumerable<(int Offset, string Location, string Abbr)> ParseTzOffsets()
|
||||
{
|
||||
var tzBinaryContentPath = GetTimeZoneBinaryTitleContentPath();
|
||||
|
||||
if (string.IsNullOrEmpty(tzBinaryContentPath))
|
||||
{
|
||||
return new[] { (0, "UTC", "UTC") };
|
||||
}
|
||||
|
||||
List<(int Offset, string Location, string Abbr)> outList = new List<(int Offset, string Location, string Abbr)>();
|
||||
var now = System.DateTimeOffset.Now.ToUnixTimeSeconds();
|
||||
using (IStorage ncaStorage = new LocalStorage(_virtualFileSystem.SwitchPathToSystemPath(tzBinaryContentPath), FileAccess.Read, FileMode.Open))
|
||||
using (IFileSystem romfs = new Nca(_virtualFileSystem.KeySet, ncaStorage).OpenFileSystem(NcaSectionType.Data, _fsIntegrityCheckLevel))
|
||||
{
|
||||
foreach (string locName in LocationNameCache)
|
||||
{
|
||||
if (locName.StartsWith("Etc"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (romfs.OpenFile(out IFile tzif, $"/zoneinfo/{locName}".ToU8Span(), OpenMode.Read).IsFailure())
|
||||
{
|
||||
Logger.PrintError(LogClass.ServiceTime, $"Error opening /zoneinfo/{locName}");
|
||||
continue;
|
||||
}
|
||||
|
||||
using (tzif)
|
||||
{
|
||||
TimeZone.ParseTimeZoneBinary(out TimeZoneRule tzRule, tzif.AsStream());
|
||||
|
||||
TimeTypeInfo ttInfo;
|
||||
if (tzRule.TimeCount > 0) // Find the current transition period
|
||||
{
|
||||
int fin = 0;
|
||||
for (int i = 0; i < tzRule.TimeCount; ++i)
|
||||
{
|
||||
if (tzRule.Ats[i] <= now)
|
||||
{
|
||||
fin = i;
|
||||
}
|
||||
}
|
||||
ttInfo = tzRule.Ttis[tzRule.Types[fin]];
|
||||
}
|
||||
else if (tzRule.TypeCount >= 1) // Otherwise, use the first offset in TTInfo
|
||||
{
|
||||
ttInfo = tzRule.Ttis[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.PrintError(LogClass.ServiceTime, $"Couldn't find UTC offset for zone {locName}");
|
||||
continue;
|
||||
}
|
||||
|
||||
var abbrStart = tzRule.Chars.AsSpan(ttInfo.AbbreviationListIndex);
|
||||
int abbrEnd = abbrStart.IndexOf('\0');
|
||||
|
||||
outList.Add((ttInfo.GmtOffset, locName, abbrStart.Slice(0, abbrEnd).ToString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
outList.Sort();
|
||||
|
||||
return outList;
|
||||
}
|
||||
|
||||
private bool IsLocationNameValid(string locationName)
|
||||
{
|
||||
foreach (string cachedLocationName in LocationNameCache)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue