More UI updates

This commit is contained in:
2023-04-16 12:57:17 -04:00
parent 5c0c84a068
commit d6a2fd5a46
47 changed files with 3695 additions and 3768 deletions

View File

@@ -6,96 +6,95 @@ using System.Windows.Controls;
using System.Windows.Data;
using FeedCenter.Data;
namespace FeedCenter.Options
namespace FeedCenter.Options;
public partial class BulkFeedWindow
{
public partial class BulkFeedWindow
private List<CheckedListItem<Feed>> _checkedListBoxItems;
private CollectionViewSource _collectionViewSource;
public BulkFeedWindow()
{
private List<CheckedListItem<Feed>> _checkedListBoxItems;
private CollectionViewSource _collectionViewSource;
InitializeComponent();
}
public BulkFeedWindow()
public void Display(Window window)
{
_checkedListBoxItems = new List<CheckedListItem<Feed>>();
foreach (var feed in Database.Entities.Feeds)
_checkedListBoxItems.Add(new CheckedListItem<Feed> { Item = feed });
_collectionViewSource = new CollectionViewSource { Source = _checkedListBoxItems };
_collectionViewSource.SortDescriptions.Add(new SortDescription("Item.Name", ListSortDirection.Ascending));
_collectionViewSource.Filter += HandleCollectionViewSourceFilter;
FilteredFeedsList.ItemsSource = _collectionViewSource.View;
Owner = window;
ShowDialog();
}
private void HandleCollectionViewSourceFilter(object sender, FilterEventArgs e)
{
var checkedListBoxItem = (CheckedListItem<Feed>) e.Item;
var feed = checkedListBoxItem.Item;
e.Accepted = feed.Link.Contains(FeedLinkFilterText.Text);
}
private void HandleFilterTextChanged(object sender, TextChangedEventArgs e)
{
_collectionViewSource.View.Refresh();
}
private void HandleOkButtonClick(object sender, RoutedEventArgs e)
{
foreach (var item in _checkedListBoxItems.Where(i => i.IsChecked))
{
InitializeComponent();
if (OpenComboBox.IsEnabled)
item.Item.MultipleOpenAction = (MultipleOpenAction) ((ComboBoxItem) OpenComboBox.SelectedItem).Tag;
}
public void Display(Window window)
DialogResult = true;
Close();
}
private void HandleSelectAll(object sender, RoutedEventArgs e)
{
foreach (var viewItem in _collectionViewSource.View)
{
_checkedListBoxItems = new List<CheckedListItem<Feed>>();
var checkedListItem = (CheckedListItem<Feed>) viewItem;
foreach (var feed in Database.Entities.Feeds)
_checkedListBoxItems.Add(new CheckedListItem<Feed> { Item = feed });
_collectionViewSource = new CollectionViewSource { Source = _checkedListBoxItems };
_collectionViewSource.SortDescriptions.Add(new SortDescription("Item.Name", ListSortDirection.Ascending));
_collectionViewSource.Filter += HandleCollectionViewSourceFilter;
FilteredFeedsList.ItemsSource = _collectionViewSource.View;
Owner = window;
ShowDialog();
}
private void HandleCollectionViewSourceFilter(object sender, FilterEventArgs e)
{
var checkedListBoxItem = (CheckedListItem<Feed>) e.Item;
var feed = checkedListBoxItem.Item;
e.Accepted = feed.Link.Contains(FeedLinkFilterText.Text);
}
private void HandleFilterTextChanged(object sender, TextChangedEventArgs e)
{
_collectionViewSource.View.Refresh();
}
private void HandleOkButtonClick(object sender, RoutedEventArgs e)
{
foreach (var item in _checkedListBoxItems.Where(i => i.IsChecked))
{
if (OpenComboBox.IsEnabled)
item.Item.MultipleOpenAction = (MultipleOpenAction) ((ComboBoxItem) OpenComboBox.SelectedItem).Tag;
}
DialogResult = true;
Close();
}
private void HandleSelectAll(object sender, RoutedEventArgs e)
{
foreach (var viewItem in _collectionViewSource.View)
{
var checkedListItem = (CheckedListItem<Feed>) viewItem;
checkedListItem.IsChecked = true;
}
}
private void HandleSelectNone(object sender, RoutedEventArgs e)
{
foreach (var viewItem in _collectionViewSource.View)
{
var checkedListItem = (CheckedListItem<Feed>) viewItem;
checkedListItem.IsChecked = false;
}
}
private void HandleSelectInvert(object sender, RoutedEventArgs e)
{
foreach (var viewItem in _collectionViewSource.View)
{
var checkedListItem = (CheckedListItem<Feed>) viewItem;
checkedListItem.IsChecked = !checkedListItem.IsChecked;
}
}
private void HandleGridMouseRightButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
OpenLabel.IsEnabled = !OpenLabel.IsEnabled;
OpenComboBox.IsEnabled = !OpenComboBox.IsEnabled;
checkedListItem.IsChecked = true;
}
}
}
private void HandleSelectNone(object sender, RoutedEventArgs e)
{
foreach (var viewItem in _collectionViewSource.View)
{
var checkedListItem = (CheckedListItem<Feed>) viewItem;
checkedListItem.IsChecked = false;
}
}
private void HandleSelectInvert(object sender, RoutedEventArgs e)
{
foreach (var viewItem in _collectionViewSource.View)
{
var checkedListItem = (CheckedListItem<Feed>) viewItem;
checkedListItem.IsChecked = !checkedListItem.IsChecked;
}
}
private void HandleGridMouseRightButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
OpenLabel.IsEnabled = !OpenLabel.IsEnabled;
OpenComboBox.IsEnabled = !OpenComboBox.IsEnabled;
}
}

View File

