Move application files to sub-folder

This commit is contained in:
2014-07-16 21:19:02 -04:00
parent 2af9d8c14f
commit f7cfa7c6cf
108 changed files with 0 additions and 0 deletions

12
Application/App.xaml Normal file
View File

@@ -0,0 +1,12 @@
<Application x:Class="FeedCenter.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Common.Wpf;component/Toolbar/SplitButton/SplitButtonStyle.xaml" />
<ResourceDictionary Source="Style.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

228
Application/App.xaml.cs Normal file
View File

@@ -0,0 +1,228 @@
using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Threading;
using Microsoft.Win32;
using Common.Debug;
using Common.Helpers;
using Common.IO;
using Common.Wpf.Extensions;
using Common.Settings;
using FeedCenter.Properties;
namespace FeedCenter
{
public partial class App
{
#region Debug properties
public static bool UseDebugPath;
#endregion
#region Properties
public bool Restart;
#endregion
#region Main function
[STAThread]
public static void Main()
{
// Create and initialize the app object
App app = new App();
app.InitializeComponent();
// Create an isolation handle to see if we are already running
IDisposable isolationHandle = ApplicationIsolation.GetIsolationHandle(FeedCenter.Properties.Resources.ApplicationName);
// If there is another copy then pass it the command line and exit
if (isolationHandle == null)
{
InterprocessMessageSender.SendMessage(FeedCenter.Properties.Resources.ApplicationName, Environment.CommandLine);
return;
}
// Use the handle over the lifetime of the application
using (isolationHandle)
{
// Set the data directory based on debug or not
AppDomain.CurrentDomain.SetData("DataDirectory",
UseDebugPath
? Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
: UserSettingsPath);
// Get the generic provider
var genericProvider = (GenericSettingsProvider) Settings.Default.Providers[typeof(GenericSettingsProvider).Name];
if (genericProvider == null)
return;
// Set the callbacks into the provider
genericProvider.OpenDataStore = SettingsStore.OpenDataStore;
genericProvider.CloseDataStore = SettingsStore.CloseDataStore;
genericProvider.GetSettingValue = SettingsStore.GetSettingValue;
genericProvider.SetSettingValue = SettingsStore.SetSettingValue;
genericProvider.DeleteSettingsForVersion = SettingsStore.DeleteSettingsForVersion;
genericProvider.GetVersionList = SettingsStore.GetVersionList;
// Initialize the tracer with the current process ID
Tracer.Initialize(UserSettingsPath, FeedCenter.Properties.Resources.ApplicationName, Process.GetCurrentProcess().Id.ToString(CultureInfo.InvariantCulture), false);
Current.DispatcherUnhandledException += HandleCurrentDispatcherUnhandledException;
AppDomain.CurrentDomain.UnhandledException += HandleCurrentDomainUnhandledException;
// Check if we need to upgrade settings from a previous version
if (Settings.Default.FirstRun)
{
Settings.Default.Upgrade();
Settings.Default.FirstRun = false;
Settings.Default.Save();
}
// Create the main window before the splash otherwise WPF gets messed up
MainWindow mainWindow = new MainWindow();
// Show the splash window
SplashWindow splashWindow = new SplashWindow();
splashWindow.ShowDialog();
// If we don't need to restart then fire up the main window
if (!app.Restart)
{
// Update the registry settings
SetStartWithWindows(Settings.Default.StartWithWindows);
SetDefaultFeedReader(Settings.Default.RegisterAsDefaultFeedReader);
// Initialize the window
mainWindow.Initialize();
// Run the app
app.Run(mainWindow);
}
// If we need to restart
if (app.Restart)
{
// Wait a bit to make sure any previous upgrade has settled
Thread.Sleep(2000);
// Restart the application
Current.Restart();
}
// Terminate the tracer
Tracer.Dispose();
}
}
private static void HandleCurrentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Tracer.WriteException((Exception) e.ExceptionObject);
Tracer.Flush();
}
private static void HandleCurrentDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
Tracer.WriteException(e.Exception);
Tracer.Flush();
}
#endregion
#region Helpers
public static string UserSettingsPath
{
get
{
// If we're running in debug mode then use a local path for the database and logs
if (UseDebugPath)
return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
// Get the path to the local application data directory
string path = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
FeedCenter.Properties.Resources.ApplicationName);
// Make sure it exists - create it if needed
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
return path;
}
}
public static void SetStartWithWindows(bool value)
{
// Get the application name
string applicationName = FeedCenter.Properties.Resources.ApplicationDisplayName;
// Get application details
string publisherName = applicationName;
string productName = applicationName;
string allProgramsPath = Environment.GetFolderPath(Environment.SpecialFolder.Programs);
string shortcutPath = Path.Combine(allProgramsPath, publisherName);
// Build the auto start path
shortcutPath = "\"" + Path.Combine(shortcutPath, productName) + ".appref-ms\"";
// Set auto start
Current.SetStartWithWindows(applicationName, shortcutPath, value);
}
public static void SetDefaultFeedReader(bool value)
{
// Get the location of the assembly
string assemblyLocation = Assembly.GetExecutingAssembly().Location;
// Open the registry key (creating if needed)
using (RegistryKey registryKey = Registry.CurrentUser.CreateSubKey("Software\\Classes\\feed", RegistryKeyPermissionCheck.ReadWriteSubTree))
{
if (registryKey == null)
return;
// Write the handler settings
registryKey.SetValue(string.Empty, "URL:Feed Handler");
registryKey.SetValue("URL Protocol", string.Empty);
// Open the icon subkey (creating if needed)
using (RegistryKey subKey = registryKey.CreateSubKey("DefaultIcon", RegistryKeyPermissionCheck.ReadWriteSubTree))
{
if (subKey != null)
{
// Write the assembly location
subKey.SetValue(string.Empty, assemblyLocation);
// Close the subkey
subKey.Close();
}
}
// Open the subkey for the command (creating if needed)
using (RegistryKey subKey = registryKey.CreateSubKey("shell\\open\\command", RegistryKeyPermissionCheck.ReadWriteSubTree))
{
if (subKey != null)
{
// Write the assembly location and parameter
subKey.SetValue(string.Empty, string.Format("\"{0}\" %1", assemblyLocation));
// Close the subkey
subKey.Close();
}
}
// Close the registry key
registryKey.Close();
}
}
#endregion
}
}

View File

@@ -0,0 +1,65 @@
using Common.Debug;
using Common.Internet;
using FeedCenter.Properties;
using System;
using System.Diagnostics;
namespace FeedCenter
{
public static class BrowserCommon
{
public static Browser FindBrowser(string browserKey)
{
Browser browser = null;
// Get the list of installed browsers
var browsers = Browser.DetectInstalledBrowsers();
// Make sure the desired browser exists
if (browsers.ContainsKey(browserKey))
{
// Get the browser
browser = browsers[browserKey];
}
return browser;
}
public static bool OpenLink(string url)
{
// Get the browser
Browser browser = FindBrowser(Settings.Default.Browser);
// Start the browser
return OpenLink(browser, url);
}
public static bool OpenLink(Browser browser, string url)
{
try
{
// Don't bother with empty links
if (String.IsNullOrEmpty(url))
return true;
// Add quotes around the URL for safety
url = string.Format("\"{0}\"", url);
// Start the browser
if (browser == null)
Process.Start(url);
else
Process.Start(browser.Command, url);
return true;
}
catch (Exception exception)
{
// Just log the exception
Tracer.WriteException(exception);
return false;
}
}
}
}

27
Application/Category.cs Normal file
View File

@@ -0,0 +1,27 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace FeedCenter
{
using System;
using System.Collections.Generic;
public partial class Category
{
public Category()
{
this.Feeds = new HashSet<Feed>();
}
public System.Guid ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Feed> Feeds { get; set; }
}
}

View File

@@ -0,0 +1,226 @@
using Common.Debug;
using FeedCenter.Properties;
using System;
using System.Collections.Generic;
using System.Data.SqlServerCe;
using System.IO;
using System.Linq;
namespace FeedCenter.Data
{
public static class Database
{
#region Static database settings
public static string DatabasePath;
#endregion
#region File version
private enum SqlServerCeFileVersion
{
Unknown,
Version20,
Version30,
Version35,
Version40,
}
private static SqlServerCeFileVersion GetFileVersion(string databasePath)
{
// Create a mapping of version numbers to the version enumeration
var versionMapping = new Dictionary<int, SqlServerCeFileVersion>
{
{ 0x73616261, SqlServerCeFileVersion.Version20 },
{ 0x002dd714, SqlServerCeFileVersion.Version30 },
{ 0x00357b9d, SqlServerCeFileVersion.Version35 },
{ 0x003d0900, SqlServerCeFileVersion.Version40 }
};
int signature;
try
{
// Open the database file
using (var stream = new FileStream(databasePath, FileMode.Open, FileAccess.Read))
{
// Read the file using the binary reader
var reader = new BinaryReader(stream);
// Seek to the version signature
stream.Seek(16, SeekOrigin.Begin);
// Read the version signature
signature = reader.ReadInt32();
}
}
catch (Exception exception)
{
Tracer.WriteException(exception);
throw;
}
// If we know about the version number then return the right enumeration - otherwise unknown
return versionMapping.ContainsKey(signature) ? versionMapping[signature] : SqlServerCeFileVersion.Unknown;
}
#endregion
public static bool DatabaseExists
{
get { return File.Exists(DatabasePath); }
}
public static void CreateDatabase()
{
Tracer.WriteLine("Creating database engine");
// Create the database engine
using (var engine = new SqlCeEngine(string.Format("Data Source={0}", DatabasePath)))
{
Tracer.WriteLine("Creating database");
// Create the database itself
engine.CreateDatabase();
Tracer.WriteLine("Running database script");
// Run the creation script
ExecuteScript(Resources.CreateDatabase);
}
}
private static int GetVersion(SqlCeConnection connection)
{
string versionString;
try
{
// Check the database version table
using (var command = new SqlCeCommand("SELECT Value FROM DatabaseVersion", connection))
versionString = command.ExecuteScalar().ToString();
}
catch (SqlCeException)
{
// Check the setting table for the version
using (var command = new SqlCeCommand("SELECT Value FROM Setting WHERE Name = 'DatabaseVersion'", connection))
versionString = command.ExecuteScalar().ToString();
}
if (string.IsNullOrEmpty(versionString))
versionString = "0";
Tracer.WriteLine("Database version: {0}", versionString);
return int.Parse(versionString);
}
public static void UpdateDatabase()
{
Tracer.WriteLine("Getting database file version");
// Get the database file version
var fileVersion = GetFileVersion(DatabasePath);
Tracer.WriteLine("Database file version: {0}", fileVersion);
// See if we need to upgrade the database file version
if (fileVersion != SqlServerCeFileVersion.Version40)
{
Tracer.WriteLine("Creating database engine");
// Create the database engine
using (var engine = new SqlCeEngine(string.Format("Data Source={0}", DatabasePath)))
{
Tracer.WriteLine("Upgrading database");
// Upgrade the database (if needed)
engine.Upgrade();
}
}
Tracer.WriteLine("Getting database version");
// Create a database connection
using (var connection = new SqlCeConnection(string.Format("Data Source={0}", DatabasePath)))
{
// Open the connection
connection.Open();
// Get the database version
var databaseVersion = GetVersion(connection);
// Create a dictionary of database upgrade scripts and their version numbers
var scriptList = new Dictionary<int, string>();
// Loop over the properties of the resource object looking for update scripts
foreach (var property in typeof(Resources).GetProperties().Where(property => property.Name.StartsWith("DatabaseUpdate")))
{
// Get the name of the property
var propertyName = property.Name;
// Extract the version from the name
var version = int.Parse(propertyName.Substring(propertyName.IndexOf("_", StringComparison.Ordinal) + 1));
// Add to the script list
scriptList[version] = propertyName;
}
// Loop over the scripts ordered by version
foreach (var pair in scriptList.OrderBy(pair => pair.Key))
{
// If the database version is less than or equal to the script version the script needs to run
if (databaseVersion <= pair.Key)
{
// Get the script text
var scriptText = Resources.ResourceManager.GetString(pair.Value);
// Run the script
ExecuteScript(scriptText);
}
}
}
}
public static void MaintainDatabase()
{
Tracer.WriteLine("Creating database engine");
// Create the database engine
using (var engine = new SqlCeEngine(string.Format("Data Source={0}", DatabasePath)))
{
Tracer.WriteLine("Shrinking database");
// Compact the database
engine.Shrink();
}
}
private static void ExecuteScript(string scriptText)
{
// Create a database connection
using (var connection = new SqlCeConnection(string.Format("Data Source={0}", DatabasePath)))
{
// Open the connection
connection.Open();
// Setup the delimiters
var delimiters = new[] { "\r\nGO\r\n" };
// Split the script at the delimiters
var statements = scriptText.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
// Loop over each statement in the script
foreach (var statement in statements)
{
// Execute the statement
using (var command = new SqlCeCommand(statement, connection))
command.ExecuteNonQuery();
}
}
}
}
}

View File

@@ -0,0 +1,155 @@
using System;
using System.Data;
using System.Data.SqlServerCe;
using System.Data.SqlTypes;
namespace FeedCenter.Data
{
public static class Extensions
{
#region SqlDateTime
public static SqlDateTime SqlDateTimeZero = new SqlDateTime(0, 0);
#endregion
#region DataSet
public static DataRow GetFirstDataRow(this DataSet dataSet)
{
// If we get no data set then return nothing
if (dataSet == null)
return null;
// If there were no tables returns then return nothing
if (dataSet.Tables.Count == 0)
return null;
// Get the first table
var firstTable = dataSet.Tables[0];
// If the table has no rows then return nothing
if (firstTable.Rows.Count == 0)
return null;
// Return the first row
return firstTable.Rows[0];
}
#endregion
#region SqlCeCommand
public static void SetStatement(this SqlCeCommand command, string statement, params object[] parameters)
{
// Create a new array to hold the updated parameters
var formattedParameters = new object[parameters.Length];
// Initialize our position
var position = 0;
// Loop over each parameter
foreach (var parameter in parameters)
{
// If the parameter is a DateTime then we need to reformat
if (parameter == null)
{
// Use a explicit null value
formattedParameters[position++] = "NULL";
}
else if (parameter is DateTime)
{
// Cast the parameter back to a DateTime
var dateTime = (DateTime) parameter;
// Convert the DateTime to sortable format
var formatted = dateTime.ToString("s");
// Set into the formatted array
formattedParameters[position++] = formatted;
}
else if (parameter is bool)
{
// Convert the boolean to a number
formattedParameters[position++] = Convert.ToInt32(parameter);
}
else if (parameter.GetType().IsEnum)
{
// Convert the enum to a number
formattedParameters[position++] = Convert.ToInt32(parameter);
}
else if (parameter is string)
{
// Escape single quotes
formattedParameters[position++] = (parameter as string).Replace("'", "''");
}
else
{
// Just put the original value in
formattedParameters[position++] = parameter;
}
}
// Build the full statement
command.CommandText = string.Format(statement, formattedParameters);
}
#endregion
#region SqlCeConnection
public static void ExecuteNonQuery(this SqlCeConnection connection, string query, params object[] parameters)
{
// Create the command object
var command = connection.CreateCommand();
// Set the statement based on the query and parameters
command.SetStatement(query, parameters);
//Tracer.WriteLine("Executing SQL statement: {0}", command.CommandText);
// Execute the command
command.ExecuteNonQuery();
}
public static DataSet ExecuteDataSet(this SqlCeConnection connection, string query, params object[] parameters)
{
// Create the command object
var command = connection.CreateCommand();
// Set the statement based on the query and parameters
command.SetStatement(query, parameters);
// Create a new data adapter
using (var adapter = new SqlCeDataAdapter(command))
{
// Create the new data set
using (var dataSet = new DataSet())
{
//Tracer.WriteLine("Executing SQL query: {0}", command.CommandText);
// Fill the data set
adapter.Fill(dataSet);
return dataSet;
}
}
}
public static object ExecuteScalar(this SqlCeConnection connection, string query, params object[] parameters)
{
// Create the command object
var command = connection.CreateCommand();
// Set the statement based on the query and parameters
command.SetStatement(query, parameters);
//Tracer.WriteLine("Executing SQL statement: {0}", command.CommandText);
// Execute the command
return command.ExecuteScalar();
}
#endregion
}
}

Binary file not shown.

131
Application/Entities.cs Normal file
View File

@@ -0,0 +1,131 @@
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Data.Entity.Infrastructure;
namespace FeedCenter
{
public partial class FeedCenterEntities
{
#region Dispose
protected override void Dispose(bool disposing)
{
if (disposing)
{
var manager = ((IObjectContextAdapter) this).ObjectContext.ObjectStateManager;
manager.ObjectStateManagerChanged -= HandleObjectStateManagerObjectStateManagerChanged;
_hookedStateManager = false;
}
base.Dispose(disposing);
}
#endregion
private bool _hookedStateManager;
#region All categories
private ObservableCollection<Category> _allCategories;
public ObservableCollection<Category> AllCategories
{
get
{
if (_allCategories == null)
{
_allCategories = new ObservableCollection<Category>(Categories);
if (!_hookedStateManager)
{
var manager = ((IObjectContextAdapter) this).ObjectContext.ObjectStateManager;
manager.ObjectStateManagerChanged += HandleObjectStateManagerObjectStateManagerChanged;
_hookedStateManager = true;
}
}
return _allCategories;
}
}
#endregion
#region All feeds
private ObservableCollection<Feed> _allFeeds;
public ObservableCollection<Feed> AllFeeds
{
get
{
if (_allFeeds == null)
{
_allFeeds = new ObservableCollection<Feed>(Feeds);
if (!_hookedStateManager)
{
var manager = ((IObjectContextAdapter) this).ObjectContext.ObjectStateManager;
manager.ObjectStateManagerChanged += HandleObjectStateManagerObjectStateManagerChanged;
_hookedStateManager = true;
}
}
return _allFeeds;
}
}
#endregion
#region Object state manager
void HandleObjectStateManagerObjectStateManagerChanged(object sender, CollectionChangeEventArgs e)
{
if (e.Element is Category)
{
if (_allCategories == null)
return;
var category = e.Element as Category;
switch (e.Action)
{
case CollectionChangeAction.Add:
_allCategories.Add(category);
break;
case CollectionChangeAction.Remove:
_allCategories.Remove(category);
break;
case CollectionChangeAction.Refresh:
_allCategories.Clear();
foreach (var loopCategory in Categories)
_allCategories.Add(loopCategory);
break;
}
}
else if (e.Element is Feed)
{
if (_allFeeds == null)
return;
var feed = e.Element as Feed;
switch (e.Action)
{
case CollectionChangeAction.Add:
_allFeeds.Add(feed);
break;
case CollectionChangeAction.Remove:
_allFeeds.Remove(feed);
break;
case CollectionChangeAction.Refresh:
_allFeeds.Clear();
foreach (var loopfeed in Feeds)
_allFeeds.Add(loopfeed);
break;
}
}
}
#endregion
}
}

59
Application/Feed.cs Normal file
View File

