mirror of
https://github.com/ckaczor/FeedCenter.git
synced 2026-02-16 18:47:28 -05:00
Start adding server support
This commit is contained in:
@@ -4,7 +4,7 @@ namespace FeedCenter.Options;
|
||||
|
||||
public partial class AboutOptionsPanel
|
||||
{
|
||||
public AboutOptionsPanel(Window parentWindow) : base(parentWindow)
|
||||
public AboutOptionsPanel(Window parentWindow, FeedCenterEntities entities) : base(parentWindow, entities)
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
24
Application/Options/AccountTypeItem.cs
Normal file
24
Application/Options/AccountTypeItem.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace FeedCenter.Options
|
||||
{
|
||||
public class AccountTypeItem
|
||||
{
|
||||
public AccountType AccountType { get; set; }
|
||||
public string Name { get; set; }
|
||||
|
||||
public static List<AccountTypeItem> AccountTypes =>
|
||||
[
|
||||
new()
|
||||
{
|
||||
Name = Properties.Resources.AccountTypeFever,
|
||||
AccountType = AccountType.Fever
|
||||
},
|
||||
//new()
|
||||
//{
|
||||
// Name = Properties.Resources.AccountTypeGoogleReader,
|
||||
// AccountType = AccountType.GoogleReader
|
||||
//}
|
||||
];
|
||||
}
|
||||
}
|
||||
22
Application/Options/AccountTypeToNameConverter.cs
Normal file
22
Application/Options/AccountTypeToNameConverter.cs
Normal file
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace FeedCenter.Options;
|
||||
|
||||
public class AccountTypeToNameConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is AccountType accountType)
|
||||
return AccountTypeItem.AccountTypes.First(at => at.AccountType == accountType).Name;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
139
Application/Options/AccountWindow.xaml
Normal file
139
Application/Options/AccountWindow.xaml
Normal file
@@ -0,0 +1,139 @@
|
||||
<Window x:Class="FeedCenter.Options.AccountWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:properties="clr-namespace:FeedCenter.Properties"
|
||||
xmlns:feedCenter="clr-namespace:FeedCenter"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
d:DataContext="{d:DesignInstance Type=feedCenter:Account}"
|
||||
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="AccountWindow"
|
||||
Height="350"
|
||||
Width="450"
|
||||
WindowStartupLocation="CenterOwner"
|
||||
Icon="/FeedCenter;component/Resources/Application.ico"
|
||||
FocusManager.FocusedElement="{Binding ElementName=NameTextBox}">
|
||||
<Window.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
|
||||
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
|
||||
<ResourceDictionary
|
||||
Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.FlatButton.xaml" />
|
||||
<ResourceDictionary
|
||||
Source="pack://application:,,,/MahApps.Metro;component/Styles/Themes/light.cobalt.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</Window.Resources>
|
||||
<Grid Margin="6">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TabControl Name="OptionsTabControl"
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
mah:HeaderedControlHelper.HeaderFontSize="16"
|
||||
mah:TabControlHelper.Underlined="SelectedTabItem">
|
||||
<TabItem Header="{x:Static properties:Resources.generalTab}">
|
||||
<StackPanel Margin="0,4"
|
||||
options:Spacing.Vertical="8">
|
||||
<ComboBox Name="AccountTypeComboBox"
|
||||
mah:TextBoxHelper.UseFloatingWatermark="True"
|
||||
mah:TextBoxHelper.Watermark="{x:Static properties:Resources.accountTypeLabel}"
|
||||
DisplayMemberPath="Name"
|
||||
ItemsSource="{Binding Source={x:Static options:AccountTypeItem.AccountTypes}}"
|
||||
SelectedValuePath="AccountType"
|
||||
SelectedValue="{Binding Path=Type, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=true}" />
|
||||
<TextBox Name="NameTextBox"
|
||||
mah:TextBoxHelper.UseFloatingWatermark="True"
|
||||
mah:TextBoxHelper.Watermark="{x:Static properties:Resources.accountNameLabel}"
|
||||
mah:TextBoxHelper.SelectAllOnFocus="True"
|
||||
Text="{Binding Path=Name, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}" />
|
||||
<TextBox Name="UrlTextBox"
|
||||
mah:TextBoxHelper.UseFloatingWatermark="True"
|
||||
mah:TextBoxHelper.Watermark="{x:Static properties:Resources.accountUrlLabel}"
|
||||
mah:TextBoxHelper.SelectAllOnFocus="True"
|
||||
Text="{Binding Path=Url, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}" />
|
||||
<CheckBox Name="ReadIntervalCheckBox"
|
||||
VerticalContentAlignment="Center"
|
||||
IsChecked="{Binding Path=Enabled, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Label Content="{x:Static properties:Resources.accountReadIntervalPrefix}"
|
||||
HorizontalAlignment="Left"
|
||||
Margin="0,0,5,0"
|
||||
VerticalAlignment="Center"
|
||||
Padding="0" />
|
||||
<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.accountReadIntervalSuffix}"
|
||||
HorizontalAlignment="Left"
|
||||
Margin="5,0,0,0"
|
||||
VerticalAlignment="Center"
|
||||
Padding="0" />
|
||||
</StackPanel>
|
||||
</CheckBox>
|
||||
</StackPanel>
|
||||
</TabItem>
|
||||
<TabItem Header="{x:Static properties:Resources.authenticationTab}">
|
||||
<StackPanel Margin="0,4">
|
||||
<CheckBox Content="{x:Static properties:Resources.accountRequiresAuthenticationCheckBox}"
|
||||
Margin="0,0,0,4"
|
||||
Name="RequiresAuthenticationCheckBox"
|
||||
IsChecked="{Binding Path=Authenticate, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}" />
|
||||
<TextBox Name="AuthenticationUserNameTextBox"
|
||||
Margin="25,0,0,4"
|
||||
IsEnabled="{Binding ElementName=RequiresAuthenticationCheckBox, Path=IsChecked}"
|
||||
mah:TextBoxHelper.UseFloatingWatermark="True"
|
||||
mah:TextBoxHelper.Watermark="{x:Static properties:Resources.authenticationUserNameLabel}"
|
||||
Text="{Binding Path=Username, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}" />
|
||||
<PasswordBox Name="AuthenticationPasswordTextBox"
|
||||
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>
|
||||
<Grid Name="AccountReadProgress"
|
||||
Grid.Row="1"
|
||||
Height="20"
|
||||
Visibility="Collapsed">
|
||||
<ProgressBar Name="AccountReadProgressBar" />
|
||||
<TextBlock Text="Loading account..."
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center" />
|
||||
</Grid>
|
||||
<StackPanel
|
||||
Name="ButtonPanel"
|
||||
Grid.Column="0"
|
||||
Grid.Row="1"
|
||||
Orientation="Horizontal"
|
||||
Visibility="Visible"
|
||||
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>
|
||||
78
Application/Options/AccountWindow.xaml.cs
Normal file
78
Application/Options/AccountWindow.xaml.cs
Normal file
@@ -0,0 +1,78 @@
|
||||
using ChrisKaczor.Wpf.Validation;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Threading;
|
||||
|
||||
namespace FeedCenter.Options;
|
||||
|
||||
public partial class AccountWindow
|
||||
{
|
||||
private Account _account;
|
||||
private bool _isNew;
|
||||
private readonly FeedCenterEntities _entities;
|
||||
|
||||
public AccountWindow(FeedCenterEntities entities)
|
||||
{
|
||||
_entities = entities;
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public bool? Display(Account account, Window owner, bool isNew)
|
||||
{
|
||||
_account = account;
|
||||
_isNew = isNew;
|
||||
|
||||
DataContext = account;
|
||||
|
||||
Title = isNew ? Properties.Resources.AccountWindowAdd : Properties.Resources.AccountWindowEdit;
|
||||
|
||||
Owner = owner;
|
||||
|
||||
return ShowDialog();
|
||||
}
|
||||
|
||||
private void HandleOkayButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var transaction = _entities.BeginTransaction();
|
||||
|
||||
if (!this.IsValid(OptionsTabControl))
|
||||
{
|
||||
transaction.Rollback();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_isNew)
|
||||
{
|
||||
_entities.Accounts.Add(_account);
|
||||
}
|
||||
|
||||
transaction.Commit();
|
||||
|
||||
var accountId = _account.Id;
|
||||
|
||||
AccountReadProgressBar.Value = 0;
|
||||
AccountReadProgressBar.Maximum = _account.GetProgressSteps(_entities) + 1;
|
||||
|
||||
AccountReadProgress.Visibility = Visibility.Visible;
|
||||
ButtonPanel.Visibility = Visibility.Collapsed;
|
||||
|
||||
var dispatcher = Dispatcher.CurrentDispatcher;
|
||||
|
||||
Task.Run(() =>
|
||||
{
|
||||
var entities = new FeedCenterEntities();
|
||||
var account = entities.Accounts.First(a => a.Id == accountId);
|
||||
var accountReadInput = new AccountReadInput(entities, null, true, () => dispatcher.Invoke(() => AccountReadProgressBar.Value++));
|
||||
account.Read(accountReadInput);
|
||||
|
||||
dispatcher.Invoke(() =>
|
||||
{
|
||||
DialogResult = true;
|
||||
|
||||
Close();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
98
Application/Options/AccountsOptionsPanel.xaml
Normal file
98
Application/Options/AccountsOptionsPanel.xaml
Normal file
@@ -0,0 +1,98 @@
|
||||
<options:OptionsPanelBase x:Class="FeedCenter.Options.AccountsOptionsPanel"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:options="clr-namespace:FeedCenter.Options"
|
||||
xmlns:properties="clr-namespace:FeedCenter.Properties"
|
||||
xmlns:controls="clr-namespace:ChrisKaczor.Wpf.Controls;assembly=ChrisKaczor.Wpf.Controls.Link"
|
||||
xmlns:feedCenter="clr-namespace:FeedCenter"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="311"
|
||||
d:DesignWidth="425">
|
||||
<options:OptionsPanelBase.Resources>
|
||||
<ResourceDictionary>
|
||||
<options:AccountTypeToNameConverter x:Key="AccountTypeToNameConverter" />
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
|
||||
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
|
||||
<ResourceDictionary
|
||||
Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.FlatButton.xaml" />
|
||||
<ResourceDictionary
|
||||
Source="pack://application:,,,/MahApps.Metro;component/Styles/Themes/light.cobalt.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</options:OptionsPanelBase.Resources>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<DataGrid Name="AccountDataGrid"
|
||||
SelectionChanged="HandleAccountDataGridSelectionChanged"
|
||||
Grid.Row="0"
|
||||
SelectionMode="Single"
|
||||
SelectionUnit="FullRow"
|
||||
Grid.Column="0"
|
||||
AutoGenerateColumns="False"
|
||||
GridLinesVisibility="None"
|
||||
CanUserResizeRows="False"
|
||||
IsReadOnly="True"
|
||||
HeadersVisibility="Column"
|
||||
BorderThickness="1,1,1,1"
|
||||
BorderBrush="{DynamicResource {x:Static SystemColors.ActiveBorderBrushKey}}"
|
||||
AllowDrop="True"
|
||||
Background="{x:Null}"
|
||||
d:DataContext="{d:DesignInstance feedCenter:Account }">
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn Binding="{Binding Name}"
|
||||
Header="{x:Static properties:Resources.AccountNameColumnHeader}"
|
||||
SortDirection="Ascending"
|
||||
Width="*" />
|
||||
<DataGridTextColumn Binding="{Binding Type, Converter={StaticResource AccountTypeToNameConverter}}"
|
||||
Header="{x:Static properties:Resources.AccountTypeColumnHeader}"
|
||||
Width="*" />
|
||||
</DataGrid.Columns>
|
||||
<DataGrid.RowStyle>
|
||||
<Style TargetType="DataGridRow"
|
||||
BasedOn="{StaticResource MahApps.Styles.DataGridRow}">
|
||||
<EventSetter Event="MouseDoubleClick"
|
||||
Handler="HandleAccountDataGridRowMouseDoubleClick" />
|
||||
</Style>
|
||||
</DataGrid.RowStyle>
|
||||
</DataGrid>
|
||||
<Border Grid.Column="0"
|
||||
Grid.Row="1"
|
||||
BorderThickness="1,0,1,1"
|
||||
BorderBrush="{DynamicResource {x:Static SystemColors.ActiveBorderBrushKey}}" />
|
||||
<Border Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
BorderThickness="1,0,1,1"
|
||||
BorderBrush="{DynamicResource {x:Static SystemColors.ActiveBorderBrushKey}}">
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}">
|
||||
<controls:Link Name="AddAccountButton"
|
||||
Margin="2"
|
||||
Click="HandleAddAccountButtonClick"
|
||||
Text="{x:Static properties:Resources.AddLink}"
|
||||
ToolTip="{x:Static properties:Resources.AddAccountButton}">
|
||||
</controls:Link>
|
||||
<controls:Link Name="EditAccountButton"
|
||||
Margin="2"
|
||||
Click="HandleEditAccountButtonClick"
|
||||
Text="{x:Static properties:Resources.EditLink}"
|
||||
ToolTip="{x:Static properties:Resources.EditAccountButton}">
|
||||
</controls:Link>
|
||||
<controls:Link Name="DeleteAccountButton"
|
||||
Margin="2"
|
||||
Click="HandleDeleteAccountButtonClick"
|
||||
Text="{x:Static properties:Resources.DeleteLink}"
|
||||
ToolTip="{x:Static properties:Resources.DeleteAccountButton}">
|
||||
</controls:Link>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</options:OptionsPanelBase>
|
||||
129
Application/Options/AccountsOptionsPanel.xaml.cs
Normal file
129
Application/Options/AccountsOptionsPanel.xaml.cs
Normal file
@@ -0,0 +1,129 @@
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace FeedCenter.Options;
|
||||
|
||||
public partial class AccountsOptionsPanel
|
||||
{
|
||||
private readonly FeedCenterEntities _entities;
|
||||
|
||||
public AccountsOptionsPanel(Window parentWindow, FeedCenterEntities entities) : base(parentWindow, entities)
|
||||
{
|
||||
_entities = entities;
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public override string CategoryName => Properties.Resources.optionCategoryAccounts;
|
||||
|
||||
public override void LoadPanel()
|
||||
{
|
||||
base.LoadPanel();
|
||||
|
||||
var collectionViewSource = new CollectionViewSource { Source = _entities.Accounts };
|
||||
collectionViewSource.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
|
||||
collectionViewSource.IsLiveSortingRequested = true;
|
||||
collectionViewSource.View.Filter = item =>
|
||||
{
|
||||
if (item is not Account account)
|
||||
return false;
|
||||
|
||||
// Filter out local accounts
|
||||
return account.Type != AccountType.Local;
|
||||
};
|
||||
|
||||
AccountDataGrid.ItemsSource = collectionViewSource.View;
|
||||
AccountDataGrid.SelectedIndex = 0;
|
||||
|
||||
SetAccountButtonStates();
|
||||
}
|
||||
|
||||
private void SetAccountButtonStates()
|
||||
{
|
||||
AddAccountButton.IsEnabled = true;
|
||||
|
||||
EditAccountButton.IsEnabled = AccountDataGrid.SelectedItem != null;
|
||||
DeleteAccountButton.IsEnabled = AccountDataGrid.SelectedItem != null;
|
||||
}
|
||||
|
||||
private void AddAccount()
|
||||
{
|
||||
var account = new Account(AccountType.Fever);
|
||||
|
||||
var accountWindow = new AccountWindow(_entities);
|
||||
|
||||
var result = accountWindow.Display(account, Window.GetWindow(this), true);
|
||||
|
||||
if (!result.HasValue || !result.Value)
|
||||
return;
|
||||
|
||||
AccountDataGrid.SelectedItem = account;
|
||||
|
||||
SetAccountButtonStates();
|
||||
}
|
||||
|
||||
private void EditSelectedAccount()
|
||||
{
|
||||
if (AccountDataGrid.SelectedItem == null)
|
||||
return;
|
||||
|
||||
var account = (Account) AccountDataGrid.SelectedItem;
|
||||
|
||||
var accountWindow = new AccountWindow(_entities);
|
||||
|
||||
accountWindow.Display(account, Window.GetWindow(this), false);
|
||||
}
|
||||
|
||||
private void DeleteSelectedAccount()
|
||||
{
|
||||
var account = (Account) AccountDataGrid.SelectedItem;
|
||||
|
||||
if (MessageBox.Show(ParentWindow, string.Format(Properties.Resources.ConfirmDeleteAccount, account.Name),
|
||||
Properties.Resources.ConfirmDeleteTitle, MessageBoxButton.YesNo, MessageBoxImage.Question,
|
||||
MessageBoxResult.No) == MessageBoxResult.No)
|
||||
return;
|
||||
|
||||
var index = AccountDataGrid.SelectedIndex;
|
||||
|
||||
if (index == AccountDataGrid.Items.Count - 1)
|
||||
AccountDataGrid.SelectedIndex = index - 1;
|
||||
else
|
||||
AccountDataGrid.SelectedIndex = index + 1;
|
||||
|
||||
_entities.SaveChanges(() => _entities.Accounts.Remove(account));
|
||||
|
||||
SetAccountButtonStates();
|
||||
}
|
||||
|
||||
private void HandleAddAccountButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
AddAccount();
|
||||
}
|
||||
|
||||
private void HandleEditAccountButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
EditSelectedAccount();
|
||||
}
|
||||
|
||||
private void HandleDeleteAccountButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
DeleteSelectedAccount();
|
||||
}
|
||||
|
||||
private void HandleAccountDataGridSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
SetAccountButtonStates();
|
||||
}
|
||||
|
||||
private void HandleAccountDataGridRowMouseDoubleClick(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
if (!EditAccountButton.IsEnabled)
|
||||
return;
|
||||
|
||||
EditSelectedAccount();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using FeedCenter.Data;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
@@ -12,9 +11,12 @@ public partial class BulkFeedWindow
|
||||
{
|
||||
private List<CheckedListItem<Feed>> _checkedListBoxItems;
|
||||
private CollectionViewSource _collectionViewSource;
|
||||
private readonly FeedCenterEntities _entities;
|
||||
|
||||
public BulkFeedWindow()
|
||||
public BulkFeedWindow(FeedCenterEntities entities)
|
||||
{
|
||||
_entities = entities;
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
@@ -22,7 +24,7 @@ public partial class BulkFeedWindow
|
||||
{
|
||||
_checkedListBoxItems = new List<CheckedListItem<Feed>>();
|
||||
|
||||
foreach (var feed in Database.Entities.Feeds)
|
||||
foreach (var feed in _entities.Feeds)
|
||||
_checkedListBoxItems.Add(new CheckedListItem<Feed> { Item = feed });
|
||||
|
||||
_collectionViewSource = new CollectionViewSource { Source = _checkedListBoxItems };
|
||||
@@ -52,7 +54,7 @@ public partial class BulkFeedWindow
|
||||
|
||||
private void HandleOkButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Database.Entities.SaveChanges(() =>
|
||||
_entities.SaveChanges(() =>
|
||||
{
|
||||
foreach (var item in _checkedListBoxItems.Where(i => i.IsChecked))
|
||||
{
|
||||
|
||||
@@ -24,14 +24,17 @@
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
|
||||
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
|
||||
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.FlatButton.xaml" />
|
||||
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Themes/light.cobalt.xaml" />
|
||||
<ResourceDictionary
|
||||
Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.FlatButton.xaml" />
|
||||
<ResourceDictionary
|
||||
Source="pack://application:,,,/MahApps.Metro;component/Styles/Themes/light.cobalt.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</Window.Resources>
|
||||
<StackPanel Margin="6"
|
||||
options:Spacing.Vertical="5">
|
||||
<TextBox mah:TextBoxHelper.UseFloatingWatermark="True"
|
||||
<TextBox Name="NameTextBox"
|
||||
mah:TextBoxHelper.UseFloatingWatermark="True"
|
||||
mah:TextBoxHelper.Watermark="{x:Static properties:Resources.categoryNameLabel}"
|
||||
mah:TextBoxHelper.SelectAllOnFocus="True"
|
||||
Text="{Binding Path=Name, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}" />
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
using System.Windows;
|
||||
using ChrisKaczor.Wpf.Validation;
|
||||
using FeedCenter.Data;
|
||||
using ChrisKaczor.Wpf.Validation;
|
||||
using System.Windows;
|
||||
|
||||
namespace FeedCenter.Options;
|
||||
|
||||
public partial class CategoryWindow
|
||||
{
|
||||
public CategoryWindow()
|
||||
private readonly FeedCenterEntities _entities;
|
||||
|
||||
public CategoryWindow(FeedCenterEntities entities)
|
||||
{
|
||||
_entities = entities;
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
@@ -30,7 +33,7 @@ public partial class CategoryWindow
|
||||
|
||||
private void HandleOkayButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var transaction = Database.Entities.BeginTransaction();
|
||||
var transaction = _entities.BeginTransaction();
|
||||
|
||||
if (!this.IsValid())
|
||||
{
|
||||
@@ -39,7 +42,6 @@ public partial class CategoryWindow
|
||||
}
|
||||
|
||||
transaction.Commit();
|
||||
Database.Entities.Refresh();
|
||||
|
||||
// Dialog is good
|
||||
DialogResult = true;
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace FeedCenter.Options;
|
||||
|
||||
public partial class DisplayOptionsPanel
|
||||
{
|
||||
public DisplayOptionsPanel(Window parentWindow) : base(parentWindow)
|
||||
public DisplayOptionsPanel(Window parentWindow, FeedCenterEntities entities) : base(parentWindow, entities)
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
using ChrisKaczor.Wpf.Validation;
|
||||
using FeedCenter.Data;
|
||||
using System.Windows;
|
||||
|
||||
namespace FeedCenter.Options;
|
||||
|
||||
public partial class FeedWindow
|
||||
{
|
||||
public FeedWindow()
|
||||
private readonly FeedCenterEntities _entities;
|
||||
|
||||
public FeedWindow(FeedCenterEntities entities)
|
||||
{
|
||||
_entities = entities;
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public bool? Display(Feed feed, Window owner)
|
||||
{
|
||||
CategoryComboBox.ItemsSource = Database.Entities.Categories;
|
||||
CategoryComboBox.ItemsSource = _entities.Categories;
|
||||
|
||||
DataContext = feed;
|
||||
|
||||
@@ -26,7 +29,7 @@ public partial class FeedWindow
|
||||
|
||||
private void HandleOkayButtonClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var transaction = Database.Entities.BeginTransaction();
|
||||
var transaction = _entities.BeginTransaction();
|
||||
|
||||
if (!this.IsValid(OptionsTabControl))
|
||||
{
|
||||
@@ -35,7 +38,6 @@ public partial class FeedWindow
|
||||
}
|
||||
|
||||
transaction.Commit();
|
||||
Database.Entities.Refresh();
|
||||
|
||||
DialogResult = true;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using FeedCenter.Data;
|
||||
using Microsoft.Win32;
|
||||
using Microsoft.Win32;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
@@ -14,9 +13,12 @@ namespace FeedCenter.Options;
|
||||
public partial class FeedsOptionsPanel
|
||||
{
|
||||
private CollectionViewSource _collectionViewSource;
|
||||
private readonly FeedCenterEntities _entities;
|
||||
|
||||
public FeedsOptionsPanel(Window parentWindow) : base(parentWindow)
|
||||
public FeedsOptionsPanel(Window parentWindow, FeedCenterEntities entities) : base(parentWindow, entities)
|
||||
{
|
||||
_entities = entities;
|
||||
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
@@ -26,7 +28,7 @@ public partial class FeedsOptionsPanel
|
||||
{
|
||||
base.LoadPanel();
|
||||
|
||||
var collectionViewSource = new CollectionViewSource { Source = Database.Entities.Categories };
|
||||
var collectionViewSource = new CollectionViewSource { Source = _entities.Categories };
|
||||
collectionViewSource.SortDescriptions.Add(new SortDescription("SortKey", ListSortDirection.Ascending));
|
||||
collectionViewSource.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
|
||||
collectionViewSource.IsLiveSortingRequested = true;
|
||||
@@ -44,20 +46,20 @@ public partial class FeedsOptionsPanel
|
||||
|
||||
private void AddFeed()
|
||||
{
|
||||
var feed = Feed.Create();
|
||||
var feed = Feed.Create(_entities);
|
||||
|
||||
var category = (Category) CategoryDataGrid.SelectedItem;
|
||||
|
||||
feed.CategoryId = category.Id;
|
||||
|
||||
var feedWindow = new FeedWindow();
|
||||
var feedWindow = new FeedWindow(_entities);
|
||||
|
||||
var result = feedWindow.Display(feed, Window.GetWindow(this));
|
||||
|
||||
if (!result.HasValue || !result.Value)
|
||||
return;
|
||||
|
||||
Database.Entities.SaveChanges(() => Database.Entities.Feeds.Add(feed));
|
||||
_entities.SaveChanges(() => _entities.Feeds.Add(feed));
|
||||
|
||||
FeedDataGrid.SelectedItem = feed;
|
||||
|
||||
@@ -71,7 +73,7 @@ public partial class FeedsOptionsPanel
|
||||
|
||||
var feed = (Feed) FeedDataGrid.SelectedItem;
|
||||
|
||||
var feedWindow = new FeedWindow();
|
||||
var feedWindow = new FeedWindow(_entities);
|
||||
|
||||
feedWindow.Display(feed, Window.GetWindow(this));
|
||||
}
|
||||
@@ -86,7 +88,7 @@ public partial class FeedsOptionsPanel
|
||||
FeedDataGrid.SelectedItems.CopyTo(selectedItems, 0);
|
||||
|
||||
foreach (var feed in selectedItems)
|
||||
Database.Entities.SaveChanges(() => Database.Entities.Feeds.Remove(feed));
|
||||
_entities.SaveChanges(() => _entities.Feeds.Remove(feed));
|
||||
|
||||
SetFeedButtonStates();
|
||||
}
|
||||
@@ -116,7 +118,7 @@ public partial class FeedsOptionsPanel
|
||||
ExportFeeds();
|
||||
}
|
||||
|
||||
private static void ExportFeeds()
|
||||
private void ExportFeeds()
|
||||
{
|
||||
var saveFileDialog = new SaveFileDialog
|
||||
{
|
||||
@@ -143,7 +145,7 @@ public partial class FeedsOptionsPanel
|
||||
xmlWriter.WriteStartElement("opml");
|
||||
xmlWriter.WriteStartElement("body");
|
||||
|
||||
foreach (var feed in Database.Entities.Feeds.OrderBy(feed => feed.Name))
|
||||
foreach (var feed in _entities.Feeds.OrderBy(feed => feed.Name))
|
||||
{
|
||||
xmlWriter.WriteStartElement("outline");
|
||||
|
||||
@@ -162,7 +164,7 @@ public partial class FeedsOptionsPanel
|
||||
xmlWriter.Close();
|
||||
}
|
||||
|
||||
private static void ImportFeeds()
|
||||
private void ImportFeeds()
|
||||
{
|
||||
var openFileDialog = new OpenFileDialog
|
||||
{
|
||||
@@ -188,8 +190,7 @@ public partial class FeedsOptionsPanel
|
||||
|
||||
while (xmlReader.NodeType != XmlNodeType.EndElement)
|
||||
{
|
||||
var feed = Feed.Create();
|
||||
feed.CategoryId = Database.Entities.Categories.First(c => c.IsDefault).Id;
|
||||
var feed = Feed.Create(_entities);
|
||||
|
||||
while (xmlReader.MoveToNextAttribute())
|
||||
{
|
||||
@@ -218,7 +219,7 @@ public partial class FeedsOptionsPanel
|
||||
if (string.IsNullOrEmpty(feed.Name))
|
||||
feed.Name = feed.Title;
|
||||
|
||||
Database.Entities.Feeds.Add(feed);
|
||||
_entities.SaveChanges(() => _entities.Feeds.Add(feed));
|
||||
|
||||
xmlReader.MoveToElement();
|
||||
|
||||
@@ -242,23 +243,23 @@ public partial class FeedsOptionsPanel
|
||||
var selectedId = ((Category) CategoryDataGrid.SelectedItem).Id;
|
||||
|
||||
EditCategoryButton.IsEnabled = CategoryDataGrid.SelectedItem != null &&
|
||||
selectedId != Database.Entities.DefaultCategory.Id;
|
||||
selectedId != _entities.DefaultCategory.Id;
|
||||
DeleteCategoryButton.IsEnabled = CategoryDataGrid.SelectedItem != null &&
|
||||
selectedId != Database.Entities.DefaultCategory.Id;
|
||||
selectedId != _entities.DefaultCategory.Id;
|
||||
}
|
||||
|
||||
private void AddCategory()
|
||||
{
|
||||
var category = new Category();
|
||||
|
||||
var categoryWindow = new CategoryWindow();
|
||||
var categoryWindow = new CategoryWindow(_entities);
|
||||
|
||||
var result = categoryWindow.Display(category, Window.GetWindow(this));
|
||||
|
||||
if (!result.HasValue || !result.Value)
|
||||
return;
|
||||
|
||||
Database.Entities.SaveChanges(() => Database.Entities.Categories.Add(category));
|
||||
_entities.SaveChanges(() => _entities.Categories.Add(category));
|
||||
|
||||
CategoryDataGrid.SelectedItem = category;
|
||||
|
||||
@@ -272,7 +273,7 @@ public partial class FeedsOptionsPanel
|
||||
|
||||
var category = (Category) CategoryDataGrid.SelectedItem;
|
||||
|
||||
var categoryWindow = new CategoryWindow();
|
||||
var categoryWindow = new CategoryWindow(_entities);
|
||||
|
||||
categoryWindow.Display(category, Window.GetWindow(this));
|
||||
}
|
||||
@@ -284,10 +285,10 @@ public partial class FeedsOptionsPanel
|
||||
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;
|
||||
var defaultCategory = _entities.DefaultCategory;
|
||||
|
||||
foreach (var feed in Database.Entities.Feeds.Where(f => f.CategoryId == category.Id))
|
||||
Database.Entities.SaveChanges(() => feed.CategoryId = defaultCategory.Id);
|
||||
foreach (var feed in _entities.Feeds.Where(f => f.CategoryId == category.Id))
|
||||
_entities.SaveChanges(() => feed.CategoryId = defaultCategory.Id);
|
||||
|
||||
var index = CategoryDataGrid.SelectedIndex;
|
||||
|
||||
@@ -296,7 +297,7 @@ public partial class FeedsOptionsPanel
|
||||
else
|
||||
CategoryDataGrid.SelectedIndex = index + 1;
|
||||
|
||||
Database.Entities.SaveChanges(() => Database.Entities.Categories.Remove(category));
|
||||
_entities.SaveChanges(() => _entities.Categories.Remove(category));
|
||||
|
||||
SetCategoryButtonStates();
|
||||
}
|
||||
@@ -320,7 +321,7 @@ public partial class FeedsOptionsPanel
|
||||
{
|
||||
if (_collectionViewSource == null)
|
||||
{
|
||||
_collectionViewSource = new CollectionViewSource { Source = Database.Entities.Feeds };
|
||||
_collectionViewSource = new CollectionViewSource { Source = _entities.Feeds };
|
||||
_collectionViewSource.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
|
||||
_collectionViewSource.Filter += HandleCollectionViewSourceFilter;
|
||||
|
||||
@@ -342,7 +343,7 @@ public partial class FeedsOptionsPanel
|
||||
|
||||
var feed = (Feed) e.Item;
|
||||
|
||||
e.Accepted = feed.CategoryId == selectedCategory.Id;
|
||||
e.Accepted = feed.CategoryId == selectedCategory.Id && feed.Account.Type == AccountType.Local;
|
||||
}
|
||||
|
||||
private void HandleCategoryDataGridRowDrop(object sender, DragEventArgs e)
|
||||
@@ -352,7 +353,7 @@ public partial class FeedsOptionsPanel
|
||||
var category = (Category) ((DataGridRow) sender).Item;
|
||||
|
||||
foreach (var feed in feedList!)
|
||||
Database.Entities.SaveChanges(() => feed.CategoryId = category.Id);
|
||||
_entities.SaveChanges(() => feed.CategoryId = category.Id);
|
||||
|
||||
_collectionViewSource.View.Refresh();
|
||||
|
||||
@@ -382,7 +383,7 @@ public partial class FeedsOptionsPanel
|
||||
|
||||
private void HandleMultipleEditClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var bulkFeedWindow = new BulkFeedWindow();
|
||||
var bulkFeedWindow = new BulkFeedWindow(_entities);
|
||||
bulkFeedWindow.Display(Window.GetWindow(this));
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace FeedCenter.Options;
|
||||
|
||||
public partial class GeneralOptionsPanel
|
||||
{
|
||||
public GeneralOptionsPanel(Window parentWindow) : base(parentWindow)
|
||||
public GeneralOptionsPanel(Window parentWindow, FeedCenterEntities entities) : base(parentWindow, entities)
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
@@ -6,10 +6,12 @@ namespace FeedCenter.Options;
|
||||
public class OptionsPanelBase : UserControl
|
||||
{
|
||||
protected readonly Window ParentWindow;
|
||||
protected readonly FeedCenterEntities Entities;
|
||||
|
||||
protected OptionsPanelBase(Window parentWindow)
|
||||
protected OptionsPanelBase(Window parentWindow, FeedCenterEntities entities)
|
||||
{
|
||||
ParentWindow = parentWindow;
|
||||
Entities = entities;
|
||||
}
|
||||
|
||||
public virtual string CategoryName => null;
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace FeedCenter.Options;
|
||||
public partial class OptionsWindow
|
||||
{
|
||||
private readonly List<OptionsPanelBase> _optionPanels = new();
|
||||
private readonly FeedCenterEntities _entities = new();
|
||||
|
||||
public OptionsWindow()
|
||||
{
|
||||
@@ -20,11 +21,12 @@ public partial class OptionsWindow
|
||||
|
||||
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));
|
||||
_optionPanels.Add(new GeneralOptionsPanel(this, _entities));
|
||||
_optionPanels.Add(new DisplayOptionsPanel(this, _entities));
|
||||
_optionPanels.Add(new FeedsOptionsPanel(this, _entities));
|
||||
_optionPanels.Add(new AccountsOptionsPanel(this, _entities));
|
||||
_optionPanels.Add(new UpdateOptionsPanel(this, _entities));
|
||||
_optionPanels.Add(new AboutOptionsPanel(this, _entities));
|
||||
}
|
||||
|
||||
private void LoadCategories()
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace FeedCenter.Options;
|
||||
|
||||
public partial class UpdateOptionsPanel
|
||||
{
|
||||
public UpdateOptionsPanel(Window parentWindow) : base(parentWindow)
|
||||
public UpdateOptionsPanel(Window parentWindow, FeedCenterEntities entities) : base(parentWindow, entities)
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user