@@ -8,6 +8,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:controls="clr-namespace:ChrisKaczor.Wpf.Windows;assembly=ChrisKaczor.Wpf.Windows.ControlBox"
xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:options="clr-namespace:FeedCenter.Options"
d:DataContext="{d:DesignInstance Type=feedCenter:Category}"
Title="CategoryWindow"
Width="300"
@@ -28,42 +29,23 @@
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid Margin="6">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Margin="6"
options:Spacing.Vertical="5">
<TextBox mah:TextBoxHelper.UseFloatingWatermark="True"
mah:TextBoxHelper.Watermark="{x:Static properties:Resources.categoryNameLabel}"
mah:TextBoxHelper.SelectAllOnFocus="True"
Text="{Binding Path=Name, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}" />
<StackPanel
Grid.Row="0"
Grid.Column="0">
<TextBox Name="NameTextBox"
VerticalAlignment="Center"
mah:TextBoxHelper.UseFloatingWatermark="True"
mah:TextBoxHelper.Watermark="{x:Static properties:Resources.categoryNameLabel}"
Text="{Binding Path=Name, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}">
</TextBox>
</StackPanel>
<StackPanel
Grid.Column="0"
Grid.Row="1"
options:Spacing.Horizontal="5"
Orientation="Horizontal"
Margin="0,5,0,0"
HorizontalAlignment="Right">
<Button Content="{x:Static properties:Resources.OkayButton}"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Width="75"
Margin="0,0,5,0"
IsDefault="True"
Click="HandleOkayButtonClick" />
<Button Content="{x:Static properties:Resources.CancelButton}"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Width="75"
IsCancel="True" />
</StackPanel>
</Grid>
</StackPanel>
</Window>

View File

@@ -2,50 +2,49 @@
using ChrisKaczor.Wpf.Validation;
using FeedCenter.Data;
namespace FeedCenter.Options
namespace FeedCenter.Options;
public partial class CategoryWindow
{
public partial class CategoryWindow
public CategoryWindow()
{
public CategoryWindow()
InitializeComponent();
}
public bool? Display(Category category, Window owner)
{
// Set the data context
DataContext = category;
// Set the title based on the state of the category
Title = string.IsNullOrWhiteSpace(category.Name)
? Properties.Resources.CategoryWindowAdd
: Properties.Resources.CategoryWindowEdit;
// Set the window owner
Owner = owner;
// Show the dialog and result the result
return ShowDialog();
}
private void HandleOkayButtonClick(object sender, RoutedEventArgs e)
{
var transaction = Database.Entities.BeginTransaction();
if (!this.IsValid())
{
InitializeComponent();
transaction.Rollback();
return;
}
public bool? Display(Category category, Window owner)
{
// Set the data context
DataContext = category;
transaction.Commit();
Database.Entities.Refresh();
// Set the title based on the state of the category
Title = string.IsNullOrWhiteSpace(category.Name)
? Properties.Resources.CategoryWindowAdd
: Properties.Resources.CategoryWindowEdit;
// Dialog is good
DialogResult = true;
// Set the window owner
Owner = owner;
// Show the dialog and result the result
return ShowDialog();
}
private void HandleOkayButtonClick(object sender, RoutedEventArgs e)
{
var transaction = Database.Entities.BeginTransaction();
if (!this.IsValid())
{
transaction.Rollback();
return;
}
transaction.Commit();
Database.Entities.Refresh();
// Dialog is good
DialogResult = true;
// Close the dialog
Close();
}
// Close the dialog
Close();
}
}

View File

