Initial commit

This commit is contained in:
2014-04-30 17:47:28 -04:00
commit 60d6f93543
102 changed files with 11747 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
<Options:OptionsPanelBase x:Class="FeedCenter.Options.AboutOptionsPanel"
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"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="300">
<Grid>
<TextBlock Text="Label"
Name="applicationNameLabel"
VerticalAlignment="Top"
FontWeight="Bold" />
<TextBlock Text="Label"
Margin="0,22,0,0"
Name="versionLabel"
VerticalAlignment="Top" />
<TextBlock Text="Label"
Margin="0,44,0,0"
Name="companyLabel"
VerticalAlignment="Top" />
</Grid>
</Options:OptionsPanelBase>

View File

@@ -0,0 +1,39 @@
using System.Deployment.Application;
using System.Reflection;
namespace FeedCenter.Options
{
public partial class AboutOptionsPanel
{
public AboutOptionsPanel()
{
InitializeComponent();
}
public override void LoadPanel(FeedCenterEntities database)
{
base.LoadPanel(database);
applicationNameLabel.Text = Properties.Resources.ApplicationDisplayName;
string version = (ApplicationDeployment.IsNetworkDeployed ? ApplicationDeployment.CurrentDeployment.CurrentVersion.ToString() : "0");
versionLabel.Text = string.Format(Properties.Resources.Version, version);
companyLabel.Text = ((AssemblyCompanyAttribute) Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false)[0]).Company;
}
public override bool ValidatePanel()
{
return true;
}
public override void SavePanel()
{
}
public override string CategoryName
{
get { return Properties.Resources.optionCategoryAbout; }
}
}
}

127
Options/BulkFeedWindow.xaml Normal file
View File

@@ -0,0 +1,127 @@
<Window x:Class="FeedCenter.Options.BulkFeedWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="{x:Static my:Resources.BulkFeedWindow}"
Height="300"
Width="500"
xmlns:my="clr-namespace:FeedCenter.Properties"
xmlns:Options="clr-namespace:FeedCenter.Options"
xmlns:LinkControl="clr-namespace:Common.Wpf.LinkControl;assembly=Common.Wpf"
WindowStartupLocation="CenterOwner"
Icon="/FeedCenter;component/Resources/Application.ico"
FocusManager.FocusedElement="{Binding ElementName=feedLinkFilterText}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Label Content="{x:Static my:Resources.FeedLinkFilterLabel}"
Name="feedLinkFilterLabel"
Margin="6"
Padding="0"
VerticalContentAlignment="Center"
Target="{Binding ElementName=feedLinkFilterText}" />
<TextBox Grid.Column="1"
Name="feedLinkFilterText"
Margin="6"
TextChanged="HandleFilterTextChanged" />
<Border Grid.Row="1"
Grid.ColumnSpan="2"
Margin="6"
BorderThickness="1"
BorderBrush="{DynamicResource {x:Static SystemColors.ActiveBorderBrushKey}}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ScrollViewer ScrollViewer.VerticalScrollBarVisibility="Auto">
<ItemsControl Name="filteredFeedsList">
<ItemsControl.ItemTemplate>
<DataTemplate>
<CheckBox Margin="2"
Content="{Binding Item.Name}"
IsChecked="{Binding IsChecked}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
<Border Grid.Row="1"
BorderThickness="0,1,0,0"
BorderBrush="{DynamicResource {x:Static SystemColors.ActiveBorderBrushKey}}">
<StackPanel Orientation="Horizontal"
Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}">
<TextBlock Margin="2"
Text="{x:Static my:Resources.SelectLabel}">
</TextBlock>
<LinkControl:LinkControl Margin="2"
Click="HandleSelectAll"
Text="{x:Static my:Resources.SelectAllLabel}">
</LinkControl:LinkControl>
<LinkControl:LinkControl Margin="2"
Click="HandleSelectNone"
Text="{x:Static my:Resources.SelectNoneLabel}">
</LinkControl:LinkControl>
<LinkControl:LinkControl Margin="2"
Click="HandleSelectInvert"
Text="{x:Static my:Resources.SelectInvertLabel}">
</LinkControl:LinkControl>
</StackPanel>
</Border>
</Grid>
</Border>
<Grid Grid.Row="2"
MouseRightButtonUp="HandleGridMouseRightButtonUp"
ToolTip="{x:Static my:Resources.EnableHint}">
<Label Content="{x:Static my:Resources.openLabel}"
Name="openLabel"
Padding="4,0,0,0"
Margin="6,8,6,6"
ToolTip="{x:Static my:Resources.DisableHint}"
IsEnabled="False" />
</Grid>
<Grid Grid.Column="1"
Grid.Row="2"
MouseRightButtonUp="HandleGridMouseRightButtonUp"
ToolTip="{x:Static my:Resources.EnableHint}">
<ComboBox Name="openComboBox"
VerticalContentAlignment="Center"
SelectedIndex="0"
Margin="6"
ToolTip="{x:Static my:Resources.DisableHint}"
IsEnabled="False">
<ComboBoxItem Content="{x:Static my:Resources.openAllMultipleToolbarButton}"
Tag="{x:Static Options:MultipleOpenAction.IndividualPages}" />
<ComboBoxItem Content="{x:Static my:Resources.openAllSingleToolbarButton}"
Tag="{x:Static Options:MultipleOpenAction.SinglePage}" />
</ComboBox>
</Grid>
<Button Content="{x:Static my:Resources.OkayButton}"
Height="23"
HorizontalAlignment="Right"
IsDefault="True"
Margin="0,6,87,6"
Name="okButton"
VerticalAlignment="Bottom"
Width="75"
Grid.Column="1"
Grid.Row="3"
Click="HandleOkButtonClick" />
<Button Content="{x:Static my:Resources.CancelButton}"
Grid.Column="1"
Height="23"
HorizontalAlignment="Right"
IsCancel="True"
Margin="0,6,6,6"
Name="cancelButton"
VerticalAlignment="Bottom"
Width="75"
Grid.Row="3" />
</Grid>
</Window>

View File

