diff --git a/Application/App.xaml.cs b/Application/App.xaml.cs
index 8ac0960..c71e977 100644
--- a/Application/App.xaml.cs
+++ b/Application/App.xaml.cs
@@ -3,6 +3,7 @@ using Common.Helpers;
using Common.IO;
using Common.Settings;
using Common.Wpf.Extensions;
+using FeedCenter.Data;
using FeedCenter.Properties;
using System;
using System.Diagnostics;
@@ -49,6 +50,14 @@ namespace FeedCenter
// Set the data directory based on debug or not
AppDomain.CurrentDomain.SetData("DataDirectory", SystemConfiguration.DataDirectory);
+ // Get the data directory
+ var path = AppDomain.CurrentDomain.GetData("DataDirectory").ToString();
+
+ // Set the path
+ Database.DatabasePath = path;
+ Database.DatabaseFile = System.IO.Path.Combine(path, Settings.Default.DatabaseFile);
+ Database.Load();
+
// Get the generic provider
var genericProvider = (GenericSettingsProvider) Settings.Default.Providers[typeof(GenericSettingsProvider).Name];
diff --git a/Application/BrowserCommon.cs b/Application/BrowserCommon.cs
index dd4f1ab..9ead038 100644
--- a/Application/BrowserCommon.cs
+++ b/Application/BrowserCommon.cs
@@ -28,7 +28,7 @@ namespace FeedCenter
public static bool OpenLink(string url)
{
// Get the browser
- Browser browser = FindBrowser(Settings.Default.Browser);
+ var browser = FindBrowser(Settings.Default.Browser);
// Start the browser
return OpenLink(browser, url);
@@ -47,7 +47,15 @@ namespace FeedCenter
// Start the browser
if (browser == null)
- Process.Start(url);
+ {
+ var ps = new ProcessStartInfo(url)
+ {
+ UseShellExecute = true,
+ Verb = "open"
+ };
+
+ Process.Start(ps);
+ }
else
Process.Start(browser.Command, url);
diff --git a/Application/Category.cs b/Application/Category.cs
deleted file mode 100644
index 9083a4d..0000000
--- a/Application/Category.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// This code was generated from a template.
-//
-// Manual changes to this file may cause unexpected behavior in your application.
-// Manual changes to this file will be overwritten if the code is regenerated.
-//
-//------------------------------------------------------------------------------
-
-namespace FeedCenter
-{
- using System;
- using System.Collections.Generic;
-
- public partial class Category
- {
- public Category()
- {
- this.Feeds = new HashSet();
- }
-
- public System.Guid ID { get; set; }
- public string Name { get; set; }
-
- public virtual ICollection Feeds { get; set; }
- }
-}
diff --git a/Application/Data/Database.cs b/Application/Data/Database.cs
index 03f7e21..c7c16bf 100644
--- a/Application/Data/Database.cs
+++ b/Application/Data/Database.cs
@@ -12,12 +12,15 @@ namespace FeedCenter.Data
{
#region Static database settings
+ public static string DatabaseFile;
public static string DatabasePath;
#endregion
#region File version
+ public static FeedCenterEntities Entities;
+
private enum SqlServerCeFileVersion
{
Unknown,
@@ -27,6 +30,11 @@ namespace FeedCenter.Data
Version40,
}
+ public static void Load()
+ {
+ Entities = new FeedCenterEntities();
+ }
+
private static SqlServerCeFileVersion GetFileVersion(string databasePath)
{
// Create a mapping of version numbers to the version enumeration
@@ -43,18 +51,15 @@ namespace FeedCenter.Data
try
{
// Open the database file
- using (var stream = new FileStream(databasePath, FileMode.Open, FileAccess.Read))
- {
- // Read the file using the binary reader
- var reader = new BinaryReader(stream);
+ using var stream = new FileStream(databasePath, FileMode.Open, FileAccess.Read);
+ // Read the file using the binary reader
+ var reader = new BinaryReader(stream);
- // Seek to the version signature
- stream.Seek(16, SeekOrigin.Begin);
+ // Seek to the version signature
+ stream.Seek(16, SeekOrigin.Begin);
- // Read the version signature
- signature = reader.ReadInt32();
-
- }
+ // Read the version signature
+ signature = reader.ReadInt32();
}
catch (Exception exception)
{
@@ -69,25 +74,23 @@ namespace FeedCenter.Data
#endregion
- public static bool DatabaseExists => File.Exists(DatabasePath);
+ public static bool DatabaseExists => File.Exists(DatabaseFile);
public static void CreateDatabase()
{
Tracer.WriteLine("Creating database engine");
// Create the database engine
- using (var engine = new SqlCeEngine($"Data Source={DatabasePath}"))
- {
- Tracer.WriteLine("Creating database");
+ using var engine = new SqlCeEngine($"Data Source={DatabaseFile}");
+ Tracer.WriteLine("Creating database");
- // Create the database itself
- engine.CreateDatabase();
+ // Create the database itself
+ engine.CreateDatabase();
- Tracer.WriteLine("Running database script");
+ Tracer.WriteLine("Running database script");
- // Run the creation script
- ExecuteScript(Resources.CreateDatabase);
- }
+ // Run the creation script
+ ExecuteScript(Resources.CreateDatabase);
}
private static int GetVersion(SqlCeConnection connection)
@@ -97,14 +100,14 @@ namespace FeedCenter.Data
try
{
// Check the database version table
- using (var command = new SqlCeCommand("SELECT Value FROM DatabaseVersion", connection))
- versionString = command.ExecuteScalar().ToString();
+ using var command = new SqlCeCommand("SELECT Value FROM DatabaseVersion", connection);
+ versionString = command.ExecuteScalar().ToString();
}
catch (SqlCeException)
{
// Check the setting table for the version
- using (var command = new SqlCeCommand("SELECT Value FROM Setting WHERE Name = 'DatabaseVersion'", connection))
- versionString = command.ExecuteScalar().ToString();
+ using var command = new SqlCeCommand("SELECT Value FROM Setting WHERE Name = 'DatabaseVersion'", connection);
+ versionString = command.ExecuteScalar().ToString();
}
if (string.IsNullOrEmpty(versionString))
@@ -120,7 +123,7 @@ namespace FeedCenter.Data
Tracer.WriteLine("Getting database file version");
// Get the database file version
- var fileVersion = GetFileVersion(DatabasePath);
+ var fileVersion = GetFileVersion(DatabaseFile);
Tracer.WriteLine("Database file version: {0}", fileVersion);
@@ -130,54 +133,50 @@ namespace FeedCenter.Data
Tracer.WriteLine("Creating database engine");
// Create the database engine
- using (var engine = new SqlCeEngine($"Data Source={DatabasePath}"))
- {
- Tracer.WriteLine("Upgrading database");
+ using var engine = new SqlCeEngine($"Data Source={DatabaseFile}");
+ Tracer.WriteLine("Upgrading database");
- // Upgrade the database (if needed)
- engine.Upgrade();
- }
+ // Upgrade the database (if needed)
+ engine.Upgrade();
}
Tracer.WriteLine("Getting database version");
// Create a database connection
- using (var connection = new SqlCeConnection($"Data Source={DatabasePath}"))
+ using var connection = new SqlCeConnection($"Data Source={DatabaseFile}");
+ // Open the connection
+ connection.Open();
+
+ // Get the database version
+ var databaseVersion = GetVersion(connection);
+
+ // Create a dictionary of database upgrade scripts and their version numbers
+ var scriptList = new Dictionary();
+
+ // 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")))
{
- // Open the connection
- connection.Open();
+ // Get the name of the property
+ var propertyName = property.Name;
- // Get the database version
- var databaseVersion = GetVersion(connection);
+ // Extract the version from the name
+ var version = int.Parse(propertyName.Substring(propertyName.IndexOf("_", StringComparison.Ordinal) + 1));
- // Create a dictionary of database upgrade scripts and their version numbers
- var scriptList = new Dictionary();
+ // Add to the script list
+ scriptList[version] = propertyName;
+ }
- // 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")))
+ // 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 name of the property
- var propertyName = property.Name;
+ // Get the script text
+ var scriptText = Resources.ResourceManager.GetString(pair.Value);
- // Extract the version from the name
- var version = int.Parse(propertyName.Substring(propertyName.IndexOf("_", StringComparison.Ordinal) + 1));
-
- // Add to the script list
- scriptList[version] = propertyName;
- }
-
- // Loop over the scripts ordered by version
- foreach (var pair in scriptList.OrderBy(pair => pair.Key))
- {
- // If the database version is less than or equal to the script version the script needs to run
- if (databaseVersion <= pair.Key)
- {
- // Get the script text
- var scriptText = Resources.ResourceManager.GetString(pair.Value);
-
- // Run the script
- ExecuteScript(scriptText);
- }
+ // Run the script
+ ExecuteScript(scriptText);
}
}
}
@@ -187,36 +186,32 @@ namespace FeedCenter.Data
Tracer.WriteLine("Creating database engine");
// Create the database engine
- using (var engine = new SqlCeEngine($"Data Source={DatabasePath}"))
- {
- Tracer.WriteLine("Shrinking database");
+ using var engine = new SqlCeEngine($"Data Source={DatabaseFile}");
+ Tracer.WriteLine("Shrinking database");
- // Compact the database
- engine.Shrink();
- }
+ // Compact the database
+ engine.Shrink();
}
private static void ExecuteScript(string scriptText)
{
// Create a database connection
- using (var connection = new SqlCeConnection($"Data Source={DatabasePath}"))
+ using var connection = new SqlCeConnection($"Data Source={DatabaseFile}");
+ // Open the connection
+ connection.Open();
+
+ // Setup the delimiters
+ var delimiters = new[] { "\r\nGO\r\n" };
+
+ // Split the script at the delimiters
+ var statements = scriptText.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
+
+ // Loop over each statement in the script
+ foreach (var statement in statements)
{
- // Open the connection
- connection.Open();
-
- // Setup the delimiters
- var delimiters = new[] { "\r\nGO\r\n" };
-
- // Split the script at the delimiters
- var statements = scriptText.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
-
- // Loop over each statement in the script
- foreach (var statement in statements)
- {
- // Execute the statement
- using (var command = new SqlCeCommand(statement, connection))
- command.ExecuteNonQuery();
- }
+ // Execute the statement
+ using var command = new SqlCeCommand(statement, connection);
+ command.ExecuteNonQuery();
}
}
}
diff --git a/Application/Data/RealmObservableCollection.cs b/Application/Data/RealmObservableCollection.cs
new file mode 100644
index 0000000..02eef85
--- /dev/null
+++ b/Application/Data/RealmObservableCollection.cs
@@ -0,0 +1,29 @@
+using Realms;
+using System.Collections.ObjectModel;
+using System.Collections.Specialized;
+
+namespace FeedCenter.Data
+{
+ public class RealmObservableCollection : ObservableCollection where T : IRealmObject
+ {
+ private readonly Realm _realm;
+
+ public RealmObservableCollection(Realm realm) : base(realm.All())
+ {
+ _realm = realm;
+ }
+
+ protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
+ {
+ if (e.OldItems != null)
+ foreach (T item in e.OldItems)
+ _realm.Remove(item);
+
+ if (e.NewItems != null)
+ foreach (T item in e.NewItems)
+ _realm.Add(item);
+
+ base.OnCollectionChanged(e);
+ }
+ }
+}
diff --git a/Application/Database/Template.sdf b/Application/Database/Template.sdf
deleted file mode 100644
index 6f98ad3..0000000
Binary files a/Application/Database/Template.sdf and /dev/null differ
diff --git a/Application/Entities.cs b/Application/Entities.cs
index ad7ebca..6278bfd 100644
--- a/Application/Entities.cs
+++ b/Application/Entities.cs
@@ -1,139 +1,96 @@
-using System.Collections.ObjectModel;
-using System.ComponentModel;
-using System.Data.Entity.Infrastructure;
+using Dapper;
+using FeedCenter.Data;
+using FeedCenter.Options;
+using Realms;
+using System;
+using System.Data.SqlServerCe;
+using System.IO;
using System.Linq;
namespace FeedCenter
{
- public partial class FeedCenterEntities
+ public class FeedCenterEntities
{
- #region Dispose
+ public Realm Realm { get; private set; }
- protected override void Dispose(bool disposing)
+ public RealmObservableCollection Categories { get; private set; }
+ public RealmObservableCollection Feeds { get; private set; }
+ public RealmObservableCollection Settings { get; private set; }
+
+ public FeedCenterEntities()
{
- if (disposing)
- {
- var manager = ((IObjectContextAdapter) this).ObjectContext.ObjectStateManager;
- manager.ObjectStateManagerChanged -= HandleObjectStateManagerObjectStateManagerChanged;
- _hookedStateManager = false;
- }
-
- base.Dispose(disposing);
+ Load();
}
- #endregion
-
- private bool _hookedStateManager;
-
- #region All categories
-
- private ObservableCollection _allCategories;
-
- public ObservableCollection AllCategories
+ public void Refresh()
{
- get
+ Realm.Refresh();
+ }
+
+ public void Load()
+ {
+ var realmConfiguration = new RealmConfiguration($"{Database.DatabasePath}/FeedCenter.realm");
+
+ Realm = Realm.GetInstance(realmConfiguration);
+
+ if (File.Exists(Database.DatabaseFile))
{
- if (_allCategories == null)
+ using var connection = new SqlCeConnection($"Data Source={Database.DatabaseFile}");
+
+ connection.Open();
+
+ var settings = connection.Query("SELECT * FROM Setting").OrderBy(s => s.Version).ToList();
+ var categories = connection.Query("SELECT * FROM Category").ToList();
+ var feeds = connection.Query("SELECT * FROM Feed").ToList();
+ var feedItems = connection.Query("SELECT * FROM FeedItem").ToList();
+
+ Realm.Write(() =>
{
- _allCategories = new ObservableCollection(Categories);
-
- if (!_hookedStateManager)
+ foreach (var category in categories)
{
- var manager = ((IObjectContextAdapter) this).ObjectContext.ObjectStateManager;
- manager.ObjectStateManagerChanged += HandleObjectStateManagerObjectStateManagerChanged;
- _hookedStateManager = true;
+ category.Feeds = feeds.Where(f => f.CategoryId == category.Id).ToList();
}
- }
- return _allCategories;
+ foreach (var feed in feeds)
+ {
+ feed.Category = categories.FirstOrDefault(c => c.Id == feed.CategoryId);
+ }
+
+ foreach (var feedItem in feedItems)
+ {
+ var feed = feeds.First(f => f.Id == feedItem.FeedId);
+
+ feed.Items.Add(feedItem);
+ }
+
+ Realm.Add(feeds);
+ Realm.Add(categories);
+ Realm.Add(settings, true);
+ });
+
+ connection.Close();
+
+ File.Move(Database.DatabaseFile, Database.DatabaseFile + "_bak");
}
+
+ Settings = new RealmObservableCollection(Realm);
+ Feeds = new RealmObservableCollection(Realm);
+ Categories = new RealmObservableCollection(Realm);
+
+ if (!Categories.Any())
+ {
+ Realm.Write(() => Categories.Add(Category.CreateDefault()));
+ }
+ }
+
+ public void SaveChanges(Action action)
+ {
+ Realm.Write(action);
}
public Category DefaultCategory
{
- get { return AllCategories.First(c => c.IsDefault); }
+ get { return Categories.First(c => c.IsDefault); }
}
-
- #endregion
-
- #region All feeds
-
- private ObservableCollection _allFeeds;
-
- public ObservableCollection AllFeeds
- {
- get
- {
- if (_allFeeds == null)
- {
- _allFeeds = new ObservableCollection(Feeds);
-
- if (!_hookedStateManager)
- {
- var manager = ((IObjectContextAdapter) this).ObjectContext.ObjectStateManager;
- manager.ObjectStateManagerChanged += HandleObjectStateManagerObjectStateManagerChanged;
- _hookedStateManager = true;
- }
- }
-
- return _allFeeds;
- }
- }
-
- #endregion
-
- #region Object state manager
-
- void HandleObjectStateManagerObjectStateManagerChanged(object sender, CollectionChangeEventArgs e)
- {
- var element = e.Element as Category;
-
- if (element != null)
- {
- if (_allCategories == null)
- return;
-
- var category = element;
-
- switch (e.Action)
- {
- case CollectionChangeAction.Add:
- _allCategories.Add(category);
- break;
- case CollectionChangeAction.Remove:
- _allCategories.Remove(category);
- break;
- case CollectionChangeAction.Refresh:
- _allCategories.Clear();
- foreach (var loopCategory in Categories)
- _allCategories.Add(loopCategory);
- break;
- }
- }
- else if (e.Element is Feed)
- {
- if (_allFeeds == null)
- return;
-
- var feed = (Feed) e.Element;
-
- switch (e.Action)
- {
- case CollectionChangeAction.Add:
- _allFeeds.Add(feed);
- break;
- case CollectionChangeAction.Remove:
- _allFeeds.Remove(feed);
- break;
- case CollectionChangeAction.Refresh:
- _allFeeds.Clear();
- foreach (var loopfeed in Feeds)
- _allFeeds.Add(loopfeed);
- break;
- }
- }
- }
-
- #endregion
}
-}
+}
\ No newline at end of file
diff --git a/Application/Feed.cs b/Application/Feed.cs
deleted file mode 100644
index 6b58466..0000000
--- a/Application/Feed.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// This code was generated from a template.
-//
-// Manual changes to this file may cause unexpected behavior in your application.
-// Manual changes to this file will be overwritten if the code is regenerated.
-//
-//------------------------------------------------------------------------------
-
-namespace FeedCenter
-{
- using System;
- using System.Collections.Generic;
-
- public partial class Feed
- {
- public Feed()
- {
- this.Name = "";
- this.Title = "";
- this.Source = "";
- this.Link = "";
- this.Description = "";
- this.LastChecked = new DateTime(599266080000000000, DateTimeKind.Unspecified);
- this.CheckInterval = 60;
- this.Enabled = true;
- this.Authenticate = false;
- this.Username = "";
- this.Password = "";
- this.Domain = "";
- this.LastUpdated = new DateTime(599266080000000000, DateTimeKind.Unspecified);
- this.Actions = new HashSet();
- this.Items = new HashSet();
- }
-
- public System.Guid ID { get; set; }
- public string Name { get; set; }
- public string Title { get; set; }
- public string Source { get; set; }
- public string Link { get; set; }
- public string Description { get; set; }
- public System.DateTime LastChecked { get; set; }
- public int CheckInterval { get; set; }
- public bool Enabled { get; set; }
- public bool Authenticate { get; set; }
- public string Username { get; set; }
- public string Password { get; set; }
- public string Domain { get; set; }
- public FeedCenter.FeedReadResult LastReadResult { get; set; }
- public System.DateTime LastUpdated { get; set; }
- public FeedCenter.FeedItemComparison ItemComparison { get; set; }
- private System.Guid CategoryID { get; set; }
- public FeedCenter.MultipleOpenAction MultipleOpenAction { get; set; }
-
- public virtual Category Category { get; set; }
- public virtual ICollection Actions { get; set; }
- public virtual ICollection Items { get; set; }
- }
-}
diff --git a/Application/FeedAction.cs b/Application/FeedAction.cs
deleted file mode 100644
index d853061..0000000
--- a/Application/FeedAction.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// This code was generated from a template.
-//
-// Manual changes to this file may cause unexpected behavior in your application.
-// Manual changes to this file will be overwritten if the code is regenerated.
-//
-//------------------------------------------------------------------------------
-
-namespace FeedCenter
-{
- using System;
- using System.Collections.Generic;
-
- public partial class FeedAction
- {
- public System.Guid ID { get; set; }
- public System.Guid FeedID { get; set; }
- public int Field { get; set; }
- public string Search { get; set; }
- public string Replace { get; set; }
- public int Sequence { get; set; }
-
- public virtual Feed Feed { get; set; }
- }
-}
diff --git a/Application/FeedCenter.csproj b/Application/FeedCenter.csproj
index cfb4152..7e65192 100644
--- a/Application/FeedCenter.csproj
+++ b/Application/FeedCenter.csproj
@@ -1,30 +1,13 @@
-
-
+
- Debug
+ net70-windows
x86
- 8.0.30703
- 2.0
- {BD3D12F2-DE23-4466-83B1-1EB617A877A4}
WinExe
- Properties
- FeedCenter
- FeedCenter
- v4.5.1
-
-
- 512
- {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
- 4
false
-
-
-
-
-
-
-
-
+
+
+
+
\\server\d\FeedCenter\
true
Unc
@@ -45,38 +28,19 @@
false
true
true
-
-
- x86
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
- false
-
-
- x86
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
- false
+ false
+ true
+ true
+ true
-
-
+
+
+ false
+
- false
-
-
-
-
+
Resources\Application.ico
@@ -91,322 +55,40 @@
Properties\app.manifest
- true
- bin\Debug\
- DEBUG;TRACE
- full
- AnyCPU
bin\Debug\FeedCenter.exe.CodeAnalysisLog.xml
- true
- GlobalSuppressions.cs
- prompt
MinimumRecommendedRules.ruleset
;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets
false
;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules
false
- false
true
- false
- bin\Release\
- TRACE
- true
- pdbonly
- AnyCPU
bin\Release\FeedCenter.exe.CodeAnalysisLog.xml
- true
- GlobalSuppressions.cs
- prompt
MinimumRecommendedRules.ruleset
;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets
;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules
- false
- true
bin\x64\Debug\
- DEBUG;TRACE
- full
- x64
- prompt
MinimumRecommendedRules.ruleset
false
false
bin\x64\Release\
- TRACE
- true
- pdbonly
- x64
- prompt
MinimumRecommendedRules.ruleset
-
- False
- ..\packages\EntityFramework.6.1.1\lib\net45\EntityFramework.dll
-
-
- ..\packages\EntityFramework.6.1.1\lib\net45\EntityFramework.SqlServer.dll
-
-
- ..\packages\EntityFramework.SqlServerCompact.6.1.1\lib\net45\EntityFramework.SqlServerCompact.dll
-
-
- ..\packages\HtmlAgilityPack.1.4.9\lib\Net45\HtmlAgilityPack.dll
- True
-
-
- ..\packages\NameBasedGrid.0.10.1\lib\net40\NameBasedGrid.dll
-
-
-
-
-
-
- True
- ..\packages\Microsoft.SqlServer.Compact.4.0.8854.1\lib\net40\System.Data.SqlServerCe.dll
-
-
- True
- ..\packages\Microsoft.SqlServer.Compact.4.0.8854.1\lib\net40\System.Data.SqlServerCe.Entity.dll
-
-
-
-
-
-
-
- 4.0
-
-
-
-
-
-
-
-
- FeedChooserWindow.xaml
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- MSBuild:Compile
- Designer
-
-
-
- Model.tt
-
-
-
-
- Model.tt
-
-
- Model.tt
-
-
- FeedErrorWindow.xaml
-
-
- Model.tt
-
-
-
- True
- True
- Model.Context.tt
-
-
- True
- True
- Model.tt
-
-
- True
- True
- Model.edmx
-
-
-
- AboutOptionsPanel.xaml
-
-
- BulkFeedWindow.xaml
-
-
- CategoryWindow.xaml
-
-
- DisplayOptionsPanel.xaml
-
-
- FeedsOptionsPanel.xaml
-
-
- FeedWindow.xaml
-
-
- GeneralOptionsPanel.xaml
-
-
-
-
- OptionsWindow.xaml
-
-
- UpdateOptionsPanel.xaml
-
-
- Model.tt
-
-
-
- SplashWindow.xaml
-
-
- Designer
- MSBuild:Compile
-
-
- Designer
- MSBuild:Compile
-
-
- MSBuild:Compile
- Designer
-
-
- App.xaml
- Code
-
-
-
-
-
-
-
-
-
-
- MainWindow.xaml
- Code
-
-
- Designer
- MSBuild:Compile
-
-
- Designer
- MSBuild:Compile
-
-
- Designer
- MSBuild:Compile
-
-
- Designer
- MSBuild:Compile
-
-
- Designer
- MSBuild:Compile
-
-
- Designer
- MSBuild:Compile
-
-
- MSBuild:Compile
- Designer
-
-
- Designer
- MSBuild:Compile
-
-
- MSBuild:Compile
- Designer
-
-
- Designer
- MSBuild:Compile
-
-
- Designer
- MSBuild:Compile
-
-
-
-
- Code
-
-
- True
- True
- Resources.resx
-
-
- True
- Settings.settings
- True
-
-
- PublicResXFileCodeGenerator
- Resources.Designer.cs
- Designer
-
-
- Designer
-
EntityModelCodeGenerator
Model.Designer.cs
-
- TextTemplatingFileGenerator
- Model.Context.cs
- Model.edmx
-
-
- TextTemplatingFileGenerator
- Model.cs
- Model.edmx
-
-
-
-
- SettingsSingleFileGenerator
- Settings.Designer.cs
-
-
-
-
-
-
-
-
-
-
False
@@ -442,32 +124,29 @@
-
- {ed1c07a1-54f5-4796-8b06-2a0bb1960d84}
- Common.Native
-
-
- {0074c983-550e-4094-9e8c-f566fb669297}
- Common.Wpf
-
-
- {17864d82-457d-4a0a-bc10-1d07f2b3a5d6}
- Common
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
- if not exist "$(TargetDir)x86" md "$(TargetDir)x86"
- xcopy /s /y "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8854.1\NativeBinaries\x86\*.*" "$(TargetDir)x86"
- if not exist "$(TargetDir)amd64" md "$(TargetDir)amd64"
- xcopy /s /y "$(SolutionDir)packages\Microsoft.SqlServer.Compact.4.0.8854.1\NativeBinaries\amd64\*.*" "$(TargetDir)amd64"
+ if not exist "$(TargetDir)x86" md "$(TargetDir)x86"
+ xcopy /s /y "$(PkgMicrosoft_SqlServer_Compact)\NativeBinaries\x86\*.*" "$(TargetDir)x86"
+ if not exist "$(TargetDir)amd64" md "$(TargetDir)amd64"
+ xcopy /s /y "$(PkgMicrosoft_SqlServer_Compact)\NativeBinaries\amd64\*.*" "$(TargetDir)amd64"
+
-
\ No newline at end of file
diff --git a/Application/FeedCenterEntities.datasource b/Application/FeedCenterEntities.datasource
deleted file mode 100644
index c919ef6..0000000
--- a/Application/FeedCenterEntities.datasource
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
- FeedCenter.FeedCenterEntities, Model.Designer.cs, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
-
\ No newline at end of file
diff --git a/Application/FeedCenterEntities1.datasource b/Application/FeedCenterEntities1.datasource
deleted file mode 100644
index c919ef6..0000000
--- a/Application/FeedCenterEntities1.datasource
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
- FeedCenter.FeedCenterEntities, Model.Designer.cs, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
-
\ No newline at end of file
diff --git a/Application/FeedCenterEntities2.datasource b/Application/FeedCenterEntities2.datasource
deleted file mode 100644
index c919ef6..0000000
--- a/Application/FeedCenterEntities2.datasource
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
-
- FeedCenter.FeedCenterEntities, Model.Designer.cs, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
-
\ No newline at end of file
diff --git a/Application/FeedErrorWindow.xaml.cs b/Application/FeedErrorWindow.xaml.cs
index 048ea1f..bc72b7c 100644
--- a/Application/FeedErrorWindow.xaml.cs
+++ b/Application/FeedErrorWindow.xaml.cs
@@ -3,6 +3,7 @@ using System.ComponentModel;
using System.Windows;
using System.Windows.Data;
using System.Windows.Input;
+using FeedCenter.Data;
namespace FeedCenter
{
@@ -18,10 +19,10 @@ namespace FeedCenter
public bool? Display(Window owner)
{
- _database = new FeedCenterEntities();
+ _database = Database.Entities;
// Create a view and sort it by name
- _collectionViewSource = new CollectionViewSource { Source = _database.AllFeeds };
+ _collectionViewSource = new CollectionViewSource { Source = _database.Feeds };
_collectionViewSource.Filter += HandleCollectionViewSourceFilter;
_collectionViewSource.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
@@ -98,7 +99,7 @@ namespace FeedCenter
private void HandleOkayButtonClick(object sender, RoutedEventArgs e)
{
// Save the actual settings
- _database.SaveChanges();
+ _database.SaveChanges(() => { });
DialogResult = true;
diff --git a/Application/FeedItem.cs b/Application/FeedItem.cs
deleted file mode 100644
index b7e3dee..0000000
--- a/Application/FeedItem.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// This code was generated from a template.
-//
-// Manual changes to this file may cause unexpected behavior in your application.
-// Manual changes to this file will be overwritten if the code is regenerated.
-//
-//------------------------------------------------------------------------------
-
-namespace FeedCenter
-{
- using System;
- using System.Collections.Generic;
-
- public partial class FeedItem
- {
- public FeedItem()
- {
- this.Title = "";
- this.Link = "";
- this.Description = "";
- this.LastFound = new DateTime(599266080000000000, DateTimeKind.Unspecified);
- }
-
- public System.Guid ID { get; set; }
- public System.Guid FeedID { get; set; }
- public string Title { get; set; }
- public string Link { get; set; }
- public string Description { get; set; }
- public bool BeenRead { get; set; }
- public System.DateTime LastFound { get; set; }
- public bool New { get; set; }
- public string Guid { get; set; }
- public int Sequence { get; set; }
-
- public virtual Feed Feed { get; set; }
- }
-}
diff --git a/Application/FeedParsers/FeedParserBase.cs b/Application/FeedParsers/FeedParserBase.cs
index 86b7583..201c168 100644
--- a/Application/FeedParsers/FeedParserBase.cs
+++ b/Application/FeedParsers/FeedParserBase.cs
@@ -40,7 +40,7 @@ namespace FeedCenter.FeedParsers
protected void HandleFeedItem(XmlNode node, ref int sequence)
{
// Build a feed item from the node
- FeedItem newFeedItem = ParseFeedItem(node);
+ var newFeedItem = ParseFeedItem(node);
if (newFeedItem == null)
return;
@@ -50,7 +50,7 @@ namespace FeedCenter.FeedParsers
return;
// Look for an item that has the same guid
- FeedItem existingFeedItem = Feed.Items.FirstOrDefault(item => item.Guid == newFeedItem.Guid && item.ID != newFeedItem.ID);
+ var 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)
@@ -102,7 +102,7 @@ namespace FeedCenter.FeedParsers
public static FeedParserBase CreateFeedParser(Feed feed, string feedText)
{
- FeedType feedType = DetectFeedType(feedText);
+ var feedType = DetectFeedType(feedText);
switch (feedType)
{
diff --git a/Application/FeedParsers/RdfParser.cs b/Application/FeedParsers/RdfParser.cs
index ba01901..8289f53 100644
--- a/Application/FeedParsers/RdfParser.cs
+++ b/Application/FeedParsers/RdfParser.cs
@@ -19,7 +19,7 @@ namespace FeedCenter.FeedParsers
document.LoadXml(feedText);
// Create the namespace manager
- XmlNamespaceManager namespaceManager = document.GetAllNamespaces();
+ var namespaceManager = document.GetAllNamespaces();
// Get the root node
XmlNode rootNode = document.DocumentElement;
@@ -29,7 +29,7 @@ namespace FeedCenter.FeedParsers
return FeedReadResult.UnknownError;
// Get the channel node
- XmlNode channelNode = rootNode.SelectSingleNode("default:channel", namespaceManager);
+ var channelNode = rootNode.SelectSingleNode("default:channel", namespaceManager);
if (channelNode == null)
return FeedReadResult.InvalidXml;
@@ -55,7 +55,7 @@ namespace FeedCenter.FeedParsers
}
// Initialize the sequence number for items
- int sequence = 0;
+ var sequence = 0;
// Loop over all nodes in the channel node
foreach (XmlNode node in rootNode.ChildNodes)
@@ -82,7 +82,7 @@ namespace FeedCenter.FeedParsers
protected override FeedItem ParseFeedItem(XmlNode node)
{
// Create a new feed item
- FeedItem feedItem = FeedItem.Create();
+ var feedItem = FeedItem.Create();
// Loop over all nodes in the feed node
foreach (XmlNode childNode in node.ChildNodes)
diff --git a/Application/FeedParsers/RssParser.cs b/Application/FeedParsers/RssParser.cs
index be3148d..fe414c9 100644
--- a/Application/FeedParsers/RssParser.cs
+++ b/Application/FeedParsers/RssParser.cs
@@ -20,7 +20,7 @@ namespace FeedCenter.FeedParsers
document.LoadXml(feedText);
// Create the namespace manager
- XmlNamespaceManager namespaceManager = document.GetAllNamespaces();
+ var namespaceManager = document.GetAllNamespaces();
// Get the root node
XmlNode rootNode = document.DocumentElement;
@@ -37,7 +37,7 @@ namespace FeedCenter.FeedParsers
return FeedReadResult.InvalidXml;
// Initialize the sequence number for items
- int sequence = 0;
+ var sequence = 0;
// Loop over all nodes in the channel node
foreach (XmlNode node in channelNode.ChildNodes)
@@ -76,7 +76,7 @@ namespace FeedCenter.FeedParsers
protected override FeedItem ParseFeedItem(XmlNode node)
{
// Create a new feed item
- FeedItem feedItem = FeedItem.Create();
+ var feedItem = FeedItem.Create();
// Loop over all nodes in the feed node
foreach (XmlNode childNode in node.ChildNodes)
@@ -95,7 +95,7 @@ namespace FeedCenter.FeedParsers
case "guid":
feedItem.Guid = childNode.InnerText.Trim();
- bool permaLink = true;
+ var permaLink = true;
if (childNode.Attributes != null)
{
diff --git a/Application/Feeds/Category.cs b/Application/Feeds/Category.cs
index 90f0cfc..50e8b5d 100644
--- a/Application/Feeds/Category.cs
+++ b/Application/Feeds/Category.cs
@@ -1,15 +1,31 @@
using System;
+using System.Collections.Generic;
+using Realms;
namespace FeedCenter
{
- public partial class Category
+ public class Category : RealmObject
{
+ private const string DefaultCategoryName = "< default >";
+
+ [PrimaryKey]
+ [MapTo("ID")]
+ public Guid Id { get; set; }
+ public string Name { get; set; }
+
+ [Ignored]
+ public ICollection Feeds { get; set; }
+
public static Category Create()
{
- return new Category { ID = Guid.NewGuid() };
+ return new Category { Id = Guid.NewGuid() };
+ }
+ public static Category CreateDefault()
+ {
+ return new Category { Id = Guid.NewGuid(), Name = DefaultCategoryName };
}
- public bool IsDefault => Name == "< default >";
+ public bool IsDefault => Name == DefaultCategoryName;
// ReSharper disable once UnusedMember.Global
public int SortKey => IsDefault ? 0 : 1;
diff --git a/Application/Feeds/Feed.cs b/Application/Feeds/Feed.cs
index e9634cb..96e7e75 100644
--- a/Application/Feeds/Feed.cs
+++ b/Application/Feeds/Feed.cs
@@ -1,17 +1,21 @@
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Net;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Threading.Tasks;
-using Common.Debug;
+using Common.Debug;
using Common.Update;
using Common.Xml;
using FeedCenter.Data;
using FeedCenter.FeedParsers;
using FeedCenter.Properties;
+using Realms;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
namespace FeedCenter
{
@@ -55,8 +59,57 @@ namespace FeedCenter
#endregion
- public partial class Feed
+ public class Feed : RealmObject
{
+ [PrimaryKey]
+ [MapTo("ID")]
+ public Guid Id { get; set; }
+ public string Name { get; set; }
+ public string Title { get; set; }
+ public string Source { get; set; }
+ public string Link { get; set; }
+ public string Description { get; set; }
+ public DateTimeOffset LastChecked { get; set; }
+ public int CheckInterval { get; set; }
+ public bool Enabled { get; set; }
+ public bool Authenticate { get; set; }
+ public string Username { get; set; }
+ public string Password { get; set; }
+ public string Domain { get; set; }
+
+ private string LastReadResultRaw { get; set; }
+
+ public FeedReadResult LastReadResult
+ {
+ get => Enum.TryParse(LastReadResultRaw, out FeedReadResult result) ? result : FeedReadResult.Success;
+ set => LastReadResultRaw = value.ToString();
+ }
+
+ public DateTimeOffset LastUpdated { get; set; }
+
+ private string ItemComparisonRaw { get; set; }
+
+ public FeedItemComparison ItemComparison
+ {
+ get => Enum.TryParse(ItemComparisonRaw, out FeedItemComparison result) ? result : FeedItemComparison.Default;
+ set => ItemComparisonRaw = value.ToString();
+ }
+
+ [MapTo("CategoryID")]
+ public Guid CategoryId { get; set; }
+
+ private string MultipleOpenActionRaw { get; set; }
+
+ public MultipleOpenAction MultipleOpenAction
+ {
+ get => Enum.TryParse(MultipleOpenActionRaw, out MultipleOpenAction result) ? result : MultipleOpenAction.IndividualPages;
+ set => MultipleOpenActionRaw = value.ToString();
+ }
+
+ public Category Category { get; set; }
+
+ public IList Items { get; }
+
// ReSharper disable once UnusedMember.Global
public string LastReadResultDescription
{
@@ -66,7 +119,7 @@ namespace FeedCenter
var lastReadResult = LastReadResult;
// Build the name of the resource using the enum name and the value
- var resourceName = $"{typeof(FeedReadResult).Name}_{lastReadResult}";
+ var resourceName = $"{nameof(FeedReadResult)}_{lastReadResult}";
// Try to get the value from the resources
var resourceValue = Resources.ResourceManager.GetString(resourceName);
@@ -76,9 +129,11 @@ namespace FeedCenter
}
}
+ private static HttpClient _httpClient;
+
public static Feed Create(FeedCenterEntities database)
{
- return new Feed { ID = Guid.NewGuid(), CategoryID = database.DefaultCategory.ID };
+ return new Feed { Id = Guid.NewGuid(), CategoryId = database.DefaultCategory.Id };
}
#region Reading
@@ -109,7 +164,7 @@ namespace FeedCenter
// 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 == Extensions.SqlDateTimeZero.Value)
- LastUpdated = DateTime.Now;
+ LastUpdated = DateTimeOffset.Now;
Tracer.DecrementIndentLevel();
Tracer.WriteLine("Done reading feed: {0}", result);
@@ -138,74 +193,46 @@ namespace FeedCenter
{
try
{
- // Add extra security protocols
- ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
-
- // Create the web request
- var request = WebRequest.Create(new Uri(Source));
-
- // If this is an http request set some special properties
- if (request is HttpWebRequest webRequest)
+ // Create and configure the HTTP client if needed
+ if (_httpClient == null)
{
- // Make sure to use HTTP version 1.1
- webRequest.ProtocolVersion = HttpVersion.Version11;
-
- // Set that we'll accept compressed data
- webRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
-
- // Set a timeout
- webRequest.Timeout = 10000;
-
- // Make sure the service point closes the connection right away
- webRequest.ServicePoint.ConnectionLeaseTimeout = 0;
-
- // If we need to authenticate then set the credentials
- if (Authenticate)
- webRequest.Credentials = new NetworkCredential(Username, Password, Domain);
+ _httpClient = new HttpClient(new HttpClientHandler
+ {
+ // Set that we'll accept compressed data
+ AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
+ });
// Set a user agent string
- if (string.IsNullOrWhiteSpace(Settings.Default.DefaultUserAgent))
- webRequest.UserAgent = "FeedCenter/" + UpdateCheck.LocalVersion;
- else
- webRequest.UserAgent = Settings.Default.DefaultUserAgent;
+ var userAgent = string.IsNullOrWhiteSpace(Settings.Default.DefaultUserAgent) ? "FeedCenter/" + UpdateCheck.LocalVersion : Settings.Default.DefaultUserAgent;
+ _httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(userAgent);
+
+ // Set a timeout
+ _httpClient.Timeout = TimeSpan.FromSeconds(10);
}
- // Set the default encoding
- var encoding = Encoding.UTF8;
+ // If we need to authenticate then set the credentials
+ _httpClient.DefaultRequestHeaders.Authorization = Authenticate ? new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.UTF8.GetBytes($"{Username}:{Password}"))) : null;
// Attempt to get the response
- using (var response = (HttpWebResponse) request.GetResponse())
- {
- // If the response included an encoding then change the encoding
- if (response.ContentEncoding.Length > 0)
- encoding = Encoding.GetEncoding(response.ContentEncoding);
+ var feedStream = _httpClient.GetStreamAsync(Source).Result;
- // Get the response stream
- using (var responseStream = response.GetResponseStream())
- {
- if (responseStream == null)
- return Tuple.Create(FeedReadResult.NoResponse, string.Empty);
+ // Create the text reader
+ using StreamReader textReader = new XmlSanitizingStream(feedStream, Encoding.UTF8);
- // Create the text reader
- using (StreamReader textReader = new XmlSanitizingStream(responseStream, encoding))
- {
- // Get the feed text
- var feedText = textReader.ReadToEnd();
+ // Get the feed text
+ var feedText = textReader.ReadToEnd();
- // Get rid of any leading and trailing whitespace
- feedText = feedText.Trim();
+ // Get rid of any leading and trailing whitespace
+ feedText = feedText.Trim();
- // Clean up common invalid XML characters
- feedText = feedText.Replace(" ", " ");
+ // Clean up common invalid XML characters
+ feedText = feedText.Replace(" ", " ");
- // Find ampersands that aren't properly escaped and replace them with escaped versions
- var r = new Regex("&(?!(?:[a-z]+|#[0-9]+|#x[0-9a-f]+);)");
- feedText = r.Replace(feedText, "&");
+ // Find ampersands that aren't properly escaped and replace them with escaped versions
+ var r = new Regex("&(?!(?:[a-z]+|#[0-9]+|#x[0-9a-f]+);)");
+ feedText = r.Replace(feedText, "&");
- return Tuple.Create(FeedReadResult.Success, feedText);
- }
- }
- }
+ return Tuple.Create(FeedReadResult.Success, feedText);
}
catch (IOException ioException)
{
@@ -281,7 +308,7 @@ namespace FeedCenter
if (!forceRead)
{
// Figure out how long since we last checked
- var timeSpan = DateTime.Now - LastChecked;
+ var timeSpan = DateTimeOffset.Now - LastChecked;
// Check if we are due to read the feed
if (timeSpan.TotalMinutes < CheckInterval)
@@ -289,7 +316,7 @@ namespace FeedCenter
}
// We're checking it now so update the time
- LastChecked = DateTime.Now;
+ LastChecked = DateTimeOffset.Now;
// Read the feed text
var retrieveResult = RetrieveFeed();
@@ -322,16 +349,10 @@ namespace FeedCenter
// Loop over the items to be removed
foreach (var itemToRemove in removedItems)
{
- // Delete the item from the database
- database.FeedItems.Remove(itemToRemove);
-
// Remove the item from the list
Items.Remove(itemToRemove);
}
- // Process actions on this feed
- ProcessActions();
-
return FeedReadResult.Success;
}
catch (InvalidFeedFormatException exception)
@@ -348,22 +369,6 @@ namespace FeedCenter
}
}
- private void ProcessActions()
- {
- var sortedActions = from action in Actions orderby action.Sequence select action;
-
- foreach (var feedAction in sortedActions)
- {
- switch (feedAction.Field)
- {
- case 0:
- Title = Title.Replace(feedAction.Search, feedAction.Replace);
-
- break;
- }
- }
- }
-
#endregion
}
}
\ No newline at end of file
diff --git a/Application/Feeds/FeedAction.cs b/Application/Feeds/FeedAction.cs
deleted file mode 100644
index db13357..0000000
--- a/Application/Feeds/FeedAction.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-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
- }
-}
diff --git a/Application/Feeds/FeedItem.cs b/Application/Feeds/FeedItem.cs
index 6c4ed69..7f4c5d3 100644
--- a/Application/Feeds/FeedItem.cs
+++ b/Application/Feeds/FeedItem.cs
@@ -1,20 +1,40 @@
using System;
using System.Text.RegularExpressions;
+using FeedCenter.Options;
+using Realms;
namespace FeedCenter
{
- public partial class FeedItem
+ public class FeedItem : RealmObject
{
+ [PrimaryKey]
+ [MapTo("ID")]
+ public Guid Id { get; set; }
+
+ [MapTo("FeedID")]
+ public Guid FeedId { get; set; }
+
+ public string Title { get; set; }
+ public string Link { get; set; }
+ public string Description { get; set; }
+ public bool BeenRead { get; set; }
+ public DateTimeOffset LastFound { get; set; }
+ public bool New { get; set; }
+ public string Guid { get; set; }
+ public int Sequence { get; set; }
+
+ public Feed Feed { get; set; }
+
public static FeedItem Create()
{
- return new FeedItem { ID = System.Guid.NewGuid() };
+ return new FeedItem { Id = System.Guid.NewGuid() };
}
#region Methods
public override string ToString()
{
- string title = Title;
+ var title = Title;
switch (Properties.Settings.Default.MultipleLineDisplay)
{
@@ -28,13 +48,17 @@ namespace FeedCenter
case Options.MultipleLineDisplay.FirstLine:
// Find the first newline
- int newlineIndex = title.IndexOf("\n", StringComparison.Ordinal);
+ var newlineIndex = title.IndexOf("\n", StringComparison.Ordinal);
// If a newline was found return everything before it
if (newlineIndex > -1)
- title = title.Substring(0, newlineIndex);
+ title = title[..newlineIndex];
break;
+ case MultipleLineDisplay.Normal:
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
}
// Condense multiple spaces to one space
diff --git a/Application/FodyWeavers.xml b/Application/FodyWeavers.xml
new file mode 100644
index 0000000..cc07b89
--- /dev/null
+++ b/Application/FodyWeavers.xml
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/Application/FodyWeavers.xsd b/Application/FodyWeavers.xsd
new file mode 100644
index 0000000..fa5cb18
--- /dev/null
+++ b/Application/FodyWeavers.xsd
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+ Disables anonymized usage information from being sent on build. Read more about what data is being collected and why here: https://github.com/realm/realm-dotnet/blob/main/Realm/Realm.Weaver/Analytics.cs
+
+
+
+
+
+
+
+ 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.
+
+
+
+
+ A comma-separated list of error codes that can be safely ignored in assembly verification.
+
+
+
+
+ 'false' to turn off automatic generation of the XML Schema file.
+
+
+
+
+
\ No newline at end of file
diff --git a/Application/MainWindow/CategoryList.cs b/Application/MainWindow/CategoryList.cs
index ef2796b..96ec954 100644
--- a/Application/MainWindow/CategoryList.cs
+++ b/Application/MainWindow/CategoryList.cs
@@ -6,7 +6,7 @@ using FeedCenter.Properties;
namespace FeedCenter
{
- public partial class MainWindow
+ public partial class MainWindow : IDisposable
{
private void DisplayCategory()
{
@@ -44,7 +44,7 @@ namespace FeedCenter
Tag = category,
// Set the current item to bold
- FontWeight = category.ID == _currentCategory?.ID ? FontWeights.Bold : FontWeights.Normal
+ FontWeight = category.Id == _currentCategory?.Id ? FontWeights.Bold : FontWeights.Normal
};
// Handle the click
@@ -70,7 +70,7 @@ namespace FeedCenter
var category = (Category) menuItem.Tag;
// If the category changed then reset the current feed to the first in the category
- if (_currentCategory?.ID != category?.ID)
+ if (_currentCategory?.Id != category?.Id)
{
_currentFeed = category == null ? _database.Feeds.FirstOrDefault() : category.Feeds.FirstOrDefault();
}
@@ -79,9 +79,9 @@ namespace FeedCenter
_currentCategory = category;
// Get the current feed list to match the category
- _feedList = _currentCategory == null ? _database.Feeds : _database.Feeds.Where(feed => feed.Category.ID == _currentCategory.ID);
+ _feedList = _currentCategory == null ? _database.Feeds : _database.Feeds.Where(feed => feed.Category.Id == _currentCategory.Id);
- // Reset the feed index
+ // Refresh the feed index
_feedIndex = -1;
// Get the first feed
@@ -94,7 +94,14 @@ namespace FeedCenter
DisplayCategory();
DisplayFeed();
- Settings.Default.LastCategoryID = _currentCategory?.ID.ToString() ?? string.Empty;
+ Settings.Default.LastCategoryID = _currentCategory?.Id.ToString() ?? string.Empty;
+ }
+
+ public void Dispose()
+ {
+ _mainTimer?.Dispose();
+ _feedReadWorker?.Dispose();
+ _commandLineListener?.Dispose();
}
}
}
diff --git a/Application/MainWindow/DragDrop.cs b/Application/MainWindow/DragDrop.cs
index e628440..17eadd3 100644
--- a/Application/MainWindow/DragDrop.cs
+++ b/Application/MainWindow/DragDrop.cs
@@ -35,13 +35,16 @@ namespace FeedCenter
// Get the data as a string
var data = (string) e.Data.GetData(DataFormats.Text);
+ if (string.IsNullOrEmpty(data))
+ return;
+
// Check to see if the data starts with any known Chrome extension
- var chromeExtension = _chromeExtensions.FirstOrDefault(c => data.StartsWith(c));
+ var chromeExtension = _chromeExtensions.FirstOrDefault(data.StartsWith);
// Remove the Chrome extension URL and decode the URL
if (chromeExtension != null)
{
- data = data.Substring(chromeExtension.Length);
+ data = data[chromeExtension.Length..];
data = WebUtility.UrlDecode(data);
}
diff --git a/Application/MainWindow/FeedCreation.cs b/Application/MainWindow/FeedCreation.cs
index 00dc559..75e973f 100644
--- a/Application/MainWindow/FeedCreation.cs
+++ b/Application/MainWindow/FeedCreation.cs
@@ -64,10 +64,7 @@ namespace FeedCenter
feed.Name = feed.Title;
// Add the feed to the feed table
- _database.Feeds.Add(feed);
-
- // Save the changes
- _database.SaveChanges();
+ _database.SaveChanges(() => _database.Feeds.Add(feed));
// Show a tip
NotificationIcon.ShowBalloonTip(string.Format(Properties.Resources.FeedAddedNotification, feed.Name), System.Windows.Forms.ToolTipIcon.Info);
@@ -77,7 +74,7 @@ namespace FeedCenter
}
else
{
- // Feed read failed - ceate a new feed window
+ // Feed read failed - create a new feed window
var feedForm = new FeedWindow();
var dialogResult = feedForm.Display(_database, feed, this);
@@ -86,10 +83,7 @@ namespace FeedCenter
if (dialogResult.HasValue && dialogResult.Value)
{
// Add the feed to the feed table
- _database.Feeds.Add(feed);
-
- // Save the changes
- _database.SaveChanges();
+ _database.SaveChanges(() => _database.Feeds.Add(feed));
// Re-initialize the feed display
DisplayFeed();
diff --git a/Application/MainWindow/FeedList.cs b/Application/MainWindow/FeedList.cs
index 11e906f..5f3ce9f 100644
--- a/Application/MainWindow/FeedList.cs
+++ b/Application/MainWindow/FeedList.cs
@@ -34,15 +34,14 @@ namespace FeedCenter
var feedItem = (FeedItem) ((ListBoxItem) sender).DataContext;
// The feed item has been read and is no longer new
- feedItem.BeenRead = true;
- feedItem.New = false;
+ _database.SaveChanges(() =>
+ {
+ feedItem.BeenRead = true;
+ feedItem.New = false;
+ });
// Remove the item from the list
LinkTextList.Items.Remove(feedItem);
-
- // Save the changes
- _database.SaveChanges();
-
}
private void HandleItemMouseDoubleClick(object sender, MouseButtonEventArgs e)
@@ -54,14 +53,14 @@ namespace FeedCenter
if (BrowserCommon.OpenLink(feedItem.Link))
{
// The feed item has been read and is no longer new
- feedItem.BeenRead = true;
- feedItem.New = false;
+ _database.SaveChanges(() =>
+ {
+ feedItem.BeenRead = true;
+ feedItem.New = false;
+ });
// Remove the item from the list
LinkTextList.Items.Remove(feedItem);
-
- // Save the changes
- _database.SaveChanges();
}
}
@@ -83,10 +82,9 @@ namespace FeedCenter
Tag = feed,
// Set the current item to bold
- FontWeight = feed == _currentFeed ? FontWeights.Bold : FontWeights.Normal
+ FontWeight = feed.Id == _currentFeed.Id ? FontWeights.Bold : FontWeights.Normal
};
-
// Handle the click
menuItem.Click += HandleFeedMenuItemClick;
@@ -113,7 +111,7 @@ namespace FeedCenter
var feedIndex = 0;
foreach (var loopFeed in _feedList.OrderBy(loopFeed => loopFeed.Name))
{
- if (loopFeed == feed)
+ if (loopFeed.Id == feed.Id)
{
_feedIndex = feedIndex;
break;
diff --git a/Application/MainWindow/FeedReading.cs b/Application/MainWindow/FeedReading.cs
index e47c7aa..53ba953 100644
--- a/Application/MainWindow/FeedReading.cs
+++ b/Application/MainWindow/FeedReading.cs
@@ -21,7 +21,7 @@ namespace FeedCenter
private void SetProgressMode(bool value, int feedCount)
{
- // Reset the progress bar if we need it
+ // Refresh the progress bar if we need it
if (value)
{
FeedReadProgress.Value = 0;
@@ -65,7 +65,7 @@ namespace FeedCenter
return;
// Switch to progress mode
- SetProgressMode(true, _database.Feeds.Count());
+ SetProgressMode(true, _database.Feeds.Count);
// Create the input class
var workerInput = new FeedReadWorkerInput { ForceRead = forceRead, Feed = null };
@@ -82,7 +82,7 @@ namespace FeedCenter
private void HandleFeedReadWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
- // Reset the database to current settings
+ // Refresh the database to current settings
ResetDatabase();
// Save settings
@@ -123,10 +123,10 @@ namespace FeedCenter
var database = new FeedCenterEntities();
// Get the worker
- var worker = (BackgroundWorker) sender;
+ var worker = (BackgroundWorker)sender;
// Get the input information
- var workerInput = (FeedReadWorkerInput) e.Argument;
+ var workerInput = (FeedReadWorkerInput)e.Argument ?? new FeedReadWorkerInput { Feed = null, ForceRead = false };
// Setup for progress
var currentProgress = 0;
@@ -136,7 +136,7 @@ namespace FeedCenter
// If we have a single feed then add it to the list - otherwise add them all
if (workerInput.Feed != null)
- feedsToRead.Add(database.Feeds.First(feed => feed.ID == workerInput.Feed.ID));
+ feedsToRead.Add(database.Feeds.First(feed => feed.Id == workerInput.Feed.Id));
else
feedsToRead.AddRange(database.Feeds);
@@ -144,7 +144,7 @@ namespace FeedCenter
foreach (var feed in feedsToRead)
{
// Read the feed
- feed.Read(database, workerInput.ForceRead);
+ database.SaveChanges(() => feed.Read(database, workerInput.ForceRead));
// Increment progress
currentProgress += 1;
@@ -153,9 +153,6 @@ namespace FeedCenter
worker.ReportProgress(currentProgress);
}
- // Save the changes
- database.SaveChanges();
-
// Increment progress
currentProgress += 1;
@@ -166,7 +163,7 @@ namespace FeedCenter
if (DateTime.Now - Settings.Default.LastVersionCheck >= Settings.Default.VersionCheckInterval)
{
// Get the update information
- UpdateCheck.CheckForUpdate();
+ UpdateCheck.CheckForUpdate().Wait();
// Update the last check time
Settings.Default.LastVersionCheck = DateTime.Now;
diff --git a/Application/MainWindow/MainWindow.xaml.cs b/Application/MainWindow/MainWindow.xaml.cs
index 21d3e0e..803213d 100644
--- a/Application/MainWindow/MainWindow.xaml.cs
+++ b/Application/MainWindow/MainWindow.xaml.cs
@@ -2,8 +2,10 @@
using Common.Helpers;
using Common.IO;
using Common.Update;
+using FeedCenter.Data;
using FeedCenter.Properties;
using System;
+using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;
@@ -18,7 +20,7 @@ namespace FeedCenter
private int _feedIndex;
private Category _currentCategory;
- private IQueryable _feedList;
+ private IEnumerable _feedList;
private Feed _currentFeed;
public MainWindow()
@@ -26,7 +28,7 @@ namespace FeedCenter
InitializeComponent();
}
- public void Initialize()
+ public async void Initialize()
{
// Setup the update handler
InitializeUpdate();
@@ -48,7 +50,7 @@ namespace FeedCenter
_feedReadWorker.RunWorkerCompleted += HandleFeedReadWorkerCompleted;
// Setup the database
- _database = new FeedCenterEntities();
+ _database = Database.Entities;
// Initialize the command line listener
_commandLineListener = new InterprocessMessageListener(Properties.Resources.ApplicationName);
@@ -65,7 +67,7 @@ namespace FeedCenter
// Check for update
if (Settings.Default.CheckVersionAtStartup)
- UpdateCheck.CheckForUpdate();
+ await UpdateCheck.CheckForUpdate();
// Show the link if updates are available
if (UpdateCheck.UpdateAvailable)
@@ -136,18 +138,18 @@ namespace FeedCenter
private void InitializeDisplay()
{
// Get the last category (defaulting to none)
- _currentCategory = _database.Categories.FirstOrDefault(category => category.ID.ToString() == Settings.Default.LastCategoryID);
+ _currentCategory = _database.Categories.FirstOrDefault(category => category.Id.ToString() == Settings.Default.LastCategoryID);
DisplayCategory();
// Get the current feed list to match the category
- _feedList = _currentCategory == null ? _database.Feeds : _database.Feeds.Where(feed => feed.Category.ID == _currentCategory.ID);
+ _feedList = _currentCategory == null ? _database.Feeds : _database.Feeds.Where(feed => feed.Category.Id == _currentCategory.Id);
UpdateToolbarButtonState();
// Clear the link list
LinkTextList.Items.Clear();
- // Reset the feed index
+ // Refresh the feed index
_feedIndex = -1;
// Start the timer
@@ -341,11 +343,11 @@ namespace FeedCenter
private void MarkAllItemsAsRead()
{
// Loop over all items and mark them as read
- foreach (FeedItem feedItem in LinkTextList.Items)
- feedItem.BeenRead = true;
-
- // Save the changes
- _database.SaveChanges();
+ _database.SaveChanges(() =>
+ {
+ foreach (FeedItem feedItem in LinkTextList.Items)
+ feedItem.BeenRead = true;
+ });
// Clear the list
LinkTextList.Items.Clear();
@@ -358,12 +360,12 @@ namespace FeedCenter
private void ResetDatabase()
{
// Get the ID of the current feed
- var currentId = _currentFeed?.ID ?? Guid.Empty;
+ var currentId = _currentFeed?.Id ?? Guid.Empty;
// Create a new database object
- _database = new FeedCenterEntities();
+ _database.Refresh();
- _feedList = _currentCategory == null ? _database.Feeds : _database.Feeds.Where(feed => feed.Category.ID == _currentCategory.ID);
+ _feedList = _currentCategory == null ? _database.Feeds : _database.Feeds.Where(feed => feed.Category.Id == _currentCategory.Id);
UpdateToolbarButtonState();
@@ -371,7 +373,7 @@ namespace FeedCenter
var feedList = _feedList.OrderBy(f => f.Name).ToList();
// First try to find the current feed by ID to see if it is still there
- var newIndex = feedList.FindIndex(f => f.ID == currentId);
+ var newIndex = feedList.FindIndex(f => f.Id == currentId);
if (newIndex == -1)
{
diff --git a/Application/MainWindow/Toolbar.cs b/Application/MainWindow/Toolbar.cs
index b862b84..46c6ddf 100644
--- a/Application/MainWindow/Toolbar.cs
+++ b/Application/MainWindow/Toolbar.cs
@@ -42,7 +42,7 @@ namespace FeedCenter
if (BrowserCommon.OpenLink(browser, feedItem.Link))
{
// Mark the feed as read
- feedItem.BeenRead = true;
+ _database.SaveChanges(() => feedItem.BeenRead = true);
// Remove the item
LinkTextList.Items.Remove(feedItem);
@@ -54,9 +54,6 @@ namespace FeedCenter
// Switch to the normal sleep interval
sleepInterval = settings.OpenAllSleepInterval;
}
-
- // Save the changes
- _database.SaveChanges();
}
private void HandleOptionsToolbarButtonClick(object sender, RoutedEventArgs e)
@@ -70,7 +67,7 @@ namespace FeedCenter
// If okay was selected
if (result.HasValue && result.Value)
{
- // Reset the database to current settings
+ // Refresh the database to current settings
ResetDatabase();
// Re-initialize the feed display
@@ -94,7 +91,7 @@ namespace FeedCenter
// If okay was selected
if (result.GetValueOrDefault())
{
- // Reset the database to current settings
+ // Refresh the database to current settings
ResetDatabase();
// Re-initialize the feed display
@@ -156,7 +153,7 @@ namespace FeedCenter
if (result.HasValue && result.Value)
{
// Save
- _database.SaveChanges();
+ _database.SaveChanges(() => { });
// Update feed
DisplayFeed();
@@ -175,15 +172,8 @@ namespace FeedCenter
// Move to the next feed
NextFeed();
- // Delete all items
- foreach (var item in feedToDelete.Items.ToList())
- _database.FeedItems.Remove(item);
-
// Delete the feed
- _database.Feeds.Remove(feedToDelete);
-
- // Save
- _database.SaveChanges();
+ _database.SaveChanges(() => _database.Feeds.Remove(feedToDelete));
}
private void OpenAllFeedItemsOnSinglePage()
diff --git a/Application/MainWindow/WindowHandler.cs b/Application/MainWindow/WindowHandler.cs
index 5e6dedc..6e17bb7 100644
--- a/Application/MainWindow/WindowHandler.cs
+++ b/Application/MainWindow/WindowHandler.cs
@@ -90,10 +90,7 @@ namespace FeedCenter
SaveWindowSettings();
// Save settings
- Settings.Default.Save();
-
- // Save options
- _database.SaveChanges();
+ _database.SaveChanges(() => Settings.Default.Save());
// Get rid of the notification icon
NotificationIcon.Dispose();
@@ -102,16 +99,14 @@ namespace FeedCenter
private DelayedMethod _windowStateDelay;
private void HandleWindowSizeChanged(object sender, SizeChangedEventArgs e)
{
- if (_windowStateDelay == null)
- _windowStateDelay = new DelayedMethod(500, UpdateWindowSettings);
+ _windowStateDelay ??= new DelayedMethod(500, UpdateWindowSettings);
_windowStateDelay.Reset();
}
private void HandleWindowLocationChanged(object sender, EventArgs e)
{
- if (_windowStateDelay == null)
- _windowStateDelay = new DelayedMethod(500, UpdateWindowSettings);
+ _windowStateDelay ??= new DelayedMethod(500, UpdateWindowSettings);
_windowStateDelay.Reset();
}
diff --git a/Application/Model.Context.cs b/Application/Model.Context.cs
deleted file mode 100644
index 45a3afc..0000000
--- a/Application/Model.Context.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// This code was generated from a template.
-//
-// Manual changes to this file may cause unexpected behavior in your application.
-// Manual changes to this file will be overwritten if the code is regenerated.
-//
-//------------------------------------------------------------------------------
-
-namespace FeedCenter
-{
- using System;
- using System.Data.Entity;
- using System.Data.Entity.Infrastructure;
-
- public partial class FeedCenterEntities : DbContext
- {
- public FeedCenterEntities()
- : base("name=FeedCenterEntities")
- {
- }
-
- protected override void OnModelCreating(DbModelBuilder modelBuilder)
- {
- throw new UnintentionalCodeFirstException();
- }
-
- public virtual DbSet Categories { get; set; }
- public virtual DbSet Feeds { get; set; }
- public virtual DbSet FeedActions { get; set; }
- public virtual DbSet FeedItems { get; set; }
- public virtual DbSet Settings { get; set; }
- }
-}
diff --git a/Application/Model.Context.tt b/Application/Model.Context.tt
deleted file mode 100644
index cfb5c34..0000000
--- a/Application/Model.Context.tt
+++ /dev/null
@@ -1,636 +0,0 @@
-<#@ template language="C#" debug="false" hostspecific="true"#>
-<#@ include file="EF6.Utility.CS.ttinclude"#><#@
- output extension=".cs"#><#
-
-const string inputFile = @"Model.edmx";
-var textTransform = DynamicTextTransformation.Create(this);
-var code = new CodeGenerationTools(this);
-var ef = new MetadataTools(this);
-var typeMapper = new TypeMapper(code, ef, textTransform.Errors);
-var loader = new EdmMetadataLoader(textTransform.Host, textTransform.Errors);
-var itemCollection = loader.CreateEdmItemCollection(inputFile);
-var modelNamespace = loader.GetModelNamespace(inputFile);
-var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef);
-
-var container = itemCollection.OfType().FirstOrDefault();
-if (container == null)
-{
- return string.Empty;
-}
-#>
-//------------------------------------------------------------------------------
-//
-// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine1")#>
-//
-// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine2")#>
-// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine3")#>
-//
-//------------------------------------------------------------------------------
-
-<#
-
-var codeNamespace = code.VsNamespaceSuggestion();
-if (!String.IsNullOrEmpty(codeNamespace))
-{
-#>
-namespace <#=code.EscapeNamespace(codeNamespace)#>
-{
-<#
- PushIndent(" ");
-}
-
-#>
-using System;
-using System.Data.Entity;
-using System.Data.Entity.Infrastructure;
-<#
-if (container.FunctionImports.Any())
-{
-#>
-using System.Data.Entity.Core.Objects;
-using System.Linq;
-<#
-}
-#>
-
-<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext
-{
- public <#=code.Escape(container)#>()
- : base("name=<#=container.Name#>")
- {
-<#
-if (!loader.IsLazyLoadingEnabled(container))
-{
-#>
- this.Configuration.LazyLoadingEnabled = false;
-<#
-}
-
-foreach (var entitySet in container.BaseEntitySets.OfType())
-{
- // Note: the DbSet members are defined below such that the getter and
- // setter always have the same accessibility as the DbSet definition
- if (Accessibility.ForReadOnlyProperty(entitySet) != "public")
- {
-#>
- <#=codeStringGenerator.DbSetInitializer(entitySet)#>
-<#
- }
-}
-#>
- }
-
- protected override void OnModelCreating(DbModelBuilder modelBuilder)
- {
- throw new UnintentionalCodeFirstException();
- }
-
-<#
- foreach (var entitySet in container.BaseEntitySets.OfType())
- {
-#>
- <#=codeStringGenerator.DbSet(entitySet)#>
-<#
- }
-
- foreach (var edmFunction in container.FunctionImports)
- {
- WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: false);
- }
-#>
-}
-<#
-
-if (!String.IsNullOrEmpty(codeNamespace))
-{
- PopIndent();
-#>
-}
-<#
-}
-#>
-<#+
-
-private void WriteFunctionImport(TypeMapper typeMapper, CodeStringGenerator codeStringGenerator, EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
-{
- if (typeMapper.IsComposable(edmFunction))
- {
-#>
-
- [DbFunction("<#=edmFunction.NamespaceName#>", "<#=edmFunction.Name#>")]
- <#=codeStringGenerator.ComposableFunctionMethod(edmFunction, modelNamespace)#>
- {
-<#+
- codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter);
-#>
- <#=codeStringGenerator.ComposableCreateQuery(edmFunction, modelNamespace)#>
- }
-<#+
- }
- else
- {
-#>
-
- <#=codeStringGenerator.FunctionMethod(edmFunction, modelNamespace, includeMergeOption)#>
- {
-<#+
- codeStringGenerator.WriteFunctionParameters(edmFunction, WriteFunctionParameter);
-#>
- <#=codeStringGenerator.ExecuteFunction(edmFunction, modelNamespace, includeMergeOption)#>
- }
-<#+
- if (typeMapper.GenerateMergeOptionFunction(edmFunction, includeMergeOption))
- {
- WriteFunctionImport(typeMapper, codeStringGenerator, edmFunction, modelNamespace, includeMergeOption: true);
- }
- }
-}
-
-public void WriteFunctionParameter(string name, string isNotNull, string notNullInit, string nullInit)
-{
-#>
- var <#=name#> = <#=isNotNull#> ?
- <#=notNullInit#> :
- <#=nullInit#>;
-
-<#+
-}
-
-public const string TemplateId = "CSharp_DbContext_Context_EF6";
-
-public class CodeStringGenerator
-{
- private readonly CodeGenerationTools _code;
- private readonly TypeMapper _typeMapper;
- private readonly MetadataTools _ef;
-
- public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef)
- {
- ArgumentNotNull(code, "code");
- ArgumentNotNull(typeMapper, "typeMapper");
- ArgumentNotNull(ef, "ef");
-
- _code = code;
- _typeMapper = typeMapper;
- _ef = ef;
- }
-
- public string Property(EdmProperty edmProperty)
- {
- return string.Format(
- CultureInfo.InvariantCulture,
- "{0} {1} {2} {{ {3}get; {4}set; }}",
- Accessibility.ForProperty(edmProperty),
- _typeMapper.GetTypeName(edmProperty.TypeUsage),
- _code.Escape(edmProperty),
- _code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
- _code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
- }
-
- public string NavigationProperty(NavigationProperty navProp)
- {
- var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType());
- return string.Format(
- CultureInfo.InvariantCulture,
- "{0} {1} {2} {{ {3}get; {4}set; }}",
- AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)),
- navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
- _code.Escape(navProp),
- _code.SpaceAfter(Accessibility.ForGetter(navProp)),
- _code.SpaceAfter(Accessibility.ForSetter(navProp)));
- }
-
- public string AccessibilityAndVirtual(string accessibility)
- {
- return accessibility + (accessibility != "private" ? " virtual" : "");
- }
-
- public string EntityClassOpening(EntityType entity)
- {
- return string.Format(
- CultureInfo.InvariantCulture,
- "{0} {1}partial class {2}{3}",
- Accessibility.ForType(entity),
- _code.SpaceAfter(_code.AbstractOption(entity)),
- _code.Escape(entity),
- _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
- }
-
- public string EnumOpening(SimpleType enumType)
- {
- return string.Format(
- CultureInfo.InvariantCulture,
- "{0} enum {1} : {2}",
- Accessibility.ForType(enumType),
- _code.Escape(enumType),
- _code.Escape(_typeMapper.UnderlyingClrType(enumType)));
- }
-
- public void WriteFunctionParameters(EdmFunction edmFunction, Action writeParameter)
- {
- var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
- foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable))
- {
- var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null";
- var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")";
- var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + TypeMapper.FixNamespaces(parameter.RawClrTypeName) + "))";
- writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit);
- }
- }
-
- public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace)
- {
- var parameters = _typeMapper.GetParameters(edmFunction);
-
- return string.Format(
- CultureInfo.InvariantCulture,
- "{0} IQueryable<{1}> {2}({3})",
- AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
- _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
- _code.Escape(edmFunction),
- string.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray()));
- }
-
- public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace)
- {
- var parameters = _typeMapper.GetParameters(edmFunction);
-
- return string.Format(
- CultureInfo.InvariantCulture,
- "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});",
- _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
- edmFunction.NamespaceName,
- edmFunction.Name,
- string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()),
- _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())));
- }
-
- public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
- {
- var parameters = _typeMapper.GetParameters(edmFunction);
- var returnType = _typeMapper.GetReturnType(edmFunction);
-
- var paramList = String.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray());
- if (includeMergeOption)
- {
- paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption";
- }
-
- return string.Format(
- CultureInfo.InvariantCulture,
- "{0} {1} {2}({3})",
- AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
- returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
- _code.Escape(edmFunction),
- paramList);
- }
-
- public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
- {
- var parameters = _typeMapper.GetParameters(edmFunction);
- var returnType = _typeMapper.GetReturnType(edmFunction);
-
- var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()));
- if (includeMergeOption)
- {
- callParams = ", mergeOption" + callParams;
- }
-
- return string.Format(
- CultureInfo.InvariantCulture,
- "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});",
- returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
- edmFunction.Name,
- callParams);
- }
-
- public string DbSet(EntitySet entitySet)
- {
- return string.Format(
- CultureInfo.InvariantCulture,
- "{0} virtual DbSet<{1}> {2} {{ get; set; }}",
- Accessibility.ForReadOnlyProperty(entitySet),
- _typeMapper.GetTypeName(entitySet.ElementType),
- _code.Escape(entitySet));
- }
-
- public string DbSetInitializer(EntitySet entitySet)
- {
- return string.Format(
- CultureInfo.InvariantCulture,
- "{0} = Set<{1}>();",
- _code.Escape(entitySet),
- _typeMapper.GetTypeName(entitySet.ElementType));
- }
-
- public string UsingDirectives(bool inHeader, bool includeCollections = true)
- {
- return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
- ? string.Format(
- CultureInfo.InvariantCulture,
- "{0}using System;{1}" +
- "{2}",
- inHeader ? Environment.NewLine : "",
- includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
- inHeader ? "" : Environment.NewLine)
- : "";
- }
-}
-
-public class TypeMapper
-{
- private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName";
-
- private readonly System.Collections.IList _errors;
- private readonly CodeGenerationTools _code;
- private readonly MetadataTools _ef;
-
- public static string FixNamespaces(string typeName)
- {
- return typeName.Replace("System.Data.Spatial.", "System.Data.Entity.Spatial.");
- }
-
- public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors)
- {
- ArgumentNotNull(code, "code");
- ArgumentNotNull(ef, "ef");
- ArgumentNotNull(errors, "errors");
-
- _code = code;
- _ef = ef;
- _errors = errors;
- }
-
- public string GetTypeName(TypeUsage typeUsage)
- {
- return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null);
- }
-
- public string GetTypeName(EdmType edmType)
- {
- return GetTypeName(edmType, isNullable: null, modelNamespace: null);
- }
-
- public string GetTypeName(TypeUsage typeUsage, string modelNamespace)
- {
- return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace);
- }
-
- public string GetTypeName(EdmType edmType, string modelNamespace)
- {
- return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace);
- }
-
- public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace)
- {
- if (edmType == null)
- {
- return null;
- }
-
- var collectionType = edmType as CollectionType;
- if (collectionType != null)
- {
- return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace));
- }
-
- var typeName = _code.Escape(edmType.MetadataProperties
- .Where(p => p.Name == ExternalTypeNameAttributeName)
- .Select(p => (string)p.Value)
- .FirstOrDefault())
- ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ?
- _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) :
- _code.Escape(edmType));
-
- if (edmType is StructuralType)
- {
- return typeName;
- }
-
- if (edmType is SimpleType)
- {
- var clrType = UnderlyingClrType(edmType);
- if (!IsEnumType(edmType))
- {
- typeName = _code.Escape(clrType);
- }
-
- typeName = FixNamespaces(typeName);
-
- return clrType.IsValueType && isNullable == true ?
- String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) :
- typeName;
- }
-
- throw new ArgumentException("edmType");
- }
-
- public Type UnderlyingClrType(EdmType edmType)
- {
- ArgumentNotNull(edmType, "edmType");
-
- var primitiveType = edmType as PrimitiveType;
- if (primitiveType != null)
- {
- return primitiveType.ClrEquivalentType;
- }
-
- if (IsEnumType(edmType))
- {
- return GetEnumUnderlyingType(edmType).ClrEquivalentType;
- }
-
- return typeof(object);
- }
-
- public object GetEnumMemberValue(MetadataItem enumMember)
- {
- ArgumentNotNull(enumMember, "enumMember");
-
- var valueProperty = enumMember.GetType().GetProperty("Value");
- return valueProperty == null ? null : valueProperty.GetValue(enumMember, null);
- }
-
- public string GetEnumMemberName(MetadataItem enumMember)
- {
- ArgumentNotNull(enumMember, "enumMember");
-
- var nameProperty = enumMember.GetType().GetProperty("Name");
- return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null);
- }
-
- public System.Collections.IEnumerable GetEnumMembers(EdmType enumType)
- {
- ArgumentNotNull(enumType, "enumType");
-
- var membersProperty = enumType.GetType().GetProperty("Members");
- return membersProperty != null
- ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null)
- : Enumerable.Empty();
- }
-
- public bool EnumIsFlags(EdmType enumType)
- {
- ArgumentNotNull(enumType, "enumType");
-
- var isFlagsProperty = enumType.GetType().GetProperty("IsFlags");
- return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null);
- }
-
- public bool IsEnumType(GlobalItem edmType)
- {
- ArgumentNotNull(edmType, "edmType");
-
- return edmType.GetType().Name == "EnumType";
- }
-
- public PrimitiveType GetEnumUnderlyingType(EdmType enumType)
- {
- ArgumentNotNull(enumType, "enumType");
-
- return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null);
- }
-
- public string CreateLiteral(object value)
- {
- if (value == null || value.GetType() != typeof(TimeSpan))
- {
- return _code.CreateLiteral(value);
- }
-
- return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks);
- }
-
- public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable types, string sourceFile)
- {
- ArgumentNotNull(types, "types");
- ArgumentNotNull(sourceFile, "sourceFile");
-
- var hash = new HashSet(StringComparer.InvariantCultureIgnoreCase);
- if (types.Any(item => !hash.Add(item)))
- {
- _errors.Add(
- new CompilerError(sourceFile, -1, -1, "6023",
- String.Format(CultureInfo.CurrentCulture, CodeGenerationTools.GetResourceString("Template_CaseInsensitiveTypeConflict"))));
- return false;
- }
- return true;
- }
-
- public IEnumerable GetEnumItemsToGenerate(IEnumerable itemCollection)
- {
- return GetItemsToGenerate(itemCollection)
- .Where(e => IsEnumType(e));
- }
-
- public IEnumerable GetItemsToGenerate(IEnumerable itemCollection) where T: EdmType
- {
- return itemCollection
- .OfType()
- .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName))
- .OrderBy(i => i.Name);
- }
-
- public IEnumerable GetAllGlobalItems(IEnumerable itemCollection)
- {
- return itemCollection
- .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i))
- .Select(g => GetGlobalItemName(g));
- }
-
- public string GetGlobalItemName(GlobalItem item)
- {
- if (item is EdmType)
- {
- return ((EdmType)item).Name;
- }
- else
- {
- return ((EntityContainer)item).Name;
- }
- }
-
- public IEnumerable GetSimpleProperties(EntityType type)
- {
- return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
- }
-
- public IEnumerable GetSimpleProperties(ComplexType type)
- {
- return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
- }
-
- public IEnumerable GetComplexProperties(EntityType type)
- {
- return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
- }
-
- public IEnumerable GetComplexProperties(ComplexType type)
- {
- return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
- }
-
- public IEnumerable GetPropertiesWithDefaultValues(EntityType type)
- {
- return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
- }
-
- public IEnumerable GetPropertiesWithDefaultValues(ComplexType type)
- {
- return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
- }
-
- public IEnumerable GetNavigationProperties(EntityType type)
- {
- return type.NavigationProperties.Where(np => np.DeclaringType == type);
- }
-
- public IEnumerable GetCollectionNavigationProperties(EntityType type)
- {
- return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
- }
-
- public FunctionParameter GetReturnParameter(EdmFunction edmFunction)
- {
- ArgumentNotNull(edmFunction, "edmFunction");
-
- var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters");
- return returnParamsProperty == null
- ? edmFunction.ReturnParameter
- : ((IEnumerable)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault();
- }
-
- public bool IsComposable(EdmFunction edmFunction)
- {
- ArgumentNotNull(edmFunction, "edmFunction");
-
- var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute");
- return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null);
- }
-
- public IEnumerable GetParameters(EdmFunction edmFunction)
- {
- return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
- }
-
- public TypeUsage GetReturnType(EdmFunction edmFunction)
- {
- var returnParam = GetReturnParameter(edmFunction);
- return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage);
- }
-
- public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption)
- {
- var returnType = GetReturnType(edmFunction);
- return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType;
- }
-}
-
-public static void ArgumentNotNull(T arg, string name) where T : class
-{
- if (arg == null)
- {
- throw new ArgumentNullException(name);
- }
-}
-#>
\ No newline at end of file
diff --git a/Application/Model.Designer.cs b/Application/Model.Designer.cs
deleted file mode 100644
index c582988..0000000
--- a/Application/Model.Designer.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-// T4 code generation is enabled for model 'D:\Code\Personal\FeedCenter\Application\Model.edmx'.
-// To enable legacy code generation, change the value of the 'Code Generation Strategy' designer
-// property to 'Legacy ObjectContext'. This property is available in the Properties Window when the model
-// is open in the designer.
-
-// If no context and entity classes have been generated, it may be because you created an empty model but
-// have not yet chosen which version of Entity Framework to use. To generate a context class and entity
-// classes for your model, open the model in the designer, right-click on the designer surface, and
-// select 'Update Model from Database...', 'Generate Database from Model...', or 'Add Code Generation
-// Item...'.
\ No newline at end of file
diff --git a/Application/Model.cs b/Application/Model.cs
deleted file mode 100644
index 7cc0662..0000000
--- a/Application/Model.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// This code was generated from a template.
-//
-// Manual changes to this file may cause unexpected behavior in your application.
-// Manual changes to this file will be overwritten if the code is regenerated.
-//
-//------------------------------------------------------------------------------
-
diff --git a/Application/Model.edmx b/Application/Model.edmx
deleted file mode 100644
index 8feef63..0000000
--- a/Application/Model.edmx
+++ /dev/null
@@ -1,383 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Application/Model.tt b/Application/Model.tt
deleted file mode 100644
index 1205534..0000000
--- a/Application/Model.tt
+++ /dev/null
@@ -1,726 +0,0 @@
-<#@ template language="C#" debug="false" hostspecific="true"#>
-<#@ include file="EF6.Utility.CS.ttinclude"#><#@
- output extension=".cs"#><#
-
-const string inputFile = @"Model.edmx";
-var textTransform = DynamicTextTransformation.Create(this);
-var code = new CodeGenerationTools(this);
-var ef = new MetadataTools(this);
-var typeMapper = new TypeMapper(code, ef, textTransform.Errors);
-var fileManager = EntityFrameworkTemplateFileManager.Create(this);
-var itemCollection = new EdmMetadataLoader(textTransform.Host, textTransform.Errors).CreateEdmItemCollection(inputFile);
-var codeStringGenerator = new CodeStringGenerator(code, typeMapper, ef);
-
-if (!typeMapper.VerifyCaseInsensitiveTypeUniqueness(typeMapper.GetAllGlobalItems(itemCollection), inputFile))
-{
- return string.Empty;
-}
-
-WriteHeader(codeStringGenerator, fileManager);
-
-foreach (var entity in typeMapper.GetItemsToGenerate(itemCollection))
-{
- fileManager.StartNewFile(entity.Name + ".cs");
- BeginNamespace(code);
-#>
-<#=codeStringGenerator.UsingDirectives(inHeader: false)#>
-<#=codeStringGenerator.EntityClassOpening(entity)#>
-{
-<#
- var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(entity);
- var collectionNavigationProperties = typeMapper.GetCollectionNavigationProperties(entity);
- var complexProperties = typeMapper.GetComplexProperties(entity);
-
- if (propertiesWithDefaultValues.Any() || collectionNavigationProperties.Any() || complexProperties.Any())
- {
-#>
- public <#=code.Escape(entity)#>()
- {
-<#
- foreach (var edmProperty in propertiesWithDefaultValues)
- {
-#>
- this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>;
-<#
- }
-
- foreach (var navigationProperty in collectionNavigationProperties)
- {
-#>
- this.<#=code.Escape(navigationProperty)#> = new HashSet<<#=typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType())#>>();
-<#
- }
-
- foreach (var complexProperty in complexProperties)
- {
-#>
- this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>();
-<#
- }
-#>
- }
-
-<#
- }
-
- var simpleProperties = typeMapper.GetSimpleProperties(entity);
- if (simpleProperties.Any())
- {
- foreach (var edmProperty in simpleProperties)
- {
-#>
- <#=codeStringGenerator.Property(edmProperty)#>
-<#
- }
- }
-
- if (complexProperties.Any())
- {
-#>
-
-<#
- foreach(var complexProperty in complexProperties)
- {
-#>
- <#=codeStringGenerator.Property(complexProperty)#>
-<#
- }
- }
-
- var navigationProperties = typeMapper.GetNavigationProperties(entity);
- if (navigationProperties.Any())
- {
-#>
-
-<#
- foreach (var navigationProperty in navigationProperties)
- {
-#>
- <#=codeStringGenerator.NavigationProperty(navigationProperty)#>
-<#
- }
- }
-#>
-}
-<#
- EndNamespace(code);
-}
-
-foreach (var complex in typeMapper.GetItemsToGenerate(itemCollection))
-{
- fileManager.StartNewFile(complex.Name + ".cs");
- BeginNamespace(code);
-#>
-<#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#>
-<#=Accessibility.ForType(complex)#> partial class <#=code.Escape(complex)#>
-{
-<#
- var complexProperties = typeMapper.GetComplexProperties(complex);
- var propertiesWithDefaultValues = typeMapper.GetPropertiesWithDefaultValues(complex);
-
- if (propertiesWithDefaultValues.Any() || complexProperties.Any())
- {
-#>
- public <#=code.Escape(complex)#>()
- {
-<#
- foreach (var edmProperty in propertiesWithDefaultValues)
- {
-#>
- this.<#=code.Escape(edmProperty)#> = <#=typeMapper.CreateLiteral(edmProperty.DefaultValue)#>;
-<#
- }
-
- foreach (var complexProperty in complexProperties)
- {
-#>
- this.<#=code.Escape(complexProperty)#> = new <#=typeMapper.GetTypeName(complexProperty.TypeUsage)#>();
-<#
- }
-#>
- }
-
-<#
- }
-
- var simpleProperties = typeMapper.GetSimpleProperties(complex);
- if (simpleProperties.Any())
- {
- foreach(var edmProperty in simpleProperties)
- {
-#>
- <#=codeStringGenerator.Property(edmProperty)#>
-<#
- }
- }
-
- if (complexProperties.Any())
- {
-#>
-
-<#
- foreach(var edmProperty in complexProperties)
- {
-#>
- <#=codeStringGenerator.Property(edmProperty)#>
-<#
- }
- }
-#>
-}
-<#
- EndNamespace(code);
-}
-
-foreach (var enumType in typeMapper.GetEnumItemsToGenerate(itemCollection))
-{
- fileManager.StartNewFile(enumType.Name + ".cs");
- BeginNamespace(code);
-#>
-<#=codeStringGenerator.UsingDirectives(inHeader: false, includeCollections: false)#>
-<#
- if (typeMapper.EnumIsFlags(enumType))
- {
-#>
-[Flags]
-<#
- }
-#>
-<#=codeStringGenerator.EnumOpening(enumType)#>
-{
-<#
- var foundOne = false;
-
- foreach (MetadataItem member in typeMapper.GetEnumMembers(enumType))
- {
- foundOne = true;
-#>
- <#=code.Escape(typeMapper.GetEnumMemberName(member))#> = <#=typeMapper.GetEnumMemberValue(member)#>,
-<#
- }
-
- if (foundOne)
- {
- this.GenerationEnvironment.Remove(this.GenerationEnvironment.Length - 3, 1);
- }
-#>
-}
-<#
- EndNamespace(code);
-}
-
-fileManager.Process();
-
-#>
-<#+
-
-public void WriteHeader(CodeStringGenerator codeStringGenerator, EntityFrameworkTemplateFileManager fileManager)
-{
- fileManager.StartHeader();
-#>
-//------------------------------------------------------------------------------
-//
-// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine1")#>
-//
-// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine2")#>
-// <#=CodeGenerationTools.GetResourceString("Template_GeneratedCodeCommentLine3")#>
-//
-//------------------------------------------------------------------------------
-<#=codeStringGenerator.UsingDirectives(inHeader: true)#>
-<#+
- fileManager.EndBlock();
-}
-
-public void BeginNamespace(CodeGenerationTools code)
-{
- var codeNamespace = code.VsNamespaceSuggestion();
- if (!String.IsNullOrEmpty(codeNamespace))
- {
-#>
-namespace <#=code.EscapeNamespace(codeNamespace)#>
-{
-<#+
- PushIndent(" ");
- }
-}
-
-public void EndNamespace(CodeGenerationTools code)
-{
- if (!String.IsNullOrEmpty(code.VsNamespaceSuggestion()))
- {
- PopIndent();
-#>
-}
-<#+
- }
-}
-
-public const string TemplateId = "CSharp_DbContext_Types_EF6";
-
-public class CodeStringGenerator
-{
- private readonly CodeGenerationTools _code;
- private readonly TypeMapper _typeMapper;
- private readonly MetadataTools _ef;
-
- public CodeStringGenerator(CodeGenerationTools code, TypeMapper typeMapper, MetadataTools ef)
- {
- ArgumentNotNull(code, "code");
- ArgumentNotNull(typeMapper, "typeMapper");
- ArgumentNotNull(ef, "ef");
-
- _code = code;
- _typeMapper = typeMapper;
- _ef = ef;
- }
-
- public string Property(EdmProperty edmProperty)
- {
- return string.Format(
- CultureInfo.InvariantCulture,
- "{0} {1} {2} {{ {3}get; {4}set; }}",
- Accessibility.ForProperty(edmProperty),
- _typeMapper.GetTypeName(edmProperty.TypeUsage),
- _code.Escape(edmProperty),
- _code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
- _code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
- }
-
- public string NavigationProperty(NavigationProperty navProp)
- {
- var endType = _typeMapper.GetTypeName(navProp.ToEndMember.GetEntityType());
- return string.Format(
- CultureInfo.InvariantCulture,
- "{0} {1} {2} {{ {3}get; {4}set; }}",
- AccessibilityAndVirtual(Accessibility.ForNavigationProperty(navProp)),
- navProp.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? ("ICollection<" + endType + ">") : endType,
- _code.Escape(navProp),
- _code.SpaceAfter(Accessibility.ForGetter(navProp)),
- _code.SpaceAfter(Accessibility.ForSetter(navProp)));
- }
-
- public string AccessibilityAndVirtual(string accessibility)
- {
- return accessibility + (accessibility != "private" ? " virtual" : "");
- }
-
- public string EntityClassOpening(EntityType entity)
- {
- return string.Format(
- CultureInfo.InvariantCulture,
- "{0} {1}partial class {2}{3}",
- Accessibility.ForType(entity),
- _code.SpaceAfter(_code.AbstractOption(entity)),
- _code.Escape(entity),
- _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
- }
-
- public string EnumOpening(SimpleType enumType)
- {
- return string.Format(
- CultureInfo.InvariantCulture,
- "{0} enum {1} : {2}",
- Accessibility.ForType(enumType),
- _code.Escape(enumType),
- _code.Escape(_typeMapper.UnderlyingClrType(enumType)));
- }
-
- public void WriteFunctionParameters(EdmFunction edmFunction, Action writeParameter)
- {
- var parameters = FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
- foreach (var parameter in parameters.Where(p => p.NeedsLocalVariable))
- {
- var isNotNull = parameter.IsNullableOfT ? parameter.FunctionParameterName + ".HasValue" : parameter.FunctionParameterName + " != null";
- var notNullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", " + parameter.FunctionParameterName + ")";
- var nullInit = "new ObjectParameter(\"" + parameter.EsqlParameterName + "\", typeof(" + TypeMapper.FixNamespaces(parameter.RawClrTypeName) + "))";
- writeParameter(parameter.LocalVariableName, isNotNull, notNullInit, nullInit);
- }
- }
-
- public string ComposableFunctionMethod(EdmFunction edmFunction, string modelNamespace)
- {
- var parameters = _typeMapper.GetParameters(edmFunction);
-
- return string.Format(
- CultureInfo.InvariantCulture,
- "{0} IQueryable<{1}> {2}({3})",
- AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
- _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
- _code.Escape(edmFunction),
- string.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray()));
- }
-
- public string ComposableCreateQuery(EdmFunction edmFunction, string modelNamespace)
- {
- var parameters = _typeMapper.GetParameters(edmFunction);
-
- return string.Format(
- CultureInfo.InvariantCulture,
- "return ((IObjectContextAdapter)this).ObjectContext.CreateQuery<{0}>(\"[{1}].[{2}]({3})\"{4});",
- _typeMapper.GetTypeName(_typeMapper.GetReturnType(edmFunction), modelNamespace),
- edmFunction.NamespaceName,
- edmFunction.Name,
- string.Join(", ", parameters.Select(p => "@" + p.EsqlParameterName).ToArray()),
- _code.StringBefore(", ", string.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray())));
- }
-
- public string FunctionMethod(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
- {
- var parameters = _typeMapper.GetParameters(edmFunction);
- var returnType = _typeMapper.GetReturnType(edmFunction);
-
- var paramList = String.Join(", ", parameters.Select(p => TypeMapper.FixNamespaces(p.FunctionParameterType) + " " + p.FunctionParameterName).ToArray());
- if (includeMergeOption)
- {
- paramList = _code.StringAfter(paramList, ", ") + "MergeOption mergeOption";
- }
-
- return string.Format(
- CultureInfo.InvariantCulture,
- "{0} {1} {2}({3})",
- AccessibilityAndVirtual(Accessibility.ForMethod(edmFunction)),
- returnType == null ? "int" : "ObjectResult<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
- _code.Escape(edmFunction),
- paramList);
- }
-
- public string ExecuteFunction(EdmFunction edmFunction, string modelNamespace, bool includeMergeOption)
- {
- var parameters = _typeMapper.GetParameters(edmFunction);
- var returnType = _typeMapper.GetReturnType(edmFunction);
-
- var callParams = _code.StringBefore(", ", String.Join(", ", parameters.Select(p => p.ExecuteParameterName).ToArray()));
- if (includeMergeOption)
- {
- callParams = ", mergeOption" + callParams;
- }
-
- return string.Format(
- CultureInfo.InvariantCulture,
- "return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction{0}(\"{1}\"{2});",
- returnType == null ? "" : "<" + _typeMapper.GetTypeName(returnType, modelNamespace) + ">",
- edmFunction.Name,
- callParams);
- }
-
- public string DbSet(EntitySet entitySet)
- {
- return string.Format(
- CultureInfo.InvariantCulture,
- "{0} virtual DbSet<{1}> {2} {{ get; set; }}",
- Accessibility.ForReadOnlyProperty(entitySet),
- _typeMapper.GetTypeName(entitySet.ElementType),
- _code.Escape(entitySet));
- }
-
- public string UsingDirectives(bool inHeader, bool includeCollections = true)
- {
- return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
- ? string.Format(
- CultureInfo.InvariantCulture,
- "{0}using System;{1}" +
- "{2}",
- inHeader ? Environment.NewLine : "",
- includeCollections ? (Environment.NewLine + "using System.Collections.Generic;") : "",
- inHeader ? "" : Environment.NewLine)
- : "";
- }
-}
-
-public class TypeMapper
-{
- private const string ExternalTypeNameAttributeName = @"http://schemas.microsoft.com/ado/2006/04/codegeneration:ExternalTypeName";
-
- private readonly System.Collections.IList _errors;
- private readonly CodeGenerationTools _code;
- private readonly MetadataTools _ef;
-
- public TypeMapper(CodeGenerationTools code, MetadataTools ef, System.Collections.IList errors)
- {
- ArgumentNotNull(code, "code");
- ArgumentNotNull(ef, "ef");
- ArgumentNotNull(errors, "errors");
-
- _code = code;
- _ef = ef;
- _errors = errors;
- }
-
- public static string FixNamespaces(string typeName)
- {
- return typeName.Replace("System.Data.Spatial.", "System.Data.Entity.Spatial.");
- }
-
- public string GetTypeName(TypeUsage typeUsage)
- {
- return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace: null);
- }
-
- public string GetTypeName(EdmType edmType)
- {
- return GetTypeName(edmType, isNullable: null, modelNamespace: null);
- }
-
- public string GetTypeName(TypeUsage typeUsage, string modelNamespace)
- {
- return typeUsage == null ? null : GetTypeName(typeUsage.EdmType, _ef.IsNullable(typeUsage), modelNamespace);
- }
-
- public string GetTypeName(EdmType edmType, string modelNamespace)
- {
- return GetTypeName(edmType, isNullable: null, modelNamespace: modelNamespace);
- }
-
- public string GetTypeName(EdmType edmType, bool? isNullable, string modelNamespace)
- {
- if (edmType == null)
- {
- return null;
- }
-
- var collectionType = edmType as CollectionType;
- if (collectionType != null)
- {
- return String.Format(CultureInfo.InvariantCulture, "ICollection<{0}>", GetTypeName(collectionType.TypeUsage, modelNamespace));
- }
-
- var typeName = _code.Escape(edmType.MetadataProperties
- .Where(p => p.Name == ExternalTypeNameAttributeName)
- .Select(p => (string)p.Value)
- .FirstOrDefault())
- ?? (modelNamespace != null && edmType.NamespaceName != modelNamespace ?
- _code.CreateFullName(_code.EscapeNamespace(edmType.NamespaceName), _code.Escape(edmType)) :
- _code.Escape(edmType));
-
- if (edmType is StructuralType)
- {
- return typeName;
- }
-
- if (edmType is SimpleType)
- {
- var clrType = UnderlyingClrType(edmType);
- if (!IsEnumType(edmType))
- {
- typeName = _code.Escape(clrType);
- }
-
- typeName = FixNamespaces(typeName);
-
- return clrType.IsValueType && isNullable == true ?
- String.Format(CultureInfo.InvariantCulture, "Nullable<{0}>", typeName) :
- typeName;
- }
-
- throw new ArgumentException("edmType");
- }
-
- public Type UnderlyingClrType(EdmType edmType)
- {
- ArgumentNotNull(edmType, "edmType");
-
- var primitiveType = edmType as PrimitiveType;
- if (primitiveType != null)
- {
- return primitiveType.ClrEquivalentType;
- }
-
- if (IsEnumType(edmType))
- {
- return GetEnumUnderlyingType(edmType).ClrEquivalentType;
- }
-
- return typeof(object);
- }
-
- public object GetEnumMemberValue(MetadataItem enumMember)
- {
- ArgumentNotNull(enumMember, "enumMember");
-
- var valueProperty = enumMember.GetType().GetProperty("Value");
- return valueProperty == null ? null : valueProperty.GetValue(enumMember, null);
- }
-
- public string GetEnumMemberName(MetadataItem enumMember)
- {
- ArgumentNotNull(enumMember, "enumMember");
-
- var nameProperty = enumMember.GetType().GetProperty("Name");
- return nameProperty == null ? null : (string)nameProperty.GetValue(enumMember, null);
- }
-
- public System.Collections.IEnumerable GetEnumMembers(EdmType enumType)
- {
- ArgumentNotNull(enumType, "enumType");
-
- var membersProperty = enumType.GetType().GetProperty("Members");
- return membersProperty != null
- ? (System.Collections.IEnumerable)membersProperty.GetValue(enumType, null)
- : Enumerable.Empty();
- }
-
- public bool EnumIsFlags(EdmType enumType)
- {
- ArgumentNotNull(enumType, "enumType");
-
- var isFlagsProperty = enumType.GetType().GetProperty("IsFlags");
- return isFlagsProperty != null && (bool)isFlagsProperty.GetValue(enumType, null);
- }
-
- public bool IsEnumType(GlobalItem edmType)
- {
- ArgumentNotNull(edmType, "edmType");
-
- return edmType.GetType().Name == "EnumType";
- }
-
- public PrimitiveType GetEnumUnderlyingType(EdmType enumType)
- {
- ArgumentNotNull(enumType, "enumType");
-
- return (PrimitiveType)enumType.GetType().GetProperty("UnderlyingType").GetValue(enumType, null);
- }
-
- public string CreateLiteral(object value)
- {
- if (value == null || value.GetType() != typeof(TimeSpan))
- {
- return _code.CreateLiteral(value);
- }
-
- return string.Format(CultureInfo.InvariantCulture, "new TimeSpan({0})", ((TimeSpan)value).Ticks);
- }
-
- public bool VerifyCaseInsensitiveTypeUniqueness(IEnumerable types, string sourceFile)
- {
- ArgumentNotNull(types, "types");
- ArgumentNotNull(sourceFile, "sourceFile");
-
- var hash = new HashSet(StringComparer.InvariantCultureIgnoreCase);
- if (types.Any(item => !hash.Add(item)))
- {
- _errors.Add(
- new CompilerError(sourceFile, -1, -1, "6023",
- String.Format(CultureInfo.CurrentCulture, CodeGenerationTools.GetResourceString("Template_CaseInsensitiveTypeConflict"))));
- return false;
- }
- return true;
- }
-
- public IEnumerable GetEnumItemsToGenerate(IEnumerable itemCollection)
- {
- return GetItemsToGenerate(itemCollection)
- .Where(e => IsEnumType(e));
- }
-
- public IEnumerable GetItemsToGenerate(IEnumerable itemCollection) where T: EdmType
- {
- return itemCollection
- .OfType()
- .Where(i => !i.MetadataProperties.Any(p => p.Name == ExternalTypeNameAttributeName))
- .OrderBy(i => i.Name);
- }
-
- public IEnumerable GetAllGlobalItems(IEnumerable itemCollection)
- {
- return itemCollection
- .Where(i => i is EntityType || i is ComplexType || i is EntityContainer || IsEnumType(i))
- .Select(g => GetGlobalItemName(g));
- }
-
- public string GetGlobalItemName(GlobalItem item)
- {
- if (item is EdmType)
- {
- return ((EdmType)item).Name;
- }
- else
- {
- return ((EntityContainer)item).Name;
- }
- }
-
- public IEnumerable GetSimpleProperties(EntityType type)
- {
- return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
- }
-
- public IEnumerable GetSimpleProperties(ComplexType type)
- {
- return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type);
- }
-
- public IEnumerable GetComplexProperties(EntityType type)
- {
- return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
- }
-
- public IEnumerable GetComplexProperties(ComplexType type)
- {
- return type.Properties.Where(p => p.TypeUsage.EdmType is ComplexType && p.DeclaringType == type);
- }
-
- public IEnumerable GetPropertiesWithDefaultValues(EntityType type)
- {
- return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
- }
-
- public IEnumerable GetPropertiesWithDefaultValues(ComplexType type)
- {
- return type.Properties.Where(p => p.TypeUsage.EdmType is SimpleType && p.DeclaringType == type && p.DefaultValue != null);
- }
-
- public IEnumerable GetNavigationProperties(EntityType type)
- {
- return type.NavigationProperties.Where(np => np.DeclaringType == type);
- }
-
- public IEnumerable GetCollectionNavigationProperties(EntityType type)
- {
- return type.NavigationProperties.Where(np => np.DeclaringType == type && np.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many);
- }
-
- public FunctionParameter GetReturnParameter(EdmFunction edmFunction)
- {
- ArgumentNotNull(edmFunction, "edmFunction");
-
- var returnParamsProperty = edmFunction.GetType().GetProperty("ReturnParameters");
- return returnParamsProperty == null
- ? edmFunction.ReturnParameter
- : ((IEnumerable)returnParamsProperty.GetValue(edmFunction, null)).FirstOrDefault();
- }
-
- public bool IsComposable(EdmFunction edmFunction)
- {
- ArgumentNotNull(edmFunction, "edmFunction");
-
- var isComposableProperty = edmFunction.GetType().GetProperty("IsComposableAttribute");
- return isComposableProperty != null && (bool)isComposableProperty.GetValue(edmFunction, null);
- }
-
- public IEnumerable GetParameters(EdmFunction edmFunction)
- {
- return FunctionImportParameter.Create(edmFunction.Parameters, _code, _ef);
- }
-
- public TypeUsage GetReturnType(EdmFunction edmFunction)
- {
- var returnParam = GetReturnParameter(edmFunction);
- return returnParam == null ? null : _ef.GetElementType(returnParam.TypeUsage);
- }
-
- public bool GenerateMergeOptionFunction(EdmFunction edmFunction, bool includeMergeOption)
- {
- var returnType = GetReturnType(edmFunction);
- return !includeMergeOption && returnType != null && returnType.EdmType.BuiltInTypeKind == BuiltInTypeKind.EntityType;
- }
-}
-
-public static void ArgumentNotNull(T arg, string name) where T : class
-{
- if (arg == null)
- {
- throw new ArgumentNullException(name);
- }
-}
-#>
\ No newline at end of file
diff --git a/Application/NotificationIcon.cs b/Application/NotificationIcon.cs
index e345e1b..d0e558b 100644
--- a/Application/NotificationIcon.cs
+++ b/Application/NotificationIcon.cs
@@ -54,7 +54,7 @@ namespace FeedCenter
// Toggle the lock setting
Settings.Default.WindowLocked = !Settings.Default.WindowLocked;
- // Reset the menu choice
+ // Refresh the menu choice
((ToolStripMenuItem) sender).Checked = Settings.Default.WindowLocked;
}
diff --git a/Application/Options/AboutOptionsPanel.xaml.cs b/Application/Options/AboutOptionsPanel.xaml.cs
index 44cbef4..3336a7c 100644
--- a/Application/Options/AboutOptionsPanel.xaml.cs
+++ b/Application/Options/AboutOptionsPanel.xaml.cs
@@ -16,7 +16,7 @@ namespace FeedCenter.Options
ApplicationNameLabel.Text = Properties.Resources.ApplicationDisplayName;
- string version = UpdateCheck.LocalVersion.ToString();
+ var version = UpdateCheck.LocalVersion.ToString();
VersionLabel.Text = string.Format(Properties.Resources.Version, version);
CompanyLabel.Text = ((AssemblyCompanyAttribute) Assembly.GetEntryAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false)[0]).Company;
diff --git a/Application/Options/BulkFeedWindow.xaml.cs b/Application/Options/BulkFeedWindow.xaml.cs
index c243cc5..141cc1e 100644
--- a/Application/Options/BulkFeedWindow.xaml.cs
+++ b/Application/Options/BulkFeedWindow.xaml.cs
@@ -22,7 +22,7 @@ namespace FeedCenter.Options
{
_checkedListBoxItems = new List>();
- foreach (var feed in database.AllFeeds)
+ foreach (var feed in database.Feeds)
_checkedListBoxItems.Add(new CheckedListItem { Item = feed });
_collectionViewSource = new CollectionViewSource { Source = _checkedListBoxItems };
diff --git a/Application/Options/FeedWindow.xaml b/Application/Options/FeedWindow.xaml
index bddfb9b..ea34eeb 100644
--- a/Application/Options/FeedWindow.xaml
+++ b/Application/Options/FeedWindow.xaml
@@ -3,6 +3,11 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:properties="clr-namespace:FeedCenter.Properties"
xmlns:feedCenter="clr-namespace:FeedCenter"
+ xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+ d:DataContext="{d:DesignInstance Type=feedCenter:Feed}"
+ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:validation="clr-namespace:Common.Wpf.Validation;assembly=Common.Wpf"
+ mc:Ignorable="d"
Title="FeedWindow"
Height="300"
Width="450"
@@ -33,8 +38,15 @@
+ Margin="6">
+
+
+
+
+
+
+
+
+ Margin="6">
+
+
+
+
+
+
+
+
-
-
+ Margin="6">
+
+
+
+
+
+
+
+
-
+
\ No newline at end of file
diff --git a/Application/Options/FeedWindow.xaml.cs b/Application/Options/FeedWindow.xaml.cs
index 962b7d2..326fbf3 100644
--- a/Application/Options/FeedWindow.xaml.cs
+++ b/Application/Options/FeedWindow.xaml.cs
@@ -1,5 +1,4 @@
-using System.Data.Entity;
-using Common.Wpf.Extensions;
+using Common.Wpf.Extensions;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
@@ -17,10 +16,8 @@ namespace FeedCenter.Options
public bool? Display(FeedCenterEntities database, Feed feed, Window owner)
{
- database.Categories.Load();
-
// Bind the category combo box
- CategoryComboBox.ItemsSource = database.Categories.Local;
+ CategoryComboBox.ItemsSource = database.Categories;
// Set the data context
DataContext = feed;
diff --git a/Application/Options/FeedsOptionsPanel.xaml.cs b/Application/Options/FeedsOptionsPanel.xaml.cs
index 59c2f5b..6d1d790 100644
--- a/Application/Options/FeedsOptionsPanel.xaml.cs
+++ b/Application/Options/FeedsOptionsPanel.xaml.cs
@@ -6,7 +6,6 @@ using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
-using System.Windows.Media;
using System.Xml;
namespace FeedCenter.Options
@@ -28,7 +27,7 @@ namespace FeedCenter.Options
{
base.LoadPanel(database);
- var collectionViewSource = new CollectionViewSource { Source = Database.AllCategories };
+ var collectionViewSource = new CollectionViewSource { Source = Database.Categories };
collectionViewSource.SortDescriptions.Add(new SortDescription("SortKey", ListSortDirection.Ascending));
collectionViewSource.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
@@ -304,7 +303,7 @@ namespace FeedCenter.Options
if (result.HasValue && result.Value)
{
- Database.Categories.Add(category);
+ Database.SaveChanges(() => Database.Categories.Add(category));
CategoryListBox.SelectedItem = category;
@@ -330,7 +329,7 @@ namespace FeedCenter.Options
var category = (Category) CategoryListBox.SelectedItem;
- category.Feeds.ToList().ForEach(feed => feed.Category = defaultCategory);
+ category.Feeds?.ToList().ForEach(feed => feed.Category = defaultCategory);
var index = CategoryListBox.SelectedIndex;
@@ -339,7 +338,7 @@ namespace FeedCenter.Options
else
CategoryListBox.SelectedIndex = index + 1;
- Database.Categories.Remove(category);
+ Database.SaveChanges(() => Database.Categories.Remove(category));
SetCategoryButtonStates();
}
@@ -371,7 +370,7 @@ namespace FeedCenter.Options
{
if (_collectionViewSource == null)
{
- _collectionViewSource = new CollectionViewSource { Source = Database.AllFeeds };
+ _collectionViewSource = new CollectionViewSource { Source = Database.Feeds };
_collectionViewSource.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
_collectionViewSource.Filter += HandleCollectionViewSourceFilter;
@@ -393,7 +392,7 @@ namespace FeedCenter.Options
var feed = (Feed) e.Item;
- e.Accepted = (feed.Category.ID == selectedCategory.ID);
+ e.Accepted = (feed.Category.Id == selectedCategory.Id);
}
private void HandleTextBlockDrop(object sender, DragEventArgs e)
diff --git a/Application/Options/OptionsWindow.xaml.cs b/Application/Options/OptionsWindow.xaml.cs
index 36476c5..8e63700 100644
--- a/Application/Options/OptionsWindow.xaml.cs
+++ b/Application/Options/OptionsWindow.xaml.cs
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
+using FeedCenter.Data;
namespace FeedCenter.Options
{
@@ -10,7 +11,7 @@ namespace FeedCenter.Options
private readonly List _optionPanels = new List();
- private readonly FeedCenterEntities _database = new FeedCenterEntities();
+ private readonly FeedCenterEntities _database = Database.Entities;
#endregion
@@ -43,7 +44,7 @@ namespace FeedCenter.Options
private void LoadCategories()
{
// Loop over each panel
- foreach (OptionsPanelBase optionsPanel in _optionPanels)
+ foreach (var optionsPanel in _optionPanels)
{
// Tell the panel to load itself
optionsPanel.LoadPanel(_database);
@@ -95,7 +96,7 @@ namespace FeedCenter.Options
private void HandleOkayButtonClick(object sender, RoutedEventArgs e)
{
// Loop over each panel and ask them to validate
- foreach (OptionsPanelBase optionsPanel in _optionPanels)
+ foreach (var optionsPanel in _optionPanels)
{
// If validation fails...
if (!optionsPanel.ValidatePanel())
@@ -109,14 +110,14 @@ namespace FeedCenter.Options
}
// Loop over each panel and ask them to save
- foreach (OptionsPanelBase optionsPanel in _optionPanels)
+ foreach (var optionsPanel in _optionPanels)
{
// Save!
optionsPanel.SavePanel();
}
// Save the actual settings
- _database.SaveChanges();
+ _database.SaveChanges(() => { });
Properties.Settings.Default.Save();
DialogResult = true;
diff --git a/Application/Options/Setting.cs b/Application/Options/Setting.cs
new file mode 100644
index 0000000..e7e8f1f
--- /dev/null
+++ b/Application/Options/Setting.cs
@@ -0,0 +1,14 @@
+using Realms;
+
+namespace FeedCenter.Options
+{
+ public class Setting : RealmObject
+ {
+ [PrimaryKey]
+ public string Name { get; set; }
+ public string Value { get; set; }
+
+ [Ignored]
+ public string Version { get; set; }
+ }
+}
diff --git a/Application/Properties/AssemblyInfo.cs b/Application/Properties/AssemblyInfo.cs
index e59970d..5d5cfd0 100644
--- a/Application/Properties/AssemblyInfo.cs
+++ b/Application/Properties/AssemblyInfo.cs
@@ -1,6 +1,7 @@
using System.Reflection;
using System.Resources;
using System.Runtime.InteropServices;
+using System.Runtime.Versioning;
using System.Windows;
[assembly: AssemblyTitle("Feed Center")]
@@ -11,6 +12,8 @@ using System.Windows;
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
+[assembly: SupportedOSPlatform("windows")]
+
#if DEBUG
[assembly: AssemblyConfiguration("Debug build")]
#else
diff --git a/Application/Properties/Resources.Designer.cs b/Application/Properties/Resources.Designer.cs
index 3beb544..9009133 100644
--- a/Application/Properties/Resources.Designer.cs
+++ b/Application/Properties/Resources.Designer.cs
@@ -19,7 +19,7 @@ namespace FeedCenter.Properties {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Resources {
diff --git a/Application/Properties/Settings.Designer.cs b/Application/Properties/Settings.Designer.cs
index 00cf9b0..7d9adcd 100644
--- a/Application/Properties/Settings.Designer.cs
+++ b/Application/Properties/Settings.Designer.cs
@@ -12,7 +12,7 @@ namespace FeedCenter.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.6.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.4.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
diff --git a/Application/Properties/launchSettings.json b/Application/Properties/launchSettings.json
new file mode 100644
index 0000000..85c7380
--- /dev/null
+++ b/Application/Properties/launchSettings.json
@@ -0,0 +1,8 @@
+{
+ "profiles": {
+ "FeedCenter": {
+ "commandName": "Project",
+ "commandLineArgs": "/debugpath"
+ }
+ }
+}
\ No newline at end of file
diff --git a/Application/Setting.cs b/Application/Setting.cs
deleted file mode 100644
index da4192b..0000000
--- a/Application/Setting.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-//------------------------------------------------------------------------------
-//
-// This code was generated from a template.
-//
-// Manual changes to this file may cause unexpected behavior in your application.
-// Manual changes to this file will be overwritten if the code is regenerated.
-//
-//------------------------------------------------------------------------------
-
-namespace FeedCenter
-{
- using System;
- using System.Collections.Generic;
-
- public partial class Setting
- {
- public string Name { get; set; }
- public string Value { get; set; }
- public string Version { get; set; }
- }
-}
diff --git a/Application/SettingsStore.cs b/Application/SettingsStore.cs
index 9a9cefa..45f655b 100644
--- a/Application/SettingsStore.cs
+++ b/Application/SettingsStore.cs
@@ -1,4 +1,6 @@
-using System;
+using FeedCenter.Data;
+using FeedCenter.Options;
+using System;
using System.Collections.Generic;
using System.Linq;
@@ -8,33 +10,18 @@ namespace FeedCenter
{
public static object OpenDataStore()
{
- var entities = new FeedCenterEntities();
-
- return entities.Database.Exists() ? entities : null;
+ return Database.Entities;
}
public static void CloseDataStore(object dataStore)
{
- var entities = (FeedCenterEntities) dataStore;
-
- if (entities == null)
- return;
-
- entities.SaveChanges();
-
- entities.Dispose();
}
public static string GetSettingValue(object dataStore, string name, Version version)
{
var entities = (FeedCenterEntities) dataStore;
- if (entities == null)
- return null;
-
- var versionString = version.ToString();
-
- var setting = entities.Settings.FirstOrDefault(s => s.Name == name && s.Version == versionString);
+ var setting = entities?.Settings.FirstOrDefault(s => s.Name == name);
return setting?.Value;
}
@@ -46,51 +33,30 @@ namespace FeedCenter
if (entities == null)
return;
- var versionString = version.ToString();
-
// Try to get the setting from the database that matches the name and version
- var setting = entities.Settings.FirstOrDefault(s => s.Name == name && s.Version == versionString);
+ var setting = entities.Settings.FirstOrDefault(s => s.Name == name);
- // If there was no setting we need to create it
- if (setting == null)
+ entities.SaveChanges(() =>
{
- // Create the new setting
- setting = new Setting { Name = name, Version = version.ToString() };
+ // If there was no setting we need to create it
+ if (setting == null)
+ {
+ // Create the new setting
+ setting = new Setting { Name = name };
- // Add the setting to the database
- entities.Settings.Add(setting);
- }
+ // Add the setting to the database
+ entities.Settings.Add(setting);
+ }
- // Set the value into the setting
- setting.Value = value;
+ // Set the value into the setting
+ setting.Value = value;
+ });
}
- public static List GetVersionList(object dataStore)
- {
- var entities = (FeedCenterEntities) dataStore;
-
- // Get a distinct list of version strings
- var versions = entities?.Settings.Select(s => s.Version).Distinct().ToList();
-
- // Create a version object for each string and return the list
- return versions?.Select(s => new Version(s)).ToList();
- }
+ public static List GetVersionList(object dataStore) => null;
public static void DeleteSettingsForVersion(object dataStore, Version version)
{
- var entities = (FeedCenterEntities) dataStore;
-
- if (entities == null)
- return;
-
- var versionString = version.ToString();
-
- // Get all the settings for the current version number
- var settings = entities.Settings.Where(setting => setting.Version == versionString);
-
- // Delete each setting
- foreach (var setting in settings)
- entities.Settings.Remove(setting);
}
}
}
diff --git a/Application/SplashWindow.xaml.cs b/Application/SplashWindow.xaml.cs
index 53934ea..5f6b594 100644
--- a/Application/SplashWindow.xaml.cs
+++ b/Application/SplashWindow.xaml.cs
@@ -9,7 +9,7 @@ using System.Windows.Threading;
namespace FeedCenter
{
- public partial class SplashWindow
+ public partial class SplashWindow : IDisposable
{
#region Progress step
@@ -49,7 +49,7 @@ namespace FeedCenter
_dispatcher = Dispatcher.CurrentDispatcher;
// Get the version to display
- string version = UpdateCheck.LocalVersion.ToString();
+ var version = UpdateCheck.LocalVersion.ToString();
// Show the version
VersionLabel.Content = string.Format(Properties.Resources.Version, version);
@@ -113,10 +113,10 @@ namespace FeedCenter
Thread.Sleep(100);
// Initialize the skip key
- string skipKey = string.Empty;
+ var skipKey = string.Empty;
// Loop over all progress steps and execute
- foreach (ProgressStep progressStep in _progressSteps)
+ foreach (var progressStep in _progressSteps)
{
if (progressStep.Key == skipKey)
{
@@ -129,7 +129,7 @@ namespace FeedCenter
UpdateProgress(_backgroundWorker, progressStep.Caption);
// Execute the step and get the result
- bool result = progressStep.Callback();
+ var result = progressStep.Callback();
// If the step indicated a skip then set the skip key, otherwise clear it
skipKey = (result ? string.Empty : progressStep.Key);
@@ -190,12 +190,6 @@ namespace FeedCenter
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;
}
@@ -203,7 +197,7 @@ namespace FeedCenter
private static bool CreateDatabase()
{
// Create the database
- Database.CreateDatabase();
+ //Database.CreateDatabase();
return true;
}
@@ -211,7 +205,7 @@ namespace FeedCenter
private static bool UpdateDatabase()
{
// Update the database
- Database.UpdateDatabase();
+ // Database.UpdateDatabase();
return true;
}
@@ -219,11 +213,16 @@ namespace FeedCenter
private static bool MaintainDatabase()
{
// Maintain the database
- Database.MaintainDatabase();
+ //Database.MaintainDatabase();
return true;
}
#endregion
+
+ public void Dispose()
+ {
+ _backgroundWorker?.Dispose();
+ }
}
}
diff --git a/Application/app.config b/Application/app.config
index 5631d43..8e46379 100644
--- a/Application/app.config
+++ b/Application/app.config
@@ -7,8 +7,6 @@
-
-
@@ -34,7 +32,7 @@
True
-
+
False
@@ -49,7 +47,7 @@
500
-
+
1500
@@ -58,10 +56,10 @@
Normal
-
+
-
+
@@ -87,27 +85,4 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Application/packages.config b/Application/packages.config
deleted file mode 100644
index e6740cd..0000000
--- a/Application/packages.config
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/FeedCenter.sln b/FeedCenter.sln
index 71942b5..ec65a10 100644
--- a/FeedCenter.sln
+++ b/FeedCenter.sln
@@ -1,8 +1,8 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-VisualStudioVersion = 15.0.27130.2027
+# Visual Studio Version 17
+VisualStudioVersion = 17.5.33414.496
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FeedCenter", "Application\FeedCenter.csproj", "{BD3D12F2-DE23-4466-83B1-1EB617A877A4}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FeedCenter", "Application\FeedCenter.csproj", "{BD3D12F2-DE23-4466-83B1-1EB617A877A4}"
EndProject
Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "Setup", "Setup\Setup.wixproj", "{DFB3FE30-18EA-4216-8D92-11DF9C8D50F1}"
EndProject
@@ -16,11 +16,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution", "Solution", "{14
README.md = README.md
EndProjectSection
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common.Native", "Common.Wpf\Common.Native\Common.Native.csproj", "{ED1C07A1-54F5-4796-8B06-2A0BB1960D84}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.Native", "Common.Wpf\Common.Native\Common.Native.csproj", "{ED1C07A1-54F5-4796-8B06-2A0BB1960D84}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common.Wpf", "Common.Wpf\Common.Wpf.csproj", "{0074C983-550E-4094-9E8C-F566FB669297}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common.Wpf", "Common.Wpf\Common.Wpf.csproj", "{0074C983-550E-4094-9E8C-F566FB669297}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common", "Common\Common.csproj", "{17864D82-457D-4A0A-BC10-1D07F2B3A5D6}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Common", "Common\Common.csproj", "{17864D82-457D-4A0A-BC10-1D07F2B3A5D6}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NameBasedGrid", "..\..\Public\namebasedgrid\src\NameBasedGrid\NameBasedGrid.csproj", "{01D2D040-A2AF-42A1-9821-D1C6D77A3309}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -220,6 +222,38 @@ Global
{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
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Debug - With Setup|Any CPU.ActiveCfg = Debug|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Debug - With Setup|Any CPU.Build.0 = Debug|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Debug - With Setup|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Debug - With Setup|Mixed Platforms.Build.0 = Debug|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Debug - With Setup|x64.ActiveCfg = Debug|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Debug - With Setup|x64.Build.0 = Debug|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Debug - With Setup|x86.ActiveCfg = Debug|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Debug - With Setup|x86.Build.0 = Debug|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Debug|x64.Build.0 = Debug|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Debug|x86.Build.0 = Debug|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Release - With Setup|Any CPU.ActiveCfg = Release|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Release - With Setup|Any CPU.Build.0 = Release|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Release - With Setup|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Release - With Setup|Mixed Platforms.Build.0 = Release|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Release - With Setup|x64.ActiveCfg = Release|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Release - With Setup|x64.Build.0 = Release|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Release - With Setup|x86.ActiveCfg = Release|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Release - With Setup|x86.Build.0 = Release|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Release|Any CPU.Build.0 = Release|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Release|x64.ActiveCfg = Release|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Release|x64.Build.0 = Release|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Release|x86.ActiveCfg = Release|Any CPU
+ {01D2D040-A2AF-42A1-9821-D1C6D77A3309}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/FeedCenter.sln.DotSettings b/FeedCenter.sln.DotSettings
new file mode 100644
index 0000000..378f8bf
--- /dev/null
+++ b/FeedCenter.sln.DotSettings
@@ -0,0 +1,6 @@
+
+ True
+ True
+ True
+ True
+ True
\ No newline at end of file