diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dac79c6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,239 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates +*.db +*.VC.db +*.VC.VC.opendb + +# Executables +*.dll +[Dd]ependencies/* + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +build/ +bld/ +[Bb]in/ +[Oo]bj/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# DNX +project.lock.json +artifacts/ + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config + +# Windows Azure Build Output +csx/ +*.build.csdef + +# Windows Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directory +AppPackages/ +BundleArtifacts/ + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.pfx +*.publishsettings +node_modules/ +orleans.codegen.cs + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe + +# FAKE - F# Make +.fake/ \ No newline at end of file diff --git a/App.config b/App.config index 41dc385..4207fd0 100644 --- a/App.config +++ b/App.config @@ -1,6 +1,6 @@ - + diff --git a/CharacterProfile.cs b/CharacterProfile.cs index c369f65..009d886 100644 --- a/CharacterProfile.cs +++ b/CharacterProfile.cs @@ -19,6 +19,14 @@ limitations under the License. using System.Windows.Media; using HighVoltz.HBRelog.Tasks; using HighVoltz.HBRelog.Settings; +using System.Xml.Linq; +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Linq; +using System.Xml.Serialization; +using System.Globalization; +using System.Diagnostics; namespace HighVoltz.HBRelog { @@ -142,7 +150,11 @@ public void Stop() private string _lastLog; public void Log(string format, params object[] args) { - var msg = string.Format(format, args); + Log(string.Format(format, args)); + } + + public void Log(string msg) + { if (msg == _lastLog) return; _lastLog = msg; @@ -154,9 +166,14 @@ public void Log(string format, params object[] args) } public void Err(string format, params object[] args) + { + Err(string.Format(format, args)); + } + + public void Err(string msg) { HBRelog.Log.Write(HbRelogManager.Settings.UseDarkStyle ? Colors.LightBlue : Colors.DarkSlateBlue, - Settings.ProfileName + ": ", Colors.Red, format, args); + Settings.ProfileName + ": ", Colors.Red, msg); } public CharacterProfile ShadowCopy() @@ -167,17 +184,88 @@ public CharacterProfile ShadowCopy() { cp.Tasks.Add(bmTask.ShadowCopy()); } - cp.Settings = Settings.ShadowCopy(); + cp.Settings = (ProfileSettings)Settings.ShadowCopy(); return cp; } public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(string name) { - if (PropertyChanged != null) + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); + } + + public void LoadFromXml(XElement element) + { + Settings.LoadFromXml(element.Element("Settings")); + + // Tasks + XElement tasksElement = element.Element("Tasks"); + foreach (XElement taskElement in tasksElement.Elements()) + { + Type taskType = Type.GetType("HighVoltz.HBRelog.Tasks." + taskElement.Name); + if (taskType != null) + { + var task = (BMTask)Activator.CreateInstance(taskType); + task.SetProfile(this); + // Dictionary of property Names and the corresponding PropertyInfo + Dictionary propertyDict = + task.GetType() + .GetProperties() + .Where(pi => pi.GetCustomAttributesData().All(cad => cad.Constructor.DeclaringType != typeof(XmlIgnoreAttribute))) + .ToDictionary(k => k.Name); + + foreach (XAttribute attr in taskElement.Attributes()) + { + string propKey = attr.Name.ToString(); + if (propertyDict.ContainsKey(propKey)) + { + // if property is an enum then use Enum.Parse.. otherwise use Convert.ChangeValue + object val = typeof(Enum).IsAssignableFrom(propertyDict[propKey].PropertyType) + ? Enum.Parse(propertyDict[propKey].PropertyType, attr.Value) + : Convert.ChangeType(attr.Value, propertyDict[propKey].PropertyType, CultureInfo.InvariantCulture); + propertyDict[propKey].SetValue(task, val, null); + } + else + { + Err("{0} does not have a property called {1}", taskElement.Name, attr.Name); + } + } + Tasks.Add(task); + } + else + { + Err("{0} is not a known task type", taskElement.Name); + } + } + } + + public XElement ConvertToXml() + { + var xml = new XElement("CharacterProfile"); + var settingsElement = Settings.ConvertToXml(); + xml.Add(settingsElement); + + // Tasks + var tasksElement = new XElement("Tasks"); + foreach (BMTask task in Tasks) { - PropertyChanged(this, new PropertyChangedEventArgs(name)); + var taskElement = new XElement(task.GetType().Name); + // get a list of propertyes that don't have [XmlIgnore] custom attribute attached. + List propertyList = + task.GetType() + .GetProperties() + .Where(pi => pi.GetCustomAttributesData().All(cad => cad.Constructor.DeclaringType != typeof(XmlIgnoreAttribute))) + .ToList(); + foreach (PropertyInfo property in propertyList) + { + var value = property.GetValue(task, null); + Debug.Assert(value != null, string.Format("value for {0} != null", property.Name)); + taskElement.Add(new XAttribute(property.Name, value)); + } + tasksElement.Add(taskElement); } + xml.Add(tasksElement); + return xml; } } } diff --git a/Controls/OptionsUserControl.xaml b/Controls/OptionsUserControl.xaml index b87e767..414dea8 100644 --- a/Controls/OptionsUserControl.xaml +++ b/Controls/OptionsUserControl.xaml @@ -31,6 +31,7 @@ + - - - - + + + + + - - + -