@@ -0,0 +1,102 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using Common.Wpf;
namespace FeedCenter.Options
{
public partial class BulkFeedWindow
{
private List<CheckedListItem<Feed>> _checkedListBoxItems;
private CollectionViewSource _collectionViewSource;
public BulkFeedWindow()
{
InitializeComponent();
}
public bool? Display(Window window, FeedCenterEntities database)
{
_checkedListBoxItems = new List<CheckedListItem<Feed>>();
foreach (var feed in database.AllFeeds)
_checkedListBoxItems.Add(new CheckedListItem<Feed> { Item = feed });
_collectionViewSource = new CollectionViewSource { Source = _checkedListBoxItems };
_collectionViewSource.SortDescriptions.Add(new SortDescription("Item.Name", ListSortDirection.Ascending));
_collectionViewSource.Filter += HandleCollectionViewSourceFilter;
filteredFeedsList.ItemsSource = _collectionViewSource.View;
Owner = window;
return ShowDialog();
}
void HandleCollectionViewSourceFilter(object sender, FilterEventArgs e)
{
CheckedListItem<Feed> checkedListBoxItem = (CheckedListItem<Feed>) e.Item;
Feed feed = checkedListBoxItem.Item;
e.Accepted = feed.Link.Contains(feedLinkFilterText.Text);
}
private void HandleFilterTextChanged(object sender, TextChangedEventArgs e)
{
_collectionViewSource.View.Refresh();
}
private void HandleOkButtonClick(object sender, RoutedEventArgs e)
{
foreach (var item in _checkedListBoxItems.Where(i => i.IsChecked))
{
if (openComboBox.IsEnabled)
item.Item.MultipleOpenAction = (int) ((ComboBoxItem) openComboBox.SelectedItem).Tag;
}
DialogResult = true;
Close();
}
private void HandleSelectAll(object sender, RoutedEventArgs e)
{
foreach (var viewItem in _collectionViewSource.View)
{
var checkedListItem = (CheckedListItem<Feed>) viewItem;
checkedListItem.IsChecked = true;
}
}
private void HandleSelectNone(object sender, RoutedEventArgs e)
{
foreach (var viewItem in _collectionViewSource.View)
{
var checkedListItem = (CheckedListItem<Feed>) viewItem;
checkedListItem.IsChecked = false;
}
}
private void HandleSelectInvert(object sender, RoutedEventArgs e)
{
foreach (var viewItem in _collectionViewSource.View)
{
var checkedListItem = (CheckedListItem<Feed>) viewItem;
checkedListItem.IsChecked = !checkedListItem.IsChecked;
}
}
private void HandleGridMouseRightButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
openLabel.IsEnabled = !openLabel.IsEnabled;
openComboBox.IsEnabled = !openComboBox.IsEnabled;
}
}
}

View File

@@ -0,0 +1,45 @@
<Window x:Class="FeedCenter.Options.CategoryWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Properties="clr-namespace:FeedCenter.Properties"
Title="CategoryWindow"
Height="119"
Width="339"
WindowStartupLocation="CenterOwner"
Icon="/FeedCenter;component/Resources/Application.ico"
FocusManager.FocusedElement="{Binding ElementName=nameTextBox}" >
<Grid Name="mainGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="367*" />
</Grid.ColumnDefinitions>
<Label Content="{x:Static Properties:Resources.feedCategoryLabel}"
HorizontalAlignment="Left" Name="urlLabel"
Target="{Binding ElementName=nameTextBox}"
VerticalAlignment="Top"
VerticalContentAlignment="Center"
Margin="12,12,0,0" />
<TextBox Margin="7,14,12,0"
Name="nameTextBox"
Text="{Binding Path=Name, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}"
VerticalAlignment="Top"
Grid.Column="1" />
<Button Content="{x:Static Properties:Resources.OkayButton}"
Height="23"
HorizontalAlignment="Right"
Name="okButton"
VerticalAlignment="Bottom"
Width="75"
IsDefault="True"
Margin="0,0,93,12"
Click="HandleOkayButtonClick" Grid.Column="1" />
<Button Content="{x:Static Properties:Resources.CancelButton}"
Height="23"
HorizontalAlignment="Right"
Name="cancelButton"
VerticalAlignment="Bottom"
Width="75"
IsCancel="True"
Margin="0,0,12,12" Grid.Column="1" />
</Grid>
</Window>

View File

@@ -0,0 +1,69 @@
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using Common.Wpf.Extensions;
namespace FeedCenter.Options
{
public partial class CategoryWindow
{
public CategoryWindow()
{
InitializeComponent();
}
public bool? Display(Category category, Window owner)
{
// Set the data context
DataContext = category;
// Set the title based on the state of the category
Title = string.IsNullOrWhiteSpace(category.Name) ? Properties.Resources.CategoryWindowAdd : Properties.Resources.CategoryWindowEdit;
// Set the window owner
Owner = owner;
// Show the dialog and result the result
return ShowDialog();
}
private void HandleOkayButtonClick(object sender, RoutedEventArgs e)
{
// Get a list of all explicit binding expressions
Dictionary<FrameworkElement, BindingExpression> bindingExpressionDictionary = this.GetExplicitBindingExpressions();
// Get the values as a list
List<BindingExpression> bindingExpressions = bindingExpressionDictionary.Values.ToList();
// Loop over each binding expression and clear any existing error
bindingExpressions.ForEach(Validation.ClearInvalid);
// Force all explicit bindings to update the source
bindingExpressions.ForEach(bindingExpression => bindingExpression.UpdateSource());
// See if there are any errors
bool hasError = bindingExpressions.Exists(bindingExpression => bindingExpression.HasError);
// If there was an error then set focus to the bad controls
if (hasError)
{
// Get the first framework element with an error
FrameworkElement firstErrorElement = bindingExpressionDictionary.First(pair => pair.Value.HasError).Key;
// Set focus
firstErrorElement.Focus();
return;
}
// Dialog is good
DialogResult = true;
// Close the dialog
Close();
}
}
}

View File