@@ -6,9 +6,11 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
d:DataContext="{d:DesignInstance Type=feedCenter:Feed}"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:options="clr-namespace:FeedCenter.Options"
mc:Ignorable="d"
Title="FeedWindow"
Height="300"
Height="350"
Width="450"
WindowStartupLocation="CenterOwner"
Icon="/FeedCenter;component/Resources/Application.ico"
@@ -23,175 +25,117 @@
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Grid Margin="6">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TabControl Name="OptionsTabControl"
Margin="12,12,12,41">
Grid.Row="0"
Grid.Column="0"
mah:HeaderedControlHelper.HeaderFontSize="16"
mah:TabControlHelper.Underlined="SelectedTabItem">
<TabItem Header="{x:Static properties:Resources.generalTab}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Content="{x:Static properties:Resources.feedUrlLabel}"
VerticalContentAlignment="Center"
Target="{Binding ElementName=UrlTextBox}"
Margin="6"
Padding="0" />
<StackPanel Margin="0,4"
options:Spacing.Vertical="8">
<TextBox Name="UrlTextBox"
Grid.Row="0"
Grid.Column="1"
Margin="6"
mah:TextBoxHelper.UseFloatingWatermark="True"
mah:TextBoxHelper.Watermark="{x:Static properties:Resources.feedUrlLabel}"
mah:TextBoxHelper.SelectAllOnFocus="True"
Text="{Binding Path=Source, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}" />
<Label Content="{x:Static properties:Resources.feedNameLabel}"
VerticalContentAlignment="Center"
Target="{Binding ElementName=NameTextBox}"
Grid.Row="1"
Grid.Column="0"
Margin="6"
Padding="0" />
<TextBox Name="NameTextBox"
Grid.Column="1"
Grid.Row="1"
Margin="6"
mah:TextBoxHelper.UseFloatingWatermark="True"
mah:TextBoxHelper.Watermark="{x:Static properties:Resources.feedNameLabel}"
mah:TextBoxHelper.SelectAllOnFocus="True"
Text="{Binding Path=Name, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}" />
<Label Content="{x:Static properties:Resources.feedCategoryLabel}"
Target="{Binding ElementName=CategoryComboBox}"
VerticalContentAlignment="Center"
Grid.Row="2"
Grid.Column="0"
Margin="6"
Padding="0" />
<ComboBox Grid.Column="1"
Name="CategoryComboBox"
<ComboBox Name="CategoryComboBox"
DisplayMemberPath="Name"
SelectedValuePath="ID"
SelectedValue="{Binding Path=Category.Id}"
Grid.Row="2"
Margin="6" />
<CheckBox Grid.ColumnSpan="2"
Grid.Column="0"
Name="ReadIntervalCheckBox"
SelectedValuePath="Id"
SelectedValue="{Binding Path=CategoryId}"
mah:TextBoxHelper.UseFloatingWatermark="True"
mah:TextBoxHelper.Watermark="{x:Static properties:Resources.feedCategoryLabel}" />
<CheckBox Name="ReadIntervalCheckBox"
VerticalContentAlignment="Center"
IsChecked="{Binding Path=Enabled, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}"
Grid.Row="3"
Margin="6">
<DockPanel>
IsChecked="{Binding Path=Enabled, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}">
<StackPanel Orientation="Horizontal">
<Label Content="{x:Static properties:Resources.feedReadIntervalPrefix}"
HorizontalAlignment="Left"
Margin="0,0,5,0"
VerticalAlignment="Center"
Padding="0" />
<TextBox Width="50"
Text="{Binding Path=CheckInterval, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}"
IsEnabled="{Binding ElementName=ReadIntervalCheckBox, Path=IsChecked}" />
<mah:NumericUpDown Width="100"
Maximum="10080"
Minimum="1"
IsEnabled="{Binding ElementName=ReadIntervalCheckBox, Path=IsChecked}"
Value="{Binding CheckInterval, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}" />
<Label Content="{x:Static properties:Resources.feedReadIntervalSuffix}"
HorizontalAlignment="Left"
Margin="5,0,0,0"
VerticalAlignment="Center"
Padding="0" />
</DockPanel>
</StackPanel>
</CheckBox>
</Grid>
</StackPanel>
</TabItem>
<TabItem Header="{x:Static properties:Resources.readingTab}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label Content="{x:Static properties:Resources.openLabel}"
Target="{Binding ElementName=OpenComboBox}"
Padding="0"
VerticalContentAlignment="Center"
Margin="6" />
<StackPanel Margin="0,4"
options:Spacing.Vertical="8">
<ComboBox Name="OpenComboBox"
VerticalContentAlignment="Center"
SelectedValue="{Binding Path=MultipleOpenAction, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=true}"
SelectedValuePath="Tag"
Grid.Row="0"
Grid.Column="1"
Margin="6">
mah:TextBoxHelper.UseFloatingWatermark="True"
mah:TextBoxHelper.Watermark="{x:Static properties:Resources.openLabel}">
<ComboBoxItem Content="{x:Static properties:Resources.openAllSingleToolbarButton}"
Tag="{x:Static feedCenter:MultipleOpenAction.SinglePage}" />
<ComboBoxItem Content="{x:Static properties:Resources.openAllMultipleToolbarButton}"
Tag="{x:Static feedCenter:MultipleOpenAction.IndividualPages}" />
</ComboBox>
</Grid>
</StackPanel>
</TabItem>
<TabItem Header="{x:Static properties:Resources.authenticationTab}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Margin="0,4">
<CheckBox Content="{x:Static properties:Resources.requiresAuthenticationCheckBox}"
Margin="0,0,0,4"
Name="RequiresAuthenticationCheckBox"
Grid.ColumnSpan="2"
Grid.Row="0"
Grid.Column="0"
IsChecked="{Binding Path=Authenticate, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}"
Margin="6" />
<Label Content="{x:Static properties:Resources.authenticationUserNameLabel}"
Target="{Binding ElementName=AuthenticationUserNameTextBox}"
VerticalContentAlignment="Center"
IsEnabled="{Binding ElementName=RequiresAuthenticationCheckBox, Path=IsChecked}"
Grid.Row="1"
Grid.Column="0"
Margin="6"
Padding="20,0,0,0" />
IsChecked="{Binding Path=Authenticate, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}" />
<TextBox Name="AuthenticationUserNameTextBox"
Grid.Column="1"
Margin="25,0,0,4"
IsEnabled="{Binding ElementName=RequiresAuthenticationCheckBox, Path=IsChecked}"
Grid.Row="1"
Margin="6"
mah:TextBoxHelper.UseFloatingWatermark="True"
mah:TextBoxHelper.Watermark="{x:Static properties:Resources.authenticationUserNameLabel}"
Text="{Binding Path=Username, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}" />
<Label Content="{x:Static properties:Resources.authenticationPasswordLabel}"
Target="{Binding ElementName=AuthenticationPasswordTextBox}"
VerticalContentAlignment="Center"
IsEnabled="{Binding ElementName=RequiresAuthenticationCheckBox, Path=IsChecked}"
Grid.Row="2"
Grid.Column="0"
Margin="6"
Padding="20,0,0,0" />
<PasswordBox Name="AuthenticationPasswordTextBox"
Grid.Column="1"
IsEnabled="{Binding ElementName=RequiresAuthenticationCheckBox, Path=IsChecked}"
Grid.Row="2"
Margin="6" />
</Grid>
Margin="25,0,0,8"
Style="{StaticResource MahApps.Styles.PasswordBox.Button.Revealed}"
mah:PasswordBoxBindingBehavior.Password="{Binding Password, UpdateSourceTrigger=Explicit, ValidatesOnDataErrors=True}"
mah:TextBoxHelper.UseFloatingWatermark="True"
mah:TextBoxHelper.Watermark="{x:Static properties:Resources.authenticationPasswordLabel}"
IsEnabled="{Binding ElementName=RequiresAuthenticationCheckBox, Path=IsChecked}" />
</StackPanel>
</TabItem>
</TabControl>
<Button Content="{x:Static properties:Resources.OkayButton}"
Height="23"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Width="75"
IsDefault="True"
Margin="0,0,93,12"
Click="HandleOkayButtonClick" />
<Button Content="{x:Static properties:Resources.CancelButton}"
Height="23"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Width="75"
IsCancel="True"
Margin="0,0,12,12" />
<StackPanel
Grid.Column="0"
Grid.Row="1"
Orientation="Horizontal"
Margin="0,5,0,0"
HorizontalAlignment="Right">
<Button Content="{x:Static properties:Resources.OkayButton}"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Width="75"
Margin="0,0,5,0"
IsDefault="True"
Click="HandleOkayButtonClick" />
<Button Content="{x:Static properties:Resources.CancelButton}"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Width="75"
IsCancel="True" />
</StackPanel>
</Grid>
</Window>

View File