@@ -0,0 +1,59 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace FeedCenter
{
using System;
using System.Collections.Generic;
public partial class Feed
{
public Feed()
{
this.Name = "";
this.Title = "";
this.Source = "";
this.Link = "";
this.Description = "";
this.LastChecked = new DateTime(599266080000000000, DateTimeKind.Unspecified);
this.CheckInterval = 60;
this.Enabled = true;
this.Authenticate = false;
this.Username = "";
this.Password = "";
this.Domain = "";
this.LastUpdated = new DateTime(599266080000000000, DateTimeKind.Unspecified);
this.Actions = new HashSet<FeedAction>();
this.Items = new HashSet<FeedItem>();
}
public System.Guid ID { get; set; }
public string Name { get; set; }
public string Title { get; set; }
public string Source { get; set; }
public string Link { get; set; }
public string Description { get; set; }
public System.DateTime LastChecked { get; set; }
public int CheckInterval { get; set; }
public bool Enabled { get; set; }
public bool Authenticate { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string Domain { get; set; }
public FeedCenter.FeedReadResult LastReadResult { get; set; }
public System.DateTime LastUpdated { get; set; }
public FeedCenter.FeedItemComparison ItemComparison { get; set; }
public System.Guid CategoryID { get; set; }
public FeedCenter.MultipleOpenAction MultipleOpenAction { get; set; }
public virtual Category Category { get; set; }
public virtual ICollection<FeedAction> Actions { get; set; }
public virtual ICollection<FeedItem> Items { get; set; }
}
}

26
Application/FeedAction.cs Normal file
View File

@@ -0,0 +1,26 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace FeedCenter
{
using System;
using System.Collections.Generic;
public partial class FeedAction
{
public System.Guid ID { get; set; }
public System.Guid FeedID { get; set; }
public int Field { get; set; }
public string Search { get; set; }
public string Replace { get; set; }
public int Sequence { get; set; }
public virtual Feed Feed { get; set; }
}
}

View File

@@ -0,0 +1,520 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{BD3D12F2-DE23-4466-83B1-1EB617A877A4}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>FeedCenter</RootNamespace>
<AssemblyName>FeedCenter</AssemblyName>
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<IsWebBootstrapper>false</IsWebBootstrapper>
<SccProjectName>SAK</SccProjectName>
<SccLocalPath>SAK</SccLocalPath>
<SccAuxPath>SAK</SccAuxPath>
<SccProvider>SAK</SccProvider>
<PublishUrl>\\server\d\FeedCenter\</PublishUrl>
<Install>true</Install>
<InstallFrom>Unc</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ProductName>Feed Center</ProductName>
<PublisherName>Feed Center</PublisherName>
<CreateWebPageOnPublish>true</CreateWebPageOnPublish>
<WebPage>Publish.html</WebPage>
<OpenBrowserOnPublish>false</OpenBrowserOnPublish>
<ApplicationRevision>208</ApplicationRevision>
<ApplicationVersion>0.1.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<PublishWizardCompleted>true</PublishWizardCompleted>
<BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<PlatformTarget>x86</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup>
<StartupObject>
</StartupObject>
</PropertyGroup>
<PropertyGroup>
<SignAssembly>true</SignAssembly>
</PropertyGroup>
<PropertyGroup>
<AssemblyOriginatorKeyFile>FeedCenter_TemporaryKey.pfx</AssemblyOriginatorKeyFile>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>Resources\Application.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<TargetZone>LocalIntranet</TargetZone>
</PropertyGroup>
<PropertyGroup>
<GenerateManifests>true</GenerateManifests>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>Properties\app.manifest</ApplicationManifest>
</PropertyGroup>
<PropertyGroup>
<SignManifests>true</SignManifests>
</PropertyGroup>
<PropertyGroup>
<ManifestCertificateThumbprint>BC151B601A9608463CB7A5371944A97EDEE60B1A</ManifestCertificateThumbprint>
</PropertyGroup>
<PropertyGroup>
<ManifestKeyFile>FeedCenter_1_TemporaryKey.pfx</ManifestKeyFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<CodeAnalysisLogFile>bin\Debug\FeedCenter.exe.CodeAnalysisLog.xml</CodeAnalysisLogFile>
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
<CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
<CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
<CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
<CodeAnalysisFailOnMissingRules>false</CodeAnalysisFailOnMissingRules>
<UseVSHostingProcess>true</UseVSHostingProcess>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'">
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<CodeAnalysisLogFile>bin\Release\FeedCenter.exe.CodeAnalysisLog.xml</CodeAnalysisLogFile>
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
<CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="Common.Wpf.MarkupExtensions">
<HintPath>..\Common.Wpf.MarkupExtensions\bin\Release\Common.Wpf.MarkupExtensions.dll</HintPath>
</Reference>
<Reference Include="EntityFramework">
<HintPath>packages\EntityFramework.6.1.1\lib\net45\EntityFramework.dll</HintPath>
</Reference>
<Reference Include="EntityFramework.SqlServer">
<HintPath>packages\EntityFramework.6.1.1\lib\net45\EntityFramework.SqlServer.dll</HintPath>
</Reference>
<Reference Include="EntityFramework.SqlServerCompact">
<HintPath>packages\EntityFramework.SqlServerCompact.6.1.1\lib\net45\EntityFramework.SqlServerCompact.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.configuration" />
<Reference Include="System.Data" />
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<Private>True</Private>
<HintPath>packages\Microsoft.SqlServer.Compact.4.0.8854.1\lib\net40\System.Data.SqlServerCe.dll</HintPath>
</Reference>
<Reference Include="System.Data.SqlServerCe.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
<Private>True</Private>
<HintPath>packages\Microsoft.SqlServer.Compact.4.0.8854.1\lib\net40\System.Data.SqlServerCe.Entity.dll</HintPath>
</Reference>
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Security" />
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
<Page Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Compile Include="BrowserCommon.cs" />
<Compile Include="Category.cs">
<DependentUpon>Model.tt</DependentUpon>
</Compile>
<Compile Include="Data\Extensions.cs" />
<Compile Include="Entities.cs" />
<Compile Include="Feed.cs">
<DependentUpon>Model.tt</DependentUpon>
</Compile>
<Compile Include="FeedAction.cs">
<DependentUpon>Model.tt</DependentUpon>
</Compile>
<Compile Include="FeedErrorWindow.xaml.cs">
<DependentUpon>FeedErrorWindow.xaml</DependentUpon>
</Compile>
<Compile Include="FeedItem.cs">
<DependentUpon>Model.tt</DependentUpon>
</Compile>
<Compile Include="Feeds\Category.cs" />
<Compile Include="Model.Context.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Model.Context.tt</DependentUpon>
</Compile>
<Compile Include="Model.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Model.tt</DependentUpon>
</Compile>
<Compile Include="Model.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Model.edmx</DependentUpon>
</Compile>
<Compile Include="NotificationIcon.cs" />
<Compile Include="Options\AboutOptionsPanel.xaml.cs">
<DependentUpon>AboutOptionsPanel.xaml</DependentUpon>
</Compile>
<Compile Include="Options\BulkFeedWindow.xaml.cs">
<DependentUpon>BulkFeedWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Options\CategoryWindow.xaml.cs">
<DependentUpon>CategoryWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Options\DisplayOptionsPanel.xaml.cs">
<DependentUpon>DisplayOptionsPanel.xaml</DependentUpon>
</Compile>
<Compile Include="Options\FeedsOptionsPanel.xaml.cs">
<DependentUpon>FeedsOptionsPanel.xaml</DependentUpon>
</Compile>
<Compile Include="Options\FeedWindow.xaml.cs">
<DependentUpon>FeedWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Options\GeneralOptionsPanel.xaml.cs">
<DependentUpon>GeneralOptionsPanel.xaml</DependentUpon>
</Compile>
<Compile Include="Options\Options.cs" />
<Compile Include="Options\OptionsPanelBase.cs" />
<Compile Include="Options\OptionsWindow.xaml.cs">
<DependentUpon>OptionsWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Options\ReadingOptionsPanel.xaml.cs">
<DependentUpon>ReadingOptionsPanel.xaml</DependentUpon>
</Compile>
<Compile Include="Options\UpdateOptionsPanel.xaml.cs">
<DependentUpon>UpdateOptionsPanel.xaml</DependentUpon>
</Compile>
<Compile Include="Setting.cs">
<DependentUpon>Model.tt</DependentUpon>
</Compile>
<Compile Include="SettingsStore.cs" />
<Compile Include="SplashWindow.xaml.cs">
<DependentUpon>SplashWindow.xaml</DependentUpon>
</Compile>
<Compile Include="VersionCheck.cs" />
<Page Include="FeedErrorWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Data\Database.cs" />
<Compile Include="FeedParsers\AtomParser.cs" />
<Compile Include="FeedParsers\FeedParserBase.cs" />
<Compile Include="FeedParsers\RdfParser.cs" />
<Compile Include="FeedParsers\RssParser.cs" />
<Compile Include="Feeds\Feed.cs" />
<Compile Include="Feeds\FeedAction.cs" />
<Compile Include="Feeds\FeedItem.cs" />
<Compile Include="MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Page Include="Options\AboutOptionsPanel.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Options\BulkFeedWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Options\CategoryWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Options\DisplayOptionsPanel.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Options\FeedsOptionsPanel.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Options\FeedWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Options\GeneralOptionsPanel.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Options\OptionsWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Options\ReadingOptionsPanel.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Options\UpdateOptionsPanel.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="SplashWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Style.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<None Include="app.config">
<SubType>Designer</SubType>
</None>
<None Include="C:\Program Files\Microsoft SQL Server Compact Edition\v4.0\Private\amd64\Microsoft.VC90.CRT\Microsoft.VC90.CRT.manifest">
<Link>amd64\Microsoft.VC90.CRT\Microsoft.VC90.CRT.manifest</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="C:\Program Files\Microsoft SQL Server Compact Edition\v4.0\Private\x86\Microsoft.VC90.CRT\Microsoft.VC90.CRT.manifest">
<Link>x86\Microsoft.VC90.CRT\Microsoft.VC90.CRT.manifest</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<EntityDeploy Include="Model.edmx">
<Generator>EntityModelCodeGenerator</Generator>
<LastGenOutput>Model.Designer.cs</LastGenOutput>
</EntityDeploy>
<None Include="FeedCenter_1_TemporaryKey.pfx" />
<None Include="FeedCenter_TemporaryKey.pfx" />
<None Include="Model.Context.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>Model.Context.cs</LastGenOutput>
<DependentUpon>Model.edmx</DependentUpon>
</None>
<None Include="Model.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>Model.cs</LastGenOutput>
<DependentUpon>Model.edmx</DependentUpon>
</None>
<None Include="packages.config" />
<None Include="Properties\app.manifest" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<AppDesigner Include="Properties\" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Application.ico" />
</ItemGroup>
<ItemGroup>
<None Include="Scripts\DatabaseUpdate_6.sqlce" />
<None Include="Scripts\DatabaseUpdate_5.sqlce" />
<None Include="Scripts\DatabaseUpdate_4.sqlce" />
<None Include="Scripts\DatabaseUpdate_3.sqlce" />
<None Include="Scripts\DatabaseUpdate_2.sqlce" />
<None Include="Scripts\DatabaseUpdate_1.sqlce" />
<None Include="Scripts\CreateDatabase.sqlce" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.5.1">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4.5.1 %28x86 and x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Windows.Installer.4.5">
<Visible>False</Visible>
<ProductName>Windows Installer 4.5</ProductName>
<Install>true</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Common.Native\Common.Native.csproj">
<Project>{ED1C07A1-54F5-4796-8B06-2A0BB1960D84}</Project>
<Name>Common.Native</Name>
</ProjectReference>
<ProjectReference Include="..\Common.Wpf\Common.Wpf.csproj">
<Project>{0074C983-550E-4094-9E8C-F566FB669297}</Project>
<Name>Common.Wpf</Name>
</ProjectReference>
<ProjectReference Include="..\Common\Common.csproj">
<Project>{17864D82-457D-4A0A-BC10-1D07F2B3A5D6}</Project>
<Name>Common</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="C:\Program Files\Microsoft SQL Server Compact Edition\v4.0\Private\amd64\Microsoft.VC90.CRT\msvcr90.dll">
<Link>amd64\Microsoft.VC90.CRT\msvcr90.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="C:\Program Files\Microsoft SQL Server Compact Edition\v4.0\Private\amd64\sqlceca40.dll">
<Link>amd64\sqlceca40.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="C:\Program Files\Microsoft SQL Server Compact Edition\v4.0\Private\amd64\sqlcecompact40.dll">
<Link>amd64\sqlcecompact40.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="C:\Program Files\Microsoft SQL Server Compact Edition\v4.0\Private\amd64\sqlceer40EN.dll">
<Link>amd64\sqlceer40EN.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="C:\Program Files\Microsoft SQL Server Compact Edition\v4.0\Private\amd64\sqlceme40.dll">
<Link>amd64\sqlceme40.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="C:\Program Files\Microsoft SQL Server Compact Edition\v4.0\Private\amd64\sqlceqp40.dll">
<Link>amd64\sqlceqp40.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="C:\Program Files\Microsoft SQL Server Compact Edition\v4.0\Private\amd64\sqlcese40.dll">
<Link>amd64\sqlcese40.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Resource Include="Resources\Rss-Download.ico" />
<Resource Include="Resources\Comments-edit.ico" />
<Resource Include="Resources\Warning.ico" />
<Resource Include="Resources\News.ico" />
<Resource Include="Resources\Compile.ico" />
<Resource Include="Resources\Left.ico" />
<Resource Include="Resources\Right.ico" />
<None Include="C:\Program Files\Microsoft SQL Server Compact Edition\v4.0\Private\System.Data.SqlServerCe.dll">
<Link>Libraries\System.Data.SqlServerCe.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="C:\Program Files\Microsoft SQL Server Compact Edition\v4.0\Private\System.Data.SqlServerCe.Entity.dll">
<Link>Libraries\System.Data.SqlServerCe.Entity.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<Content Include="C:\Program Files\Microsoft SQL Server Compact Edition\v4.0\Private\x86\Microsoft.VC90.CRT\msvcr90.dll">
<Link>x86\Microsoft.VC90.CRT\msvcr90.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="C:\Program Files\Microsoft SQL Server Compact Edition\v4.0\Private\x86\sqlceca40.dll">
<Link>x86\sqlceca40.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="C:\Program Files\Microsoft SQL Server Compact Edition\v4.0\Private\x86\sqlcecompact40.dll">
<Link>x86\sqlcecompact40.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="C:\Program Files\Microsoft SQL Server Compact Edition\v4.0\Private\x86\sqlceer40EN.dll">
<Link>x86\sqlceer40EN.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="C:\Program Files\Microsoft SQL Server Compact Edition\v4.0\Private\x86\sqlceme40.dll">
<Link>x86\sqlceme40.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="C:\Program Files\Microsoft SQL Server Compact Edition\v4.0\Private\x86\sqlceqp40.dll">
<Link>x86\sqlceqp40.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="C:\Program Files\Microsoft SQL Server Compact Edition\v4.0\Private\x86\sqlcese40.dll">
<Link>x86\sqlcese40.dll</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>
if not exist "$(TargetDir)x86" md "$(TargetDir)x86"
xcopy /s /y "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8854.1\NativeBinaries\x86\*.*" "$(TargetDir)x86"
if not exist "$(TargetDir)amd64" md "$(TargetDir)amd64"
xcopy /s /y "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8854.1\NativeBinaries\amd64\*.*" "$(TargetDir)amd64"</PostBuildEvent>
</PropertyGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -0,0 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=Feeds/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is automatically generated by Visual Studio .Net. It is
used to store generic object data source configuration information.
Renaming the file extension or editing the content of this file may
cause the file to be unrecognizable by the program.
-->
<GenericObjectDataSource DisplayName="FeedCenterEntities" Identifier="FeedCenter.FeedCenterEntities" ProviderType="Microsoft.VisualStudio.DataDesign.DataSourceProviders.EntityDataModel.EdmDataSourceProvider" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<TypeInfo>FeedCenter.FeedCenterEntities, Model.Designer.cs, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
</GenericObjectDataSource>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is automatically generated by Visual Studio .Net. It is
used to store generic object data source configuration information.
Renaming the file extension or editing the content of this file may
cause the file to be unrecognizable by the program.
-->
<GenericObjectDataSource DisplayName="FeedCenterEntities" Identifier="FeedCenter.FeedCenterEntities" ProviderType="Microsoft.VisualStudio.DataDesign.DataSourceProviders.EntityDataModel.EdmDataSourceProvider" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<TypeInfo>FeedCenter.FeedCenterEntities, Model.Designer.cs, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
</GenericObjectDataSource>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is automatically generated by Visual Studio .Net. It is
used to store generic object data source configuration information.
Renaming the file extension or editing the content of this file may
cause the file to be unrecognizable by the program.
-->
<GenericObjectDataSource DisplayName="FeedCenterEntities" Identifier="FeedCenter.FeedCenterEntities" ProviderType="Microsoft.VisualStudio.DataDesign.DataSourceProviders.EntityDataModel.EdmDataSourceProvider" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<TypeInfo>FeedCenter.FeedCenterEntities, Model.Designer.cs, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
</GenericObjectDataSource>

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,112 @@
<Window x:Class="FeedCenter.FeedErrorWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="{x:Static my:Resources.FeedErrorWindow}"
Height="300"
Width="550"
WindowStartupLocation="CenterOwner"
Icon="/FeedCenter;component/Resources/Application.ico"
xmlns:my="clr-namespace:FeedCenter.Properties"
xmlns:LinkControl="clr-namespace:Common.Wpf.LinkControl;assembly=Common.Wpf"
WindowStyle="ToolWindow">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="225*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<DataGrid AutoGenerateColumns="False"
Name="feedDataGrid"
CanUserReorderColumns="False"
GridLinesVisibility="None"
SelectionMode="Single"
IsReadOnly="True"
CanUserResizeRows="False"
HeadersVisibility="Column"
Margin="6,6,6,0"
Background="{x:Null}"
CanUserSortColumns="True">
<DataGrid.CellStyle>
<Style TargetType="DataGridCell">
<Setter Property="BorderThickness"
Value="0" />
</Style>
</DataGrid.CellStyle>
<DataGrid.Columns>
<DataGridTextColumn Header="{x:Static my:Resources.FeedNameColumnHeader}"
Binding="{Binding Name}"
Width="*"
SortDirection="Ascending">
</DataGridTextColumn>
<DataGridTextColumn Header="{x:Static my:Resources.FeedErrorColumnHeader}"
Binding="{Binding LastReadResultDescription}"
Width="*">
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding LastUpdated, StringFormat=d}"
Header="{x:Static my:Resources.LastUpdatedColumnHeader}"
Width="Auto" />
</DataGrid.Columns>
</DataGrid>
<Border Grid.Row="1"
BorderThickness="1,0,1,1"
Margin="6,0,6,3"
BorderBrush="{DynamicResource {x:Static SystemColors.ActiveBorderBrushKey}}">
<StackPanel Orientation="Horizontal"
Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}">
<LinkControl:LinkControl Name="editFeedButton"
Margin="2"
Click="HandleEditFeedButtonClick"
Text="{x:Static my:Resources.EditLink}"
ToolTip="{x:Static my:Resources.EditFeedButton}">
</LinkControl:LinkControl>
<LinkControl:LinkControl Name="deleteFeedButton"
Margin="2"
Click="HandleDeleteFeedButtonClick"
Text="{x:Static my:Resources.DeleteLink}"
ToolTip="{x:Static my:Resources.DeleteFeedButton}">
</LinkControl:LinkControl>
<LinkControl:LinkControl Name="refreshCurrent"
Margin="2"
Click="HandleRefreshCurrentButtonClick"
Text="{x:Static my:Resources.RefreshCurrent}"
ToolTip="{x:Static my:Resources.RefreshCurrent}">
</LinkControl:LinkControl>
<LinkControl:LinkControl Name="openPage"
Margin="6,2,2,2"
Click="HandleOpenPageButtonClick"
Text="{x:Static my:Resources.OpenPage}"
ToolTip="{x:Static my:Resources.OpenPage}">
</LinkControl:LinkControl>
<LinkControl:LinkControl Name="openFeed"
Margin="2"
Click="HandleOpenFeedButtonClick"
Text="{x:Static my:Resources.OpenFeed}"
ToolTip="{x:Static my:Resources.OpenFeed}">
</LinkControl:LinkControl>
</StackPanel>
</Border>
<Grid DockPanel.Dock="Right"
Grid.Row="2"
Margin="6,3,6,6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button Content="{x:Static my:Resources.OkayButton}"
Height="23"
IsDefault="True"
Name="okButton"
Width="75"
Grid.Column="1"
Click="HandleOkayButtonClick" />
<Button Content="{x:Static my:Resources.CancelButton}"
Height="23"
IsCancel="True"
Name="cancelButton"
Width="75"
Margin="6,0,0,0"
Grid.Column="2" />
</Grid>
</Grid>
</Window>

View File

@@ -0,0 +1,122 @@
using FeedCenter.Options;
using System.ComponentModel;
using System.Windows;
using System.Windows.Data;
using System.Windows.Input;
namespace FeedCenter
{
public partial class FeedErrorWindow
{
public FeedErrorWindow()
{
InitializeComponent();
}
private FeedCenterEntities _database;
private CollectionViewSource _collectionViewSource;
public bool? Display(Window owner)
{
_database = new FeedCenterEntities();
// Create a view and sort it by name
_collectionViewSource = new CollectionViewSource { Source = _database.AllFeeds };
_collectionViewSource.Filter += HandleCollectionViewSourceFilter;
_collectionViewSource.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
// Bind to the list
feedDataGrid.ItemsSource = _collectionViewSource.View;
feedDataGrid.SelectedIndex = 0;
// Set the window owner
Owner = owner;
// Show the dialog and result the result
return ShowDialog();
}
private void HandleCollectionViewSourceFilter(object sender, FilterEventArgs e)
{
var feed = (Feed) e.Item;
e.Accepted = (feed.LastReadResult != FeedReadResult.Success);
}
private void HandleEditFeedButtonClick(object sender, RoutedEventArgs e)
{
EditSelectedFeed();
}
private void HandleDeleteFeedButtonClick(object sender, RoutedEventArgs e)
{
DeleteSelectedFeed();
}
private void EditSelectedFeed()
{
if (feedDataGrid.SelectedItem == null)
return;
var feed = (Feed) feedDataGrid.SelectedItem;
var feedWindow = new FeedWindow();
feedWindow.Display(_database, feed, GetWindow(this));
}
private void DeleteSelectedFeed()
{
var feed = (Feed) feedDataGrid.SelectedItem;
_database.Feeds.Remove(feed);
SetFeedButtonStates();
}
private void SetFeedButtonStates()
{
editFeedButton.IsEnabled = (feedDataGrid.SelectedItem != null);
deleteFeedButton.IsEnabled = (feedDataGrid.SelectedItem != null);
refreshCurrent.IsEnabled = (feedDataGrid.SelectedItem != null);
openPage.IsEnabled = (feedDataGrid.SelectedItem != null);
openFeed.IsEnabled = (feedDataGrid.SelectedItem != null);
}
private void HandleOpenPageButtonClick(object sender, RoutedEventArgs e)
{
var feed = (Feed) feedDataGrid.SelectedItem;
BrowserCommon.OpenLink(feed.Link);
}
private void HandleOpenFeedButtonClick(object sender, RoutedEventArgs e)
{
var feed = (Feed) feedDataGrid.SelectedItem;
BrowserCommon.OpenLink(feed.Source);
}
private void HandleOkayButtonClick(object sender, RoutedEventArgs e)
{
// Save the actual settings
_database.SaveChanges();
DialogResult = true;
Close();
}
private void HandleRefreshCurrentButtonClick(object sender, RoutedEventArgs e)
{
Mouse.OverrideCursor = Cursors.Wait;
var feed = (Feed) feedDataGrid.SelectedItem;
feed.Read(_database, true);
_collectionViewSource.View.Refresh();
SetFeedButtonStates();
Mouse.OverrideCursor = null;
}
}
}