@@ -0,0 +1,64 @@
<Options:OptionsPanelBase x:Class="FeedCenter.Options.DisplayOptionsPanel"
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"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="300">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<CheckBox Content="{x:Static Properties:Resources.lockWindowCheckBox}"
Height="16"
HorizontalAlignment="Left"
Name="lockWindowCheckBox"
VerticalAlignment="Top"
Width="300"
Grid.ColumnSpan="2" />
<CheckBox Content="{x:Static Properties:Resources.displayEmptyFeedsCheckBox}"
Height="16"
HorizontalAlignment="Left"
Margin="0,22,0,0"
Name="displayEmptyFeedsCheckBox"
VerticalAlignment="Top"
Width="300"
Grid.ColumnSpan="2" />
<Label Content="{x:Static Properties:Resources.toolbarLocationLabel}"
Name="toolbarLocationLabel"
VerticalAlignment="Top"
Margin="0,50,0,0"
Padding="0,5,5,5"
Target="{Binding ElementName=toolbarLocationComboBox}"
Width="97" />
<ComboBox Margin="8,53,0,0"
Name="toolbarLocationComboBox"
VerticalAlignment="Top" Grid.Column="1">
<ComboBoxItem Content="{x:Static Properties:Resources.Top}"
Tag="{x:Static Dock.Top}" />
<ComboBoxItem Content="{x:Static Properties:Resources.Bottom}"
Tag="{x:Static Dock.Bottom}" />
</ComboBox>
<Label Content="{x:Static Properties:Resources.multipleLineDisplayLabel}"
Name="multipleLineDisplayLabel"
VerticalAlignment="Top"
Margin="0,82,0,0"
Padding="0,5,5,5"
Target="{Binding ElementName=multipleLineDisplayComboBox}"
Width="97" />
<ComboBox Margin="8,86,0,0"
Name="multipleLineDisplayComboBox"
VerticalAlignment="Top" Grid.Column="1">
<ComboBoxItem Content="{x:Static Properties:Resources.multipleLineDisplayNormal}"
Tag="{x:Static Options:MultipleLineDisplay.Normal}" />
<ComboBoxItem Content="{x:Static Properties:Resources.multipleLineDisplaySingleLine}"
Tag="{x:Static Options:MultipleLineDisplay.SingleLine}" />
<ComboBoxItem Content="{x:Static Properties:Resources.multipleLineDisplayFirstLine}"
Tag="{x:Static Options:MultipleLineDisplay.FirstLine}" />
</ComboBox>
</Grid>
</Options:OptionsPanelBase>

View File

@@ -0,0 +1,52 @@
using System.Linq;
using System.Windows.Controls;
using FeedCenter.Properties;
namespace FeedCenter.Options
{
public partial class DisplayOptionsPanel
{
public DisplayOptionsPanel()
{
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;
Dock dock = (Dock) ((ComboBoxItem) toolbarLocationComboBox.SelectedItem).Tag;
if (Settings.Default.ToolbarLocation != dock)
Settings.Default.ToolbarLocation = dock;
MultipleLineDisplay multipleLineDisplay = (MultipleLineDisplay) ((ComboBoxItem) multipleLineDisplayComboBox.SelectedItem).Tag;
if (Settings.Default.MultipleLineDisplay != multipleLineDisplay)
Settings.Default.MultipleLineDisplay = multipleLineDisplay;
}
public override string CategoryName
{
get { return Properties.Resources.optionCategoryDisplay; }
}
}
}

195
Options/FeedWindow.xaml Normal file
View File

@@ -0,0 +1,195 @@
<Window x:Class="FeedCenter.Options.FeedWindow"
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:Options="clr-namespace:FeedCenter.Options"
Title="FeedWindow"
Height="300"
Width="450"
WindowStartupLocation="CenterOwner"
Icon="/FeedCenter;component/Resources/Application.ico"
FocusManager.FocusedElement="{Binding ElementName=urlTextBox}">
<Window.Resources>
<Options:MultipleOpenActionConverter x:Key="multipleOpenActionConverter" />
</Window.Resources>
<Grid Name="mainGrid">
<TabControl Name="optionsTabControl"
Margin="12,12,12,41">
<TabItem Header="{x:Static Properties:Resources.generalTab}"
Name="generalTab">
<Grid Name="generalGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Content="{x:Static Properties:Resources.feedUrlLabel}"
Name="urlLabel"
VerticalContentAlignment="Center"
Target="{Binding ElementName=urlTextBox}"
Margin="6"
Padding="0" />
<TextBox Name="urlTextBox"
Grid.Column="1"
Text="{Binding Path=Source, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}"
Margin="6" />
<Label Content="{x:Static Properties:Resources.feedNameLabel}"
Name="nameLabel"
VerticalContentAlignment="Center"
Target="{Binding ElementName=nameTextBox}"
Grid.Row="1"
Margin="6"
Padding="0" />
<TextBox Name="nameTextBox"
Grid.Column="1"
Text="{Binding Path=Name, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=true}"
Grid.Row="1"
Margin="6" />
<Label Content="{x:Static Properties:Resources.feedCategoryLabel}"
Name="feedCategoryLabel"
Target="{Binding ElementName=categoryComboBox}"
VerticalContentAlignment="Center"
Grid.Row="2"
Margin="6"
Padding="0" />
<ComboBox Grid.Column="1"
Name="categoryComboBox"
DisplayMemberPath="Name"
SelectedValuePath="ID"
SelectedValue="{Binding Path=CategoryID}"
Grid.Row="2"
Margin="6" />
<CheckBox Grid.ColumnSpan="2"
Name="readIntervalCheckBox"
VerticalContentAlignment="Center"
IsChecked="{Binding Path=Enabled, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}"
Grid.Row="3"
Margin="6">
<DockPanel>
<Label Content="{x:Static Properties:Resources.feedReadIntervalPrefix}"
HorizontalAlignment="Left"
Margin="0,0,5,0"
VerticalAlignment="Center"
Padding="0" />
<TextBox Width="50"
Name="readIntervalTextBox"
Text="{Binding Path=CheckInterval, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}"
IsEnabled="{Binding ElementName=readIntervalCheckBox, Path=IsChecked}" />
<Label Content="{x:Static Properties:Resources.feedReadIntervalSuffix}"
HorizontalAlignment="Left"
Margin="5,0,0,0"
VerticalAlignment="Center"
Padding="0" />
</DockPanel>
</CheckBox>
</Grid>
</TabItem>
<TabItem Header="{x:Static Properties:Resources.readingTab}"
Name="readingTab">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label Content="{x:Static Properties:Resources.openLabel}"
Name="openLabel"
Target="{Binding ElementName=openComboBox}"
Padding="0"
VerticalContentAlignment="Center"
Margin="6" />
<ComboBox Name="openComboBox"
VerticalContentAlignment="Center"
SelectedValue="{Binding Path=MultipleOpenAction, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=true, Converter={StaticResource multipleOpenActionConverter}}"
SelectedValuePath="Tag"
Grid.Column="1"
Margin="6">
<ComboBoxItem Content="{x:Static Properties:Resources.openAllSingleToolbarButton}"
Tag="{x:Static Options:MultipleOpenAction.SinglePage}" />
<ComboBoxItem Content="{x:Static Properties:Resources.openAllMultipleToolbarButton}"
Tag="{x:Static Options:MultipleOpenAction.IndividualPages}" />
</ComboBox>
</Grid>
</TabItem>
<TabItem Header="{x:Static Properties:Resources.authenticationTab}"
Name="authenticationTab">
<Grid Name="authenticationGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<CheckBox Content="{x:Static Properties:Resources.requiresAuthenticationCheckBox}"
Name="requiresAuthenticationCheckBox"
Grid.ColumnSpan="2"
Grid.Row="0"
Grid.Column="0"
IsChecked="{Binding Path=Authenticate, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}"
Margin="6" />
<Label Content="{x:Static Properties:Resources.authenticationUserNameLabel}"
Name="authenticationUserNameLabel"
Target="{Binding ElementName=authenticationUserNameTextBox}"
VerticalContentAlignment="Center"
IsEnabled="{Binding ElementName=requiresAuthenticationCheckBox, Path=IsChecked}"
Grid.Row="1"
Margin="6"
Padding="20,0,0,0" />
<TextBox Name="authenticationUserNameTextBox"
Text="{Binding Path=UserName, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}"
Grid.Column="1"
IsEnabled="{Binding ElementName=requiresAuthenticationCheckBox, Path=IsChecked}"
Grid.Row="1"
Margin="6" />
<Label Content="{x:Static Properties:Resources.authenticationPasswordLabel}"
Name="authenticationPasswordLabel"
Target="{Binding ElementName=authenticationPasswordTextBox}"
VerticalContentAlignment="Center"
IsEnabled="{Binding ElementName=requiresAuthenticationCheckBox, Path=IsChecked}"
Grid.Row="2"
Margin="6"
Padding="20,0,0,0" />
<TextBox Name="authenticationPasswordTextBox"
Text="{Binding Path=Password, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}"
Grid.Column="1"
IsEnabled="{Binding ElementName=requiresAuthenticationCheckBox, Path=IsChecked}"
Grid.Row="2"
Margin="6" />
</Grid>
</TabItem>
</TabControl>
<Button Content="{x:Static Properties:Resources.OkayButton}"
Height="23"
HorizontalAlignment="Right"
Name="okButton"
VerticalAlignment="Bottom"
Width="75"
IsDefault="True"
Margin="0,0,93,12"
Click="HandleOkayButtonClick" />
<Button Content="{x:Static Properties:Resources.CancelButton}"
Height="23"
HorizontalAlignment="Right"
Name="cancelButton"
VerticalAlignment="Bottom"
Width="75"
IsCancel="True"
Margin="0,0,12,12" />
</Grid>
</Window>