@@ -1,96 +1,44 @@
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using ChrisKaczor.Wpf.Validation;
using ChrisKaczor.Wpf.Validation;
using FeedCenter.Data;
using System.Windows;
namespace FeedCenter.Options
namespace FeedCenter.Options;
public partial class FeedWindow
{
public partial class FeedWindow
public FeedWindow()
{
public FeedWindow()
InitializeComponent();
}
public bool? Display(Feed feed, Window owner)
{
CategoryComboBox.ItemsSource = Database.Entities.Categories;
DataContext = feed;
Title = string.IsNullOrWhiteSpace(feed.Link) ? Properties.Resources.FeedWindowAdd : Properties.Resources.FeedWindowEdit;
Owner = owner;
return ShowDialog();
}
private void HandleOkayButtonClick(object sender, RoutedEventArgs e)
{
var transaction = Database.Entities.BeginTransaction();
if (!this.IsValid(OptionsTabControl))
{
InitializeComponent();
transaction.Rollback();
return;
}
public bool? Display(Feed feed, Window owner)
{
// Bind the category combo box
CategoryComboBox.ItemsSource = Database.Entities.Categories;
transaction.Commit();
Database.Entities.Refresh();
// Set the data context
DataContext = feed;
DialogResult = true;
// Set the title based on the state of the feed
Title = string.IsNullOrWhiteSpace(feed.Link) ? Properties.Resources.FeedWindowAdd : Properties.Resources.FeedWindowEdit;
// Set the window owner
Owner = owner;
// Show the dialog and result the result
return ShowDialog();
}
private void HandleOkayButtonClick(object sender, RoutedEventArgs e)
{
var transaction = Database.Entities.BeginTransaction();
var feed = (Feed) DataContext;
// Get a list of all framework elements and explicit binding expressions
var bindingExpressions = this.GetBindingExpressions(new[] { UpdateSourceTrigger.Explicit });
// Loop over each binding expression and clear any existing error
this.ClearAllValidationErrors(bindingExpressions);
// Force all explicit bindings to update the source
this.UpdateAllSources(bindingExpressions);
// See if there are any errors
var hasError = bindingExpressions.Any(b => b.BindingExpression.HasError);
// If there was an error then set focus to the bad controls
if (hasError)
{
// Get the first framework element with an error
var firstErrorElement = bindingExpressions.First(b => b.BindingExpression.HasError).FrameworkElement;
// Loop over each tab item
foreach (TabItem tabItem in OptionsTabControl.Items)
{
// Cast the content as visual
var content = (Visual) tabItem.Content;
// See if the control with the error is a descendant
if (firstErrorElement.IsDescendantOf(content))
{
// Select the tab
tabItem.IsSelected = true;
break;
}
}
// Set focus
firstErrorElement.Focus();
transaction.Rollback();
return;
}
if (RequiresAuthenticationCheckBox.IsChecked.GetValueOrDefault(false))
feed.Password = AuthenticationPasswordTextBox.Password;
transaction.Commit();
Database.Entities.Refresh();
// Dialog is good
DialogResult = true;
// Close the dialog
Close();
}
Close();
}
}

View File

