Initial commit
63
.gitattributes
vendored
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
###############################################################################
|
||||||
|
# Set default behavior to automatically normalize line endings.
|
||||||
|
###############################################################################
|
||||||
|
* text=auto
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Set default behavior for command prompt diff.
|
||||||
|
#
|
||||||
|
# This is need for earlier builds of msysgit that does not have it on by
|
||||||
|
# default for csharp files.
|
||||||
|
# Note: This is only used by command line
|
||||||
|
###############################################################################
|
||||||
|
#*.cs diff=csharp
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Set the merge driver for project and solution files
|
||||||
|
#
|
||||||
|
# Merging from the command prompt will add diff markers to the files if there
|
||||||
|
# are conflicts (Merging from VS is not affected by the settings below, in VS
|
||||||
|
# the diff markers are never inserted). Diff markers may cause the following
|
||||||
|
# file extensions to fail to load in VS. An alternative would be to treat
|
||||||
|
# these files as binary and thus will always conflict and require user
|
||||||
|
# intervention with every merge. To do so, just uncomment the entries below
|
||||||
|
###############################################################################
|
||||||
|
#*.sln merge=binary
|
||||||
|
#*.csproj merge=binary
|
||||||
|
#*.vbproj merge=binary
|
||||||
|
#*.vcxproj merge=binary
|
||||||
|
#*.vcproj merge=binary
|
||||||
|
#*.dbproj merge=binary
|
||||||
|
#*.fsproj merge=binary
|
||||||
|
#*.lsproj merge=binary
|
||||||
|
#*.wixproj merge=binary
|
||||||
|
#*.modelproj merge=binary
|
||||||
|
#*.sqlproj merge=binary
|
||||||
|
#*.wwaproj merge=binary
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# behavior for image files
|
||||||
|
#
|
||||||
|
# image files are treated as binary by default.
|
||||||
|
###############################################################################
|
||||||
|
#*.jpg binary
|
||||||
|
#*.png binary
|
||||||
|
#*.gif binary
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# diff behavior for common document formats
|
||||||
|
#
|
||||||
|
# Convert binary document formats to text before diffing them. This feature
|
||||||
|
# is only available from the command line. Turn it on by uncommenting the
|
||||||
|
# entries below.
|
||||||
|
###############################################################################
|
||||||
|
#*.doc diff=astextplain
|
||||||
|
#*.DOC diff=astextplain
|
||||||
|
#*.docx diff=astextplain
|
||||||
|
#*.DOCX diff=astextplain
|
||||||
|
#*.dot diff=astextplain
|
||||||
|
#*.DOT diff=astextplain
|
||||||
|
#*.pdf diff=astextplain
|
||||||
|
#*.PDF diff=astextplain
|
||||||
|
#*.rtf diff=astextplain
|
||||||
|
#*.RTF diff=astextplain
|
||||||
156
.gitignore
vendored
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
|
||||||
|
# User-specific files
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.sln.docstates
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
|
||||||
|
[Dd]ebug/
|
||||||
|
[Rr]elease/
|
||||||
|
x64/
|
||||||
|
build/
|
||||||
|
[Bb]in/
|
||||||
|
[Oo]bj/
|
||||||
|
|
||||||
|
# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
|
||||||
|
!packages/*/build/
|
||||||
|
|
||||||
|
# MSTest test Results
|
||||||
|
[Tt]est[Rr]esult*/
|
||||||
|
[Bb]uild[Ll]og.*
|
||||||
|
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*.ilk
|
||||||
|
*.meta
|
||||||
|
*.obj
|
||||||
|
*.pch
|
||||||
|
*.pdb
|
||||||
|
*.pgc
|
||||||
|
*.pgd
|
||||||
|
*.rsp
|
||||||
|
*.sbr
|
||||||
|
*.tlb
|
||||||
|
*.tli
|
||||||
|
*.tlh
|
||||||
|
*.tmp
|
||||||
|
*.tmp_proj
|
||||||
|
*.log
|
||||||
|
*.vspscc
|
||||||
|
*.vssscc
|
||||||
|
.builds
|
||||||
|
*.pidb
|
||||||
|
*.log
|
||||||
|
*.scc
|
||||||
|
|
||||||
|
# Visual C++ cache files
|
||||||
|
ipch/
|
||||||
|
*.aps
|
||||||
|
*.ncb
|
||||||
|
*.opensdf
|
||||||
|
*.sdf
|
||||||
|
*.cachefile
|
||||||
|
|
||||||
|
# Visual Studio profiler
|
||||||
|
*.psess
|
||||||
|
*.vsp
|
||||||
|
*.vspx
|
||||||
|
|
||||||
|
# Guidance Automation Toolkit
|
||||||
|
*.gpState
|
||||||
|
|
||||||
|
# ReSharper is a .NET coding add-in
|
||||||
|
_ReSharper*/
|
||||||
|
*.[Rr]e[Ss]harper
|
||||||
|
|
||||||
|
# TeamCity is a build add-in
|
||||||
|
_TeamCity*
|
||||||
|
|
||||||
|
# DotCover is a Code Coverage Tool
|
||||||
|
*.dotCover
|
||||||
|
|
||||||
|
# NCrunch
|
||||||
|
*.ncrunch*
|
||||||
|
.*crunch*.local.xml
|
||||||
|
|
||||||
|
# Installshield output folder
|
||||||
|
[Ee]xpress/
|
||||||
|
|
||||||
|
# DocProject is a documentation generator add-in
|
||||||
|
DocProject/buildhelp/
|
||||||
|
DocProject/Help/*.HxT
|
||||||
|
DocProject/Help/*.HxC
|
||||||
|
DocProject/Help/*.hhc
|
||||||
|
DocProject/Help/*.hhk
|
||||||
|
DocProject/Help/*.hhp
|
||||||
|
DocProject/Help/Html2
|
||||||
|
DocProject/Help/html
|
||||||
|
|
||||||
|
# Click-Once directory
|
||||||
|
publish/
|
||||||
|
|
||||||
|
# Publish Web Output
|
||||||
|
*.Publish.xml
|
||||||
|
|
||||||
|
# NuGet Packages Directory
|
||||||
|
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
|
||||||
|
#packages/
|
||||||
|
|
||||||
|
# Windows Azure Build Output
|
||||||
|
csx
|
||||||
|
*.build.csdef
|
||||||
|
|
||||||
|
# Windows Store app package directory
|
||||||
|
AppPackages/
|
||||||
|
|
||||||
|
# Others
|
||||||
|
sql/
|
||||||
|
*.Cache
|
||||||
|
ClientBin/
|
||||||
|
[Ss]tyle[Cc]op.*
|
||||||
|
~$*
|
||||||
|
*~
|
||||||
|
*.dbmdl
|
||||||
|
*.[Pp]ublish.xml
|
||||||
|
*.pfx
|
||||||
|
*.publishsettings
|
||||||
|
|
||||||
|
# RIA/Silverlight projects
|
||||||
|
Generated_Code/
|
||||||
|
|
||||||
|
# Backup & report files from converting an old project file to a newer
|
||||||
|
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
||||||
|
_UpgradeReport_Files/
|
||||||
|
Backup*/
|
||||||
|
UpgradeLog*.XML
|
||||||
|
UpgradeLog*.htm
|
||||||
|
|
||||||
|
# SQL Server files
|
||||||
|
App_Data/*.mdf
|
||||||
|
App_Data/*.ldf
|
||||||
|
|
||||||
|
|
||||||
|
#LightSwitch generated files
|
||||||
|
GeneratedArtifacts/
|
||||||
|
_Pvt_Extensions/
|
||||||
|
ModelManifest.xml
|
||||||
|
|
||||||
|
# =========================
|
||||||
|
# Windows detritus
|
||||||
|
# =========================
|
||||||
|
|
||||||
|
# Windows image file caches
|
||||||
|
Thumbs.db
|
||||||
|
ehthumbs.db
|
||||||
|
|
||||||
|
# Folder config file
|
||||||
|
Desktop.ini
|
||||||
|
|
||||||
|
# Recycle Bin used on file shares
|
||||||
|
$RECYCLE.BIN/
|
||||||
|
|
||||||
|
# Mac desktop service store files
|
||||||
|
.DS_Store
|
||||||
12
App.xaml
Normal 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
App.xaml.cs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
65
BrowserCommon.cs
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using Common.Debug;
|
||||||
|
using Common.Internet;
|
||||||
|
using FeedCenter.Properties;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
228
Data/Database.cs
Normal file
@@ -0,0 +1,228 @@
|
|||||||
|
using System;
|
||||||
|
using System.Data.SqlServerCe;
|
||||||
|
using System.IO;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
using Common.Debug;
|
||||||
|
|
||||||
|
using FeedCenter.Properties;
|
||||||
|
|
||||||
|
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 (FileStream stream = new FileStream(databasePath, FileMode.Open, FileAccess.Read))
|
||||||
|
{
|
||||||
|
// Read the file using the binary reader
|
||||||
|
BinaryReader 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 (SqlCeEngine 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 = string.Empty;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Check the database version table
|
||||||
|
using (SqlCeCommand command = new SqlCeCommand("SELECT Value FROM DatabaseVersion", connection))
|
||||||
|
versionString = command.ExecuteScalar().ToString();
|
||||||
|
}
|
||||||
|
catch (SqlCeException)
|
||||||
|
{
|
||||||
|
// Check the setting table for the version
|
||||||
|
using (SqlCeCommand 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
|
||||||
|
SqlServerCeFileVersion 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 (SqlCeEngine 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 (SqlCeConnection connection = new SqlCeConnection(string.Format("Data Source={0}", DatabasePath)))
|
||||||
|
{
|
||||||
|
// Open the connection
|
||||||
|
connection.Open();
|
||||||
|
|
||||||
|
// Get the database version
|
||||||
|
int 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
|
||||||
|
string propertyName = property.Name;
|
||||||
|
|
||||||
|
// Extract the version from the name
|
||||||
|
int 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
|
||||||
|
string 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 (SqlCeEngine 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 (SqlCeConnection connection = new SqlCeConnection(string.Format("Data Source={0}", DatabasePath)))
|
||||||
|
{
|
||||||
|
// Open the connection
|
||||||
|
connection.Open();
|
||||||
|
|
||||||
|
// Setup the delimiters
|
||||||
|
string[] delimiters = new[] { "\r\nGO\r\n" };
|
||||||
|
|
||||||
|
// Split the script at the delimiters
|
||||||
|
string[] statements = scriptText.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
|
||||||
|
// Loop over each statement in the script
|
||||||
|
foreach (string statement in statements)
|
||||||
|
{
|
||||||
|
// Execute the statement
|
||||||
|
using (SqlCeCommand command = new SqlCeCommand(statement, connection))
|
||||||
|
command.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
155
Data/Extensions.cs
Normal 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
|
||||||
|
DataTable 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
|
||||||
|
object[] formattedParameters = new object[parameters.Length];
|
||||||
|
|
||||||
|
// Initialize our position
|
||||||
|
int position = 0;
|
||||||
|
|
||||||
|
// Loop over each parameter
|
||||||
|
foreach (object 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
|
||||||
|
DateTime dateTime = (DateTime) parameter;
|
||||||
|
|
||||||
|
// Convert the DateTime to sortable format
|
||||||
|
string 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
|
||||||
|
SqlCeCommand 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
|
||||||
|
SqlCeCommand command = connection.CreateCommand();
|
||||||
|
|
||||||
|
// Set the statement based on the query and parameters
|
||||||
|
command.SetStatement(query, parameters);
|
||||||
|
|
||||||
|
// Create a new data adapter
|
||||||
|
using (SqlCeDataAdapter adapter = new SqlCeDataAdapter(command))
|
||||||
|
{
|
||||||
|
// Create the new data set
|
||||||
|
using (DataSet 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
|
||||||
|
SqlCeCommand 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
|
||||||
|
}
|
||||||
|
}
|
||||||
127
Entities.cs
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.ComponentModel;
|
||||||
|
|
||||||
|
namespace FeedCenter
|
||||||
|
{
|
||||||
|
public partial class FeedCenterEntities
|
||||||
|
{
|
||||||
|
#region Dispose
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
ObjectStateManager.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)
|
||||||
|
{
|
||||||
|
ObjectStateManager.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)
|
||||||
|
{
|
||||||
|
ObjectStateManager.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;
|
||||||
|
|
||||||
|
Category 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 (Category loopCategory in Categories)
|
||||||
|
_allCategories.Add(loopCategory);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (e.Element is Feed)
|
||||||
|
{
|
||||||
|
if (_allFeeds == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Feed 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 (Feed loopfeed in Feeds)
|
||||||
|
_allFeeds.Add(loopfeed);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
471
FeedCenter.csproj
Normal file
@@ -0,0 +1,471 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.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</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="System" />
|
||||||
|
<Reference Include="System.configuration" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Data.Entity" />
|
||||||
|
<Reference Include="System.Data.SqlServerCe, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>bin\Debug\System.Data.SqlServerCe.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="System.Data.SqlServerCe.Entity, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91, processorArchitecture=MSIL">
|
||||||
|
<SpecificVersion>False</SpecificVersion>
|
||||||
|
<HintPath>bin\Debug\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="Data\Extensions.cs" />
|
||||||
|
<Compile Include="Entities.cs" />
|
||||||
|
<Compile Include="FeedErrorWindow.xaml.cs">
|
||||||
|
<DependentUpon>FeedErrorWindow.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Feeds\Category.cs" />
|
||||||
|
<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="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="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">
|
||||||
|
<Visible>False</Visible>
|
||||||
|
<ProductName>Microsoft .NET Framework 4.5 %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>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
<Import Project="packages\Microsoft.Bcl.Build.1.0.13\tools\Microsoft.Bcl.Build.targets" Condition="Exists('packages\Microsoft.Bcl.Build.1.0.13\tools\Microsoft.Bcl.Build.targets')" />
|
||||||
|
<Target Name="EnsureBclBuildImported" BeforeTargets="BeforeBuild" Condition="'$(BclBuildImported)' == ''">
|
||||||
|
<Error Condition="!Exists('packages\Microsoft.Bcl.Build.1.0.13\tools\Microsoft.Bcl.Build.targets')" Text="This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="BCLBUILD2001" />
|
||||||
|
<Error Condition="Exists('packages\Microsoft.Bcl.Build.1.0.13\tools\Microsoft.Bcl.Build.targets')" Text="The build restored NuGet packages. Build the project again to include these packages in the build. For more information, see http://go.microsoft.com/fwlink/?LinkID=317568." HelpKeyword="BCLBUILD2002" />
|
||||||
|
</Target>
|
||||||
|
<!-- 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>
|
||||||
2
FeedCenter.csproj.DotSettings
Normal 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>
|
||||||
91
FeedCenter.sln
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 2013
|
||||||
|
VisualStudioVersion = 12.0.21005.1
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FeedCenter", "FeedCenter.csproj", "{BD3D12F2-DE23-4466-83B1-1EB617A877A4}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common", "..\Common\Common.csproj", "{17864D82-457D-4A0A-BC10-1D07F2B3A5D6}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common.Wpf", "..\Common.Wpf\Common.Wpf.csproj", "{0074C983-550E-4094-9E8C-F566FB669297}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common.Native", "..\Common.Native\Common.Native.csproj", "{ED1C07A1-54F5-4796-8B06-2A0BB1960D84}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Debug|Mixed Platforms = Debug|Mixed Platforms
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
Release|Mixed Platforms = Release|Mixed Platforms
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{BD3D12F2-DE23-4466-83B1-1EB617A877A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{BD3D12F2-DE23-4466-83B1-1EB617A877A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{BD3D12F2-DE23-4466-83B1-1EB617A877A4}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
||||||
|
{BD3D12F2-DE23-4466-83B1-1EB617A877A4}.Debug|Mixed Platforms.Build.0 = Debug|x86
|
||||||
|
{BD3D12F2-DE23-4466-83B1-1EB617A877A4}.Debug|x64.ActiveCfg = Debug|x86
|
||||||
|
{BD3D12F2-DE23-4466-83B1-1EB617A877A4}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{BD3D12F2-DE23-4466-83B1-1EB617A877A4}.Debug|x86.Build.0 = Debug|x86
|
||||||
|
{BD3D12F2-DE23-4466-83B1-1EB617A877A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{BD3D12F2-DE23-4466-83B1-1EB617A877A4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{BD3D12F2-DE23-4466-83B1-1EB617A877A4}.Release|Mixed Platforms.ActiveCfg = Release|x86
|
||||||
|
{BD3D12F2-DE23-4466-83B1-1EB617A877A4}.Release|Mixed Platforms.Build.0 = Release|x86
|
||||||
|
{BD3D12F2-DE23-4466-83B1-1EB617A877A4}.Release|x64.ActiveCfg = Release|x86
|
||||||
|
{BD3D12F2-DE23-4466-83B1-1EB617A877A4}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
{BD3D12F2-DE23-4466-83B1-1EB617A877A4}.Release|x86.Build.0 = Release|x86
|
||||||
|
{17864D82-457D-4A0A-BC10-1D07F2B3A5D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{17864D82-457D-4A0A-BC10-1D07F2B3A5D6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{17864D82-457D-4A0A-BC10-1D07F2B3A5D6}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
||||||
|
{17864D82-457D-4A0A-BC10-1D07F2B3A5D6}.Debug|Mixed Platforms.Build.0 = Debug|x86
|
||||||
|
{17864D82-457D-4A0A-BC10-1D07F2B3A5D6}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{17864D82-457D-4A0A-BC10-1D07F2B3A5D6}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{17864D82-457D-4A0A-BC10-1D07F2B3A5D6}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{17864D82-457D-4A0A-BC10-1D07F2B3A5D6}.Debug|x86.Build.0 = Debug|x86
|
||||||
|
{17864D82-457D-4A0A-BC10-1D07F2B3A5D6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{17864D82-457D-4A0A-BC10-1D07F2B3A5D6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{17864D82-457D-4A0A-BC10-1D07F2B3A5D6}.Release|Mixed Platforms.ActiveCfg = Release|x86
|
||||||
|
{17864D82-457D-4A0A-BC10-1D07F2B3A5D6}.Release|Mixed Platforms.Build.0 = Release|x86
|
||||||
|
{17864D82-457D-4A0A-BC10-1D07F2B3A5D6}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{17864D82-457D-4A0A-BC10-1D07F2B3A5D6}.Release|x64.Build.0 = Release|x64
|
||||||
|
{17864D82-457D-4A0A-BC10-1D07F2B3A5D6}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
{17864D82-457D-4A0A-BC10-1D07F2B3A5D6}.Release|x86.Build.0 = Release|x86
|
||||||
|
{0074C983-550E-4094-9E8C-F566FB669297}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{0074C983-550E-4094-9E8C-F566FB669297}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{0074C983-550E-4094-9E8C-F566FB669297}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
||||||
|
{0074C983-550E-4094-9E8C-F566FB669297}.Debug|Mixed Platforms.Build.0 = Debug|x86
|
||||||
|
{0074C983-550E-4094-9E8C-F566FB669297}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{0074C983-550E-4094-9E8C-F566FB669297}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{0074C983-550E-4094-9E8C-F566FB669297}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{0074C983-550E-4094-9E8C-F566FB669297}.Debug|x86.Build.0 = Debug|x86
|
||||||
|
{0074C983-550E-4094-9E8C-F566FB669297}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{0074C983-550E-4094-9E8C-F566FB669297}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{0074C983-550E-4094-9E8C-F566FB669297}.Release|Mixed Platforms.ActiveCfg = Release|x86
|
||||||
|
{0074C983-550E-4094-9E8C-F566FB669297}.Release|Mixed Platforms.Build.0 = Release|x86
|
||||||
|
{0074C983-550E-4094-9E8C-F566FB669297}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{0074C983-550E-4094-9E8C-F566FB669297}.Release|x64.Build.0 = Release|x64
|
||||||
|
{0074C983-550E-4094-9E8C-F566FB669297}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
{0074C983-550E-4094-9E8C-F566FB669297}.Release|x86.Build.0 = Release|x86
|
||||||
|
{ED1C07A1-54F5-4796-8B06-2A0BB1960D84}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{ED1C07A1-54F5-4796-8B06-2A0BB1960D84}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{ED1C07A1-54F5-4796-8B06-2A0BB1960D84}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
||||||
|
{ED1C07A1-54F5-4796-8B06-2A0BB1960D84}.Debug|Mixed Platforms.Build.0 = Debug|x86
|
||||||
|
{ED1C07A1-54F5-4796-8B06-2A0BB1960D84}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{ED1C07A1-54F5-4796-8B06-2A0BB1960D84}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{ED1C07A1-54F5-4796-8B06-2A0BB1960D84}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{ED1C07A1-54F5-4796-8B06-2A0BB1960D84}.Debug|x86.Build.0 = Debug|x86
|
||||||
|
{ED1C07A1-54F5-4796-8B06-2A0BB1960D84}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{ED1C07A1-54F5-4796-8B06-2A0BB1960D84}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{ED1C07A1-54F5-4796-8B06-2A0BB1960D84}.Release|Mixed Platforms.ActiveCfg = Release|x86
|
||||||
|
{ED1C07A1-54F5-4796-8B06-2A0BB1960D84}.Release|Mixed Platforms.Build.0 = Release|x86
|
||||||
|
{ED1C07A1-54F5-4796-8B06-2A0BB1960D84}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{ED1C07A1-54F5-4796-8B06-2A0BB1960D84}.Release|x64.Build.0 = Release|x64
|
||||||
|
{ED1C07A1-54F5-4796-8B06-2A0BB1960D84}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
{ED1C07A1-54F5-4796-8B06-2A0BB1960D84}.Release|x86.Build.0 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
10
FeedCenterEntities.datasource
Normal 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>
|
||||||
10
FeedCenterEntities1.datasource
Normal 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>
|
||||||
10
FeedCenterEntities2.datasource
Normal 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>
|
||||||
BIN
FeedCenter_1_TemporaryKey.pfx
Normal file
BIN
FeedCenter_TemporaryKey.pfx
Normal file
112
FeedErrorWindow.xaml
Normal 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>
|
||||||
122
FeedErrorWindow.xaml.cs
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using FeedCenter.Options;
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
Feed feed = (Feed) e.Item;
|
||||||
|
|
||||||
|
e.Accepted = (feed.LastReadResult != (int) 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;
|
||||||
|
|
||||||
|
Feed feed = (Feed) feedDataGrid.SelectedItem;
|
||||||
|
|
||||||
|
FeedWindow feedWindow = new FeedWindow();
|
||||||
|
|
||||||
|
feedWindow.Display(_database, feed, GetWindow(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DeleteSelectedFeed()
|
||||||
|
{
|
||||||
|
Feed feed = (Feed) feedDataGrid.SelectedItem;
|
||||||
|
|
||||||
|
_database.Feeds.DeleteObject(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)
|
||||||
|
{
|
||||||
|
Feed feed = (Feed) feedDataGrid.SelectedItem;
|
||||||
|
BrowserCommon.OpenLink(feed.Link);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleOpenFeedButtonClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
Feed 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;
|
||||||
|
|
||||||
|
Feed feed = (Feed) feedDataGrid.SelectedItem;
|
||||||
|
feed.Read(_database, true);
|
||||||
|
|
||||||
|
_collectionViewSource.View.Refresh();
|
||||||
|
|
||||||
|
SetFeedButtonStates();
|
||||||
|
|
||||||
|
Mouse.OverrideCursor = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
138
FeedParsers/AtomParser.cs
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
using System.Xml;
|
||||||
|
|
||||||
|
using Common.Debug;
|
||||||
|
using Common.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
|
||||||
|
XmlDocument 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;
|
||||||
|
|
||||||
|
// Initialize the sequence number for items
|
||||||
|
int 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
|
||||||
|
FeedItem feedItem = new FeedItem();
|
||||||
|
|
||||||
|
// 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")
|
||||||
|
{
|
||||||
|
string 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
159
FeedParsers/FeedParserBase.cs
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Xml;
|
||||||
|
|
||||||
|
using Common.Debug;
|
||||||
|
|
||||||
|
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
|
||||||
|
XmlDocument 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
|
||||||
|
}
|
||||||
|
}
|
||||||
115
FeedParsers/RdfParser.cs
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
using System.Xml;
|
||||||
|
|
||||||
|
using Common.Debug;
|
||||||
|
using Common.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
|
||||||
|
XmlDocument 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 = new FeedItem();
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
122
FeedParsers/RssParser.cs
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
using System.Xml;
|
||||||
|
|
||||||
|
using Common.Debug;
|
||||||
|
using Common.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
|
||||||
|
XmlDocument 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 = new FeedItem();
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
26
Feeds/Category.cs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace FeedCenter
|
||||||
|
{
|
||||||
|
public partial class Category
|
||||||
|
{
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
public Category()
|
||||||
|
{
|
||||||
|
ID = Guid.NewGuid();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public bool IsDefault
|
||||||
|
{
|
||||||
|
get { return Name == "< default >"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public int SortKey
|
||||||
|
{
|
||||||
|
get { return IsDefault ? 0 : 1; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
342
Feeds/Feed.cs
Normal file
@@ -0,0 +1,342 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
using Common.Debug;
|
||||||
|
using Common.Extensions;
|
||||||
|
using Common.Xml;
|
||||||
|
using FeedCenter.Data;
|
||||||
|
using FeedCenter.FeedParsers;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace FeedCenter
|
||||||
|
{
|
||||||
|
#region Enumerations
|
||||||
|
|
||||||
|
public enum FeedType
|
||||||
|
{
|
||||||
|
Unknown,
|
||||||
|
Rss,
|
||||||
|
Rdf,
|
||||||
|
Atom
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum FeedItemComparison
|
||||||
|
{
|
||||||
|
Default,
|
||||||
|
Title
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum FeedReadResult
|
||||||
|
{
|
||||||
|
Success,
|
||||||
|
NotModified,
|
||||||
|
NotDue,
|
||||||
|
UnknownError,
|
||||||
|
InvalidXml,
|
||||||
|
NotEnabled,
|
||||||
|
Unauthorized,
|
||||||
|
NoResponse,
|
||||||
|
NotFound,
|
||||||
|
Timeout,
|
||||||
|
ConnectionFailed,
|
||||||
|
ServerError
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public partial class Feed
|
||||||
|
{
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
public Feed()
|
||||||
|
{
|
||||||
|
ID = Guid.NewGuid();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#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();
|
||||||
|
|
||||||
|
FeedReadResult 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 = (int) 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 == FeedCenter.Data.Extensions.SqlDateTimeZero.Value)
|
||||||
|
LastUpdated = DateTime.Now;
|
||||||
|
|
||||||
|
Tracer.DecrementIndentLevel();
|
||||||
|
Tracer.WriteLine("Done reading feed: {0}", result);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<Tuple<FeedReadResult, string>> RetrieveFeed()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Create the web request
|
||||||
|
WebRequest oRequest = WebRequest.Create(new Uri(Source));
|
||||||
|
|
||||||
|
// If this is an http request set some special properties
|
||||||
|
if (oRequest is HttpWebRequest)
|
||||||
|
{
|
||||||
|
// Cast the request
|
||||||
|
HttpWebRequest webRequest = (HttpWebRequest) oRequest;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
// 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
|
||||||
|
Encoding encoding = Encoding.UTF8;
|
||||||
|
|
||||||
|
// Attempt to get the response
|
||||||
|
var response = (HttpWebResponse) await oRequest.GetResponseAsync().WithTimeout(10000).ConfigureAwait(false);
|
||||||
|
|
||||||
|
// If there was no response assume it was a timeout of the async method
|
||||||
|
if (response == null)
|
||||||
|
return Tuple.Create(FeedReadResult.Timeout, string.Empty);
|
||||||
|
|
||||||
|
// If the response included an encoding then change the encoding
|
||||||
|
if (response.ContentEncoding.Length > 0)
|
||||||
|
encoding = Encoding.GetEncoding(response.ContentEncoding);
|
||||||
|
|
||||||
|
// Get the response stream
|
||||||
|
Stream 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
|
||||||
|
string feedText = textReader.ReadToEnd();
|
||||||
|
|
||||||
|
// Get rid of any leading and trailing whitespace
|
||||||
|
feedText = feedText.Trim();
|
||||||
|
|
||||||
|
// Clean up common invalid XML characters
|
||||||
|
feedText = feedText.Replace(" ", " ");
|
||||||
|
|
||||||
|
return Tuple.Create(FeedReadResult.Success, feedText);
|
||||||
|
}
|
||||||
|
catch (IOException ioException)
|
||||||
|
{
|
||||||
|
Tracer.WriteLine(ioException.Message);
|
||||||
|
|
||||||
|
return Tuple.Create(FeedReadResult.ConnectionFailed, string.Empty);
|
||||||
|
}
|
||||||
|
catch (WebException webException)
|
||||||
|
{
|
||||||
|
FeedReadResult result = FeedReadResult.UnknownError;
|
||||||
|
|
||||||
|
if (webException.Response is HttpWebResponse)
|
||||||
|
{
|
||||||
|
HttpWebResponse errorResponse = (HttpWebResponse) webException.Response;
|
||||||
|
|
||||||
|
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
|
||||||
|
{
|
||||||
|
string feedText;
|
||||||
|
|
||||||
|
// 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
|
||||||
|
TimeSpan 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();
|
||||||
|
|
||||||
|
// Wait on the result
|
||||||
|
retrieveResult.Wait();
|
||||||
|
|
||||||
|
// Get the information out of the async result
|
||||||
|
FeedReadResult result = retrieveResult.Result.Item1;
|
||||||
|
feedText = retrieveResult.Result.Item2;
|
||||||
|
|
||||||
|
// If we didn't successfully retrieve the feed then stop
|
||||||
|
if (result != FeedReadResult.Success)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
// Create a new RSS parser
|
||||||
|
FeedParserBase 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
|
||||||
|
List<FeedItem> 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 (FeedItem itemToRemove in removedItems)
|
||||||
|
{
|
||||||
|
// Delete the item from the database
|
||||||
|
database.FeedItems.DeleteObject(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 (FeedAction 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 = (FeedReadResult) LastReadResult;
|
||||||
|
|
||||||
|
// Build the name of the resource using the enum name and the value
|
||||||
|
string resourceName = string.Format("{0}_{1}", typeof(FeedReadResult).Name, lastReadResult);
|
||||||
|
|
||||||
|
// Try to get the value from the resources
|
||||||
|
string resourceValue = Properties.Resources.ResourceManager.GetString(resourceName);
|
||||||
|
|
||||||
|
// Return the value or just the enum value if not found
|
||||||
|
return resourceValue ?? lastReadResult.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
25
Feeds/FeedAction.cs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
74
Feeds/FeedItem.cs
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace FeedCenter
|
||||||
|
{
|
||||||
|
public partial class FeedItem
|
||||||
|
{
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
public FeedItem()
|
||||||
|
{
|
||||||
|
ID = System.Guid.NewGuid();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#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
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
Libraries/System.Data.SqlServerCe.Entity.dll
Normal file
BIN
Libraries/System.Data.SqlServerCe.dll
Normal 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>
|
||||||
BIN
Libraries/amd64/Microsoft.VC90.CRT/msvcr90.dll
Normal file
BIN
Libraries/amd64/sqlceca40.dll
Normal file
BIN
Libraries/amd64/sqlcecompact40.dll
Normal file
BIN
Libraries/amd64/sqlceer40EN.dll
Normal file
BIN
Libraries/amd64/sqlceme40.dll
Normal file
BIN
Libraries/amd64/sqlceqp40.dll
Normal file
BIN
Libraries/amd64/sqlcese40.dll
Normal 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>
|
||||||
BIN
Libraries/x86/Microsoft.VC90.CRT/msvcr90.dll
Normal file
BIN
Libraries/x86/sqlceca40.dll
Normal file
BIN
Libraries/x86/sqlcecompact40.dll
Normal file
BIN
Libraries/x86/sqlceer40EN.dll
Normal file
BIN
Libraries/x86/sqlceme40.dll
Normal file
BIN
Libraries/x86/sqlceqp40.dll
Normal file
BIN
Libraries/x86/sqlcese40.dll
Normal file
286
MainWindow.xaml
Normal 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>
|
||||||
1378
MainWindow.xaml.cs
Normal file
1535
Model.Designer.cs
generated
Normal file
378
Model.edmx
Normal file
@@ -0,0 +1,378 @@
|
|||||||
|
<?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" Alias="Self" Provider="System.Data.SqlServerCe.4.0" ProviderManifestToken="4.0" xmlns="http://schemas.microsoft.com/ado/2009/11/edm/ssdl">
|
||||||
|
<EntityContainer Name="FeedCenterModelStoreContainer">
|
||||||
|
<EntitySet Name="Category" EntityType="FeedCenterModel.Store.Category" store:Type="Tables" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" />
|
||||||
|
<EntitySet Name="Feed" EntityType="FeedCenterModel.Store.Feed" store:Type="Tables" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" />
|
||||||
|
<EntitySet Name="FeedAction" EntityType="FeedCenterModel.Store.FeedAction" store:Type="Tables" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" />
|
||||||
|
<EntitySet Name="FeedItem" EntityType="FeedCenterModel.Store.FeedItem" store:Type="Tables" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" />
|
||||||
|
<EntitySet Name="Setting" EntityType="FeedCenterModel.Store.Setting" store:Type="Tables" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" />
|
||||||
|
<AssociationSet Name="FK_Feed_Category" Association="FeedCenterModel.Store.FK_Feed_Category">
|
||||||
|
<End Role="Category" EntitySet="Category" />
|
||||||
|
<End Role="Feed" EntitySet="Feed" />
|
||||||
|
</AssociationSet>
|
||||||
|
<AssociationSet Name="FK_FeedAction_Feed" Association="FeedCenterModel.Store.FK_FeedAction_Feed">
|
||||||
|
<End Role="Feed" EntitySet="Feed" />
|
||||||
|
<End Role="FeedAction" EntitySet="FeedAction" />
|
||||||
|
</AssociationSet>
|
||||||
|
<AssociationSet Name="FK_FeedItem_Feed" Association="FeedCenterModel.Store.FK_FeedItem_Feed">
|
||||||
|
<End Role="Feed" EntitySet="Feed" />
|
||||||
|
<End Role="FeedItem" EntitySet="FeedItem" />
|
||||||
|
</AssociationSet>
|
||||||
|
</EntityContainer>
|
||||||
|
<EntityType Name="Category">
|
||||||
|
<Key>
|
||||||
|
<PropertyRef Name="ID" />
|
||||||
|
</Key>
|
||||||
|
<Property Name="ID" Type="uniqueidentifier" Nullable="false" />
|
||||||
|
<Property Name="Name" Type="nvarchar" Nullable="false" MaxLength="1000" />
|
||||||
|
</EntityType>
|
||||||
|
<EntityType Name="Feed">
|
||||||
|
<Key>
|
||||||
|
<PropertyRef Name="ID" />
|
||||||
|
</Key>
|
||||||
|
<Property Name="ID" Type="uniqueidentifier" Nullable="false" />
|
||||||
|
<Property Name="Name" Type="nvarchar" Nullable="false" MaxLength="1000" />
|
||||||
|
<Property Name="Title" Type="nvarchar" Nullable="false" MaxLength="1000" />
|
||||||
|
<Property Name="Source" Type="nvarchar" Nullable="false" MaxLength="1000" />
|
||||||
|
<Property Name="Link" Type="nvarchar" Nullable="false" MaxLength="1000" />
|
||||||
|
<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" Nullable="false" MaxLength="1000" />
|
||||||
|
<Property Name="Password" Type="nvarchar" Nullable="false" MaxLength="1000" />
|
||||||
|
<Property Name="Domain" Type="nvarchar" Nullable="false" MaxLength="1000" />
|
||||||
|
<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" Nullable="false" MaxLength="1000" />
|
||||||
|
<Property Name="Replace" Type="nvarchar" Nullable="false" MaxLength="1000" />
|
||||||
|
<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" Nullable="false" MaxLength="1000" />
|
||||||
|
<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" Nullable="false" MaxLength="1000" />
|
||||||
|
</EntityType>
|
||||||
|
<EntityType Name="Setting">
|
||||||
|
<Key>
|
||||||
|
<PropertyRef Name="Name" />
|
||||||
|
<PropertyRef Name="Version" />
|
||||||
|
</Key>
|
||||||
|
<Property Name="Name" Type="nvarchar" Nullable="false" MaxLength="500" />
|
||||||
|
<Property Name="Value" Type="nvarchar" Nullable="false" MaxLength="3500" />
|
||||||
|
<Property Name="Version" Type="nvarchar" Nullable="false" MaxLength="50" />
|
||||||
|
</EntityType>
|
||||||
|
<Association Name="FK_Feed_Category">
|
||||||
|
<End Role="Category" Type="FeedCenterModel.Store.Category" Multiplicity="1" />
|
||||||
|
<End Role="Feed" Type="FeedCenterModel.Store.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="FeedCenterModel.Store.Feed" Multiplicity="1">
|
||||||
|
<OnDelete Action="Cascade" />
|
||||||
|
</End>
|
||||||
|
<End Role="FeedAction" Type="FeedCenterModel.Store.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="FeedCenterModel.Store.Feed" Multiplicity="1">
|
||||||
|
<OnDelete Action="Cascade" />
|
||||||
|
</End>
|
||||||
|
<End Role="FeedItem" Type="FeedCenterModel.Store.FeedItem" Multiplicity="*" />
|
||||||
|
<ReferentialConstraint>
|
||||||
|
<Principal Role="Feed">
|
||||||
|
<PropertyRef Name="ID" />
|
||||||
|
</Principal>
|
||||||
|
<Dependent Role="FeedItem">
|
||||||
|
<PropertyRef Name="FeedID" />
|
||||||
|
</Dependent>
|
||||||
|
</ReferentialConstraint>
|
||||||
|
</Association>
|
||||||
|
</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" />
|
||||||
|
<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="Int32" Name="LastReadResult" Nullable="false" />
|
||||||
|
<Property Type="DateTime" Name="LastUpdated" Nullable="false" DefaultValue="1900-01-01 00:00:00.000Z" />
|
||||||
|
<Property Type="Byte" Name="ItemComparison" Nullable="false" DefaultValue="0" />
|
||||||
|
<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="Int32" Name="MultipleOpenAction" Nullable="false" DefaultValue="0" />
|
||||||
|
</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" />
|
||||||
|
<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>
|
||||||
|
</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" />
|
||||||
|
</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>
|
||||||
82
NotificationIcon.cs
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
using System.Windows.Forms;
|
||||||
|
|
||||||
|
using FeedCenter.Properties;
|
||||||
|
|
||||||
|
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
|
||||||
|
ContextMenuStrip contextMenuStrip = new ContextMenuStrip();
|
||||||
|
|
||||||
|
ToolStripMenuItem 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
24
Options/AboutOptionsPanel.xaml
Normal 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>
|
||||||
39
Options/AboutOptionsPanel.xaml.cs
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
using System.Deployment.Application;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace FeedCenter.Options
|
||||||
|
{
|
||||||
|
public partial class AboutOptionsPanel
|
||||||
|
{
|
||||||
|
public AboutOptionsPanel()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void LoadPanel(FeedCenterEntities database)
|
||||||
|
{
|
||||||
|
base.LoadPanel(database);
|
||||||
|
|
||||||
|
applicationNameLabel.Text = Properties.Resources.ApplicationDisplayName;
|
||||||
|
|
||||||
|
string version = (ApplicationDeployment.IsNetworkDeployed ? ApplicationDeployment.CurrentDeployment.CurrentVersion.ToString() : "0");
|
||||||
|
versionLabel.Text = string.Format(Properties.Resources.Version, version);
|
||||||
|
|
||||||
|
companyLabel.Text = ((AssemblyCompanyAttribute) Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false)[0]).Company;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool ValidatePanel()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SavePanel()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string CategoryName
|
||||||
|
{
|
||||||
|
get { return Properties.Resources.optionCategoryAbout; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
127
Options/BulkFeedWindow.xaml
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
<Window x:Class="FeedCenter.Options.BulkFeedWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
Title="{x:Static my:Resources.BulkFeedWindow}"
|
||||||
|
Height="300"
|
||||||
|
Width="500"
|
||||||
|
xmlns:my="clr-namespace:FeedCenter.Properties"
|
||||||
|
xmlns:Options="clr-namespace:FeedCenter.Options"
|
||||||
|
xmlns:LinkControl="clr-namespace:Common.Wpf.LinkControl;assembly=Common.Wpf"
|
||||||
|
WindowStartupLocation="CenterOwner"
|
||||||
|
Icon="/FeedCenter;component/Resources/Application.ico"
|
||||||
|
FocusManager.FocusedElement="{Binding ElementName=feedLinkFilterText}">
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Label Content="{x:Static my:Resources.FeedLinkFilterLabel}"
|
||||||
|
Name="feedLinkFilterLabel"
|
||||||
|
Margin="6"
|
||||||
|
Padding="0"
|
||||||
|
VerticalContentAlignment="Center"
|
||||||
|
Target="{Binding ElementName=feedLinkFilterText}" />
|
||||||
|
<TextBox Grid.Column="1"
|
||||||
|
Name="feedLinkFilterText"
|
||||||
|
Margin="6"
|
||||||
|
TextChanged="HandleFilterTextChanged" />
|
||||||
|
<Border Grid.Row="1"
|
||||||
|
Grid.ColumnSpan="2"
|
||||||
|
Margin="6"
|
||||||
|
BorderThickness="1"
|
||||||
|
BorderBrush="{DynamicResource {x:Static SystemColors.ActiveBorderBrushKey}}">
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<ScrollViewer ScrollViewer.VerticalScrollBarVisibility="Auto">
|
||||||
|
<ItemsControl Name="filteredFeedsList">
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<CheckBox Margin="2"
|
||||||
|
Content="{Binding Item.Name}"
|
||||||
|
IsChecked="{Binding IsChecked}" />
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
</ScrollViewer>
|
||||||
|
<Border Grid.Row="1"
|
||||||
|
BorderThickness="0,1,0,0"
|
||||||
|
BorderBrush="{DynamicResource {x:Static SystemColors.ActiveBorderBrushKey}}">
|
||||||
|
<StackPanel Orientation="Horizontal"
|
||||||
|
Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}">
|
||||||
|
<TextBlock Margin="2"
|
||||||
|
Text="{x:Static my:Resources.SelectLabel}">
|
||||||
|
</TextBlock>
|
||||||
|
<LinkControl:LinkControl Margin="2"
|
||||||
|
Click="HandleSelectAll"
|
||||||
|
Text="{x:Static my:Resources.SelectAllLabel}">
|
||||||
|
</LinkControl:LinkControl>
|
||||||
|
<LinkControl:LinkControl Margin="2"
|
||||||
|
Click="HandleSelectNone"
|
||||||
|
Text="{x:Static my:Resources.SelectNoneLabel}">
|
||||||
|
</LinkControl:LinkControl>
|
||||||
|
<LinkControl:LinkControl Margin="2"
|
||||||
|
Click="HandleSelectInvert"
|
||||||
|
Text="{x:Static my:Resources.SelectInvertLabel}">
|
||||||
|
</LinkControl:LinkControl>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
<Grid Grid.Row="2"
|
||||||
|
MouseRightButtonUp="HandleGridMouseRightButtonUp"
|
||||||
|
ToolTip="{x:Static my:Resources.EnableHint}">
|
||||||
|
<Label Content="{x:Static my:Resources.openLabel}"
|
||||||
|
Name="openLabel"
|
||||||
|
Padding="4,0,0,0"
|
||||||
|
Margin="6,8,6,6"
|
||||||
|
ToolTip="{x:Static my:Resources.DisableHint}"
|
||||||
|
IsEnabled="False" />
|
||||||
|
</Grid>
|
||||||
|
<Grid Grid.Column="1"
|
||||||
|
Grid.Row="2"
|
||||||
|
MouseRightButtonUp="HandleGridMouseRightButtonUp"
|
||||||
|
ToolTip="{x:Static my:Resources.EnableHint}">
|
||||||
|
<ComboBox Name="openComboBox"
|
||||||
|
VerticalContentAlignment="Center"
|
||||||
|
SelectedIndex="0"
|
||||||
|
Margin="6"
|
||||||
|
ToolTip="{x:Static my:Resources.DisableHint}"
|
||||||
|
IsEnabled="False">
|
||||||
|
<ComboBoxItem Content="{x:Static my:Resources.openAllMultipleToolbarButton}"
|
||||||
|
Tag="{x:Static Options:MultipleOpenAction.IndividualPages}" />
|
||||||
|
<ComboBoxItem Content="{x:Static my:Resources.openAllSingleToolbarButton}"
|
||||||
|
Tag="{x:Static Options:MultipleOpenAction.SinglePage}" />
|
||||||
|
</ComboBox>
|
||||||
|
</Grid>
|
||||||
|
<Button Content="{x:Static my:Resources.OkayButton}"
|
||||||
|
Height="23"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
IsDefault="True"
|
||||||
|
Margin="0,6,87,6"
|
||||||
|
Name="okButton"
|
||||||
|
VerticalAlignment="Bottom"
|
||||||
|
Width="75"
|
||||||
|
Grid.Column="1"
|
||||||
|
Grid.Row="3"
|
||||||
|
Click="HandleOkButtonClick" />
|
||||||
|
<Button Content="{x:Static my:Resources.CancelButton}"
|
||||||
|
Grid.Column="1"
|
||||||
|
Height="23"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
IsCancel="True"
|
||||||
|
Margin="0,6,6,6"
|
||||||
|
Name="cancelButton"
|
||||||
|
VerticalAlignment="Bottom"
|
||||||
|
Width="75"
|
||||||
|
Grid.Row="3" />
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
||||||
102
Options/BulkFeedWindow.xaml.cs
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
|
||||||
|
using Common.Wpf;
|
||||||
|
|
||||||
|
namespace FeedCenter.Options
|
||||||
|
{
|
||||||
|
public partial class BulkFeedWindow
|
||||||
|
{
|
||||||
|
private List<CheckedListItem<Feed>> _checkedListBoxItems;
|
||||||
|
private CollectionViewSource _collectionViewSource;
|
||||||
|
|
||||||
|
public BulkFeedWindow()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool? Display(Window window, FeedCenterEntities database)
|
||||||
|
{
|
||||||
|
_checkedListBoxItems = new List<CheckedListItem<Feed>>();
|
||||||
|
|
||||||
|
foreach (var feed in database.AllFeeds)
|
||||||
|
_checkedListBoxItems.Add(new CheckedListItem<Feed> { Item = feed });
|
||||||
|
|
||||||
|
_collectionViewSource = new CollectionViewSource { Source = _checkedListBoxItems };
|
||||||
|
_collectionViewSource.SortDescriptions.Add(new SortDescription("Item.Name", ListSortDirection.Ascending));
|
||||||
|
_collectionViewSource.Filter += HandleCollectionViewSourceFilter;
|
||||||
|
|
||||||
|
filteredFeedsList.ItemsSource = _collectionViewSource.View;
|
||||||
|
|
||||||
|
Owner = window;
|
||||||
|
|
||||||
|
return ShowDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleCollectionViewSourceFilter(object sender, FilterEventArgs e)
|
||||||
|
{
|
||||||
|
CheckedListItem<Feed> checkedListBoxItem = (CheckedListItem<Feed>) e.Item;
|
||||||
|
|
||||||
|
Feed feed = checkedListBoxItem.Item;
|
||||||
|
|
||||||
|
e.Accepted = feed.Link.Contains(feedLinkFilterText.Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleFilterTextChanged(object sender, TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
_collectionViewSource.View.Refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleOkButtonClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
foreach (var item in _checkedListBoxItems.Where(i => i.IsChecked))
|
||||||
|
{
|
||||||
|
if (openComboBox.IsEnabled)
|
||||||
|
item.Item.MultipleOpenAction = (int) ((ComboBoxItem) openComboBox.SelectedItem).Tag;
|
||||||
|
}
|
||||||
|
|
||||||
|
DialogResult = true;
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleSelectAll(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
foreach (var viewItem in _collectionViewSource.View)
|
||||||
|
{
|
||||||
|
var checkedListItem = (CheckedListItem<Feed>) viewItem;
|
||||||
|
|
||||||
|
checkedListItem.IsChecked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleSelectNone(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
foreach (var viewItem in _collectionViewSource.View)
|
||||||
|
{
|
||||||
|
var checkedListItem = (CheckedListItem<Feed>) viewItem;
|
||||||
|
|
||||||
|
checkedListItem.IsChecked = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleSelectInvert(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
foreach (var viewItem in _collectionViewSource.View)
|
||||||
|
{
|
||||||
|
var checkedListItem = (CheckedListItem<Feed>) viewItem;
|
||||||
|
|
||||||
|
checkedListItem.IsChecked = !checkedListItem.IsChecked;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleGridMouseRightButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
openLabel.IsEnabled = !openLabel.IsEnabled;
|
||||||
|
openComboBox.IsEnabled = !openComboBox.IsEnabled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
45
Options/CategoryWindow.xaml
Normal 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>
|
||||||
69
Options/CategoryWindow.xaml.cs
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
|
||||||
|
using Common.Wpf.Extensions;
|
||||||
|
|
||||||
|
namespace FeedCenter.Options
|
||||||
|
{
|
||||||
|
public partial class CategoryWindow
|
||||||
|
{
|
||||||
|
public CategoryWindow()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool? Display(Category category, Window owner)
|
||||||
|
{
|
||||||
|
// Set the data context
|
||||||
|
DataContext = category;
|
||||||
|
|
||||||
|
// Set the title based on the state of the category
|
||||||
|
Title = string.IsNullOrWhiteSpace(category.Name) ? Properties.Resources.CategoryWindowAdd : Properties.Resources.CategoryWindowEdit;
|
||||||
|
|
||||||
|
// Set the window owner
|
||||||
|
Owner = owner;
|
||||||
|
|
||||||
|
// Show the dialog and result the result
|
||||||
|
return ShowDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleOkayButtonClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
// Get a list of all explicit binding expressions
|
||||||
|
Dictionary<FrameworkElement, BindingExpression> bindingExpressionDictionary = this.GetExplicitBindingExpressions();
|
||||||
|
|
||||||
|
// Get the values as a list
|
||||||
|
List<BindingExpression> bindingExpressions = bindingExpressionDictionary.Values.ToList();
|
||||||
|
|
||||||
|
// Loop over each binding expression and clear any existing error
|
||||||
|
bindingExpressions.ForEach(Validation.ClearInvalid);
|
||||||
|
|
||||||
|
// Force all explicit bindings to update the source
|
||||||
|
bindingExpressions.ForEach(bindingExpression => bindingExpression.UpdateSource());
|
||||||
|
|
||||||
|
// See if there are any errors
|
||||||
|
bool hasError = bindingExpressions.Exists(bindingExpression => bindingExpression.HasError);
|
||||||
|
|
||||||
|
// If there was an error then set focus to the bad controls
|
||||||
|
if (hasError)
|
||||||
|
{
|
||||||
|
// Get the first framework element with an error
|
||||||
|
FrameworkElement firstErrorElement = bindingExpressionDictionary.First(pair => pair.Value.HasError).Key;
|
||||||
|
|
||||||
|
// Set focus
|
||||||
|
firstErrorElement.Focus();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dialog is good
|
||||||
|
DialogResult = true;
|
||||||
|
|
||||||
|
// Close the dialog
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
64
Options/DisplayOptionsPanel.xaml
Normal 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>
|
||||||
52
Options/DisplayOptionsPanel.xaml.cs
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
|
||||||
|
using FeedCenter.Properties;
|
||||||
|
|
||||||
|
namespace FeedCenter.Options
|
||||||
|
{
|
||||||
|
public partial class DisplayOptionsPanel
|
||||||
|
{
|
||||||
|
public DisplayOptionsPanel()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void LoadPanel(FeedCenterEntities database)
|
||||||
|
{
|
||||||
|
base.LoadPanel(database);
|
||||||
|
|
||||||
|
lockWindowCheckBox.IsChecked = Settings.Default.WindowLocked;
|
||||||
|
displayEmptyFeedsCheckBox.IsChecked = Settings.Default.DisplayEmptyFeeds;
|
||||||
|
toolbarLocationComboBox.SelectedItem = toolbarLocationComboBox.Items.Cast<ComboBoxItem>().First(comboBoxItem => (Dock) comboBoxItem.Tag == Settings.Default.ToolbarLocation);
|
||||||
|
multipleLineDisplayComboBox.SelectedItem = multipleLineDisplayComboBox.Items.Cast<ComboBoxItem>().First(comboBoxItem => (MultipleLineDisplay) comboBoxItem.Tag == Settings.Default.MultipleLineDisplay);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool ValidatePanel()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SavePanel()
|
||||||
|
{
|
||||||
|
if (lockWindowCheckBox.IsChecked.HasValue && Settings.Default.WindowLocked != lockWindowCheckBox.IsChecked.Value)
|
||||||
|
Settings.Default.WindowLocked = lockWindowCheckBox.IsChecked.Value;
|
||||||
|
|
||||||
|
if (displayEmptyFeedsCheckBox.IsChecked.HasValue && Settings.Default.DisplayEmptyFeeds != displayEmptyFeedsCheckBox.IsChecked.Value)
|
||||||
|
Settings.Default.DisplayEmptyFeeds = displayEmptyFeedsCheckBox.IsChecked.Value;
|
||||||
|
|
||||||
|
Dock dock = (Dock) ((ComboBoxItem) toolbarLocationComboBox.SelectedItem).Tag;
|
||||||
|
if (Settings.Default.ToolbarLocation != dock)
|
||||||
|
Settings.Default.ToolbarLocation = dock;
|
||||||
|
|
||||||
|
MultipleLineDisplay multipleLineDisplay = (MultipleLineDisplay) ((ComboBoxItem) multipleLineDisplayComboBox.SelectedItem).Tag;
|
||||||
|
if (Settings.Default.MultipleLineDisplay != multipleLineDisplay)
|
||||||
|
Settings.Default.MultipleLineDisplay = multipleLineDisplay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string CategoryName
|
||||||
|
{
|
||||||
|
get { return Properties.Resources.optionCategoryDisplay; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
195
Options/FeedWindow.xaml
Normal file
@@ -0,0 +1,195 @@
|
|||||||
|
<Window x:Class="FeedCenter.Options.FeedWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:Properties="clr-namespace:FeedCenter.Properties"
|
||||||
|
xmlns:Options="clr-namespace:FeedCenter.Options"
|
||||||
|
Title="FeedWindow"
|
||||||
|
Height="300"
|
||||||
|
Width="450"
|
||||||
|
WindowStartupLocation="CenterOwner"
|
||||||
|
Icon="/FeedCenter;component/Resources/Application.ico"
|
||||||
|
FocusManager.FocusedElement="{Binding ElementName=urlTextBox}">
|
||||||
|
<Window.Resources>
|
||||||
|
<Options:MultipleOpenActionConverter x:Key="multipleOpenActionConverter" />
|
||||||
|
</Window.Resources>
|
||||||
|
<Grid Name="mainGrid">
|
||||||
|
<TabControl Name="optionsTabControl"
|
||||||
|
Margin="12,12,12,41">
|
||||||
|
<TabItem Header="{x:Static Properties:Resources.generalTab}"
|
||||||
|
Name="generalTab">
|
||||||
|
<Grid Name="generalGrid">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Label Content="{x:Static Properties:Resources.feedUrlLabel}"
|
||||||
|
Name="urlLabel"
|
||||||
|
VerticalContentAlignment="Center"
|
||||||
|
Target="{Binding ElementName=urlTextBox}"
|
||||||
|
Margin="6"
|
||||||
|
Padding="0" />
|
||||||
|
<TextBox Name="urlTextBox"
|
||||||
|
Grid.Column="1"
|
||||||
|
Text="{Binding Path=Source, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}"
|
||||||
|
Margin="6" />
|
||||||
|
<Label Content="{x:Static Properties:Resources.feedNameLabel}"
|
||||||
|
Name="nameLabel"
|
||||||
|
VerticalContentAlignment="Center"
|
||||||
|
Target="{Binding ElementName=nameTextBox}"
|
||||||
|
Grid.Row="1"
|
||||||
|
Margin="6"
|
||||||
|
Padding="0" />
|
||||||
|
<TextBox Name="nameTextBox"
|
||||||
|
Grid.Column="1"
|
||||||
|
Text="{Binding Path=Name, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=true}"
|
||||||
|
Grid.Row="1"
|
||||||
|
Margin="6" />
|
||||||
|
<Label Content="{x:Static Properties:Resources.feedCategoryLabel}"
|
||||||
|
Name="feedCategoryLabel"
|
||||||
|
Target="{Binding ElementName=categoryComboBox}"
|
||||||
|
VerticalContentAlignment="Center"
|
||||||
|
Grid.Row="2"
|
||||||
|
Margin="6"
|
||||||
|
Padding="0" />
|
||||||
|
<ComboBox Grid.Column="1"
|
||||||
|
Name="categoryComboBox"
|
||||||
|
DisplayMemberPath="Name"
|
||||||
|
SelectedValuePath="ID"
|
||||||
|
SelectedValue="{Binding Path=CategoryID}"
|
||||||
|
Grid.Row="2"
|
||||||
|
Margin="6" />
|
||||||
|
|
||||||
|
<CheckBox Grid.ColumnSpan="2"
|
||||||
|
Name="readIntervalCheckBox"
|
||||||
|
VerticalContentAlignment="Center"
|
||||||
|
IsChecked="{Binding Path=Enabled, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}"
|
||||||
|
Grid.Row="3"
|
||||||
|
Margin="6">
|
||||||
|
<DockPanel>
|
||||||
|
<Label Content="{x:Static Properties:Resources.feedReadIntervalPrefix}"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
Margin="0,0,5,0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Padding="0" />
|
||||||
|
<TextBox Width="50"
|
||||||
|
Name="readIntervalTextBox"
|
||||||
|
Text="{Binding Path=CheckInterval, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}"
|
||||||
|
IsEnabled="{Binding ElementName=readIntervalCheckBox, Path=IsChecked}" />
|
||||||
|
<Label Content="{x:Static Properties:Resources.feedReadIntervalSuffix}"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
Margin="5,0,0,0"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Padding="0" />
|
||||||
|
</DockPanel>
|
||||||
|
</CheckBox>
|
||||||
|
</Grid>
|
||||||
|
</TabItem>
|
||||||
|
<TabItem Header="{x:Static Properties:Resources.readingTab}"
|
||||||
|
Name="readingTab">
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Label Content="{x:Static Properties:Resources.openLabel}"
|
||||||
|
Name="openLabel"
|
||||||
|
Target="{Binding ElementName=openComboBox}"
|
||||||
|
Padding="0"
|
||||||
|
VerticalContentAlignment="Center"
|
||||||
|
Margin="6" />
|
||||||
|
<ComboBox Name="openComboBox"
|
||||||
|
VerticalContentAlignment="Center"
|
||||||
|
SelectedValue="{Binding Path=MultipleOpenAction, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=true, Converter={StaticResource multipleOpenActionConverter}}"
|
||||||
|
SelectedValuePath="Tag"
|
||||||
|
Grid.Column="1"
|
||||||
|
Margin="6">
|
||||||
|
|
||||||
|
<ComboBoxItem Content="{x:Static Properties:Resources.openAllSingleToolbarButton}"
|
||||||
|
Tag="{x:Static Options:MultipleOpenAction.SinglePage}" />
|
||||||
|
<ComboBoxItem Content="{x:Static Properties:Resources.openAllMultipleToolbarButton}"
|
||||||
|
Tag="{x:Static Options:MultipleOpenAction.IndividualPages}" />
|
||||||
|
</ComboBox>
|
||||||
|
</Grid>
|
||||||
|
</TabItem>
|
||||||
|
<TabItem Header="{x:Static Properties:Resources.authenticationTab}"
|
||||||
|
Name="authenticationTab">
|
||||||
|
<Grid Name="authenticationGrid">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<CheckBox Content="{x:Static Properties:Resources.requiresAuthenticationCheckBox}"
|
||||||
|
Name="requiresAuthenticationCheckBox"
|
||||||
|
Grid.ColumnSpan="2"
|
||||||
|
Grid.Row="0"
|
||||||
|
Grid.Column="0"
|
||||||
|
IsChecked="{Binding Path=Authenticate, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}"
|
||||||
|
Margin="6" />
|
||||||
|
<Label Content="{x:Static Properties:Resources.authenticationUserNameLabel}"
|
||||||
|
Name="authenticationUserNameLabel"
|
||||||
|
Target="{Binding ElementName=authenticationUserNameTextBox}"
|
||||||
|
VerticalContentAlignment="Center"
|
||||||
|
IsEnabled="{Binding ElementName=requiresAuthenticationCheckBox, Path=IsChecked}"
|
||||||
|
Grid.Row="1"
|
||||||
|
Margin="6"
|
||||||
|
Padding="20,0,0,0" />
|
||||||
|
<TextBox Name="authenticationUserNameTextBox"
|
||||||
|
Text="{Binding Path=UserName, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}"
|
||||||
|
Grid.Column="1"
|
||||||
|
IsEnabled="{Binding ElementName=requiresAuthenticationCheckBox, Path=IsChecked}"
|
||||||
|
Grid.Row="1"
|
||||||
|
Margin="6" />
|
||||||
|
<Label Content="{x:Static Properties:Resources.authenticationPasswordLabel}"
|
||||||
|
Name="authenticationPasswordLabel"
|
||||||
|
Target="{Binding ElementName=authenticationPasswordTextBox}"
|
||||||
|
VerticalContentAlignment="Center"
|
||||||
|
IsEnabled="{Binding ElementName=requiresAuthenticationCheckBox, Path=IsChecked}"
|
||||||
|
Grid.Row="2"
|
||||||
|
Margin="6"
|
||||||
|
Padding="20,0,0,0" />
|
||||||
|
<TextBox Name="authenticationPasswordTextBox"
|
||||||
|
Text="{Binding Path=Password, UpdateSourceTrigger=Explicit, ValidatesOnExceptions=True}"
|
||||||
|
Grid.Column="1"
|
||||||
|
IsEnabled="{Binding ElementName=requiresAuthenticationCheckBox, Path=IsChecked}"
|
||||||
|
Grid.Row="2"
|
||||||
|
Margin="6" />
|
||||||
|
</Grid>
|
||||||
|
</TabItem>
|
||||||
|
</TabControl>
|
||||||
|
<Button Content="{x:Static Properties:Resources.OkayButton}"
|
||||||
|
Height="23"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
Name="okButton"
|
||||||
|
VerticalAlignment="Bottom"
|
||||||
|
Width="75"
|
||||||
|
IsDefault="True"
|
||||||
|
Margin="0,0,93,12"
|
||||||
|
Click="HandleOkayButtonClick" />
|
||||||
|
<Button Content="{x:Static Properties:Resources.CancelButton}"
|
||||||
|
Height="23"
|
||||||
|
HorizontalAlignment="Right"
|
||||||
|
Name="cancelButton"
|
||||||
|
VerticalAlignment="Bottom"
|
||||||
|
Width="75"
|
||||||
|
IsCancel="True"
|
||||||
|
Margin="0,0,12,12" />
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
||||||
88
Options/FeedWindow.xaml.cs
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Media;
|
||||||
|
|
||||||
|
using Common.Wpf.Extensions;
|
||||||
|
|
||||||
|
namespace FeedCenter.Options
|
||||||
|
{
|
||||||
|
public partial class FeedWindow
|
||||||
|
{
|
||||||
|
public FeedWindow()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool? Display(FeedCenterEntities database, Feed feed, Window owner)
|
||||||
|
{
|
||||||
|
// Bind the category combo box
|
||||||
|
categoryComboBox.ItemsSource = database.Categories;
|
||||||
|
|
||||||
|
// Set the data context
|
||||||
|
DataContext = feed;
|
||||||
|
|
||||||
|
// Set the title based on the state of the feed
|
||||||
|
Title = string.IsNullOrWhiteSpace(feed.Link) ? Properties.Resources.FeedWindowAdd : Properties.Resources.FeedWindowEdit;
|
||||||
|
|
||||||
|
// Set the window owner
|
||||||
|
Owner = owner;
|
||||||
|
|
||||||
|
// Show the dialog and result the result
|
||||||
|
return ShowDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleOkayButtonClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
// Get a dictionary of all framework elements and explicit binding expressions
|
||||||
|
Dictionary<FrameworkElement, BindingExpression> bindingExpressionDictionary = this.GetExplicitBindingExpressions();
|
||||||
|
|
||||||
|
// Get just the binding expressions
|
||||||
|
var bindingExpressions = bindingExpressionDictionary.Values;
|
||||||
|
|
||||||
|
// Loop over each binding expression and clear any existing error
|
||||||
|
this.ClearAllValidationErrors(bindingExpressions);
|
||||||
|
|
||||||
|
// Force all explicit bindings to update the source
|
||||||
|
this.UpdateAllSources(bindingExpressions);
|
||||||
|
|
||||||
|
// See if there are any errors
|
||||||
|
bool hasError = bindingExpressions.Any(b => b.HasError);
|
||||||
|
|
||||||
|
// If there was an error then set focus to the bad controls
|
||||||
|
if (hasError)
|
||||||
|
{
|
||||||
|
// Get the first framework element with an error
|
||||||
|
FrameworkElement firstErrorElement = bindingExpressionDictionary.First(pair => pair.Value.HasError).Key;
|
||||||
|
|
||||||
|
// Loop over each tab item
|
||||||
|
foreach (TabItem tabItem in optionsTabControl.Items)
|
||||||
|
{
|
||||||
|
// Cast the content as visual
|
||||||
|
Visual content = (Visual) tabItem.Content;
|
||||||
|
|
||||||
|
// See if the control with the error is a descendant
|
||||||
|
if (firstErrorElement.IsDescendantOf(content))
|
||||||
|
{
|
||||||
|
// Select the tab
|
||||||
|
tabItem.IsSelected = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set focus
|
||||||
|
firstErrorElement.Focus();
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dialog is good
|
||||||
|
DialogResult = true;
|
||||||
|
|
||||||
|
// Close the dialog
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
161
Options/FeedsOptionsPanel.xaml
Normal 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>
|
||||||
433
Options/FeedsOptionsPanel.xaml.cs
Normal file
@@ -0,0 +1,433 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Xml;
|
||||||
|
using Microsoft.Win32;
|
||||||
|
|
||||||
|
namespace FeedCenter.Options
|
||||||
|
{
|
||||||
|
public partial class FeedsOptionsPanel
|
||||||
|
{
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
public FeedsOptionsPanel()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region OptionsPanelBase overrides
|
||||||
|
|
||||||
|
public override void LoadPanel(FeedCenterEntities database)
|
||||||
|
{
|
||||||
|
base.LoadPanel(database);
|
||||||
|
|
||||||
|
CollectionViewSource collectionViewSource = new CollectionViewSource { Source = Database.AllCategories };
|
||||||
|
collectionViewSource.SortDescriptions.Add(new SortDescription("SortKey", ListSortDirection.Ascending));
|
||||||
|
collectionViewSource.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
|
||||||
|
|
||||||
|
categoryListBox.ItemsSource = collectionViewSource.View;
|
||||||
|
categoryListBox.SelectedIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool ValidatePanel()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SavePanel()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
public override string CategoryName
|
||||||
|
{
|
||||||
|
get { return Properties.Resources.optionCategoryFeeds; }
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Feed list management
|
||||||
|
|
||||||
|
private void SetFeedButtonStates()
|
||||||
|
{
|
||||||
|
addFeedButton.IsEnabled = true;
|
||||||
|
editFeedButton.IsEnabled = (feedListBox.SelectedItem != null);
|
||||||
|
deleteFeedButton.IsEnabled = (feedListBox.SelectedItem != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddFeed()
|
||||||
|
{
|
||||||
|
Feed feed = new Feed();
|
||||||
|
|
||||||
|
FeedWindow feedWindow = new FeedWindow();
|
||||||
|
|
||||||
|
bool? result = feedWindow.Display(Database, feed, Window.GetWindow(this));
|
||||||
|
|
||||||
|
if (result.HasValue && result.Value)
|
||||||
|
{
|
||||||
|
Database.Feeds.AddObject(feed);
|
||||||
|
|
||||||
|
feedListBox.SelectedItem = feed;
|
||||||
|
|
||||||
|
SetFeedButtonStates();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EditSelectedFeed()
|
||||||
|
{
|
||||||
|
if (feedListBox.SelectedItem == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Feed feed = (Feed) feedListBox.SelectedItem;
|
||||||
|
|
||||||
|
FeedWindow feedWindow = new FeedWindow();
|
||||||
|
|
||||||
|
feedWindow.Display(Database, feed, Window.GetWindow(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DeleteSelectedFeed()
|
||||||
|
{
|
||||||
|
Feed feed = (Feed) feedListBox.SelectedItem;
|
||||||
|
|
||||||
|
Database.Feeds.DeleteObject(feed);
|
||||||
|
|
||||||
|
SetFeedButtonStates();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Feed event handlers
|
||||||
|
|
||||||
|
private void HandleAddFeedButtonClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
AddFeed();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleEditFeedButtonClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
EditSelectedFeed();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleDeleteFeedButtonClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
DeleteSelectedFeed();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleImportButtonClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
ImportFeeds();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleExportButtonClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
ExportFeeds();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Feed import and export
|
||||||
|
|
||||||
|
private void ExportFeeds()
|
||||||
|
{
|
||||||
|
// Setup the save file dialog
|
||||||
|
SaveFileDialog saveFileDialog = new SaveFileDialog
|
||||||
|
{
|
||||||
|
Filter = Properties.Resources.ImportExportFilter,
|
||||||
|
FilterIndex = 0,
|
||||||
|
OverwritePrompt = true
|
||||||
|
};
|
||||||
|
|
||||||
|
bool? result = saveFileDialog.ShowDialog();
|
||||||
|
|
||||||
|
if (!result.Value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Setup the writer settings
|
||||||
|
XmlWriterSettings writerSettings = new XmlWriterSettings
|
||||||
|
{
|
||||||
|
Indent = true,
|
||||||
|
CheckCharacters = true,
|
||||||
|
ConformanceLevel = ConformanceLevel.Document
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create an XML writer for the file chosen
|
||||||
|
XmlWriter xmlWriter = XmlWriter.Create(saveFileDialog.FileName, writerSettings);
|
||||||
|
|
||||||
|
// Start the opml element
|
||||||
|
xmlWriter.WriteStartElement("opml");
|
||||||
|
|
||||||
|
// Start the body element
|
||||||
|
xmlWriter.WriteStartElement("body");
|
||||||
|
|
||||||
|
// Loop over each feed
|
||||||
|
foreach (Feed feed in Database.Feeds.OrderBy(feed => feed.Name))
|
||||||
|
{
|
||||||
|
// Start the outline element
|
||||||
|
xmlWriter.WriteStartElement("outline");
|
||||||
|
|
||||||
|
// Write the title
|
||||||
|
xmlWriter.WriteAttributeString("title", feed.Title);
|
||||||
|
|
||||||
|
// Write the HTML link
|
||||||
|
xmlWriter.WriteAttributeString("htmlUrl", feed.Link);
|
||||||
|
|
||||||
|
// Write the XML link
|
||||||
|
xmlWriter.WriteAttributeString("xmlUrl", feed.Source);
|
||||||
|
|
||||||
|
// End the outline element
|
||||||
|
xmlWriter.WriteEndElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
// End the body element
|
||||||
|
xmlWriter.WriteEndElement();
|
||||||
|
|
||||||
|
// End the opml element
|
||||||
|
xmlWriter.WriteEndElement();
|
||||||
|
|
||||||
|
// Flush and close the writer
|
||||||
|
xmlWriter.Flush();
|
||||||
|
xmlWriter.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ImportFeeds()
|
||||||
|
{
|
||||||
|
// Setup the open file dialog
|
||||||
|
OpenFileDialog openFileDialog = new OpenFileDialog
|
||||||
|
{
|
||||||
|
Filter = Properties.Resources.ImportExportFilter,
|
||||||
|
FilterIndex = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
bool? result = openFileDialog.ShowDialog();
|
||||||
|
|
||||||
|
if (!result.Value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Setup the reader settings
|
||||||
|
XmlReaderSettings xmlReaderSettings = new XmlReaderSettings { IgnoreWhitespace = true };
|
||||||
|
|
||||||
|
// Create an XML reader for the file chosen
|
||||||
|
XmlReader xmlReader = XmlReader.Create(openFileDialog.FileName, xmlReaderSettings);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Read the first node
|
||||||
|
xmlReader.Read();
|
||||||
|
|
||||||
|
// Read the OPML node
|
||||||
|
xmlReader.ReadStartElement("opml");
|
||||||
|
|
||||||
|
// Read the body node
|
||||||
|
xmlReader.ReadStartElement("body");
|
||||||
|
|
||||||
|
// Read all outline nodes
|
||||||
|
while (xmlReader.NodeType != XmlNodeType.EndElement)
|
||||||
|
{
|
||||||
|
// Create a new feed
|
||||||
|
Feed feed = new Feed { Category = Database.Categories.ToList().First(c => c.IsDefault) };
|
||||||
|
|
||||||
|
// Loop over all attributes
|
||||||
|
while (xmlReader.MoveToNextAttribute())
|
||||||
|
{
|
||||||
|
// Handle the attibute
|
||||||
|
switch (xmlReader.Name.ToLower())
|
||||||
|
{
|
||||||
|
case "title":
|
||||||
|
feed.Title = xmlReader.Value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "htmlurl":
|
||||||
|
feed.Link = xmlReader.Value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "xmlurl":
|
||||||
|
feed.Source = xmlReader.Value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "text":
|
||||||
|
feed.Name = xmlReader.Value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill in defaults for optional fields
|
||||||
|
if (string.IsNullOrEmpty(feed.Name))
|
||||||
|
feed.Name = feed.Title;
|
||||||
|
|
||||||
|
// Add the feed to the main list
|
||||||
|
Database.Feeds.AddObject(feed);
|
||||||
|
|
||||||
|
// Move back to the element node
|
||||||
|
xmlReader.MoveToElement();
|
||||||
|
|
||||||
|
// Skip to the next node
|
||||||
|
xmlReader.Skip();
|
||||||
|
}
|
||||||
|
|
||||||
|
// End the body node
|
||||||
|
xmlReader.ReadEndElement();
|
||||||
|
|
||||||
|
// End the OPML node
|
||||||
|
xmlReader.ReadEndElement();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
xmlReader.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Category list management
|
||||||
|
|
||||||
|
private void SetCategoryButtonStates()
|
||||||
|
{
|
||||||
|
addCategoryButton.IsEnabled = true;
|
||||||
|
editCategoryButton.IsEnabled = (categoryListBox.SelectedItem != null);
|
||||||
|
deleteCategoryButton.IsEnabled = (categoryListBox.SelectedItem != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddCategory()
|
||||||
|
{
|
||||||
|
Category category = new Category();
|
||||||
|
|
||||||
|
CategoryWindow categoryWindow = new CategoryWindow();
|
||||||
|
|
||||||
|
bool? result = categoryWindow.Display(category, Window.GetWindow(this));
|
||||||
|
|
||||||
|
if (result.HasValue && result.Value)
|
||||||
|
{
|
||||||
|
Database.Categories.AddObject(category);
|
||||||
|
|
||||||
|
categoryListBox.SelectedItem = category;
|
||||||
|
|
||||||
|
SetCategoryButtonStates();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EditSelectedCategory()
|
||||||
|
{
|
||||||
|
if (categoryListBox.SelectedItem == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Category category = (Category) categoryListBox.SelectedItem;
|
||||||
|
|
||||||
|
CategoryWindow categoryWindow = new CategoryWindow();
|
||||||
|
|
||||||
|
categoryWindow.Display(category, Window.GetWindow(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DeleteSelectedCategory()
|
||||||
|
{
|
||||||
|
Category category = (Category) categoryListBox.SelectedItem;
|
||||||
|
|
||||||
|
Database.Categories.DeleteObject(category);
|
||||||
|
|
||||||
|
SetCategoryButtonStates();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Category event handlers
|
||||||
|
|
||||||
|
private void HandleAddCategoryButtonClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
AddCategory();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleEditCategoryButtonClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
EditSelectedCategory();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleDeleteCategoryButtonClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
DeleteSelectedCategory();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private CollectionViewSource _collectionViewSource;
|
||||||
|
|
||||||
|
private void HandleCategoryListBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (_collectionViewSource == null)
|
||||||
|
{
|
||||||
|
_collectionViewSource = new CollectionViewSource {Source = Database.AllFeeds};
|
||||||
|
_collectionViewSource.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
|
||||||
|
_collectionViewSource.Filter += HandleCollectionViewSourceFilter;
|
||||||
|
|
||||||
|
feedListBox.ItemsSource = _collectionViewSource.View;
|
||||||
|
}
|
||||||
|
|
||||||
|
_collectionViewSource.View.Refresh();
|
||||||
|
|
||||||
|
if (feedListBox.Items.Count > 0)
|
||||||
|
feedListBox.SelectedIndex = 0;
|
||||||
|
|
||||||
|
SetFeedButtonStates();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleCollectionViewSourceFilter(object sender, FilterEventArgs e)
|
||||||
|
{
|
||||||
|
Category selectedCategory = (Category) categoryListBox.SelectedItem;
|
||||||
|
|
||||||
|
Feed feed = (Feed) e.Item;
|
||||||
|
|
||||||
|
e.Accepted = (feed.Category == selectedCategory);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleTextBlockDrop(object sender, DragEventArgs e)
|
||||||
|
{
|
||||||
|
List<Feed> feedList = (List<Feed>) e.Data.GetData(typeof(List<Feed>));
|
||||||
|
|
||||||
|
Category category = (Category) ((DataGridRow) sender).Item;
|
||||||
|
|
||||||
|
foreach (Feed feed in feedList)
|
||||||
|
feed.Category = category;
|
||||||
|
|
||||||
|
_collectionViewSource.View.Refresh();
|
||||||
|
|
||||||
|
//textBlock.TextDecorations = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleListBoxItemPreviewMouseMove(object sender, MouseEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.LeftButton == MouseButtonState.Pressed)
|
||||||
|
{
|
||||||
|
List<Feed> selectedItems = feedListBox.SelectedItems.Cast<Feed>().ToList();
|
||||||
|
|
||||||
|
DragDrop.DoDragDrop(feedListBox, selectedItems, DragDropEffects.Move);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleTextBlockDragEnter(object sender, DragEventArgs e)
|
||||||
|
{
|
||||||
|
DataGridRow dataGridRow = (DataGridRow) sender;
|
||||||
|
|
||||||
|
dataGridRow.FontWeight = FontWeights.Bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleTextBlockDragLeave(object sender, DragEventArgs e)
|
||||||
|
{
|
||||||
|
DataGridRow dataGridRow = (DataGridRow) sender;
|
||||||
|
|
||||||
|
dataGridRow.FontWeight = FontWeights.Normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleListBoxItemMouseDoubleClick(object sender, MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
EditSelectedFeed();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleMultipleEditClick(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
BulkFeedWindow bulkFeedWindow = new BulkFeedWindow();
|
||||||
|
bulkFeedWindow.Display(Window.GetWindow(this), Database);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
21
Options/GeneralOptionsPanel.xaml
Normal 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>
|
||||||
44
Options/GeneralOptionsPanel.xaml.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
namespace FeedCenter.Options
|
||||||
|
{
|
||||||
|
public partial class GeneralOptionsPanel
|
||||||
|
{
|
||||||
|
public GeneralOptionsPanel()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void LoadPanel(FeedCenterEntities database)
|
||||||
|
{
|
||||||
|
base.LoadPanel(database);
|
||||||
|
|
||||||
|
var settings = Properties.Settings.Default;
|
||||||
|
|
||||||
|
startWithWindowsCheckBox.IsChecked = settings.StartWithWindows;
|
||||||
|
registerAsDefaultFeedReaderCheckBox.IsChecked = settings.RegisterAsDefaultFeedReader;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool ValidatePanel()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SavePanel()
|
||||||
|
{
|
||||||
|
var settings = Properties.Settings.Default;
|
||||||
|
|
||||||
|
if (startWithWindowsCheckBox.IsChecked.HasValue && settings.StartWithWindows != startWithWindowsCheckBox.IsChecked.Value)
|
||||||
|
settings.StartWithWindows = startWithWindowsCheckBox.IsChecked.Value;
|
||||||
|
|
||||||
|
if (registerAsDefaultFeedReaderCheckBox.IsChecked.HasValue && settings.RegisterAsDefaultFeedReader != registerAsDefaultFeedReaderCheckBox.IsChecked.Value)
|
||||||
|
settings.RegisterAsDefaultFeedReader = registerAsDefaultFeedReaderCheckBox.IsChecked.Value;
|
||||||
|
|
||||||
|
App.SetStartWithWindows(settings.StartWithWindows);
|
||||||
|
App.SetDefaultFeedReader(settings.RegisterAsDefaultFeedReader);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string CategoryName
|
||||||
|
{
|
||||||
|
get { return Properties.Resources.optionCategoryGeneral; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
33
Options/Options.cs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Windows.Data;
|
||||||
|
|
||||||
|
namespace FeedCenter.Options
|
||||||
|
{
|
||||||
|
public enum MultipleLineDisplay
|
||||||
|
{
|
||||||
|
Normal,
|
||||||
|
SingleLine,
|
||||||
|
FirstLine
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum MultipleOpenAction
|
||||||
|
{
|
||||||
|
IndividualPages,
|
||||||
|
SinglePage
|
||||||
|
}
|
||||||
|
|
||||||
|
[ValueConversion(typeof(int), typeof(MultipleOpenAction))]
|
||||||
|
public class MultipleOpenActionConverter : IValueConverter
|
||||||
|
{
|
||||||
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
return (MultipleOpenAction) value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
return (int) value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
30
Options/OptionsPanelBase.cs
Normal 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; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
38
Options/OptionsWindow.xaml
Normal 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>
|
||||||
127
Options/OptionsWindow.xaml.cs
Normal 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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
34
Options/ReadingOptionsPanel.xaml
Normal 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>
|
||||||
66
Options/ReadingOptionsPanel.xaml.cs
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
using System.Windows.Controls;
|
||||||
|
|
||||||
|
using Common.Internet;
|
||||||
|
using Common.Wpf.Extensions;
|
||||||
|
|
||||||
|
namespace FeedCenter.Options
|
||||||
|
{
|
||||||
|
public partial class ReadingOptionsPanel
|
||||||
|
{
|
||||||
|
public ReadingOptionsPanel()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void LoadPanel(FeedCenterEntities database)
|
||||||
|
{
|
||||||
|
base.LoadPanel(database);
|
||||||
|
|
||||||
|
var settings = Properties.Settings.Default;
|
||||||
|
|
||||||
|
LoadBrowserComboBox(browserComboBox, settings.Browser);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool ValidatePanel()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void SavePanel()
|
||||||
|
{
|
||||||
|
var settings = Properties.Settings.Default;
|
||||||
|
|
||||||
|
string browser = (string) ((ComboBoxItem) browserComboBox.SelectedItem).Tag;
|
||||||
|
if (settings.Browser != browser)
|
||||||
|
settings.Browser = browser;
|
||||||
|
|
||||||
|
this.UpdateAllSources();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string CategoryName
|
||||||
|
{
|
||||||
|
get { return Properties.Resources.optionCategoryReading; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void LoadBrowserComboBox(ComboBox comboBox, string selected)
|
||||||
|
{
|
||||||
|
comboBox.SelectedIndex = 0;
|
||||||
|
|
||||||
|
ComboBoxItem selectedItem = null;
|
||||||
|
|
||||||
|
var browsers = Browser.DetectInstalledBrowsers();
|
||||||
|
foreach (var browser in browsers)
|
||||||
|
{
|
||||||
|
ComboBoxItem item = new ComboBoxItem { Content = browser.Value.Name, Tag = browser.Key };
|
||||||
|
|
||||||
|
comboBox.Items.Add(item);
|
||||||
|
|
||||||
|
if (browser.Key == selected)
|
||||||
|
selectedItem = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedItem != null)
|
||||||
|
comboBox.SelectedItem = selectedItem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
Options/UpdateOptionsPanel.xaml
Normal 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>
|
||||||
38
Options/UpdateOptionsPanel.xaml.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
53
Properties/AssemblyInfo.cs
Normal 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")]
|
||||||
10
Properties/DataSources/FeedCenterEntities.datasource
Normal 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>
|
||||||
1403
Properties/Resources.Designer.cs
generated
Normal file
530
Properties/Resources.resx
Normal 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>< no title ></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>
|
||||||
276
Properties/Settings.Designer.cs
generated
Normal file
@@ -0,0 +1,276 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
// Runtime Version:4.0.30319.18213
|
||||||
|
//
|
||||||
|
// 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", "11.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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
69
Properties/Settings.settings
Normal 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>
|
||||||
47
Properties/app.manifest
Normal 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>
|
||||||
BIN
Resources/Application.ico
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
Resources/Comments-edit.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Resources/Compile.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Resources/Left.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Resources/News.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Resources/Right.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Resources/Rss-Download.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
Resources/Warning.ico
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
85
Scripts/CreateDatabase.sqlce
Normal 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
|
||||||
18
Scripts/DatabaseUpdate_1.sqlce
Normal 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
|
||||||
30
Scripts/DatabaseUpdate_2.sqlce
Normal 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
|
||||||
9
Scripts/DatabaseUpdate_3.sqlce
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
UPDATE Category
|
||||||
|
SET Name = '< default >'
|
||||||
|
WHERE Name = 'Default'
|
||||||
|
GO
|
||||||
|
|
||||||
|
UPDATE Setting
|
||||||
|
SET Value = '4'
|
||||||
|
WHERE Name = 'DatabaseVersion'
|
||||||
|
GO
|
||||||
8
Scripts/DatabaseUpdate_4.sqlce
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
ALTER TABLE Feed
|
||||||
|
DROP COLUMN Sequence
|
||||||
|
GO
|
||||||
|
|
||||||
|
UPDATE Setting
|
||||||
|
SET Value = '5'
|
||||||
|
WHERE Name = 'DatabaseVersion'
|
||||||
|
GO
|
||||||
18
Scripts/DatabaseUpdate_5.sqlce
Normal 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
|
||||||
14
Scripts/DatabaseUpdate_6.sqlce
Normal 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
|
||||||
89
SettingsStore.cs
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace FeedCenter
|
||||||
|
{
|
||||||
|
public static class SettingsStore
|
||||||
|
{
|
||||||
|
public static object OpenDataStore()
|
||||||
|
{
|
||||||
|
FeedCenterEntities entities = new FeedCenterEntities();
|
||||||
|
|
||||||
|
return entities.DatabaseExists() ? entities : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void CloseDataStore(object dataStore)
|
||||||
|
{
|
||||||
|
FeedCenterEntities entities = (FeedCenterEntities) dataStore;
|
||||||
|
|
||||||
|
if (entities == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
entities.SaveChanges();
|
||||||
|
|
||||||
|
entities.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetSettingValue(object dataStore, string name, string version)
|
||||||
|
{
|
||||||
|
FeedCenterEntities entities = (FeedCenterEntities) dataStore;
|
||||||
|
|
||||||
|
if (entities == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
Setting setting = entities.Settings.FirstOrDefault(s => s.Name == name && s.Version == version);
|
||||||
|
|
||||||
|
return setting == null ? null : setting.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetSettingValue(object dataStore, string name, string version, string value)
|
||||||
|
{
|
||||||
|
FeedCenterEntities entities = (FeedCenterEntities) dataStore;
|
||||||
|
|
||||||
|
if (entities == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Try to get the setting from the database that matches the name and version
|
||||||
|
Setting setting = entities.Settings.FirstOrDefault(s => s.Name == name && s.Version == version);
|
||||||
|
|
||||||
|
// If there was no setting we need to create it
|
||||||
|
if (setting == null)
|
||||||
|
{
|
||||||
|
// Create the new setting
|
||||||
|
setting = new Setting { Name = name, Version = version };
|
||||||
|
|
||||||
|
// Add the setting to the database
|
||||||
|
entities.Settings.AddObject(setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the value into the setting
|
||||||
|
setting.Value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<string> GetVersionList(object dataStore)
|
||||||
|
{
|
||||||
|
FeedCenterEntities entities = (FeedCenterEntities) dataStore;
|
||||||
|
|
||||||
|
if (entities == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return (from setting in entities.Settings
|
||||||
|
select setting.Version).Distinct().ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DeleteSettingsForVersion(object dataStore, string version)
|
||||||
|
{
|
||||||
|
FeedCenterEntities entities = (FeedCenterEntities) dataStore;
|
||||||
|
|
||||||
|
if (entities == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Get all the settings for the current version number
|
||||||
|
var settings = entities.Settings.Where(setting => setting.Version == version);
|
||||||
|
|
||||||
|
// Delete each setting
|
||||||
|
foreach (Setting setting in settings)
|
||||||
|
entities.Settings.DeleteObject(setting);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
53
SplashWindow.xaml
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
<Window x:Class="FeedCenter.SplashWindow"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:Properties="clr-namespace:FeedCenter.Properties"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
Title="Splash"
|
||||||
|
WindowStartupLocation="CenterScreen"
|
||||||
|
WindowStyle="None"
|
||||||
|
AllowsTransparency="True"
|
||||||
|
Background="Transparent"
|
||||||
|
ResizeMode="NoResize"
|
||||||
|
Height="150"
|
||||||
|
Width="270"
|
||||||
|
SizeToContent="Height"
|
||||||
|
ShowInTaskbar="False">
|
||||||
|
<Border BorderThickness="2"
|
||||||
|
CornerRadius="10"
|
||||||
|
Background="{x:Static SystemColors.GradientActiveCaptionBrush}"
|
||||||
|
BorderBrush="{x:Static SystemColors.ActiveBorderBrush}"
|
||||||
|
Padding="3">
|
||||||
|
<DockPanel LastChildFill="True">
|
||||||
|
<Label Content="{x:Static Properties:Resources.ApplicationDisplayName}"
|
||||||
|
Padding="0"
|
||||||
|
Name="lblApplicationName"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
FontSize="20"
|
||||||
|
FontWeight="Bold"
|
||||||
|
HorizontalContentAlignment="Center"
|
||||||
|
VerticalContentAlignment="Center"
|
||||||
|
DockPanel.Dock="Top" />
|
||||||
|
<Label Content="*Version"
|
||||||
|
Padding="0,3,0,0"
|
||||||
|
Name="lblVersion"
|
||||||
|
HorizontalContentAlignment="Center"
|
||||||
|
VerticalContentAlignment="Center"
|
||||||
|
DockPanel.Dock="Top" />
|
||||||
|
<ProgressBar Name="progressBar"
|
||||||
|
VerticalAlignment="Bottom"
|
||||||
|
Height="16"
|
||||||
|
DockPanel.Dock="Bottom"
|
||||||
|
Margin="5,0,5,5" />
|
||||||
|
<Label Content="*Status"
|
||||||
|
Height="35"
|
||||||
|
Name="lblStatus"
|
||||||
|
DockPanel.Dock="Bottom"
|
||||||
|
VerticalContentAlignment="Bottom"
|
||||||
|
Margin="5,0,5,0"
|
||||||
|
Padding="1,0,0,2"/>
|
||||||
|
</DockPanel>
|
||||||
|
</Border>
|
||||||
|
</Window>
|
||||||
286
SplashWindow.xaml.cs
Normal file
@@ -0,0 +1,286 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Deployment.Application;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Threading;
|
||||||
|
|
||||||
|
using Common.Debug;
|
||||||
|
using FeedCenter.Data;
|
||||||
|
using FeedCenter.Properties;
|
||||||
|
|
||||||
|
namespace FeedCenter
|
||||||
|
{
|
||||||
|
public partial class SplashWindow
|
||||||
|
{
|
||||||
|
#region Progress step
|
||||||
|
|
||||||
|
private class ProgressStep
|
||||||
|
{
|
||||||
|
public delegate bool ProgressCallback();
|
||||||
|
|
||||||
|
public readonly string Key;
|
||||||
|
public readonly string Caption;
|
||||||
|
public readonly ProgressCallback Callback;
|
||||||
|
|
||||||
|
public ProgressStep(string key, string caption, ProgressCallback callback)
|
||||||
|
{
|
||||||
|
Key = key;
|
||||||
|
Caption = caption;
|
||||||
|
Callback = callback;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Member variables
|
||||||
|
|
||||||
|
private readonly List<ProgressStep> _progressSteps = new List<ProgressStep>();
|
||||||
|
private readonly Dispatcher _dispatcher;
|
||||||
|
private readonly BackgroundWorker _backgroundWorker;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructor
|
||||||
|
|
||||||
|
public SplashWindow()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
// Store the dispatcher - the background worker has trouble getting the right thread when called from Main
|
||||||
|
_dispatcher = Dispatcher.CurrentDispatcher;
|
||||||
|
|
||||||
|
// Get the version to display
|
||||||
|
string version = (ApplicationDeployment.IsNetworkDeployed ? ApplicationDeployment.CurrentDeployment.CurrentVersion.ToString() : "0");
|
||||||
|
|
||||||
|
// Show the version
|
||||||
|
lblVersion.Content = string.Format(Properties.Resources.Version, version);
|
||||||
|
|
||||||
|
// Set the starting caption
|
||||||
|
lblStatus.Content = Properties.Resources.SplashStarting;
|
||||||
|
|
||||||
|
// Build the progress steps
|
||||||
|
LoadProgressSteps();
|
||||||
|
|
||||||
|
// Set the progress bar to the number of steps
|
||||||
|
progressBar.Maximum = _progressSteps.Count;
|
||||||
|
|
||||||
|
// Create the worker with progress and cancel
|
||||||
|
_backgroundWorker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true };
|
||||||
|
|
||||||
|
// Setup the events
|
||||||
|
_backgroundWorker.DoWork += HandleBackgroundWorkerDoWork;
|
||||||
|
_backgroundWorker.ProgressChanged += HandleBackgroundWorkerProgressChanged;
|
||||||
|
_backgroundWorker.RunWorkerCompleted += HandleBackgroundWorkerCompleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Form overrides
|
||||||
|
|
||||||
|
protected override void OnContentRendered(EventArgs e)
|
||||||
|
{
|
||||||
|
base.OnContentRendered(e);
|
||||||
|
|
||||||
|
// Start the worker
|
||||||
|
_backgroundWorker.RunWorkerAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Background worker
|
||||||
|
|
||||||
|
private void HandleBackgroundWorkerProgressChanged(object sender, ProgressChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (!_dispatcher.CheckAccess())
|
||||||
|
{
|
||||||
|
_dispatcher.Invoke(new EventHandler<ProgressChangedEventArgs>(HandleBackgroundWorkerProgressChanged), sender, e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the progress bar
|
||||||
|
progressBar.Value += e.ProgressPercentage;
|
||||||
|
|
||||||
|
// Get the message
|
||||||
|
string message = (string) e.UserState;
|
||||||
|
|
||||||
|
// Update the status label if one was supplied
|
||||||
|
if (!string.IsNullOrEmpty(message))
|
||||||
|
lblStatus.Content = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleBackgroundWorkerDoWork(object sender, DoWorkEventArgs e)
|
||||||
|
{
|
||||||
|
// Wait just a little bit to make sure the window is up
|
||||||
|
Thread.Sleep(100);
|
||||||
|
|
||||||
|
// Initialize the skip key
|
||||||
|
string skipKey = string.Empty;
|
||||||
|
|
||||||
|
// Loop over all progress steps and execute
|
||||||
|
foreach (ProgressStep progressStep in _progressSteps)
|
||||||
|
{
|
||||||
|
if (progressStep.Key == skipKey)
|
||||||
|
{
|
||||||
|
// Update progress with an empty step
|
||||||
|
UpdateProgress(_backgroundWorker, string.Empty);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Update progress
|
||||||
|
UpdateProgress(_backgroundWorker, progressStep.Caption);
|
||||||
|
|
||||||
|
// Execute the step and get the result
|
||||||
|
bool result = progressStep.Callback();
|
||||||
|
|
||||||
|
// If the step indicated a skip then set the skip key, otherwise clear it
|
||||||
|
skipKey = (result ? string.Empty : progressStep.Key);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop if cancelled
|
||||||
|
if (_backgroundWorker.CancellationPending)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void UpdateProgress(BackgroundWorker worker, string progressMessage)
|
||||||
|
{
|
||||||
|
// Update the worker
|
||||||
|
worker.ReportProgress(1, progressMessage);
|
||||||
|
|
||||||
|
// Sleep a bit if we actually updated
|
||||||
|
if (!string.IsNullOrEmpty(progressMessage))
|
||||||
|
Thread.Sleep(Settings.Default.ProgressSleepInterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleBackgroundWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
|
||||||
|
{
|
||||||
|
if (!_dispatcher.CheckAccess())
|
||||||
|
{
|
||||||
|
_dispatcher.Invoke(new EventHandler<RunWorkerCompletedEventArgs>(HandleBackgroundWorkerCompleted), sender, e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move the progress bar to the max just in case
|
||||||
|
progressBar.Value = progressBar.Maximum;
|
||||||
|
|
||||||
|
// Close the window
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Progress steps
|
||||||
|
|
||||||
|
private static class ProgressKey
|
||||||
|
{
|
||||||
|
public const string Update = "Update";
|
||||||
|
public const string DatabaseCreate = "CreateDatabase";
|
||||||
|
public const string DatabaseUpdate = "UpdateDatabase";
|
||||||
|
public const string DatabaseMaintenance = "MaintainDatabase";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadProgressSteps()
|
||||||
|
{
|
||||||
|
// Load the progress steps
|
||||||
|
_progressSteps.Add(new ProgressStep(ProgressKey.Update, Properties.Resources.SplashCheckingForUpdate, CheckUpdate));
|
||||||
|
_progressSteps.Add(new ProgressStep(ProgressKey.Update, Properties.Resources.SplashInstallingUpdate, DownloadUpdate));
|
||||||
|
_progressSteps.Add(new ProgressStep(ProgressKey.Update, Properties.Resources.SplashRestarting, RestartAfterUpdate));
|
||||||
|
|
||||||
|
_progressSteps.Add(new ProgressStep(ProgressKey.DatabaseCreate, Properties.Resources.SplashCheckingForDatabase, CheckDatabase));
|
||||||
|
_progressSteps.Add(new ProgressStep(ProgressKey.DatabaseCreate, Properties.Resources.SplashCreatingDatabase, CreateDatabase));
|
||||||
|
|
||||||
|
_progressSteps.Add(new ProgressStep(ProgressKey.DatabaseUpdate, Properties.Resources.SplashUpdatingDatabase, UpdateDatabase));
|
||||||
|
|
||||||
|
_progressSteps.Add(new ProgressStep(ProgressKey.DatabaseMaintenance, Properties.Resources.SplashMaintainingDatabase, MaintainDatabase));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool CheckUpdate()
|
||||||
|
{
|
||||||
|
// If the user does not want to check version at startup then we're done
|
||||||
|
if (!Settings.Default.CheckVersionAtStartup)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// If the application isn't install then skip
|
||||||
|
if (!ApplicationDeployment.IsNetworkDeployed)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
UpdateCheckInfo updateCheckInfo;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Get detailed version information
|
||||||
|
updateCheckInfo = ApplicationDeployment.CurrentDeployment.CheckForDetailedUpdate(false);
|
||||||
|
}
|
||||||
|
catch (Exception exception)
|
||||||
|
{
|
||||||
|
// Log the exception
|
||||||
|
Tracer.WriteException(exception);
|
||||||
|
|
||||||
|
// No update at this time
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return if an update is available
|
||||||
|
return updateCheckInfo.UpdateAvailable;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool DownloadUpdate()
|
||||||
|
{
|
||||||
|
// Download and installthe update
|
||||||
|
ApplicationDeployment.CurrentDeployment.Update();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool RestartAfterUpdate()
|
||||||
|
{
|
||||||
|
// We need to restart
|
||||||
|
((App) Application.Current).Restart = true;
|
||||||
|
|
||||||
|
// Cancel the worker
|
||||||
|
_backgroundWorker.CancelAsync();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool CheckDatabase()
|
||||||
|
{
|
||||||
|
// Get the data directory
|
||||||
|
string path = AppDomain.CurrentDomain.GetData("DataDirectory").ToString();
|
||||||
|
|
||||||
|
// Set the path
|
||||||
|
Database.DatabasePath = System.IO.Path.Combine(path, Settings.Default.DatabaseFile);
|
||||||
|
|
||||||
|
// If the database exists then we're done
|
||||||
|
return !Database.DatabaseExists;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool CreateDatabase()
|
||||||
|
{
|
||||||
|
// Create the database
|
||||||
|
Database.CreateDatabase();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool UpdateDatabase()
|
||||||
|
{
|
||||||
|
// Update the database
|
||||||
|
Database.UpdateDatabase();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool MaintainDatabase()
|
||||||
|
{
|
||||||
|
// Maintain the database
|
||||||
|
Database.MaintainDatabase();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
116
SqlSettingsProvider.cs
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Configuration;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using Microsoft.Win32;
|
||||||
|
|
||||||
|
namespace FeedCenter
|
||||||
|
{
|
||||||
|
class RegistrySettingsProvider : SettingsProvider
|
||||||
|
{
|
||||||
|
public RegistrySettingsProvider()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ApplicationName
|
||||||
|
{
|
||||||
|
get { return Application.ProductName; }
|
||||||
|
set { }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Initialize(string name, NameValueCollection col)
|
||||||
|
{
|
||||||
|
base.Initialize(this.ApplicationName, col);
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPropertyValue is invoked when ApplicationSettingsBase.Save is called
|
||||||
|
// ASB makes sure to pass each provider only the values marked for that provider -
|
||||||
|
// though in this sample, since the entire settings class was marked with a SettingsProvider
|
||||||
|
// attribute, all settings in that class map to this provider
|
||||||
|
public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection propvals)
|
||||||
|
{
|
||||||
|
// Iterate through the settings to be stored
|
||||||
|
// Only IsDirty=true properties should be included in propvals
|
||||||
|
foreach (SettingsPropertyValue propval in propvals)
|
||||||
|
{
|
||||||
|
// NOTE: this provider allows setting to both user- and application-scoped
|
||||||
|
// settings. The default provider for ApplicationSettingsBase -
|
||||||
|
// LocalFileSettingsProvider - is read-only for application-scoped setting. This
|
||||||
|
// is an example of a policy that a provider may need to enforce for implementation,
|
||||||
|
// security or other reasons.
|
||||||
|
GetRegKey(propval.Property).SetValue(propval.Name, propval.SerializedValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection props)
|
||||||
|
{
|
||||||
|
|
||||||
|
// Create new collection of values
|
||||||
|
SettingsPropertyValueCollection values = new SettingsPropertyValueCollection();
|
||||||
|
|
||||||
|
// Iterate through the settings to be retrieved
|
||||||
|
foreach (SettingsProperty setting in props)
|
||||||
|
{
|
||||||
|
SettingsPropertyValue value = new SettingsPropertyValue(setting);
|
||||||
|
value.IsDirty = false;
|
||||||
|
value.SerializedValue = GetRegKey(setting).GetValue(setting.Name);
|
||||||
|
values.Add(value);
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper method: fetches correct registry subkey.
|
||||||
|
// HKLM is used for settings marked as application-scoped.
|
||||||
|
// HKLU is used for settings marked as user-scoped.
|
||||||
|
private RegistryKey GetRegKey(SettingsProperty prop)
|
||||||
|
{
|
||||||
|
RegistryKey regKey;
|
||||||
|
|
||||||
|
if (IsUserScoped(prop))
|
||||||
|
{
|
||||||
|
regKey = Registry.CurrentUser;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
regKey = Registry.LocalMachine;
|
||||||
|
}
|
||||||
|
|
||||||
|
regKey = regKey.CreateSubKey(GetSubKeyPath());
|
||||||
|
return regKey;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper method: walks the "attribute bag" for a given property
|
||||||
|
// to determine if it is user-scoped or not.
|
||||||
|
// Note that this provider does not enforce other rules, such as
|
||||||
|
// - unknown attributes
|
||||||
|
// - improper attribute combinations (e.g. both user and app - this implementation
|
||||||
|
// would say true for user-scoped regardless of existence of app-scoped)
|
||||||
|
private bool IsUserScoped(SettingsProperty prop)
|
||||||
|
{
|
||||||
|
foreach (DictionaryEntry d in prop.Attributes)
|
||||||
|
{
|
||||||
|
Attribute a = (Attribute) d.Value;
|
||||||
|
if (a.GetType() == typeof(UserScopedSettingAttribute))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Builds a key path based on the CompanyName, ProductName, and ProductVersion attributes in
|
||||||
|
// the AssemblyInfo file (editable directly or within the Project Properties UI)
|
||||||
|
private string GetSubKeyPath()
|
||||||
|
{
|
||||||
|
return "Software\\" + Application.CompanyName + "\\" + Application.ProductName + "\\" + Application.ProductVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
12
Style.xaml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||||
|
<Style TargetType="{x:Type TextBox}">
|
||||||
|
<Style.Triggers>
|
||||||
|
<Trigger Property="Validation.HasError"
|
||||||
|
Value="true">
|
||||||
|
<Setter Property="ToolTip"
|
||||||
|
Value="{Binding RelativeSource={RelativeSource Self}, Path=(Validation.Errors)[0].ErrorContent}" />
|
||||||
|
</Trigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
</ResourceDictionary>
|
||||||
133
VersionCheck.cs
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Deployment.Application;
|
||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
using Common.Debug;
|
||||||
|
|
||||||
|
using FeedCenter.Properties;
|
||||||
|
using Application = System.Windows.Forms.Application;
|
||||||
|
|
||||||
|
namespace FeedCenter
|
||||||
|
{
|
||||||
|
internal static class VersionCheck
|
||||||
|
{
|
||||||
|
public static void DisplayUpdateInformation(bool showIfCurrent)
|
||||||
|
{
|
||||||
|
if (!ApplicationDeployment.IsNetworkDeployed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
UpdateCheckInfo updateCheckInfo = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
updateCheckInfo = ApplicationDeployment.CurrentDeployment.CheckForDetailedUpdate(false);
|
||||||
|
}
|
||||||
|
catch (Exception exception)
|
||||||
|
{
|
||||||
|
Tracer.WriteException(exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayUpdateInformation(updateCheckInfo, showIfCurrent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DisplayUpdateInformation(UpdateCheckInfo updateCheckInfo, bool showIfCurrent)
|
||||||
|
{
|
||||||
|
// If we didn't get any information then do nothing
|
||||||
|
if (updateCheckInfo == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Check for an update
|
||||||
|
if (updateCheckInfo.UpdateAvailable)
|
||||||
|
{
|
||||||
|
// Load the version string from the server
|
||||||
|
Version serverVersion = updateCheckInfo.AvailableVersion;
|
||||||
|
|
||||||
|
// Format the check title
|
||||||
|
string updateCheckTitle = string.Format(Resources.UpdateCheckTitle, Resources.ApplicationDisplayName);
|
||||||
|
|
||||||
|
// Format the message
|
||||||
|
string updateCheckMessage = string.Format(Resources.UpdateCheckNewVersion, Resources.ApplicationDisplayName, serverVersion);
|
||||||
|
|
||||||
|
// Ask the user to update
|
||||||
|
if (MessageBox.Show(updateCheckMessage, updateCheckTitle, MessageBoxButton.YesNo, MessageBoxImage.Question) != MessageBoxResult.Yes)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Get the update
|
||||||
|
ApplicationDeployment.CurrentDeployment.Update();
|
||||||
|
|
||||||
|
// Set to restart
|
||||||
|
((App) System.Windows.Application.Current).Restart = true;
|
||||||
|
|
||||||
|
// Restart the application
|
||||||
|
System.Windows.Application.Current.Shutdown();
|
||||||
|
}
|
||||||
|
else if (showIfCurrent)
|
||||||
|
{
|
||||||
|
// Format the check title
|
||||||
|
string updateCheckTitle = string.Format(Resources.UpdateCheckTitle, Resources.ApplicationDisplayName);
|
||||||
|
|
||||||
|
// Format the message
|
||||||
|
string updateCheckMessage = string.Format(Resources.UpdateCheckCurrent, Resources.ApplicationDisplayName);
|
||||||
|
|
||||||
|
MessageBox.Show(updateCheckMessage, updateCheckTitle, MessageBoxButton.OK, MessageBoxImage.Information);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Background checking
|
||||||
|
|
||||||
|
private static BackgroundWorker _backgroundWorker;
|
||||||
|
|
||||||
|
public static void DisplayUpdateInformationAsync()
|
||||||
|
{
|
||||||
|
// Do nothing if we already have a worker
|
||||||
|
if (_backgroundWorker != null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Create a new worker
|
||||||
|
_backgroundWorker = new BackgroundWorker();
|
||||||
|
|
||||||
|
// Setup worker events
|
||||||
|
_backgroundWorker.DoWork += HandleBackgroundWorkerDoWork;
|
||||||
|
_backgroundWorker.RunWorkerCompleted += HandleBackgroundWorkerCompleted;
|
||||||
|
|
||||||
|
// Run the worker
|
||||||
|
_backgroundWorker.RunWorkerAsync();
|
||||||
|
|
||||||
|
// Wait for the worker
|
||||||
|
while (_backgroundWorker.IsBusy)
|
||||||
|
Application.DoEvents();
|
||||||
|
|
||||||
|
// Clear out the worker
|
||||||
|
_backgroundWorker.Dispose();
|
||||||
|
_backgroundWorker = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void HandleBackgroundWorkerDoWork(object sender, DoWorkEventArgs e)
|
||||||
|
{
|
||||||
|
// If the application isn't installed then do nothing
|
||||||
|
if (!ApplicationDeployment.IsNetworkDeployed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
e.Result = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Get the update information and set it into the result
|
||||||
|
e.Result = ApplicationDeployment.CurrentDeployment.CheckForDetailedUpdate(false);
|
||||||
|
}
|
||||||
|
catch (Exception exception)
|
||||||
|
{
|
||||||
|
Tracer.WriteException(exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void HandleBackgroundWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
|
||||||
|
{
|
||||||
|
// Display any update info
|
||||||
|
DisplayUpdateInformation(e.Result as UpdateCheckInfo, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
94
app.config
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<configuration>
|
||||||
|
<configSections>
|
||||||
|
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<section name="FeedCenter.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
|
||||||
|
</sectionGroup>
|
||||||
|
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
|
<section name="FeedCenter.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
|
||||||
|
</sectionGroup>
|
||||||
|
</configSections>
|
||||||
|
<userSettings>
|
||||||
|
<FeedCenter.Properties.Settings>
|
||||||
|
<setting name="WindowLocked" serializeAs="String">
|
||||||
|
<value>False</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="WindowSize" serializeAs="String">
|
||||||
|
<value>0,0</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="WindowLocation" serializeAs="String">
|
||||||
|
<value>0,0</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="CheckVersionAtStartup" serializeAs="String">
|
||||||
|
<value>True</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="FeedScrollInterval" serializeAs="String">
|
||||||
|
<value>00:01:00</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="FeedCheckInterval" serializeAs="String">
|
||||||
|
<value>00:30:00</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="DisplayEmptyFeeds" serializeAs="String">
|
||||||
|
<value>True</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="LastVersionCheck" serializeAs="String">
|
||||||
|
<value/>
|
||||||
|
</setting>
|
||||||
|
<setting name="StartWithWindows" serializeAs="String">
|
||||||
|
<value>False</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="FirstRun" serializeAs="String">
|
||||||
|
<value>True</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="ToolbarLocation" serializeAs="String">
|
||||||
|
<value>Bottom</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="OpenAllSleepInterval" serializeAs="String">
|
||||||
|
<value>500</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="RegisterAsDefaultFeedReader" serializeAs="String">
|
||||||
|
<value>False</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="Browser" serializeAs="String">
|
||||||
|
<value/>
|
||||||
|
</setting>
|
||||||
|
<setting name="OpenAllSleepIntervalFirst" serializeAs="String">
|
||||||
|
<value>1500</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="MultipleLineDisplay" serializeAs="String">
|
||||||
|
<value>Normal</value>
|
||||||
|
</setting>
|
||||||
|
</FeedCenter.Properties.Settings>
|
||||||
|
</userSettings>
|
||||||
|
<applicationSettings>
|
||||||
|
<FeedCenter.Properties.Settings>
|
||||||
|
<setting name="LogDatabase" serializeAs="String">
|
||||||
|
<value>True</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="DatabaseFile" serializeAs="String">
|
||||||
|
<value>FeedCenter.sdf</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="ProgressSleepInterval" serializeAs="String">
|
||||||
|
<value>250</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="BalloonTipTimeout" serializeAs="String">
|
||||||
|
<value>5000</value>
|
||||||
|
</setting>
|
||||||
|
<setting name="VersionCheckInterval" serializeAs="String">
|
||||||
|
<value>01:00:00</value>
|
||||||
|
</setting>
|
||||||
|
</FeedCenter.Properties.Settings>
|
||||||
|
</applicationSettings>
|
||||||
|
<startup>
|
||||||
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>
|
||||||
|
</startup>
|
||||||
|
<!--<system.data>
|
||||||
|
<DbProviderFactories>
|
||||||
|
<remove invariant="System.Data.SqlServerCe.4.0"/>
|
||||||
|
<add name="Microsoft SQL Server Compact Data Provider" invariant="System.Data.SqlServerCe.4.0" description=".NET Framework Data Provider for Microsoft SQL Server Compact" type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe, Version=4.0.0.1, Culture=neutral, PublicKeyToken=89845dcd8080cc91"/>
|
||||||
|
</DbProviderFactories>
|
||||||
|
</system.data>-->
|
||||||
|
<connectionStrings>
|
||||||
|
<add name="FeedCenterEntities" connectionString="metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl;provider=System.Data.SqlServerCe.4.0;provider connection string="Data Source=|DataDirectory|\FeedCenter.sdf"" providerName="System.Data.EntityClient"/>
|
||||||
|
</connectionStrings>
|
||||||
|
</configuration>
|
||||||