View File

@@ -0,0 +1,88 @@
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using Common.Wpf.Extensions;
namespace FeedCenter.Options
{
public partial class FeedWindow
{
public FeedWindow()
{
InitializeComponent();
}
public bool? Display(FeedCenterEntities database, Feed feed, Window owner)
{
// Bind the category combo box
categoryComboBox.ItemsSource = database.Categories;
// Set the data context
DataContext = feed;
// Set the title based on the state of the feed
Title = string.IsNullOrWhiteSpace(feed.Link) ? Properties.Resources.FeedWindowAdd : Properties.Resources.FeedWindowEdit;
// Set the window owner
Owner = owner;
// Show the dialog and result the result
return ShowDialog();
}
private void HandleOkayButtonClick(object sender, RoutedEventArgs e)
{
// Get a dictionary of all framework elements and explicit binding expressions
Dictionary<FrameworkElement, BindingExpression> bindingExpressionDictionary = this.GetExplicitBindingExpressions();
// Get just the binding expressions
var bindingExpressions = bindingExpressionDictionary.Values;
// Loop over each binding expression and clear any existing error
this.ClearAllValidationErrors(bindingExpressions);
// Force all explicit bindings to update the source
this.UpdateAllSources(bindingExpressions);
// See if there are any errors
bool hasError = bindingExpressions.Any(b => b.HasError);
// If there was an error then set focus to the bad controls
if (hasError)
{
// Get the first framework element with an error
FrameworkElement firstErrorElement = bindingExpressionDictionary.First(pair => pair.Value.HasError).Key;
// Loop over each tab item
foreach (TabItem tabItem in optionsTabControl.Items)
{
// Cast the content as visual
Visual content = (Visual) tabItem.Content;
// See if the control with the error is a descendant
if (firstErrorElement.IsDescendantOf(content))
{
// Select the tab
tabItem.IsSelected = true;
break;
}
}
// Set focus
firstErrorElement.Focus();
return;
}
// Dialog is good
DialogResult = true;
// Close the dialog
Close();
}
}
}

View File