38
Application/FeedItem.cs Normal file
View File

@@ -0,0 +1,38 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace FeedCenter
{
using System;
using System.Collections.Generic;
public partial class FeedItem
{
public FeedItem()
{
this.Title = "";
this.Link = "";
this.Description = "";
this.LastFound = new DateTime(599266080000000000, DateTimeKind.Unspecified);
}
public System.Guid ID { get; set; }
public System.Guid FeedID { get; set; }
public string Title { get; set; }
public string Link { get; set; }
public string Description { get; set; }
public bool BeenRead { get; set; }
public System.DateTime LastFound { get; set; }
public bool New { get; set; }
public string Guid { get; set; }
public int Sequence { get; set; }
public virtual Feed Feed { get; set; }
}
}

View File

@@ -0,0 +1,137 @@
using Common.Debug;
using Common.Xml;
using System.Xml;
namespace FeedCenter.FeedParsers
{
internal class AtomParser : FeedParserBase
{
public AtomParser(Feed feed) : base(feed) { }
public override FeedReadResult ParseFeed(string feedText)
{
try
{
// Create the XML document
var document = new XmlDocument { XmlResolver = null };
// Load the XML document from the text
document.LoadXml(feedText);
// Create the namespace manager
var namespaceManager = document.GetAllNamespaces();
// Get the root node
XmlNode rootNode = document.DocumentElement;
// If we didn't find a root node then bail
if (rootNode == null)
return FeedReadResult.UnknownError;
// Initialize the sequence number for items
var sequence = 0;
// Loop over all nodes in the root node
foreach (XmlNode node in rootNode.ChildNodes)
{
// Handle each node that we find
switch (node.Name)
{
case "title":
Feed.Title = System.Net.WebUtility.HtmlDecode(node.InnerText).Trim();
break;
case "link":
string rel = null;
if (node.Attributes == null)
break;
XmlNode relNode = node.Attributes["rel"];
if (relNode != null)
rel = relNode.InnerText;
if (string.IsNullOrEmpty(rel) || rel == "alternate")
Feed.Link = node.Attributes["href"].InnerText.Trim();
break;
case "subtitle":
Feed.Description = node.InnerText;
break;
case "entry":
HandleFeedItem(namespaceManager, node, ref sequence);
break;
}
}
return FeedReadResult.Success;
}
catch (XmlException xmlException)
{
Tracer.WriteLine("XML error: " + xmlException.Message + "\n" + feedText);
return FeedReadResult.InvalidXml;
}
}
protected override FeedItem ParseFeedItem(XmlNamespaceManager namespaceManager, XmlNode node)
{
// Create a new feed item
var feedItem = FeedItem.Create();
// Loop over all nodes in the feed node
foreach (XmlNode childNode in node.ChildNodes)
{
// Handle each node that we find
switch (childNode.Name.ToLower())
{
case "title":
feedItem.Title = System.Net.WebUtility.HtmlDecode(childNode.InnerText).Trim();
break;
case "id":
feedItem.Guid = childNode.InnerText;
break;
case "content":
feedItem.Description = System.Net.WebUtility.HtmlDecode(childNode.InnerText);
break;
case "link":
string rel = null;
if (childNode.Attributes == null)
break;
XmlNode relNode = childNode.Attributes["rel"];
if (relNode != null)
rel = relNode.InnerText.Trim();
if (string.IsNullOrEmpty(rel) || rel == "alternate")
{
var link = childNode.Attributes["href"].InnerText;
if (link.StartsWith("/"))
{
link = Feed.Link + link;
link = link.Replace("//", "/");
}
feedItem.Link = link;
}
break;
}
}
if (string.IsNullOrWhiteSpace(feedItem.Guid))
feedItem.Guid = feedItem.Link;
return feedItem;
}
}
}

View File

@@ -0,0 +1,159 @@
using Common.Debug;
using System;
using System.Linq;
using System.Xml;
namespace FeedCenter.FeedParsers
{
[Serializable]
internal class InvalidFeedFormatException : ApplicationException
{
internal InvalidFeedFormatException(Exception exception)
: base(string.Empty, exception)
{
}
}
internal abstract class FeedParserBase
{
#region Member variables
protected readonly Feed Feed;
#endregion
#region Constructor
protected FeedParserBase(Feed feed)
{
Feed = feed;
}
#endregion
#region Methods
public abstract FeedReadResult ParseFeed(string feedText);
protected abstract FeedItem ParseFeedItem(XmlNamespaceManager namespaceManager, XmlNode node);
protected void HandleFeedItem(XmlNamespaceManager namespaceManager, XmlNode node, ref int sequence)
{
// Build a feed item from the node
FeedItem newFeedItem = ParseFeedItem(namespaceManager, node);
if (newFeedItem == null)
return;
// Check for feed items with no guid or link
if (string.IsNullOrWhiteSpace(newFeedItem.Guid) && string.IsNullOrWhiteSpace(newFeedItem.Link))
return;
// Look for an item that has the same guid
FeedItem existingFeedItem = Feed.Items.FirstOrDefault(item => item.Guid == newFeedItem.Guid && item.ID != newFeedItem.ID);
// Check to see if we already have this feed item
if (existingFeedItem == null)
{
Tracer.WriteLine("New link: " + newFeedItem.Link);
// Associate the new item with the right feed
newFeedItem.Feed = Feed;
// Set the item as new
newFeedItem.New = true;
// Add the item to the list
Feed.Items.Add(newFeedItem);
// Feed was updated
Feed.LastUpdated = DateTime.Now;
}
else
{
Tracer.WriteLine("Existing link: " + newFeedItem.Link);
// Update the fields in the existing item
existingFeedItem.Link = newFeedItem.Link;
existingFeedItem.Title = newFeedItem.Title;
existingFeedItem.Guid = newFeedItem.Guid;
existingFeedItem.Description = newFeedItem.Description;
// Item is no longer new
existingFeedItem.New = false;
// Switch over to the existing item for the rest
newFeedItem = existingFeedItem;
}
// Item was last seen now
newFeedItem.LastFound = Feed.LastChecked;
// Set the sequence
newFeedItem.Sequence = sequence;
// Increment the sequence
sequence++;
}
#endregion
#region Parser creation and detection
public static FeedParserBase CreateFeedParser(Feed feed, string feedText)
{
FeedType feedType = DetectFeedType(feedText);
switch (feedType)
{
case FeedType.Rss:
return new RssParser(feed);
case FeedType.Rdf:
return new RdfParser(feed);
case FeedType.Atom:
return new AtomParser(feed);
}
throw new ArgumentException(string.Format("Feed type {0} is not supported", feedType));
}
public static FeedType DetectFeedType(string feedText)
{
try
{
// Create the XML document
var document = new XmlDocument { XmlResolver = null };
// Load the XML document from the text
document.LoadXml(feedText);
// Loop over all child nodes
foreach (XmlNode node in document.ChildNodes)
{
switch (node.Name)
{
case "rss":
return FeedType.Rss;
case "rdf:RDF":
return FeedType.Rdf;
case "feed":
return FeedType.Atom;
}
}
// No clue!
return FeedType.Unknown;
}
catch (Exception exception)
{
throw new InvalidFeedFormatException(exception);
}
}
#endregion
}
}

View File

@@ -0,0 +1,114 @@
using Common.Debug;
using Common.Xml;
using System.Xml;
namespace FeedCenter.FeedParsers
{
internal class RdfParser : FeedParserBase
{
public RdfParser(Feed feed) : base(feed) { }
public override FeedReadResult ParseFeed(string feedText)
{
try
{
// Create the XML document
var document = new XmlDocument { XmlResolver = null };
// Load the XML document from the text
document.LoadXml(feedText);
// Create the namespace manager
XmlNamespaceManager namespaceManager = document.GetAllNamespaces();
// Get the root node
XmlNode rootNode = document.DocumentElement;
// If we didn't find a root node then bail
if (rootNode == null)
return FeedReadResult.UnknownError;
// Get the channel node
XmlNode channelNode = rootNode.SelectSingleNode("default:channel", namespaceManager);
if (channelNode == null)
return FeedReadResult.InvalidXml;
// Loop over all nodes in the channel node
foreach (XmlNode node in channelNode.ChildNodes)
{
// Handle each node that we find
switch (node.Name)
{
case "title":
Feed.Title = System.Net.WebUtility.HtmlDecode(node.InnerText).Trim();
break;
case "link":
Feed.Link = node.InnerText.Trim();
break;
case "description":
Feed.Description = node.InnerText;
break;
}
}
// Initialize the sequence number for items
int sequence = 0;
// Loop over all nodes in the channel node
foreach (XmlNode node in rootNode.ChildNodes)
{
// Handle each node that we find
switch (node.Name)
{
case "item":
HandleFeedItem(namespaceManager, node, ref sequence);
break;
}
}
return FeedReadResult.Success;
}
catch (XmlException xmlException)
{
Tracer.WriteLine("XML error: " + xmlException.Message + "\n" + feedText);
return FeedReadResult.InvalidXml;
}
}
protected override FeedItem ParseFeedItem(XmlNamespaceManager namespaceManager, XmlNode node)
{
// Create a new feed item
FeedItem feedItem = FeedItem.Create();
// Loop over all nodes in the feed node
foreach (XmlNode childNode in node.ChildNodes)
{
// Handle each node that we find
switch (childNode.Name.ToLower())
{
case "title":
feedItem.Title = System.Net.WebUtility.HtmlDecode(childNode.InnerText).Trim();
break;
case "link":
feedItem.Link = childNode.InnerText.Trim();
// RDF doesn't have a GUID node so we'll just use the link
feedItem.Guid = feedItem.Link;
break;
case "description":
feedItem.Description = System.Net.WebUtility.HtmlDecode(childNode.InnerText);
break;
}
}
return feedItem;
}
}
}

View File

@@ -0,0 +1,121 @@
using Common.Debug;
using Common.Xml;
using System.Xml;
namespace FeedCenter.FeedParsers
{
internal class RssParser : FeedParserBase
{
public RssParser(Feed feed) : base(feed) { }
public override FeedReadResult ParseFeed(string feedText)
{
try
{
// Create the XML document
var document = new XmlDocument { XmlResolver = null };
// Load the XML document from the text
document.LoadXml(feedText);
// Create the namespace manager
XmlNamespaceManager namespaceManager = document.GetAllNamespaces();
// Get the root node
XmlNode rootNode = document.DocumentElement;
// If we didn't find a root node then bail
if (rootNode == null)
return FeedReadResult.UnknownError;
// Get the channel node
XmlNode channelNode = rootNode.SelectSingleNode("default:channel", namespaceManager);
if (channelNode == null)
return FeedReadResult.InvalidXml;
// Initialize the sequence number for items
int sequence = 0;
// Loop over all nodes in the channel node
foreach (XmlNode node in channelNode.ChildNodes)
{
// Handle each node that we find
switch (node.Name)
{
case "title":
Feed.Title = System.Net.WebUtility.HtmlDecode(node.InnerText).Trim();
break;
case "link":
Feed.Link = node.InnerText.Trim();
break;
case "description":
Feed.Description = node.InnerText;
break;
case "item":
HandleFeedItem(namespaceManager, node, ref sequence);
break;
}
}
return FeedReadResult.Success;
}
catch (XmlException xmlException)
{
Tracer.WriteLine("XML error: " + xmlException.Message + "\n" + feedText);
return FeedReadResult.InvalidXml;
}
}
protected override FeedItem ParseFeedItem(XmlNamespaceManager namespaceManager, XmlNode node)
{
// Create a new feed item
FeedItem feedItem = FeedItem.Create();
// Loop over all nodes in the feed node
foreach (XmlNode childNode in node.ChildNodes)
{
// Handle each node that we find
switch (childNode.Name.ToLower())
{
case "title":
feedItem.Title = System.Net.WebUtility.HtmlDecode(childNode.InnerText).Trim();
break;
case "link":
feedItem.Link = childNode.InnerText.Trim();
break;
case "guid":
feedItem.Guid = childNode.InnerText.Trim();
bool permaLink = true;
if (childNode.Attributes != null)
{
var permaLinkNode = childNode.Attributes.GetNamedItem("isPermaLink");
permaLink = (permaLinkNode == null || permaLinkNode.Value == "true");
}
if (permaLink)
feedItem.Link = feedItem.Guid;
break;
case "description":
feedItem.Description = System.Net.WebUtility.HtmlDecode(childNode.InnerText);
break;
}
}
if (string.IsNullOrWhiteSpace(feedItem.Guid))
feedItem.Guid = feedItem.Link;
return feedItem;
}
}
}

View File

@@ -0,0 +1,22 @@
using System;
namespace FeedCenter
{
public partial class Category
{
public static Category Create()
{
return new Category { ID = Guid.NewGuid() };
}
public bool IsDefault
{
get { return Name == "< default >"; }
}
public int SortKey
{
get { return IsDefault ? 0 : 1; }
}
}
}

349
Application/Feeds/Feed.cs Normal file
View File

@@ -0,0 +1,349 @@
using Common.Debug;
using Common.Xml;
using FeedCenter.FeedParsers;
using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows.Data;
namespace FeedCenter
{
#region Enumerations
public enum MultipleOpenAction
{
IndividualPages,
SinglePage
}
public enum FeedType
{
Unknown,
Rss,
Rdf,
Atom
}
public enum FeedItemComparison : byte
{
Default,
Title
}
public enum FeedReadResult
{
Success,
NotModified,
NotDue,
UnknownError,
InvalidXml,
NotEnabled,
Unauthorized,
NoResponse,
NotFound,
Timeout,
ConnectionFailed,
ServerError
}
#endregion
[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;
}
}
public partial class Feed
{
public static Feed Create()
{
return new Feed { ID = Guid.NewGuid() };
}
#region Event delegates
public delegate void ErrorEventHandler(WebException webException);
#endregion
#region Reading
public FeedReadResult Read(FeedCenterEntities database, bool forceRead = false)
{
Tracer.WriteLine("Reading feed: {0}", Source);
Tracer.IncrementIndentLevel();
var result = ReadFeed(database, forceRead);
// Handle the result
switch (result)
{
case FeedReadResult.NotDue:
case FeedReadResult.NotEnabled:
case FeedReadResult.NotModified:
// Ignore
break;
default:
// Save as last result
LastReadResult = result;
break;
}
// If the feed was successfully read and we have no last update timestamp - set the last update timestamp to now
if (result == FeedReadResult.Success && LastUpdated == Data.Extensions.SqlDateTimeZero.Value)
LastUpdated = DateTime.Now;
Tracer.DecrementIndentLevel();
Tracer.WriteLine("Done reading feed: {0}", result);
return result;
}
private Tuple<FeedReadResult, string> RetrieveFeed()
{
try
{
// Create the web request
var oRequest = WebRequest.Create(new Uri(Source));
// Attempt to cast to a web request
var webRequest = oRequest as HttpWebRequest;
// If this is an http request set some special properties
if (webRequest != null)
{
// Make sure to use HTTP version 1.1
webRequest.ProtocolVersion = HttpVersion.Version11;
// Set that we'll accept compressed data
webRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
// Set a timeout
webRequest.Timeout = 10000;
// If we need to authenticate then set the credentials
if (Authenticate)
webRequest.Credentials = new NetworkCredential(Username, Password, Domain);
// Set a user agent string
webRequest.UserAgent = "FeedCenter 1.0 ALPHA";
}
// Set the default encoding
var encoding = Encoding.UTF8;
// Attempt to get the response
var response = (HttpWebResponse) oRequest.GetResponse();
// If the response included an encoding then change the encoding
if (response.ContentEncoding.Length > 0)
encoding = Encoding.GetEncoding(response.ContentEncoding);
// Get the response stream
var responseStream = response.GetResponseStream();
if (responseStream == null)
return Tuple.Create(FeedReadResult.NoResponse, string.Empty);
// Create the text reader
StreamReader textReader = new XmlSanitizingStream(responseStream, encoding);
// Get the feed text
var feedText = textReader.ReadToEnd();
// Get rid of any leading and trailing whitespace
feedText = feedText.Trim();
// Clean up common invalid XML characters
feedText = feedText.Replace("&nbsp;", "&#160;");
return Tuple.Create(FeedReadResult.Success, feedText);
}
catch (IOException ioException)
{
Tracer.WriteLine(ioException.Message);
return Tuple.Create(FeedReadResult.ConnectionFailed, string.Empty);
}
catch (WebException webException)
{
var result = FeedReadResult.UnknownError;
var errorResponse = webException.Response as HttpWebResponse;
if (errorResponse != null)
{
switch (errorResponse.StatusCode)
{
case HttpStatusCode.InternalServerError:
return Tuple.Create(FeedReadResult.ServerError, string.Empty);
case HttpStatusCode.NotModified:
return Tuple.Create(FeedReadResult.NotModified, string.Empty);
case HttpStatusCode.NotFound:
return Tuple.Create(FeedReadResult.NotFound, string.Empty);
case HttpStatusCode.Unauthorized:
case HttpStatusCode.Forbidden:
return Tuple.Create(FeedReadResult.Unauthorized, string.Empty);
}
}
switch (webException.Status)
{
case WebExceptionStatus.ConnectFailure:
case WebExceptionStatus.NameResolutionFailure:
result = FeedReadResult.ConnectionFailed;
break;
case WebExceptionStatus.Timeout:
result = FeedReadResult.Timeout;
break;
}
Tracer.WriteException(webException);
if (result == FeedReadResult.UnknownError)
Debug.Print("Unknown error");
return Tuple.Create(result, string.Empty);
}
catch (Exception exception)
{
Tracer.WriteLine(exception.Message);
return Tuple.Create(FeedReadResult.UnknownError, string.Empty);
}
}
private FeedReadResult ReadFeed(FeedCenterEntities database, bool forceRead)
{
try
{
// If not enabled then do nothing
if (!Enabled)
return FeedReadResult.NotEnabled;
// Check if we're forcing a read
if (!forceRead)
{
// Figure out how long since we last checked
var timeSpan = DateTime.Now - LastChecked;
// Check if we are due to read the feed
if (timeSpan.TotalMinutes < CheckInterval)
return FeedReadResult.NotDue;
}
// We're checking it now so update the time
LastChecked = DateTime.Now;
// Read the feed text
var retrieveResult = RetrieveFeed();
// Get the information out of the async result
var result = retrieveResult.Item1;
var feedText = retrieveResult.Item2;
// If we didn't successfully retrieve the feed then stop
if (result != FeedReadResult.Success)
return result;
// Create a new RSS parser
var feedParser = FeedParserBase.CreateFeedParser(this, feedText);
// Parse the feed
result = feedParser.ParseFeed(feedText);
// If we didn't successfully parse the feed then stop
if (result != FeedReadResult.Success)
return result;
// Create the removed items list - if an item wasn't seen during this check then remove it
var removedItems = Items.Where(testItem => testItem.LastFound != LastChecked).ToList();
// If items were removed the feed was updated
if (removedItems.Count > 0)
LastUpdated = DateTime.Now;
// Loop over the items to be removed
foreach (var itemToRemove in removedItems)
{
// Delete the item from the database
database.FeedItems.Remove(itemToRemove);
// Remove the item from the list
Items.Remove(itemToRemove);
}
// Process actions on this feed
ProcessActions();
return FeedReadResult.Success;
}
catch (InvalidFeedFormatException exception)
{
Tracer.WriteException(exception.InnerException);
return FeedReadResult.InvalidXml;
}
catch (Exception exception)
{
Tracer.WriteLine(exception.Message);
return FeedReadResult.UnknownError;
}
}
private void ProcessActions()
{
var sortedActions = from action in Actions orderby action.Sequence ascending select action;
foreach (var feedAction in sortedActions)
{
switch (feedAction.Field)
{
case 0:
Title = Title.Replace(feedAction.Search, feedAction.Replace);
break;
}
}
}
#endregion
public string LastReadResultDescription
{
get
{
// Cast the last read result to the proper enum
var lastReadResult = LastReadResult;
// Build the name of the resource using the enum name and the value
var resourceName = string.Format("{0}_{1}", typeof(FeedReadResult).Name, lastReadResult);
// Try to get the value from the resources
var resourceValue = Properties.Resources.ResourceManager.GetString(resourceName);
// Return the value or just the enum value if not found
return resourceValue ?? lastReadResult.ToString();
}
}
}
}

View File

@@ -0,0 +1,25 @@
using System;
namespace FeedCenter
{
public partial class FeedAction
{
#region Constructor
public FeedAction()
{
ID = Guid.NewGuid();
}
#endregion
#region Methods
public override string ToString()
{
return string.Format(Properties.Resources.FeedActionDescription, Field, Search, Replace);
}
#endregion
}
}

View File

@@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace FeedCenter
{
public partial class FeedItem
{
public static FeedItem Create()
{
return new FeedItem { ID = System.Guid.NewGuid() };
}
#region Methods
public override string ToString()
{
string title = Title;
switch (Properties.Settings.Default.MultipleLineDisplay)
{
case Options.MultipleLineDisplay.SingleLine:
// Strip any newlines from the title
title = Regex.Replace(title, @"\n", " ");
break;
case Options.MultipleLineDisplay.FirstLine:
// Find the first newline
int newlineIndex = title.IndexOf("\n", StringComparison.Ordinal);
// If a newline was found return everything before it
if (newlineIndex > -1)
title = title.Substring(0, newlineIndex);
break;
}
// Condense multiple spaces to one space
title = Regex.Replace(title, @"[ ]{2,}", " ");
// Condense tabs to one space
title = Regex.Replace(title, @"\t", " ");
// If the title is blank then put in the "no title" title
if (title.Length == 0)
title = Properties.Resources.NoTitleText;
return title;
}
public void ProcessActions(IEnumerable<FeedAction> feedActions)
{
foreach (FeedAction feedAction in feedActions)
{
switch (feedAction.Field)
{
case 1:
Title = Regex.Replace(Title, feedAction.Search, feedAction.Replace);
break;
}
}
}
#endregion
}
}

