From d6a2fd5a46ff7b751248f0e8d393cabcc5df684f Mon Sep 17 00:00:00 2001 From: Chris Kaczor Date: Sun, 16 Apr 2023 12:57:17 -0400 Subject: [PATCH] More UI updates --- Application/App.xaml.cs | 215 +++-- Application/Data/Database.cs | 33 +- Application/Data/RealmObservableCollection.cs | 35 +- Application/Entities.cs | 77 +- Application/FeedCenter.csproj | 2 +- Application/FeedChooserWindow.xaml | 63 +- Application/FeedChooserWindow.xaml.cs | 65 +- Application/FeedErrorWindow.xaml | 99 ++- Application/FeedErrorWindow.xaml.cs | 226 ++--- Application/FeedParsers/AtomParser.cs | 207 +++-- Application/FeedParsers/FeedParseError.cs | 11 +- Application/FeedParsers/FeedParseException.cs | 17 +- Application/FeedParsers/FeedParserBase.cs | 303 ++++--- Application/FeedParsers/RdfParser.cs | 165 ++-- Application/FeedParsers/RssParser.cs | 177 ++-- Application/Feeds/Category.cs | 117 ++- Application/Feeds/DataErrorDictionary.cs | 55 +- Application/Feeds/Feed.cs | 753 ++++++++-------- Application/Feeds/FeedItem.cs | 153 ++-- Application/MainWindow/CategoryList.cs | 147 ++-- Application/MainWindow/CommandLine.cs | 47 +- Application/MainWindow/DragDrop.cs | 85 +- Application/MainWindow/FeedCreation.cs | 170 ++-- Application/MainWindow/FeedList.cs | 235 +++-- Application/MainWindow/FeedReading.cs | 349 ++++---- Application/MainWindow/Header.cs | 41 +- Application/MainWindow/MainWindow.xaml.cs | 823 +++++++++--------- Application/MainWindow/Timer.cs | 103 ++- Application/MainWindow/Toolbar.cs | 429 +++++---- Application/MainWindow/UpdateHandler.cs | 55 +- Application/MainWindow/WindowHandler.cs | 269 +++--- Application/NotificationIcon.cs | 129 ++- Application/Options/BulkFeedWindow.xaml.cs | 165 ++-- Application/Options/CategoryWindow.xaml | 36 +- Application/Options/CategoryWindow.xaml.cs | 75 +- Application/Options/FeedWindow.xaml | 208 ++--- Application/Options/FeedWindow.xaml.cs | 118 +-- Application/Options/FeedsOptionsPanel.xaml.cs | 751 ++++++++-------- Application/Options/Options.cs | 15 +- Application/Options/OptionsWindow.xaml.cs | 115 ++- Application/Options/Setting.cs | 21 +- Application/Options/Spacing.cs | 95 +- Application/Options/UserAgentItem.cs | 57 +- Application/Properties/Resources.Designer.cs | 12 +- Application/Properties/Resources.resx | 12 +- Application/SettingsStore.cs | 85 +- Application/SystemConfiguration.cs | 43 +- 47 files changed, 3695 insertions(+), 3768 deletions(-) diff --git a/Application/App.xaml.cs b/Application/App.xaml.cs index 99f6a6b..ce588b1 100644 --- a/Application/App.xaml.cs +++ b/Application/App.xaml.cs @@ -8,121 +8,120 @@ using System.IO; using System.Linq; using System.Windows.Threading; -namespace FeedCenter +namespace FeedCenter; + +public partial class App { - public partial class App + // ReSharper disable ConvertPropertyToExpressionBody + private static bool IsDebugBuild { - // ReSharper disable ConvertPropertyToExpressionBody - private static bool IsDebugBuild + get { - get - { #if DEBUG - return true; + return true; #else return false; #endif - } - } - // ReSharper restore ConvertPropertyToExpressionBody - - public static string Name => FeedCenter.Properties.Resources.ApplicationName; - - [STAThread] - public static void Main() - { - // Create and initialize the app object - var app = new App(); - app.InitializeComponent(); - - // Create an single instance handle to see if we are already running - var isolationHandle = SingleInstance.GetSingleInstanceHandleAsync(Name).Result; - - // If there is another copy then pass it the command line and exit - if (isolationHandle == null) - return; - - // Use the handle over the lifetime of the application - using (isolationHandle) - { - // Set the path - LegacyDatabase.DatabasePath = SystemConfiguration.DataDirectory; - LegacyDatabase.DatabaseFile = Path.Combine(SystemConfiguration.DataDirectory, - Settings.Default.DatabaseFile_Legacy); - - Database.DatabasePath = SystemConfiguration.DataDirectory; - Database.DatabaseFile = Path.Combine(SystemConfiguration.DataDirectory, Settings.Default.DatabaseFile); - - // Get the generic provider - var genericProvider = - (GenericSettingsProvider) Settings.Default.Providers[nameof(GenericSettingsProvider)]; - - if (genericProvider == null) - return; - - // Set the callbacks into the provider - genericProvider.OpenDataStore = SettingsStore.OpenDataStore; - genericProvider.GetSettingValue = SettingsStore.GetSettingValue; - genericProvider.SetSettingValue = SettingsStore.SetSettingValue; - - Log.Logger = new LoggerConfiguration() - .Enrich.WithThreadId() - .WriteTo.Console() - .WriteTo.File( - Path.Join(SystemConfiguration.UserSettingsPath, - $"{FeedCenter.Properties.Resources.ApplicationName}_.txt"), - rollingInterval: RollingInterval.Day, retainedFileCountLimit: 5, - outputTemplate: "[{Timestamp:u} - {ThreadId} - {Level:u3}] {Message:lj}{NewLine}{Exception}") - .CreateLogger(); - - Log.Logger.Information("---"); - Log.Logger.Information("Application started"); - - Log.Logger.Information("Command line arguments:"); - - foreach (var arg in Environment.GetCommandLineArgs() - .Select((value, index) => (Value: value, Index: index))) - Log.Logger.Information("\tArg {0}: {1}", arg.Index, arg.Value); - - Current.DispatcherUnhandledException += HandleCurrentDispatcherUnhandledException; - AppDomain.CurrentDomain.UnhandledException += HandleCurrentDomainUnhandledException; - - // Check if we need to upgrade settings from a previous version - if (Settings.Default.FirstRun) - { - Settings.Default.Upgrade(); - Settings.Default.FirstRun = false; - Settings.Default.Save(); - } - - // Create the main window before the splash otherwise WPF gets messed up - var mainWindow = new MainWindow(); - - // Show the splash window - var splashWindow = new SplashWindow(); - splashWindow.ShowDialog(); - - // Set whether we should auto-start (if not debugging) - if (!IsDebugBuild) - Current.SetStartWithWindows(Settings.Default.StartWithWindows); - - // Initialize the window - mainWindow.Initialize(); - - // Run the app - app.Run(mainWindow); - } - } - - private static void HandleCurrentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e) - { - Log.Logger.Error((Exception) e.ExceptionObject, "Exception"); - } - - private static void HandleCurrentDispatcherUnhandledException(object sender, - DispatcherUnhandledExceptionEventArgs e) - { - Log.Logger.Error(e.Exception, "Exception"); } } + // ReSharper restore ConvertPropertyToExpressionBody + + public static string Name => FeedCenter.Properties.Resources.ApplicationName; + + [STAThread] + public static void Main() + { + // Create and initialize the app object + var app = new App(); + app.InitializeComponent(); + + // Create an single instance handle to see if we are already running + var isolationHandle = SingleInstance.GetSingleInstanceHandleAsync(Name).Result; + + // If there is another copy then pass it the command line and exit + if (isolationHandle == null) + return; + + // Use the handle over the lifetime of the application + using (isolationHandle) + { + // Set the path + LegacyDatabase.DatabasePath = SystemConfiguration.DataDirectory; + LegacyDatabase.DatabaseFile = Path.Combine(SystemConfiguration.DataDirectory, + Settings.Default.DatabaseFile_Legacy); + + Database.DatabasePath = SystemConfiguration.DataDirectory; + Database.DatabaseFile = Path.Combine(SystemConfiguration.DataDirectory, Settings.Default.DatabaseFile); + + // Get the generic provider + var genericProvider = + (GenericSettingsProvider) Settings.Default.Providers[nameof(GenericSettingsProvider)]; + + if (genericProvider == null) + return; + + // Set the callbacks into the provider + genericProvider.OpenDataStore = SettingsStore.OpenDataStore; + genericProvider.GetSettingValue = SettingsStore.GetSettingValue; + genericProvider.SetSettingValue = SettingsStore.SetSettingValue; + + Log.Logger = new LoggerConfiguration() + .Enrich.WithThreadId() + .WriteTo.Console() + .WriteTo.File( + Path.Join(SystemConfiguration.UserSettingsPath, + $"{FeedCenter.Properties.Resources.ApplicationName}_.txt"), + rollingInterval: RollingInterval.Day, retainedFileCountLimit: 5, + outputTemplate: "[{Timestamp:u} - {ThreadId} - {Level:u3}] {Message:lj}{NewLine}{Exception}") + .CreateLogger(); + + Log.Logger.Information("---"); + Log.Logger.Information("Application started"); + + Log.Logger.Information("Command line arguments:"); + + foreach (var arg in Environment.GetCommandLineArgs() + .Select((value, index) => (Value: value, Index: index))) + Log.Logger.Information("\tArg {0}: {1}", arg.Index, arg.Value); + + Current.DispatcherUnhandledException += HandleCurrentDispatcherUnhandledException; + AppDomain.CurrentDomain.UnhandledException += HandleCurrentDomainUnhandledException; + + // Check if we need to upgrade settings from a previous version + if (Settings.Default.FirstRun) + { + Settings.Default.Upgrade(); + Settings.Default.FirstRun = false; + Settings.Default.Save(); + } + + // Create the main window before the splash otherwise WPF gets messed up + var mainWindow = new MainWindow(); + + // Show the splash window + var splashWindow = new SplashWindow(); + splashWindow.ShowDialog(); + + // Set whether we should auto-start (if not debugging) + if (!IsDebugBuild) + Current.SetStartWithWindows(Settings.Default.StartWithWindows); + + // Initialize the window + mainWindow.Initialize(); + + // Run the app + app.Run(mainWindow); + } + } + + private static void HandleCurrentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e) + { + Log.Logger.Error((Exception) e.ExceptionObject, "Exception"); + } + + private static void HandleCurrentDispatcherUnhandledException(object sender, + DispatcherUnhandledExceptionEventArgs e) + { + Log.Logger.Error(e.Exception, "Exception"); + } } \ No newline at end of file diff --git a/Application/Data/Database.cs b/Application/Data/Database.cs index f7917ae..0503592 100644 --- a/Application/Data/Database.cs +++ b/Application/Data/Database.cs @@ -1,25 +1,24 @@ using System.IO; -namespace FeedCenter.Data +namespace FeedCenter.Data; + +public static class Database { - public static class Database + public static string DatabaseFile { get; set; } + public static string DatabasePath { get; set; } + + public static FeedCenterEntities Entities { get; set; } + + public static bool Exists => File.Exists(DatabaseFile); + + public static bool Loaded { get; set; } + + public static void Load() { - public static string DatabaseFile { get; set; } - public static string DatabasePath { get; set; } + if (Loaded) return; - public static FeedCenterEntities Entities { get; set; } + Entities = new FeedCenterEntities(); - public static bool Exists => File.Exists(DatabaseFile); - - public static bool Loaded { get; set; } - - public static void Load() - { - if (Loaded) return; - - Entities = new FeedCenterEntities(); - - Loaded = true; - } + Loaded = true; } } \ No newline at end of file diff --git a/Application/Data/RealmObservableCollection.cs b/Application/Data/RealmObservableCollection.cs index 5ccd46a..27eafcc 100644 --- a/Application/Data/RealmObservableCollection.cs +++ b/Application/Data/RealmObservableCollection.cs @@ -2,28 +2,27 @@ using System.Collections.ObjectModel; using System.Collections.Specialized; -namespace FeedCenter.Data +namespace FeedCenter.Data; + +public class RealmObservableCollection : ObservableCollection where T : IRealmObject { - public class RealmObservableCollection : ObservableCollection where T : IRealmObject + private readonly Realm _realm; + + public RealmObservableCollection(Realm realm) : base(realm.All()) { - private readonly Realm _realm; + _realm = realm; + } - public RealmObservableCollection(Realm realm) : base(realm.All()) - { - _realm = realm; - } + protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e) + { + if (e.OldItems != null) + foreach (T item in e.OldItems) + _realm.Remove(item); - protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e) - { - if (e.OldItems != null) - foreach (T item in e.OldItems) - _realm.Remove(item); + if (e.NewItems != null) + foreach (T item in e.NewItems) + _realm.Add(item); - if (e.NewItems != null) - foreach (T item in e.NewItems) - _realm.Add(item); - - base.OnCollectionChanged(e); - } + base.OnCollectionChanged(e); } } \ No newline at end of file diff --git a/Application/Entities.cs b/Application/Entities.cs index 4153af6..4e61206 100644 --- a/Application/Entities.cs +++ b/Application/Entities.cs @@ -4,50 +4,49 @@ using Realms; using System; using System.Linq; -namespace FeedCenter +namespace FeedCenter; + +public class FeedCenterEntities { - public class FeedCenterEntities + public Realm RealmInstance { get; } + + public RealmObservableCollection Categories { get; } + public RealmObservableCollection Feeds { get; private set; } + public RealmObservableCollection Settings { get; private set; } + + public FeedCenterEntities() { - public Realm RealmInstance { get; } + var realmConfiguration = new RealmConfiguration($"{Database.DatabaseFile}"); - public RealmObservableCollection Categories { get; } - public RealmObservableCollection Feeds { get; private set; } - public RealmObservableCollection Settings { get; private set; } + RealmInstance = Realm.GetInstance(realmConfiguration); - public FeedCenterEntities() + Settings = new RealmObservableCollection(RealmInstance); + Feeds = new RealmObservableCollection(RealmInstance); + Categories = new RealmObservableCollection(RealmInstance); + + if (!Categories.Any()) { - var realmConfiguration = new RealmConfiguration($"{Database.DatabaseFile}"); - - RealmInstance = Realm.GetInstance(realmConfiguration); - - Settings = new RealmObservableCollection(RealmInstance); - Feeds = new RealmObservableCollection(RealmInstance); - Categories = new RealmObservableCollection(RealmInstance); - - if (!Categories.Any()) - { - RealmInstance.Write(() => Categories.Add(Category.CreateDefault())); - } - } - - public void Refresh() - { - RealmInstance.Refresh(); - } - - public void SaveChanges(Action action) - { - RealmInstance.Write(action); - } - - public Transaction BeginTransaction() - { - return RealmInstance.BeginWrite(); - } - - public Category DefaultCategory - { - get { return Categories.First(c => c.IsDefault); } + RealmInstance.Write(() => Categories.Add(Category.CreateDefault())); } } + + public void Refresh() + { + RealmInstance.Refresh(); + } + + public void SaveChanges(Action action) + { + RealmInstance.Write(action); + } + + public Transaction BeginTransaction() + { + return RealmInstance.BeginWrite(); + } + + public Category DefaultCategory + { + get { return Categories.First(c => c.IsDefault); } + } } \ No newline at end of file diff --git a/Application/FeedCenter.csproj b/Application/FeedCenter.csproj index 5214a5f..905fe3f 100644 --- a/Application/FeedCenter.csproj +++ b/Application/FeedCenter.csproj @@ -132,7 +132,7 @@ - + diff --git a/Application/FeedChooserWindow.xaml b/Application/FeedChooserWindow.xaml index 283c049..84a0b98 100644 --- a/Application/FeedChooserWindow.xaml +++ b/Application/FeedChooserWindow.xaml @@ -14,12 +14,24 @@ FocusManager.FocusedElement="{Binding ElementName=FeedDataGrid}" controlBox:ControlBox.HasMaximizeButton="False" controlBox:ControlBox.HasMinimizeButton="False"> - + + + + + + + + + + + - - - - -