@@ -0,0 +1,161 @@
<Options:OptionsPanelBase x:Class="FeedCenter.Options.FeedsOptionsPanel"
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:LinkControl="clr-namespace:Common.Wpf.LinkControl;assembly=Common.Wpf"
xmlns:Properties="clr-namespace:FeedCenter.Properties"
mc:Ignorable="d"
d:DesignHeight="311"
d:DesignWidth="425">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" />
<ColumnDefinition Width="5" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<DataGrid Name="feedListBox"
SelectionMode="Extended"
Grid.Column="2"
Grid.Row="0"
AutoGenerateColumns="False"
GridLinesVisibility="None"
CanUserResizeRows="False"
IsReadOnly="True"
HeadersVisibility="Column"
Background="{x:Null}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Name}"
Header="{x:Static Properties:Resources.FeedNameColumnHeader}"
SortDirection="Ascending"
Width="*" />
<DataGridTextColumn Binding="{Binding LastUpdated, StringFormat=d}"
Header="{x:Static Properties:Resources.LastUpdatedColumnHeader}"
Width="Auto" />
</DataGrid.Columns>
<DataGrid.ItemContainerStyle>
<Style TargetType="DataGridRow">
<EventSetter Event="MouseDoubleClick"
Handler="HandleListBoxItemMouseDoubleClick" />
<EventSetter Event="PreviewMouseMove"
Handler="HandleListBoxItemPreviewMouseMove" />
</Style>
</DataGrid.ItemContainerStyle>
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="BorderThickness"
Value="0" />
</Style>
</DataGrid.CellStyle>
</DataGrid>
<DataGrid Name="categoryListBox"
SelectionChanged="HandleCategoryListBoxSelectionChanged"
Grid.Row="0"
SelectionMode="Extended"
Grid.Column="0"
AutoGenerateColumns="False"
GridLinesVisibility="None"
CanUserResizeRows="False"
IsReadOnly="True"
HeadersVisibility="Column"
AllowDrop="True"
Background="{x:Null}">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Name}"
Header="{x:Static Properties:Resources.CategoryNameColumnHeader}"
SortDirection="Ascending"
Width="*" />
</DataGrid.Columns>
<DataGrid.ItemContainerStyle>
<Style TargetType="DataGridRow">
<EventSetter Event="Drop"
Handler="HandleTextBlockDrop" />
<EventSetter Event="DragEnter"
Handler="HandleTextBlockDragEnter" />
<EventSetter Event="DragLeave"
Handler="HandleTextBlockDragLeave" />
</Style>
</DataGrid.ItemContainerStyle>
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="BorderThickness"
Value="0" />
</Style>
</DataGrid.CellStyle>
</DataGrid>
<Border Grid.Column="2"
Grid.Row="1"
BorderThickness="1,0,1,1"
BorderBrush="{DynamicResource {x:Static SystemColors.ActiveBorderBrushKey}}">
<StackPanel Orientation="Horizontal"
Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}">
<LinkControl:LinkControl Name="addFeedButton"
Margin="2"
Click="HandleAddFeedButtonClick"
Text="{x:Static Properties:Resources.AddLink}"
ToolTip="{x:Static Properties:Resources.AddFeedButton}">
</LinkControl:LinkControl>
<LinkControl:LinkControl Name="editFeedButton"
Margin="2"
Click="HandleEditFeedButtonClick"
Text="{x:Static Properties:Resources.EditLink}"
ToolTip="{x:Static Properties:Resources.EditFeedButton}">
</LinkControl:LinkControl>
<LinkControl:LinkControl Name="deleteFeedButton"
Margin="2"
Click="HandleDeleteFeedButtonClick"
Text="{x:Static Properties:Resources.DeleteLink}"
ToolTip="{x:Static Properties:Resources.DeleteFeedButton}">
</LinkControl:LinkControl>
<LinkControl:LinkControl Name="importButton"
Margin="6,2,2,2"
Click="HandleImportButtonClick"
Text="{x:Static Properties:Resources.ImportLink}"
ToolTip="{x:Static Properties:Resources.ImportFeedsButton}">
</LinkControl:LinkControl>
<LinkControl:LinkControl Name="exportButton"
Margin="2"
Click="HandleExportButtonClick"
Text="{x:Static Properties:Resources.ExportLink}"
ToolTip="{x:Static Properties:Resources.ExportFeedsButton}">
</LinkControl:LinkControl>
<LinkControl:LinkControl Name="multipleEditButton"
Margin="6,2,2,2"
Click="HandleMultipleEditClick"
Text="{x:Static Properties:Resources.MultipleEditLink}"
ToolTip="{x:Static Properties:Resources.MultipleEditButton}">
</LinkControl:LinkControl>
</StackPanel>
</Border>
<Border Grid.Row="1"
BorderThickness="1,0,1,1"
BorderBrush="{DynamicResource {x:Static SystemColors.ActiveBorderBrushKey}}">
<StackPanel Orientation="Horizontal"
Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}">
<LinkControl:LinkControl Name="addCategoryButton"
Margin="2"
Click="HandleAddCategoryButtonClick"
Text="{x:Static Properties:Resources.AddLink}"
ToolTip="{x:Static Properties:Resources.AddCategoryButton}">
</LinkControl:LinkControl>
<LinkControl:LinkControl Name="editCategoryButton"
Margin="2"
Click="HandleEditCategoryButtonClick"
Text="{x:Static Properties:Resources.EditLink}"
ToolTip="{x:Static Properties:Resources.EditCategoryButton}">
</LinkControl:LinkControl>
<LinkControl:LinkControl Name="deleteCategoryButton"
Margin="2"
Click="HandleDeleteCategoryButtonClick"
Text="{x:Static Properties:Resources.DeleteLink}"
ToolTip="{x:Static Properties:Resources.DeleteCategoryButton}">
</LinkControl:LinkControl>
</StackPanel>
</Border>
</Grid>
</Options:OptionsPanelBase>

View File