@@ -9,417 +9,416 @@ using System.Xml;
using FeedCenter.Data;
using Microsoft.Win32;
namespace FeedCenter.Options
namespace FeedCenter.Options;
public partial class FeedsOptionsPanel
{
public partial class FeedsOptionsPanel
private CollectionViewSource _collectionViewSource;
public FeedsOptionsPanel(Window parentWindow) : base(parentWindow)
{
private CollectionViewSource _collectionViewSource;
InitializeComponent();
}
public FeedsOptionsPanel(Window parentWindow) : base(parentWindow)
public override string CategoryName => Properties.Resources.optionCategoryFeeds;
public override void LoadPanel()
{
base.LoadPanel();
var collectionViewSource = new CollectionViewSource { Source = Database.Entities.Categories };
collectionViewSource.SortDescriptions.Add(new SortDescription("SortKey", ListSortDirection.Ascending));
collectionViewSource.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
collectionViewSource.IsLiveSortingRequested = true;
CategoryListBox.ItemsSource = collectionViewSource.View;
CategoryListBox.SelectedIndex = 0;
}
private void SetFeedButtonStates()
{
AddFeedButton.IsEnabled = true;
EditFeedButton.IsEnabled = FeedListBox.SelectedItems.Count == 1;
DeleteFeedButton.IsEnabled = FeedListBox.SelectedItems.Count > 0;
}
private void AddFeed()
{
var feed = Feed.Create();
var category = (Category) CategoryListBox.SelectedItem;
feed.CategoryId = category.Id;
var feedWindow = new FeedWindow();
var result = feedWindow.Display(feed, Window.GetWindow(this));
if (!result.HasValue || !result.Value)
return;
Database.Entities.SaveChanges(() => Database.Entities.Feeds.Add(feed));
FeedListBox.SelectedItem = feed;
SetFeedButtonStates();
}
private void EditSelectedFeed()
{
if (FeedListBox.SelectedItem == null)
return;
var feed = (Feed) FeedListBox.SelectedItem;
var feedWindow = new FeedWindow();
feedWindow.Display(feed, Window.GetWindow(this));
}
private void DeleteSelectedFeeds()
{
if (MessageBox.Show(ParentWindow, Properties.Resources.ConfirmDeleteFeeds, Properties.Resources.ConfirmDeleteTitle, MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) == MessageBoxResult.No)
return;
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();
}
private void HandleAddFeedButtonClick(object sender, RoutedEventArgs e)
{
AddFeed();
}
private void HandleEditFeedButtonClick(object sender, RoutedEventArgs e)
{
EditSelectedFeed();
}
private void HandleDeleteFeedButtonClick(object sender, RoutedEventArgs e)
{
DeleteSelectedFeeds();
}
private void HandleImportButtonClick(object sender, RoutedEventArgs e)
{
ImportFeeds();
}
private void HandleExportButtonClick(object sender, RoutedEventArgs e)
{
ExportFeeds();
}
private static void ExportFeeds()
{
var saveFileDialog = new SaveFileDialog
{
InitializeComponent();
}
FileName = Properties.Resources.ApplicationName,
Filter = Properties.Resources.ImportExportFilter,
FilterIndex = 0,
OverwritePrompt = true
};
public override string CategoryName => Properties.Resources.optionCategoryFeeds;
var result = saveFileDialog.ShowDialog();
public override void LoadPanel()
if (!result.GetValueOrDefault(false))
return;
var writerSettings = new XmlWriterSettings
{
base.LoadPanel();
Indent = true,
CheckCharacters = true,
ConformanceLevel = ConformanceLevel.Document
};
var collectionViewSource = new CollectionViewSource { Source = Database.Entities.Categories };
collectionViewSource.SortDescriptions.Add(new SortDescription("SortKey", ListSortDirection.Ascending));
collectionViewSource.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
collectionViewSource.IsLiveSortingRequested = true;
var xmlWriter = XmlWriter.Create(saveFileDialog.FileName, writerSettings);
CategoryListBox.ItemsSource = collectionViewSource.View;
CategoryListBox.SelectedIndex = 0;
}
xmlWriter.WriteStartElement("opml");
xmlWriter.WriteStartElement("body");
private void SetFeedButtonStates()
foreach (var feed in Database.Entities.Feeds.OrderBy(feed => feed.Name))
{
AddFeedButton.IsEnabled = true;
EditFeedButton.IsEnabled = FeedListBox.SelectedItems.Count == 1;
DeleteFeedButton.IsEnabled = FeedListBox.SelectedItems.Count > 0;
}
xmlWriter.WriteStartElement("outline");
private void AddFeed()
{
var feed = Feed.Create();
var category = (Category) CategoryListBox.SelectedItem;
feed.CategoryId = category.Id;
var feedWindow = new FeedWindow();
var result = feedWindow.Display(feed, Window.GetWindow(this));
if (!result.HasValue || !result.Value)
return;
Database.Entities.SaveChanges(() => Database.Entities.Feeds.Add(feed));
FeedListBox.SelectedItem = feed;
SetFeedButtonStates();
}
private void EditSelectedFeed()
{
if (FeedListBox.SelectedItem == null)
return;
var feed = (Feed) FeedListBox.SelectedItem;
var feedWindow = new FeedWindow();
feedWindow.Display(feed, Window.GetWindow(this));
}
private void DeleteSelectedFeeds()
{
if (MessageBox.Show(ParentWindow, Properties.Resources.ConfirmDeleteFeeds, Properties.Resources.ConfirmDeleteTitle, MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) == MessageBoxResult.No)
return;
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();
}
private void HandleAddFeedButtonClick(object sender, RoutedEventArgs e)
{
AddFeed();
}
private void HandleEditFeedButtonClick(object sender, RoutedEventArgs e)
{
EditSelectedFeed();
}
private void HandleDeleteFeedButtonClick(object sender, RoutedEventArgs e)
{
DeleteSelectedFeeds();
}
private void HandleImportButtonClick(object sender, RoutedEventArgs e)
{
ImportFeeds();
}
private void HandleExportButtonClick(object sender, RoutedEventArgs e)
{
ExportFeeds();
}
private static void ExportFeeds()
{
var saveFileDialog = new SaveFileDialog
{
FileName = Properties.Resources.ApplicationName,
Filter = Properties.Resources.ImportExportFilter,
FilterIndex = 0,
OverwritePrompt = true
};
var result = saveFileDialog.ShowDialog();
if (!result.GetValueOrDefault(false))
return;
var writerSettings = new XmlWriterSettings
{
Indent = true,
CheckCharacters = true,
ConformanceLevel = ConformanceLevel.Document
};
var xmlWriter = XmlWriter.Create(saveFileDialog.FileName, writerSettings);
xmlWriter.WriteStartElement("opml");
xmlWriter.WriteStartElement("body");
foreach (var feed in Database.Entities.Feeds.OrderBy(feed => feed.Name))
{
xmlWriter.WriteStartElement("outline");
xmlWriter.WriteAttributeString("title", feed.Title);
xmlWriter.WriteAttributeString("htmlUrl", feed.Link);
xmlWriter.WriteAttributeString("xmlUrl", feed.Source);
xmlWriter.WriteEndElement();
}
xmlWriter.WriteAttributeString("title", feed.Title);
xmlWriter.WriteAttributeString("htmlUrl", feed.Link);
xmlWriter.WriteAttributeString("xmlUrl", feed.Source);
xmlWriter.WriteEndElement();
xmlWriter.WriteEndElement();
xmlWriter.Flush();
xmlWriter.Close();
}
private static void ImportFeeds()
xmlWriter.WriteEndElement();
xmlWriter.WriteEndElement();
xmlWriter.Flush();
xmlWriter.Close();
}
private static void ImportFeeds()
{
var openFileDialog = new OpenFileDialog
{
var openFileDialog = new OpenFileDialog
Filter = Properties.Resources.ImportExportFilter,
FilterIndex = 0
};
var result = openFileDialog.ShowDialog();
if (!result.GetValueOrDefault(false))
return;
var xmlReaderSettings = new XmlReaderSettings { IgnoreWhitespace = true };
var xmlReader = XmlReader.Create(openFileDialog.FileName, xmlReaderSettings);
try
{
xmlReader.Read();
xmlReader.ReadStartElement("opml");
xmlReader.ReadStartElement("body");
while (xmlReader.NodeType != XmlNodeType.EndElement)
{
Filter = Properties.Resources.ImportExportFilter,
FilterIndex = 0
};
var feed = Feed.Create();
feed.CategoryId = Database.Entities.Categories.First(c => c.IsDefault).Id;
var result = openFileDialog.ShowDialog();
if (!result.GetValueOrDefault(false))
return;
var xmlReaderSettings = new XmlReaderSettings { IgnoreWhitespace = true };
var xmlReader = XmlReader.Create(openFileDialog.FileName, xmlReaderSettings);
try
{
xmlReader.Read();
xmlReader.ReadStartElement("opml");
xmlReader.ReadStartElement("body");
while (xmlReader.NodeType != XmlNodeType.EndElement)
while (xmlReader.MoveToNextAttribute())
{
var feed = Feed.Create();
feed.CategoryId = Database.Entities.Categories.First(c => c.IsDefault).Id;
while (xmlReader.MoveToNextAttribute())
switch (xmlReader.Name.ToLower())
{
switch (xmlReader.Name.ToLower())
{
case "title":
feed.Title = xmlReader.Value;
break;
case "title":
feed.Title = xmlReader.Value;
break;
// ReSharper disable once StringLiteralTypo
case "htmlurl":
feed.Link = xmlReader.Value;
break;
// ReSharper disable once StringLiteralTypo
case "htmlurl":
feed.Link = xmlReader.Value;
break;
// ReSharper disable once StringLiteralTypo
case "xmlurl":
feed.Source = xmlReader.Value;
break;
// ReSharper disable once StringLiteralTypo
case "xmlurl":
feed.Source = xmlReader.Value;
break;
case "text":
feed.Name = xmlReader.Value;
break;
}
case "text":
feed.Name = xmlReader.Value;
break;
}
if (string.IsNullOrEmpty(feed.Name))
feed.Name = feed.Title;
Database.Entities.Feeds.Add(feed);
xmlReader.MoveToElement();
xmlReader.Skip();
}
xmlReader.ReadEndElement();
if (string.IsNullOrEmpty(feed.Name))
feed.Name = feed.Title;
xmlReader.ReadEndElement();
}
finally
{
xmlReader.Close();
}
}
Database.Entities.Feeds.Add(feed);
private void SetCategoryButtonStates()
{
AddCategoryButton.IsEnabled = true;
xmlReader.MoveToElement();
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;
}
private void AddCategory()
{
var category = new Category();
var categoryWindow = new CategoryWindow();
var result = categoryWindow.Display(category, Window.GetWindow(this));
if (!result.HasValue || !result.Value)
return;
Database.Entities.SaveChanges(() => Database.Entities.Categories.Add(category));
CategoryListBox.SelectedItem = category;
SetCategoryButtonStates();
}
private void EditSelectedCategory()
{
if (CategoryListBox.SelectedItem == null)
return;
var category = (Category) CategoryListBox.SelectedItem;
var categoryWindow = new CategoryWindow();
categoryWindow.Display(category, Window.GetWindow(this));
}
private void DeleteSelectedCategory()
{
var category = (Category) CategoryListBox.SelectedItem;
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;
if (index == CategoryListBox.Items.Count - 1)
CategoryListBox.SelectedIndex = index - 1;
else
CategoryListBox.SelectedIndex = index + 1;
Database.Entities.SaveChanges(() => Database.Entities.Categories.Remove(category));
SetCategoryButtonStates();
}
private void HandleAddCategoryButtonClick(object sender, RoutedEventArgs e)
{
AddCategory();
}
private void HandleEditCategoryButtonClick(object sender, RoutedEventArgs e)
{
EditSelectedCategory();
}
private void HandleDeleteCategoryButtonClick(object sender, RoutedEventArgs e)
{
DeleteSelectedCategory();
}
private void HandleCategoryListBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (_collectionViewSource == null)
{
_collectionViewSource = new CollectionViewSource { Source = Database.Entities.Feeds };
_collectionViewSource.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
_collectionViewSource.Filter += HandleCollectionViewSourceFilter;
FeedListBox.ItemsSource = _collectionViewSource.View;
xmlReader.Skip();
}
_collectionViewSource.View.Refresh();
xmlReader.ReadEndElement();
if (FeedListBox.Items.Count > 0)
FeedListBox.SelectedIndex = 0;
SetFeedButtonStates();
SetCategoryButtonStates();
xmlReader.ReadEndElement();
}
private void HandleCollectionViewSourceFilter(object sender, FilterEventArgs e)
finally
{
var selectedCategory = (Category) CategoryListBox.SelectedItem;
var feed = (Feed) e.Item;
e.Accepted = feed.CategoryId == selectedCategory.Id;
}
private void CategoryListBox_Drop(object sender, DragEventArgs e)
{
var feedList = (List<Feed>) e.Data.GetData(typeof(List<Feed>));
var category = (Category) ((DataGridRow) sender).Item;
foreach (var feed in feedList!)
Database.Entities.SaveChanges(() => feed.CategoryId = category.Id);
_collectionViewSource.View.Refresh();
var dataGridRow = (DataGridRow) sender;
dataGridRow.FontWeight = FontWeights.Normal;
}
private void HandleListBoxItemPreviewMouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton != MouseButtonState.Pressed)
return;
var selectedItems = FeedListBox.SelectedItems.Cast<Feed>().ToList();
DragDrop.DoDragDrop(FeedListBox, selectedItems, DragDropEffects.Move);
}
private void CategoryListBox_DragEnter(object sender, DragEventArgs e)
{
var dataGridRow = (DataGridRow) sender;
dataGridRow.FontWeight = FontWeights.Bold;
}
private void CategoryListBox_DragLeave(object sender, DragEventArgs e)
{
var dataGridRow = (DataGridRow) sender;
dataGridRow.FontWeight = FontWeights.Normal;
}
private void HandleListBoxItemMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
EditSelectedFeed();
}
private void HandleMultipleEditClick(object sender, RoutedEventArgs e)
{
var bulkFeedWindow = new BulkFeedWindow();
bulkFeedWindow.Display(Window.GetWindow(this));
}
private void HandleFeedListPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
// Get the object that was clicked on
var originalSource = (DependencyObject) e.OriginalSource;
// Look for a row that contains the object
var dataGridRow = (DataGridRow) FeedListBox.ContainerFromElement(originalSource);
// If the selection already contains this row then ignore it
if (dataGridRow != null && FeedListBox.SelectedItems.Contains(dataGridRow.Item))
e.Handled = true;
}
private void CategoryListBox_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
if (!EditCategoryButton.IsEnabled)
return;
EditSelectedCategory();
}
private void FeedListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
SetFeedButtonStates();
xmlReader.Close();
}
}
private void SetCategoryButtonStates()
{
AddCategoryButton.IsEnabled = true;
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;
}
private void AddCategory()
{
var category = new Category();
var categoryWindow = new CategoryWindow();
var result = categoryWindow.Display(category, Window.GetWindow(this));
if (!result.HasValue || !result.Value)
return;
Database.Entities.SaveChanges(() => Database.Entities.Categories.Add(category));
CategoryListBox.SelectedItem = category;
SetCategoryButtonStates();
}
private void EditSelectedCategory()
{
if (CategoryListBox.SelectedItem == null)
return;
var category = (Category) CategoryListBox.SelectedItem;
var categoryWindow = new CategoryWindow();
categoryWindow.Display(category, Window.GetWindow(this));
}
private void DeleteSelectedCategory()
{
var category = (Category) CategoryListBox.SelectedItem;
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;
if (index == CategoryListBox.Items.Count - 1)
CategoryListBox.SelectedIndex = index - 1;
else
CategoryListBox.SelectedIndex = index + 1;
Database.Entities.SaveChanges(() => Database.Entities.Categories.Remove(category));
SetCategoryButtonStates();
}
private void HandleAddCategoryButtonClick(object sender, RoutedEventArgs e)
{
AddCategory();
}
private void HandleEditCategoryButtonClick(object sender, RoutedEventArgs e)
{
EditSelectedCategory();
}
private void HandleDeleteCategoryButtonClick(object sender, RoutedEventArgs e)
{
DeleteSelectedCategory();
}
private void HandleCategoryListBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (_collectionViewSource == null)
{
_collectionViewSource = new CollectionViewSource { Source = Database.Entities.Feeds };
_collectionViewSource.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
_collectionViewSource.Filter += HandleCollectionViewSourceFilter;
FeedListBox.ItemsSource = _collectionViewSource.View;
}
_collectionViewSource.View.Refresh();
if (FeedListBox.Items.Count > 0)
FeedListBox.SelectedIndex = 0;
SetFeedButtonStates();
SetCategoryButtonStates();
}
private void HandleCollectionViewSourceFilter(object sender, FilterEventArgs e)
{
var selectedCategory = (Category) CategoryListBox.SelectedItem;
var feed = (Feed) e.Item;
e.Accepted = feed.CategoryId == selectedCategory.Id;
}
private void CategoryListBox_Drop(object sender, DragEventArgs e)
{
var feedList = (List<Feed>) e.Data.GetData(typeof(List<Feed>));
var category = (Category) ((DataGridRow) sender).Item;
foreach (var feed in feedList!)
Database.Entities.SaveChanges(() => feed.CategoryId = category.Id);
_collectionViewSource.View.Refresh();
var dataGridRow = (DataGridRow) sender;
dataGridRow.FontWeight = FontWeights.Normal;
}
private void HandleListBoxItemPreviewMouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton != MouseButtonState.Pressed)
return;
var selectedItems = FeedListBox.SelectedItems.Cast<Feed>().ToList();
DragDrop.DoDragDrop(FeedListBox, selectedItems, DragDropEffects.Move);
}
private void CategoryListBox_DragEnter(object sender, DragEventArgs e)
{
var dataGridRow = (DataGridRow) sender;
dataGridRow.FontWeight = FontWeights.Bold;
}
private void CategoryListBox_DragLeave(object sender, DragEventArgs e)
{
var dataGridRow = (DataGridRow) sender;
dataGridRow.FontWeight = FontWeights.Normal;
}
private void HandleListBoxItemMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
EditSelectedFeed();
}
private void HandleMultipleEditClick(object sender, RoutedEventArgs e)
{
var bulkFeedWindow = new BulkFeedWindow();
bulkFeedWindow.Display(Window.GetWindow(this));
}
private void HandleFeedListPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
// Get the object that was clicked on
var originalSource = (DependencyObject) e.OriginalSource;
// Look for a row that contains the object
var dataGridRow = (DataGridRow) FeedListBox.ContainerFromElement(originalSource);
// If the selection already contains this row then ignore it
if (dataGridRow != null && FeedListBox.SelectedItems.Contains(dataGridRow.Item))
e.Handled = true;
}
private void CategoryListBox_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
if (!EditCategoryButton.IsEnabled)
return;
EditSelectedCategory();
}
private void FeedListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
SetFeedButtonStates();
}
}

