diff --git a/lib/TweetLib.Browser.CEF/Interfaces/IFileDialogOpener.cs b/lib/TweetLib.Browser.CEF/Interfaces/IFileDialogOpener.cs index fb449091..2f86c8b7 100644 --- a/lib/TweetLib.Browser.CEF/Interfaces/IFileDialogOpener.cs +++ b/lib/TweetLib.Browser.CEF/Interfaces/IFileDialogOpener.cs @@ -1,8 +1,9 @@ using System; using System.Collections.Generic; +using TweetLib.Utils.Dialogs; namespace TweetLib.Browser.CEF.Interfaces { public interface IFileDialogOpener { - void OpenFile(string title, bool multiple, List<string> supportedExtensions, Action<string[]> onAccepted, Action onCancelled); + void OpenFile(string title, bool multiple, List<FileDialogFilter> filters, Action<string[]> onAccepted, Action onCancelled); } } diff --git a/lib/TweetLib.Browser.CEF/Logic/DialogHandlerLogic.cs b/lib/TweetLib.Browser.CEF/Logic/DialogHandlerLogic.cs index 920bcd3e..d85ab24b 100644 --- a/lib/TweetLib.Browser.CEF/Logic/DialogHandlerLogic.cs +++ b/lib/TweetLib.Browser.CEF/Logic/DialogHandlerLogic.cs @@ -1,9 +1,11 @@ +using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using TweetLib.Browser.CEF.Dialogs; using TweetLib.Browser.CEF.Interfaces; +using TweetLib.Utils.Dialogs; using TweetLib.Utils.Static; namespace TweetLib.Browser.CEF.Logic { @@ -19,11 +21,16 @@ public DialogHandlerLogic(IFileDialogOpener fileDialogOpener, IFileDialogCallbac public bool OnFileDialog(FileDialogType type, IEnumerable<string> acceptFilters, TCallback callback) { if (type is FileDialogType.Open or FileDialogType.OpenMultiple) { var multiple = type == FileDialogType.OpenMultiple; - var supportedExtensions = acceptFilters.SelectMany(ParseFileType).Where(static filter => !string.IsNullOrEmpty(filter)).ToList(); + var supportedExtensions = acceptFilters.SelectMany(ParseFileType).Where(static filter => !string.IsNullOrEmpty(filter)).ToArray(); + + var filters = new List<FileDialogFilter> { + new ("All Supported Formats", supportedExtensions), + new ("All Files", ".*") + }; - fileDialogOpener.OpenFile("Open Files", multiple, supportedExtensions, files => { + fileDialogOpener.OpenFile("Open Files", multiple, filters, files => { string ext = Path.GetExtension(files[0])!.ToLower(); - callbackAdapter.Continue(callback, supportedExtensions.FindIndex(filter => ParseFileType(filter).Contains(ext)), files); + callbackAdapter.Continue(callback, Array.FindIndex(supportedExtensions, filter => ParseFileType(filter).Contains(ext)), files); callbackAdapter.Dispose(callback); }, () => { callbackAdapter.Cancel(callback); diff --git a/lib/TweetLib.Core/Features/Chromium/SpellCheck.cs b/lib/TweetLib.Browser.CEF/Utils/SpellCheck.cs similarity index 95% rename from lib/TweetLib.Core/Features/Chromium/SpellCheck.cs rename to lib/TweetLib.Browser.CEF/Utils/SpellCheck.cs index c29af9d7..9016ed41 100644 --- a/lib/TweetLib.Core/Features/Chromium/SpellCheck.cs +++ b/lib/TweetLib.Browser.CEF/Utils/SpellCheck.cs @@ -3,7 +3,7 @@ using TweetLib.Utils.Globalization; using TweetLib.Utils.Static; -namespace TweetLib.Core.Features.Chromium { +namespace TweetLib.Browser.CEF.Utils { public static class SpellCheck { // https://cs.chromium.org/chromium/src/third_party/hunspell_dictionaries/ public static IEnumerable<Language> SupportedLanguages { get; } = new List<string> { diff --git a/lib/TweetLib.Core/Resources/ResourceCache.cs b/lib/TweetLib.Browser/Request/ResourceCache.cs similarity index 86% rename from lib/TweetLib.Core/Resources/ResourceCache.cs rename to lib/TweetLib.Browser/Request/ResourceCache.cs index ef8411a3..630324ce 100644 --- a/lib/TweetLib.Core/Resources/ResourceCache.cs +++ b/lib/TweetLib.Browser/Request/ResourceCache.cs @@ -2,18 +2,17 @@ using System.Collections.Generic; using System.IO; using System.Net; -using TweetLib.Browser.Request; using IOFile = System.IO.File; -namespace TweetLib.Core.Resources { +namespace TweetLib.Browser.Request { public sealed class ResourceCache { private readonly Dictionary<string, SchemeResource> cache = new (); - public void ClearCache() { + public void Clear() { cache.Clear(); } - internal SchemeResource ReadFile(string path) { + public SchemeResource ReadFile(string path) { string key = new Uri(path).LocalPath; if (cache.TryGetValue(key, out var cachedResource)) { diff --git a/lib/TweetLib.Core/App.cs b/lib/TweetLib.Core/App.cs index e871d2d4..ff5399dc 100644 --- a/lib/TweetLib.Core/App.cs +++ b/lib/TweetLib.Core/App.cs @@ -1,10 +1,10 @@ using System; using System.IO; using System.Linq; +using TweetLib.Browser.Request; using TweetLib.Core.Application; using TweetLib.Core.Features; using TweetLib.Core.Features.Plugins; -using TweetLib.Core.Resources; using TweetLib.Core.Systems.Configuration; using TweetLib.Core.Systems.Logging; using TweetLib.Utils.Static; diff --git a/lib/TweetLib.Core/Application/IAppFileDialogs.cs b/lib/TweetLib.Core/Application/IAppFileDialogs.cs index 80a89cc9..9d925ed8 100644 --- a/lib/TweetLib.Core/Application/IAppFileDialogs.cs +++ b/lib/TweetLib.Core/Application/IAppFileDialogs.cs @@ -1,5 +1,5 @@ using System; -using TweetLib.Core.Systems.Dialogs; +using TweetLib.Utils.Dialogs; namespace TweetLib.Core.Application { public interface IAppFileDialogs { diff --git a/lib/TweetLib.Core/Application/IAppSetup.cs b/lib/TweetLib.Core/Application/IAppSetup.cs index 72db9d33..0b447ba0 100644 --- a/lib/TweetLib.Core/Application/IAppSetup.cs +++ b/lib/TweetLib.Core/Application/IAppSetup.cs @@ -1,5 +1,5 @@ +using TweetLib.Browser.Request; using TweetLib.Core.Features.Plugins; -using TweetLib.Core.Resources; using TweetLib.Core.Systems.Configuration; namespace TweetLib.Core.Application { diff --git a/lib/TweetLib.Core/Features/FileDownloadManager.cs b/lib/TweetLib.Core/Features/FileDownloadManager.cs index 865370f2..8d609fde 100644 --- a/lib/TweetLib.Core/Features/FileDownloadManager.cs +++ b/lib/TweetLib.Core/Features/FileDownloadManager.cs @@ -4,7 +4,7 @@ using System.Linq; using TweetLib.Browser.Interfaces; using TweetLib.Core.Features.Twitter; -using TweetLib.Core.Systems.Dialogs; +using TweetLib.Utils.Dialogs; using TweetLib.Utils.Static; namespace TweetLib.Core.Features { diff --git a/lib/TweetLib.Core/Features/Plugins/PluginSchemeHandler.cs b/lib/TweetLib.Core/Features/Plugins/PluginSchemeHandler.cs index 0bb37525..531e9b1a 100644 --- a/lib/TweetLib.Core/Features/Plugins/PluginSchemeHandler.cs +++ b/lib/TweetLib.Core/Features/Plugins/PluginSchemeHandler.cs @@ -4,7 +4,6 @@ using TweetLib.Browser.Interfaces; using TweetLib.Browser.Request; using TweetLib.Core.Features.Plugins.Enums; -using TweetLib.Core.Resources; namespace TweetLib.Core.Features.Plugins { public sealed class PluginSchemeHandler : ICustomSchemeHandler { diff --git a/lib/TweetLib.Core/Features/TweetDeck/TweetDuckSchemeHandler.cs b/lib/TweetLib.Core/Features/TweetDeck/TweetDuckSchemeHandler.cs index a7033c2e..cbc695c4 100644 --- a/lib/TweetLib.Core/Features/TweetDeck/TweetDuckSchemeHandler.cs +++ b/lib/TweetLib.Core/Features/TweetDeck/TweetDuckSchemeHandler.cs @@ -2,7 +2,6 @@ using System.Net; using TweetLib.Browser.Interfaces; using TweetLib.Browser.Request; -using TweetLib.Core.Resources; using TweetLib.Utils.Static; namespace TweetLib.Core.Features.TweetDeck { diff --git a/lib/TweetLib.Core/Systems/Dialogs/FileDialogFilter.cs b/lib/TweetLib.Core/Systems/Dialogs/FileDialogFilter.cs deleted file mode 100644 index bd518e5c..00000000 --- a/lib/TweetLib.Core/Systems/Dialogs/FileDialogFilter.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System.Collections.Generic; - -namespace TweetLib.Core.Systems.Dialogs { - public sealed class FileDialogFilter { - public string Name { get; } - public IReadOnlyList<string> Extensions { get; } - - internal FileDialogFilter(string name, params string[] extensions) { - Name = name; - Extensions = extensions; - } - } -} diff --git a/lib/TweetLib.Core/Systems/Dialogs/SaveFileDialogSettings.cs b/lib/TweetLib.Core/Systems/Dialogs/SaveFileDialogSettings.cs deleted file mode 100644 index c6615867..00000000 --- a/lib/TweetLib.Core/Systems/Dialogs/SaveFileDialogSettings.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Collections.Generic; - -namespace TweetLib.Core.Systems.Dialogs { - public sealed class SaveFileDialogSettings { - public string DialogTitle { get; internal set; } = "Save File"; - public bool OverwritePrompt { get; internal set; } = true; - public string? FileName { get; internal set; } - public IReadOnlyList<FileDialogFilter>? Filters { get; internal set; } - } -} diff --git a/lib/TweetLib.Utils/Dialogs/FileDialogFilter.cs b/lib/TweetLib.Utils/Dialogs/FileDialogFilter.cs new file mode 100644 index 00000000..ebdfbe79 --- /dev/null +++ b/lib/TweetLib.Utils/Dialogs/FileDialogFilter.cs @@ -0,0 +1,38 @@ +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; + +namespace TweetLib.Utils.Dialogs { + [SuppressMessage("ReSharper", "MemberCanBePrivate.Global")] + [SuppressMessage("ReSharper", "UnusedMember.Global")] + public sealed class FileDialogFilter { + public string Name { get; } + public IReadOnlyList<string> Extensions { get; } + + public string FullName => FullNameAndPattern.Item1; + public string Pattern => FullNameAndPattern.Item2; + + private (string, string) FullNameAndPattern { + get { + if (Extensions.Count == 0) { + return (Name, "*.*"); + } + else { + string pattern = string.Join(";", Extensions.Select(static ext => "*" + ext)); + string fullName = Name + " (" + pattern + ")"; + return (fullName, pattern); + } + } + } + + public FileDialogFilter(string name, params string[] extensions) { + Name = name; + Extensions = extensions; + } + + public string JoinFullNameAndPattern(string separator) { + var (fullName, pattern) = FullNameAndPattern; + return fullName + separator + pattern; + } + } +} diff --git a/lib/TweetLib.Utils/Dialogs/SaveFileDialogSettings.cs b/lib/TweetLib.Utils/Dialogs/SaveFileDialogSettings.cs new file mode 100644 index 00000000..82945f1d --- /dev/null +++ b/lib/TweetLib.Utils/Dialogs/SaveFileDialogSettings.cs @@ -0,0 +1,10 @@ +using System.Collections.Generic; + +namespace TweetLib.Utils.Dialogs { + public sealed class SaveFileDialogSettings { + public string DialogTitle { get; set; } = "Save File"; + public bool OverwritePrompt { get; set; } = true; + public string? FileName { get; set; } + public IReadOnlyList<FileDialogFilter>? Filters { get; set; } + } +} diff --git a/lib/TweetLib.Utils/Globalization/Language.cs b/lib/TweetLib.Utils/Globalization/Language.cs index d4c51e99..5089a88c 100644 --- a/lib/TweetLib.Utils/Globalization/Language.cs +++ b/lib/TweetLib.Utils/Globalization/Language.cs @@ -3,6 +3,8 @@ namespace TweetLib.Utils.Globalization { public sealed class Language : IComparable<Language> { + public static Language English { get; } = new ("en-US"); + public string Code { get; } private string Name => cultureInfo?.NativeName ?? Code; diff --git a/lib/TweetLib.Core/Systems/Startup/LockFile.cs b/lib/TweetLib.Utils/Startup/LockFile.cs similarity index 95% rename from lib/TweetLib.Core/Systems/Startup/LockFile.cs rename to lib/TweetLib.Utils/Startup/LockFile.cs index f08e8043..25e17543 100644 --- a/lib/TweetLib.Core/Systems/Startup/LockFile.cs +++ b/lib/TweetLib.Utils/Startup/LockFile.cs @@ -5,7 +5,7 @@ using System.Threading; using TweetLib.Utils.Static; -namespace TweetLib.Core.Systems.Startup { +namespace TweetLib.Utils.Startup { public sealed class LockFile { private static int CurrentProcessID { get { @@ -79,17 +79,16 @@ public LockResult LockWait(int timeout, int retryDelay) { return Lock(); } - public bool Unlock() { + public UnlockResult Unlock() { if (ReleaseLockFileStream()) { try { File.Delete(path); } catch (Exception e) { - App.Logger.Error(e.ToString()); - return false; + return new UnlockResult.Fail(e); } } - return true; + return UnlockResult.Success; } [SuppressMessage("ReSharper", "PossibleNullReferenceException")] diff --git a/lib/TweetLib.Core/Systems/Startup/LockResult.cs b/lib/TweetLib.Utils/Startup/LockResult.cs similarity index 94% rename from lib/TweetLib.Core/Systems/Startup/LockResult.cs rename to lib/TweetLib.Utils/Startup/LockResult.cs index fc320fc0..fd83b19d 100644 --- a/lib/TweetLib.Core/Systems/Startup/LockResult.cs +++ b/lib/TweetLib.Utils/Startup/LockResult.cs @@ -1,7 +1,7 @@ using System; using System.Diagnostics; -namespace TweetLib.Core.Systems.Startup { +namespace TweetLib.Utils.Startup { public class LockResult { private readonly string name; diff --git a/lib/TweetLib.Utils/Startup/UnlockResult.cs b/lib/TweetLib.Utils/Startup/UnlockResult.cs new file mode 100644 index 00000000..2b48bf4d --- /dev/null +++ b/lib/TweetLib.Utils/Startup/UnlockResult.cs @@ -0,0 +1,25 @@ +using System; + +namespace TweetLib.Utils.Startup { + public class UnlockResult { + private readonly string name; + + private UnlockResult(string name) { + this.name = name; + } + + public override string ToString() { + return name; + } + + public static UnlockResult Success { get; } = new ("Success"); + + public sealed class Fail : UnlockResult { + public Exception Exception { get; } + + internal Fail(Exception exception) : base("Fail") { + this.Exception = exception; + } + } + } +} diff --git a/lib/TweetTest.Utils/Dialogs/TestFileDialogFilter.fs b/lib/TweetTest.Utils/Dialogs/TestFileDialogFilter.fs new file mode 100644 index 00000000..98a968c3 --- /dev/null +++ b/lib/TweetTest.Utils/Dialogs/TestFileDialogFilter.fs @@ -0,0 +1,41 @@ +namespace TweetTest.Utils.Dialogs.FileDialogFilter + +open TweetLib.Utils.Dialogs +open Xunit + + +type internal TestData = + + static member noExtensions = FileDialogFilter("Any Filter") + static member oneExtension = FileDialogFilter("Single Filter", ".1") + static member twoExtensions = FileDialogFilter("Double Filter", ".1", ".2") + + +module Pattern = + + [<Fact>] + let ``no extension assumes any files`` () = + Assert.Equal("*.*", TestData.noExtensions.Pattern) + + [<Fact>] + let ``one extension prepends with asterisk`` () = + Assert.Equal("*.1", TestData.oneExtension.Pattern) + + [<Fact>] + let ``multiple extensions are separated by semicolons`` () = + Assert.Equal("*.1;*.2", TestData.twoExtensions.Pattern) + + +module FullName = + + [<Fact>] + let ``no extension keeps original name`` () = + Assert.Equal("Any Filter", TestData.noExtensions.FullName) + + [<Fact>] + let ``one extension appends pattern in parentheses`` () = + Assert.Equal("Single Filter (*.1)", TestData.oneExtension.FullName) + + [<Fact>] + let ``multiple extensions in pattern are separated by semicolons`` () = + Assert.Equal("Double Filter (*.1;*.2)", TestData.twoExtensions.FullName) diff --git a/lib/TweetTest.Utils/TweetTest.Utils.fsproj b/lib/TweetTest.Utils/TweetTest.Utils.fsproj index 01f93983..54f4a5ff 100644 --- a/lib/TweetTest.Utils/TweetTest.Utils.fsproj +++ b/lib/TweetTest.Utils/TweetTest.Utils.fsproj @@ -27,6 +27,7 @@ <Compile Include="Collections\TestTwoKeyDictionary.fs" /> <Compile Include="Data\TestInjectedString.fs" /> <Compile Include="Data\TestResult.fs" /> + <Compile Include="Dialogs\TestFileDialogFilter.fs" /> <Compile Include="IO\TestCombinedFileStream.fs" /> <Compile Include="Static\TestStringUtils.fs" /> </ItemGroup> diff --git a/windows/TweetDuck/Application/FileDialogs.cs b/windows/TweetDuck/Application/FileDialogs.cs index b2907ec6..eecfa9fe 100644 --- a/windows/TweetDuck/Application/FileDialogs.cs +++ b/windows/TweetDuck/Application/FileDialogs.cs @@ -1,37 +1,20 @@ using System; using System.Linq; -using System.Text; using System.Windows.Forms; using TweetDuck.Management; using TweetLib.Core.Application; -using TweetLib.Core.Systems.Dialogs; +using TweetLib.Utils.Dialogs; namespace TweetDuck.Application { sealed class FileDialogs : IAppFileDialogs { public void SaveFile(SaveFileDialogSettings settings, Action<string> onAccepted) { - static string FormatFilter(FileDialogFilter filter) { - var builder = new StringBuilder(); - builder.Append(filter.Name); - - var extensions = string.Join(";", filter.Extensions.Select(ext => "*" + ext)); - if (extensions.Length > 0) { - builder.Append(" ("); - builder.Append(extensions); - builder.Append(")"); - } - - builder.Append('|'); - builder.Append(extensions.Length == 0 ? "*.*" : extensions); - return builder.ToString(); - } - FormManager.RunOnUIThreadAsync(() => { using SaveFileDialog dialog = new SaveFileDialog { AutoUpgradeEnabled = true, OverwritePrompt = settings.OverwritePrompt, Title = settings.DialogTitle, FileName = settings.FileName, - Filter = settings.Filters == null ? null : string.Join("|", settings.Filters.Select(FormatFilter)) + Filter = settings.Filters == null ? null : string.Join("|", settings.Filters.Select(filter => filter.JoinFullNameAndPattern("|"))) }; if (dialog.ShowDialog() == DialogResult.OK) { diff --git a/windows/TweetDuck/Browser/FormBrowser.cs b/windows/TweetDuck/Browser/FormBrowser.cs index 16e05468..ab1dc9e9 100644 --- a/windows/TweetDuck/Browser/FormBrowser.cs +++ b/windows/TweetDuck/Browser/FormBrowser.cs @@ -14,15 +14,19 @@ using TweetDuck.Dialogs; using TweetDuck.Dialogs.Settings; using TweetDuck.Management; +using TweetDuck.Properties; using TweetDuck.Updates; using TweetDuck.Utils; +using TweetLib.Browser.Request; using TweetLib.Core; using TweetLib.Core.Features.Notifications; using TweetLib.Core.Features.Plugins; using TweetLib.Core.Features.TweetDeck; -using TweetLib.Core.Resources; using TweetLib.Core.Systems.Configuration; using TweetLib.Core.Systems.Updates; +#if DEBUG +using TweetLib.Core.Resources; +#endif namespace TweetDuck.Browser { sealed partial class FormBrowser : Form, CustomKeyboardHandler.IBrowserKeyHandler { @@ -143,7 +147,7 @@ private void RestoreWindow() { } private void UpdateFormIcon() { // TODO fix to show icon in taskbar too - Icon = Config.MuteNotifications ? Properties.Resources.icon_muted : Properties.Resources.icon; + Icon = Config.MuteNotifications ? Resources.icon_muted : Resources.icon; } private void UpdateTray() { @@ -346,10 +350,10 @@ public void ResumeNotification(NotificationPauseReason reason) { public void ReloadToTweetDeck() { #if DEBUG ResourceHotSwap.Run(); - resourceCache.ClearCache(); + resourceCache.Clear(); #else if (ModifierKeys.HasFlag(Keys.Shift)) { - resourceCache.ClearCache(); + resourceCache.Clear(); } #endif diff --git a/windows/TweetDuck/Dialogs/Settings/TabSettingsGeneral.cs b/windows/TweetDuck/Dialogs/Settings/TabSettingsGeneral.cs index 435d4e45..a747faae 100644 --- a/windows/TweetDuck/Dialogs/Settings/TabSettingsGeneral.cs +++ b/windows/TweetDuck/Dialogs/Settings/TabSettingsGeneral.cs @@ -5,8 +5,8 @@ using TweetDuck.Browser.Base; using TweetDuck.Controls; using TweetDuck.Utils; +using TweetLib.Browser.CEF.Utils; using TweetLib.Core; -using TweetLib.Core.Features.Chromium; using TweetLib.Core.Features.Twitter; using TweetLib.Core.Systems.Updates; using TweetLib.Utils.Globalization; @@ -115,7 +115,7 @@ public TabSettingsGeneral(Action reloadTweetDeck, Action reloadColumns, UpdateCh comboBoxSpellCheckLanguage.Items.Add(item); } } catch { - comboBoxSpellCheckLanguage.Items.Add(new Language("en-US")); + comboBoxSpellCheckLanguage.Items.Add(Language.English); } comboBoxSpellCheckLanguage.SelectedItem = new Language(Config.SpellCheckLanguage); diff --git a/windows/TweetDuck/Management/LockManager.cs b/windows/TweetDuck/Management/LockManager.cs index 277a1776..1b9c796f 100644 --- a/windows/TweetDuck/Management/LockManager.cs +++ b/windows/TweetDuck/Management/LockManager.cs @@ -4,7 +4,7 @@ using TweetDuck.Dialogs; using TweetDuck.Utils; using TweetLib.Core; -using TweetLib.Core.Systems.Startup; +using TweetLib.Utils.Startup; namespace TweetDuck.Management { sealed class LockManager { @@ -26,15 +26,25 @@ public bool Lock(bool wasRestarted) { } public bool Unlock() { - return lockFile.Unlock(); + UnlockResult result = lockFile.Unlock(); + + if (result is UnlockResult.Fail fail) { + App.Logger.Error(fail.Exception.ToString()); + return false; + } + else if (result != UnlockResult.Success) { + return false; + } + + return true; } // Locking private bool LaunchNormally() { - LockResult lockResult = lockFile.Lock(); + LockResult result = lockFile.Lock(); - if (lockResult is LockResult.HasProcess info) { + if (result is LockResult.HasProcess info) { if (!RestoreProcess(info.Process, WindowRestoreMessage) && FormMessage.Error("TweetDuck is Already Running", "Another instance of TweetDuck is already running.\nDo you want to close it?", FormMessage.Yes, FormMessage.No)) { if (!CloseProcess(info.Process)) { FormMessage.Error("TweetDuck Has Failed :(", "Could not close the other process.", FormMessage.OK); @@ -42,18 +52,18 @@ private bool LaunchNormally() { } info.Dispose(); - lockResult = lockFile.Lock(); + result = lockFile.Lock(); } else { return false; } } - if (lockResult is LockResult.Fail fail) { + if (result is LockResult.Fail fail) { ShowGenericException(fail); return false; } - else if (lockResult != LockResult.Success) { + else if (result != LockResult.Success) { FormMessage.Error("TweetDuck Has Failed :(", "An unknown error occurred accessing the data folder. Please, make sure TweetDuck is not already running. If the problem persists, try restarting your system.", FormMessage.OK); return false; } @@ -62,10 +72,10 @@ private bool LaunchNormally() { } private bool LaunchAfterRestart() { - LockResult lockResult = lockFile.LockWait(10000, WaitRetryDelay); + LockResult result = lockFile.LockWait(10000, WaitRetryDelay); - while (lockResult != LockResult.Success) { - if (lockResult is LockResult.Fail fail) { + while (result != LockResult.Success) { + if (result is LockResult.Fail fail) { ShowGenericException(fail); return false; } @@ -73,7 +83,7 @@ private bool LaunchAfterRestart() { return false; } - lockResult = lockFile.LockWait(5000, WaitRetryDelay); + result = lockFile.LockWait(5000, WaitRetryDelay); } return true; diff --git a/windows/TweetDuck/Program.cs b/windows/TweetDuck/Program.cs index 07281684..53ff420d 100644 --- a/windows/TweetDuck/Program.cs +++ b/windows/TweetDuck/Program.cs @@ -13,12 +13,12 @@ using TweetDuck.Utils; using TweetImpl.CefSharp.Handlers; using TweetLib.Browser.CEF.Utils; +using TweetLib.Browser.Request; using TweetLib.Core; using TweetLib.Core.Application; using TweetLib.Core.Features.Plugins; using TweetLib.Core.Features.Plugins.Config; using TweetLib.Core.Features.TweetDeck; -using TweetLib.Core.Resources; using TweetLib.Core.Systems.Configuration; using TweetLib.Utils.Collections; using Win = System.Windows.Forms; diff --git a/windows/TweetImpl.CefSharp/Dialogs/FileDialogOpener.cs b/windows/TweetImpl.CefSharp/Dialogs/FileDialogOpener.cs index b4a9ccf3..b19998fc 100644 --- a/windows/TweetImpl.CefSharp/Dialogs/FileDialogOpener.cs +++ b/windows/TweetImpl.CefSharp/Dialogs/FileDialogOpener.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Windows.Forms; using TweetLib.Browser.CEF.Interfaces; +using TweetLib.Utils.Dialogs; namespace TweetImpl.CefSharp.Dialogs { sealed class FileDialogOpener : IFileDialogOpener { @@ -10,15 +11,13 @@ sealed class FileDialogOpener : IFileDialogOpener { private FileDialogOpener() {} - public void OpenFile(string title, bool multiple, List<string> supportedExtensions, Action<string[]> onAccepted, Action onCancelled) { - string supportedFormatsFilter = string.Join(";", supportedExtensions.Select(filter => "*" + filter)); - + public void OpenFile(string title, bool multiple, List<FileDialogFilter> filters, Action<string[]> onAccepted, Action onCancelled) { using OpenFileDialog dialog = new OpenFileDialog { AutoUpgradeEnabled = true, DereferenceLinks = true, Multiselect = multiple, Title = title, - Filter = $"All Supported Formats ({supportedFormatsFilter})|{supportedFormatsFilter}|All Files (*.*)|*.*" + Filter = string.Join("|", filters.Select(filter => filter.JoinFullNameAndPattern("|"))) }; if (dialog.ShowDialog() == DialogResult.OK) { diff --git a/windows/TweetImpl.CefSharp/TweetImpl.CefSharp.csproj b/windows/TweetImpl.CefSharp/TweetImpl.CefSharp.csproj index 18e83a70..312dffdf 100644 --- a/windows/TweetImpl.CefSharp/TweetImpl.CefSharp.csproj +++ b/windows/TweetImpl.CefSharp/TweetImpl.CefSharp.csproj @@ -62,6 +62,10 @@ <Project>{eefb1f37-7cad-46bd-8042-66e7b502ab02}</Project> <Name>TweetLib.Browser</Name> </ProjectReference> + <ProjectReference Include="..\..\lib\TweetLib.Utils\TweetLib.Utils.csproj"> + <Project>{476b1007-b12c-447f-b855-9886048201d6}</Project> + <Name>TweetLib.Utils</Name> + </ProjectReference> </ItemGroup> <ItemGroup> <Compile Include="..\..\Version.cs" Link="Version.cs" />