Binary file not shown.

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<noInheritable></noInheritable>
<assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.30729.4148" processorArchitecture="amd64" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
<file name="msvcr90.dll" hashalg="SHA1" hash="1b065fdf0cb8516b0553128eae4af39c5f8eeb46"><asmv2:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"><dsig:Transforms><dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity"></dsig:Transform></dsig:Transforms><dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></dsig:DigestMethod><dsig:DigestValue>Vy8CgQgbu3qH5JHTK0op4kR8114=</dsig:DigestValue></asmv2:hash></file> <file name="msvcp90.dll" hashalg="SHA1" hash="45d3027d87eade77317e92994790598c755b3920"><asmv2:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"><dsig:Transforms><dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity"></dsig:Transform></dsig:Transforms><dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></dsig:DigestMethod><dsig:DigestValue>QTJu3Gttpt8hhCktGelNeXj4Yp8=</dsig:DigestValue></asmv2:hash></file> <file name="msvcm90.dll" hashalg="SHA1" hash="e77fd69f7c88f34329d8a95c3179f67ead330217"><asmv2:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"><dsig:Transforms><dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity"></dsig:Transform></dsig:Transforms><dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></dsig:DigestMethod><dsig:DigestValue>1ruqF7/L+m1tqnJVscaOtNRNHIE=</dsig:DigestValue></asmv2:hash></file>
</assembly>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<noInheritable></noInheritable>
<assemblyIdentity type="win32" name="Microsoft.VC90.CRT" version="9.0.30729.4148" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
<file name="msvcr90.dll" hashalg="SHA1" hash="98e8006e0a4542e69f1a3555b927758bd76ca07d"><asmv2:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"><dsig:Transforms><dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity"></dsig:Transform></dsig:Transforms><dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></dsig:DigestMethod><dsig:DigestValue>+CXED+6HzJlSphyMNOn27ujadC0=</dsig:DigestValue></asmv2:hash></file> <file name="msvcp90.dll" hashalg="SHA1" hash="3aec3be680024a46813dee891a753bd58b3f3b12"><asmv2:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"><dsig:Transforms><dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity"></dsig:Transform></dsig:Transforms><dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></dsig:DigestMethod><dsig:DigestValue>MyKED+9DyS+1XcMeaC0Zlw2vFZ0=</dsig:DigestValue></asmv2:hash></file> <file name="msvcm90.dll" hashalg="SHA1" hash="0195dd0896d74b62531e4f3c771904a3d996450e"><asmv2:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"><dsig:Transforms><dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity"></dsig:Transform></dsig:Transforms><dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></dsig:DigestMethod><dsig:DigestValue>EeyDE7og6WoPd2oBhYbMEnpFHhY=</dsig:DigestValue></asmv2:hash></file>
</assembly>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

286
Application/MainWindow.xaml Normal file
View File

@@ -0,0 +1,286 @@
<Windows:SnappingWindow x:Class="FeedCenter.MainWindow"
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:Windows="clr-namespace:Common.Wpf.Windows;assembly=Common.Wpf"
xmlns:Toolbar="clr-namespace:Common.Wpf.Toolbar;assembly=Common.Wpf"
xmlns:SplitButton="clr-namespace:Common.Wpf.Toolbar.SplitButton;assembly=Common.Wpf"
xmlns:Markup="clr-namespace:Common.Wpf.MarkupExtensions;assembly=Common.Wpf.MarkupExtensions"
xmlns:LinkControl="clr-namespace:Common.Wpf.LinkControl;assembly=Common.Wpf"
xmlns:HtmlTextBlock="clr-namespace:Common.Wpf.HtmlTextBlock;assembly=Common.Wpf"
xmlns:System="clr-namespace:System;assembly=mscorlib"
Title="MainWindow"
Height="360"
Width="252"
WindowStyle="None"
ResizeMode="NoResize"
Background="{x:Static SystemColors.DesktopBrush}"
AllowDrop="True"
DragOver="HandleDragOver"
Drop="HandleDragDrop"
ShowInTaskbar="False">
<Window.Resources>
<Style TargetType="{x:Type ToolBar}">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToolBar}">
<ToolBarPanel IsItemsHost="True"
Margin="0,1,2,2"
SnapsToDevicePixels="True" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Border BorderBrush="{x:Static SystemColors.ActiveBorderBrush}"
BorderThickness="1"
Name="windowBorder"
Padding="0"
Background="{x:Static SystemColors.DesktopBrush}">
<Grid Name="mainGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"
Name="headerRow" />
<RowDefinition Height="Auto"
Name="newVersionRow" />
<RowDefinition Height="Auto"
Name="feedRow" />
<RowDefinition Height="Auto"
Name="topToolbarRow" />
<RowDefinition Height="*"
Name="feedListRow" />
<RowDefinition Height="Auto"
Name="progressRow" />
<RowDefinition Height="Auto"
Name="bottomToolbarRow" />
<RowDefinition Height="Auto"
Name="feedErrorsRow" />
</Grid.RowDefinitions>
<Grid Height="21"
Name="headerGrid"
Grid.Row="{Markup:GridRow RowName=headerRow}">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="21" />
</Grid.ColumnDefinitions>
<Label Content="{x:Static Properties:Resources.ApplicationDisplayName}"
Name="headerLabel"
Padding="3,0"
FontWeight="Bold"
Foreground="White"
MouseLeftButtonDown="HandleHeaderLabelMouseLeftButtonDown"
VerticalContentAlignment="Center"
Grid.Column="0" />
<Button Name="closeButton"
Width="13"
Height="13"
Click="HandleCloseButtonClick"
FontFamily="Marlett"
Content="r"
FontSize="8"
Grid.Column="1"></Button>
</Grid>
<LinkControl:LinkControl Name="newVersionLink"
Height="21"
Grid.Row="{Markup:GridRow newVersionRow}"
Text="{x:Static Properties:Resources.NewVersionLink}"
Background="AntiqueWhite"
VerticalContentAlignment="Center"
HorizontalContentAlignment="Center"
Visibility="Collapsed"
Click="HandleNewVersionLinkClick">
</LinkControl:LinkControl>
<Grid Height="21"
Name="feedGrid"
Grid.Row="{Markup:GridRow RowName=feedRow}">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="21" />
</Grid.ColumnDefinitions>
<TextBlock Text="*Feed Name"
Name="feedLabel"
Padding="3,0"
FontWeight="Bold"
Foreground="White"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Width="Auto"
Cursor="Hand"
TextTrimming="CharacterEllipsis"
MouseDown="HandleFeedLabelMouseDown"
Grid.Column="0" />
<Button Name="feedButton"
Width="13"
Height="13"
Click="HandleFeedButtonClick"
FontFamily="Marlett"
Content="u"
FontSize="8"
Grid.Column="1" />
</Grid>
<ListBox Name="linkTextList"
BorderThickness="0"
Background="{x:Static SystemColors.DesktopBrush}"
MouseUp="HandleLinkTextListMouseUp"
Foreground="White"
Grid.Row="{Markup:GridRow RowName=feedListRow}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListBoxItem Content="Test item" />
<ListBox.ItemTemplate>
<DataTemplate>
<HtmlTextBlock:HtmlTextBlock Html="{Binding}"
TextWrapping="Wrap"
Margin="0,1" />
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border BorderThickness="{TemplateBinding Border.BorderThickness}"
Padding="{TemplateBinding Control.Padding}"
BorderBrush="{TemplateBinding Border.BorderBrush}"
Background="{TemplateBinding Panel.Background}"
Name="Bd"
SnapsToDevicePixels="True">
<ContentPresenter Content="{TemplateBinding ContentControl.Content}"
ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}"
HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Selector.IsMouseOver">
<Trigger.Value>
<System:Boolean>True</System:Boolean>
</Trigger.Value>
<Setter Property="Panel.Background"
TargetName="Bd">
<Setter.Value>
<DynamicResource ResourceKey="{x:Static SystemColors.HighlightBrushKey}" />
</Setter.Value>
</Setter>
<Setter Property="TextElement.Foreground">
<Setter.Value>
<DynamicResource ResourceKey="{x:Static SystemColors.HighlightTextBrushKey}" />
</Setter.Value>
</Setter>
<Setter Property="Panel.Cursor"
TargetName="Bd"
Value="Hand">
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<EventSetter Event="MouseDoubleClick"
Handler="HandleLinkTextListListItemMouseDoubleClick" />
<EventSetter Event="MouseUp"
Handler="HandleLinkTextListListItemMouseUp" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
<ProgressBar Name="feedReadProgress"
Height="15"
Visibility="Collapsed"
Grid.Row="{Markup:GridRow RowName=progressRow}" />
<ToolBarTray Name="navigationToolbarTray"
Background="Transparent"
Orientation="Horizontal"
Grid.Row="{Markup:GridRow RowName=bottomToolbarRow}">
<ToolBar Name="navigationToolbar"
ToolBarTray.IsLocked="True"
Background="Transparent"
ToolBar.OverflowMode="Never">
<Toolbar:ImageButton Height="20"
Width="20"
Name="previousToolbarButton"
Click="HandlePreviousToolbarButtonClick"
ToolTip="{x:Static Properties:Resources.previousToolbarButton}"
ImageSource="Resources/Left.ico" />
<Toolbar:ImageButton Height="20"
Width="20"
Name="nextToolbarButton"
Click="HandleNextToolbarButtonClick"
ToolTip="{x:Static Properties:Resources.nextToolbarButton}"
ImageSource="Resources/Right.ico" />
<SplitButton:SplitButton Name="refreshToolbarButton"
Image="Resources/Rss-Download.ico"
ToolTip="{x:Static Properties:Resources.refreshAllToolbarButton}"
Height="20"
MinWidth="35"
Margin="5,0,0,0"
Click="HandleRefreshToolbarButtonClick">
<SplitButton:SplitButton.DropDownContextMenu>
<ContextMenu MenuItem.Click="HandleRefreshMenuItemClick">
<MenuItem Name="menuRefreshAll"
Header="{x:Static Properties:Resources.refreshAllToolbarButton}" />
<MenuItem Name="menuRefresh"
Header="{x:Static Properties:Resources.refreshToolbarButton}" />
</ContextMenu>
</SplitButton:SplitButton.DropDownContextMenu>
</SplitButton:SplitButton>
<SplitButton:SplitButton Name="openAllToolbarButton"
Image="Resources/News.ico"
ToolTip="{x:Static Properties:Resources.openAllMultipleToolbarButton}"
Height="20"
MinWidth="35"
Margin="5,0,0,0"
Click="HandleOpenAllToolbarButtonClick">
<SplitButton:SplitButton.DropDownContextMenu>
<ContextMenu MenuItem.Click="HandleOpenAllMenuItemClick">
<MenuItem Name="menuOpenAllMultiplePages"
Header="{x:Static Properties:Resources.openAllMultipleToolbarButton}" />
<MenuItem Name="menuOpenAllSinglePage"
Header="{x:Static Properties:Resources.openAllSingleToolbarButton}" />
</ContextMenu>
</SplitButton:SplitButton.DropDownContextMenu>
</SplitButton:SplitButton>
<Toolbar:ImageButton Height="20"
Width="20"
Margin="5,0,0,0"
Name="markReadToolbarButton"
Click="HandleMarkReadToolbarButtonClick"
ToolTip="{x:Static Properties:Resources.markReadToolbarButton}"
ImageSource="Resources/Comments-edit.ico" />
<SplitButton:SplitButton Height="20"
MinWidth="35"
Margin="5,0,0,0"
Name="optionsToolbarButton"
Click="HandleOptionsToolbarButtonClick"
ToolTip="{x:Static Properties:Resources.optionsToolbarButton}"
Image="Resources/Compile.ico">
<SplitButton:SplitButton.DropDownContextMenu>
<ContextMenu>
<MenuItem Header="{x:Static Properties:Resources.lockWindowCheckBox}"
IsCheckable="True"
IsChecked="{Binding Source={x:Static Properties:Settings.Default}, Path=WindowLocked}" />
<Separator />
<MenuItem Header="{x:Static Properties:Resources.CurrentFeed}">
<MenuItem Header="{x:Static Properties:Resources.EditMenu}"
Click="HandleEditCurrentFeedMenuItemClick" />
<MenuItem Header="{x:Static Properties:Resources.DeleteMenu}"
Click="HandleDeleteCurrentFeedMenuItemClick" />
</MenuItem>
</ContextMenu>
</SplitButton:SplitButton.DropDownContextMenu>
</SplitButton:SplitButton>
</ToolBar>
</ToolBarTray>
<LinkControl:LinkControl Name="feedErrorsLink"
Height="21"
Grid.Row="{Markup:GridRow feedErrorsRow}"
Text="{x:Static Properties:Resources.FeedErrorsLink}"
ToolTip="{x:Static Properties:Resources.showErrorsToolbarButton}"
Background="AntiqueWhite"
VerticalContentAlignment="Center"
HorizontalContentAlignment="Center"
Visibility="Collapsed"
Click="HandleShowErrorsButtonClick">
</LinkControl:LinkControl>
</Grid>
</Border>
</Windows:SnappingWindow>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,34 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace FeedCenter
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class FeedCenterEntities : DbContext
{
public FeedCenterEntities()
: base("name=FeedCenterEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<Category> Categories { get; set; }
public virtual DbSet<Feed> Feeds { get; set; }
public virtual DbSet<FeedAction> FeedActions { get; set; }
public virtual DbSet<FeedItem> FeedItems { get; set; }
public virtual DbSet<Setting> Settings { get; set; }
}
}

View File

@@ -0,0 +1,636 @@
<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="EF6.Utility.CS.ttinclude"#><#@
output extension=".cs"#><#
const string inputFile = @"Model.edmx";
var textTransform = DynamicTextTransformation.Create(this);
var code = new CodeGenerationTools(this);
var ef = new MetadataTools(this);
var typeMapper = new TypeMapper(code, ef, textTransform.Errors);
var loader = new EdmMetadataLoader(textTransform.Host, textTransform.Errors);
var itemCollection = loader.CreateEdmItemCollection(inputFile);
var modelNamespace = loader.GetModelNamespace(inputFile);
var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef);
var container = itemCollection.OfType<EntityContainer>().FirstOrDefault();
if (container == null)
{
return string.Empty;
}
#>
//------------------------------------------------------------------------------
// <auto-generated>
// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine1")#>
//
// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine2")#>
// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine3")#>
// </auto-generated>
//------------------------------------------------------------------------------
<#
var codeNamespace = code.VsNamespaceSuggestion();
if (!String.IsNullOrEmpty(codeNamespace))
{
#>
namespace <#=code.EscapeNamespace(codeNamespace)#>
{
<#
PushIndent(" ");
}
#>
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
<#
if (container.FunctionImports.Any())
{
#>
using System.Data.Entity.Core.Objects;
using System.Linq;
<#
}
#>
<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext
{
public <#=code.Escape(container)#>()
: base("name=<#=container.Name#>")
{
<#
if (!loader.IsLazyLoadingEnabled(container))
{
#>
this.Configuration.LazyLoadingEnabled = false;
<#
}
foreach (var entitySet in container.BaseEntitySets.OfType<EntitySet>())
{
// Note: the DbSet members are defined below such that the getter and
// setter always have the same accessibility as the DbSet definition
if (Accessibility.ForReadOnlyProperty(entitySet) != "public")
{
#>
<#=codeStringGenerator.DbSetInitializer(entitySet)#>
<#
}
}
#>
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
<#
foreach (var entitySet in container.BaseEntitySets.OfType<EntitySet>())
{
#>
<#=codeStringGenerator.DbSet(entitySet)#>
<#
}
foreach (var edmFunction in container.FunctionImports)
{
WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: false);
}
#>
}
<#
if (!String.IsNullOrEmpty(codeNamespace))
{
PopIndent();
#>
}
<#
}
#>
<#+
private void WriteFunctionImport(TypeMapper typeMapper, CodeStringGenerator codeStringGenerator, EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
{
if (typeMapper.IsComposable(edmFunction))
{
#>
[DbFunction("<#=edmFunction.NamespaceName#>", "<#=edmFunction.Name#>")]
<#=codeStringGenerator.ComposableFunctionMethod(edmFunction, modelNamespace)#>
{
<#+
codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter);
#>
<#=codeStringGenerator.ComposableCreateQuery(edmFunction, modelNamespace)#>
}
<#+
}
else
{
#>
<#=codeStringGenerator.FunctionMethod(edmFunction, modelNamespace, includeMergeOption)#>
{
<#+
codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter);
#>
<#=codeStringGenerator.ExecuteFunction(edmFunction, modelNamespace, includeMergeOption)#>
}
<#+
if (typeMapper.GenerateMergeOptionFunction(edmFunction, includeMergeOption))
{
WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: true);
}
}
}
public void WriteFunctionParameter(string name, string isNotNull, string notNullInit, string nullInit)
{
#>
var <#=name#> = <#=isNotNull#> ?
<#=notNullInit#> :
<#=nullInit#>;
<#+
}
public const string TemplateId = "CSharp_DbContext_Context_EF6";
public class CodeStringGenerator
{
private readonly CodeGenerationTools _code;
private readonly TypeMapper _typeMapper;
private readonly MetadataTools _ef;
public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef)
{
ArgumentNotNull(code, "code");
ArgumentNotNull(typeMapper, "typeMapper");
ArgumentNotNull(ef, "ef");
_code = code;
_typeMapper = typeMapper;
_ef = ef;
}
public string Property(EdmProperty edmProperty)
{
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1} {2} {{ {3}get; {4}set; }}",
Accessibility.ForProperty(edmProperty),
_typeMapper.GetTypeName(edmProperty.TypeUsage),
_code.Escape(edmProperty),
_code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
_code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
}
public string NavigationProperty(NavigationProperty navProp)
{
var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType());
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1} {2} {{ {3}get; {4}set; }}",
AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)),
navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
_code.Escape(navProp),
_code.SpaceAfter(Accessibility.ForGetter(navProp)),
_code.SpaceAfter(Accessibility.ForSetter(navProp)));
}
public string AccessibilityAndVirtual(string accessibility)
{
return accessibility + (accessibility != "private" ? " virtual" : "");
}
public string EntityClassOpening(EntityType entity)
{
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1}partial class {2}{3}",
Accessibility.ForType(entity),
_code.SpaceAfter(_code.AbstractOption(entity)),
_code.Escape(entity),
_code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
}
public string EnumOpening(SimpleType enumType)
{
return string.Format(
CultureInfo.InvariantCulture,
"{0} enum {1} : {2}",
Accessibility.ForType(enumType),
_code.Escape(enumType),
_code.Escape(_typeMapper.UnderlyingClrType(enumType)));
}
public void WriteFunctionParameters(EdmFunction edmFunction, Action<string, string, string, string> writeParameter)
{
var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable))
{
var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null";
var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")";
var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + TypeMapper.FixNamespaces(parameter.RawClrTypeName) + "))";
writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit);
}
}
public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace)
{
var parameters = _typeMapper.GetParameters(edmFunction);
return string.Format(
CultureInfo.InvariantCulture,
"{0} IQueryable<{1}> {2}({3})",
AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
_typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
_code.Escape(edmFunction),
string.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray()));
}
public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace)
{
var parameters = _typeMapper.GetParameters(edmFunction);
return string.Format(
CultureInfo.InvariantCulture,
"return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});",
_typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
edmFunction.NamespaceName,
edmFunction.Name,
string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()),
_code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())));
}
public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
{
var parameters = _typeMapper.GetParameters(edmFunction);
var returnType = _typeMapper.GetReturnType(edmFunction);
var paramList = String.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray());
if (includeMergeOption)
{
paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption";
}
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1} {2}({3})",
AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
_code.Escape(edmFunction),
paramList);
}
public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
{
var parameters = _typeMapper.GetParameters(edmFunction);
var returnType = _typeMapper.GetReturnType(edmFunction);
var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()));
if (includeMergeOption)
{
callParams = ", mergeOption" + callParams;
}
return string.Format(
CultureInfo.InvariantCulture,
"return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});",
returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
edmFunction.Name,
callParams);
}
public string DbSet(EntitySet entitySet)
{
return string.Format(
CultureInfo.InvariantCulture,
"{0} virtual DbSet<{1}> {2} {{ get; set; }}",
Accessibility.ForReadOnlyProperty(entitySet),
_typeMapper.GetTypeName(entitySet.ElementType),
_code.Escape(entitySet));
}
public string DbSetInitializer(EntitySet entitySet)
{
return string.Format(
CultureInfo.InvariantCulture,
"{0} = Set<{1}>();",
_code.Escape(entitySet),
_typeMapper.GetTypeName(entitySet.ElementType));
}
public string UsingDirectives(bool inHeader, bool includeCollections = true)
{
return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
? string.Format(
CultureInfo.InvariantCulture,
"{0}using System;{1}" +
"{2}",
inHeader ? Environment.NewLine : "",
includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
inHeader ? "" : Environment.NewLine)
: "";
}
}
public class TypeMapper
{
private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName";
private readonly System.Collections.IList _errors;
private readonly CodeGenerationTools _code;
private readonly MetadataTools _ef;
public static string FixNamespaces(string typeName)
{
return typeName.Replace("System.Data.Spatial.", "System.Data.Entity.Spatial.");
}
public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors)
{
ArgumentNotNull(code, "code");
ArgumentNotNull(ef, "ef");
ArgumentNotNull(errors, "errors");
_code = code;
_ef = ef;
_errors = errors;
}
public string GetTypeName(TypeUsage typeUsage)
{
return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null);
}
public string GetTypeName(EdmType edmType)
{
return GetTypeName(edmType, isNullable: null, modelNamespace: null);
}
public string GetTypeName(TypeUsage typeUsage, string modelNamespace)
{
return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace);
}
public string GetTypeName(EdmType edmType, string modelNamespace)
{
return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace);
}
public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace)
{
if (edmType == null)
{
return null;
}
var collectionType = edmType as CollectionType;
if (collectionType != null)
{
return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace));
}
var typeName = _code.Escape(edmType.MetadataProperties
.Where(p => p.Name == ExternalTypeNameAttributeName)
.Select(p => (string)p.Value)
.FirstOrDefault())
?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ?
_code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) :
_code.Escape(edmType));
if (edmType is StructuralType)
{
return typeName;
}
if (edmType is SimpleType)
{
var clrType = UnderlyingClrType(edmType);
if (!IsEnumType(edmType))
{
typeName = _code.Escape(clrType);
}
typeName = FixNamespaces(typeName);
return clrType.IsValueType && isNullable == true ?
String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) :
typeName;
}
throw new ArgumentException("edmType");
}
public Type UnderlyingClrType(EdmType edmType)
{
ArgumentNotNull(edmType, "edmType");
var primitiveType = edmType as PrimitiveType;
if (primitiveType != null)
{
return primitiveType.ClrEquivalentType;
}
if (IsEnumType(edmType))
{
return GetEnumUnderlyingType(edmType).ClrEquivalentType;
}
return typeof(object);
}
public object GetEnumMemberValue(MetadataItem enumMember)
{
ArgumentNotNull(enumMember, "enumMember");
var valueProperty = enumMember.GetType().GetProperty("Value");
return valueProperty == null ? null : valueProperty.GetValue(enumMember, null);
}
public string GetEnumMemberName(MetadataItem enumMember)
{
ArgumentNotNull(enumMember, "enumMember");
var nameProperty = enumMember.GetType().GetProperty("Name");
return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null);
}
public System.Collections.IEnumerable GetEnumMembers(EdmType enumType)
{
ArgumentNotNull(enumType, "enumType");
var membersProperty = enumType.GetType().GetProperty("Members");
return membersProperty != null
? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null)
: Enumerable.Empty<MetadataItem>();
}
public bool EnumIsFlags(EdmType enumType)
{
ArgumentNotNull(enumType, "enumType");
var isFlagsProperty = enumType.GetType().GetProperty("IsFlags");
return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null);
}
public bool IsEnumType(GlobalItem edmType)
{
ArgumentNotNull(edmType, "edmType");
return edmType.GetType().Name == "EnumType";
}
public PrimitiveType GetEnumUnderlyingType(EdmType enumType)
{
ArgumentNotNull(enumType, "enumType");
return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null);
}
public string CreateLiteral(object value)
{
if (value == null || value.GetType() != typeof(TimeSpan))
{
return _code.CreateLiteral(value);
}
return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks);
}
public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable<string> types, string sourceFile)
{
ArgumentNotNull(types, "types");
ArgumentNotNull(sourceFile, "sourceFile");
var hash = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
if (types.Any(item => !hash.Add(item)))
{
_errors.Add(
new CompilerError(sourceFile, -1, -1, "6023",
String.Format(CultureInfo.CurrentCulture, CodeGenerationTools.GetResourceString("Template_CaseInsensitiveTypeConflict"))));
return false;
}
return true;
}
public IEnumerable<SimpleType> GetEnumItemsToGenerate(IEnumerable<GlobalItem> itemCollection)
{
return GetItemsToGenerate<SimpleType>(itemCollection)
.Where(e => IsEnumType(e));
}
public IEnumerable<T> GetItemsToGenerate<T>(IEnumerable<GlobalItem> itemCollection) where T: EdmType
{
return itemCollection
.OfType<T>()
.Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName))
.OrderBy(i => i.Name);
}
public IEnumerable<string> GetAllGlobalItems(IEnumerable<GlobalItem> itemCollection)
{
return itemCollection
.Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i))
.Select(g => GetGlobalItemName(g));
}
public string GetGlobalItemName(GlobalItem item)
{
if (item is EdmType)
{
return ((EdmType)item).Name;
}
else
{
return ((EntityContainer)item).Name;
}
}
public IEnumerable<EdmProperty> GetSimpleProperties(EntityType type)
{
return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
}
public IEnumerable<EdmProperty> GetSimpleProperties(ComplexType type)
{
return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
}
public IEnumerable<EdmProperty> GetComplexProperties(EntityType type)
{
return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
}
public IEnumerable<EdmProperty> GetComplexProperties(ComplexType type)
{
return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
}
public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(EntityType type)
{
return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
}
public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(ComplexType type)
{
return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
}
public IEnumerable<NavigationProperty> GetNavigationProperties(EntityType type)
{
return type.NavigationProperties.Where(np => np.DeclaringType == type);
}
public IEnumerable<NavigationProperty> GetCollectionNavigationProperties(EntityType type)
{
return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
}
public FunctionParameter GetReturnParameter(EdmFunction edmFunction)
{
ArgumentNotNull(edmFunction, "edmFunction");
var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters");
return returnParamsProperty == null
? edmFunction.ReturnParameter
: ((IEnumerable<FunctionParameter>)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault();
}
public bool IsComposable(EdmFunction edmFunction)
{
ArgumentNotNull(edmFunction, "edmFunction");
var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute");
return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null);
}
public IEnumerable<FunctionImportParameter> GetParameters(EdmFunction edmFunction)
{
return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
}
public TypeUsage GetReturnType(EdmFunction edmFunction)
{
var returnParam = GetReturnParameter(edmFunction);
return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage);
}
public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption)
{
var returnType = GetReturnType(edmFunction);
return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType;
}
}
public static void ArgumentNotNull<T>(T arg, string name) where T : class
{
if (arg == null)
{
throw new ArgumentNullException(name);
}
}
#>

