From 9430b9d75b332414bcacaacf4585825a1193b7c0 Mon Sep 17 00:00:00 2001 From: Piotrekol <4990365+Piotrekol@users.noreply.github.com> Date: Sat, 4 Jun 2022 00:36:13 +0200 Subject: [PATCH 01/10] Misc: Bump projects to net 4.8 --- App/App.csproj | 2 +- CollectionGenerator/CollectionGenerator.csproj | 2 +- CollectionManagerDll/CollectionManagerDll.csproj | 2 +- Common/Common.csproj | 2 +- GuiComponents/GuiComponents.csproj | 3 ++- MusicPlayer/MusicPlayer.csproj | 2 +- 6 files changed, 7 insertions(+), 6 deletions(-) diff --git a/App/App.csproj b/App/App.csproj index 5cc92b7..43db4a0 100644 --- a/App/App.csproj +++ b/App/App.csproj @@ -1,7 +1,7 @@ WinExe - net472 + net48 osu! Collection Manager Gui Copyright © 2017-present Piotrekol diff --git a/CollectionGenerator/CollectionGenerator.csproj b/CollectionGenerator/CollectionGenerator.csproj index 822a0ec..e406d66 100644 --- a/CollectionGenerator/CollectionGenerator.csproj +++ b/CollectionGenerator/CollectionGenerator.csproj @@ -1,7 +1,7 @@  Exe - net472 + net48 true CollectionGenerator CollectionGenerator diff --git a/CollectionManagerDll/CollectionManagerDll.csproj b/CollectionManagerDll/CollectionManagerDll.csproj index c577da8..ed003de 100644 --- a/CollectionManagerDll/CollectionManagerDll.csproj +++ b/CollectionManagerDll/CollectionManagerDll.csproj @@ -3,7 +3,7 @@ {533AB47A-D1B5-45DB-A37E-F053FA3699C4} CollectionManager CollectionManager - netstandard20;net471 + netstandard20;net48 CollectionManager Implements read/write access to osu! db & osdb collection files, along with ability to edit these in a reasonable manner diff --git a/Common/Common.csproj b/Common/Common.csproj index 2df1a9d..1801b7d 100644 --- a/Common/Common.csproj +++ b/Common/Common.csproj @@ -1,6 +1,6 @@  - net472 + net48 Common Common Copyright © 2017 diff --git a/GuiComponents/GuiComponents.csproj b/GuiComponents/GuiComponents.csproj index d192ca0..0b35996 100644 --- a/GuiComponents/GuiComponents.csproj +++ b/GuiComponents/GuiComponents.csproj @@ -1,10 +1,11 @@  - net472 + net48 GuiComponents GuiComponents Copyright © 2017 latest + true true diff --git a/MusicPlayer/MusicPlayer.csproj b/MusicPlayer/MusicPlayer.csproj index 0846055..7abbce6 100644 --- a/MusicPlayer/MusicPlayer.csproj +++ b/MusicPlayer/MusicPlayer.csproj @@ -1,6 +1,6 @@  - net472 + net48 MusicPlayer MusicPlayer Copyright © 2017 From f08549d209b4f469ed1c4cd1aebb5f474a93615d Mon Sep 17 00:00:00 2001 From: Piotrekol <4990365+Piotrekol@users.noreply.github.com> Date: Sat, 4 Jun 2022 00:39:35 +0200 Subject: [PATCH 02/10] Misc: Support canceling of osu!.db load --- .../FileIO/OsuDb/LOsuDatabaseLoader.cs | 12 ++++--- .../Modules/FileIO/OsuDb/OsuDatabase.cs | 10 ++++-- .../Modules/FileIO/OsuDb/OsuDatabaseReader.cs | 35 ++++++++++--------- 3 files changed, 32 insertions(+), 25 deletions(-) diff --git a/CollectionManagerDll/Modules/FileIO/OsuDb/LOsuDatabaseLoader.cs b/CollectionManagerDll/Modules/FileIO/OsuDb/LOsuDatabaseLoader.cs index 966b2f3..aeeabe7 100644 --- a/CollectionManagerDll/Modules/FileIO/OsuDb/LOsuDatabaseLoader.cs +++ b/CollectionManagerDll/Modules/FileIO/OsuDb/LOsuDatabaseLoader.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using CollectionManager.DataTypes; using CollectionManager.Interfaces; @@ -8,7 +9,7 @@ public class LOsuDatabaseLoader : OsuDatabaseLoader { private ILogger logger; public string status { get; private set; } - public LOsuDatabaseLoader(ILogger logger, IMapDataManager mapDataStorer, Beatmap tempBeatmap) : base(logger, mapDataStorer, tempBeatmap) + public LOsuDatabaseLoader(IMapDataManager mapDataStorer, Beatmap tempBeatmap) : base(mapDataStorer, tempBeatmap) { } @@ -20,17 +21,18 @@ protected override bool FileExists(string fullPath) return result; } - public override void LoadDatabase(string fullOsuDbPath) + public override void LoadDatabase(string fullOsuDbPath, IProgress progress, CancellationToken cancellationToken) { status = "Loading database"; - base.LoadDatabase(fullOsuDbPath); + base.LoadDatabase(fullOsuDbPath, progress, cancellationToken); status = $"Loaded {NumberOfLoadedBeatmaps} beatmaps"; } - protected override void ReadDatabaseEntries() + + protected override void ReadDatabaseEntries(IProgress progress, CancellationToken cancellationToken) { try { - base.ReadDatabaseEntries(); + base.ReadDatabaseEntries(progress, cancellationToken); } catch (Exception e) { diff --git a/CollectionManagerDll/Modules/FileIO/OsuDb/OsuDatabase.cs b/CollectionManagerDll/Modules/FileIO/OsuDb/OsuDatabase.cs index c44dcb6..cb99af7 100644 --- a/CollectionManagerDll/Modules/FileIO/OsuDb/OsuDatabase.cs +++ b/CollectionManagerDll/Modules/FileIO/OsuDb/OsuDatabase.cs @@ -1,4 +1,6 @@ using CollectionManager.DataTypes; +using System; +using System.Threading; namespace CollectionManager.Modules.FileIO.OsuDb { @@ -17,14 +19,16 @@ public class OsuDatabase public OsuDatabase(Beatmap beatmapBase) { - _databaseLoader = new LOsuDatabaseLoader(null, LoadedMaps, beatmapBase); + _databaseLoader = new LOsuDatabaseLoader(LoadedMaps, beatmapBase); } - public void Load(string fileDir) + public void Load(string fileDir, IProgress progress, CancellationToken cancellationToken) { OsuFileLocation = fileDir; - _databaseLoader.LoadDatabase(fileDir); + _databaseLoader.LoadDatabase(fileDir, progress, cancellationToken); } + public void Load(string fileDir, IProgress progress = null) => Load(fileDir, progress, CancellationToken.None); + } } diff --git a/CollectionManagerDll/Modules/FileIO/OsuDb/OsuDatabaseReader.cs b/CollectionManagerDll/Modules/FileIO/OsuDb/OsuDatabaseReader.cs index 2cbf175..4314a4d 100644 --- a/CollectionManagerDll/Modules/FileIO/OsuDb/OsuDatabaseReader.cs +++ b/CollectionManagerDll/Modules/FileIO/OsuDb/OsuDatabaseReader.cs @@ -6,13 +6,13 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Threading; namespace CollectionManager.Modules.FileIO.OsuDb { //TODO: refactor to allow for read/write access. public class OsuDatabaseLoader { - private readonly ILogger _logger; private readonly IMapDataManager _mapDataStorer; private FileStream _fileStream; private BinaryReader _binaryReader; @@ -27,44 +27,46 @@ public class OsuDatabaseLoader public int ExpectedNumOfBeatmaps { get; private set; } = -1; public int NumberOfLoadedBeatmaps { get; private set; } - public OsuDatabaseLoader(ILogger logger, IMapDataManager mapDataStorer, Beatmap tempBeatmap) + public OsuDatabaseLoader(IMapDataManager mapDataStorer, Beatmap tempBeatmap) { _tempBeatmap = tempBeatmap; _mapDataStorer = mapDataStorer; - _logger = logger; } - public virtual void LoadDatabase(string fullOsuDbPath) + public virtual void LoadDatabase(string fullOsuDbPath, IProgress progress, CancellationToken cancellationToken) { if (FileExists(fullOsuDbPath)) { _fileStream = new FileStream(fullOsuDbPath, FileMode.Open, FileAccess.Read); _binaryReader = new BinaryReader(_fileStream); - if (DatabaseContainsData()) + if (DatabaseContainsData(progress)) { - ReadDatabaseEntries(); + ReadDatabaseEntries(progress, cancellationToken); } DestoryReader(); } GC.Collect(); } - protected virtual void ReadDatabaseEntries() + protected virtual void ReadDatabaseEntries(IProgress progress, CancellationToken cancellationToken) { - _logger?.Log("Starting MassStoring of {0} beatmaps", ExpectedNumOfBeatmaps.ToString()); + progress?.Report($"Starting load of {ExpectedNumOfBeatmaps} beatmaps"); _mapDataStorer.StartMassStoring(); for (NumberOfLoadedBeatmaps = 0; NumberOfLoadedBeatmaps < ExpectedNumOfBeatmaps; NumberOfLoadedBeatmaps++) { if (NumberOfLoadedBeatmaps % 100 == 0) - _logger?.Log("Loading {0} of {1}", NumberOfLoadedBeatmaps.ToString(), - ExpectedNumOfBeatmaps.ToString()); + progress?.Report($"Loading {NumberOfLoadedBeatmaps} of {ExpectedNumOfBeatmaps}"); + if (cancellationToken.IsCancellationRequested) + break; ReadNextBeatmap(); } - _logger?.Log("Loaded {0} beatmaps", NumberOfLoadedBeatmaps.ToString()); + + progress?.Report($"Loaded {NumberOfLoadedBeatmaps} beatmaps"); _mapDataStorer.EndMassStoring(); - LoadedSuccessfully = true; + if (!cancellationToken.IsCancellationRequested) + LoadedSuccessfully = true; } private void ReadNextBeatmap() { @@ -361,16 +363,16 @@ private string ReadString() } return ""; } - private bool DatabaseContainsData() + private bool DatabaseContainsData(IProgress progress) { FileDate = _binaryReader.ReadInt32(); if (FileDate < 20191105) { - _logger?.Log(string.Format("Outdated osu!.db version({0}). Load failed.", FileDate.ToString())); + progress?.Report($"Outdated osu!.db version ({FileDate}). Load failed."); return false; } ExpectedNumberOfMapSets = _binaryReader.ReadInt32(); - _logger?.Log(string.Format("Expected number of mapSets: {0}", ExpectedNumberOfMapSets)); + progress?.Report($"Expected number of mapSets: {ExpectedNumberOfMapSets}"); try { bool something = _binaryReader.ReadBoolean(); @@ -378,8 +380,7 @@ private bool DatabaseContainsData() _binaryReader.BaseStream.Seek(1, SeekOrigin.Current); Username = _binaryReader.ReadString(); ExpectedNumOfBeatmaps = _binaryReader.ReadInt32(); - - _logger?.Log(string.Format("Expected number of beatmaps: {0}", ExpectedNumOfBeatmaps)); + progress?.Report($"Expected number of beatmaps: {ExpectedNumOfBeatmaps}"); if (ExpectedNumOfBeatmaps < 0) { From 32a30d14b4c75b48aed05c5c52086ba6d521755a Mon Sep 17 00:00:00 2001 From: Piotrekol <4990365+Piotrekol@users.noreply.github.com> Date: Sat, 4 Jun 2022 00:45:45 +0200 Subject: [PATCH 03/10] Add: Improved startup screen --- App/Initalizer.cs | 53 +---- App/Models/StartupSettings.cs | 12 ++ App/Presenters/Controls/StartupPresenter.cs | 155 ++++++++++++++ App/Properties/Settings.Designer.cs | 22 +- App/Properties/Settings.settings | 7 +- App/SidePanelActionsHandler.cs | 4 + App/app.config | 7 +- CollectionManagerDll/DataTypes/Beatmap.cs | 4 +- .../Interfaces/IScoreDataStorer.cs | 1 + .../Modules/FileIO/OsuPathResolver.cs | 3 + .../FileIO/OsuScoresDb/ScoresCacher.cs | 7 + .../FileIO/OsuScoresDb/ScoresDatabaseIO.cs | 6 +- Common/GuiHelpers.cs | 3 +- Common/Interfaces/Controls/IStartupView.cs | 15 ++ Common/Interfaces/Forms/IStartupForm.cs | 11 + Common/StartupCollectionAction.cs | 9 + Common/StartupDatabaseAction.cs | 8 + .../Controls/MainSidePanelView.Designer.cs | 42 ++-- .../Controls/StartupView.Designer.cs | 200 ++++++++++++++++++ GuiComponents/Controls/StartupView.cs | 117 ++++++++++ GuiComponents/Controls/StartupView.resx | 120 +++++++++++ GuiComponents/Forms/MainFormView.cs | 9 +- GuiComponents/Forms/StartupForm.Designer.cs | 65 ++++++ GuiComponents/Forms/StartupForm.cs | 39 ++++ GuiComponents/Forms/StartupForm.resx | 120 +++++++++++ 25 files changed, 941 insertions(+), 98 deletions(-) create mode 100644 App/Models/StartupSettings.cs create mode 100644 App/Presenters/Controls/StartupPresenter.cs create mode 100644 Common/Interfaces/Controls/IStartupView.cs create mode 100644 Common/Interfaces/Forms/IStartupForm.cs create mode 100644 Common/StartupCollectionAction.cs create mode 100644 Common/StartupDatabaseAction.cs create mode 100644 GuiComponents/Controls/StartupView.Designer.cs create mode 100644 GuiComponents/Controls/StartupView.cs create mode 100644 GuiComponents/Controls/StartupView.resx create mode 100644 GuiComponents/Forms/StartupForm.Designer.cs create mode 100644 GuiComponents/Forms/StartupForm.cs create mode 100644 GuiComponents/Forms/StartupForm.resx diff --git a/App/Initalizer.cs b/App/Initalizer.cs index 72fa9b3..18ef268 100644 --- a/App/Initalizer.cs +++ b/App/Initalizer.cs @@ -1,18 +1,17 @@ -using System; using System.IO; +using System.Threading.Tasks; using System.Windows.Forms; using App.Interfaces; using App.Misc; using App.Models; using App.Models.Forms; +using App.Presenters.Controls; using App.Presenters.Forms; using App.Properties; using CollectionManager.DataTypes; using CollectionManager.Modules.CollectionsManager; using CollectionManager.Modules.FileIO; using CollectionManagerExtensionsDll.Modules.API.osustats; -using CollectionManagerExtensionsDll.Utils; -using Common; using GuiComponents.Interfaces; namespace App @@ -27,51 +26,14 @@ public class Initalizer : ApplicationContext public static CollectionEditor CollectionEditor { get; private set; } private IUserDialogs UserDialogs { get; set; }// = new GuiComponents.UserDialogs(); public static OsuStatsApi WebCollectionProvider = new OsuStatsApi("", OsuFileIo.LoadedMaps); - public void Run(string[] args) + public static StartupPresenter StartupPresenter; + + public async Task Run(string[] args) { //IUserDialogs can be implemented in WinForm or WPF or Gtk or Console or...? UserDialogs = GuiComponentsProvider.Instance.GetClassImplementing(); - if (Settings.Default.DontAskAboutOsuDirectory) - OsuDirectory = OsuFileIo.OsuPathResolver.GetOsuDir(_ => false, _ => Settings.Default.OsuDirectory); - else - OsuDirectory = OsuFileIo.OsuPathResolver.GetOsuDir(dir => - { - var result = UserDialogs.YesNoMessageBox($"Detected osu! in \"{dir}\"{Environment.NewLine}Is that correct?", "osu! directory", MessageBoxType.Question, - "Don't ask me again"); - Settings.Default.DontAskAboutOsuDirectory = result.doNotAskAgain; - Settings.Default.Save(); - return result.Result; - }, UserDialogs.SelectDirectory); - - if (string.IsNullOrEmpty(OsuDirectory) && UserDialogs.YesNoMessageBox( - "osu! could not be found. Do you want to continue regardless?" + Environment.NewLine + - "This will cause all .db collections to show only as beatmap hashes.", "osu! location", - MessageBoxType.Question) == false) - { - Quit(); - } - if (!string.IsNullOrEmpty(OsuDirectory)) - { - Settings.Default.OsuDirectory = OsuDirectory; - Settings.Default.Save(); - //Load osu database and setting files - var osuDbFile = Path.Combine(OsuDirectory, @"osu!.db"); - var osuScoresFile = Path.Combine(OsuDirectory, @"scores.db"); - OsuFileIo.OsuDatabase.Load(osuDbFile); - OsuFileIo.OsuSettings.Load(OsuDirectory); - try - { - OsuFileIo.ScoresLoader.ReadDb(osuScoresFile); - } - catch (Exception e) - { - UserDialogs.OkMessageBox("Warning", "osu! scores database could not be loaded. Score related searches will not work in this session." + Environment.NewLine + Environment.NewLine + e); - } - - BeatmapUtils.OsuSongsDirectory = OsuFileIo.OsuSettings.CustomBeatmapDirectoryLocation; - } //Init "main" classes CollectionsManager = new CollectionsManagerWithCounts(LoadedBeatmaps); @@ -88,8 +50,6 @@ public void Run(string[] args) //set initial text info and update events SetTextData(infoTextModel); - - if (args.Length > 0) { if (File.Exists(args[0])) @@ -104,6 +64,9 @@ public void Run(string[] args) if (!string.IsNullOrWhiteSpace(Settings.Default.Osustats_apiKey)) guiActionsHandler.SidePanelActionsHandler.OsustatsLogin(null, Settings.Default.Osustats_apiKey); + StartupPresenter = new StartupPresenter(GuiComponentsProvider.Instance.GetClassImplementing(), guiActionsHandler.SidePanelActionsHandler, UserDialogs); + await StartupPresenter.Run(); + mainForm.ShowAndBlock(); Quit(); } diff --git a/App/Models/StartupSettings.cs b/App/Models/StartupSettings.cs new file mode 100644 index 0000000..43aaf14 --- /dev/null +++ b/App/Models/StartupSettings.cs @@ -0,0 +1,12 @@ +using Common; + +namespace App.Models +{ + public class StartupSettings + { + public StartupDatabaseAction StartupDatabaseAction { get; set; } + public StartupCollectionAction StartupCollectionAction { get; set; } + public bool UseSelectedOptionsOnStartup { get; set; } + public string OsuLocation { get; set; } + } +} \ No newline at end of file diff --git a/App/Presenters/Controls/StartupPresenter.cs b/App/Presenters/Controls/StartupPresenter.cs new file mode 100644 index 0000000..94b8b48 --- /dev/null +++ b/App/Presenters/Controls/StartupPresenter.cs @@ -0,0 +1,155 @@ +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; +using App.Models; +using App.Properties; +using CollectionManagerExtensionsDll.Utils; +using Common; +using GuiComponents.Interfaces; +using Newtonsoft.Json; + +namespace App.Presenters.Controls +{ + public class StartupPresenter + { + private readonly IStartupForm _view; + private readonly SidePanelActionsHandler _sidePanelActionsHandler; + private readonly IUserDialogs _userDialogs; + private StartupSettings _startupSettings; + private CancellationTokenSource _cancellationTokenSource; + private Progress _databaseLoadProgressReporter; + private Task _databaseLoadTask; + + public StartupPresenter(IStartupForm view, SidePanelActionsHandler sidePanelActionsHandler, IUserDialogs userDialogs) + { + _view = view; + _sidePanelActionsHandler = sidePanelActionsHandler; + _userDialogs = userDialogs; + _startupSettings = JsonConvert.DeserializeObject(Settings.Default.StartupSettings); + _cancellationTokenSource = new CancellationTokenSource(); + _databaseLoadProgressReporter = new Progress(report => + { + if (string.IsNullOrEmpty(Initalizer.OsuDirectory)) + _view.StartupView.LoadDatabaseStatusText = report; + else + _view.StartupView.LoadDatabaseStatusText = $"osu! location: \"{Initalizer.OsuDirectory}\"{Environment.NewLine}{report}"; + }); + + _view.StartupView.UseSelectedOptionsOnStartup = _startupSettings.UseSelectedOptionsOnStartup; + _view.StartupView.StartupCollectionOperation += _view_StartupCollectionOperation; + _view.StartupView.StartupDatabaseOperation += StartupView_StartupDatabaseOperation; + } + + public async Task Run() + { + _databaseLoadTask = Task.Run(() => LoadDatabase(_cancellationTokenSource.Token)); + if (_startupSettings.UseSelectedOptionsOnStartup) + { + _view.StartupView.ButtonsEnabled = false; + Application.UseWaitCursor = true; + _view.Show(); + } + else + _view.ShowAndBlock(); + + await _databaseLoadTask; + if (_startupSettings.UseSelectedOptionsOnStartup) + { + _view.Close(); + Application.UseWaitCursor = false; + } + + _startupSettings.UseSelectedOptionsOnStartup = _view.StartupView.UseSelectedOptionsOnStartup; + SaveSettings(); + + switch (_startupSettings.StartupCollectionAction) + { + case StartupCollectionAction.None: + break; + case StartupCollectionAction.LoadCollection: + _sidePanelActionsHandler.LoadCollectionFile(); + break; + case StartupCollectionAction.LoadDefaultCollection: + _sidePanelActionsHandler.LoadDefaultCollection(); + break; + } + } + + private async void StartupView_StartupDatabaseOperation(object sender, StartupDatabaseAction args) + { + _startupSettings.StartupDatabaseAction = args; + _cancellationTokenSource.Cancel(); + _cancellationTokenSource.Dispose(); + _cancellationTokenSource = new CancellationTokenSource(); + await _databaseLoadTask; + switch (args) + { + case StartupDatabaseAction.None: + Initalizer.OsuFileIo.OsuDatabase.LoadedMaps.UnloadBeatmaps(); + Initalizer.OsuFileIo.ScoresDatabase.Clear(); + Initalizer.OsuDirectory = null; + _view.StartupView.LoadDefaultCollectionButtonEnabled = false; + ((IProgress)_databaseLoadProgressReporter).Report("osu! database unloaded"); + break; + case StartupDatabaseAction.LoadFromDifferentLocation: + var osuDirectory = Initalizer.OsuFileIo.OsuPathResolver.GetManualOsuDir(_userDialogs.SelectDirectory); + if (!string.IsNullOrEmpty(osuDirectory)) + { + _startupSettings.OsuLocation = osuDirectory; + _databaseLoadTask = Task.Run(() => LoadDatabase(_cancellationTokenSource.Token)); + } + + break; + } + } + + private async void _view_StartupCollectionOperation(object sender, StartupCollectionAction args) + { + _startupSettings.StartupCollectionAction = args; + _view.StartupView.ButtonsEnabled = false; + Application.UseWaitCursor = true; + await _databaseLoadTask; + Application.UseWaitCursor = false; + _view.Close(); + } + + private void LoadDatabase(CancellationToken cancellationToken) + { + var osuFileIo = Initalizer.OsuFileIo; + var osuDirectory = Initalizer.OsuDirectory = string.IsNullOrEmpty(_startupSettings.OsuLocation) + ? osuFileIo.OsuPathResolver.GetOsuDir() + : _startupSettings.OsuLocation; + + if (string.IsNullOrEmpty(osuDirectory)) + { + _view.StartupView.LoadDatabaseStatusText = "osu! could not be found. Select osu! location manually"; + return; + } + + osuFileIo.OsuDatabase.LoadedMaps.UnloadBeatmaps(); + osuFileIo.ScoresDatabase.Clear(); + osuFileIo.OsuDatabase.Load(Path.Combine(osuDirectory, @"osu!.db"), _databaseLoadProgressReporter, cancellationToken); + osuFileIo.OsuSettings.Load(osuDirectory); + try + { + osuFileIo.ScoresLoader.ReadDb(Path.Combine(osuDirectory, @"scores.db"), cancellationToken); + _view.StartupView.LoadDatabaseStatusText += $"{Environment.NewLine}Loaded {osuFileIo.ScoresDatabase.Scores.Count} scores"; + } + catch (Exception) + { + _view.StartupView.LoadDatabaseStatusText += $"{Environment.NewLine}Could not load scores."; + } + + _view.StartupView.LoadDefaultCollectionButtonEnabled = true; + BeatmapUtils.OsuSongsDirectory = Initalizer.OsuFileIo.OsuSettings.CustomBeatmapDirectoryLocation; + } + + private void SaveSettings() + { + Settings.Default.StartupSettings = JsonConvert.SerializeObject(_startupSettings); + Settings.Default.Save(); + } + } +} \ No newline at end of file diff --git a/App/Properties/Settings.Designer.cs b/App/Properties/Settings.Designer.cs index 3f7ff11..501cd9c 100644 --- a/App/Properties/Settings.Designer.cs +++ b/App/Properties/Settings.Designer.cs @@ -12,7 +12,7 @@ namespace App.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.1.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.2.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); @@ -25,13 +25,13 @@ public static Settings Default { [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("False")] - public bool DontAskAboutOsuDirectory { + [global::System.Configuration.DefaultSettingValueAttribute("{}")] + public string StartupSettings { get { - return ((bool)(this["DontAskAboutOsuDirectory"])); + return ((string)(this["StartupSettings"])); } set { - this["DontAskAboutOsuDirectory"] = value; + this["StartupSettings"] = value; } } @@ -83,18 +83,6 @@ public string Osustats_apiKey { } } - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("")] - public string OsuDirectory { - get { - return ((string)(this["OsuDirectory"])); - } - set { - this["OsuDirectory"] = value; - } - } - [global::System.Configuration.UserScopedSettingAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Configuration.DefaultSettingValueAttribute("{}")] diff --git a/App/Properties/Settings.settings b/App/Properties/Settings.settings index 8a5b9da..e01ac22 100644 --- a/App/Properties/Settings.settings +++ b/App/Properties/Settings.settings @@ -2,8 +2,8 @@ - - False + + {} False @@ -17,9 +17,6 @@ - - - {} diff --git a/App/SidePanelActionsHandler.cs b/App/SidePanelActionsHandler.cs index 7ca3c51..98b9282 100644 --- a/App/SidePanelActionsHandler.cs +++ b/App/SidePanelActionsHandler.cs @@ -95,6 +95,10 @@ private void BindMainFormActions() _mainForm.Closing += FormOnClosing; } + public void LoadDefaultCollection() => LoadDefaultCollection(null, null); + + public void LoadCollectionFile() => LoadCollectionFile(null); + private void ResetApplicationSettings(object arg1, object arg2) { if (_userDialogs.YesNoMessageBox( diff --git a/App/app.config b/App/app.config index 799efb4..38fd813 100644 --- a/App/app.config +++ b/App/app.config @@ -8,8 +8,8 @@ - - False + + {} False @@ -23,9 +23,6 @@ - - - {} diff --git a/CollectionManagerDll/DataTypes/Beatmap.cs b/CollectionManagerDll/DataTypes/Beatmap.cs index f62d533..7fd98a5 100644 --- a/CollectionManagerDll/DataTypes/Beatmap.cs +++ b/CollectionManagerDll/DataTypes/Beatmap.cs @@ -61,7 +61,7 @@ public string MapLink { if (MapId == 0) return MapSetLink; - return @"http://osu.ppy.sh/b/" + MapId; + return @"https://osu.ppy.sh/b/" + MapId; } } @@ -71,7 +71,7 @@ public string MapSetLink { if (MapSetId == 0) return string.Empty; - return @"http://osu.ppy.sh/s/" + MapSetId; + return @"https://osu.ppy.sh/s/" + MapSetId; } } //TODO: add helper functions for adding/removing star values diff --git a/CollectionManagerDll/Interfaces/IScoreDataStorer.cs b/CollectionManagerDll/Interfaces/IScoreDataStorer.cs index f8179e4..1d4f5f2 100644 --- a/CollectionManagerDll/Interfaces/IScoreDataStorer.cs +++ b/CollectionManagerDll/Interfaces/IScoreDataStorer.cs @@ -7,6 +7,7 @@ public interface IScoreDataStorer Scores Scores { get; } void StartMassStoring(); void EndMassStoring(); + void Clear(); void Store(Score score); } } \ No newline at end of file diff --git a/CollectionManagerDll/Modules/FileIO/OsuPathResolver.cs b/CollectionManagerDll/Modules/FileIO/OsuPathResolver.cs index b40aacd..fae3a18 100644 --- a/CollectionManagerDll/Modules/FileIO/OsuPathResolver.cs +++ b/CollectionManagerDll/Modules/FileIO/OsuPathResolver.cs @@ -49,6 +49,9 @@ public string GetOsuDir(Func thisPathIsCorrect, Func _getRunningOsuDir(); + private string _getRunningOsuDir() { if (OsuIsRunning) diff --git a/CollectionManagerDll/Modules/FileIO/OsuScoresDb/ScoresCacher.cs b/CollectionManagerDll/Modules/FileIO/OsuScoresDb/ScoresCacher.cs index 067fbd9..c123325 100644 --- a/CollectionManagerDll/Modules/FileIO/OsuScoresDb/ScoresCacher.cs +++ b/CollectionManagerDll/Modules/FileIO/OsuScoresDb/ScoresCacher.cs @@ -17,6 +17,13 @@ public void EndMassStoring() { } + public void Clear() + { + ScoreList.Clear(); + Scores.Clear(); + ScoreHashes.Clear(); + } + public List GetScores(Beatmap map) { return GetScores(map.Md5); diff --git a/CollectionManagerDll/Modules/FileIO/OsuScoresDb/ScoresDatabaseIO.cs b/CollectionManagerDll/Modules/FileIO/OsuScoresDb/ScoresDatabaseIO.cs index bfdb4db..4b16c8a 100644 --- a/CollectionManagerDll/Modules/FileIO/OsuScoresDb/ScoresDatabaseIO.cs +++ b/CollectionManagerDll/Modules/FileIO/OsuScoresDb/ScoresDatabaseIO.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Threading; using CollectionManager.DataTypes; using CollectionManager.Interfaces; @@ -20,7 +21,7 @@ public ScoresDatabaseIo(IScoreDataStorer scoreDataStorer) _scoreDataStorer = scoreDataStorer; } - public virtual void ReadDb(string osuScoresDbPath) + public virtual void ReadDb(string osuScoresDbPath, CancellationToken cancellationToken) { if (FileExists(osuScoresDbPath)) { @@ -37,6 +38,9 @@ public virtual void ReadDb(string osuScoresDbPath) { _scoreDataStorer.Store(Score.ReadScore(_binaryReader, true, Version)); } + + if (cancellationToken.IsCancellationRequested) + break; } _scoreDataStorer.EndMassStoring(); } diff --git a/Common/GuiHelpers.cs b/Common/GuiHelpers.cs index d162567..5b945aa 100644 --- a/Common/GuiHelpers.cs +++ b/Common/GuiHelpers.cs @@ -11,6 +11,7 @@ public static class GuiHelpers public delegate void BeatmapListingActionArgs(object sender, BeatmapListingAction args); public delegate void SidePanelActionsHandlerArgs(object sender, MainSidePanelActions args, object data = null); public delegate void LoadFileArgs(object sender, string[] filePaths); - + public delegate void StartupCollectionEventArgs(object sender, StartupCollectionAction args); + public delegate void StartupDatabaseEventArgs(object sender, StartupDatabaseAction args); } } \ No newline at end of file diff --git a/Common/Interfaces/Controls/IStartupView.cs b/Common/Interfaces/Controls/IStartupView.cs new file mode 100644 index 0000000..d351a25 --- /dev/null +++ b/Common/Interfaces/Controls/IStartupView.cs @@ -0,0 +1,15 @@ +using Gui.Misc; + +namespace GuiComponents.Interfaces +{ + public interface IStartupView + { + event GuiHelpers.StartupCollectionEventArgs StartupCollectionOperation; + event GuiHelpers.StartupDatabaseEventArgs StartupDatabaseOperation; + + string LoadDatabaseStatusText { get; set; } + bool UseSelectedOptionsOnStartup { get; set; } + bool ButtonsEnabled { get; set; } + bool LoadDefaultCollectionButtonEnabled { get; set; } + } +} \ No newline at end of file diff --git a/Common/Interfaces/Forms/IStartupForm.cs b/Common/Interfaces/Forms/IStartupForm.cs new file mode 100644 index 0000000..27a0da2 --- /dev/null +++ b/Common/Interfaces/Forms/IStartupForm.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using Common.Interfaces; + +namespace GuiComponents.Interfaces +{ + public interface IStartupForm : IForm + { + IStartupView StartupView { get; } + } +} \ No newline at end of file diff --git a/Common/StartupCollectionAction.cs b/Common/StartupCollectionAction.cs new file mode 100644 index 0000000..f2a1683 --- /dev/null +++ b/Common/StartupCollectionAction.cs @@ -0,0 +1,9 @@ +namespace Common +{ + public enum StartupCollectionAction + { + None, + LoadCollection, + LoadDefaultCollection, + } +} \ No newline at end of file diff --git a/Common/StartupDatabaseAction.cs b/Common/StartupDatabaseAction.cs new file mode 100644 index 0000000..e3665c2 --- /dev/null +++ b/Common/StartupDatabaseAction.cs @@ -0,0 +1,8 @@ +namespace Common +{ + public enum StartupDatabaseAction + { + None, + LoadFromDifferentLocation + } +} \ No newline at end of file diff --git a/GuiComponents/Controls/MainSidePanelView.Designer.cs b/GuiComponents/Controls/MainSidePanelView.Designer.cs index 28ada1e..cf494d5 100644 --- a/GuiComponents/Controls/MainSidePanelView.Designer.cs +++ b/GuiComponents/Controls/MainSidePanelView.Designer.cs @@ -37,10 +37,10 @@ private void InitializeComponent() this.Menu_saveAllCollections = new System.Windows.Forms.ToolStripMenuItem(); this.Menu_saveOsuCollection = new System.Windows.Forms.ToolStripMenuItem(); this.Menu_collectionsSplit = new System.Windows.Forms.ToolStripMenuItem(); - this.Menu_unloadCollections = new System.Windows.Forms.ToolStripMenuItem(); - this.listingToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); + this.listingToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem(); this.Menu_listAllCollections = new System.Windows.Forms.ToolStripMenuItem(); this.Menu_listMissingMaps = new System.Windows.Forms.ToolStripMenuItem(); + this.Menu_unloadCollections = new System.Windows.Forms.ToolStripMenuItem(); this.onlineToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.Menu_mapDownloads = new System.Windows.Forms.ToolStripMenuItem(); this.Menu_downloadAllMissing = new System.Windows.Forms.ToolStripMenuItem(); @@ -63,7 +63,6 @@ private void InitializeComponent() // this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.fileToolStripMenuItem, - this.listingToolStripMenuItem, this.onlineToolStripMenuItem, this.osustatsCollectionsToolStripMenuItem, this.Menu_beatmapListing, @@ -80,6 +79,7 @@ private void InitializeComponent() this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.MenuItem_Opennn, this.saveToolStripMenuItem, + this.listingToolStripMenuItem1, this.Menu_unloadCollections}); this.fileToolStripMenuItem.Name = "fileToolStripMenuItem"; this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20); @@ -91,7 +91,7 @@ private void InitializeComponent() this.Menu_loadCollection, this.Menu_loadDefaultCollection}); this.MenuItem_Opennn.Name = "MenuItem_Opennn"; - this.MenuItem_Opennn.Size = new System.Drawing.Size(103, 22); + this.MenuItem_Opennn.Size = new System.Drawing.Size(180, 22); this.MenuItem_Opennn.Text = "Open"; // // Menu_loadCollection @@ -113,7 +113,7 @@ private void InitializeComponent() this.Menu_saveOsuCollection, this.Menu_collectionsSplit}); this.saveToolStripMenuItem.Name = "saveToolStripMenuItem"; - this.saveToolStripMenuItem.Size = new System.Drawing.Size(103, 22); + this.saveToolStripMenuItem.Size = new System.Drawing.Size(180, 22); this.saveToolStripMenuItem.Text = "Save"; // // Menu_saveAllCollections @@ -134,20 +134,14 @@ private void InitializeComponent() this.Menu_collectionsSplit.Size = new System.Drawing.Size(217, 22); this.Menu_collectionsSplit.Text = "Collections in separate files"; // - // Menu_unloadCollections - // - this.Menu_unloadCollections.Name = "Menu_unloadCollections"; - this.Menu_unloadCollections.Size = new System.Drawing.Size(103, 22); - this.Menu_unloadCollections.Text = "Clear"; + // listingToolStripMenuItem1 // - // listingToolStripMenuItem - // - this.listingToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.listingToolStripMenuItem1.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { this.Menu_listAllCollections, this.Menu_listMissingMaps}); - this.listingToolStripMenuItem.Name = "listingToolStripMenuItem"; - this.listingToolStripMenuItem.Size = new System.Drawing.Size(54, 20); - this.listingToolStripMenuItem.Text = "Listing"; + this.listingToolStripMenuItem1.Name = "listingToolStripMenuItem1"; + this.listingToolStripMenuItem1.Size = new System.Drawing.Size(180, 22); + this.listingToolStripMenuItem1.Text = "Listing"; // // Menu_listAllCollections // @@ -161,6 +155,12 @@ private void InitializeComponent() this.Menu_listMissingMaps.Size = new System.Drawing.Size(168, 22); this.Menu_listMissingMaps.Text = "List missing maps"; // + // Menu_unloadCollections + // + this.Menu_unloadCollections.Name = "Menu_unloadCollections"; + this.Menu_unloadCollections.Size = new System.Drawing.Size(180, 22); + this.Menu_unloadCollections.Text = "Clear"; + // // onlineToolStripMenuItem // this.onlineToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { @@ -244,8 +244,8 @@ private void InitializeComponent() // Menu_beatmapListing // this.Menu_beatmapListing.Name = "Menu_beatmapListing"; - this.Menu_beatmapListing.Size = new System.Drawing.Size(133, 20); - this.Menu_beatmapListing.Text = "Show beatmap listing"; + this.Menu_beatmapListing.Size = new System.Drawing.Size(101, 20); + this.Menu_beatmapListing.Text = "Beatmap listing"; // // Menu_refreshBeatmapList // @@ -286,9 +286,6 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem MenuItem_Opennn; private System.Windows.Forms.ToolStripMenuItem saveToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem listingToolStripMenuItem; - private System.Windows.Forms.ToolStripMenuItem Menu_listAllCollections; - private System.Windows.Forms.ToolStripMenuItem Menu_listMissingMaps; private System.Windows.Forms.ToolStripMenuItem onlineToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem Menu_mapDownloads; private System.Windows.Forms.ToolStripMenuItem Menu_downloadAllMissing; @@ -310,5 +307,8 @@ private void InitializeComponent() private System.Windows.Forms.ToolStripMenuItem Menu_saveOsuCollection; private System.Windows.Forms.ToolStripMenuItem settingsToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem Menu_resetSettings; + private System.Windows.Forms.ToolStripMenuItem listingToolStripMenuItem1; + private System.Windows.Forms.ToolStripMenuItem Menu_listAllCollections; + private System.Windows.Forms.ToolStripMenuItem Menu_listMissingMaps; } } diff --git a/GuiComponents/Controls/StartupView.Designer.cs b/GuiComponents/Controls/StartupView.Designer.cs new file mode 100644 index 0000000..004c733 --- /dev/null +++ b/GuiComponents/Controls/StartupView.Designer.cs @@ -0,0 +1,200 @@ +namespace GuiComponents.Controls +{ + partial class StartupView + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Component Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.button_LoadOsuCollection = new System.Windows.Forms.Button(); + this.checkBox_DoNotShowOnStartup = new System.Windows.Forms.CheckBox(); + this.label_title = new System.Windows.Forms.Label(); + this.button_LoadCollectionFromFile = new System.Windows.Forms.Button(); + this.button_DoNothing = new System.Windows.Forms.Button(); + this.label_LoadDatabaseStatus = new System.Windows.Forms.Label(); + this.button_LoadDatabase = new System.Windows.Forms.Button(); + this.groupBox_Step1 = new System.Windows.Forms.GroupBox(); + this.button_LoadDatabaseSkip = new System.Windows.Forms.Button(); + this.groupBox_Step2 = new System.Windows.Forms.GroupBox(); + this.groupBox_Step1.SuspendLayout(); + this.groupBox_Step2.SuspendLayout(); + this.SuspendLayout(); + // + // button_LoadOsuCollection + // + this.button_LoadOsuCollection.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.button_LoadOsuCollection.Font = new System.Drawing.Font("Segoe UI", 9F); + this.button_LoadOsuCollection.Location = new System.Drawing.Point(6, 19); + this.button_LoadOsuCollection.Name = "button_LoadOsuCollection"; + this.button_LoadOsuCollection.Size = new System.Drawing.Size(519, 23); + this.button_LoadOsuCollection.TabIndex = 0; + this.button_LoadOsuCollection.Text = "Load your osu! collection"; + this.button_LoadOsuCollection.UseVisualStyleBackColor = true; + this.button_LoadOsuCollection.Click += new System.EventHandler(this.button_StartupAction_Click); + // + // checkBox_DoNotShowOnStartup + // + this.checkBox_DoNotShowOnStartup.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.checkBox_DoNotShowOnStartup.AutoSize = true; + this.checkBox_DoNotShowOnStartup.Font = new System.Drawing.Font("Segoe UI", 9F); + this.checkBox_DoNotShowOnStartup.Location = new System.Drawing.Point(4, 363); + this.checkBox_DoNotShowOnStartup.Name = "checkBox_DoNotShowOnStartup"; + this.checkBox_DoNotShowOnStartup.Size = new System.Drawing.Size(191, 19); + this.checkBox_DoNotShowOnStartup.TabIndex = 1; + this.checkBox_DoNotShowOnStartup.Text = "Use selected options on startup"; + this.checkBox_DoNotShowOnStartup.UseVisualStyleBackColor = true; + // + // label_title + // + this.label_title.AutoSize = true; + this.label_title.Font = new System.Drawing.Font("Segoe UI", 12F, System.Drawing.FontStyle.Bold); + this.label_title.Location = new System.Drawing.Point(3, 12); + this.label_title.Name = "label_title"; + this.label_title.Size = new System.Drawing.Size(196, 21); + this.label_title.TabIndex = 2; + this.label_title.Text = "osu! Collection Manager"; + // + // button_LoadCollectionFromFile + // + this.button_LoadCollectionFromFile.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.button_LoadCollectionFromFile.Font = new System.Drawing.Font("Segoe UI", 9F); + this.button_LoadCollectionFromFile.Location = new System.Drawing.Point(6, 48); + this.button_LoadCollectionFromFile.Name = "button_LoadCollectionFromFile"; + this.button_LoadCollectionFromFile.Size = new System.Drawing.Size(519, 23); + this.button_LoadCollectionFromFile.TabIndex = 3; + this.button_LoadCollectionFromFile.Text = "Load osu! collection from file"; + this.button_LoadCollectionFromFile.UseVisualStyleBackColor = true; + this.button_LoadCollectionFromFile.Click += new System.EventHandler(this.button_StartupAction_Click); + // + // button_DoNothing + // + this.button_DoNothing.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.button_DoNothing.Font = new System.Drawing.Font("Segoe UI", 9F); + this.button_DoNothing.Location = new System.Drawing.Point(6, 77); + this.button_DoNothing.Name = "button_DoNothing"; + this.button_DoNothing.Size = new System.Drawing.Size(519, 23); + this.button_DoNothing.TabIndex = 4; + this.button_DoNothing.Text = "Continue without loading collections"; + this.button_DoNothing.UseVisualStyleBackColor = true; + this.button_DoNothing.Click += new System.EventHandler(this.button_StartupAction_Click); + // + // label_LoadDatabaseStatus + // + this.label_LoadDatabaseStatus.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.label_LoadDatabaseStatus.Location = new System.Drawing.Point(6, 18); + this.label_LoadDatabaseStatus.Name = "label_LoadDatabaseStatus"; + this.label_LoadDatabaseStatus.Size = new System.Drawing.Size(519, 62); + this.label_LoadDatabaseStatus.TabIndex = 6; + this.label_LoadDatabaseStatus.Text = "..."; + this.label_LoadDatabaseStatus.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // button_LoadDatabase + // + this.button_LoadDatabase.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.button_LoadDatabase.Font = new System.Drawing.Font("Segoe UI", 9F); + this.button_LoadDatabase.Location = new System.Drawing.Point(6, 83); + this.button_LoadDatabase.Name = "button_LoadDatabase"; + this.button_LoadDatabase.Size = new System.Drawing.Size(519, 23); + this.button_LoadDatabase.TabIndex = 7; + this.button_LoadDatabase.Text = "Load beatmaps from different location"; + this.button_LoadDatabase.UseVisualStyleBackColor = true; + this.button_LoadDatabase.Click += new System.EventHandler(this.button_DatabaseAction_Click); + // + // groupBox_Step1 + // + this.groupBox_Step1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupBox_Step1.Controls.Add(this.button_LoadDatabaseSkip); + this.groupBox_Step1.Controls.Add(this.button_LoadDatabase); + this.groupBox_Step1.Controls.Add(this.label_LoadDatabaseStatus); + this.groupBox_Step1.Location = new System.Drawing.Point(7, 36); + this.groupBox_Step1.Name = "groupBox_Step1"; + this.groupBox_Step1.Size = new System.Drawing.Size(531, 147); + this.groupBox_Step1.TabIndex = 8; + this.groupBox_Step1.TabStop = false; + this.groupBox_Step1.Text = "Load osu! database"; + // + // button_LoadDatabaseSkip + // + this.button_LoadDatabaseSkip.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.button_LoadDatabaseSkip.Font = new System.Drawing.Font("Segoe UI", 9F); + this.button_LoadDatabaseSkip.Location = new System.Drawing.Point(6, 113); + this.button_LoadDatabaseSkip.Name = "button_LoadDatabaseSkip"; + this.button_LoadDatabaseSkip.Size = new System.Drawing.Size(519, 23); + this.button_LoadDatabaseSkip.TabIndex = 9; + this.button_LoadDatabaseSkip.Text = "Skip"; + this.button_LoadDatabaseSkip.UseVisualStyleBackColor = true; + this.button_LoadDatabaseSkip.Click += new System.EventHandler(this.button_DatabaseAction_Click); + // + // groupBox_Step2 + // + this.groupBox_Step2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.groupBox_Step2.Controls.Add(this.button_LoadOsuCollection); + this.groupBox_Step2.Controls.Add(this.button_LoadCollectionFromFile); + this.groupBox_Step2.Controls.Add(this.button_DoNothing); + this.groupBox_Step2.Location = new System.Drawing.Point(7, 189); + this.groupBox_Step2.Name = "groupBox_Step2"; + this.groupBox_Step2.Size = new System.Drawing.Size(531, 112); + this.groupBox_Step2.TabIndex = 9; + this.groupBox_Step2.TabStop = false; + this.groupBox_Step2.Text = "Starting point"; + // + // StartupView + // + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; + this.Controls.Add(this.groupBox_Step2); + this.Controls.Add(this.groupBox_Step1); + this.Controls.Add(this.label_title); + this.Controls.Add(this.checkBox_DoNotShowOnStartup); + this.Name = "StartupView"; + this.Size = new System.Drawing.Size(541, 385); + this.groupBox_Step1.ResumeLayout(false); + this.groupBox_Step2.ResumeLayout(false); + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private System.Windows.Forms.Button button_LoadOsuCollection; + private System.Windows.Forms.CheckBox checkBox_DoNotShowOnStartup; + private System.Windows.Forms.Label label_title; + private System.Windows.Forms.Button button_LoadCollectionFromFile; + private System.Windows.Forms.Button button_DoNothing; + private System.Windows.Forms.Label label_LoadDatabaseStatus; + private System.Windows.Forms.Button button_LoadDatabase; + private System.Windows.Forms.GroupBox groupBox_Step1; + private System.Windows.Forms.GroupBox groupBox_Step2; + private System.Windows.Forms.Button button_LoadDatabaseSkip; + } +} diff --git a/GuiComponents/Controls/StartupView.cs b/GuiComponents/Controls/StartupView.cs new file mode 100644 index 0000000..567b8f9 --- /dev/null +++ b/GuiComponents/Controls/StartupView.cs @@ -0,0 +1,117 @@ +using Common; +using Gui.Misc; +using GuiComponents.Interfaces; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace GuiComponents.Controls +{ + public partial class StartupView : UserControl, IStartupView + { + public event GuiHelpers.StartupCollectionEventArgs StartupCollectionOperation; + public event GuiHelpers.StartupDatabaseEventArgs StartupDatabaseOperation; + + public string LoadDatabaseStatusText + { + get => label_LoadDatabaseStatus.Text; + set + { + if (label_LoadDatabaseStatus.InvokeRequired) + { + label_LoadDatabaseStatus.Invoke((MethodInvoker)(() => + { + label_LoadDatabaseStatus.Text = value; + })); + return; + } + + label_LoadDatabaseStatus.Text = value; + } + } + + public bool UseSelectedOptionsOnStartup + { + get => checkBox_DoNotShowOnStartup.Checked; + set + { + if (checkBox_DoNotShowOnStartup.InvokeRequired) + { + checkBox_DoNotShowOnStartup.Invoke((MethodInvoker)(() => + { + checkBox_DoNotShowOnStartup.Checked = value; + })); + return; + } + + checkBox_DoNotShowOnStartup.Checked = value; + } + } + + public bool LoadDefaultCollectionButtonEnabled + { + get => button_LoadOsuCollection.Enabled; + set + { + if (button_LoadOsuCollection.InvokeRequired) + { + button_LoadOsuCollection.Invoke((MethodInvoker)(() => + { + button_LoadOsuCollection.Enabled = value; + })); + return; + } + + button_LoadOsuCollection.Enabled = value; + } + } + + public bool ButtonsEnabled + { + get => button_DoNothing.Enabled; + set + { + foreach (var control in groupBox_Step1.Controls) + { + if (control is Button button) + button.Enabled = value; + } + + foreach (var control in groupBox_Step2.Controls) + { + if (control is Button button) + button.Enabled = value; + } + } + } + + public StartupView() + { + InitializeComponent(); + button_DoNothing.Tag = StartupCollectionAction.None; + button_LoadOsuCollection.Tag = StartupCollectionAction.LoadDefaultCollection; + button_LoadCollectionFromFile.Tag = StartupCollectionAction.LoadCollection; + + button_LoadDatabase.Tag = StartupDatabaseAction.LoadFromDifferentLocation; + button_LoadDatabaseSkip.Tag = StartupDatabaseAction.None; + } + + private void button_StartupAction_Click(object sender, EventArgs e) + { + var button = (Button)sender; + StartupCollectionOperation?.Invoke(this, (StartupCollectionAction)button.Tag); + } + + private void button_DatabaseAction_Click(object sender, EventArgs e) + { + var button = (Button)sender; + StartupDatabaseOperation?.Invoke(this, (StartupDatabaseAction)button.Tag); + } + } +} diff --git a/GuiComponents/Controls/StartupView.resx b/GuiComponents/Controls/StartupView.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/GuiComponents/Controls/StartupView.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/GuiComponents/Forms/MainFormView.cs b/GuiComponents/Forms/MainFormView.cs index b978a7a..f3bb6ca 100644 --- a/GuiComponents/Forms/MainFormView.cs +++ b/GuiComponents/Forms/MainFormView.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System; +using System.Linq; using System.Windows.Forms; using Gui.Misc; using GuiComponents.Interfaces; @@ -41,5 +42,11 @@ private void Form1_DragDrop(object sender, DragEventArgs e) var files = (string[]) e.Data.GetData(DataFormats.FileDrop); OnLoadFile?.Invoke(this, files); } + + protected override void OnShown(EventArgs e) + { + Activate(); + base.OnShown(e); + } } } \ No newline at end of file diff --git a/GuiComponents/Forms/StartupForm.Designer.cs b/GuiComponents/Forms/StartupForm.Designer.cs new file mode 100644 index 0000000..97ae188 --- /dev/null +++ b/GuiComponents/Forms/StartupForm.Designer.cs @@ -0,0 +1,65 @@ +namespace GuiComponents.Forms +{ + partial class StartupForm + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.startupView1 = new GuiComponents.Controls.StartupView(); + this.SuspendLayout(); + // + // startupView1 + // + this.startupView1.ButtonsEnabled = true; + this.startupView1.Dock = System.Windows.Forms.DockStyle.Fill; + this.startupView1.LoadDatabaseStatusText = "..."; + this.startupView1.LoadDefaultCollectionButtonEnabled = true; + this.startupView1.Location = new System.Drawing.Point(0, 0); + this.startupView1.Name = "startupView1"; + this.startupView1.Size = new System.Drawing.Size(519, 356); + this.startupView1.TabIndex = 0; + this.startupView1.UseSelectedOptionsOnStartup = false; + // + // StartupForm + // + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; + this.ClientSize = new System.Drawing.Size(519, 356); + this.Controls.Add(this.startupView1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; + this.MaximizeBox = false; + this.MaximumSize = new System.Drawing.Size(859, 872); + this.MinimumSize = new System.Drawing.Size(448, 317); + this.Name = "StartupForm"; + this.Text = "osu! Collection Manager"; + this.ResumeLayout(false); + + } + + #endregion + + private Controls.StartupView startupView1; + } +} \ No newline at end of file diff --git a/GuiComponents/Forms/StartupForm.cs b/GuiComponents/Forms/StartupForm.cs new file mode 100644 index 0000000..4b38291 --- /dev/null +++ b/GuiComponents/Forms/StartupForm.cs @@ -0,0 +1,39 @@ +using GuiComponents.Interfaces; +using System; +using System.ComponentModel; + +namespace GuiComponents.Forms +{ + public partial class StartupForm : BaseForm, IStartupForm + { + public StartupForm() + { + InitializeComponent(); + } + + protected override void OnClosing(CancelEventArgs e) + { + base.OnClosing(e); + } + + public IStartupView StartupView => startupView1; + + event EventHandler IForm.Closing + { + add + { + throw new NotImplementedException(); + } + + remove + { + throw new NotImplementedException(); + } + } + + public void ShowAndBlock() + { + this.ShowDialog(); + } + } +} diff --git a/GuiComponents/Forms/StartupForm.resx b/GuiComponents/Forms/StartupForm.resx new file mode 100644 index 0000000..1af7de1 --- /dev/null +++ b/GuiComponents/Forms/StartupForm.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file From 58ec9e5e97f835ec388aa9b2f0c8a5467b5a5550 Mon Sep 17 00:00:00 2001 From: Piotrekol <4990365+Piotrekol@users.noreply.github.com> Date: Sat, 4 Jun 2022 00:48:47 +0200 Subject: [PATCH 04/10] Misc: Adjust InnoSetup script --- InnoSetup/script.iss | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/InnoSetup/script.iss b/InnoSetup/script.iss index b67e438..3bc072b 100644 --- a/InnoSetup/script.iss +++ b/InnoSetup/script.iss @@ -51,21 +51,21 @@ Name: osdbAssociation; Description: "Associate "".osdb"" extension (Collection f Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 0,6.1 [Files] -Source: "..\App\bin\Release\net472\App.exe"; DestDir: "{app}"; Flags: ignoreversion -Source: "..\App\bin\Release\net472\downloadSources.json"; DestDir: "{app}"; Flags: ignoreversion -Source: "..\App\bin\Release\net472\CollectionManager.dll"; DestDir: "{app}"; Flags: ignoreversion -Source: "..\App\bin\Release\net472\CollectionManagerExtensionsDll.dll"; DestDir: "{app}"; Flags: ignoreversion -Source: "..\App\bin\Release\net472\Common.dll"; DestDir: "{app}"; Flags: ignoreversion -Source: "..\App\bin\Release\net472\GuiComponents.dll"; DestDir: "{app}"; Flags: ignoreversion -Source: "..\App\bin\Release\net472\MusicPlayer.dll"; DestDir: "{app}"; Flags: ignoreversion -Source: "..\App\bin\Release\net472\NAudio.dll"; DestDir: "{app}"; Flags: ignoreversion -Source: "..\App\bin\Release\net472\Newtonsoft.Json.dll"; DestDir: "{app}"; Flags: ignoreversion -Source: "..\App\bin\Release\net472\ObjectListView.dll"; DestDir: "{app}"; Flags: ignoreversion -Source: "..\App\bin\Release\net472\System.Security.Principal.Windows.dll"; DestDir: "{app}"; Flags: ignoreversion -Source: "..\App\bin\Release\net472\Microsoft.Win32.Registry.dll"; DestDir: "{app}"; Flags: ignoreversion -Source: "..\App\bin\Release\net472\System.Security.AccessControl.dll"; DestDir: "{app}"; Flags: ignoreversion -Source: "..\App\bin\Release\net472\SharpCompress.dll"; DestDir: "{app}"; Flags: ignoreversion -Source: "..\App\bin\Release\net472\CommandLine.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "..\App\bin\Release\net48\App.exe"; DestDir: "{app}"; Flags: ignoreversion +Source: "..\App\bin\Release\net48\downloadSources.json"; DestDir: "{app}"; Flags: ignoreversion +Source: "..\App\bin\Release\net48\CollectionManager.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "..\App\bin\Release\net48\CollectionManagerExtensionsDll.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "..\App\bin\Release\net48\Common.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "..\App\bin\Release\net48\GuiComponents.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "..\App\bin\Release\net48\MusicPlayer.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "..\App\bin\Release\net48\NAudio.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "..\App\bin\Release\net48\Newtonsoft.Json.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "..\App\bin\Release\net48\ObjectListView.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "..\App\bin\Release\net48\System.Security.Principal.Windows.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "..\App\bin\Release\net48\Microsoft.Win32.Registry.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "..\App\bin\Release\net48\System.Security.AccessControl.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "..\App\bin\Release\net48\SharpCompress.dll"; DestDir: "{app}"; Flags: ignoreversion +Source: "..\App\bin\Release\net48\CommandLine.dll"; DestDir: "{app}"; Flags: ignoreversion ; NOTE: Don't use "Flags: ignoreversion" on any shared system files [Icons] From eee2addb5a7400fbd9e3b556dda9b02e024462c8 Mon Sep 17 00:00:00 2001 From: Piotrekol <4990365+Piotrekol@users.noreply.github.com> Date: Sat, 4 Jun 2022 12:03:43 +0200 Subject: [PATCH 05/10] Misc: Handle user closing startup window --- App/Initalizer.cs | 4 ++-- App/Presenters/Controls/StartupPresenter.cs | 26 ++++++++++++++++++--- GuiComponents/Controls/StartupView.cs | 17 +++++--------- GuiComponents/Forms/BaseForm.cs | 4 +++- GuiComponents/Forms/StartupForm.cs | 26 +-------------------- 5 files changed, 35 insertions(+), 42 deletions(-) diff --git a/App/Initalizer.cs b/App/Initalizer.cs index 18ef268..921dc87 100644 --- a/App/Initalizer.cs +++ b/App/Initalizer.cs @@ -65,9 +65,9 @@ public async Task Run(string[] args) guiActionsHandler.SidePanelActionsHandler.OsustatsLogin(null, Settings.Default.Osustats_apiKey); StartupPresenter = new StartupPresenter(GuiComponentsProvider.Instance.GetClassImplementing(), guiActionsHandler.SidePanelActionsHandler, UserDialogs); - await StartupPresenter.Run(); + if (await StartupPresenter.Run()) + mainForm.ShowAndBlock(); - mainForm.ShowAndBlock(); Quit(); } diff --git a/App/Presenters/Controls/StartupPresenter.cs b/App/Presenters/Controls/StartupPresenter.cs index 94b8b48..33664bf 100644 --- a/App/Presenters/Controls/StartupPresenter.cs +++ b/App/Presenters/Controls/StartupPresenter.cs @@ -21,6 +21,8 @@ public class StartupPresenter private CancellationTokenSource _cancellationTokenSource; private Progress _databaseLoadProgressReporter; private Task _databaseLoadTask; + private bool _formClosedByUser; + private bool _formClosedManually; public StartupPresenter(IStartupForm view, SidePanelActionsHandler sidePanelActionsHandler, IUserDialogs userDialogs) { @@ -37,12 +39,23 @@ public StartupPresenter(IStartupForm view, SidePanelActionsHandler sidePanelActi _view.StartupView.LoadDatabaseStatusText = $"osu! location: \"{Initalizer.OsuDirectory}\"{Environment.NewLine}{report}"; }); + _view.Closing += _view_Closing; _view.StartupView.UseSelectedOptionsOnStartup = _startupSettings.UseSelectedOptionsOnStartup; _view.StartupView.StartupCollectionOperation += _view_StartupCollectionOperation; _view.StartupView.StartupDatabaseOperation += StartupView_StartupDatabaseOperation; } - public async Task Run() + private async void _view_Closing(object sender, EventArgs eventArgs) + { + if (eventArgs is not FormClosingEventArgs formEventArgs || formEventArgs.CloseReason != CloseReason.UserClosing || _formClosedManually) + return; + + _formClosedByUser = true; + _cancellationTokenSource.Cancel(); + _cancellationTokenSource.Dispose(); + } + + public async Task Run() { _databaseLoadTask = Task.Run(() => LoadDatabase(_cancellationTokenSource.Token)); if (_startupSettings.UseSelectedOptionsOnStartup) @@ -57,13 +70,12 @@ public async Task Run() await _databaseLoadTask; if (_startupSettings.UseSelectedOptionsOnStartup) { - _view.Close(); + CloseForm(); Application.UseWaitCursor = false; } _startupSettings.UseSelectedOptionsOnStartup = _view.StartupView.UseSelectedOptionsOnStartup; SaveSettings(); - switch (_startupSettings.StartupCollectionAction) { case StartupCollectionAction.None: @@ -75,6 +87,8 @@ public async Task Run() _sidePanelActionsHandler.LoadDefaultCollection(); break; } + + return !_formClosedByUser; } private async void StartupView_StartupDatabaseOperation(object sender, StartupDatabaseAction args) @@ -112,6 +126,12 @@ private async void _view_StartupCollectionOperation(object sender, StartupCollec Application.UseWaitCursor = true; await _databaseLoadTask; Application.UseWaitCursor = false; + CloseForm(); + } + + private void CloseForm() + { + _formClosedManually = true; _view.Close(); } diff --git a/GuiComponents/Controls/StartupView.cs b/GuiComponents/Controls/StartupView.cs index 567b8f9..a1632d7 100644 --- a/GuiComponents/Controls/StartupView.cs +++ b/GuiComponents/Controls/StartupView.cs @@ -77,17 +77,12 @@ public bool ButtonsEnabled get => button_DoNothing.Enabled; set { - foreach (var control in groupBox_Step1.Controls) - { - if (control is Button button) - button.Enabled = value; - } - - foreach (var control in groupBox_Step2.Controls) - { - if (control is Button button) - button.Enabled = value; - } + button_DoNothing.Enabled + = button_LoadOsuCollection.Enabled + = button_LoadCollectionFromFile.Enabled + = button_LoadDatabase.Enabled + = button_LoadDatabaseSkip.Enabled + = value; } } diff --git a/GuiComponents/Forms/BaseForm.cs b/GuiComponents/Forms/BaseForm.cs index c4cff12..9578da3 100644 --- a/GuiComponents/Forms/BaseForm.cs +++ b/GuiComponents/Forms/BaseForm.cs @@ -9,16 +9,18 @@ public class BaseForm : Form, IForm { protected BaseForm() { - FormClosing += (s, a) => Closing?.Invoke(this, EventArgs.Empty); + FormClosing += (s, e) => Closing?.Invoke(this, e); StartPosition = FormStartPosition.CenterParent; Icon = Icon.ExtractAssociatedIcon(Application.ExecutablePath); Font = new Font("Segoe UI", 9f); } + public void ShowAndBlock() { this.ShowDialog(); } public event EventHandler Closing; + public event EventHandler UserClosing; } } \ No newline at end of file diff --git a/GuiComponents/Forms/StartupForm.cs b/GuiComponents/Forms/StartupForm.cs index 4b38291..cd276e2 100644 --- a/GuiComponents/Forms/StartupForm.cs +++ b/GuiComponents/Forms/StartupForm.cs @@ -1,6 +1,5 @@ using GuiComponents.Interfaces; -using System; -using System.ComponentModel; +using System.Windows.Forms; namespace GuiComponents.Forms { @@ -11,29 +10,6 @@ public StartupForm() InitializeComponent(); } - protected override void OnClosing(CancelEventArgs e) - { - base.OnClosing(e); - } - public IStartupView StartupView => startupView1; - - event EventHandler IForm.Closing - { - add - { - throw new NotImplementedException(); - } - - remove - { - throw new NotImplementedException(); - } - } - - public void ShowAndBlock() - { - this.ShowDialog(); - } } } From 2d3e933f31ce2bb9fb7f5560d095c9bd8e70b334 Mon Sep 17 00:00:00 2001 From: Piotrekol <4990365+Piotrekol@users.noreply.github.com> Date: Sat, 4 Jun 2022 19:04:14 +0200 Subject: [PATCH 06/10] Misc: Handle starting from osdb file in startup screen --- App/Initalizer.cs | 21 ++-- App/Models/StartupSettings.cs | 2 +- App/Presenters/Controls/StartupPresenter.cs | 112 ++++++++++------- App/Program.cs | 8 +- App/Properties/launchSettings.json | 7 ++ Common/Interfaces/Controls/IStartupView.cs | 5 +- Common/StartupDatabaseAction.cs | 1 + .../Controls/StartupView.Designer.cs | 118 +++++++++++------- GuiComponents/Controls/StartupView.cs | 97 +++++++++++--- GuiComponents/Forms/BaseForm.cs | 3 +- GuiComponents/Forms/StartupForm.Designer.cs | 13 +- 11 files changed, 262 insertions(+), 125 deletions(-) create mode 100644 App/Properties/launchSettings.json diff --git a/App/Initalizer.cs b/App/Initalizer.cs index 921dc87..0ef2654 100644 --- a/App/Initalizer.cs +++ b/App/Initalizer.cs @@ -50,6 +50,13 @@ public async Task Run(string[] args) //set initial text info and update events SetTextData(infoTextModel); + + var loginForm = GuiComponentsProvider.Instance.GetClassImplementing(); + var guiActionsHandler = new GuiActionsHandler(OsuFileIo, CollectionsManager, UserDialogs, mainForm, mainPresenter, loginForm); + + if (!string.IsNullOrWhiteSpace(Settings.Default.Osustats_apiKey)) + guiActionsHandler.SidePanelActionsHandler.OsustatsLogin(null, Settings.Default.Osustats_apiKey); + if (args.Length > 0) { if (File.Exists(args[0])) @@ -58,15 +65,11 @@ public async Task Run(string[] args) } } - var loginForm = GuiComponentsProvider.Instance.GetClassImplementing(); - var guiActionsHandler = new GuiActionsHandler(OsuFileIo, CollectionsManager, UserDialogs, mainForm, mainPresenter, loginForm); - - if (!string.IsNullOrWhiteSpace(Settings.Default.Osustats_apiKey)) - guiActionsHandler.SidePanelActionsHandler.OsustatsLogin(null, Settings.Default.Osustats_apiKey); + StartupPresenter = new StartupPresenter(GuiComponentsProvider.Instance.GetClassImplementing(), guiActionsHandler.SidePanelActionsHandler, UserDialogs, CollectionsManager); + await StartupPresenter.Run(); + - StartupPresenter = new StartupPresenter(GuiComponentsProvider.Instance.GetClassImplementing(), guiActionsHandler.SidePanelActionsHandler, UserDialogs); - if (await StartupPresenter.Run()) - mainForm.ShowAndBlock(); + mainForm.ShowAndBlock(); Quit(); } @@ -88,7 +91,7 @@ private void SetTextData(IInfoTextModel model) } - private static void Quit() + public static void Quit() { Settings.Default.Save(); diff --git a/App/Models/StartupSettings.cs b/App/Models/StartupSettings.cs index 43aaf14..917c63c 100644 --- a/App/Models/StartupSettings.cs +++ b/App/Models/StartupSettings.cs @@ -6,7 +6,7 @@ public class StartupSettings { public StartupDatabaseAction StartupDatabaseAction { get; set; } public StartupCollectionAction StartupCollectionAction { get; set; } - public bool UseSelectedOptionsOnStartup { get; set; } + public bool AutoLoadMode { get; set; } public string OsuLocation { get; set; } } } \ No newline at end of file diff --git a/App/Presenters/Controls/StartupPresenter.cs b/App/Presenters/Controls/StartupPresenter.cs index 33664bf..f17862c 100644 --- a/App/Presenters/Controls/StartupPresenter.cs +++ b/App/Presenters/Controls/StartupPresenter.cs @@ -5,6 +5,7 @@ using System.Windows.Forms; using App.Models; using App.Properties; +using CollectionManager.Modules.CollectionsManager; using CollectionManagerExtensionsDll.Utils; using Common; using GuiComponents.Interfaces; @@ -14,68 +15,79 @@ namespace App.Presenters.Controls { public class StartupPresenter { - private readonly IStartupForm _view; + private readonly IStartupForm _form; + private readonly IStartupView _view; private readonly SidePanelActionsHandler _sidePanelActionsHandler; private readonly IUserDialogs _userDialogs; + private readonly CollectionsManagerWithCounts _collectionsManager; private StartupSettings _startupSettings; private CancellationTokenSource _cancellationTokenSource; private Progress _databaseLoadProgressReporter; private Task _databaseLoadTask; - private bool _formClosedByUser; private bool _formClosedManually; - public StartupPresenter(IStartupForm view, SidePanelActionsHandler sidePanelActionsHandler, IUserDialogs userDialogs) + public StartupPresenter(IStartupForm view, SidePanelActionsHandler sidePanelActionsHandler, IUserDialogs userDialogs, CollectionsManagerWithCounts collectionsManager) { - _view = view; + _form = view; + _view = view.StartupView; _sidePanelActionsHandler = sidePanelActionsHandler; _userDialogs = userDialogs; + _collectionsManager = collectionsManager; _startupSettings = JsonConvert.DeserializeObject(Settings.Default.StartupSettings); _cancellationTokenSource = new CancellationTokenSource(); _databaseLoadProgressReporter = new Progress(report => { if (string.IsNullOrEmpty(Initalizer.OsuDirectory)) - _view.StartupView.LoadDatabaseStatusText = report; + _view.LoadDatabaseStatusText = report; else - _view.StartupView.LoadDatabaseStatusText = $"osu! location: \"{Initalizer.OsuDirectory}\"{Environment.NewLine}{report}"; + _view.LoadDatabaseStatusText = $"osu! location: \"{Initalizer.OsuDirectory}\"{Environment.NewLine}{report}"; }); - _view.Closing += _view_Closing; - _view.StartupView.UseSelectedOptionsOnStartup = _startupSettings.UseSelectedOptionsOnStartup; - _view.StartupView.StartupCollectionOperation += _view_StartupCollectionOperation; - _view.StartupView.StartupDatabaseOperation += StartupView_StartupDatabaseOperation; + _view.UseSelectedOptionsOnStartup = _startupSettings.AutoLoadMode; + _form.Closing += _view_Closing; + _view.StartupCollectionOperation += _view_StartupCollectionOperation; + _view.StartupDatabaseOperation += _view_StartupDatabaseOperation; } - private async void _view_Closing(object sender, EventArgs eventArgs) + public async Task Run() { - if (eventArgs is not FormClosingEventArgs formEventArgs || formEventArgs.CloseReason != CloseReason.UserClosing || _formClosedManually) + if (_startupSettings.AutoLoadMode && _startupSettings.StartupDatabaseAction == StartupDatabaseAction.Skip) + { + DoCollectionAction(); return; + } - _formClosedByUser = true; - _cancellationTokenSource.Cancel(); - _cancellationTokenSource.Dispose(); - } + var loadedCollectionFromFile = _collectionsManager.CollectionsCount != 0; + Application.UseWaitCursor = loadedCollectionFromFile || _startupSettings.AutoLoadMode; + _view.UseSelectedOptionsOnStartupEnabled = !loadedCollectionFromFile; + _view.CollectionButtonsEnabled = !(loadedCollectionFromFile || _startupSettings.AutoLoadMode); + _view.DatabaseButtonsEnabled = true; + _view.CollectionStatusText = loadedCollectionFromFile + ? $"Going to load {_collectionsManager.CollectionsCount} collections with {_collectionsManager.BeatmapsInCollectionsCount} beatmaps" + : string.Empty; - public async Task Run() - { - _databaseLoadTask = Task.Run(() => LoadDatabase(_cancellationTokenSource.Token)); - if (_startupSettings.UseSelectedOptionsOnStartup) + _databaseLoadTask = Task.Run(() => { - _view.StartupView.ButtonsEnabled = false; - Application.UseWaitCursor = true; - _view.Show(); - } + LoadDatabase(_cancellationTokenSource.Token); + Application.UseWaitCursor = false; + _view.CollectionButtonsEnabled = true; + }); + if (_startupSettings.AutoLoadMode) + _form.Show(); else - _view.ShowAndBlock(); + _form.ShowAndBlock(); await _databaseLoadTask; - if (_startupSettings.UseSelectedOptionsOnStartup) - { - CloseForm(); - Application.UseWaitCursor = false; - } + _startupSettings.AutoLoadMode = _view.UseSelectedOptionsOnStartup; + if (!loadedCollectionFromFile) + SaveSettings(); + + DoCollectionAction(); + _form.Close(); + } - _startupSettings.UseSelectedOptionsOnStartup = _view.StartupView.UseSelectedOptionsOnStartup; - SaveSettings(); + private void DoCollectionAction() + { switch (_startupSettings.StartupCollectionAction) { case StartupCollectionAction.None: @@ -87,11 +99,9 @@ public async Task Run() _sidePanelActionsHandler.LoadDefaultCollection(); break; } - - return !_formClosedByUser; } - private async void StartupView_StartupDatabaseOperation(object sender, StartupDatabaseAction args) + private async void _view_StartupDatabaseOperation(object sender, StartupDatabaseAction args) { _startupSettings.StartupDatabaseAction = args; _cancellationTokenSource.Cancel(); @@ -100,14 +110,15 @@ private async void StartupView_StartupDatabaseOperation(object sender, StartupDa await _databaseLoadTask; switch (args) { - case StartupDatabaseAction.None: + case StartupDatabaseAction.Skip: Initalizer.OsuFileIo.OsuDatabase.LoadedMaps.UnloadBeatmaps(); Initalizer.OsuFileIo.ScoresDatabase.Clear(); Initalizer.OsuDirectory = null; - _view.StartupView.LoadDefaultCollectionButtonEnabled = false; + GC.Collect(); ((IProgress)_databaseLoadProgressReporter).Report("osu! database unloaded"); break; case StartupDatabaseAction.LoadFromDifferentLocation: + _view.LoadDefaultCollectionButtonEnabled = true; var osuDirectory = Initalizer.OsuFileIo.OsuPathResolver.GetManualOsuDir(_userDialogs.SelectDirectory); if (!string.IsNullOrEmpty(osuDirectory)) { @@ -115,6 +126,8 @@ private async void StartupView_StartupDatabaseOperation(object sender, StartupDa _databaseLoadTask = Task.Run(() => LoadDatabase(_cancellationTokenSource.Token)); } + break; + case StartupDatabaseAction.None: break; } } @@ -122,17 +135,23 @@ private async void StartupView_StartupDatabaseOperation(object sender, StartupDa private async void _view_StartupCollectionOperation(object sender, StartupCollectionAction args) { _startupSettings.StartupCollectionAction = args; - _view.StartupView.ButtonsEnabled = false; + _view.CollectionButtonsEnabled = _view.DatabaseButtonsEnabled = false; Application.UseWaitCursor = true; await _databaseLoadTask; Application.UseWaitCursor = false; - CloseForm(); + + _formClosedManually = true; + _form.Close(); } - private void CloseForm() + private void _view_Closing(object sender, EventArgs eventArgs) { - _formClosedManually = true; - _view.Close(); + if (eventArgs is not FormClosingEventArgs formEventArgs || formEventArgs.CloseReason != CloseReason.UserClosing || _formClosedManually) + return; + + _cancellationTokenSource.Cancel(); + _cancellationTokenSource.Dispose(); + Initalizer.Quit(); } private void LoadDatabase(CancellationToken cancellationToken) @@ -144,7 +163,7 @@ private void LoadDatabase(CancellationToken cancellationToken) if (string.IsNullOrEmpty(osuDirectory)) { - _view.StartupView.LoadDatabaseStatusText = "osu! could not be found. Select osu! location manually"; + _view.LoadDatabaseStatusText = "osu! could not be found. Select osu! location manually"; return; } @@ -155,19 +174,20 @@ private void LoadDatabase(CancellationToken cancellationToken) try { osuFileIo.ScoresLoader.ReadDb(Path.Combine(osuDirectory, @"scores.db"), cancellationToken); - _view.StartupView.LoadDatabaseStatusText += $"{Environment.NewLine}Loaded {osuFileIo.ScoresDatabase.Scores.Count} scores"; + _view.LoadDatabaseStatusText += $"{Environment.NewLine}Loaded {osuFileIo.ScoresDatabase.Scores.Count} scores"; } catch (Exception) { - _view.StartupView.LoadDatabaseStatusText += $"{Environment.NewLine}Could not load scores."; + _view.LoadDatabaseStatusText += $"{Environment.NewLine}Could not load scores"; } - _view.StartupView.LoadDefaultCollectionButtonEnabled = true; + _view.LoadDefaultCollectionButtonEnabled = true; BeatmapUtils.OsuSongsDirectory = Initalizer.OsuFileIo.OsuSettings.CustomBeatmapDirectoryLocation; } private void SaveSettings() { + Settings.Default.StartupSettings = JsonConvert.SerializeObject(_startupSettings); Settings.Default.Save(); } diff --git a/App/Program.cs b/App/Program.cs index 807cd0d..9cb6218 100644 --- a/App/Program.cs +++ b/App/Program.cs @@ -26,8 +26,12 @@ static int Main(string[] args) if (exArgs.ExceptionObject is Exception exception) HandleException(exception); }; - Application.ThreadException += (_, exArgs) => HandleException(exArgs.Exception); - TaskScheduler.UnobservedTaskException += (_, exArgs) => HandleException(exArgs.Exception); + Application.ThreadException += (_, exArgs) + => + HandleException(exArgs.Exception); + TaskScheduler.UnobservedTaskException += (_, exArgs) + => + HandleException(exArgs.Exception); if (args.Length > 0 && !File.Exists(args[0])) { diff --git a/App/Properties/launchSettings.json b/App/Properties/launchSettings.json new file mode 100644 index 0000000..45eed2b --- /dev/null +++ b/App/Properties/launchSettings.json @@ -0,0 +1,7 @@ +{ + "profiles": { + "App": { + "commandName": "Project" + } + } +} \ No newline at end of file diff --git a/Common/Interfaces/Controls/IStartupView.cs b/Common/Interfaces/Controls/IStartupView.cs index d351a25..bb36129 100644 --- a/Common/Interfaces/Controls/IStartupView.cs +++ b/Common/Interfaces/Controls/IStartupView.cs @@ -8,8 +8,11 @@ public interface IStartupView event GuiHelpers.StartupDatabaseEventArgs StartupDatabaseOperation; string LoadDatabaseStatusText { get; set; } + string CollectionStatusText { get; set; } bool UseSelectedOptionsOnStartup { get; set; } - bool ButtonsEnabled { get; set; } + bool UseSelectedOptionsOnStartupEnabled { get; set; } + bool CollectionButtonsEnabled { get; set; } + bool DatabaseButtonsEnabled { get; set; } bool LoadDefaultCollectionButtonEnabled { get; set; } } } \ No newline at end of file diff --git a/Common/StartupDatabaseAction.cs b/Common/StartupDatabaseAction.cs index e3665c2..115d48f 100644 --- a/Common/StartupDatabaseAction.cs +++ b/Common/StartupDatabaseAction.cs @@ -3,6 +3,7 @@ public enum StartupDatabaseAction { None, + Skip, LoadFromDifferentLocation } } \ No newline at end of file diff --git a/GuiComponents/Controls/StartupView.Designer.cs b/GuiComponents/Controls/StartupView.Designer.cs index 004c733..73bc550 100644 --- a/GuiComponents/Controls/StartupView.Designer.cs +++ b/GuiComponents/Controls/StartupView.Designer.cs @@ -36,21 +36,25 @@ private void InitializeComponent() this.label_LoadDatabaseStatus = new System.Windows.Forms.Label(); this.button_LoadDatabase = new System.Windows.Forms.Button(); this.groupBox_Step1 = new System.Windows.Forms.GroupBox(); + this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel(); this.button_LoadDatabaseSkip = new System.Windows.Forms.Button(); this.groupBox_Step2 = new System.Windows.Forms.GroupBox(); + this.label_OpenedCollection = new System.Windows.Forms.Label(); + this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); this.groupBox_Step1.SuspendLayout(); + this.flowLayoutPanel2.SuspendLayout(); this.groupBox_Step2.SuspendLayout(); + this.flowLayoutPanel1.SuspendLayout(); this.SuspendLayout(); // // button_LoadOsuCollection // - this.button_LoadOsuCollection.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); + this.button_LoadOsuCollection.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); this.button_LoadOsuCollection.Font = new System.Drawing.Font("Segoe UI", 9F); - this.button_LoadOsuCollection.Location = new System.Drawing.Point(6, 19); + this.button_LoadOsuCollection.Location = new System.Drawing.Point(3, 37); this.button_LoadOsuCollection.Name = "button_LoadOsuCollection"; - this.button_LoadOsuCollection.Size = new System.Drawing.Size(519, 23); - this.button_LoadOsuCollection.TabIndex = 0; + this.button_LoadOsuCollection.Size = new System.Drawing.Size(495, 23); + this.button_LoadOsuCollection.TabIndex = 2; this.button_LoadOsuCollection.Text = "Load your osu! collection"; this.button_LoadOsuCollection.UseVisualStyleBackColor = true; this.button_LoadOsuCollection.Click += new System.EventHandler(this.button_StartupAction_Click); @@ -60,10 +64,10 @@ private void InitializeComponent() this.checkBox_DoNotShowOnStartup.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.checkBox_DoNotShowOnStartup.AutoSize = true; this.checkBox_DoNotShowOnStartup.Font = new System.Drawing.Font("Segoe UI", 9F); - this.checkBox_DoNotShowOnStartup.Location = new System.Drawing.Point(4, 363); + this.checkBox_DoNotShowOnStartup.Location = new System.Drawing.Point(4, 396); this.checkBox_DoNotShowOnStartup.Name = "checkBox_DoNotShowOnStartup"; this.checkBox_DoNotShowOnStartup.Size = new System.Drawing.Size(191, 19); - this.checkBox_DoNotShowOnStartup.TabIndex = 1; + this.checkBox_DoNotShowOnStartup.TabIndex = 5; this.checkBox_DoNotShowOnStartup.Text = "Use selected options on startup"; this.checkBox_DoNotShowOnStartup.UseVisualStyleBackColor = true; // @@ -79,50 +83,46 @@ private void InitializeComponent() // // button_LoadCollectionFromFile // - this.button_LoadCollectionFromFile.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); + this.button_LoadCollectionFromFile.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); this.button_LoadCollectionFromFile.Font = new System.Drawing.Font("Segoe UI", 9F); - this.button_LoadCollectionFromFile.Location = new System.Drawing.Point(6, 48); + this.button_LoadCollectionFromFile.Location = new System.Drawing.Point(3, 66); this.button_LoadCollectionFromFile.Name = "button_LoadCollectionFromFile"; - this.button_LoadCollectionFromFile.Size = new System.Drawing.Size(519, 23); - this.button_LoadCollectionFromFile.TabIndex = 3; + this.button_LoadCollectionFromFile.Size = new System.Drawing.Size(495, 23); + this.button_LoadCollectionFromFile.TabIndex = 4; this.button_LoadCollectionFromFile.Text = "Load osu! collection from file"; this.button_LoadCollectionFromFile.UseVisualStyleBackColor = true; this.button_LoadCollectionFromFile.Click += new System.EventHandler(this.button_StartupAction_Click); // // button_DoNothing // - this.button_DoNothing.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); + this.button_DoNothing.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); this.button_DoNothing.Font = new System.Drawing.Font("Segoe UI", 9F); - this.button_DoNothing.Location = new System.Drawing.Point(6, 77); + this.button_DoNothing.Location = new System.Drawing.Point(3, 95); this.button_DoNothing.Name = "button_DoNothing"; - this.button_DoNothing.Size = new System.Drawing.Size(519, 23); - this.button_DoNothing.TabIndex = 4; - this.button_DoNothing.Text = "Continue without loading collections"; + this.button_DoNothing.Size = new System.Drawing.Size(495, 23); + this.button_DoNothing.TabIndex = 3; + this.button_DoNothing.Text = "Continue without loading any more collections"; this.button_DoNothing.UseVisualStyleBackColor = true; this.button_DoNothing.Click += new System.EventHandler(this.button_StartupAction_Click); // // label_LoadDatabaseStatus // - this.label_LoadDatabaseStatus.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.label_LoadDatabaseStatus.Location = new System.Drawing.Point(6, 18); + this.label_LoadDatabaseStatus.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); + this.label_LoadDatabaseStatus.Location = new System.Drawing.Point(3, 0); this.label_LoadDatabaseStatus.Name = "label_LoadDatabaseStatus"; - this.label_LoadDatabaseStatus.Size = new System.Drawing.Size(519, 62); + this.label_LoadDatabaseStatus.Size = new System.Drawing.Size(511, 49); this.label_LoadDatabaseStatus.TabIndex = 6; - this.label_LoadDatabaseStatus.Text = "..."; + this.label_LoadDatabaseStatus.Text = "AAA\r\nBBB\r\nCCC"; this.label_LoadDatabaseStatus.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; // // button_LoadDatabase // - this.button_LoadDatabase.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); + this.button_LoadDatabase.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); this.button_LoadDatabase.Font = new System.Drawing.Font("Segoe UI", 9F); - this.button_LoadDatabase.Location = new System.Drawing.Point(6, 83); + this.button_LoadDatabase.Location = new System.Drawing.Point(3, 52); this.button_LoadDatabase.Name = "button_LoadDatabase"; - this.button_LoadDatabase.Size = new System.Drawing.Size(519, 23); - this.button_LoadDatabase.TabIndex = 7; + this.button_LoadDatabase.Size = new System.Drawing.Size(495, 23); + this.button_LoadDatabase.TabIndex = 0; this.button_LoadDatabase.Text = "Load beatmaps from different location"; this.button_LoadDatabase.UseVisualStyleBackColor = true; this.button_LoadDatabase.Click += new System.EventHandler(this.button_DatabaseAction_Click); @@ -131,25 +131,33 @@ private void InitializeComponent() // this.groupBox_Step1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.groupBox_Step1.Controls.Add(this.button_LoadDatabaseSkip); - this.groupBox_Step1.Controls.Add(this.button_LoadDatabase); - this.groupBox_Step1.Controls.Add(this.label_LoadDatabaseStatus); + this.groupBox_Step1.Controls.Add(this.flowLayoutPanel2); this.groupBox_Step1.Location = new System.Drawing.Point(7, 36); this.groupBox_Step1.Name = "groupBox_Step1"; - this.groupBox_Step1.Size = new System.Drawing.Size(531, 147); + this.groupBox_Step1.Size = new System.Drawing.Size(525, 135); this.groupBox_Step1.TabIndex = 8; this.groupBox_Step1.TabStop = false; this.groupBox_Step1.Text = "Load osu! database"; // + // flowLayoutPanel2 + // + this.flowLayoutPanel2.Controls.Add(this.label_LoadDatabaseStatus); + this.flowLayoutPanel2.Controls.Add(this.button_LoadDatabase); + this.flowLayoutPanel2.Controls.Add(this.button_LoadDatabaseSkip); + this.flowLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill; + this.flowLayoutPanel2.Location = new System.Drawing.Point(3, 16); + this.flowLayoutPanel2.Name = "flowLayoutPanel2"; + this.flowLayoutPanel2.Size = new System.Drawing.Size(519, 116); + this.flowLayoutPanel2.TabIndex = 10; + // // button_LoadDatabaseSkip // - this.button_LoadDatabaseSkip.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); + this.button_LoadDatabaseSkip.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); this.button_LoadDatabaseSkip.Font = new System.Drawing.Font("Segoe UI", 9F); - this.button_LoadDatabaseSkip.Location = new System.Drawing.Point(6, 113); + this.button_LoadDatabaseSkip.Location = new System.Drawing.Point(3, 81); this.button_LoadDatabaseSkip.Name = "button_LoadDatabaseSkip"; - this.button_LoadDatabaseSkip.Size = new System.Drawing.Size(519, 23); - this.button_LoadDatabaseSkip.TabIndex = 9; + this.button_LoadDatabaseSkip.Size = new System.Drawing.Size(495, 23); + this.button_LoadDatabaseSkip.TabIndex = 1; this.button_LoadDatabaseSkip.Text = "Skip"; this.button_LoadDatabaseSkip.UseVisualStyleBackColor = true; this.button_LoadDatabaseSkip.Click += new System.EventHandler(this.button_DatabaseAction_Click); @@ -158,16 +166,35 @@ private void InitializeComponent() // this.groupBox_Step2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.groupBox_Step2.Controls.Add(this.button_LoadOsuCollection); - this.groupBox_Step2.Controls.Add(this.button_LoadCollectionFromFile); - this.groupBox_Step2.Controls.Add(this.button_DoNothing); - this.groupBox_Step2.Location = new System.Drawing.Point(7, 189); + this.groupBox_Step2.Controls.Add(this.flowLayoutPanel1); + this.groupBox_Step2.Location = new System.Drawing.Point(7, 177); this.groupBox_Step2.Name = "groupBox_Step2"; - this.groupBox_Step2.Size = new System.Drawing.Size(531, 112); + this.groupBox_Step2.Size = new System.Drawing.Size(525, 168); this.groupBox_Step2.TabIndex = 9; this.groupBox_Step2.TabStop = false; this.groupBox_Step2.Text = "Starting point"; // + // label_OpenedCollection + // + this.label_OpenedCollection.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right))); + this.label_OpenedCollection.Location = new System.Drawing.Point(3, 0); + this.label_OpenedCollection.Name = "label_OpenedCollection"; + this.label_OpenedCollection.Size = new System.Drawing.Size(511, 34); + this.label_OpenedCollection.TabIndex = 7; + this.label_OpenedCollection.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; + // + // flowLayoutPanel1 + // + this.flowLayoutPanel1.Controls.Add(this.label_OpenedCollection); + this.flowLayoutPanel1.Controls.Add(this.button_LoadOsuCollection); + this.flowLayoutPanel1.Controls.Add(this.button_LoadCollectionFromFile); + this.flowLayoutPanel1.Controls.Add(this.button_DoNothing); + this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.flowLayoutPanel1.Location = new System.Drawing.Point(3, 16); + this.flowLayoutPanel1.Name = "flowLayoutPanel1"; + this.flowLayoutPanel1.Size = new System.Drawing.Size(519, 149); + this.flowLayoutPanel1.TabIndex = 10; + // // StartupView // this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; @@ -176,9 +203,11 @@ private void InitializeComponent() this.Controls.Add(this.label_title); this.Controls.Add(this.checkBox_DoNotShowOnStartup); this.Name = "StartupView"; - this.Size = new System.Drawing.Size(541, 385); + this.Size = new System.Drawing.Size(535, 418); this.groupBox_Step1.ResumeLayout(false); + this.flowLayoutPanel2.ResumeLayout(false); this.groupBox_Step2.ResumeLayout(false); + this.flowLayoutPanel1.ResumeLayout(false); this.ResumeLayout(false); this.PerformLayout(); @@ -196,5 +225,8 @@ private void InitializeComponent() private System.Windows.Forms.GroupBox groupBox_Step1; private System.Windows.Forms.GroupBox groupBox_Step2; private System.Windows.Forms.Button button_LoadDatabaseSkip; + private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2; + private System.Windows.Forms.Label label_OpenedCollection; + private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; } } diff --git a/GuiComponents/Controls/StartupView.cs b/GuiComponents/Controls/StartupView.cs index a1632d7..a7d45da 100644 --- a/GuiComponents/Controls/StartupView.cs +++ b/GuiComponents/Controls/StartupView.cs @@ -2,13 +2,6 @@ using Gui.Misc; using GuiComponents.Interfaces; using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Windows.Forms; namespace GuiComponents.Controls @@ -72,29 +65,103 @@ public bool LoadDefaultCollectionButtonEnabled } } - public bool ButtonsEnabled + + public string CollectionStatusText + { + get => label_OpenedCollection.Text; + set + { + if (label_OpenedCollection.InvokeRequired) + { + label_OpenedCollection.Invoke((MethodInvoker)(() => + { + label_OpenedCollection.Visible = !string.IsNullOrEmpty(value); + label_OpenedCollection.Text = value; + })); + return; + } + + label_OpenedCollection.Visible = !string.IsNullOrEmpty(value); + label_OpenedCollection.Text = value; + } + } + + public bool CollectionButtonsEnabled + { + get => button_LoadCollectionFromFile.Enabled; + set + { + if (button_LoadCollectionFromFile.InvokeRequired) + { + button_LoadCollectionFromFile.Invoke((MethodInvoker)(() => + { + button_DoNothing.Enabled + = button_LoadCollectionFromFile.Enabled + = value; + + button_LoadOsuCollection.Enabled = LoadDefaultCollectionButtonEnabled && value; + })); + return; + } + + button_DoNothing.Enabled + = button_LoadCollectionFromFile.Enabled + = value; + + button_LoadOsuCollection.Enabled = LoadDefaultCollectionButtonEnabled && value; + } + } + + public bool DatabaseButtonsEnabled { - get => button_DoNothing.Enabled; + get => button_LoadDatabase.Enabled; set { - button_DoNothing.Enabled - = button_LoadOsuCollection.Enabled - = button_LoadCollectionFromFile.Enabled - = button_LoadDatabase.Enabled - = button_LoadDatabaseSkip.Enabled + if (button_LoadDatabase.InvokeRequired) + { + button_LoadDatabase.Invoke((MethodInvoker)(() => + { + button_LoadDatabase.Enabled + = button_LoadDatabaseSkip.Enabled + = value; + })); + return; + } + + button_LoadDatabase.Enabled + = button_LoadDatabaseSkip.Enabled = value; } } + public bool UseSelectedOptionsOnStartupEnabled + { + get => checkBox_DoNotShowOnStartup.Enabled; + set + { + if (checkBox_DoNotShowOnStartup.InvokeRequired) + { + checkBox_DoNotShowOnStartup.Invoke((MethodInvoker)(() => + { + checkBox_DoNotShowOnStartup.Enabled = value; + })); + return; + } + + checkBox_DoNotShowOnStartup.Enabled = value; + } + } + public StartupView() { InitializeComponent(); + flowLayoutPanel1.SetFlowBreak(button_DoNothing, true); button_DoNothing.Tag = StartupCollectionAction.None; button_LoadOsuCollection.Tag = StartupCollectionAction.LoadDefaultCollection; button_LoadCollectionFromFile.Tag = StartupCollectionAction.LoadCollection; button_LoadDatabase.Tag = StartupDatabaseAction.LoadFromDifferentLocation; - button_LoadDatabaseSkip.Tag = StartupDatabaseAction.None; + button_LoadDatabaseSkip.Tag = StartupDatabaseAction.Skip; } private void button_StartupAction_Click(object sender, EventArgs e) diff --git a/GuiComponents/Forms/BaseForm.cs b/GuiComponents/Forms/BaseForm.cs index 9578da3..96cbea1 100644 --- a/GuiComponents/Forms/BaseForm.cs +++ b/GuiComponents/Forms/BaseForm.cs @@ -17,10 +17,9 @@ protected BaseForm() public void ShowAndBlock() { - this.ShowDialog(); + ShowDialog(); } public event EventHandler Closing; - public event EventHandler UserClosing; } } \ No newline at end of file diff --git a/GuiComponents/Forms/StartupForm.Designer.cs b/GuiComponents/Forms/StartupForm.Designer.cs index 97ae188..fa31fab 100644 --- a/GuiComponents/Forms/StartupForm.Designer.cs +++ b/GuiComponents/Forms/StartupForm.Designer.cs @@ -33,25 +33,26 @@ private void InitializeComponent() // // startupView1 // - this.startupView1.ButtonsEnabled = true; - this.startupView1.Dock = System.Windows.Forms.DockStyle.Fill; + this.startupView1.CollectionButtonsEnabled = true; + this.startupView1.CollectionStatusText = ""; + this.startupView1.DatabaseButtonsEnabled = true; this.startupView1.LoadDatabaseStatusText = "..."; this.startupView1.LoadDefaultCollectionButtonEnabled = true; this.startupView1.Location = new System.Drawing.Point(0, 0); this.startupView1.Name = "startupView1"; - this.startupView1.Size = new System.Drawing.Size(519, 356); + this.startupView1.Size = new System.Drawing.Size(519, 379); this.startupView1.TabIndex = 0; this.startupView1.UseSelectedOptionsOnStartup = false; // // StartupForm // this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; - this.ClientSize = new System.Drawing.Size(519, 356); + this.ClientSize = new System.Drawing.Size(519, 379); this.Controls.Add(this.startupView1); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle; this.MaximizeBox = false; - this.MaximumSize = new System.Drawing.Size(859, 872); - this.MinimumSize = new System.Drawing.Size(448, 317); + this.MaximumSize = new System.Drawing.Size(535, 418); + this.MinimumSize = new System.Drawing.Size(535, 418); this.Name = "StartupForm"; this.Text = "osu! Collection Manager"; this.ResumeLayout(false); From c40774fb3e0f9e19d4ae32a7fd574f7428435a2b Mon Sep 17 00:00:00 2001 From: Piotrekol <4990365+Piotrekol@users.noreply.github.com> Date: Sat, 4 Jun 2022 19:11:45 +0200 Subject: [PATCH 07/10] Oops: CM killing itself on startup with collection file --- App/Presenters/Controls/StartupPresenter.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/App/Presenters/Controls/StartupPresenter.cs b/App/Presenters/Controls/StartupPresenter.cs index f17862c..8608f2c 100644 --- a/App/Presenters/Controls/StartupPresenter.cs +++ b/App/Presenters/Controls/StartupPresenter.cs @@ -83,7 +83,7 @@ public async Task Run() SaveSettings(); DoCollectionAction(); - _form.Close(); + CloseForm(); } private void DoCollectionAction() @@ -139,7 +139,11 @@ private async void _view_StartupCollectionOperation(object sender, StartupCollec Application.UseWaitCursor = true; await _databaseLoadTask; Application.UseWaitCursor = false; + CloseForm(); + } + private void CloseForm() + { _formClosedManually = true; _form.Close(); } From 482437e17937b28dd1218cbed4f993559f577ab5 Mon Sep 17 00:00:00 2001 From: Piotrekol <4990365+Piotrekol@users.noreply.github.com> Date: Sun, 5 Jun 2022 19:51:24 +0200 Subject: [PATCH 08/10] Fix: Load osu! collection button staying enabled after aborting db load & slight renaming --- App/Presenters/Controls/StartupPresenter.cs | 15 ++++++++------- App/SidePanelActionsHandler.cs | 2 +- Common/Interfaces/Controls/IStartupView.cs | 2 +- Common/StartupCollectionAction.cs | 4 ++-- Common/StartupDatabaseAction.cs | 2 +- GuiComponents/Controls/StartupView.cs | 12 ++++++------ GuiComponents/Forms/StartupForm.Designer.cs | 2 +- 7 files changed, 20 insertions(+), 19 deletions(-) diff --git a/App/Presenters/Controls/StartupPresenter.cs b/App/Presenters/Controls/StartupPresenter.cs index 8608f2c..7148fb1 100644 --- a/App/Presenters/Controls/StartupPresenter.cs +++ b/App/Presenters/Controls/StartupPresenter.cs @@ -51,7 +51,7 @@ public StartupPresenter(IStartupForm view, SidePanelActionsHandler sidePanelActi public async Task Run() { - if (_startupSettings.AutoLoadMode && _startupSettings.StartupDatabaseAction == StartupDatabaseAction.Skip) + if (_startupSettings.AutoLoadMode && _startupSettings.StartupDatabaseAction == StartupDatabaseAction.Unload) { DoCollectionAction(); return; @@ -92,11 +92,11 @@ private void DoCollectionAction() { case StartupCollectionAction.None: break; - case StartupCollectionAction.LoadCollection: + case StartupCollectionAction.LoadCollectionFromFile: _sidePanelActionsHandler.LoadCollectionFile(); break; - case StartupCollectionAction.LoadDefaultCollection: - _sidePanelActionsHandler.LoadDefaultCollection(); + case StartupCollectionAction.LoadOsuCollection: + _sidePanelActionsHandler.LoadOsuCollection(); break; } } @@ -110,18 +110,19 @@ private async void _view_StartupDatabaseOperation(object sender, StartupDatabase await _databaseLoadTask; switch (args) { - case StartupDatabaseAction.Skip: + case StartupDatabaseAction.Unload: Initalizer.OsuFileIo.OsuDatabase.LoadedMaps.UnloadBeatmaps(); Initalizer.OsuFileIo.ScoresDatabase.Clear(); Initalizer.OsuDirectory = null; + _view.LoadOsuCollectionButtonEnabled = false; GC.Collect(); ((IProgress)_databaseLoadProgressReporter).Report("osu! database unloaded"); break; case StartupDatabaseAction.LoadFromDifferentLocation: - _view.LoadDefaultCollectionButtonEnabled = true; var osuDirectory = Initalizer.OsuFileIo.OsuPathResolver.GetManualOsuDir(_userDialogs.SelectDirectory); if (!string.IsNullOrEmpty(osuDirectory)) { + _view.LoadOsuCollectionButtonEnabled = true; _startupSettings.OsuLocation = osuDirectory; _databaseLoadTask = Task.Run(() => LoadDatabase(_cancellationTokenSource.Token)); } @@ -185,7 +186,7 @@ private void LoadDatabase(CancellationToken cancellationToken) _view.LoadDatabaseStatusText += $"{Environment.NewLine}Could not load scores"; } - _view.LoadDefaultCollectionButtonEnabled = true; + _view.LoadOsuCollectionButtonEnabled = true; BeatmapUtils.OsuSongsDirectory = Initalizer.OsuFileIo.OsuSettings.CustomBeatmapDirectoryLocation; } diff --git a/App/SidePanelActionsHandler.cs b/App/SidePanelActionsHandler.cs index 98b9282..8ffe0d3 100644 --- a/App/SidePanelActionsHandler.cs +++ b/App/SidePanelActionsHandler.cs @@ -95,7 +95,7 @@ private void BindMainFormActions() _mainForm.Closing += FormOnClosing; } - public void LoadDefaultCollection() => LoadDefaultCollection(null, null); + public void LoadOsuCollection() => LoadDefaultCollection(null, null); public void LoadCollectionFile() => LoadCollectionFile(null); diff --git a/Common/Interfaces/Controls/IStartupView.cs b/Common/Interfaces/Controls/IStartupView.cs index bb36129..875e2f4 100644 --- a/Common/Interfaces/Controls/IStartupView.cs +++ b/Common/Interfaces/Controls/IStartupView.cs @@ -13,6 +13,6 @@ public interface IStartupView bool UseSelectedOptionsOnStartupEnabled { get; set; } bool CollectionButtonsEnabled { get; set; } bool DatabaseButtonsEnabled { get; set; } - bool LoadDefaultCollectionButtonEnabled { get; set; } + bool LoadOsuCollectionButtonEnabled { get; set; } } } \ No newline at end of file diff --git a/Common/StartupCollectionAction.cs b/Common/StartupCollectionAction.cs index f2a1683..0d3b79f 100644 --- a/Common/StartupCollectionAction.cs +++ b/Common/StartupCollectionAction.cs @@ -3,7 +3,7 @@ public enum StartupCollectionAction { None, - LoadCollection, - LoadDefaultCollection, + LoadCollectionFromFile, + LoadOsuCollection, } } \ No newline at end of file diff --git a/Common/StartupDatabaseAction.cs b/Common/StartupDatabaseAction.cs index 115d48f..1724394 100644 --- a/Common/StartupDatabaseAction.cs +++ b/Common/StartupDatabaseAction.cs @@ -3,7 +3,7 @@ public enum StartupDatabaseAction { None, - Skip, + Unload, LoadFromDifferentLocation } } \ No newline at end of file diff --git a/GuiComponents/Controls/StartupView.cs b/GuiComponents/Controls/StartupView.cs index a7d45da..f516274 100644 --- a/GuiComponents/Controls/StartupView.cs +++ b/GuiComponents/Controls/StartupView.cs @@ -47,7 +47,7 @@ public bool UseSelectedOptionsOnStartup } } - public bool LoadDefaultCollectionButtonEnabled + public bool LoadOsuCollectionButtonEnabled { get => button_LoadOsuCollection.Enabled; set @@ -99,7 +99,7 @@ public bool CollectionButtonsEnabled = button_LoadCollectionFromFile.Enabled = value; - button_LoadOsuCollection.Enabled = LoadDefaultCollectionButtonEnabled && value; + button_LoadOsuCollection.Enabled = LoadOsuCollectionButtonEnabled && value; })); return; } @@ -108,7 +108,7 @@ public bool CollectionButtonsEnabled = button_LoadCollectionFromFile.Enabled = value; - button_LoadOsuCollection.Enabled = LoadDefaultCollectionButtonEnabled && value; + button_LoadOsuCollection.Enabled = LoadOsuCollectionButtonEnabled && value; } } @@ -157,11 +157,11 @@ public StartupView() InitializeComponent(); flowLayoutPanel1.SetFlowBreak(button_DoNothing, true); button_DoNothing.Tag = StartupCollectionAction.None; - button_LoadOsuCollection.Tag = StartupCollectionAction.LoadDefaultCollection; - button_LoadCollectionFromFile.Tag = StartupCollectionAction.LoadCollection; + button_LoadOsuCollection.Tag = StartupCollectionAction.LoadOsuCollection; + button_LoadCollectionFromFile.Tag = StartupCollectionAction.LoadCollectionFromFile; button_LoadDatabase.Tag = StartupDatabaseAction.LoadFromDifferentLocation; - button_LoadDatabaseSkip.Tag = StartupDatabaseAction.Skip; + button_LoadDatabaseSkip.Tag = StartupDatabaseAction.Unload; } private void button_StartupAction_Click(object sender, EventArgs e) diff --git a/GuiComponents/Forms/StartupForm.Designer.cs b/GuiComponents/Forms/StartupForm.Designer.cs index fa31fab..4123dcf 100644 --- a/GuiComponents/Forms/StartupForm.Designer.cs +++ b/GuiComponents/Forms/StartupForm.Designer.cs @@ -37,7 +37,7 @@ private void InitializeComponent() this.startupView1.CollectionStatusText = ""; this.startupView1.DatabaseButtonsEnabled = true; this.startupView1.LoadDatabaseStatusText = "..."; - this.startupView1.LoadDefaultCollectionButtonEnabled = true; + this.startupView1.LoadOsuCollectionButtonEnabled = true; this.startupView1.Location = new System.Drawing.Point(0, 0); this.startupView1.Name = "startupView1"; this.startupView1.Size = new System.Drawing.Size(519, 379); From 2a4788ced5c7ffd0e84a0b43c4baa4114fc0609b Mon Sep 17 00:00:00 2001 From: Piotrekol <4990365+Piotrekol@users.noreply.github.com> Date: Tue, 7 Jun 2022 21:08:11 +0200 Subject: [PATCH 09/10] Misc: Cancel scores db load early --- .../Modules/FileIO/OsuScoresDb/ScoresDatabaseIO.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CollectionManagerDll/Modules/FileIO/OsuScoresDb/ScoresDatabaseIO.cs b/CollectionManagerDll/Modules/FileIO/OsuScoresDb/ScoresDatabaseIO.cs index 4b16c8a..c7a50cf 100644 --- a/CollectionManagerDll/Modules/FileIO/OsuScoresDb/ScoresDatabaseIO.cs +++ b/CollectionManagerDll/Modules/FileIO/OsuScoresDb/ScoresDatabaseIO.cs @@ -23,6 +23,9 @@ public ScoresDatabaseIo(IScoreDataStorer scoreDataStorer) public virtual void ReadDb(string osuScoresDbPath, CancellationToken cancellationToken) { + if (cancellationToken.IsCancellationRequested) + return; + if (FileExists(osuScoresDbPath)) { _fileStream = new FileStream(osuScoresDbPath, FileMode.Open, FileAccess.Read); From c973b84a68b3a1f154ba430cc3c88cbe998eea94 Mon Sep 17 00:00:00 2001 From: Piotrekol <4990365+Piotrekol@users.noreply.github.com> Date: Tue, 7 Jun 2022 21:13:06 +0200 Subject: [PATCH 10/10] Misc: Handle detection of stale osu! locations --- App/Presenters/Controls/StartupPresenter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/App/Presenters/Controls/StartupPresenter.cs b/App/Presenters/Controls/StartupPresenter.cs index 7148fb1..20a9a4c 100644 --- a/App/Presenters/Controls/StartupPresenter.cs +++ b/App/Presenters/Controls/StartupPresenter.cs @@ -166,7 +166,7 @@ private void LoadDatabase(CancellationToken cancellationToken) ? osuFileIo.OsuPathResolver.GetOsuDir() : _startupSettings.OsuLocation; - if (string.IsNullOrEmpty(osuDirectory)) + if (string.IsNullOrEmpty(osuDirectory) || !Directory.Exists(osuDirectory)) { _view.LoadDatabaseStatusText = "osu! could not be found. Select osu! location manually"; return;