@@ -0,0 +1,433 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Xml;
using Microsoft.Win32;
namespace FeedCenter.Options
{
public partial class FeedsOptionsPanel
{
#region Constructor
public FeedsOptionsPanel()
{
InitializeComponent();
}
#endregion
#region OptionsPanelBase overrides
public override void LoadPanel(FeedCenterEntities database)
{
base.LoadPanel(database);
CollectionViewSource collectionViewSource = new CollectionViewSource { Source = Database.AllCategories };
collectionViewSource.SortDescriptions.Add(new SortDescription("SortKey", ListSortDirection.Ascending));
collectionViewSource.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
categoryListBox.ItemsSource = collectionViewSource.View;
categoryListBox.SelectedIndex = 0;
}
public override bool ValidatePanel()
{
return true;
}
public override void SavePanel()
{ }
public override string CategoryName
{
get { return Properties.Resources.optionCategoryFeeds; }
}
#endregion
#region Feed list management
private void SetFeedButtonStates()
{
addFeedButton.IsEnabled = true;
editFeedButton.IsEnabled = (feedListBox.SelectedItem != null);
deleteFeedButton.IsEnabled = (feedListBox.SelectedItem != null);
}
private void AddFeed()
{
Feed feed = new Feed();
FeedWindow feedWindow = new FeedWindow();
bool? result = feedWindow.Display(Database, feed, Window.GetWindow(this));
if (result.HasValue && result.Value)
{
Database.Feeds.AddObject(feed);
feedListBox.SelectedItem = feed;
SetFeedButtonStates();
}
}
private void EditSelectedFeed()
{
if (feedListBox.SelectedItem == null)
return;
Feed feed = (Feed) feedListBox.SelectedItem;
FeedWindow feedWindow = new FeedWindow();
feedWindow.Display(Database, feed, Window.GetWindow(this));
}
private void DeleteSelectedFeed()
{
Feed feed = (Feed) feedListBox.SelectedItem;
Database.Feeds.DeleteObject(feed);
SetFeedButtonStates();
}
#endregion
#region Feed event handlers
private void HandleAddFeedButtonClick(object sender, RoutedEventArgs e)
{
AddFeed();
}
private void HandleEditFeedButtonClick(object sender, RoutedEventArgs e)
{
EditSelectedFeed();
}
private void HandleDeleteFeedButtonClick(object sender, RoutedEventArgs e)
{
DeleteSelectedFeed();
}
private void HandleImportButtonClick(object sender, RoutedEventArgs e)
{
ImportFeeds();
}
private void HandleExportButtonClick(object sender, RoutedEventArgs e)
{
ExportFeeds();
}
#endregion
#region Feed import and export
private void ExportFeeds()
{
// Setup the save file dialog
SaveFileDialog saveFileDialog = new SaveFileDialog
{
Filter = Properties.Resources.ImportExportFilter,
FilterIndex = 0,
OverwritePrompt = true
};
bool? result = saveFileDialog.ShowDialog();
if (!result.Value)
return;
// Setup the writer settings
XmlWriterSettings writerSettings = new XmlWriterSettings
{
Indent = true,
CheckCharacters = true,
ConformanceLevel = ConformanceLevel.Document
};
// Create an XML writer for the file chosen
XmlWriter xmlWriter = XmlWriter.Create(saveFileDialog.FileName, writerSettings);
// Start the opml element
xmlWriter.WriteStartElement("opml");
// Start the body element
xmlWriter.WriteStartElement("body");
// Loop over each feed
foreach (Feed feed in Database.Feeds.OrderBy(feed => feed.Name))
{
// Start the outline element
xmlWriter.WriteStartElement("outline");
// Write the title
xmlWriter.WriteAttributeString("title", feed.Title);
// Write the HTML link
xmlWriter.WriteAttributeString("htmlUrl", feed.Link);
// Write the XML link
xmlWriter.WriteAttributeString("xmlUrl", feed.Source);
// End the outline element
xmlWriter.WriteEndElement();
}
// End the body element
xmlWriter.WriteEndElement();
// End the opml element
xmlWriter.WriteEndElement();
// Flush and close the writer
xmlWriter.Flush();
xmlWriter.Close();
}
private void ImportFeeds()
{
// Setup the open file dialog
OpenFileDialog openFileDialog = new OpenFileDialog
{
Filter = Properties.Resources.ImportExportFilter,
FilterIndex = 0
};
bool? result = openFileDialog.ShowDialog();
if (!result.Value)
return;
// Setup the reader settings
XmlReaderSettings xmlReaderSettings = new XmlReaderSettings { IgnoreWhitespace = true };
// Create an XML reader for the file chosen
XmlReader xmlReader = XmlReader.Create(openFileDialog.FileName, xmlReaderSettings);
try
{
// Read the first node
xmlReader.Read();
// Read the OPML node
xmlReader.ReadStartElement("opml");
// Read the body node
xmlReader.ReadStartElement("body");
// Read all outline nodes
while (xmlReader.NodeType != XmlNodeType.EndElement)
{
// Create a new feed
Feed feed = new Feed { Category = Database.Categories.ToList().First(c => c.IsDefault) };
// Loop over all attributes
while (xmlReader.MoveToNextAttribute())
{
// Handle the attibute
switch (xmlReader.Name.ToLower())
{
case "title":
feed.Title = xmlReader.Value;
break;
case "htmlurl":
feed.Link = xmlReader.Value;
break;
case "xmlurl":
feed.Source = xmlReader.Value;
break;
case "text":
feed.Name = xmlReader.Value;
break;
}
}
// Fill in defaults for optional fields
if (string.IsNullOrEmpty(feed.Name))
feed.Name = feed.Title;
// Add the feed to the main list
Database.Feeds.AddObject(feed);
// Move back to the element node
xmlReader.MoveToElement();
// Skip to the next node
xmlReader.Skip();
}
// End the body node
xmlReader.ReadEndElement();
// End the OPML node
xmlReader.ReadEndElement();
}
finally
{
xmlReader.Close();
}
}
#endregion
#region Category list management
private void SetCategoryButtonStates()
{
addCategoryButton.IsEnabled = true;
editCategoryButton.IsEnabled = (categoryListBox.SelectedItem != null);
deleteCategoryButton.IsEnabled = (categoryListBox.SelectedItem != null);
}
private void AddCategory()
{
Category category = new Category();
CategoryWindow categoryWindow = new CategoryWindow();
bool? result = categoryWindow.Display(category, Window.GetWindow(this));
if (result.HasValue && result.Value)
{
Database.Categories.AddObject(category);
categoryListBox.SelectedItem = category;
SetCategoryButtonStates();
}
}
private void EditSelectedCategory()
{
if (categoryListBox.SelectedItem == null)
return;
Category category = (Category) categoryListBox.SelectedItem;
CategoryWindow categoryWindow = new CategoryWindow();
categoryWindow.Display(category, Window.GetWindow(this));
}
private void DeleteSelectedCategory()
{
Category category = (Category) categoryListBox.SelectedItem;
Database.Categories.DeleteObject(category);
SetCategoryButtonStates();
}
#endregion
#region Category event handlers
private void HandleAddCategoryButtonClick(object sender, RoutedEventArgs e)
{
AddCategory();
}
private void HandleEditCategoryButtonClick(object sender, RoutedEventArgs e)
{
EditSelectedCategory();
}
private void HandleDeleteCategoryButtonClick(object sender, RoutedEventArgs e)
{
DeleteSelectedCategory();
}
#endregion
private CollectionViewSource _collectionViewSource;
private void HandleCategoryListBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (_collectionViewSource == null)
{
_collectionViewSource = new CollectionViewSource {Source = Database.AllFeeds};
_collectionViewSource.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
_collectionViewSource.Filter += HandleCollectionViewSourceFilter;
feedListBox.ItemsSource = _collectionViewSource.View;
}
_collectionViewSource.View.Refresh();
if (feedListBox.Items.Count > 0)
feedListBox.SelectedIndex = 0;
SetFeedButtonStates();
}
private void HandleCollectionViewSourceFilter(object sender, FilterEventArgs e)
{
Category selectedCategory = (Category) categoryListBox.SelectedItem;
Feed feed = (Feed) e.Item;
e.Accepted = (feed.Category == selectedCategory);
}
private void HandleTextBlockDrop(object sender, DragEventArgs e)
{
List<Feed> feedList = (List<Feed>) e.Data.GetData(typeof(List<Feed>));
Category category = (Category) ((DataGridRow) sender).Item;
foreach (Feed feed in feedList)
feed.Category = category;
_collectionViewSource.View.Refresh();
//textBlock.TextDecorations = null;
}
private void HandleListBoxItemPreviewMouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
List<Feed> selectedItems = feedListBox.SelectedItems.Cast<Feed>().ToList();
DragDrop.DoDragDrop(feedListBox, selectedItems, DragDropEffects.Move);
}
}
private void HandleTextBlockDragEnter(object sender, DragEventArgs e)
{
DataGridRow dataGridRow = (DataGridRow) sender;
dataGridRow.FontWeight = FontWeights.Bold;
}
private void HandleTextBlockDragLeave(object sender, DragEventArgs e)
{
DataGridRow dataGridRow = (DataGridRow) sender;
dataGridRow.FontWeight = FontWeights.Normal;
}
private void HandleListBoxItemMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
EditSelectedFeed();
}
private void HandleMultipleEditClick(object sender, RoutedEventArgs e)
{
BulkFeedWindow bulkFeedWindow = new BulkFeedWindow();
bulkFeedWindow.Display(Window.GetWindow(this), Database);
}
}
}

