diff --git a/Application/Data/LegacyDatabase.cs b/Application/Data/LegacyDatabase.cs index d48b2d9..55dd41b 100644 --- a/Application/Data/LegacyDatabase.cs +++ b/Application/Data/LegacyDatabase.cs @@ -193,7 +193,7 @@ public static class LegacyDatabase foreach (var feed in feeds) { - feed.Category = categories.FirstOrDefault(c => c.Id == feed.CategoryId); + feed.CategoryId = categories.First(c => c.Id == feed.CategoryId).Id; } foreach (var feedItem in feedItems) diff --git a/Application/FeedErrorWindow.xaml.cs b/Application/FeedErrorWindow.xaml.cs index 1414bf7..0d412e3 100644 --- a/Application/FeedErrorWindow.xaml.cs +++ b/Application/FeedErrorWindow.xaml.cs @@ -43,7 +43,7 @@ namespace FeedCenter { var feed = (Feed) e.Item; - e.Accepted = (feed.LastReadResult != FeedReadResult.Success); + e.Accepted = feed.LastReadResult != FeedReadResult.Success; } private void HandleEditFeedButtonClick(object sender, RoutedEventArgs e) @@ -79,11 +79,11 @@ namespace FeedCenter private void SetFeedButtonStates() { - EditFeedButton.IsEnabled = (FeedDataGrid.SelectedItem != null); - DeleteFeedButton.IsEnabled = (FeedDataGrid.SelectedItem != null); - RefreshCurrent.IsEnabled = (FeedDataGrid.SelectedItem != null); - OpenPage.IsEnabled = (FeedDataGrid.SelectedItem != null); - OpenFeed.IsEnabled = (FeedDataGrid.SelectedItem != null); + EditFeedButton.IsEnabled = FeedDataGrid.SelectedItem != null; + DeleteFeedButton.IsEnabled = FeedDataGrid.SelectedItem != null; + RefreshCurrent.IsEnabled = FeedDataGrid.SelectedItem != null; + OpenPage.IsEnabled = FeedDataGrid.SelectedItem != null; + OpenFeed.IsEnabled = FeedDataGrid.SelectedItem != null; } private void HandleOpenPageButtonClick(object sender, RoutedEventArgs e) diff --git a/Application/FeedParsers/RssParser.cs b/Application/FeedParsers/RssParser.cs index 2f4beda..64181c4 100644 --- a/Application/FeedParsers/RssParser.cs +++ b/Application/FeedParsers/RssParser.cs @@ -100,7 +100,7 @@ namespace FeedCenter.FeedParsers if (childNode.Attributes != null) { var permaLinkNode = childNode.Attributes.GetNamedItem("isPermaLink"); - permaLink = (permaLinkNode == null || permaLinkNode.Value == "true"); + permaLink = permaLinkNode == null || permaLinkNode.Value == "true"; } if (permaLink && Uri.IsWellFormedUriString(feedItem.Guid, UriKind.Absolute)) diff --git a/Application/Feeds/Feed.cs b/Application/Feeds/Feed.cs index 83e4ec7..6410e9a 100644 --- a/Application/Feeds/Feed.cs +++ b/Application/Feeds/Feed.cs @@ -93,8 +93,6 @@ namespace FeedCenter set => MultipleOpenActionRaw = value.ToString(); } - public Category Category { get; set; } - [UsedImplicitly] public IList Items { get; } diff --git a/Application/MainWindow/CategoryList.cs b/Application/MainWindow/CategoryList.cs index 1509726..44fd1ba 100644 --- a/Application/MainWindow/CategoryList.cs +++ b/Application/MainWindow/CategoryList.cs @@ -79,7 +79,7 @@ namespace FeedCenter _currentCategory = category; // Get the current feed list to match the category - _feedList = _currentCategory == null ? _database.Feeds : _database.Feeds.Where(feed => feed.Category.Id == _currentCategory.Id); + _feedList = _currentCategory == null ? _database.Feeds : _database.Feeds.Where(feed => feed.CategoryId == _currentCategory.Id); // Refresh the feed index _feedIndex = -1; diff --git a/Application/MainWindow/FeedCreation.cs b/Application/MainWindow/FeedCreation.cs index 48a5222..740b7ca 100644 --- a/Application/MainWindow/FeedCreation.cs +++ b/Application/MainWindow/FeedCreation.cs @@ -22,7 +22,7 @@ namespace FeedCenter // Create and configure the new feed var feed = Feed.Create(); feed.Source = feedUrl; - feed.Category = _database.DefaultCategory; + feed.CategoryId = _database.DefaultCategory.Id; // Try to detect the feed type var feedTypeResult = feed.DetectFeedType(); diff --git a/Application/MainWindow/MainWindow.xaml.cs b/Application/MainWindow/MainWindow.xaml.cs index dcdb3f9..fdd6676 100644 --- a/Application/MainWindow/MainWindow.xaml.cs +++ b/Application/MainWindow/MainWindow.xaml.cs @@ -53,7 +53,7 @@ namespace FeedCenter LoadWindowSettings(); // Set the foreground color to something that can be seen - LinkTextList.Foreground = (System.Drawing.SystemColors.Desktop.GetBrightness() < 0.5) + LinkTextList.Foreground = System.Drawing.SystemColors.Desktop.GetBrightness() < 0.5 ? Brushes.White : Brushes.Black; HeaderLabel.Foreground = LinkTextList.Foreground; @@ -153,7 +153,7 @@ namespace FeedCenter _feedList = _currentCategory == null ? _database.Feeds.ToList() - : _database.Feeds.Where(feed => feed.Category.Id == _currentCategory.Id).ToList(); + : _database.Feeds.Where(feed => feed.CategoryId == _currentCategory.Id).ToList(); UpdateToolbarButtonState(); @@ -178,9 +178,9 @@ namespace FeedCenter _feedIndex = newIndex; // Re-get the current feed - _currentFeed = (_feedIndex == -1 + _currentFeed = _feedIndex == -1 ? null - : _feedList.OrderBy(feed => feed.Name).AsEnumerable().ElementAt(_feedIndex)); + : _feedList.OrderBy(feed => feed.Name).AsEnumerable().ElementAt(_feedIndex); } #endregion @@ -215,7 +215,7 @@ namespace FeedCenter // Get the current feed list to match the category _feedList = _currentCategory == null ? _database.Feeds - : _database.Feeds.Where(feed => feed.Category.Id == _currentCategory.Id); + : _database.Feeds.Where(feed => feed.CategoryId == _currentCategory.Id); UpdateToolbarButtonState(); @@ -257,7 +257,7 @@ namespace FeedCenter var found = false; // Remember our starting position - var startIndex = (_feedIndex == -1 ? 0 : _feedIndex); + var startIndex = _feedIndex == -1 ? 0 : _feedIndex; // Increment the index and adjust if we've gone around the end _feedIndex = (_feedIndex + 1) % feedCount; @@ -319,7 +319,7 @@ namespace FeedCenter var found = false; // Remember our starting position - var startIndex = (_feedIndex == -1 ? 0 : _feedIndex); + var startIndex = _feedIndex == -1 ? 0 : _feedIndex; // Decrement the feed index _feedIndex--; @@ -392,7 +392,7 @@ namespace FeedCenter } // Set the header to the feed title - FeedLabel.Text = (_currentFeed.Name.Length > 0 ? _currentFeed.Name : _currentFeed.Title); + FeedLabel.Text = _currentFeed.Name.Length > 0 ? _currentFeed.Name : _currentFeed.Title; FeedButton.Visibility = _feedList.Count() > 1 ? Visibility.Visible : Visibility.Hidden; // Clear the current list diff --git a/Application/MainWindow/Toolbar.cs b/Application/MainWindow/Toolbar.cs index 231b188..b4e55b0 100644 --- a/Application/MainWindow/Toolbar.cs +++ b/Application/MainWindow/Toolbar.cs @@ -161,7 +161,7 @@ namespace FeedCenter private void HandleDeleteCurrentFeedMenuItemClick(object sender, RoutedEventArgs e) { // Confirm this delete since it is for real - if (MessageBox.Show(this, Properties.Resources.ConfirmDelete, string.Empty, MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) == MessageBoxResult.No) + if (MessageBox.Show(this, Properties.Resources.ConfirmDeleteFeed, string.Empty, MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) == MessageBoxResult.No) return; // Get the current feed diff --git a/Application/Options/AboutOptionsPanel.xaml.cs b/Application/Options/AboutOptionsPanel.xaml.cs index fbea6bb..4d27702 100644 --- a/Application/Options/AboutOptionsPanel.xaml.cs +++ b/Application/Options/AboutOptionsPanel.xaml.cs @@ -1,15 +1,18 @@ -using ChrisKaczor.ApplicationUpdate; -using System.Reflection; +using System.Reflection; +using System.Windows; +using ChrisKaczor.ApplicationUpdate; namespace FeedCenter.Options; public partial class AboutOptionsPanel { - public AboutOptionsPanel() + public AboutOptionsPanel(Window parentWindow) : base(parentWindow) { InitializeComponent(); } + public override string CategoryName => Properties.Resources.optionCategoryAbout; + public override void LoadPanel() { base.LoadPanel(); @@ -21,6 +24,4 @@ public partial class AboutOptionsPanel CompanyLabel.Text = ((AssemblyCompanyAttribute) Assembly.GetEntryAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false)[0]).Company; } - - public override string CategoryName => Properties.Resources.optionCategoryAbout; } \ No newline at end of file diff --git a/Application/Options/DisplayOptionsPanel.xaml.cs b/Application/Options/DisplayOptionsPanel.xaml.cs index ceb8388..a0a6982 100644 --- a/Application/Options/DisplayOptionsPanel.xaml.cs +++ b/Application/Options/DisplayOptionsPanel.xaml.cs @@ -1,16 +1,19 @@ -using FeedCenter.Properties; -using System.Linq; +using System.Linq; +using System.Windows; using System.Windows.Controls; +using FeedCenter.Properties; namespace FeedCenter.Options; public partial class DisplayOptionsPanel { - public DisplayOptionsPanel() + public DisplayOptionsPanel(Window parentWindow) : base(parentWindow) { InitializeComponent(); } + public override string CategoryName => Properties.Resources.optionCategoryDisplay; + public override void LoadPanel() { base.LoadPanel(); @@ -23,8 +26,6 @@ public partial class DisplayOptionsPanel MarkLoaded(); } - public override string CategoryName => Properties.Resources.optionCategoryDisplay; - private void LockWindowCheckBox_Click(object sender, System.Windows.RoutedEventArgs e) { if (!HasLoaded) return; diff --git a/Application/Options/FeedsOptionsPanel.xaml b/Application/Options/FeedsOptionsPanel.xaml index 7a50de6..f070f43 100644 --- a/Application/Options/FeedsOptionsPanel.xaml +++ b/Application/Options/FeedsOptionsPanel.xaml @@ -30,7 +30,7 @@ IsReadOnly="True" HeadersVisibility="Column" Background="{x:Null}" - PreviewMouseLeftButtonDown="HandleFeedListPreviewMouseLeftButtonDown"> + PreviewMouseLeftButtonDown="HandleFeedListPreviewMouseLeftButtonDown" SelectionChanged="FeedListBox_SelectionChanged"> Properties.Resources.optionCategoryFeeds; + public override void LoadPanel() { base.LoadPanel(); @@ -31,13 +35,11 @@ namespace FeedCenter.Options CategoryListBox.SelectedIndex = 0; } - public override string CategoryName => Properties.Resources.optionCategoryFeeds; - private void SetFeedButtonStates() { AddFeedButton.IsEnabled = true; - EditFeedButton.IsEnabled = FeedListBox.SelectedItem != null; - DeleteFeedButton.IsEnabled = FeedListBox.SelectedItem != null; + EditFeedButton.IsEnabled = FeedListBox.SelectedItems.Count == 1; + DeleteFeedButton.IsEnabled = FeedListBox.SelectedItems.Count > 0; } private void AddFeed() @@ -46,13 +48,13 @@ namespace FeedCenter.Options var category = (Category) CategoryListBox.SelectedItem; - feed.Category = category; + feed.CategoryId = category.Id; var feedWindow = new FeedWindow(); var result = feedWindow.Display(feed, Window.GetWindow(this)); - if (!result.HasValue || !result.Value) + if (!result.HasValue || !result.Value) return; Database.Entities.Feeds.Add(feed); @@ -74,11 +76,17 @@ namespace FeedCenter.Options feedWindow.Display(feed, Window.GetWindow(this)); } - private void DeleteSelectedFeed() + private void DeleteSelectedFeeds() { - var feed = (Feed) FeedListBox.SelectedItem; + if (MessageBox.Show(ParentWindow, Properties.Resources.ConfirmDeleteFeeds, Properties.Resources.ConfirmDeleteTitle, MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) == MessageBoxResult.No) + return; - Database.Entities.Feeds.Remove(feed); + var selectedItems = new Feed[FeedListBox.SelectedItems.Count]; + + FeedListBox.SelectedItems.CopyTo(selectedItems, 0); + + foreach (var feed in selectedItems) + Database.Entities.SaveChanges(() => Database.Entities.Feeds.Remove(feed)); SetFeedButtonStates(); } @@ -95,7 +103,7 @@ namespace FeedCenter.Options private void HandleDeleteFeedButtonClick(object sender, RoutedEventArgs e) { - DeleteSelectedFeed(); + DeleteSelectedFeeds(); } private void HandleImportButtonClick(object sender, RoutedEventArgs e) @@ -181,7 +189,7 @@ namespace FeedCenter.Options while (xmlReader.NodeType != XmlNodeType.EndElement) { var feed = Feed.Create(); - feed.Category = Database.Entities.Categories.First(c => c.IsDefault); + feed.CategoryId = Database.Entities.Categories.First(c => c.IsDefault).Id; while (xmlReader.MoveToNextAttribute()) { @@ -233,8 +241,10 @@ namespace FeedCenter.Options var selectedId = ((Category) CategoryListBox.SelectedItem).Id; - EditCategoryButton.IsEnabled = CategoryListBox.SelectedItem != null && selectedId != Database.Entities.DefaultCategory.Id; - DeleteCategoryButton.IsEnabled = CategoryListBox.SelectedItem != null && selectedId != Database.Entities.DefaultCategory.Id; + EditCategoryButton.IsEnabled = CategoryListBox.SelectedItem != null && + selectedId != Database.Entities.DefaultCategory.Id; + DeleteCategoryButton.IsEnabled = CategoryListBox.SelectedItem != null && + selectedId != Database.Entities.DefaultCategory.Id; } private void AddCategory() @@ -269,11 +279,15 @@ namespace FeedCenter.Options private void DeleteSelectedCategory() { - var defaultCategory = Database.Entities.DefaultCategory; - var category = (Category) CategoryListBox.SelectedItem; - category.Feeds?.ToList().ForEach(feed => feed.Category = defaultCategory); + if (MessageBox.Show(ParentWindow, string.Format(Properties.Resources.ConfirmDeleteCategory, category.Name), Properties.Resources.ConfirmDeleteTitle, MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) == MessageBoxResult.No) + return; + + var defaultCategory = Database.Entities.DefaultCategory; + + foreach (var feed in Database.Entities.Feeds.Where(f => f.CategoryId == category.Id)) + Database.Entities.SaveChanges(() => feed.CategoryId = defaultCategory.Id); var index = CategoryListBox.SelectedIndex; @@ -302,8 +316,6 @@ namespace FeedCenter.Options DeleteSelectedCategory(); } - private CollectionViewSource _collectionViewSource; - private void HandleCategoryListBoxSelectionChanged(object sender, SelectionChangedEventArgs e) { if (_collectionViewSource == null) @@ -330,7 +342,7 @@ namespace FeedCenter.Options var feed = (Feed) e.Item; - e.Accepted = feed.Category.Id == selectedCategory.Id; + e.Accepted = feed.CategoryId == selectedCategory.Id; } private void CategoryListBox_Drop(object sender, DragEventArgs e) @@ -340,7 +352,7 @@ namespace FeedCenter.Options var category = (Category) ((DataGridRow) sender).Item; foreach (var feed in feedList!) - feed.Category = category; + Database.Entities.SaveChanges(() => feed.CategoryId = category.Id); _collectionViewSource.View.Refresh(); @@ -404,5 +416,10 @@ namespace FeedCenter.Options EditSelectedCategory(); } + + private void FeedListBox_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + SetFeedButtonStates(); + } } } \ No newline at end of file diff --git a/Application/Options/GeneralOptionsPanel.xaml.cs b/Application/Options/GeneralOptionsPanel.xaml.cs index f509f4e..adf8e37 100644 --- a/Application/Options/GeneralOptionsPanel.xaml.cs +++ b/Application/Options/GeneralOptionsPanel.xaml.cs @@ -1,5 +1,6 @@ using ChrisKaczor.InstalledBrowsers; using ChrisKaczor.Wpf.Application; +using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; @@ -7,7 +8,7 @@ namespace FeedCenter.Options; public partial class GeneralOptionsPanel { - public GeneralOptionsPanel() + public GeneralOptionsPanel(Window parentWindow) : base(parentWindow) { InitializeComponent(); } diff --git a/Application/Options/OptionsPanelBase.cs b/Application/Options/OptionsPanelBase.cs index 23fc697..d3701cf 100644 --- a/Application/Options/OptionsPanelBase.cs +++ b/Application/Options/OptionsPanelBase.cs @@ -1,19 +1,27 @@ -using System.Windows.Controls; +using System.Windows; +using System.Windows.Controls; namespace FeedCenter.Options; public class OptionsPanelBase : UserControl { - public bool HasLoaded { get; private set; } + protected readonly Window ParentWindow; + + protected OptionsPanelBase(Window parentWindow) + { + ParentWindow = parentWindow; + } + + public virtual string CategoryName => null; + + protected bool HasLoaded { get; private set; } public virtual void LoadPanel() { } - public void MarkLoaded() + protected void MarkLoaded() { HasLoaded = true; } - - public virtual string CategoryName => null; } \ No newline at end of file diff --git a/Application/Options/OptionsWindow.xaml.cs b/Application/Options/OptionsWindow.xaml.cs index 4327c82..1bca1ab 100644 --- a/Application/Options/OptionsWindow.xaml.cs +++ b/Application/Options/OptionsWindow.xaml.cs @@ -1,5 +1,4 @@ -using FeedCenter.Data; -using System.Collections.Generic; +using System.Collections.Generic; using System.Windows.Controls; namespace FeedCenter.Options @@ -21,11 +20,11 @@ namespace FeedCenter.Options private void AddCategories() { - _optionPanels.Add(new GeneralOptionsPanel()); - _optionPanels.Add(new DisplayOptionsPanel()); - _optionPanels.Add(new FeedsOptionsPanel()); - _optionPanels.Add(new UpdateOptionsPanel()); - _optionPanels.Add(new AboutOptionsPanel()); + _optionPanels.Add(new GeneralOptionsPanel(this)); + _optionPanels.Add(new DisplayOptionsPanel(this)); + _optionPanels.Add(new FeedsOptionsPanel(this)); + _optionPanels.Add(new UpdateOptionsPanel(this)); + _optionPanels.Add(new AboutOptionsPanel(this)); } private void LoadCategories() @@ -61,13 +60,13 @@ namespace FeedCenter.Options private class CategoryListItem { - public OptionsPanelBase Panel { get; } - public CategoryListItem(OptionsPanelBase panel) { Panel = panel; } + public OptionsPanelBase Panel { get; } + public override string ToString() { return Panel.CategoryName; diff --git a/Application/Options/UpdateOptionsPanel.xaml.cs b/Application/Options/UpdateOptionsPanel.xaml.cs index f72159a..d2b0c75 100644 --- a/Application/Options/UpdateOptionsPanel.xaml.cs +++ b/Application/Options/UpdateOptionsPanel.xaml.cs @@ -1,14 +1,17 @@ -using ChrisKaczor.ApplicationUpdate; +using System.Windows; +using ChrisKaczor.ApplicationUpdate; namespace FeedCenter.Options; public partial class UpdateOptionsPanel { - public UpdateOptionsPanel() + public UpdateOptionsPanel(Window parentWindow) : base(parentWindow) { InitializeComponent(); } + public override string CategoryName => Properties.Resources.optionCategoryUpdate; + public override void LoadPanel() { base.LoadPanel(); @@ -18,8 +21,6 @@ public partial class UpdateOptionsPanel MarkLoaded(); } - public override string CategoryName => Properties.Resources.optionCategoryUpdate; - private void HandleCheckVersionNowButtonClick(object sender, System.Windows.RoutedEventArgs e) { UpdateCheck.DisplayUpdateInformation(true); diff --git a/Application/Properties/Resources.Designer.cs b/Application/Properties/Resources.Designer.cs index eaaec04..7ac6450 100644 --- a/Application/Properties/Resources.Designer.cs +++ b/Application/Properties/Resources.Designer.cs @@ -268,12 +268,41 @@ namespace FeedCenter.Properties { } } + /// + /// Looks up a localized string similar to Are you sure you want to delete this category? + /// + ///All feeds currently in category "{0}" will be moved to the default category.. + /// + public static string ConfirmDeleteCategory { + get { + return ResourceManager.GetString("ConfirmDeleteCategory", resourceCulture); + } + } + /// /// Looks up a localized string similar to Are you sure you want to delete this feed?. /// - public static string ConfirmDelete { + public static string ConfirmDeleteFeed { get { - return ResourceManager.GetString("ConfirmDelete", resourceCulture); + return ResourceManager.GetString("ConfirmDeleteFeed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Are you sure you want to delete the selected feeds?. + /// + public static string ConfirmDeleteFeeds { + get { + return ResourceManager.GetString("ConfirmDeleteFeeds", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Confirm Delete. + /// + public static string ConfirmDeleteTitle { + get { + return ResourceManager.GetString("ConfirmDeleteTitle", resourceCulture); } } diff --git a/Application/Properties/Resources.resx b/Application/Properties/Resources.resx index d42e704..4ad19f8 100644 --- a/Application/Properties/Resources.resx +++ b/Application/Properties/Resources.resx @@ -400,7 +400,7 @@ Edit... - + Are you sure you want to delete this feed? @@ -538,4 +538,15 @@ _Name: + + Are you sure you want to delete this category? + +All feeds currently in category "{0}" will be moved to the default category. + + + Confirm Delete + + + Are you sure you want to delete the selected feeds? + \ No newline at end of file diff --git a/Application/Properties/app.manifest b/Application/Properties/app.manifest index 42ff09e..d26ca0b 100644 --- a/Application/Properties/app.manifest +++ b/Application/Properties/app.manifest @@ -32,7 +32,7 @@ - + \ No newline at end of file