10
Application/Model.Designer.cs generated Normal file
View File

@@ -0,0 +1,10 @@
// T4 code generation is enabled for model 'D:\Code\Personal\FeedCenter\Model.edmx'.
// To enable legacy code generation, change the value of the 'Code Generation Strategy' designer
// property to 'Legacy ObjectContext'. This property is available in the Properties Window when the model
// is open in the designer.
// If no context and entity classes have been generated, it may be because you created an empty model but
// have not yet chosen which version of Entity Framework to use. To generate a context class and entity
// classes for your model, open the model in the designer, right-click on the designer surface, and
// select 'Update Model from Database...', 'Generate Database from Model...', or 'Add Code Generation
// Item...'.

9
Application/Model.cs Normal file
View File

@@ -0,0 +1,9 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

383
Application/Model.edmx Normal file
View File

@@ -0,0 +1,383 @@
<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="3.0" xmlns:edmx="http://schemas.microsoft.com/ado/2009/11/edmx">
<!-- EF Runtime content -->
<edmx:Runtime>
<!-- SSDL content -->
<edmx:StorageModels>
<Schema Namespace="FeedCenterModel.Store" Provider="System.Data.SqlServerCe.4.0" ProviderManifestToken="4.0" Alias="Self" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns:customannotation="http://schemas.microsoft.com/ado/2013/11/edm/customannotation" xmlns="http://schemas.microsoft.com/ado/2009/11/edm/ssdl">
<EntityType Name="Category">
<Key>
<PropertyRef Name="ID" />
</Key>
<Property Name="ID" Type="uniqueidentifier" Nullable="false" />
<Property Name="Name" Type="nvarchar" MaxLength="1000" Nullable="false" />
</EntityType>
<EntityType Name="Feed">
<Key>
<PropertyRef Name="ID" />
</Key>
<Property Name="ID" Type="uniqueidentifier" Nullable="false" />
<Property Name="Name" Type="nvarchar" MaxLength="1000" Nullable="false" />
<Property Name="Title" Type="nvarchar" MaxLength="1000" Nullable="false" />
<Property Name="Source" Type="nvarchar" MaxLength="1000" Nullable="false" />
<Property Name="Link" Type="nvarchar" MaxLength="1000" Nullable="false" />
<Property Name="Description" Type="ntext" Nullable="false" />
<Property Name="LastChecked" Type="datetime" Nullable="false" />
<Property Name="CheckInterval" Type="int" Nullable="false" />
<Property Name="Enabled" Type="bit" Nullable="false" />
<Property Name="Authenticate" Type="bit" Nullable="false" />
<Property Name="Username" Type="nvarchar" MaxLength="1000" Nullable="false" />
<Property Name="Password" Type="nvarchar" MaxLength="1000" Nullable="false" />
<Property Name="Domain" Type="nvarchar" MaxLength="1000" Nullable="false" />
<Property Name="LastReadResult" Type="int" Nullable="false" />
<Property Name="LastUpdated" Type="datetime" Nullable="false" />
<Property Name="ItemComparison" Type="tinyint" Nullable="false" />
<Property Name="CategoryID" Type="uniqueidentifier" Nullable="false" />
<Property Name="MultipleOpenAction" Type="int" Nullable="false" />
</EntityType>
<EntityType Name="FeedAction">
<Key>
<PropertyRef Name="ID" />
</Key>
<Property Name="ID" Type="uniqueidentifier" Nullable="false" />
<Property Name="FeedID" Type="uniqueidentifier" Nullable="false" />
<Property Name="Field" Type="int" Nullable="false" />
<Property Name="Search" Type="nvarchar" MaxLength="1000" Nullable="false" />
<Property Name="Replace" Type="nvarchar" MaxLength="1000" Nullable="false" />
<Property Name="Sequence" Type="int" Nullable="false" />
</EntityType>
<EntityType Name="FeedItem">
<Key>
<PropertyRef Name="ID" />
</Key>
<Property Name="ID" Type="uniqueidentifier" Nullable="false" />
<Property Name="FeedID" Type="uniqueidentifier" Nullable="false" />
<Property Name="Title" Type="ntext" Nullable="false" />
<Property Name="Link" Type="nvarchar" MaxLength="1000" Nullable="false" />
<Property Name="Description" Type="ntext" Nullable="false" />
<Property Name="BeenRead" Type="bit" Nullable="false" />
<Property Name="LastFound" Type="datetime" Nullable="false" />
<Property Name="New" Type="bit" Nullable="false" />
<Property Name="Sequence" Type="int" Nullable="false" />
<Property Name="Guid" Type="nvarchar" MaxLength="1000" Nullable="false" />
</EntityType>
<EntityType Name="Setting">
<Key>
<PropertyRef Name="Name" />
<PropertyRef Name="Version" />
</Key>
<Property Name="Name" Type="nvarchar" MaxLength="500" Nullable="false" />
<Property Name="Value" Type="nvarchar" MaxLength="3500" Nullable="false" />
<Property Name="Version" Type="nvarchar" MaxLength="50" Nullable="false" />
</EntityType>
<Association Name="FK_Feed_Category">
<End Role="Category" Type="Self.Category" Multiplicity="1" />
<End Role="Feed" Type="Self.Feed" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="Category">
<PropertyRef Name="ID" />
</Principal>
<Dependent Role="Feed">
<PropertyRef Name="CategoryID" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_FeedAction_Feed">
<End Role="Feed" Type="Self.Feed" Multiplicity="1">
<OnDelete Action="Cascade" />
</End>
<End Role="FeedAction" Type="Self.FeedAction" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="Feed">
<PropertyRef Name="ID" />
</Principal>
<Dependent Role="FeedAction">
<PropertyRef Name="FeedID" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_FeedItem_Feed">
<End Role="Feed" Type="Self.Feed" Multiplicity="1">
<OnDelete Action="Cascade" />
</End>
<End Role="FeedItem" Type="Self.FeedItem" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="Feed">
<PropertyRef Name="ID" />
</Principal>
<Dependent Role="FeedItem">
<PropertyRef Name="FeedID" />
</Dependent>
</ReferentialConstraint>
</Association>
<EntityContainer Name="FeedCenterModelStoreContainer">
<EntitySet Name="Category" EntityType="Self.Category" store:Type="Tables" />
<EntitySet Name="Feed" EntityType="Self.Feed" store:Type="Tables" />
<EntitySet Name="FeedAction" EntityType="Self.FeedAction" store:Type="Tables" />
<EntitySet Name="FeedItem" EntityType="Self.FeedItem" store:Type="Tables" />
<EntitySet Name="Setting" EntityType="Self.Setting" store:Type="Tables" />
<AssociationSet Name="FK_Feed_Category" Association="Self.FK_Feed_Category">
<End Role="Category" EntitySet="Category" />
<End Role="Feed" EntitySet="Feed" />
</AssociationSet>
<AssociationSet Name="FK_FeedAction_Feed" Association="Self.FK_FeedAction_Feed">
<End Role="Feed" EntitySet="Feed" />
<End Role="FeedAction" EntitySet="FeedAction" />
</AssociationSet>
<AssociationSet Name="FK_FeedItem_Feed" Association="Self.FK_FeedItem_Feed">
<End Role="Feed" EntitySet="Feed" />
<End Role="FeedItem" EntitySet="FeedItem" />
</AssociationSet>
</EntityContainer>
</Schema></edmx:StorageModels>
<!-- CSDL content -->
<edmx:ConceptualModels>
<Schema Namespace="FeedCenterModel" Alias="Self" xmlns="http://schemas.microsoft.com/ado/2009/11/edm">
<EntityContainer Name="FeedCenterEntities" annotation:LazyLoadingEnabled="true" xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation">
<EntitySet Name="Categories" EntityType="FeedCenterModel.Category" />
<EntitySet Name="Feeds" EntityType="FeedCenterModel.Feed" />
<EntitySet Name="FeedActions" EntityType="FeedCenterModel.FeedAction" />
<EntitySet Name="FeedItems" EntityType="FeedCenterModel.FeedItem" />
<EntitySet Name="Settings" EntityType="FeedCenterModel.Setting" />
<AssociationSet Name="FK_Feed_Category" Association="FeedCenterModel.FK_Feed_Category">
<End Role="Category" EntitySet="Categories" />
<End Role="Feed" EntitySet="Feeds" />
</AssociationSet>
<AssociationSet Name="FK_FeedAction_Feed" Association="FeedCenterModel.FK_FeedAction_Feed">
<End Role="Feed" EntitySet="Feeds" />
<End Role="FeedAction" EntitySet="FeedActions" />
</AssociationSet>
<AssociationSet Name="FK_FeedItem_Feed" Association="FeedCenterModel.FK_FeedItem_Feed">
<End Role="Feed" EntitySet="Feeds" />
<End Role="FeedItem" EntitySet="FeedItems" />
</AssociationSet>
</EntityContainer>
<EntityType Name="Category">
<Key>
<PropertyRef Name="ID" />
</Key>
<Property Type="Guid" Name="ID" Nullable="false" />
<Property Type="String" Name="Name" Nullable="false" MaxLength="1000" FixedLength="false" Unicode="true" />
<NavigationProperty Name="Feeds" Relationship="FeedCenterModel.FK_Feed_Category" FromRole="Category" ToRole="Feed" />
</EntityType>
<EntityType Name="Feed">
<Key>
<PropertyRef Name="ID" />
</Key>
<Property Type="Guid" Name="ID" Nullable="false" />
<Property Type="String" Name="Name" Nullable="false" MaxLength="1000" FixedLength="false" Unicode="true" DefaultValue="" />
<Property Type="String" Name="Title" Nullable="false" MaxLength="1000" FixedLength="false" Unicode="true" DefaultValue="" />
<Property Type="String" Name="Source" Nullable="false" MaxLength="1000" FixedLength="false" Unicode="true" DefaultValue="" />
<Property Type="String" Name="Link" Nullable="false" MaxLength="1000" FixedLength="false" Unicode="true" DefaultValue="" />
<Property Type="String" Name="Description" Nullable="false" MaxLength="Max" FixedLength="false" Unicode="true" DefaultValue="" />
<Property Type="DateTime" Name="LastChecked" Nullable="false" DefaultValue="1900-01-01 00:00:00.000Z" Precision="3" />
<Property Type="Int32" Name="CheckInterval" Nullable="false" DefaultValue="60" />
<Property Type="Boolean" Name="Enabled" Nullable="false" DefaultValue="True" />
<Property Type="Boolean" Name="Authenticate" Nullable="false" DefaultValue="False" />
<Property Type="String" Name="Username" Nullable="false" MaxLength="1000" FixedLength="false" Unicode="true" DefaultValue="" />
<Property Type="String" Name="Password" Nullable="false" MaxLength="1000" FixedLength="false" Unicode="true" DefaultValue="" />
<Property Type="String" Name="Domain" Nullable="false" MaxLength="1000" FixedLength="false" Unicode="true" DefaultValue="" />
<Property Type="FeedCenterModel.FeedReadResult" Name="LastReadResult" Nullable="false" />
<Property Type="DateTime" Name="LastUpdated" Nullable="false" DefaultValue="1900-01-01 00:00:00.000Z" Precision="3" />
<Property Type="FeedCenterModel.FeedItemComparison" Name="ItemComparison" Nullable="false" />
<Property Type="Guid" Name="CategoryID" Nullable="false" />
<NavigationProperty Name="Category" Relationship="FeedCenterModel.FK_Feed_Category" FromRole="Feed" ToRole="Category" />
<NavigationProperty Name="Actions" Relationship="FeedCenterModel.FK_FeedAction_Feed" FromRole="Feed" ToRole="FeedAction" />
<NavigationProperty Name="Items" Relationship="FeedCenterModel.FK_FeedItem_Feed" FromRole="Feed" ToRole="FeedItem" />
<Property Type="FeedCenterModel.MultipleOpenAction" Name="MultipleOpenAction" Nullable="false" />
</EntityType>
<EntityType Name="FeedAction">
<Key>
<PropertyRef Name="ID" />
</Key>
<Property Type="Guid" Name="ID" Nullable="false" />
<Property Type="Guid" Name="FeedID" Nullable="false" />
<Property Type="Int32" Name="Field" Nullable="false" />
<Property Type="String" Name="Search" Nullable="false" MaxLength="1000" FixedLength="false" Unicode="true" />
<Property Type="String" Name="Replace" Nullable="false" MaxLength="1000" FixedLength="false" Unicode="true" />
<Property Type="Int32" Name="Sequence" Nullable="false" />
<NavigationProperty Name="Feed" Relationship="FeedCenterModel.FK_FeedAction_Feed" FromRole="FeedAction" ToRole="Feed" />
</EntityType>
<EntityType Name="FeedItem">
<Key>
<PropertyRef Name="ID" />
</Key>
<Property Type="Guid" Name="ID" Nullable="false" />
<Property Type="Guid" Name="FeedID" Nullable="false" />
<Property Type="String" Name="Title" Nullable="false" MaxLength="Max" FixedLength="false" Unicode="true" DefaultValue="" />
<Property Type="String" Name="Link" Nullable="false" MaxLength="1000" FixedLength="false" Unicode="true" DefaultValue="" />
<Property Type="String" Name="Description" Nullable="false" MaxLength="Max" FixedLength="false" Unicode="true" DefaultValue="" />
<Property Type="Boolean" Name="BeenRead" Nullable="false" />
<Property Type="DateTime" Name="LastFound" Nullable="false" DefaultValue="1900-01-01 00:00:00.000Z" Precision="3" />
<Property Type="Boolean" Name="New" Nullable="false" />
<NavigationProperty Name="Feed" Relationship="FeedCenterModel.FK_FeedItem_Feed" FromRole="FeedItem" ToRole="Feed" />
<Property Type="String" Name="Guid" Nullable="false" MaxLength="1000" FixedLength="false" Unicode="true" />
<Property Type="Int32" Name="Sequence" Nullable="false" />
</EntityType>
<EntityType Name="Setting">
<Key>
<PropertyRef Name="Name" />
<PropertyRef Name="Version" />
</Key>
<Property Type="String" Name="Name" Nullable="false" MaxLength="500" FixedLength="false" Unicode="true" />
<Property Type="String" Name="Value" Nullable="false" MaxLength="3500" FixedLength="false" Unicode="true" />
<Property Type="String" Name="Version" Nullable="false" MaxLength="50" FixedLength="false" Unicode="true" />
</EntityType>
<Association Name="FK_Feed_Category">
<End Type="FeedCenterModel.Category" Role="Category" Multiplicity="1" />
<End Type="FeedCenterModel.Feed" Role="Feed" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="Category">
<PropertyRef Name="ID" />
</Principal>
<Dependent Role="Feed">
<PropertyRef Name="CategoryID" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_FeedAction_Feed">
<End Type="FeedCenterModel.Feed" Role="Feed" Multiplicity="1" />
<End Type="FeedCenterModel.FeedAction" Role="FeedAction" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="Feed">
<PropertyRef Name="ID" />
</Principal>
<Dependent Role="FeedAction">
<PropertyRef Name="FeedID" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_FeedItem_Feed">
<End Type="FeedCenterModel.Feed" Role="Feed" Multiplicity="1" />
<End Type="FeedCenterModel.FeedItem" Role="FeedItem" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="Feed">
<PropertyRef Name="ID" />
</Principal>
<Dependent Role="FeedItem">
<PropertyRef Name="FeedID" />
</Dependent>
</ReferentialConstraint>
</Association>
<EnumType Name="FeedReadResult" a:ExternalTypeName="FeedCenter.FeedReadResult" xmlns:a="http://schemas.microsoft.com/ado/2006/04/codegeneration" />
<EnumType Name="FeedItemComparison" UnderlyingType="Byte" a:ExternalTypeName="FeedCenter.FeedItemComparison" xmlns:a="http://schemas.microsoft.com/ado/2006/04/codegeneration" />
<EnumType Name="MultipleOpenAction" a:ExternalTypeName="FeedCenter.MultipleOpenAction" xmlns:a="http://schemas.microsoft.com/ado/2006/04/codegeneration" />
</Schema>
</edmx:ConceptualModels>
<!-- C-S mapping content -->
<edmx:Mappings>
<Mapping Space="C-S" xmlns="http://schemas.microsoft.com/ado/2009/11/mapping/cs">
<EntityContainerMapping StorageEntityContainer="FeedCenterModelStoreContainer" CdmEntityContainer="FeedCenterEntities">
<EntitySetMapping Name="Categories">
<EntityTypeMapping TypeName="FeedCenterModel.Category">
<MappingFragment StoreEntitySet="Category">
<ScalarProperty Name="Name" ColumnName="Name" />
<ScalarProperty Name="ID" ColumnName="ID" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
<EntitySetMapping Name="Feeds">
<EntityTypeMapping TypeName="FeedCenterModel.Feed">
<MappingFragment StoreEntitySet="Feed">
<ScalarProperty Name="MultipleOpenAction" ColumnName="MultipleOpenAction" />
<ScalarProperty Name="CategoryID" ColumnName="CategoryID" />
<ScalarProperty Name="ItemComparison" ColumnName="ItemComparison" />
<ScalarProperty Name="LastUpdated" ColumnName="LastUpdated" />
<ScalarProperty Name="LastReadResult" ColumnName="LastReadResult" />
<ScalarProperty Name="Domain" ColumnName="Domain" />
<ScalarProperty Name="Password" ColumnName="Password" />
<ScalarProperty Name="Username" ColumnName="Username" />
<ScalarProperty Name="Authenticate" ColumnName="Authenticate" />
<ScalarProperty Name="Enabled" ColumnName="Enabled" />
<ScalarProperty Name="CheckInterval" ColumnName="CheckInterval" />
<ScalarProperty Name="LastChecked" ColumnName="LastChecked" />
<ScalarProperty Name="Description" ColumnName="Description" />
<ScalarProperty Name="Link" ColumnName="Link" />
<ScalarProperty Name="Source" ColumnName="Source" />
<ScalarProperty Name="Title" ColumnName="Title" />
<ScalarProperty Name="Name" ColumnName="Name" />
<ScalarProperty Name="ID" ColumnName="ID" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
<EntitySetMapping Name="FeedActions">
<EntityTypeMapping TypeName="FeedCenterModel.FeedAction">
<MappingFragment StoreEntitySet="FeedAction">
<ScalarProperty Name="Sequence" ColumnName="Sequence" />
<ScalarProperty Name="Replace" ColumnName="Replace" />
<ScalarProperty Name="Search" ColumnName="Search" />
<ScalarProperty Name="Field" ColumnName="Field" />
<ScalarProperty Name="FeedID" ColumnName="FeedID" />
<ScalarProperty Name="ID" ColumnName="ID" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
<EntitySetMapping Name="FeedItems">
<EntityTypeMapping TypeName="FeedCenterModel.FeedItem">
<MappingFragment StoreEntitySet="FeedItem">
<ScalarProperty Name="Sequence" ColumnName="Sequence" />
<ScalarProperty Name="Guid" ColumnName="Guid" />
<ScalarProperty Name="New" ColumnName="New" />
<ScalarProperty Name="LastFound" ColumnName="LastFound" />
<ScalarProperty Name="BeenRead" ColumnName="BeenRead" />
<ScalarProperty Name="Description" ColumnName="Description" />
<ScalarProperty Name="Link" ColumnName="Link" />
<ScalarProperty Name="Title" ColumnName="Title" />
<ScalarProperty Name="FeedID" ColumnName="FeedID" />
<ScalarProperty Name="ID" ColumnName="ID" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
<EntitySetMapping Name="Settings">
<EntityTypeMapping TypeName="FeedCenterModel.Setting">
<MappingFragment StoreEntitySet="Setting">
<ScalarProperty Name="Version" ColumnName="Version" />
<ScalarProperty Name="Value" ColumnName="Value" />
<ScalarProperty Name="Name" ColumnName="Name" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
</EntityContainerMapping>
</Mapping>
</edmx:Mappings>
</edmx:Runtime>
<!-- EF Designer content (DO NOT EDIT MANUALLY BELOW HERE) -->
<Designer xmlns="http://schemas.microsoft.com/ado/2009/11/edmx">
<Connection>
<DesignerInfoPropertySet>
<DesignerProperty Name="MetadataArtifactProcessing" Value="EmbedInOutputAssembly" />
</DesignerInfoPropertySet>
</Connection>
<Options>
<DesignerInfoPropertySet>
<DesignerProperty Name="ValidateOnBuild" Value="true" />
<DesignerProperty Name="EnablePluralization" Value="True" />
<DesignerProperty Name="IncludeForeignKeysInModel" Value="True" />
<DesignerProperty Name="CodeGenerationStrategy" Value="None" />
<DesignerProperty Name="UseLegacyProvider" Value="False" />
</DesignerInfoPropertySet>
</Options>
<!-- Diagram content (shape and connector positions) -->
<Diagrams>
<Diagram Name="Model">
<EntityTypeShape EntityType="FeedCenterModel.Category" Width="1.5" PointX="0.75" PointY="3.375" Height="1.5956835937499996" />
<EntityTypeShape EntityType="FeedCenterModel.Feed" Width="1.5" PointX="3" PointY="1.625" Height="5.057109375" />
<EntityTypeShape EntityType="FeedCenterModel.FeedAction" Width="1.5" PointX="5.25" PointY="1.125" Height="2.3648893229166674" />
<EntityTypeShape EntityType="FeedCenterModel.FeedItem" Width="1.5" PointX="5.25" PointY="4.25" Height="2.9417936197916656" />
<EntityTypeShape EntityType="FeedCenterModel.Setting" Width="1.5" PointX="7.75" PointY="0.75" Height="1.5956835937499996" />
<AssociationConnector Association="FeedCenterModel.FK_Feed_Category">
<ConnectorPoint PointX="2.25" PointY="4.172841796875" />
<ConnectorPoint PointX="3" PointY="4.172841796875" />
</AssociationConnector>
<AssociationConnector Association="FeedCenterModel.FK_FeedAction_Feed">
<ConnectorPoint PointX="4.5" PointY="2.5574446614583337" />
<ConnectorPoint PointX="5.25" PointY="2.5574446614583337" />
</AssociationConnector>
<AssociationConnector Association="FeedCenterModel.FK_FeedItem_Feed">
<ConnectorPoint PointX="4.5" PointY="5.4660546875" />
<ConnectorPoint PointX="5.25" PointY="5.4660546875" />
</AssociationConnector>
</Diagram>
</Diagrams>
</Designer>
</edmx:Edmx>