View File

@@ -0,0 +1,21 @@
<Options:OptionsPanelBase x:Class="FeedCenter.Options.GeneralOptionsPanel"
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" mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<CheckBox Content="{x:Static Properties:Resources.startWithWindowsCheckBox}"
Name="startWithWindowsCheckBox"
VerticalAlignment="Top" VerticalContentAlignment="Center" Grid.ColumnSpan="2" />
<CheckBox Content="{x:Static Properties:Resources.registerAsDefaultFeedReaderCheckBox}"
HorizontalAlignment="Left"
Margin="0,22,0,0"
Name="registerAsDefaultFeedReaderCheckBox"
VerticalAlignment="Top" VerticalContentAlignment="Center" Grid.ColumnSpan="2" />
</Grid>
</Options:OptionsPanelBase>

View File

@@ -0,0 +1,44 @@
namespace FeedCenter.Options
{
public partial class GeneralOptionsPanel
{
public GeneralOptionsPanel()
{
InitializeComponent();
}
public override void LoadPanel(FeedCenterEntities database)
{
base.LoadPanel(database);
var settings = Properties.Settings.Default;
startWithWindowsCheckBox.IsChecked = settings.StartWithWindows;
registerAsDefaultFeedReaderCheckBox.IsChecked = settings.RegisterAsDefaultFeedReader;
}
public override bool ValidatePanel()
{
return true;
}
public override void SavePanel()
{
var settings = Properties.Settings.Default;
if (startWithWindowsCheckBox.IsChecked.HasValue && settings.StartWithWindows != startWithWindowsCheckBox.IsChecked.Value)
settings.StartWithWindows = startWithWindowsCheckBox.IsChecked.Value;
if (registerAsDefaultFeedReaderCheckBox.IsChecked.HasValue && settings.RegisterAsDefaultFeedReader != registerAsDefaultFeedReaderCheckBox.IsChecked.Value)
settings.RegisterAsDefaultFeedReader = registerAsDefaultFeedReaderCheckBox.IsChecked.Value;
App.SetStartWithWindows(settings.StartWithWindows);
App.SetDefaultFeedReader(settings.RegisterAsDefaultFeedReader);
}
public override string CategoryName
{
get { return Properties.Resources.optionCategoryGeneral; }
}
}
}

33
Options/Options.cs Normal file
View File

@@ -0,0 +1,33 @@
using System;
using System.Globalization;
using System.Windows.Data;
namespace FeedCenter.Options
{
public enum MultipleLineDisplay
{
Normal,
SingleLine,
FirstLine
}
public enum MultipleOpenAction
{
IndividualPages,
SinglePage
}
[ValueConversion(typeof(int), typeof(MultipleOpenAction))]
public class MultipleOpenActionConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (MultipleOpenAction) value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return (int) value;
}
}
}

View File