View File

@@ -1,9 +1,8 @@
namespace FeedCenter.Options
namespace FeedCenter.Options;
public enum MultipleLineDisplay
{
public enum MultipleLineDisplay
{
Normal,
SingleLine,
FirstLine
}
}
Normal,
SingleLine,
FirstLine
}

View File

@@ -1,76 +1,75 @@
using System.Collections.Generic;
using System.Windows.Controls;
namespace FeedCenter.Options
namespace FeedCenter.Options;
public partial class OptionsWindow
{
public partial class OptionsWindow
private readonly List<OptionsPanelBase> _optionPanels = new();
public OptionsWindow()
{
private readonly List<OptionsPanelBase> _optionPanels = new();
InitializeComponent();
public OptionsWindow()
// Add all the option categories
AddCategories();
// Load the category list
LoadCategories();
}
private void AddCategories()
{
_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()
{
// Loop over each panel
foreach (var optionsPanel in _optionPanels)
{
InitializeComponent();
// Tell the panel to load itself
optionsPanel.LoadPanel();
// Add all the option categories
AddCategories();
// Add the panel to the category ist
CategoryListBox.Items.Add(new CategoryListItem(optionsPanel));
// Load the category list
LoadCategories();
// Set the panel into the right side
ContentControl.Content = optionsPanel;
}
private void AddCategories()
// Select the first item
CategoryListBox.SelectedItem = CategoryListBox.Items[0];
}
private void SelectCategory(OptionsPanelBase panel)
{
// Set the content
ContentControl.Content = panel;
}
private void HandleSelectedCategoryChanged(object sender, SelectionChangedEventArgs e)
{
// Select the right category
SelectCategory(((CategoryListItem) CategoryListBox.SelectedItem).Panel);
}
private class CategoryListItem
{
public CategoryListItem(OptionsPanelBase panel)
{
_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));
Panel = panel;
}
private void LoadCategories()
public OptionsPanelBase Panel { get; }
public override string ToString()
{
// Loop over each panel
foreach (var optionsPanel in _optionPanels)
{
// Tell the panel to load itself
optionsPanel.LoadPanel();
// Add the panel to the category ist
CategoryListBox.Items.Add(new CategoryListItem(optionsPanel));
// Set the panel into the right side
ContentControl.Content = optionsPanel;
}
// Select the first item
CategoryListBox.SelectedItem = CategoryListBox.Items[0];
}
private void SelectCategory(OptionsPanelBase panel)
{
// Set the content
ContentControl.Content = panel;
}
private void HandleSelectedCategoryChanged(object sender, SelectionChangedEventArgs e)
{
// Select the right category
SelectCategory(((CategoryListItem) CategoryListBox.SelectedItem).Panel);
}
private class CategoryListItem
{
public CategoryListItem(OptionsPanelBase panel)
{
Panel = panel;
}
public OptionsPanelBase Panel { get; }
public override string ToString()
{
return Panel.CategoryName;
}
return Panel.CategoryName;
}
}
}