726
Application/Model.tt Normal file
View File

@@ -0,0 +1,726 @@
<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ include file="EF6.Utility.CS.ttinclude"#><#@
output extension=".cs"#><#
const string inputFile = @"Model.edmx";
var textTransform = DynamicTextTransformation.Create(this);
var code = new CodeGenerationTools(this);
var ef = new MetadataTools(this);
var typeMapper = new TypeMapper(code, ef, textTransform.Errors);
var fileManager = EntityFrameworkTemplateFileManager.Create(this);
var itemCollection = new EdmMetadataLoader(textTransform.Host, textTransform.Errors).CreateEdmItemCollection(inputFile);
var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef);
if (!typeMapper.VerifyCaseInsensitiveTypeUniqueness(typeMapper.GetAllGlobalItems(itemCollection), inputFile))
{
return string.Empty;
}
WriteHeader(codeStringGenerator, fileManager);
foreach (var entity in typeMapper.GetItemsToGenerate<EntityType>(itemCollection))
{
fileManager.StartNewFile(entity.Name + ".cs");
BeginNamespace(code);
#>
<#=codeStringGenerator.UsingDirectives(inHeader: false)#>
<#=codeStringGenerator.EntityClassOpening(entity)#>
{
<#
var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(entity);
var collectionNavigationProperties = typeMapper.GetCollectionNavigationProperties(entity);
var complexProperties = typeMapper.GetComplexProperties(entity);
if (propertiesWithDefaultValues.Any() || collectionNavigationProperties.Any() || complexProperties.Any())
{
#>
public <#=code.Escape(entity)#>()
{
<#
foreach (var edmProperty in propertiesWithDefaultValues)
{
#>
this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>;
<#
}
foreach (var navigationProperty in collectionNavigationProperties)
{
#>
this.<#=code.Escape(navigationProperty)#> = new HashSet<<#=typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType())#>>();
<#
}
foreach (var complexProperty in complexProperties)
{
#>
this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>();
<#
}
#>
}
<#
}
var simpleProperties = typeMapper.GetSimpleProperties(entity);
if (simpleProperties.Any())
{
foreach (var edmProperty in simpleProperties)
{
#>
<#=codeStringGenerator.Property(edmProperty)#>
<#
}
}
if (complexProperties.Any())
{
#>
<#
foreach(var complexProperty in complexProperties)
{
#>
<#=codeStringGenerator.Property(complexProperty)#>
<#
}
}
var navigationProperties = typeMapper.GetNavigationProperties(entity);
if (navigationProperties.Any())
{
#>
<#
foreach (var navigationProperty in navigationProperties)
{
#>
<#=codeStringGenerator.NavigationProperty(navigationProperty)#>
<#
}
}
#>
}
<#
EndNamespace(code);
}
foreach (var complex in typeMapper.GetItemsToGenerate<ComplexType>(itemCollection))
{
fileManager.StartNewFile(complex.Name + ".cs");
BeginNamespace(code);
#>
<#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#>
<#=Accessibility.ForType(complex)#> partial class <#=code.Escape(complex)#>
{
<#
var complexProperties = typeMapper.GetComplexProperties(complex);
var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(complex);
if (propertiesWithDefaultValues.Any() || complexProperties.Any())
{
#>
public <#=code.Escape(complex)#>()
{
<#
foreach (var edmProperty in propertiesWithDefaultValues)
{
#>
this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>;
<#
}
foreach (var complexProperty in complexProperties)
{
#>
this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>();
<#
}
#>
}
<#
}
var simpleProperties = typeMapper.GetSimpleProperties(complex);
if (simpleProperties.Any())
{
foreach(var edmProperty in simpleProperties)
{
#>
<#=codeStringGenerator.Property(edmProperty)#>
<#
}
}
if (complexProperties.Any())
{
#>
<#
foreach(var edmProperty in complexProperties)
{
#>
<#=codeStringGenerator.Property(edmProperty)#>
<#
}
}
#>
}
<#
EndNamespace(code);
}
foreach (var enumType in typeMapper.GetEnumItemsToGenerate(itemCollection))
{
fileManager.StartNewFile(enumType.Name + ".cs");
BeginNamespace(code);
#>
<#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#>
<#
if (typeMapper.EnumIsFlags(enumType))
{
#>
[Flags]
<#
}
#>
<#=codeStringGenerator.EnumOpening(enumType)#>
{
<#
var foundOne = false;
foreach (MetadataItem member in typeMapper.GetEnumMembers(enumType))
{
foundOne = true;
#>
<#=code.Escape(typeMapper.GetEnumMemberName(member))#> = <#=typeMapper.GetEnumMemberValue(member)#>,
<#
}
if (foundOne)
{
this.GenerationEnvironment.Remove(this.GenerationEnvironment.Length - 3, 1);
}
#>
}
<#
EndNamespace(code);
}
fileManager.Process();
#>
<#+
public void WriteHeader(CodeStringGenerator codeStringGenerator, EntityFrameworkTemplateFileManager fileManager)
{
fileManager.StartHeader();
#>
//------------------------------------------------------------------------------
// <auto-generated>
// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine1")#>
//
// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine2")#>
// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine3")#>
// </auto-generated>
//------------------------------------------------------------------------------
<#=codeStringGenerator.UsingDirectives(inHeader: true)#>
<#+
fileManager.EndBlock();
}
public void BeginNamespace(CodeGenerationTools code)
{
var codeNamespace = code.VsNamespaceSuggestion();
if (!String.IsNullOrEmpty(codeNamespace))
{
#>
namespace <#=code.EscapeNamespace(codeNamespace)#>
{
<#+
PushIndent(" ");
}
}
public void EndNamespace(CodeGenerationTools code)
{
if (!String.IsNullOrEmpty(code.VsNamespaceSuggestion()))
{
PopIndent();
#>
}
<#+
}
}
public const string TemplateId = "CSharp_DbContext_Types_EF6";
public class CodeStringGenerator
{
private readonly CodeGenerationTools _code;
private readonly TypeMapper _typeMapper;
private readonly MetadataTools _ef;
public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef)
{
ArgumentNotNull(code, "code");
ArgumentNotNull(typeMapper, "typeMapper");
ArgumentNotNull(ef, "ef");
_code = code;
_typeMapper = typeMapper;
_ef = ef;
}
public string Property(EdmProperty edmProperty)
{
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1} {2} {{ {3}get; {4}set; }}",
Accessibility.ForProperty(edmProperty),
_typeMapper.GetTypeName(edmProperty.TypeUsage),
_code.Escape(edmProperty),
_code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
_code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
}
public string NavigationProperty(NavigationProperty navProp)
{
var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType());
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1} {2} {{ {3}get; {4}set; }}",
AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)),
navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
_code.Escape(navProp),
_code.SpaceAfter(Accessibility.ForGetter(navProp)),
_code.SpaceAfter(Accessibility.ForSetter(navProp)));
}
public string AccessibilityAndVirtual(string accessibility)
{
return accessibility + (accessibility != "private" ? " virtual" : "");
}
public string EntityClassOpening(EntityType entity)
{
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1}partial class {2}{3}",
Accessibility.ForType(entity),
_code.SpaceAfter(_code.AbstractOption(entity)),
_code.Escape(entity),
_code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
}
public string EnumOpening(SimpleType enumType)
{
return string.Format(
CultureInfo.InvariantCulture,
"{0} enum {1} : {2}",
Accessibility.ForType(enumType),
_code.Escape(enumType),
_code.Escape(_typeMapper.UnderlyingClrType(enumType)));
}
public void WriteFunctionParameters(EdmFunction edmFunction, Action<string, string, string, string> writeParameter)
{
var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable))
{
var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null";
var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")";
var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + TypeMapper.FixNamespaces(parameter.RawClrTypeName) + "))";
writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit);
}
}
public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace)
{
var parameters = _typeMapper.GetParameters(edmFunction);
return string.Format(
CultureInfo.InvariantCulture,
"{0} IQueryable<{1}> {2}({3})",
AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
_typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
_code.Escape(edmFunction),
string.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray()));
}
public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace)
{
var parameters = _typeMapper.GetParameters(edmFunction);
return string.Format(
CultureInfo.InvariantCulture,
"return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});",
_typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
edmFunction.NamespaceName,
edmFunction.Name,
string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()),
_code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())));
}
public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
{
var parameters = _typeMapper.GetParameters(edmFunction);
var returnType = _typeMapper.GetReturnType(edmFunction);
var paramList = String.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray());
if (includeMergeOption)
{
paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption";
}
return string.Format(
CultureInfo.InvariantCulture,
"{0} {1} {2}({3})",
AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
_code.Escape(edmFunction),
paramList);
}
public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
{
var parameters = _typeMapper.GetParameters(edmFunction);
var returnType = _typeMapper.GetReturnType(edmFunction);
var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()));
if (includeMergeOption)
{
callParams = ", mergeOption" + callParams;
}
return string.Format(
CultureInfo.InvariantCulture,
"return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});",
returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
edmFunction.Name,
callParams);
}
public string DbSet(EntitySet entitySet)
{
return string.Format(
CultureInfo.InvariantCulture,
"{0} virtual DbSet<{1}> {2} {{ get; set; }}",
Accessibility.ForReadOnlyProperty(entitySet),
_typeMapper.GetTypeName(entitySet.ElementType),
_code.Escape(entitySet));
}
public string UsingDirectives(bool inHeader, bool includeCollections = true)
{
return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
? string.Format(
CultureInfo.InvariantCulture,
"{0}using System;{1}" +
"{2}",
inHeader ? Environment.NewLine : "",
includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
inHeader ? "" : Environment.NewLine)
: "";
}
}
public class TypeMapper
{
private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName";
private readonly System.Collections.IList _errors;
private readonly CodeGenerationTools _code;
private readonly MetadataTools _ef;
public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors)
{
ArgumentNotNull(code, "code");
ArgumentNotNull(ef, "ef");
ArgumentNotNull(errors, "errors");
_code = code;
_ef = ef;
_errors = errors;
}
public static string FixNamespaces(string typeName)
{
return typeName.Replace("System.Data.Spatial.", "System.Data.Entity.Spatial.");
}
public string GetTypeName(TypeUsage typeUsage)
{
return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null);
}
public string GetTypeName(EdmType edmType)
{
return GetTypeName(edmType, isNullable: null, modelNamespace: null);
}
public string GetTypeName(TypeUsage typeUsage, string modelNamespace)
{
return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace);
}
public string GetTypeName(EdmType edmType, string modelNamespace)
{
return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace);
}
public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace)
{
if (edmType == null)
{
return null;
}
var collectionType = edmType as CollectionType;
if (collectionType != null)
{
return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace));
}
var typeName = _code.Escape(edmType.MetadataProperties
.Where(p => p.Name == ExternalTypeNameAttributeName)
.Select(p => (string)p.Value)
.FirstOrDefault())
?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ?
_code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) :
_code.Escape(edmType));
if (edmType is StructuralType)
{
return typeName;
}
if (edmType is SimpleType)
{
var clrType = UnderlyingClrType(edmType);
if (!IsEnumType(edmType))
{
typeName = _code.Escape(clrType);
}
typeName = FixNamespaces(typeName);
return clrType.IsValueType && isNullable == true ?
String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) :
typeName;
}
throw new ArgumentException("edmType");
}
public Type UnderlyingClrType(EdmType edmType)
{
ArgumentNotNull(edmType, "edmType");
var primitiveType = edmType as PrimitiveType;
if (primitiveType != null)
{
return primitiveType.ClrEquivalentType;
}
if (IsEnumType(edmType))
{
return GetEnumUnderlyingType(edmType).ClrEquivalentType;
}
return typeof(object);
}
public object GetEnumMemberValue(MetadataItem enumMember)
{
ArgumentNotNull(enumMember, "enumMember");
var valueProperty = enumMember.GetType().GetProperty("Value");
return valueProperty == null ? null : valueProperty.GetValue(enumMember, null);
}
public string GetEnumMemberName(MetadataItem enumMember)
{
ArgumentNotNull(enumMember, "enumMember");
var nameProperty = enumMember.GetType().GetProperty("Name");
return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null);
}
public System.Collections.IEnumerable GetEnumMembers(EdmType enumType)
{
ArgumentNotNull(enumType, "enumType");
var membersProperty = enumType.GetType().GetProperty("Members");
return membersProperty != null
? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null)
: Enumerable.Empty<MetadataItem>();
}
public bool EnumIsFlags(EdmType enumType)
{
ArgumentNotNull(enumType, "enumType");
var isFlagsProperty = enumType.GetType().GetProperty("IsFlags");
return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null);
}
public bool IsEnumType(GlobalItem edmType)
{
ArgumentNotNull(edmType, "edmType");
return edmType.GetType().Name == "EnumType";
}
public PrimitiveType GetEnumUnderlyingType(EdmType enumType)
{
ArgumentNotNull(enumType, "enumType");
return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null);
}
public string CreateLiteral(object value)
{
if (value == null || value.GetType() != typeof(TimeSpan))
{
return _code.CreateLiteral(value);
}
return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks);
}
public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable<string> types, string sourceFile)
{
ArgumentNotNull(types, "types");
ArgumentNotNull(sourceFile, "sourceFile");
var hash = new HashSet<string>(StringComparer.InvariantCultureIgnoreCase);
if (types.Any(item => !hash.Add(item)))
{
_errors.Add(
new CompilerError(sourceFile, -1, -1, "6023",
String.Format(CultureInfo.CurrentCulture, CodeGenerationTools.GetResourceString("Template_CaseInsensitiveTypeConflict"))));
return false;
}
return true;
}
public IEnumerable<SimpleType> GetEnumItemsToGenerate(IEnumerable<GlobalItem> itemCollection)
{
return GetItemsToGenerate<SimpleType>(itemCollection)
.Where(e => IsEnumType(e));
}
public IEnumerable<T> GetItemsToGenerate<T>(IEnumerable<GlobalItem> itemCollection) where T: EdmType
{
return itemCollection
.OfType<T>()
.Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName))
.OrderBy(i => i.Name);
}
public IEnumerable<string> GetAllGlobalItems(IEnumerable<GlobalItem> itemCollection)
{
return itemCollection
.Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i))
.Select(g => GetGlobalItemName(g));
}
public string GetGlobalItemName(GlobalItem item)
{
if (item is EdmType)
{
return ((EdmType)item).Name;
}
else
{
return ((EntityContainer)item).Name;
}
}
public IEnumerable<EdmProperty> GetSimpleProperties(EntityType type)
{
return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
}
public IEnumerable<EdmProperty> GetSimpleProperties(ComplexType type)
{
return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
}
public IEnumerable<EdmProperty> GetComplexProperties(EntityType type)
{
return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
}
public IEnumerable<EdmProperty> GetComplexProperties(ComplexType type)
{
return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
}
public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(EntityType type)
{
return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
}
public IEnumerable<EdmProperty> GetPropertiesWithDefaultValues(ComplexType type)
{
return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
}
public IEnumerable<NavigationProperty> GetNavigationProperties(EntityType type)
{
return type.NavigationProperties.Where(np => np.DeclaringType == type);
}
public IEnumerable<NavigationProperty> GetCollectionNavigationProperties(EntityType type)
{
return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
}
public FunctionParameter GetReturnParameter(EdmFunction edmFunction)
{
ArgumentNotNull(edmFunction, "edmFunction");
var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters");
return returnParamsProperty == null
? edmFunction.ReturnParameter
: ((IEnumerable<FunctionParameter>)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault();
}
public bool IsComposable(EdmFunction edmFunction)
{
ArgumentNotNull(edmFunction, "edmFunction");
var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute");
return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null);
}
public IEnumerable<FunctionImportParameter> GetParameters(EdmFunction edmFunction)
{
return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
}
public TypeUsage GetReturnType(EdmFunction edmFunction)
{
var returnParam = GetReturnParameter(edmFunction);
return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage);
}
public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption)
{
var returnType = GetReturnType(edmFunction);
return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType;
}
}
public static void ArgumentNotNull<T>(T arg, string name) where T : class
{
if (arg == null)
{
throw new ArgumentNullException(name);
}
}
#>