@@ -0,0 +1,30 @@
using System;
using System.Windows.Controls;
namespace FeedCenter.Options
{
public class OptionsPanelBase : UserControl
{
protected FeedCenterEntities Database { get; 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
{
get { return null; }
}
}
}

View File

@@ -0,0 +1,38 @@
<Window x:Class="FeedCenter.Options.OptionsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Properties="clr-namespace:FeedCenter.Properties"
Title="{x:Static Properties:Resources.OptionsWindow}"
Height="360"
Width="720"
ResizeMode="CanResize"
WindowStartupLocation="CenterScreen"
Icon="/FeedCenter;component/Resources/Application.ico">
<Grid>
<ListBox HorizontalAlignment="Left"
Name="categoryListBox"
Width="126"
SelectionChanged="HandleSelectedCategoryChanged"
Margin="12,12,0,41" />
<ContentControl Margin="144,12,12,41"
Name="contentControl"
IsTabStop="False" />
<Button Content="{x:Static Properties:Resources.OkayButton}"
Height="23"
HorizontalAlignment="Right"
Margin="0,0,93,12"
Name="okButton"
VerticalAlignment="Bottom"
Width="75"
IsDefault="True"
Click="HandleOkayButtonClick" />
<Button Content="{x:Static Properties:Resources.CancelButton}"
Margin="0,0,12,12"
Name="cancelButton"
Height="23"
VerticalAlignment="Bottom"
HorizontalAlignment="Right"
Width="75"
IsCancel="True" />
</Grid>
</Window>

View File

@@ -0,0 +1,127 @@
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
namespace FeedCenter.Options
{
public partial class OptionsWindow
{
#region Member variables
private readonly List<OptionsPanelBase> _optionPanels = new List<OptionsPanelBase>();
private readonly FeedCenterEntities _database = new FeedCenterEntities();
#endregion
#region Constructor
public OptionsWindow()
{
InitializeComponent();
// Add all the option categories
AddCategories();
// Load the category list
LoadCategories();
}
#endregion
#region Category handling
private void AddCategories()
{
_optionPanels.Add(new GeneralOptionsPanel());
_optionPanels.Add(new DisplayOptionsPanel());
_optionPanels.Add(new FeedsOptionsPanel());
_optionPanels.Add(new ReadingOptionsPanel());
_optionPanels.Add(new UpdateOptionsPanel());
_optionPanels.Add(new AboutOptionsPanel());
}
private void LoadCategories()
{
// Loop over each panel
foreach (OptionsPanelBase optionsPanel in _optionPanels)
{
// Tell the panel to load itself
optionsPanel.LoadPanel(_database);
// Add the panel to the category ist
categoryListBox.Items.Add(new CategoryListItem(optionsPanel));
// Set the panel into the right side
contentControl.Content = optionsPanel;
}
// Select the first item
categoryListBox.SelectedItem = categoryListBox.Items[0];
}
private void SelectCategory(OptionsPanelBase panel)
{
// Set the content
contentControl.Content = panel;
}
private void HandleSelectedCategoryChanged(object sender, SelectionChangedEventArgs e)
{
// Select the right category
SelectCategory(((CategoryListItem) categoryListBox.SelectedItem).Panel);
}
#endregion
#region Category list item
private class CategoryListItem
{
public OptionsPanelBase Panel { get; private set; }
public CategoryListItem(OptionsPanelBase panel)
{
Panel = panel;
}
public override string ToString()
{
return Panel.CategoryName;
}
}
#endregion
private void HandleOkayButtonClick(object sender, RoutedEventArgs e)
{
// Loop over each panel and ask them to validate
foreach (OptionsPanelBase 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 (OptionsPanelBase optionsPanel in _optionPanels)
{
// Save!
optionsPanel.SavePanel();
}
// Save the actual settings
_database.SaveChanges();
Properties.Settings.Default.Save();
// Close the window
Close();
}
}
}

View File

@@ -0,0 +1,34 @@
<Options:OptionsPanelBase x:Class="FeedCenter.Options.ReadingOptionsPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Options="clr-namespace:FeedCenter.Options"
xmlns:Properties="clr-namespace:FeedCenter.Properties"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Content="{x:Static Properties:Resources.browserLabel}"
Name="browserLabel"
Target="{Binding ElementName=browserComboBox}"
Grid.Column="0"
Padding="0"
VerticalContentAlignment="Center"
Margin="0,0,5,0" />
<ComboBox Name="browserComboBox"
Grid.Column="1"
VerticalContentAlignment="Center">
<ComboBoxItem Content="{x:Static Properties:Resources.DefaultBrowserCaption}"
Tag="" />
</ComboBox>
</Grid>
</Options:OptionsPanelBase>

View File

@@ -0,0 +1,66 @@
using System.Windows.Controls;
using Common.Internet;
using Common.Wpf.Extensions;
namespace FeedCenter.Options
{
public partial class ReadingOptionsPanel
{
public ReadingOptionsPanel()
{
InitializeComponent();
}
public override void LoadPanel(FeedCenterEntities database)
{
base.LoadPanel(database);
var settings = Properties.Settings.Default;
LoadBrowserComboBox(browserComboBox, settings.Browser);
}
public override bool ValidatePanel()
{
return true;
}
public override void SavePanel()
{
var settings = Properties.Settings.Default;
string browser = (string) ((ComboBoxItem) browserComboBox.SelectedItem).Tag;
if (settings.Browser != browser)
settings.Browser = browser;
this.UpdateAllSources();
}
public override string CategoryName
{
get { return Properties.Resources.optionCategoryReading; }
}
private static void LoadBrowserComboBox(ComboBox comboBox, string selected)
{
comboBox.SelectedIndex = 0;
ComboBoxItem selectedItem = null;
var browsers = Browser.DetectInstalledBrowsers();
foreach (var browser in browsers)
{
ComboBoxItem item = new ComboBoxItem { Content = browser.Value.Name, Tag = browser.Key };
comboBox.Items.Add(item);
if (browser.Key == selected)
selectedItem = item;
}
if (selectedItem != null)
comboBox.SelectedItem = selectedItem;
}
}
}

View File

@@ -0,0 +1,20 @@
<Options:OptionsPanelBase x:Class="FeedCenter.Options.UpdateOptionsPanel"
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" mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<CheckBox Content="{x:Static Properties:Resources.checkVersionOnStartupCheckBox}"
Name="checkVersionOnStartupCheckBox"
VerticalAlignment="Top" />
<Button Content="{x:Static Properties:Resources.checkVersionNowButton}"
Height="23"
HorizontalAlignment="Left"
Margin="0,22,0,0"
Name="checkVersionNowButton"
VerticalAlignment="Top"
Width="75"
Click="HandleCheckVersionNowButtonClick" />
</Grid>
</Options:OptionsPanelBase>

View File

@@ -0,0 +1,38 @@
namespace FeedCenter.Options
{
public partial class UpdateOptionsPanel
{
public UpdateOptionsPanel()
{
InitializeComponent();
}
public override void LoadPanel(FeedCenterEntities database)
{
base.LoadPanel(database);
checkVersionOnStartupCheckBox.IsChecked = Properties.Settings.Default.CheckVersionAtStartup;
}
public override bool ValidatePanel()
{
return true;
}
public override void SavePanel()
{
if (checkVersionOnStartupCheckBox.IsChecked.HasValue && Properties.Settings.Default.CheckVersionAtStartup != checkVersionOnStartupCheckBox.IsChecked.Value)
Properties.Settings.Default.CheckVersionAtStartup = checkVersionOnStartupCheckBox.IsChecked.Value;
}
public override string CategoryName
{
get { return Properties.Resources.optionCategoryUpdate; }
}
private void HandleCheckVersionNowButtonClick(object sender, System.Windows.RoutedEventArgs e)
{
VersionCheck.DisplayUpdateInformation(true);
}
}
}