mirror of
https://github.com/ckaczor/FeedCenter.git
synced 2026-01-13 17:22:48 -05:00
More cleanup and fixes
This commit is contained in:
@@ -185,6 +185,9 @@ public static class LegacyDatabase
|
|||||||
{
|
{
|
||||||
foreach (var category in categories)
|
foreach (var category in categories)
|
||||||
{
|
{
|
||||||
|
if (category.Name == Category.DefaultName)
|
||||||
|
category.IsDefault = true;
|
||||||
|
|
||||||
category.Feeds = feeds.Where(f => f.CategoryId == category.Id).ToList();
|
category.Feeds = feeds.Where(f => f.CategoryId == category.Id).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,4 +26,4 @@ namespace FeedCenter.Data
|
|||||||
base.OnCollectionChanged(e);
|
base.OnCollectionChanged(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,9 +8,9 @@ namespace FeedCenter
|
|||||||
{
|
{
|
||||||
public class FeedCenterEntities
|
public class FeedCenterEntities
|
||||||
{
|
{
|
||||||
public Realm Realm { get; private set; }
|
public Realm RealmInstance { get; }
|
||||||
|
|
||||||
public RealmObservableCollection<Category> Categories { get; private set; }
|
public RealmObservableCollection<Category> Categories { get; }
|
||||||
public RealmObservableCollection<Feed> Feeds { get; private set; }
|
public RealmObservableCollection<Feed> Feeds { get; private set; }
|
||||||
public RealmObservableCollection<Setting> Settings { get; private set; }
|
public RealmObservableCollection<Setting> Settings { get; private set; }
|
||||||
|
|
||||||
@@ -18,26 +18,31 @@ namespace FeedCenter
|
|||||||
{
|
{
|
||||||
var realmConfiguration = new RealmConfiguration($"{Database.DatabaseFile}");
|
var realmConfiguration = new RealmConfiguration($"{Database.DatabaseFile}");
|
||||||
|
|
||||||
Realm = Realm.GetInstance(realmConfiguration);
|
RealmInstance = Realm.GetInstance(realmConfiguration);
|
||||||
|
|
||||||
Settings = new RealmObservableCollection<Setting>(Realm);
|
Settings = new RealmObservableCollection<Setting>(RealmInstance);
|
||||||
Feeds = new RealmObservableCollection<Feed>(Realm);
|
Feeds = new RealmObservableCollection<Feed>(RealmInstance);
|
||||||
Categories = new RealmObservableCollection<Category>(Realm);
|
Categories = new RealmObservableCollection<Category>(RealmInstance);
|
||||||
|
|
||||||
if (!Categories.Any())
|
if (!Categories.Any())
|
||||||
{
|
{
|
||||||
Realm.Write(() => Categories.Add(Category.CreateDefault()));
|
RealmInstance.Write(() => Categories.Add(Category.CreateDefault()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Refresh()
|
public void Refresh()
|
||||||
{
|
{
|
||||||
Realm.Refresh();
|
RealmInstance.Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SaveChanges(Action action)
|
public void SaveChanges(Action action)
|
||||||
{
|
{
|
||||||
Realm.Write(action);
|
RealmInstance.Write(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Transaction BeginTransaction()
|
||||||
|
{
|
||||||
|
return RealmInstance.BeginWrite();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Category DefaultCategory
|
public Category DefaultCategory
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ namespace FeedCenter
|
|||||||
|
|
||||||
var feedWindow = new FeedWindow();
|
var feedWindow = new FeedWindow();
|
||||||
|
|
||||||
feedWindow.Display(_database, feed, GetWindow(this));
|
feedWindow.Display(feed, GetWindow(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DeleteSelectedFeed()
|
private void DeleteSelectedFeed()
|
||||||
|
|||||||
@@ -1,33 +1,90 @@
|
|||||||
using Realms;
|
using Realms;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace FeedCenter
|
namespace FeedCenter
|
||||||
{
|
{
|
||||||
public class Category : RealmObject
|
public class Category : RealmObject, INotifyDataErrorInfo
|
||||||
{
|
{
|
||||||
private const string DefaultCategoryName = "< default >";
|
public const string DefaultName = "< default >";
|
||||||
|
|
||||||
|
private readonly Dictionary<string, List<string>> _errorsByPropertyName = new();
|
||||||
|
|
||||||
[PrimaryKey]
|
[PrimaryKey]
|
||||||
[MapTo("ID")]
|
public Guid Id { get; set; } = Guid.NewGuid();
|
||||||
public Guid Id { get; set; }
|
|
||||||
public string Name { get; set; }
|
[MapTo("Name")]
|
||||||
|
private string RawName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get => RawName;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
RawName = value;
|
||||||
|
|
||||||
|
ValidateName();
|
||||||
|
RaisePropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Ignored]
|
[Ignored]
|
||||||
public ICollection<Feed> Feeds { get; set; }
|
public ICollection<Feed> Feeds { get; set; }
|
||||||
|
|
||||||
public static Category Create()
|
|
||||||
{
|
|
||||||
return new Category { Id = Guid.NewGuid() };
|
|
||||||
}
|
|
||||||
public static Category CreateDefault()
|
public static Category CreateDefault()
|
||||||
{
|
{
|
||||||
return new Category { Id = Guid.NewGuid(), Name = DefaultCategoryName };
|
return new Category { Name = DefaultName, IsDefault = true };
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsDefault => Name == DefaultCategoryName;
|
public bool IsDefault { get; internal set; }
|
||||||
|
|
||||||
// ReSharper disable once UnusedMember.Global
|
// ReSharper disable once UnusedMember.Global
|
||||||
public int SortKey => IsDefault ? 0 : 1;
|
public int SortKey => IsDefault ? 0 : 1;
|
||||||
|
|
||||||
|
public bool HasErrors => _errorsByPropertyName.Any();
|
||||||
|
|
||||||
|
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
|
||||||
|
|
||||||
|
public IEnumerable GetErrors(string propertyName)
|
||||||
|
{
|
||||||
|
return _errorsByPropertyName.TryGetValue(propertyName, out var value) ? value : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnErrorsChanged(string propertyName)
|
||||||
|
{
|
||||||
|
ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ValidateName()
|
||||||
|
{
|
||||||
|
ClearErrors(nameof(Name));
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(Name))
|
||||||
|
AddError(nameof(Name), "Name cannot be empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddError(string propertyName, string error)
|
||||||
|
{
|
||||||
|
if (!_errorsByPropertyName.ContainsKey(propertyName))
|
||||||
|
_errorsByPropertyName[propertyName] = new List<string>();
|
||||||
|
|
||||||
|
if (_errorsByPropertyName[propertyName].Contains(error))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_errorsByPropertyName[propertyName].Add(error);
|
||||||
|
OnErrorsChanged(propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ClearErrors(string propertyName)
|
||||||
|
{
|
||||||
|
if (!_errorsByPropertyName.ContainsKey(propertyName))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_errorsByPropertyName.Remove(propertyName);
|
||||||
|
OnErrorsChanged(propertyName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using ChrisKaczor.ApplicationUpdate;
|
using ChrisKaczor.ApplicationUpdate;
|
||||||
|
using FeedCenter.Data;
|
||||||
using FeedCenter.FeedParsers;
|
using FeedCenter.FeedParsers;
|
||||||
using FeedCenter.Properties;
|
using FeedCenter.Properties;
|
||||||
using FeedCenter.Xml;
|
using FeedCenter.Xml;
|
||||||
@@ -118,9 +119,9 @@ namespace FeedCenter
|
|||||||
|
|
||||||
private static HttpClient _httpClient;
|
private static HttpClient _httpClient;
|
||||||
|
|
||||||
public static Feed Create(FeedCenterEntities database)
|
public static Feed Create()
|
||||||
{
|
{
|
||||||
return new Feed { Id = Guid.NewGuid(), CategoryId = database.DefaultCategory.Id };
|
return new Feed { Id = Guid.NewGuid(), CategoryId = Database.Entities.DefaultCategory.Id };
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Reading
|
#region Reading
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace FeedCenter
|
|||||||
private void HandleNewFeed(string feedUrl)
|
private void HandleNewFeed(string feedUrl)
|
||||||
{
|
{
|
||||||
// Create and configure the new feed
|
// Create and configure the new feed
|
||||||
var feed = Feed.Create(_database);
|
var feed = Feed.Create();
|
||||||
feed.Source = feedUrl;
|
feed.Source = feedUrl;
|
||||||
feed.Category = _database.DefaultCategory;
|
feed.Category = _database.DefaultCategory;
|
||||||
|
|
||||||
@@ -85,7 +85,7 @@ namespace FeedCenter
|
|||||||
// Feed read failed - create a new feed window
|
// Feed read failed - create a new feed window
|
||||||
var feedForm = new FeedWindow();
|
var feedForm = new FeedWindow();
|
||||||
|
|
||||||
var dialogResult = feedForm.Display(_database, feed, this);
|
var dialogResult = feedForm.Display(feed, this);
|
||||||
|
|
||||||
// Display the new feed form
|
// Display the new feed form
|
||||||
if (dialogResult.HasValue && dialogResult.Value)
|
if (dialogResult.HasValue && dialogResult.Value)
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ namespace FeedCenter
|
|||||||
var feedWindow = new FeedWindow();
|
var feedWindow = new FeedWindow();
|
||||||
|
|
||||||
// Display the feed window and get the result
|
// Display the feed window and get the result
|
||||||
var result = feedWindow.Display(_database, _currentFeed, this);
|
var result = feedWindow.Display(_currentFeed, this);
|
||||||
|
|
||||||
// If OK was clicked...
|
// If OK was clicked...
|
||||||
if (result.HasValue && result.Value)
|
if (result.HasValue && result.Value)
|
||||||
|
|||||||
@@ -1,36 +1,26 @@
|
|||||||
using ChrisKaczor.ApplicationUpdate;
|
using ChrisKaczor.ApplicationUpdate;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace FeedCenter.Options
|
namespace FeedCenter.Options;
|
||||||
|
|
||||||
|
public partial class AboutOptionsPanel
|
||||||
{
|
{
|
||||||
public partial class AboutOptionsPanel
|
public AboutOptionsPanel()
|
||||||
{
|
{
|
||||||
public AboutOptionsPanel()
|
InitializeComponent();
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void LoadPanel(FeedCenterEntities database)
|
|
||||||
{
|
|
||||||
base.LoadPanel(database);
|
|
||||||
|
|
||||||
ApplicationNameLabel.Text = Properties.Resources.ApplicationDisplayName;
|
|
||||||
|
|
||||||
var version = UpdateCheck.LocalVersion.ToString();
|
|
||||||
VersionLabel.Text = string.Format(Properties.Resources.Version, version);
|
|
||||||
|
|
||||||
CompanyLabel.Text = ((AssemblyCompanyAttribute) Assembly.GetEntryAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false)[0]).Company;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool ValidatePanel()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SavePanel()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string CategoryName => Properties.Resources.optionCategoryAbout;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void LoadPanel()
|
||||||
|
{
|
||||||
|
base.LoadPanel();
|
||||||
|
|
||||||
|
ApplicationNameLabel.Text = Properties.Resources.ApplicationDisplayName;
|
||||||
|
|
||||||
|
var version = UpdateCheck.LocalVersion.ToString();
|
||||||
|
VersionLabel.Text = string.Format(Properties.Resources.Version, version);
|
||||||
|
|
||||||
|
CompanyLabel.Text = ((AssemblyCompanyAttribute) Assembly.GetEntryAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false)[0]).Company;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string CategoryName => Properties.Resources.optionCategoryAbout;
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,7 @@ using System.Linq;
|
|||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Data;
|
using System.Windows.Data;
|
||||||
|
using FeedCenter.Data;
|
||||||
|
|
||||||
namespace FeedCenter.Options
|
namespace FeedCenter.Options
|
||||||
{
|
{
|
||||||
@@ -17,11 +18,11 @@ namespace FeedCenter.Options
|
|||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Display(Window window, FeedCenterEntities database)
|
public void Display(Window window)
|
||||||
{
|
{
|
||||||
_checkedListBoxItems = new List<CheckedListItem<Feed>>();
|
_checkedListBoxItems = new List<CheckedListItem<Feed>>();
|
||||||
|
|
||||||
foreach (var feed in database.Feeds)
|
foreach (var feed in Database.Entities.Feeds)
|
||||||
_checkedListBoxItems.Add(new CheckedListItem<Feed> { Item = feed });
|
_checkedListBoxItems.Add(new CheckedListItem<Feed> { Item = feed });
|
||||||
|
|
||||||
_collectionViewSource = new CollectionViewSource { Source = _checkedListBoxItems };
|
_collectionViewSource = new CollectionViewSource { Source = _checkedListBoxItems };
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:validation="clr-namespace:ChrisKaczor.Wpf.Validation;assembly=ChrisKaczor.Wpf.Validation"
|
|
||||||
xmlns:controls="clr-namespace:ChrisKaczor.Wpf.Windows;assembly=ChrisKaczor.Wpf.Windows.ControlBox"
|
xmlns:controls="clr-namespace:ChrisKaczor.Wpf.Windows;assembly=ChrisKaczor.Wpf.Windows.ControlBox"
|
||||||
d:DataContext="{d:DesignInstance Type=feedCenter:Category}"
|
d:DataContext="{d:DesignInstance Type=feedCenter:Category}"
|
||||||
Title="CategoryWindow"
|
Title="CategoryWindow"
|
||||||
@@ -18,40 +17,31 @@
|
|||||||
FocusManager.FocusedElement="{Binding ElementName=NameTextBox}"
|
FocusManager.FocusedElement="{Binding ElementName=NameTextBox}"
|
||||||
controls:ControlBox.HasMinimizeButton="False"
|
controls:ControlBox.HasMinimizeButton="False"
|
||||||
controls:ControlBox.HasMaximizeButton="False">
|
controls:ControlBox.HasMaximizeButton="False">
|
||||||
<Grid Margin="8">
|
<Grid Margin="6,3,6,6">
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="Auto" />
|
<RowDefinition Height="Auto" />
|
||||||
<RowDefinition Height="*" />
|
<RowDefinition Height="*" />
|
||||||
<RowDefinition Height="Auto" />
|
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="Auto" />
|
|
||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="*" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<Label Content="{x:Static properties:Resources.feedCategoryLabel}"
|
<StackPanel
|
||||||
HorizontalAlignment="Left"
|
Grid.Row="0"
|
||||||
Grid.Column="0"
|
Grid.Column="0">
|
||||||
Grid.Row="0"
|
<Label Content="{x:Static properties:Resources.categoryNameLabel}"
|
||||||
Target="{Binding ElementName=NameTextBox}"
|
Padding="0"
|
||||||
VerticalAlignment="Center"
|
Margin="0,0,0,1"
|
||||||
VerticalContentAlignment="Center" />
|
Target="{Binding ElementName=NameTextBox}" />
|
||||||
<TextBox Name="NameTextBox"
|
<TextBox Name="NameTextBox"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Grid.Row="0"
|
Text="{Binding Path=Name, UpdateSourceTrigger=PropertyChanged, ValidatesOnExceptions=True}">
|
||||||
Grid.Column="1">
|
</TextBox>
|
||||||
<TextBox.Text>
|
</StackPanel>
|
||||||
<Binding Path="Name" UpdateSourceTrigger="Explicit" ValidatesOnExceptions="True">
|
|
||||||
<Binding.ValidationRules>
|
|
||||||
<validation:RequiredValidationRule></validation:RequiredValidationRule>
|
|
||||||
</Binding.ValidationRules>
|
|
||||||
</Binding>
|
|
||||||
</TextBox.Text>
|
|
||||||
</TextBox>
|
|
||||||
<StackPanel
|
<StackPanel
|
||||||
Grid.Column="1"
|
Grid.Column="0"
|
||||||
Grid.Row="2"
|
Grid.Row="1"
|
||||||
Orientation="Horizontal"
|
Orientation="Horizontal"
|
||||||
Margin="0,4,0,0"
|
Margin="0,5,0,0"
|
||||||
HorizontalAlignment="Right">
|
HorizontalAlignment="Right">
|
||||||
<Button Content="{x:Static properties:Resources.OkayButton}"
|
<Button Content="{x:Static properties:Resources.OkayButton}"
|
||||||
Height="23"
|
Height="23"
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using ChrisKaczor.Wpf.Validation;
|
using ChrisKaczor.Wpf.Validation;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using FeedCenter.Data;
|
||||||
|
|
||||||
namespace FeedCenter.Options
|
namespace FeedCenter.Options
|
||||||
{
|
{
|
||||||
@@ -29,8 +30,16 @@ namespace FeedCenter.Options
|
|||||||
|
|
||||||
private void HandleOkayButtonClick(object sender, RoutedEventArgs e)
|
private void HandleOkayButtonClick(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
|
var transaction = Database.Entities.BeginTransaction();
|
||||||
|
|
||||||
if (!this.IsValid())
|
if (!this.IsValid())
|
||||||
|
{
|
||||||
|
transaction.Rollback();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
transaction.Commit();
|
||||||
|
Database.Entities.Refresh();
|
||||||
|
|
||||||
// Dialog is good
|
// Dialog is good
|
||||||
DialogResult = true;
|
DialogResult = true;
|
||||||
|
|||||||
@@ -19,7 +19,8 @@
|
|||||||
Name="LockWindowCheckBox"
|
Name="LockWindowCheckBox"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Top"
|
||||||
Width="300"
|
Width="300"
|
||||||
Grid.ColumnSpan="2" />
|
Grid.ColumnSpan="2"
|
||||||
|
Click="LockWindowCheckBox_Click" />
|
||||||
<CheckBox Content="{x:Static properties:Resources.displayEmptyFeedsCheckBox}"
|
<CheckBox Content="{x:Static properties:Resources.displayEmptyFeedsCheckBox}"
|
||||||
Height="16"
|
Height="16"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
@@ -28,7 +29,8 @@
|
|||||||
VerticalAlignment="Top"
|
VerticalAlignment="Top"
|
||||||
Width="300"
|
Width="300"
|
||||||
Grid.ColumnSpan="2"
|
Grid.ColumnSpan="2"
|
||||||
Grid.Column="0" />
|
Grid.Column="0"
|
||||||
|
Click="DisplayEmptyFeedsCheckBox_Click" />
|
||||||
<Label Grid.Column="0"
|
<Label Grid.Column="0"
|
||||||
Content="{x:Static properties:Resources.toolbarLocationLabel}"
|
Content="{x:Static properties:Resources.toolbarLocationLabel}"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Top"
|
||||||
@@ -39,7 +41,8 @@
|
|||||||
<ComboBox Margin="8,53,0,0"
|
<ComboBox Margin="8,53,0,0"
|
||||||
Name="ToolbarLocationComboBox"
|
Name="ToolbarLocationComboBox"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Top"
|
||||||
Grid.Column="1">
|
Grid.Column="1"
|
||||||
|
SelectionChanged="ToolbarLocationComboBox_SelectionChanged">
|
||||||
<ComboBoxItem Content="{x:Static properties:Resources.Top}"
|
<ComboBoxItem Content="{x:Static properties:Resources.Top}"
|
||||||
Tag="{x:Static Dock.Top}" />
|
Tag="{x:Static Dock.Top}" />
|
||||||
<ComboBoxItem Content="{x:Static properties:Resources.Bottom}"
|
<ComboBoxItem Content="{x:Static properties:Resources.Bottom}"
|
||||||
@@ -55,7 +58,8 @@
|
|||||||
<ComboBox Margin="8,86,0,0"
|
<ComboBox Margin="8,86,0,0"
|
||||||
Name="MultipleLineDisplayComboBox"
|
Name="MultipleLineDisplayComboBox"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Top"
|
||||||
Grid.Column="1">
|
Grid.Column="1"
|
||||||
|
SelectionChanged="MultipleLineDisplayComboBox_SelectionChanged">
|
||||||
<ComboBoxItem Content="{x:Static properties:Resources.multipleLineDisplayNormal}"
|
<ComboBoxItem Content="{x:Static properties:Resources.multipleLineDisplayNormal}"
|
||||||
Tag="{x:Static options:MultipleLineDisplay.Normal}" />
|
Tag="{x:Static options:MultipleLineDisplay.Normal}" />
|
||||||
<ComboBoxItem Content="{x:Static properties:Resources.multipleLineDisplaySingleLine}"
|
<ComboBoxItem Content="{x:Static properties:Resources.multipleLineDisplaySingleLine}"
|
||||||
@@ -64,4 +68,4 @@
|
|||||||
Tag="{x:Static options:MultipleLineDisplay.FirstLine}" />
|
Tag="{x:Static options:MultipleLineDisplay.FirstLine}" />
|
||||||
</ComboBox>
|
</ComboBox>
|
||||||
</Grid>
|
</Grid>
|
||||||
</options:OptionsPanelBase>
|
</options:OptionsPanelBase>
|
||||||
@@ -2,45 +2,58 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
|
||||||
namespace FeedCenter.Options
|
namespace FeedCenter.Options;
|
||||||
|
|
||||||
|
public partial class DisplayOptionsPanel
|
||||||
{
|
{
|
||||||
public partial class DisplayOptionsPanel
|
public DisplayOptionsPanel()
|
||||||
{
|
{
|
||||||
public DisplayOptionsPanel()
|
InitializeComponent();
|
||||||
{
|
|
||||||
InitializeComponent();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void LoadPanel(FeedCenterEntities database)
|
|
||||||
{
|
|
||||||
base.LoadPanel(database);
|
|
||||||
|
|
||||||
LockWindowCheckBox.IsChecked = Settings.Default.WindowLocked;
|
|
||||||
DisplayEmptyFeedsCheckBox.IsChecked = Settings.Default.DisplayEmptyFeeds;
|
|
||||||
ToolbarLocationComboBox.SelectedItem = ToolbarLocationComboBox.Items.Cast<ComboBoxItem>().First(comboBoxItem => (Dock) comboBoxItem.Tag == Settings.Default.ToolbarLocation);
|
|
||||||
MultipleLineDisplayComboBox.SelectedItem = MultipleLineDisplayComboBox.Items.Cast<ComboBoxItem>().First(comboBoxItem => (MultipleLineDisplay) comboBoxItem.Tag == Settings.Default.MultipleLineDisplay);
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool ValidatePanel()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SavePanel()
|
|
||||||
{
|
|
||||||
if (LockWindowCheckBox.IsChecked.HasValue && Settings.Default.WindowLocked != LockWindowCheckBox.IsChecked.Value)
|
|
||||||
Settings.Default.WindowLocked = LockWindowCheckBox.IsChecked.Value;
|
|
||||||
|
|
||||||
if (DisplayEmptyFeedsCheckBox.IsChecked.HasValue && Settings.Default.DisplayEmptyFeeds != DisplayEmptyFeedsCheckBox.IsChecked.Value)
|
|
||||||
Settings.Default.DisplayEmptyFeeds = DisplayEmptyFeedsCheckBox.IsChecked.Value;
|
|
||||||
|
|
||||||
var dock = (Dock) ((ComboBoxItem) ToolbarLocationComboBox.SelectedItem).Tag;
|
|
||||||
Settings.Default.ToolbarLocation = dock;
|
|
||||||
|
|
||||||
var multipleLineDisplay = (MultipleLineDisplay) ((ComboBoxItem) MultipleLineDisplayComboBox.SelectedItem).Tag;
|
|
||||||
Settings.Default.MultipleLineDisplay = multipleLineDisplay;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string CategoryName => Properties.Resources.optionCategoryDisplay;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public override void LoadPanel()
|
||||||
|
{
|
||||||
|
base.LoadPanel();
|
||||||
|
|
||||||
|
LockWindowCheckBox.IsChecked = Settings.Default.WindowLocked;
|
||||||
|
DisplayEmptyFeedsCheckBox.IsChecked = Settings.Default.DisplayEmptyFeeds;
|
||||||
|
ToolbarLocationComboBox.SelectedItem = ToolbarLocationComboBox.Items.Cast<ComboBoxItem>().First(comboBoxItem => (Dock) comboBoxItem.Tag == Settings.Default.ToolbarLocation);
|
||||||
|
MultipleLineDisplayComboBox.SelectedItem = MultipleLineDisplayComboBox.Items.Cast<ComboBoxItem>().First(comboBoxItem => (MultipleLineDisplay) comboBoxItem.Tag == Settings.Default.MultipleLineDisplay);
|
||||||
|
|
||||||
|
MarkLoaded();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string CategoryName => Properties.Resources.optionCategoryDisplay;
|
||||||
|
|
||||||
|
private void LockWindowCheckBox_Click(object sender, System.Windows.RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (!HasLoaded) return;
|
||||||
|
|
||||||
|
if (LockWindowCheckBox.IsChecked.HasValue && Settings.Default.WindowLocked != LockWindowCheckBox.IsChecked.Value)
|
||||||
|
Settings.Default.WindowLocked = LockWindowCheckBox.IsChecked.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DisplayEmptyFeedsCheckBox_Click(object sender, System.Windows.RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
if (!HasLoaded) return;
|
||||||
|
|
||||||
|
if (DisplayEmptyFeedsCheckBox.IsChecked.HasValue && Settings.Default.DisplayEmptyFeeds != DisplayEmptyFeedsCheckBox.IsChecked.Value)
|
||||||
|
Settings.Default.DisplayEmptyFeeds = DisplayEmptyFeedsCheckBox.IsChecked.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ToolbarLocationComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (!HasLoaded) return;
|
||||||
|
|
||||||
|
var dock = (Dock) ((ComboBoxItem) ToolbarLocationComboBox.SelectedItem).Tag;
|
||||||
|
Settings.Default.ToolbarLocation = dock;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MultipleLineDisplayComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (!HasLoaded) return;
|
||||||
|
|
||||||
|
var multipleLineDisplay = (MultipleLineDisplay) ((ComboBoxItem) MultipleLineDisplayComboBox.SelectedItem).Tag;
|
||||||
|
Settings.Default.MultipleLineDisplay = multipleLineDisplay;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using ChrisKaczor.Wpf.Validation;
|
using ChrisKaczor.Wpf.Validation;
|
||||||
|
using FeedCenter.Data;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
@@ -14,10 +15,10 @@ namespace FeedCenter.Options
|
|||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool? Display(FeedCenterEntities database, Feed feed, Window owner)
|
public bool? Display(Feed feed, Window owner)
|
||||||
{
|
{
|
||||||
// Bind the category combo box
|
// Bind the category combo box
|
||||||
CategoryComboBox.ItemsSource = database.Categories;
|
CategoryComboBox.ItemsSource = Database.Entities.Categories;
|
||||||
|
|
||||||
// Set the data context
|
// Set the data context
|
||||||
DataContext = feed;
|
DataContext = feed;
|
||||||
@@ -85,4 +86,4 @@ namespace FeedCenter.Options
|
|||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
xmlns:options="clr-namespace:FeedCenter.Options"
|
xmlns:options="clr-namespace:FeedCenter.Options"
|
||||||
xmlns:properties="clr-namespace:FeedCenter.Properties"
|
xmlns:properties="clr-namespace:FeedCenter.Properties"
|
||||||
xmlns:controls="clr-namespace:ChrisKaczor.Wpf.Controls;assembly=ChrisKaczor.Wpf.Controls.Link"
|
xmlns:controls="clr-namespace:ChrisKaczor.Wpf.Controls;assembly=ChrisKaczor.Wpf.Controls.Link"
|
||||||
|
xmlns:feedCenter="clr-namespace:FeedCenter"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DesignHeight="311"
|
d:DesignHeight="311"
|
||||||
d:DesignWidth="425">
|
d:DesignWidth="425">
|
||||||
@@ -65,7 +66,8 @@
|
|||||||
IsReadOnly="True"
|
IsReadOnly="True"
|
||||||
HeadersVisibility="Column"
|
HeadersVisibility="Column"
|
||||||
AllowDrop="True"
|
AllowDrop="True"
|
||||||
Background="{x:Null}">
|
Background="{x:Null}"
|
||||||
|
d:DataContext="{d:DesignInstance Type=feedCenter:Category }">
|
||||||
<DataGrid.Columns>
|
<DataGrid.Columns>
|
||||||
<DataGridTextColumn Binding="{Binding Name}"
|
<DataGridTextColumn Binding="{Binding Name}"
|
||||||
Header="{x:Static properties:Resources.CategoryNameColumnHeader}"
|
Header="{x:Static properties:Resources.CategoryNameColumnHeader}"
|
||||||
@@ -75,11 +77,13 @@
|
|||||||
<DataGrid.ItemContainerStyle>
|
<DataGrid.ItemContainerStyle>
|
||||||
<Style TargetType="DataGridRow">
|
<Style TargetType="DataGridRow">
|
||||||
<EventSetter Event="Drop"
|
<EventSetter Event="Drop"
|
||||||
Handler="HandleTextBlockDrop" />
|
Handler="CategoryListBox_Drop" />
|
||||||
<EventSetter Event="DragEnter"
|
<EventSetter Event="DragEnter"
|
||||||
Handler="HandleTextBlockDragEnter" />
|
Handler="CategoryListBox_DragEnter" />
|
||||||
<EventSetter Event="DragLeave"
|
<EventSetter Event="DragLeave"
|
||||||
Handler="HandleTextBlockDragLeave" />
|
Handler="CategoryListBox_DragLeave" />
|
||||||
|
<EventSetter Event="MouseDoubleClick"
|
||||||
|
Handler="CategoryListBox_MouseDoubleClick" />
|
||||||
</Style>
|
</Style>
|
||||||
</DataGrid.ItemContainerStyle>
|
</DataGrid.ItemContainerStyle>
|
||||||
<DataGrid.CellStyle>
|
<DataGrid.CellStyle>
|
||||||
|
|||||||
@@ -7,58 +7,42 @@ using System.Windows.Controls;
|
|||||||
using System.Windows.Data;
|
using System.Windows.Data;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
|
using FeedCenter.Data;
|
||||||
|
|
||||||
namespace FeedCenter.Options
|
namespace FeedCenter.Options
|
||||||
{
|
{
|
||||||
public partial class FeedsOptionsPanel
|
public partial class FeedsOptionsPanel
|
||||||
{
|
{
|
||||||
#region Constructor
|
|
||||||
|
|
||||||
public FeedsOptionsPanel()
|
public FeedsOptionsPanel()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
public override void LoadPanel()
|
||||||
|
|
||||||
#region OptionsPanelBase overrides
|
|
||||||
|
|
||||||
public override void LoadPanel(FeedCenterEntities database)
|
|
||||||
{
|
{
|
||||||
base.LoadPanel(database);
|
base.LoadPanel();
|
||||||
|
|
||||||
var collectionViewSource = new CollectionViewSource { Source = Database.Categories };
|
var collectionViewSource = new CollectionViewSource { Source = Database.Entities.Categories };
|
||||||
collectionViewSource.SortDescriptions.Add(new SortDescription("SortKey", ListSortDirection.Ascending));
|
collectionViewSource.SortDescriptions.Add(new SortDescription("SortKey", ListSortDirection.Ascending));
|
||||||
collectionViewSource.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
|
collectionViewSource.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
|
||||||
|
collectionViewSource.IsLiveSortingRequested = true;
|
||||||
|
|
||||||
CategoryListBox.ItemsSource = collectionViewSource.View;
|
CategoryListBox.ItemsSource = collectionViewSource.View;
|
||||||
CategoryListBox.SelectedIndex = 0;
|
CategoryListBox.SelectedIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool ValidatePanel()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SavePanel()
|
|
||||||
{ }
|
|
||||||
|
|
||||||
public override string CategoryName => Properties.Resources.optionCategoryFeeds;
|
public override string CategoryName => Properties.Resources.optionCategoryFeeds;
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Feed list management
|
|
||||||
|
|
||||||
private void SetFeedButtonStates()
|
private void SetFeedButtonStates()
|
||||||
{
|
{
|
||||||
AddFeedButton.IsEnabled = true;
|
AddFeedButton.IsEnabled = true;
|
||||||
EditFeedButton.IsEnabled = (FeedListBox.SelectedItem != null);
|
EditFeedButton.IsEnabled = FeedListBox.SelectedItem != null;
|
||||||
DeleteFeedButton.IsEnabled = (FeedListBox.SelectedItem != null);
|
DeleteFeedButton.IsEnabled = FeedListBox.SelectedItem != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddFeed()
|
private void AddFeed()
|
||||||
{
|
{
|
||||||
var feed = Feed.Create(Database);
|
var feed = Feed.Create();
|
||||||
|
|
||||||
var category = (Category) CategoryListBox.SelectedItem;
|
var category = (Category) CategoryListBox.SelectedItem;
|
||||||
|
|
||||||
@@ -66,16 +50,16 @@ namespace FeedCenter.Options
|
|||||||
|
|
||||||
var feedWindow = new FeedWindow();
|
var feedWindow = new FeedWindow();
|
||||||
|
|
||||||
var result = feedWindow.Display(Database, feed, Window.GetWindow(this));
|
var result = feedWindow.Display(feed, Window.GetWindow(this));
|
||||||
|
|
||||||
if (result.HasValue && result.Value)
|
if (!result.HasValue || !result.Value)
|
||||||
{
|
return;
|
||||||
Database.Feeds.Add(feed);
|
|
||||||
|
|
||||||
FeedListBox.SelectedItem = feed;
|
Database.Entities.Feeds.Add(feed);
|
||||||
|
|
||||||
SetFeedButtonStates();
|
FeedListBox.SelectedItem = feed;
|
||||||
}
|
|
||||||
|
SetFeedButtonStates();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EditSelectedFeed()
|
private void EditSelectedFeed()
|
||||||
@@ -87,22 +71,18 @@ namespace FeedCenter.Options
|
|||||||
|
|
||||||
var feedWindow = new FeedWindow();
|
var feedWindow = new FeedWindow();
|
||||||
|
|
||||||
feedWindow.Display(Database, feed, Window.GetWindow(this));
|
feedWindow.Display(feed, Window.GetWindow(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DeleteSelectedFeed()
|
private void DeleteSelectedFeed()
|
||||||
{
|
{
|
||||||
var feed = (Feed) FeedListBox.SelectedItem;
|
var feed = (Feed) FeedListBox.SelectedItem;
|
||||||
|
|
||||||
Database.Feeds.Remove(feed);
|
Database.Entities.Feeds.Remove(feed);
|
||||||
|
|
||||||
SetFeedButtonStates();
|
SetFeedButtonStates();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Feed event handlers
|
|
||||||
|
|
||||||
private void HandleAddFeedButtonClick(object sender, RoutedEventArgs e)
|
private void HandleAddFeedButtonClick(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
AddFeed();
|
AddFeed();
|
||||||
@@ -128,15 +108,11 @@ namespace FeedCenter.Options
|
|||||||
ExportFeeds();
|
ExportFeeds();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
private static void ExportFeeds()
|
||||||
|
|
||||||
#region Feed import and export
|
|
||||||
|
|
||||||
private void ExportFeeds()
|
|
||||||
{
|
{
|
||||||
// Setup the save file dialog
|
|
||||||
var saveFileDialog = new SaveFileDialog
|
var saveFileDialog = new SaveFileDialog
|
||||||
{
|
{
|
||||||
|
FileName = Properties.Resources.ApplicationName,
|
||||||
Filter = Properties.Resources.ImportExportFilter,
|
Filter = Properties.Resources.ImportExportFilter,
|
||||||
FilterIndex = 0,
|
FilterIndex = 0,
|
||||||
OverwritePrompt = true
|
OverwritePrompt = true
|
||||||
@@ -147,7 +123,6 @@ namespace FeedCenter.Options
|
|||||||
if (!result.GetValueOrDefault(false))
|
if (!result.GetValueOrDefault(false))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Setup the writer settings
|
|
||||||
var writerSettings = new XmlWriterSettings
|
var writerSettings = new XmlWriterSettings
|
||||||
{
|
{
|
||||||
Indent = true,
|
Indent = true,
|
||||||
@@ -155,48 +130,32 @@ namespace FeedCenter.Options
|
|||||||
ConformanceLevel = ConformanceLevel.Document
|
ConformanceLevel = ConformanceLevel.Document
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create an XML writer for the file chosen
|
|
||||||
var xmlWriter = XmlWriter.Create(saveFileDialog.FileName, writerSettings);
|
var xmlWriter = XmlWriter.Create(saveFileDialog.FileName, writerSettings);
|
||||||
|
|
||||||
// Start the opml element
|
|
||||||
xmlWriter.WriteStartElement("opml");
|
xmlWriter.WriteStartElement("opml");
|
||||||
|
|
||||||
// Start the body element
|
|
||||||
xmlWriter.WriteStartElement("body");
|
xmlWriter.WriteStartElement("body");
|
||||||
|
|
||||||
// Loop over each feed
|
foreach (var feed in Database.Entities.Feeds.OrderBy(feed => feed.Name))
|
||||||
foreach (var feed in Database.Feeds.OrderBy(feed => feed.Name))
|
|
||||||
{
|
{
|
||||||
// Start the outline element
|
|
||||||
xmlWriter.WriteStartElement("outline");
|
xmlWriter.WriteStartElement("outline");
|
||||||
|
|
||||||
// Write the title
|
|
||||||
xmlWriter.WriteAttributeString("title", feed.Title);
|
xmlWriter.WriteAttributeString("title", feed.Title);
|
||||||
|
|
||||||
// Write the HTML link
|
|
||||||
xmlWriter.WriteAttributeString("htmlUrl", feed.Link);
|
xmlWriter.WriteAttributeString("htmlUrl", feed.Link);
|
||||||
|
|
||||||
// Write the XML link
|
|
||||||
xmlWriter.WriteAttributeString("xmlUrl", feed.Source);
|
xmlWriter.WriteAttributeString("xmlUrl", feed.Source);
|
||||||
|
|
||||||
// End the outline element
|
|
||||||
xmlWriter.WriteEndElement();
|
xmlWriter.WriteEndElement();
|
||||||
}
|
}
|
||||||
|
|
||||||
// End the body element
|
|
||||||
xmlWriter.WriteEndElement();
|
xmlWriter.WriteEndElement();
|
||||||
|
|
||||||
// End the opml element
|
|
||||||
xmlWriter.WriteEndElement();
|
xmlWriter.WriteEndElement();
|
||||||
|
|
||||||
// Flush and close the writer
|
|
||||||
xmlWriter.Flush();
|
xmlWriter.Flush();
|
||||||
xmlWriter.Close();
|
xmlWriter.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ImportFeeds()
|
private static void ImportFeeds()
|
||||||
{
|
{
|
||||||
// Setup the open file dialog
|
|
||||||
var openFileDialog = new OpenFileDialog
|
var openFileDialog = new OpenFileDialog
|
||||||
{
|
{
|
||||||
Filter = Properties.Resources.ImportExportFilter,
|
Filter = Properties.Resources.ImportExportFilter,
|
||||||
@@ -208,44 +167,36 @@ namespace FeedCenter.Options
|
|||||||
if (!result.GetValueOrDefault(false))
|
if (!result.GetValueOrDefault(false))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Setup the reader settings
|
|
||||||
var xmlReaderSettings = new XmlReaderSettings { IgnoreWhitespace = true };
|
var xmlReaderSettings = new XmlReaderSettings { IgnoreWhitespace = true };
|
||||||
|
|
||||||
// Create an XML reader for the file chosen
|
|
||||||
var xmlReader = XmlReader.Create(openFileDialog.FileName, xmlReaderSettings);
|
var xmlReader = XmlReader.Create(openFileDialog.FileName, xmlReaderSettings);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Read the first node
|
|
||||||
xmlReader.Read();
|
xmlReader.Read();
|
||||||
|
|
||||||
// Read the OPML node
|
|
||||||
xmlReader.ReadStartElement("opml");
|
xmlReader.ReadStartElement("opml");
|
||||||
|
|
||||||
// Read the body node
|
|
||||||
xmlReader.ReadStartElement("body");
|
xmlReader.ReadStartElement("body");
|
||||||
|
|
||||||
// Read all outline nodes
|
|
||||||
while (xmlReader.NodeType != XmlNodeType.EndElement)
|
while (xmlReader.NodeType != XmlNodeType.EndElement)
|
||||||
{
|
{
|
||||||
// Create a new feed
|
var feed = Feed.Create();
|
||||||
var feed = Feed.Create(Database);
|
feed.Category = Database.Entities.Categories.First(c => c.IsDefault);
|
||||||
feed.Category = Database.Categories.First(c => c.IsDefault);
|
|
||||||
|
|
||||||
// Loop over all attributes
|
|
||||||
while (xmlReader.MoveToNextAttribute())
|
while (xmlReader.MoveToNextAttribute())
|
||||||
{
|
{
|
||||||
// Handle the attibute
|
|
||||||
switch (xmlReader.Name.ToLower())
|
switch (xmlReader.Name.ToLower())
|
||||||
{
|
{
|
||||||
case "title":
|
case "title":
|
||||||
feed.Title = xmlReader.Value;
|
feed.Title = xmlReader.Value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// ReSharper disable once StringLiteralTypo
|
||||||
case "htmlurl":
|
case "htmlurl":
|
||||||
feed.Link = xmlReader.Value;
|
feed.Link = xmlReader.Value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// ReSharper disable once StringLiteralTypo
|
||||||
case "xmlurl":
|
case "xmlurl":
|
||||||
feed.Source = xmlReader.Value;
|
feed.Source = xmlReader.Value;
|
||||||
break;
|
break;
|
||||||
@@ -256,24 +207,18 @@ namespace FeedCenter.Options
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fill in defaults for optional fields
|
|
||||||
if (string.IsNullOrEmpty(feed.Name))
|
if (string.IsNullOrEmpty(feed.Name))
|
||||||
feed.Name = feed.Title;
|
feed.Name = feed.Title;
|
||||||
|
|
||||||
// Add the feed to the main list
|
Database.Entities.Feeds.Add(feed);
|
||||||
Database.Feeds.Add(feed);
|
|
||||||
|
|
||||||
// Move back to the element node
|
|
||||||
xmlReader.MoveToElement();
|
xmlReader.MoveToElement();
|
||||||
|
|
||||||
// Skip to the next node
|
|
||||||
xmlReader.Skip();
|
xmlReader.Skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
// End the body node
|
|
||||||
xmlReader.ReadEndElement();
|
xmlReader.ReadEndElement();
|
||||||
|
|
||||||
// End the OPML node
|
|
||||||
xmlReader.ReadEndElement();
|
xmlReader.ReadEndElement();
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@@ -282,33 +227,32 @@ namespace FeedCenter.Options
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Category list management
|
|
||||||
|
|
||||||
private void SetCategoryButtonStates()
|
private void SetCategoryButtonStates()
|
||||||
{
|
{
|
||||||
AddCategoryButton.IsEnabled = true;
|
AddCategoryButton.IsEnabled = true;
|
||||||
EditCategoryButton.IsEnabled = (CategoryListBox.SelectedItem != null && CategoryListBox.SelectedItem != Database.DefaultCategory);
|
|
||||||
DeleteCategoryButton.IsEnabled = (CategoryListBox.SelectedItem != null && CategoryListBox.SelectedItem != Database.DefaultCategory);
|
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()
|
private void AddCategory()
|
||||||
{
|
{
|
||||||
var category = Category.Create();
|
var category = new Category();
|
||||||
|
|
||||||
var categoryWindow = new CategoryWindow();
|
var categoryWindow = new CategoryWindow();
|
||||||
|
|
||||||
var result = categoryWindow.Display(category, Window.GetWindow(this));
|
var result = categoryWindow.Display(category, Window.GetWindow(this));
|
||||||
|
|
||||||
if (result.HasValue && result.Value)
|
if (!result.HasValue || !result.Value)
|
||||||
{
|
return;
|
||||||
Database.SaveChanges(() => Database.Categories.Add(category));
|
|
||||||
|
|
||||||
CategoryListBox.SelectedItem = category;
|
Database.Entities.SaveChanges(() => Database.Entities.Categories.Add(category));
|
||||||
|
|
||||||
SetCategoryButtonStates();
|
CategoryListBox.SelectedItem = category;
|
||||||
}
|
|
||||||
|
SetCategoryButtonStates();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EditSelectedCategory()
|
private void EditSelectedCategory()
|
||||||
@@ -325,7 +269,7 @@ namespace FeedCenter.Options
|
|||||||
|
|
||||||
private void DeleteSelectedCategory()
|
private void DeleteSelectedCategory()
|
||||||
{
|
{
|
||||||
var defaultCategory = Database.DefaultCategory;
|
var defaultCategory = Database.Entities.DefaultCategory;
|
||||||
|
|
||||||
var category = (Category) CategoryListBox.SelectedItem;
|
var category = (Category) CategoryListBox.SelectedItem;
|
||||||
|
|
||||||
@@ -338,15 +282,11 @@ namespace FeedCenter.Options
|
|||||||
else
|
else
|
||||||
CategoryListBox.SelectedIndex = index + 1;
|
CategoryListBox.SelectedIndex = index + 1;
|
||||||
|
|
||||||
Database.SaveChanges(() => Database.Categories.Remove(category));
|
Database.Entities.SaveChanges(() => Database.Entities.Categories.Remove(category));
|
||||||
|
|
||||||
SetCategoryButtonStates();
|
SetCategoryButtonStates();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Category event handlers
|
|
||||||
|
|
||||||
private void HandleAddCategoryButtonClick(object sender, RoutedEventArgs e)
|
private void HandleAddCategoryButtonClick(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
AddCategory();
|
AddCategory();
|
||||||
@@ -362,15 +302,13 @@ namespace FeedCenter.Options
|
|||||||
DeleteSelectedCategory();
|
DeleteSelectedCategory();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
private CollectionViewSource _collectionViewSource;
|
private CollectionViewSource _collectionViewSource;
|
||||||
|
|
||||||
private void HandleCategoryListBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
|
private void HandleCategoryListBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
{
|
{
|
||||||
if (_collectionViewSource == null)
|
if (_collectionViewSource == null)
|
||||||
{
|
{
|
||||||
_collectionViewSource = new CollectionViewSource { Source = Database.Feeds };
|
_collectionViewSource = new CollectionViewSource { Source = Database.Entities.Feeds };
|
||||||
_collectionViewSource.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
|
_collectionViewSource.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
|
||||||
_collectionViewSource.Filter += HandleCollectionViewSourceFilter;
|
_collectionViewSource.Filter += HandleCollectionViewSourceFilter;
|
||||||
|
|
||||||
@@ -392,16 +330,16 @@ namespace FeedCenter.Options
|
|||||||
|
|
||||||
var feed = (Feed) e.Item;
|
var feed = (Feed) e.Item;
|
||||||
|
|
||||||
e.Accepted = (feed.Category.Id == selectedCategory.Id);
|
e.Accepted = feed.Category.Id == selectedCategory.Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleTextBlockDrop(object sender, DragEventArgs e)
|
private void CategoryListBox_Drop(object sender, DragEventArgs e)
|
||||||
{
|
{
|
||||||
var feedList = (List<Feed>) e.Data.GetData(typeof(List<Feed>));
|
var feedList = (List<Feed>) e.Data.GetData(typeof(List<Feed>));
|
||||||
|
|
||||||
var category = (Category) ((DataGridRow) sender).Item;
|
var category = (Category) ((DataGridRow) sender).Item;
|
||||||
|
|
||||||
foreach (var feed in feedList)
|
foreach (var feed in feedList!)
|
||||||
feed.Category = category;
|
feed.Category = category;
|
||||||
|
|
||||||
_collectionViewSource.View.Refresh();
|
_collectionViewSource.View.Refresh();
|
||||||
@@ -413,22 +351,22 @@ namespace FeedCenter.Options
|
|||||||
|
|
||||||
private void HandleListBoxItemPreviewMouseMove(object sender, MouseEventArgs e)
|
private void HandleListBoxItemPreviewMouseMove(object sender, MouseEventArgs e)
|
||||||
{
|
{
|
||||||
if (e.LeftButton == MouseButtonState.Pressed)
|
if (e.LeftButton != MouseButtonState.Pressed)
|
||||||
{
|
return;
|
||||||
var selectedItems = FeedListBox.SelectedItems.Cast<Feed>().ToList();
|
|
||||||
|
|
||||||
DragDrop.DoDragDrop(FeedListBox, selectedItems, DragDropEffects.Move);
|
var selectedItems = FeedListBox.SelectedItems.Cast<Feed>().ToList();
|
||||||
}
|
|
||||||
|
DragDrop.DoDragDrop(FeedListBox, selectedItems, DragDropEffects.Move);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleTextBlockDragEnter(object sender, DragEventArgs e)
|
private void CategoryListBox_DragEnter(object sender, DragEventArgs e)
|
||||||
{
|
{
|
||||||
var dataGridRow = (DataGridRow) sender;
|
var dataGridRow = (DataGridRow) sender;
|
||||||
|
|
||||||
dataGridRow.FontWeight = FontWeights.Bold;
|
dataGridRow.FontWeight = FontWeights.Bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleTextBlockDragLeave(object sender, DragEventArgs e)
|
private void CategoryListBox_DragLeave(object sender, DragEventArgs e)
|
||||||
{
|
{
|
||||||
var dataGridRow = (DataGridRow) sender;
|
var dataGridRow = (DataGridRow) sender;
|
||||||
|
|
||||||
@@ -443,7 +381,7 @@ namespace FeedCenter.Options
|
|||||||
private void HandleMultipleEditClick(object sender, RoutedEventArgs e)
|
private void HandleMultipleEditClick(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
var bulkFeedWindow = new BulkFeedWindow();
|
var bulkFeedWindow = new BulkFeedWindow();
|
||||||
bulkFeedWindow.Display(Window.GetWindow(this), Database);
|
bulkFeedWindow.Display(Window.GetWindow(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleFeedListPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
private void HandleFeedListPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
|
||||||
@@ -458,5 +396,13 @@ namespace FeedCenter.Options
|
|||||||
if (dataGridRow != null && FeedListBox.SelectedItems.Contains(dataGridRow.Item))
|
if (dataGridRow != null && FeedListBox.SelectedItems.Contains(dataGridRow.Item))
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CategoryListBox_MouseDoubleClick(object sender, MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
if (!EditCategoryButton.IsEnabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
EditSelectedCategory();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -26,7 +26,8 @@
|
|||||||
VerticalAlignment="Top"
|
VerticalAlignment="Top"
|
||||||
VerticalContentAlignment="Center"
|
VerticalContentAlignment="Center"
|
||||||
Margin="0,5"
|
Margin="0,5"
|
||||||
Grid.ColumnSpan="2" />
|
Grid.ColumnSpan="2"
|
||||||
|
Click="StartWithWindowsCheckBox_Click" />
|
||||||
<Label Content="{x:Static properties:Resources.defaultBrowserLabel}"
|
<Label Content="{x:Static properties:Resources.defaultBrowserLabel}"
|
||||||
Target="{Binding ElementName=BrowserComboBox}"
|
Target="{Binding ElementName=BrowserComboBox}"
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
@@ -37,7 +38,8 @@
|
|||||||
<ComboBox Name="BrowserComboBox"
|
<ComboBox Name="BrowserComboBox"
|
||||||
Grid.Row="2"
|
Grid.Row="2"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
VerticalContentAlignment="Center">
|
VerticalContentAlignment="Center"
|
||||||
|
SelectionChanged="BrowserComboBox_SelectionChanged">
|
||||||
</ComboBox>
|
</ComboBox>
|
||||||
<Label Content="{x:Static properties:Resources.defaultUserAgentLabel}"
|
<Label Content="{x:Static properties:Resources.defaultUserAgentLabel}"
|
||||||
Target="{Binding ElementName=BrowserComboBox}"
|
Target="{Binding ElementName=BrowserComboBox}"
|
||||||
@@ -49,8 +51,8 @@
|
|||||||
<ComboBox Name="UserAgentComboBox"
|
<ComboBox Name="UserAgentComboBox"
|
||||||
Grid.Row="4"
|
Grid.Row="4"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
VerticalContentAlignment="Center">
|
VerticalContentAlignment="Center"
|
||||||
|
SelectionChanged="UserAgentComboBox_SelectionChanged">
|
||||||
</ComboBox>
|
</ComboBox>
|
||||||
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</options:OptionsPanelBase>
|
</options:OptionsPanelBase>
|
||||||
@@ -1,132 +1,104 @@
|
|||||||
using ChrisKaczor.InstalledBrowsers;
|
using ChrisKaczor.InstalledBrowsers;
|
||||||
using ChrisKaczor.Wpf.Application;
|
using ChrisKaczor.Wpf.Application;
|
||||||
using ChrisKaczor.Wpf.Validation;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Data;
|
using System.Windows.Controls.Primitives;
|
||||||
|
|
||||||
internal class UserAgentItem
|
namespace FeedCenter.Options;
|
||||||
{
|
|
||||||
internal string Caption { get; set; }
|
|
||||||
internal string UserAgent { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace FeedCenter.Options
|
public partial class GeneralOptionsPanel
|
||||||
{
|
{
|
||||||
public partial class GeneralOptionsPanel
|
public GeneralOptionsPanel()
|
||||||
{
|
{
|
||||||
public GeneralOptionsPanel()
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string CategoryName => Properties.Resources.optionCategoryGeneral;
|
||||||
|
|
||||||
|
public override void LoadPanel()
|
||||||
|
{
|
||||||
|
base.LoadPanel();
|
||||||
|
|
||||||
|
var settings = Properties.Settings.Default;
|
||||||
|
|
||||||
|
StartWithWindowsCheckBox.IsChecked = settings.StartWithWindows;
|
||||||
|
|
||||||
|
LoadBrowserComboBox(BrowserComboBox, settings.Browser);
|
||||||
|
|
||||||
|
LoadUserAgentComboBox(UserAgentComboBox, settings.DefaultUserAgent);
|
||||||
|
|
||||||
|
MarkLoaded();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void LoadBrowserComboBox(Selector selector, string selected)
|
||||||
|
{
|
||||||
|
selector.SelectedIndex = 0;
|
||||||
|
|
||||||
|
ComboBoxItem selectedItem = null;
|
||||||
|
|
||||||
|
var browsers = InstalledBrowser.GetInstalledBrowsers(true);
|
||||||
|
foreach (var browser in browsers)
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
var item = new ComboBoxItem { Content = browser.Value.Name, Tag = browser.Key };
|
||||||
|
|
||||||
|
selector.Items.Add(item);
|
||||||
|
|
||||||
|
if (browser.Key == selected)
|
||||||
|
selectedItem = item;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string CategoryName => Properties.Resources.optionCategoryGeneral;
|
if (selectedItem != null)
|
||||||
|
selector.SelectedItem = selectedItem;
|
||||||
|
}
|
||||||
|
|
||||||
public override void LoadPanel(FeedCenterEntities database)
|
private static void LoadUserAgentComboBox(Selector selector, string selected)
|
||||||
|
{
|
||||||
|
selector.SelectedIndex = 0;
|
||||||
|
|
||||||
|
ComboBoxItem selectedItem = null;
|
||||||
|
|
||||||
|
var userAgents = UserAgentItem.GetUserAgents();
|
||||||
|
foreach (var userAgent in userAgents)
|
||||||
{
|
{
|
||||||
base.LoadPanel(database);
|
var item = new ComboBoxItem { Content = userAgent.Caption, Tag = userAgent.UserAgent };
|
||||||
|
|
||||||
var settings = Properties.Settings.Default;
|
selector.Items.Add(item);
|
||||||
|
|
||||||
StartWithWindowsCheckBox.IsChecked = settings.StartWithWindows;
|
if (userAgent.UserAgent == selected)
|
||||||
|
selectedItem = item;
|
||||||
LoadBrowserComboBox(BrowserComboBox, settings.Browser);
|
|
||||||
|
|
||||||
LoadUserAgentComboBox(UserAgentComboBox, settings.DefaultUserAgent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool ValidatePanel()
|
if (selectedItem != null)
|
||||||
{
|
selector.SelectedItem = selectedItem;
|
||||||
return true;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public override void SavePanel()
|
private void StartWithWindowsCheckBox_Click(object sender, System.Windows.RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
var settings = Properties.Settings.Default;
|
if (!HasLoaded) return;
|
||||||
|
|
||||||
if (StartWithWindowsCheckBox.IsChecked.HasValue &&
|
var settings = Properties.Settings.Default;
|
||||||
settings.StartWithWindows != StartWithWindowsCheckBox.IsChecked.Value)
|
|
||||||
settings.StartWithWindows = StartWithWindowsCheckBox.IsChecked.Value;
|
|
||||||
|
|
||||||
System.Windows.Application.Current.SetStartWithWindows(settings.StartWithWindows);
|
if (StartWithWindowsCheckBox.IsChecked.HasValue &&
|
||||||
|
settings.StartWithWindows != StartWithWindowsCheckBox.IsChecked.Value)
|
||||||
|
settings.StartWithWindows = StartWithWindowsCheckBox.IsChecked.Value;
|
||||||
|
|
||||||
settings.Browser = (string) ((ComboBoxItem) BrowserComboBox.SelectedItem).Tag;
|
System.Windows.Application.Current.SetStartWithWindows(settings.StartWithWindows);
|
||||||
|
}
|
||||||
|
|
||||||
settings.DefaultUserAgent = (string) ((ComboBoxItem) UserAgentComboBox.SelectedItem).Tag;
|
private void BrowserComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (!HasLoaded) return;
|
||||||
|
|
||||||
var expressions = this.GetBindingExpressions(new[] { UpdateSourceTrigger.Explicit });
|
var settings = Properties.Settings.Default;
|
||||||
this.UpdateAllSources(expressions);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void LoadBrowserComboBox(ComboBox comboBox, string selected)
|
settings.Browser = (string) ((ComboBoxItem) BrowserComboBox.SelectedItem).Tag;
|
||||||
{
|
}
|
||||||
comboBox.SelectedIndex = 0;
|
|
||||||
|
|
||||||
ComboBoxItem selectedItem = null;
|
private void UserAgentComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (!HasLoaded) return;
|
||||||
|
|
||||||
var browsers = InstalledBrowser.GetInstalledBrowsers(true);
|
var settings = Properties.Settings.Default;
|
||||||
foreach (var browser in browsers)
|
|
||||||
{
|
|
||||||
var item = new ComboBoxItem { Content = browser.Value.Name, Tag = browser.Key };
|
|
||||||
|
|
||||||
comboBox.Items.Add(item);
|
settings.DefaultUserAgent = (string) ((ComboBoxItem) UserAgentComboBox.SelectedItem).Tag;
|
||||||
|
|
||||||
if (browser.Key == selected)
|
|
||||||
selectedItem = item;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selectedItem != null)
|
|
||||||
comboBox.SelectedItem = selectedItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void LoadUserAgentComboBox(ComboBox comboBox, string selected)
|
|
||||||
{
|
|
||||||
comboBox.SelectedIndex = 0;
|
|
||||||
|
|
||||||
ComboBoxItem selectedItem = null;
|
|
||||||
|
|
||||||
var userAgents = GetUserAgents();
|
|
||||||
foreach (var userAgent in userAgents)
|
|
||||||
{
|
|
||||||
var item = new ComboBoxItem { Content = userAgent.Caption, Tag = userAgent.UserAgent };
|
|
||||||
|
|
||||||
comboBox.Items.Add(item);
|
|
||||||
|
|
||||||
if (userAgent.UserAgent == selected)
|
|
||||||
selectedItem = item;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selectedItem != null)
|
|
||||||
comboBox.SelectedItem = selectedItem;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<UserAgentItem> GetUserAgents()
|
|
||||||
{
|
|
||||||
var userAgents = new List<UserAgentItem>
|
|
||||||
{
|
|
||||||
new()
|
|
||||||
{
|
|
||||||
Caption = Properties.Resources.DefaultUserAgentCaption,
|
|
||||||
UserAgent = string.Empty
|
|
||||||
},
|
|
||||||
new()
|
|
||||||
{
|
|
||||||
Caption = "Windows RSS Platform 2.0",
|
|
||||||
UserAgent = "Windows-RSS-Platform/2.0 (MSIE 9.0; Windows NT 6.1)"
|
|
||||||
},
|
|
||||||
new()
|
|
||||||
{
|
|
||||||
Caption = "Feedly 1.0",
|
|
||||||
UserAgent = "Feedly/1.0"
|
|
||||||
},
|
|
||||||
new()
|
|
||||||
{
|
|
||||||
Caption = "curl",
|
|
||||||
UserAgent = "curl/7.47.0"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return userAgents;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,27 +1,19 @@
|
|||||||
using System;
|
using System.Windows.Controls;
|
||||||
using System.Windows.Controls;
|
|
||||||
|
|
||||||
namespace FeedCenter.Options
|
namespace FeedCenter.Options;
|
||||||
|
|
||||||
|
public class OptionsPanelBase : UserControl
|
||||||
{
|
{
|
||||||
public class OptionsPanelBase : UserControl
|
public bool HasLoaded { get; private set; }
|
||||||
|
|
||||||
|
public virtual void LoadPanel()
|
||||||
{
|
{
|
||||||
protected FeedCenterEntities Database { get; private set; }
|
|
||||||
|
|
||||||
public virtual void LoadPanel(FeedCenterEntities database)
|
|
||||||
{
|
|
||||||
Database = database;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual bool ValidatePanel()
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void SavePanel()
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual string CategoryName => null;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
public void MarkLoaded()
|
||||||
|
{
|
||||||
|
HasLoaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual string CategoryName => null;
|
||||||
|
}
|
||||||
@@ -17,15 +17,7 @@
|
|||||||
<ContentControl Margin="144,12,12,41"
|
<ContentControl Margin="144,12,12,41"
|
||||||
Name="ContentControl"
|
Name="ContentControl"
|
||||||
IsTabStop="False" />
|
IsTabStop="False" />
|
||||||
<Button Content="{x:Static properties:Resources.OkayButton}"
|
<Button Content="{x:Static properties:Resources.CloseButton}"
|
||||||
Height="23"
|
|
||||||
HorizontalAlignment="Right"
|
|
||||||
Margin="0,0,93,12"
|
|
||||||
VerticalAlignment="Bottom"
|
|
||||||
Width="75"
|
|
||||||
IsDefault="True"
|
|
||||||
Click="HandleOkayButtonClick" />
|
|
||||||
<Button Content="{x:Static properties:Resources.CancelButton}"
|
|
||||||
Margin="0,0,12,12"
|
Margin="0,0,12,12"
|
||||||
Height="23"
|
Height="23"
|
||||||
VerticalAlignment="Bottom"
|
VerticalAlignment="Bottom"
|
||||||
|
|||||||
@@ -1,22 +1,13 @@
|
|||||||
using FeedCenter.Data;
|
using FeedCenter.Data;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Windows;
|
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
|
||||||
namespace FeedCenter.Options
|
namespace FeedCenter.Options
|
||||||
{
|
{
|
||||||
public partial class OptionsWindow
|
public partial class OptionsWindow
|
||||||
{
|
{
|
||||||
#region Member variables
|
|
||||||
|
|
||||||
private readonly List<OptionsPanelBase> _optionPanels = new();
|
private readonly List<OptionsPanelBase> _optionPanels = new();
|
||||||
|
|
||||||
private readonly FeedCenterEntities _database = Database.Entities;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Constructor
|
|
||||||
|
|
||||||
public OptionsWindow()
|
public OptionsWindow()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
@@ -28,10 +19,6 @@ namespace FeedCenter.Options
|
|||||||
LoadCategories();
|
LoadCategories();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Category handling
|
|
||||||
|
|
||||||
private void AddCategories()
|
private void AddCategories()
|
||||||
{
|
{
|
||||||
_optionPanels.Add(new GeneralOptionsPanel());
|
_optionPanels.Add(new GeneralOptionsPanel());
|
||||||
@@ -47,7 +34,7 @@ namespace FeedCenter.Options
|
|||||||
foreach (var optionsPanel in _optionPanels)
|
foreach (var optionsPanel in _optionPanels)
|
||||||
{
|
{
|
||||||
// Tell the panel to load itself
|
// Tell the panel to load itself
|
||||||
optionsPanel.LoadPanel(_database);
|
optionsPanel.LoadPanel();
|
||||||
|
|
||||||
// Add the panel to the category ist
|
// Add the panel to the category ist
|
||||||
CategoryListBox.Items.Add(new CategoryListItem(optionsPanel));
|
CategoryListBox.Items.Add(new CategoryListItem(optionsPanel));
|
||||||
@@ -72,10 +59,6 @@ namespace FeedCenter.Options
|
|||||||
SelectCategory(((CategoryListItem) CategoryListBox.SelectedItem).Panel);
|
SelectCategory(((CategoryListItem) CategoryListBox.SelectedItem).Panel);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Category list item
|
|
||||||
|
|
||||||
private class CategoryListItem
|
private class CategoryListItem
|
||||||
{
|
{
|
||||||
public OptionsPanelBase Panel { get; }
|
public OptionsPanelBase Panel { get; }
|
||||||
@@ -90,40 +73,5 @@ namespace FeedCenter.Options
|
|||||||
return Panel.CategoryName;
|
return Panel.CategoryName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
private void HandleOkayButtonClick(object sender, RoutedEventArgs e)
|
|
||||||
{
|
|
||||||
// Loop over each panel and ask them to validate
|
|
||||||
foreach (var optionsPanel in _optionPanels)
|
|
||||||
{
|
|
||||||
// If validation fails...
|
|
||||||
if (!optionsPanel.ValidatePanel())
|
|
||||||
{
|
|
||||||
// ...select the right category
|
|
||||||
SelectCategory(optionsPanel);
|
|
||||||
|
|
||||||
// Stop validation
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Loop over each panel and ask them to save
|
|
||||||
foreach (var optionsPanel in _optionPanels)
|
|
||||||
{
|
|
||||||
// Save!
|
|
||||||
optionsPanel.SavePanel();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save the actual settings
|
|
||||||
_database.SaveChanges(() => { });
|
|
||||||
Properties.Settings.Default.Save();
|
|
||||||
|
|
||||||
DialogResult = true;
|
|
||||||
|
|
||||||
// Close the window
|
|
||||||
Close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,7 +11,8 @@
|
|||||||
<Grid>
|
<Grid>
|
||||||
<CheckBox Content="{x:Static properties:Resources.checkVersionOnStartupCheckBox}"
|
<CheckBox Content="{x:Static properties:Resources.checkVersionOnStartupCheckBox}"
|
||||||
Name="CheckVersionOnStartupCheckBox"
|
Name="CheckVersionOnStartupCheckBox"
|
||||||
VerticalAlignment="Top" />
|
VerticalAlignment="Top"
|
||||||
|
Click="CheckVersionOnStartupCheckBox_Click" />
|
||||||
<Button Content="{x:Static properties:Resources.checkVersionNowButton}"
|
<Button Content="{x:Static properties:Resources.checkVersionNowButton}"
|
||||||
Height="23"
|
Height="23"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
@@ -20,4 +21,4 @@
|
|||||||
Width="75"
|
Width="75"
|
||||||
Click="HandleCheckVersionNowButtonClick" />
|
Click="HandleCheckVersionNowButtonClick" />
|
||||||
</Grid>
|
</Grid>
|
||||||
</options:OptionsPanelBase>
|
</options:OptionsPanelBase>
|
||||||
@@ -1,37 +1,35 @@
|
|||||||
using ChrisKaczor.ApplicationUpdate;
|
using ChrisKaczor.ApplicationUpdate;
|
||||||
|
|
||||||
namespace FeedCenter.Options
|
namespace FeedCenter.Options;
|
||||||
|
|
||||||
|
public partial class UpdateOptionsPanel
|
||||||
{
|
{
|
||||||
public partial class UpdateOptionsPanel
|
public UpdateOptionsPanel()
|
||||||
{
|
{
|
||||||
public UpdateOptionsPanel()
|
InitializeComponent();
|
||||||
{
|
}
|
||||||
InitializeComponent();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void LoadPanel(FeedCenterEntities database)
|
public override void LoadPanel()
|
||||||
{
|
{
|
||||||
base.LoadPanel(database);
|
base.LoadPanel();
|
||||||
|
|
||||||
CheckVersionOnStartupCheckBox.IsChecked = Properties.Settings.Default.CheckVersionAtStartup;
|
CheckVersionOnStartupCheckBox.IsChecked = Properties.Settings.Default.CheckVersionAtStartup;
|
||||||
}
|
|
||||||
|
|
||||||
public override bool ValidatePanel()
|
MarkLoaded();
|
||||||
{
|
}
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void SavePanel()
|
public override string CategoryName => Properties.Resources.optionCategoryUpdate;
|
||||||
{
|
|
||||||
if (CheckVersionOnStartupCheckBox.IsChecked.HasValue && Properties.Settings.Default.CheckVersionAtStartup != CheckVersionOnStartupCheckBox.IsChecked.Value)
|
|
||||||
Properties.Settings.Default.CheckVersionAtStartup = CheckVersionOnStartupCheckBox.IsChecked.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string CategoryName => Properties.Resources.optionCategoryUpdate;
|
private void HandleCheckVersionNowButtonClick(object sender, System.Windows.RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
UpdateCheck.DisplayUpdateInformation(true);
|
||||||
|
}
|
||||||
|
|
||||||
private void HandleCheckVersionNowButtonClick(object sender, System.Windows.RoutedEventArgs e)
|
private void CheckVersionOnStartupCheckBox_Click(object sender, System.Windows.RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
UpdateCheck.DisplayUpdateInformation(true);
|
if (!HasLoaded) return;
|
||||||
}
|
|
||||||
|
if (CheckVersionOnStartupCheckBox.IsChecked.HasValue && Properties.Settings.Default.CheckVersionAtStartup != CheckVersionOnStartupCheckBox.IsChecked.Value)
|
||||||
|
Properties.Settings.Default.CheckVersionAtStartup = CheckVersionOnStartupCheckBox.IsChecked.Value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
39
Application/Options/UserAgentItem.cs
Normal file
39
Application/Options/UserAgentItem.cs
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace FeedCenter.Options
|
||||||
|
{
|
||||||
|
internal class UserAgentItem
|
||||||
|
{
|
||||||
|
internal string Caption { get; set; }
|
||||||
|
internal string UserAgent { get; set; }
|
||||||
|
|
||||||
|
internal static List<UserAgentItem> GetUserAgents()
|
||||||
|
{
|
||||||
|
var userAgents = new List<UserAgentItem>
|
||||||
|
{
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Caption = Properties.Resources.DefaultUserAgentCaption,
|
||||||
|
UserAgent = string.Empty
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Caption = "Windows RSS Platform 2.0",
|
||||||
|
UserAgent = "Windows-RSS-Platform/2.0 (MSIE 9.0; Windows NT 6.1)"
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Caption = "Feedly 1.0",
|
||||||
|
UserAgent = "Feedly/1.0"
|
||||||
|
},
|
||||||
|
new()
|
||||||
|
{
|
||||||
|
Caption = "curl",
|
||||||
|
UserAgent = "curl/7.47.0"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return userAgents;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
9
Application/Properties/Resources.Designer.cs
generated
9
Application/Properties/Resources.Designer.cs
generated
@@ -214,6 +214,15 @@ namespace FeedCenter.Properties {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to _Name:.
|
||||||
|
/// </summary>
|
||||||
|
public static string categoryNameLabel {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("categoryNameLabel", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Add Category.
|
/// Looks up a localized string similar to Add Category.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -535,4 +535,7 @@
|
|||||||
<data name="SplashMigratingLegacyDatabase" xml:space="preserve">
|
<data name="SplashMigratingLegacyDatabase" xml:space="preserve">
|
||||||
<value>Migrating legacy database...</value>
|
<value>Migrating legacy database...</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="categoryNameLabel" xml:space="preserve">
|
||||||
|
<value>_Name:</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -1,11 +1,30 @@
|
|||||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
<Style TargetType="{x:Type TextBox}">
|
<Style TargetType="{x:Type TextBox}">
|
||||||
|
<Setter Property="Validation.ErrorTemplate">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<AdornedElementPlaceholder x:Name="placeholder" />
|
||||||
|
<TextBlock FontSize="14"
|
||||||
|
Margin="2,0"
|
||||||
|
Foreground="White"
|
||||||
|
Background="Red"
|
||||||
|
TextAlignment="Center"
|
||||||
|
Width="16"
|
||||||
|
Text="!"
|
||||||
|
ToolTip="{Binding AdornedElement.(Validation.Errors)[0].ErrorContent, ElementName=placeholder}" />
|
||||||
|
</StackPanel>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
<Style.Triggers>
|
<Style.Triggers>
|
||||||
<Trigger Property="Validation.HasError"
|
<Trigger Property="Validation.HasError"
|
||||||
Value="true">
|
Value="true">
|
||||||
<Setter Property="ToolTip"
|
<Setter Property="ToolTip"
|
||||||
Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" />
|
Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" />
|
||||||
|
<Setter Property="Margin"
|
||||||
|
Value="0,0,18,0" />
|
||||||
</Trigger>
|
</Trigger>
|
||||||
</Style.Triggers>
|
</Style.Triggers>
|
||||||
</Style>
|
</Style>
|
||||||
|
|||||||
Reference in New Issue
Block a user