View File

@@ -0,0 +1,81 @@
using FeedCenter.Properties;
using System.Windows.Forms;
namespace FeedCenter
{
internal static class NotificationIcon
{
private static MainWindow _mainForm;
private static NotifyIcon _notificationIcon;
public static void Initialize(MainWindow mainForm)
{
// Store the main window
_mainForm = mainForm;
// Create the notification icon
_notificationIcon = new NotifyIcon { Icon = Resources.Application };
_notificationIcon.DoubleClick += HandleNotificationIconDoubleClick;
// Setup the menu
var contextMenuStrip = new ContextMenuStrip();
var toolStripMenuItem = new ToolStripMenuItem(Resources.NotificationIconContextMenuLocked, null, HandleLockWindowClicked)
{
Checked = Settings.Default.WindowLocked
};
contextMenuStrip.Items.Add(toolStripMenuItem);
contextMenuStrip.Items.Add(new ToolStripSeparator());
contextMenuStrip.Items.Add(Resources.NotificationIconContextMenuExit, null, HandleContextMenuExitClick);
// Set the menu into the icon
_notificationIcon.ContextMenuStrip = contextMenuStrip;
// Show the icon
_notificationIcon.Visible = true;
}
private static void HandleNotificationIconDoubleClick(object sender, System.EventArgs e)
{
// Bring the main form to the front
_mainForm.Activate();
}
private static void HandleContextMenuExitClick(object sender, System.EventArgs e)
{
// Close the main form
_mainForm.Close();
}
private static void HandleLockWindowClicked(object sender, System.EventArgs e)
{
// Toggle the lock setting
Settings.Default.WindowLocked = !Settings.Default.WindowLocked;
// Reset the menu choice
((ToolStripMenuItem) sender).Checked = Settings.Default.WindowLocked;
}
public static void Dispose()
{
// Get rid of the icon
_notificationIcon.Visible = false;
_notificationIcon.Dispose();
_notificationIcon = null;
_mainForm = null;
}
public static void ShowBalloonTip(string text, ToolTipIcon icon)
{
ShowBalloonTip(text, icon, Settings.Default.BalloonTipTimeout);
}
public static void ShowBalloonTip(string text, ToolTipIcon icon, int timeout)
{
_notificationIcon.ShowBalloonTip(timeout, Resources.ApplicationDisplayName, text, icon);
}
}
}

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; }
}
}
}

View File

@@ -0,0 +1,128 @@
<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"
xmlns:feedCenter="clr-namespace:FeedCenter"
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 feedCenter:MultipleOpenAction.IndividualPages}" />
<ComboBoxItem Content="{x:Static my:Resources.openAllSingleToolbarButton}"
Tag="{x:Static feedCenter: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,101 @@
using Common.Wpf;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
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)
{
var checkedListBoxItem = (CheckedListItem<Feed>) e.Item;
var feed = checkedListBoxItem.Item;
e.Accepted = feed.Link.Contains(feedLinkFilterText.Text);
}
private void HandleFilterTextChanged(object sender, TextChangedEventArgs e)
{
_collectionViewSource.View.Refresh();
}
private void HandleOkButtonClick(object sender, RoutedEventArgs e)
{
foreach (var item in _checkedListBoxItems.Where(i => i.IsChecked))
{
if (openComboBox.IsEnabled)
item.Item.MultipleOpenAction = (MultipleOpenAction) ((ComboBoxItem) openComboBox.SelectedItem).Tag;
}
DialogResult = true;
Close();
}
private void HandleSelectAll(object sender, RoutedEventArgs e)
{
foreach (var viewItem in _collectionViewSource.View)
{
var checkedListItem = (CheckedListItem<Feed>) viewItem;
checkedListItem.IsChecked = true;
}
}
private void HandleSelectNone(object sender, RoutedEventArgs e)
{
foreach (var viewItem in _collectionViewSource.View)
{
var checkedListItem = (CheckedListItem<Feed>) viewItem;
checkedListItem.IsChecked = false;
}
}
private void HandleSelectInvert(object sender, RoutedEventArgs e)
{
foreach (var viewItem in _collectionViewSource.View)
{
var checkedListItem = (CheckedListItem<Feed>) viewItem;
checkedListItem.IsChecked = !checkedListItem.IsChecked;
}
}
private void HandleGridMouseRightButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
openLabel.IsEnabled = !openLabel.IsEnabled;
openComboBox.IsEnabled = !openComboBox.IsEnabled;
}
}
}

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,64 @@
using Common.Wpf.Extensions;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
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
var bindingExpressions = this.GetBindingExpressions(new[] { UpdateSourceTrigger.Explicit });
// Loop over each binding expression and clear any existing error
bindingExpressions.ForEach(b => Validation.ClearInvalid(b.BindingExpression));
// Force all explicit bindings to update the source
bindingExpressions.ForEach(bindingExpression => bindingExpression.BindingExpression.UpdateSource());
// See if there are any errors
var hasError = bindingExpressions.Exists(bindingExpression => 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
var firstErrorElement = bindingExpressions.First(b => b.BindingExpression.HasError).FrameworkElement;
// 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,49 @@
using FeedCenter.Properties;
using System.Linq;
using System.Windows.Controls;
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;
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
{
get { return Properties.Resources.optionCategoryDisplay; }
}
}
}

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:feedCenter="clr-namespace:FeedCenter"
Title="FeedWindow"
Height="300"
Width="450"
WindowStartupLocation="CenterOwner"
Icon="/FeedCenter;component/Resources/Application.ico"
FocusManager.FocusedElement="{Binding ElementName=urlTextBox}">
<Window.Resources>
<feedCenter: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 feedCenter:MultipleOpenAction.SinglePage}" />
<ComboBoxItem Content="{x:Static Properties:Resources.openAllMultipleToolbarButton}"
Tag="{x:Static feedCenter: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,83 @@
using Common.Wpf.Extensions;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
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 list of all framework elements and explicit binding expressions
var bindingExpressions = this.GetBindingExpressions(new[] { UpdateSourceTrigger.Explicit });
// Loop over each binding expression and clear any existing error
this.ClearAllValidationErrors(bindingExpressions);
// Force all explicit bindings to update the source
this.UpdateAllSources(bindingExpressions);
// See if there are any errors
var hasError = bindingExpressions.Any(b => b.BindingExpression.HasError);
// If there was an error then set focus to the bad controls
if (hasError)
{
// Get the first framework element with an error
var firstErrorElement = bindingExpressions.First(b => b.BindingExpression.HasError).FrameworkElement;
// Loop over each tab item
foreach (TabItem tabItem in optionsTabControl.Items)
{
// Cast the content as visual
var content = (Visual) tabItem.Content;
// See if the control with the error is a descendant
if (firstErrorElement.IsDescendantOf(content))
{
// Select the tab
tabItem.IsSelected = true;
break;
}
}
// Set focus
firstErrorElement.Focus();
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,434 @@
using Microsoft.Win32;
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;
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);
var 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()
{
var feed = Feed.Create();
var feedWindow = new FeedWindow();
var result = feedWindow.Display(Database, feed, Window.GetWindow(this));
if (result.HasValue && result.Value)
{
Database.Feeds.Add(feed);
feedListBox.SelectedItem = feed;
SetFeedButtonStates();
}
}
private void EditSelectedFeed()
{
if (feedListBox.SelectedItem == null)
return;
var feed = (Feed) feedListBox.SelectedItem;
var feedWindow = new FeedWindow();
feedWindow.Display(Database, feed, Window.GetWindow(this));
}
private void DeleteSelectedFeed()
{
var feed = (Feed) feedListBox.SelectedItem;
Database.Feeds.Remove(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
var saveFileDialog = new SaveFileDialog
{
Filter = Properties.Resources.ImportExportFilter,
FilterIndex = 0,
OverwritePrompt = true
};
var result = saveFileDialog.ShowDialog();
if (!result.GetValueOrDefault(false))
return;
// Setup the writer settings
var writerSettings = new XmlWriterSettings
{
Indent = true,
CheckCharacters = true,
ConformanceLevel = ConformanceLevel.Document
};
// Create an XML writer for the file chosen
var 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 (var 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
var openFileDialog = new OpenFileDialog
{
Filter = Properties.Resources.ImportExportFilter,
FilterIndex = 0
};
var result = openFileDialog.ShowDialog();
if (!result.GetValueOrDefault(false))
return;
// Setup the reader settings
var xmlReaderSettings = new XmlReaderSettings { IgnoreWhitespace = true };
// Create an XML reader for the file chosen
var 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
var feed = Feed.Create();
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.Add(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()
{
var category = Category.Create();
var categoryWindow = new CategoryWindow();
var result = categoryWindow.Display(category, Window.GetWindow(this));
if (result.HasValue && result.Value)
{
Database.Categories.Add(category);
categoryListBox.SelectedItem = category;
SetCategoryButtonStates();
}
}
private void EditSelectedCategory()
{
if (categoryListBox.SelectedItem == null)
return;
var category = (Category) categoryListBox.SelectedItem;
var categoryWindow = new CategoryWindow();
categoryWindow.Display(category, Window.GetWindow(this));
}
private void DeleteSelectedCategory()
{
var category = (Category) categoryListBox.SelectedItem;
Database.Categories.Remove(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)
{
var selectedCategory = (Category) categoryListBox.SelectedItem;
var feed = (Feed) e.Item;
e.Accepted = (feed.Category == selectedCategory);
}
private void HandleTextBlockDrop(object sender, DragEventArgs e)
{
var feedList = (List<Feed>) e.Data.GetData(typeof(List<Feed>));
var category = (Category) ((DataGridRow) sender).Item;
foreach (var feed in feedList)
feed.Category = category;
_collectionViewSource.View.Refresh();
//textBlock.TextDecorations = null;
}
private void HandleListBoxItemPreviewMouseMove(object sender, MouseEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
var selectedItems = feedListBox.SelectedItems.Cast<Feed>().ToList();
DragDrop.DoDragDrop(feedListBox, selectedItems, DragDropEffects.Move);
}
}
private void HandleTextBlockDragEnter(object sender, DragEventArgs e)
{
var dataGridRow = (DataGridRow) sender;
dataGridRow.FontWeight = FontWeights.Bold;
}
private void HandleTextBlockDragLeave(object sender, DragEventArgs e)
{
var dataGridRow = (DataGridRow) sender;
dataGridRow.FontWeight = FontWeights.Normal;
}
private void HandleListBoxItemMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
EditSelectedFeed();
}
private void HandleMultipleEditClick(object sender, RoutedEventArgs e)
{
var bulkFeedWindow = new BulkFeedWindow();
bulkFeedWindow.Display(Window.GetWindow(this), 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; }
}
}
}

View File

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

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,67 @@
using Common.Internet;
using Common.Wpf.Extensions;
using System.Windows.Controls;
using System.Windows.Data;
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;
var browser = (string) ((ComboBoxItem) browserComboBox.SelectedItem).Tag;
settings.Browser = browser;
var expressions = this.GetBindingExpressions(new[] { UpdateSourceTrigger.Explicit });
this.UpdateAllSources(expressions);
}
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)
{
var 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);
}
}
}

View File