View File

@@ -1,14 +1,13 @@
using Realms;
namespace FeedCenter.Options
{
public class Setting : RealmObject
{
[PrimaryKey]
public string Name { get; set; }
public string Value { get; set; }
namespace FeedCenter.Options;
[Ignored]
public string Version { get; set; }
}
}
public class Setting : RealmObject
{
[PrimaryKey]
public string Name { get; set; }
public string Value { get; set; }
[Ignored]
public string Version { get; set; }
}

View File

@@ -1,55 +1,54 @@
using JetBrains.Annotations;
using System.Windows;
namespace FeedCenter.Options
namespace FeedCenter.Options;
public class Spacing
{
public class Spacing
public static double GetHorizontal(DependencyObject obj)
{
public static double GetHorizontal(DependencyObject obj)
{
return (double) obj.GetValue(HorizontalProperty);
}
public static double GetVertical(DependencyObject obj)
{
return (double) obj.GetValue(VerticalProperty);
}
private static void HorizontalChangedCallback(object sender, DependencyPropertyChangedEventArgs e)
{
var space = (double) e.NewValue;
var obj = (DependencyObject) sender;
MarginSetter.SetMargin(obj, new Thickness(0, 0, space, 0));
MarginSetter.SetLastItemMargin(obj, new Thickness(0));
}
[UsedImplicitly]
public static void SetHorizontal(DependencyObject obj, double space)
{
obj.SetValue(HorizontalProperty, space);
}
[UsedImplicitly]
public static void SetVertical(DependencyObject obj, double value)
{
obj.SetValue(VerticalProperty, value);
}
private static void VerticalChangedCallback(object sender, DependencyPropertyChangedEventArgs e)
{
var space = (double) e.NewValue;
var obj = (DependencyObject) sender;
MarginSetter.SetMargin(obj, new Thickness(0, 0, 0, space));
MarginSetter.SetLastItemMargin(obj, new Thickness(0));
}
public static readonly DependencyProperty VerticalProperty =
DependencyProperty.RegisterAttached("Vertical", typeof(double), typeof(Spacing),
new UIPropertyMetadata(0d, VerticalChangedCallback));
public static readonly DependencyProperty HorizontalProperty =
DependencyProperty.RegisterAttached("Horizontal", typeof(double), typeof(Spacing),
new UIPropertyMetadata(0d, HorizontalChangedCallback));
return (double) obj.GetValue(HorizontalProperty);
}
public static double GetVertical(DependencyObject obj)
{
return (double) obj.GetValue(VerticalProperty);
}
private static void HorizontalChangedCallback(object sender, DependencyPropertyChangedEventArgs e)
{
var space = (double) e.NewValue;
var obj = (DependencyObject) sender;
MarginSetter.SetMargin(obj, new Thickness(0, 0, space, 0));
MarginSetter.SetLastItemMargin(obj, new Thickness(0));
}
[UsedImplicitly]
public static void SetHorizontal(DependencyObject obj, double space)
{
obj.SetValue(HorizontalProperty, space);
}
[UsedImplicitly]
public static void SetVertical(DependencyObject obj, double value)
{
obj.SetValue(VerticalProperty, value);
}
private static void VerticalChangedCallback(object sender, DependencyPropertyChangedEventArgs e)
{
var space = (double) e.NewValue;
var obj = (DependencyObject) sender;
MarginSetter.SetMargin(obj, new Thickness(0, 0, 0, space));
MarginSetter.SetLastItemMargin(obj, new Thickness(0));
}
public static readonly DependencyProperty VerticalProperty =
DependencyProperty.RegisterAttached("Vertical", typeof(double), typeof(Spacing),
new UIPropertyMetadata(0d, VerticalChangedCallback));
public static readonly DependencyProperty HorizontalProperty =
DependencyProperty.RegisterAttached("Horizontal", typeof(double), typeof(Spacing),
new UIPropertyMetadata(0d, HorizontalChangedCallback));
}