@@ -0,0 +1,53 @@
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Feed Center")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Chris Kaczor")]
[assembly: AssemblyProduct("Feed Center")]
[assembly: AssemblyCopyright("Copyright © Chris Kaczor 2010")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
//In order to begin building localizable applications, set
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
//inside a <PropertyGroup>. For example, if you are using US english
//in your source files, set the <UICulture> to en-US. Then uncomment
//the NeutralResourceLanguage attribute below. Update the "en-US" in
//the line below to match the UICulture setting in the project file.
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.0.0.0")]
[assembly: AssemblyFileVersion("0.0.0.0")]

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file is automatically generated by Visual Studio .Net. It is
used to store generic object data source configuration information.
Renaming the file extension or editing the content of this file may
cause the file to be unrecognizable by the program.
-->
<GenericObjectDataSource DisplayName="FeedCenterEntities" Identifier="FeedCenter.FeedCenterEntities" ProviderType="Microsoft.VisualStudio.DataDesign.DataSourceProviders.EntityDataModel.EdmDataSourceProvider" Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<TypeInfo>FeedCenter.FeedCenterEntities, Model.Designer.cs, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null</TypeInfo>
</GenericObjectDataSource>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,530 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="Application" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\Application.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="CreateDatabase" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Scripts\CreateDatabase.sqlce;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="DatabaseUpdate_1" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Scripts\DatabaseUpdate_1.sqlce;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="DatabaseUpdate_2" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Scripts\DatabaseUpdate_2.sqlce;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="DatabaseUpdate_3" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Scripts\DatabaseUpdate_3.sqlce;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="DatabaseUpdate_4" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Scripts\DatabaseUpdate_4.sqlce;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="FeedActionDescription" xml:space="preserve">
<value>In field '{0}' - search for '{1}' - replace with '{2}'</value>
</data>
<data name="NotificationIconContextMenuExit" xml:space="preserve">
<value>Exit</value>
</data>
<data name="NotificationIconContextMenuLocked" xml:space="preserve">
<value>Lock window</value>
</data>
<data name="NoTitleText" xml:space="preserve">
<value>&lt; no title &gt;</value>
</data>
<data name="Version" xml:space="preserve">
<value>Version: {0}</value>
</data>
<data name="SplashCheckingForUpdate" xml:space="preserve">
<value>Checking for update...</value>
</data>
<data name="SplashCheckingForDatabase" xml:space="preserve">
<value>Checking database existence...</value>
</data>
<data name="SplashCreatingDatabase" xml:space="preserve">
<value>Creating database...</value>
</data>
<data name="SplashRestarting" xml:space="preserve">
<value>Restarting...</value>
</data>
<data name="SplashInstallingUpdate" xml:space="preserve">
<value>Installing update...</value>
</data>
<data name="SplashMaintainingDatabase" xml:space="preserve">
<value>Maintaining database...</value>
</data>
<data name="SplashUpdatingDatabase" xml:space="preserve">
<value>Updating database...</value>
</data>
<data name="SplashStarting" xml:space="preserve">
<value>Starting...</value>
</data>
<data name="ApplicationDisplayName" xml:space="preserve">
<value>Feed Center</value>
</data>
<data name="ApplicationName" xml:space="preserve">
<value>FeedCenter</value>
</data>
<data name="UpdateCheckNewVersion" xml:space="preserve">
<value>Version {1} of {0} is now available.
Would you like to download and install it now?</value>
</data>
<data name="UpdateCheckCurrent" xml:space="preserve">
<value>You are already running the most recent version.
No updates are available at this time.</value>
</data>
<data name="UpdateCheckTitle" xml:space="preserve">
<value>{0} Update</value>
</data>
<data name="UpdateAvailable" xml:space="preserve">
<value>An update to version {0} is now available.</value>
</data>
<data name="FeedAddedNotification" xml:space="preserve">
<value>"{0}" has been successfully added to your feed list.</value>
</data>
<data name="optionCategoryGeneral" xml:space="preserve">
<value>General</value>
</data>
<data name="startWithWindowsCheckBox" xml:space="preserve">
<value>_Start when Windows starts</value>
</data>
<data name="nextToolbarButton" xml:space="preserve">
<value>Next feed</value>
</data>
<data name="optionsToolbarButton" xml:space="preserve">
<value>Options</value>
</data>
<data name="previousToolbarButton" xml:space="preserve">
<value>Previous feed</value>
</data>
<data name="refreshToolbarButton" xml:space="preserve">
<value>Refresh current feed</value>
</data>
<data name="refreshAllToolbarButton" xml:space="preserve">
<value>Refresh all feeds</value>
</data>
<data name="markReadToolbarButton" xml:space="preserve">
<value>Mark feed as read</value>
</data>
<data name="optionCategoryDisplay" xml:space="preserve">
<value>Display</value>
</data>
<data name="displayEmptyFeedsCheckBox" xml:space="preserve">
<value>_Display empty feeds</value>
</data>
<data name="lockWindowCheckBox" xml:space="preserve">
<value>_Lock window</value>
</data>
<data name="CancelButton" xml:space="preserve">
<value>Cancel</value>
</data>
<data name="OkayButton" xml:space="preserve">
<value>OK</value>
</data>
<data name="optionCategoryAbout" xml:space="preserve">
<value>About</value>
</data>
<data name="optionCategoryFeeds" xml:space="preserve">
<value>Feeds</value>
</data>
<data name="optionCategoryUpdate" xml:space="preserve">
<value>Update</value>
</data>
<data name="OptionsWindow" xml:space="preserve">
<value>Options</value>
</data>
<data name="AddFeedButton" xml:space="preserve">
<value>Add Feed</value>
</data>
<data name="DeleteFeedButton" xml:space="preserve">
<value>Delete Feed</value>
</data>
<data name="EditFeedButton" xml:space="preserve">
<value>Edit Feed</value>
</data>
<data name="ImportExportFilter" xml:space="preserve">
<value>OPML Files (*.opml)|*.opml|All Files (*.*)|*.*</value>
</data>
<data name="ActionsButton" xml:space="preserve">
<value>A_ctions</value>
</data>
<data name="ImportFeedsButton" xml:space="preserve">
<value>Import Feeds</value>
</data>
<data name="ExportFeedsButton" xml:space="preserve">
<value>Export Feeds</value>
</data>
<data name="SortFeeds" xml:space="preserve">
<value>Sort</value>
</data>
<data name="authenticationTab" xml:space="preserve">
<value>Authentication</value>
</data>
<data name="feedNameLabel" xml:space="preserve">
<value>Feed _name:</value>
</data>
<data name="feedReadIntervalPrefix" xml:space="preserve">
<value>_Refresh feed every</value>
</data>
<data name="feedReadIntervalSuffix" xml:space="preserve">
<value>minutes</value>
</data>
<data name="feedUrlLabel" xml:space="preserve">
<value>Feed _URL:</value>
</data>
<data name="FeedWindowAdd" xml:space="preserve">
<value>Add Feed</value>
</data>
<data name="FeedWindowEdit" xml:space="preserve">
<value>Edit Feed</value>
</data>
<data name="generalTab" xml:space="preserve">
<value>General</value>
</data>
<data name="checkVersionNowButton" xml:space="preserve">
<value>Check _Now</value>
</data>
<data name="checkVersionOnStartupCheckBox" xml:space="preserve">
<value>_Check for a new version on startup</value>
</data>
<data name="authenticationPasswordLabel" xml:space="preserve">
<value>_Password:</value>
</data>
<data name="authenticationUserNameLabel" xml:space="preserve">
<value>_User name:</value>
</data>
<data name="requiresAuthenticationCheckBox" xml:space="preserve">
<value>_Feed requires authentication</value>
</data>
<data name="FeedAuthenticationUserNameError" xml:space="preserve">
<value>Authentication user name must be specified</value>
</data>
<data name="FeedNameError" xml:space="preserve">
<value>Feed name must be specified</value>
</data>
<data name="FeedUrlError" xml:space="preserve">
<value>Feed URL must be specified</value>
</data>
<data name="Bottom" xml:space="preserve">
<value>Bottom</value>
</data>
<data name="Left" xml:space="preserve">
<value>Left</value>
</data>
<data name="Right" xml:space="preserve">
<value>Right</value>
</data>
<data name="toolbarLocationLabel" xml:space="preserve">
<value>_Tool bar location:</value>
</data>
<data name="Top" xml:space="preserve">
<value>Top</value>
</data>
<data name="showErrorsToolbarButton" xml:space="preserve">
<value>Show problems from last refresh</value>
</data>
<data name="FeedErrorColumnHeader" xml:space="preserve">
<value>Error</value>
</data>
<data name="FeedNameColumnHeader" xml:space="preserve">
<value>Feed</value>
</data>
<data name="CloseButton" xml:space="preserve">
<value>Close</value>
</data>
<data name="FeedErrorWindow" xml:space="preserve">
<value>Feed Reading Errors</value>
</data>
<data name="openAllSingleToolbarButton" xml:space="preserve">
<value>Open all links on single page</value>
</data>
<data name="registerAsDefaultFeedReaderCheckBox" xml:space="preserve">
<value>_Register as default feed reader</value>
</data>
<data name="browserLabel" xml:space="preserve">
<value>_Browser:</value>
</data>
<data name="DefaultBrowserCaption" xml:space="preserve">
<value>Default</value>
</data>
<data name="feedCategoryLabel" xml:space="preserve">
<value>_Category:</value>
</data>
<data name="optionCategoryCategories" xml:space="preserve">
<value>Categories</value>
</data>
<data name="AddCategoryButton" xml:space="preserve">
<value>Add Category</value>
</data>
<data name="EditCategoryButton" xml:space="preserve">
<value>Edit Category</value>
</data>
<data name="multipleLineDisplayLabel" xml:space="preserve">
<value>_Multi-line items:</value>
</data>
<data name="multipleLineDisplayFirstLine" xml:space="preserve">
<value>Show only first line</value>
</data>
<data name="multipleLineDisplayNormal" xml:space="preserve">
<value>Leave alone</value>
</data>
<data name="multipleLineDisplaySingleLine" xml:space="preserve">
<value>Flatten to single line</value>
</data>
<data name="CategoryWindowAdd" xml:space="preserve">
<value>Add Category</value>
</data>
<data name="CategoryWindowEdit" xml:space="preserve">
<value>Edit Category</value>
</data>
<data name="DeleteCategoryButton" xml:space="preserve">
<value>Delete Category</value>
</data>
<data name="showOnSinglePageToolbarButton" xml:space="preserve">
<value>Show all items on a single page</value>
</data>
<data name="openAllMultipleToolbarButton" xml:space="preserve">
<value>Open all links on individual pages</value>
</data>
<data name="CurrentFeed" xml:space="preserve">
<value>Current Feed</value>
</data>
<data name="DeleteMenu" xml:space="preserve">
<value>Delete</value>
</data>
<data name="EditMenu" xml:space="preserve">
<value>Edit...</value>
</data>
<data name="ConfirmDelete" xml:space="preserve">
<value>Are you sure you want to delete this feed?</value>
</data>
<data name="optionCategoryReading" xml:space="preserve">
<value>Reading</value>
</data>
<data name="openLabel" xml:space="preserve">
<value>"Open all" _action:</value>
</data>
<data name="DatabaseUpdate_5" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Scripts\DatabaseUpdate_5.sqlce;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
<data name="readingTab" xml:space="preserve">
<value>Reading</value>
</data>
<data name="BulkFeedWindow" xml:space="preserve">
<value>Edit Multiple Feeds</value>
</data>
<data name="FeedLinkFilterLabel" xml:space="preserve">
<value>Feed _link contains:</value>
</data>
<data name="SelectAllLabel" xml:space="preserve">
<value>All</value>
</data>
<data name="SelectInvertLabel" xml:space="preserve">
<value>Invert</value>
</data>
<data name="SelectLabel" xml:space="preserve">
<value>Select:</value>
</data>
<data name="SelectNoneLabel" xml:space="preserve">
<value>None</value>
</data>
<data name="AddLink" xml:space="preserve">
<value>Add</value>
</data>
<data name="CategoriesHeader" xml:space="preserve">
<value>Categories:</value>
</data>
<data name="DeleteLink" xml:space="preserve">
<value>Delete</value>
</data>
<data name="EditLink" xml:space="preserve">
<value>Edit</value>
</data>
<data name="ExportLink" xml:space="preserve">
<value>Export</value>
</data>
<data name="FeedsHeader" xml:space="preserve">
<value>Feeds:</value>
</data>
<data name="ImportLink" xml:space="preserve">
<value>Import</value>
</data>
<data name="MultipleEditButton" xml:space="preserve">
<value>Edit Multiple Feeds</value>
</data>
<data name="MultipleEditLink" xml:space="preserve">
<value>Multiple Edit</value>
</data>
<data name="CategoryNameColumnHeader" xml:space="preserve">
<value>Category</value>
</data>
<data name="LastUpdatedColumnHeader" xml:space="preserve">
<value>Last Updated</value>
</data>
<data name="FeedErrorLink" xml:space="preserve">
<value>One feed has an error</value>
</data>
<data name="FeedErrorsLink" xml:space="preserve">
<value>{0} feeds have errors</value>
</data>
<data name="NewVersionLink" xml:space="preserve">
<value>New version available</value>
</data>
<data name="OpenFeed" xml:space="preserve">
<value>Open Feed</value>
</data>
<data name="OpenPage" xml:space="preserve">
<value>Open Page</value>
</data>
<data name="FeedReadResult_NotFound" xml:space="preserve">
<value>Not found</value>
</data>
<data name="FeedReadResult_ServerError" xml:space="preserve">
<value>Server error</value>
</data>
<data name="FeedReadResult_ConnectionFailed" xml:space="preserve">
<value>Connection failed</value>
</data>
<data name="FeedReadResult_InvalidXml" xml:space="preserve">
<value>Invalid format</value>
</data>
<data name="FeedReadResult_NoResponse" xml:space="preserve">
<value>No response</value>
</data>
<data name="FeedReadResult_Timeout" xml:space="preserve">
<value>Timeout</value>
</data>
<data name="FeedReadResult_Unauthorized" xml:space="preserve">
<value>Not authorized</value>
</data>
<data name="RefreshCurrent" xml:space="preserve">
<value>Retry</value>
</data>
<data name="DisableHint" xml:space="preserve">
<value>Right click to disable</value>
</data>
<data name="EnableHint" xml:space="preserve">
<value>Right click to enable</value>
</data>
<data name="DatabaseUpdate_6" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Scripts\DatabaseUpdate_6.sqlce;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
</data>
</root>

View File

@@ -0,0 +1,276 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.34209
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace FeedCenter.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default {
get {
return defaultInstance;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Configuration.SettingsProviderAttribute(typeof(Common.Settings.GenericSettingsProvider))]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("False")]
public bool WindowLocked {
get {
return ((bool)(this["WindowLocked"]));
}
set {
this["WindowLocked"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Configuration.SettingsProviderAttribute(typeof(Common.Settings.GenericSettingsProvider))]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("0,0")]
public global::System.Windows.Size WindowSize {
get {
return ((global::System.Windows.Size)(this["WindowSize"]));
}
set {
this["WindowSize"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Configuration.SettingsProviderAttribute(typeof(Common.Settings.GenericSettingsProvider))]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("0,0")]
public global::System.Windows.Point WindowLocation {
get {
return ((global::System.Windows.Point)(this["WindowLocation"]));
}
set {
this["WindowLocation"] = value;
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("True")]
public bool LogDatabase {
get {
return ((bool)(this["LogDatabase"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("FeedCenter.sdf")]
public string DatabaseFile {
get {
return ((string)(this["DatabaseFile"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("250")]
public int ProgressSleepInterval {
get {
return ((int)(this["ProgressSleepInterval"]));
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("True")]
public bool CheckVersionAtStartup {
get {
return ((bool)(this["CheckVersionAtStartup"]));
}
set {
this["CheckVersionAtStartup"] = value;
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("5000")]
public int BalloonTipTimeout {
get {
return ((int)(this["BalloonTipTimeout"]));
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Configuration.SettingsProviderAttribute(typeof(Common.Settings.GenericSettingsProvider))]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("00:01:00")]
public global::System.TimeSpan FeedScrollInterval {
get {
return ((global::System.TimeSpan)(this["FeedScrollInterval"]));
}
set {
this["FeedScrollInterval"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Configuration.SettingsProviderAttribute(typeof(Common.Settings.GenericSettingsProvider))]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("00:30:00")]
public global::System.TimeSpan FeedCheckInterval {
get {
return ((global::System.TimeSpan)(this["FeedCheckInterval"]));
}
set {
this["FeedCheckInterval"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Configuration.SettingsProviderAttribute(typeof(Common.Settings.GenericSettingsProvider))]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("True")]
public bool DisplayEmptyFeeds {
get {
return ((bool)(this["DisplayEmptyFeeds"]));
}
set {
this["DisplayEmptyFeeds"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Configuration.SettingsProviderAttribute(typeof(Common.Settings.GenericSettingsProvider))]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public global::System.DateTime LastVersionCheck {
get {
return ((global::System.DateTime)(this["LastVersionCheck"]));
}
set {
this["LastVersionCheck"] = value;
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("01:00:00")]
public global::System.TimeSpan VersionCheckInterval {
get {
return ((global::System.TimeSpan)(this["VersionCheckInterval"]));
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Configuration.SettingsProviderAttribute(typeof(Common.Settings.GenericSettingsProvider))]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("False")]
public bool StartWithWindows {
get {
return ((bool)(this["StartWithWindows"]));
}
set {
this["StartWithWindows"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("True")]
public bool FirstRun {
get {
return ((bool)(this["FirstRun"]));
}
set {
this["FirstRun"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Configuration.SettingsProviderAttribute(typeof(Common.Settings.GenericSettingsProvider))]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("Bottom")]
public global::System.Windows.Controls.Dock ToolbarLocation {
get {
return ((global::System.Windows.Controls.Dock)(this["ToolbarLocation"]));
}
set {
this["ToolbarLocation"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Configuration.SettingsProviderAttribute(typeof(Common.Settings.GenericSettingsProvider))]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("500")]
public int OpenAllSleepInterval {
get {
return ((int)(this["OpenAllSleepInterval"]));
}
set {
this["OpenAllSleepInterval"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Configuration.SettingsProviderAttribute(typeof(Common.Settings.GenericSettingsProvider))]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("False")]
public bool RegisterAsDefaultFeedReader {
get {
return ((bool)(this["RegisterAsDefaultFeedReader"]));
}
set {
this["RegisterAsDefaultFeedReader"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Configuration.SettingsProviderAttribute(typeof(Common.Settings.GenericSettingsProvider))]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string Browser {
get {
return ((string)(this["Browser"]));
}
set {
this["Browser"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Configuration.SettingsProviderAttribute(typeof(Common.Settings.GenericSettingsProvider))]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("1500")]
public int OpenAllSleepIntervalFirst {
get {
return ((int)(this["OpenAllSleepIntervalFirst"]));
}
set {
this["OpenAllSleepIntervalFirst"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Configuration.SettingsProviderAttribute(typeof(Common.Settings.GenericSettingsProvider))]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("Normal")]
public global::FeedCenter.Options.MultipleLineDisplay MultipleLineDisplay {
get {
return ((global::FeedCenter.Options.MultipleLineDisplay)(this["MultipleLineDisplay"]));
}
set {
this["MultipleLineDisplay"] = value;
}
}
}
}

View File

@@ -0,0 +1,69 @@
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="FeedCenter.Properties" GeneratedClassName="Settings">
<Profiles />
<Settings>
<Setting Name="WindowLocked" Provider="Common.Settings.GenericSettingsProvider" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
<Setting Name="WindowSize" Provider="Common.Settings.GenericSettingsProvider" Type="System.Windows.Size" Scope="User">
<Value Profile="(Default)">0,0</Value>
</Setting>
<Setting Name="WindowLocation" Provider="Common.Settings.GenericSettingsProvider" Type="System.Windows.Point" Scope="User">
<Value Profile="(Default)">0,0</Value>
</Setting>
<Setting Name="LogDatabase" Type="System.Boolean" Scope="Application">
<Value Profile="(Default)">True</Value>
</Setting>
<Setting Name="DatabaseFile" Type="System.String" Scope="Application">
<Value Profile="(Default)">FeedCenter.sdf</Value>
</Setting>
<Setting Name="ProgressSleepInterval" Type="System.Int32" Scope="Application">
<Value Profile="(Default)">250</Value>
</Setting>
<Setting Name="CheckVersionAtStartup" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value>
</Setting>
<Setting Name="BalloonTipTimeout" Type="System.Int32" Scope="Application">
<Value Profile="(Default)">5000</Value>
</Setting>
<Setting Name="FeedScrollInterval" Provider="Common.Settings.GenericSettingsProvider" Type="System.TimeSpan" Scope="User">
<Value Profile="(Default)">00:01:00</Value>
</Setting>
<Setting Name="FeedCheckInterval" Provider="Common.Settings.GenericSettingsProvider" Type="System.TimeSpan" Scope="User">
<Value Profile="(Default)">00:30:00</Value>
</Setting>
<Setting Name="DisplayEmptyFeeds" Provider="Common.Settings.GenericSettingsProvider" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value>
</Setting>
<Setting Name="LastVersionCheck" Provider="Common.Settings.GenericSettingsProvider" Type="System.DateTime" Scope="User">
<Value Profile="(Default)" />
</Setting>
<Setting Name="VersionCheckInterval" Type="System.TimeSpan" Scope="Application">
<Value Profile="(Default)">01:00:00</Value>
</Setting>
<Setting Name="StartWithWindows" Provider="Common.Settings.GenericSettingsProvider" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
<Setting Name="FirstRun" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value>
</Setting>
<Setting Name="ToolbarLocation" Provider="Common.Settings.GenericSettingsProvider" Type="System.Windows.Controls.Dock" Scope="User">
<Value Profile="(Default)">Bottom</Value>
</Setting>
<Setting Name="OpenAllSleepInterval" Provider="Common.Settings.GenericSettingsProvider" Type="System.Int32" Scope="User">
<Value Profile="(Default)">500</Value>
</Setting>
<Setting Name="RegisterAsDefaultFeedReader" Provider="Common.Settings.GenericSettingsProvider" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
<Setting Name="Browser" Provider="Common.Settings.GenericSettingsProvider" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
<Setting Name="OpenAllSleepIntervalFirst" Provider="Common.Settings.GenericSettingsProvider" Type="System.Int32" Scope="User">
<Value Profile="(Default)">1500</Value>
</Setting>
<Setting Name="MultipleLineDisplay" Provider="Common.Settings.GenericSettingsProvider" Type="FeedCenter.Options.MultipleLineDisplay" Scope="User">
<Value Profile="(Default)">Normal</Value>
</Setting>
</Settings>
</SettingsFile>

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app" />
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<!-- UAC Manifest Options
If you want to change the Windows User Account Control level replace the
requestedExecutionLevel node with one of the following.
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
Specifying requestedExecutionLevel node will disable file and registry virtualization.
If you want to utilize File and Registry Virtualization for backward
compatibility then delete the requestedExecutionLevel node.
-->
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
</requestedPrivileges>
<applicationRequestMinimum>
<PermissionSet class="System.Security.PermissionSet" version="1" Unrestricted="true" ID="Custom" SameSite="site" />
<defaultAssemblyRequest permissionSetReference="Custom" />
</applicationRequestMinimum>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- A list of all Windows versions that this application is designed to work with. Windows will automatically select the most compatible environment.-->
<!-- If your application is designed to work with Windows 7, uncomment the following supportedOS node-->
<!--<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>-->
</application>
</compatibility>
<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
<!-- <dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>-->
</asmv1:assembly>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,85 @@
CREATE TABLE Category
(
ID uniqueidentifier NOT NULL,
Name nvarchar(1000) NOT NULL DEFAULT '',
CONSTRAINT PK_Category PRIMARY KEY (ID)
)
GO
CREATE TABLE Setting
(
Name nvarchar(500) NOT NULL DEFAULT '',
Value nvarchar(3500) NOT NULL DEFAULT '',
Version nvarchar(50) NOT NULL DEFAULT '',
CONSTRAINT PK_Setting PRIMARY KEY (Name, Version)
)
GO
CREATE TABLE Feed
(
ID uniqueidentifier NOT NULL,
Name nvarchar(1000) NOT NULL DEFAULT '',
Title nvarchar(1000) NOT NULL DEFAULT '',
Source nvarchar(1000) NOT NULL DEFAULT '',
Link nvarchar(1000) NOT NULL DEFAULT '',
Description ntext NOT NULL DEFAULT '',
LastChecked datetime NOT NULL DEFAULT 0,
CheckInterval int NOT NULL DEFAULT 0,
Enabled bit NOT NULL DEFAULT 1,
Authenticate bit NOT NULL DEFAULT 0,
Username nvarchar(1000) NOT NULL DEFAULT '',
Password nvarchar(1000) NOT NULL DEFAULT '',
Domain nvarchar(1000) NOT NULL DEFAULT '',
Sequence int NOT NULL DEFAULT 0,
LastReadResult int NOT NULL DEFAULT 0,
LastUpdated datetime NOT NULL DEFAULT 0,
ItemComparison tinyint NOT NULL DEFAULT 0,
CategoryID uniqueidentifier NOT NULL,
CONSTRAINT PK_Feed PRIMARY KEY (ID),
CONSTRAINT FK_Feed_Category FOREIGN KEY (CategoryID) REFERENCES Category(ID)
)
GO
CREATE TABLE FeedItem
(
ID uniqueidentifier NOT NULL,
FeedID uniqueidentifier NOT NULL,
Title nvarchar(1000) NOT NULL DEFAULT '',
Link nvarchar(1000) NOT NULL DEFAULT '',
Description nvarchar(1000) NOT NULL DEFAULT '',
BeenRead bit NOT NULL DEFAULT 0,
LastFound datetime NOT NULL DEFAULT 0,
New bit NOT NULL DEFAULT 0,
Sequence int NOT NULL DEFAULT 0,
CONSTRAINT PK_FeedItem PRIMARY KEY (ID),
CONSTRAINT FK_FeedItem_Feed FOREIGN KEY (FeedID) REFERENCES Feed(ID) ON UPDATE CASCADE ON DELETE CASCADE
)
GO
CREATE TABLE FeedAction
(
ID uniqueidentifier NOT NULL,
FeedID uniqueidentifier NOT NULL,
Field int NOT NULL DEFAULT 0,
Search nvarchar(1000) NOT NULL DEFAULT '',
Replace nvarchar(1000) NOT NULL DEFAULT '',
Sequence int NOT NULL DEFAULT 0,
CONSTRAINT PK_FeedAction PRIMARY KEY (ID),
CONSTRAINT FK_FeedAction_Feed FOREIGN KEY (FeedID) REFERENCES Feed(ID) ON UPDATE CASCADE ON DELETE CASCADE
)
GO
INSERT Category
(ID, Name)
VALUES (newid(), 'Default')
GO
INSERT Setting
(Name, Value, Version)
VALUES ('DatabaseVersion', '1', '')
GO

View File

@@ -0,0 +1,18 @@
ALTER TABLE FeedItem ADD COLUMN Guid nvarchar(1000)
GO
UPDATE FeedItem
SET Guid = ''
WHERE Guid IS NULL
GO
ALTER TABLE FeedItem ALTER COLUMN Guid nvarchar(1000) NOT NULL
GO
ALTER TABLE FeedItem ALTER COLUMN Guid SET DEFAULT ''
GO
UPDATE Setting
SET Value = '2'
WHERE Name = 'DatabaseVersion'
GO

View File

@@ -0,0 +1,30 @@
ALTER TABLE FeedItem
ALTER COLUMN Description
DROP DEFAULT
GO
ALTER TABLE FeedItem
ALTER COLUMN Description ntext NOT NULL
GO
ALTER TABLE FeedItem
ALTER COLUMN Description SET DEFAULT ''
GO
ALTER TABLE FeedItem
ALTER COLUMN Title
DROP DEFAULT
GO
ALTER TABLE FeedItem
ALTER COLUMN Title ntext NOT NULL
GO
ALTER TABLE FeedItem
ALTER COLUMN Title SET DEFAULT ''
GO
UPDATE Setting
SET Value = '3'
WHERE Name = 'DatabaseVersion'
GO

View File

@@ -0,0 +1,9 @@
UPDATE Category
SET Name = '< default >'
WHERE Name = 'Default'
GO
UPDATE Setting
SET Value = '4'
WHERE Name = 'DatabaseVersion'
GO

View File

@@ -0,0 +1,8 @@
ALTER TABLE Feed
DROP COLUMN Sequence
GO
UPDATE Setting
SET Value = '5'
WHERE Name = 'DatabaseVersion'
GO

View File

@@ -0,0 +1,18 @@
ALTER TABLE Feed ADD COLUMN MultipleOpenAction int
GO
UPDATE Feed
SET MultipleOpenAction = 0
WHERE MultipleOpenAction IS NULL
GO
ALTER TABLE Feed ALTER COLUMN MultipleOpenAction int NOT NULL
GO
ALTER TABLE Feed ALTER COLUMN MultipleOpenAction SET DEFAULT 0
GO
UPDATE Setting
SET Value = '6'
WHERE Name = 'DatabaseVersion'
GO

View File

@@ -0,0 +1,14 @@
CREATE TABLE DatabaseVersion
(
Value int NOT NULL DEFAULT 0
)
GO
INSERT DatabaseVersion
(Value)
VALUES (7)
GO
DELETE Setting
WHERE Name = 'DatabaseVersion'
GO

21
Application/Setting.cs Normal file
View File

@@ -0,0 +1,21 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace FeedCenter
{
using System;
using System.Collections.Generic;
public partial class Setting
{
public string Name { get; set; }
public string Value { get; set; }
public string Version { get; set; }
}
}

Some files were not shown because too many files have changed in this diff Show More