View File

@@ -1,34 +1,33 @@
using System.Collections.Generic;
namespace FeedCenter.Options
{
public class UserAgentItem
{
public string Caption { get; set; }
public string UserAgent { get; set; }
namespace FeedCenter.Options;
public static List<UserAgentItem> UserAgents => new()
public class UserAgentItem
{
public string Caption { get; set; }
public string UserAgent { get; set; }
public static List<UserAgentItem> UserAgents => new()
{
new UserAgentItem
{
new UserAgentItem
{
Caption = Properties.Resources.DefaultUserAgentCaption,
UserAgent = string.Empty
},
new UserAgentItem
{
Caption = "Windows RSS Platform 2.0",
UserAgent = "Windows-RSS-Platform/2.0 (MSIE 9.0; Windows NT 6.1)"
},
new UserAgentItem
{
Caption = "Feedly 1.0",
UserAgent = "Feedly/1.0"
},
new UserAgentItem
{
Caption = "curl",
UserAgent = "curl/7.47.0"
}
};
}
Caption = Properties.Resources.DefaultUserAgentCaption,
UserAgent = string.Empty
},
new UserAgentItem
{
Caption = "Windows RSS Platform 2.0",
UserAgent = "Windows-RSS-Platform/2.0 (MSIE 9.0; Windows NT 6.1)"
},
new UserAgentItem
{
Caption = "Feedly 1.0",
UserAgent = "Feedly/1.0"
},
new UserAgentItem
{
Caption = "curl",
UserAgent = "curl/7.47.0"
}
};
}