Split into smaller projects, now uses plugins.

This commit is contained in:
2014-08-12 16:33:13 +03:00
parent 69913fa251
commit b8c8f2a1b0
80 changed files with 1520 additions and 494 deletions

View File

@ -4,10 +4,10 @@ using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using RainmeterStudio.Documents;
using RainmeterStudio.Model;
using RainmeterStudio.Model.Events;
using RainmeterStudio.Utils;
using RainmeterStudio.Core.Documents;
using RainmeterStudio.Core.Model;
using RainmeterStudio.Core.Model.Events;
using RainmeterStudio.Core.Storage;
namespace RainmeterStudio.Business
{
@ -67,61 +67,6 @@ namespace RainmeterStudio.Business
{
}
/// <summary>
/// Registers all classes with the auto register flag
/// </summary>
/// <remarks>We love linq</remarks>
public void PerformAutoRegister()
{
// Get all assemblies
AppDomain.CurrentDomain.GetAssemblies()
// Get all types
.SelectMany(assembly => assembly.GetTypes())
// Select only the classes
.Where(type => type.IsClass)
// That have the AutoRegister attribute
.Where(type => type.GetCustomAttributes(typeof(AutoRegisterAttribute), false).Length > 0)
// That implement any of the types that can be registered
.Where((type) =>
{
bool res = false;
res |= typeof(IDocumentEditorFactory).IsAssignableFrom(type);
res |= typeof(IDocumentStorage).IsAssignableFrom(type);
res |= typeof(DocumentTemplate).IsAssignableFrom(type);
return res;
})
// Obtain their default constructor
.Select(type => type.GetConstructor(new Type[0]))
// Invoke the default constructor
.Select(constructor => constructor.Invoke(new object[0]))
// Register
.ForEach(obj =>
{
// Try to register factory
var factory = obj as IDocumentEditorFactory;
if (factory != null)
RegisterEditorFactory(factory);
// Try to register as storage
var storage = obj as IDocumentStorage;
if (storage != null)
RegisterStorage(storage);
// Try to register as document template
var doctemplate = obj as DocumentTemplate;
if (doctemplate != null)
RegisterTemplate(doctemplate);
});
}
/// <summary>
/// Registers a document editor factory
/// </summary>

View File

@ -0,0 +1,104 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using RainmeterStudio.Core;
using RainmeterStudio.Core.Documents;
using RainmeterStudio.Core.Utils;
namespace RainmeterStudio.Business
{
/// <summary>
/// Manages RainmeterStudio plugins
/// </summary>
public class PluginManager
{
public delegate void RegisterMethod(object objectToRegister);
List<Assembly> _loadedPlugins = new List<Assembly>();
Dictionary<Type, RegisterMethod> _registerTypes = new Dictionary<Type,RegisterMethod>();
public PluginManager()
{
}
public void AddRegisterType(Type interfaceType, RegisterMethod method)
{
_registerTypes.Add(interfaceType, method);
}
public void LoadPlugins()
{
// Get "Plugins" folder path
var location = Assembly.GetExecutingAssembly().Location;
var pluginsPath = Path.Combine(Path.GetDirectoryName(location), "Plugins");
// Load all DLLs from "Plugins" folder
foreach (var file in Directory.EnumerateFiles(pluginsPath, "*.dll"))
LoadPlugin(file);
}
public void LoadPlugin(string file)
{
Assembly assembly = null;
// Try to load assembly
try
{
assembly = Assembly.LoadFile(file);
}
catch (Exception ex)
{
Debug.WriteLine("Failed to load assembly {0}: {1}", file, ex);
}
// Loaded, do initialization stuff
if (assembly != null)
{
_loadedPlugins.Add(assembly);
Initialize(assembly);
Debug.WriteLine("Loaded plugin: {0}", assembly.FullName);
}
}
private void Initialize(Assembly assembly)
{
// Register factories and stuff
assembly.GetTypes()
// Select only the classes
.Where(type => type.IsClass)
// That have the AutoRegister attribute
.Where(type => type.GetCustomAttributes(typeof(PluginExportAttribute), false).Length > 0)
// Perform register
.ForEach((type) =>
{
foreach (var pair in _registerTypes)
{
if (pair.Key.IsAssignableFrom(type))
{
var constructor = type.GetConstructor(new Type[0]);
var obj = constructor.Invoke(new object[0]);
pair.Value(obj);
}
}
});
}
public IEnumerable<Assembly> LoadedPlugins
{
get
{
return _loadedPlugins;
}
}
}
}

View File

@ -3,7 +3,8 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using RainmeterStudio.Model;
using RainmeterStudio.Core.Model;
using RainmeterStudio.Core.Storage;
using RainmeterStudio.Storage;
namespace RainmeterStudio.Business

View File

@ -1,13 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace RainmeterStudio.Documents.DocumentEditorFeatures
{
public interface ICustomDocumentTitleProvider
{
string Title { get; }
event EventHandler TitleChanged;
}
}

View File

@ -1,16 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RainmeterStudio.Model;
namespace RainmeterStudio.Documents.DocumentEditorFeatures
{
interface ISelectionPropertiesProvider
{
string SelectionName { get; }
IEnumerable<Property> SelectionProperties { get; }
event EventHandler SelectionChanged;
}
}

View File

@ -1,15 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace RainmeterStudio.Documents.DocumentEditorFeatures
{
public interface IToolboxProvider
{
bool SupportsToolboxDrop { get; }
IEnumerable<string> ToolboxItems { get; }
event EventHandler ToolboxItemsChanged;
}
}

View File

@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace RainmeterStudio.Documents.DocumentEditorFeatures
{
public interface IUndoSupport
{
// TODO
}
}

View File

@ -1,36 +0,0 @@
using RainmeterStudio.Model;
namespace RainmeterStudio.Documents
{
/// <summary>
/// Represents a document template
/// </summary>
public abstract class DocumentTemplate
{
/// <summary>
/// Gets the document template name
/// </summary>
public string Name { get; private set; }
/// <summary>
/// Gets the default extension of this template
/// </summary>
public string DefaultExtension { get; private set; }
/// <summary>
/// Initializes the document template
/// </summary>
/// <param name="name">Name of template</param>
/// <param name="defaultExtension">Default extension</param>
public DocumentTemplate(string name, string defaultExtension)
{
Name = name;
DefaultExtension = defaultExtension;
}
/// <summary>
/// Creates a document using this template
/// </summary>
/// <returns></returns>
public abstract IDocument CreateDocument();
}
}

View File

@ -1,15 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using RainmeterStudio.Model;
namespace RainmeterStudio.Documents
{
public interface IDocumentEditor
{
IDocument AttachedDocument { get; }
UIElement EditorUI { get; }
}
}

View File

@ -1,25 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RainmeterStudio.Model;
namespace RainmeterStudio.Documents
{
public interface IDocumentEditorFactory
{
/// <summary>
/// Creates a new editor object
/// </summary>
/// <param name="document">Document to be edited by the editor</param>
/// <returns>A new document editor</returns>
IDocumentEditor CreateEditor(IDocument document);
/// <summary>
/// Tests if this editor can edit this document type
/// </summary>
/// <param name="type">Document type</param>
/// <returns>True if the editor can edit the document type</returns>
bool CanEdit(Type type);
}
}

View File

@ -1,39 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RainmeterStudio.Model;
namespace RainmeterStudio.Documents
{
public interface IDocumentStorage
{
/// <summary>
/// Reads a document from file
/// </summary>
/// <param name="path">Path to file</param>
/// <returns>Read document</returns>
IDocument Read(string path);
/// <summary>
/// Writes a document to a file
/// </summary>
/// <param name="path">Path to file</param>
/// <param name="document">Document to write</param>
void Write(string path, IDocument document);
/// <summary>
/// Tests if the file can be read by this storage
/// </summary>
/// <param name="path">Path to file</param>
/// <returns>True if file can be read</returns>
bool CanRead(string path);
/// <summary>
/// Tests if the document can be written by this storage
/// </summary>
/// <param name="documentType">Document type</param>
/// <returns>True if the document can be written</returns>
bool CanWrite(Type documentType);
}
}

View File

@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RainmeterStudio.Model;
namespace RainmeterStudio.Documents.Ini
{
/*public class IniDocument : IDocument
{
}*/
}

View File

@ -1,31 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RainmeterStudio.Model;
namespace RainmeterStudio.Documents.Ini
{
/*public class IniSkinDesigner : IDocumentEditor
{
public override IDocument Document
{
get { throw new NotImplementedException(); }
}
public override string Title
{
get { throw new NotImplementedException(); }
}
public override System.Windows.UIElement EditorUI
{
get { throw new NotImplementedException(); }
}
public override EventHandler SelectionChanged
{
get { throw new NotImplementedException(); }
}
}*/
}

View File

@ -1,11 +0,0 @@
<UserControl x:Class="RainmeterStudio.Documents.Ini.IniSkinDesignerControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
</Grid>
</UserControl>

View File

@ -1,27 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace RainmeterStudio.Documents.Ini
{
/// <summary>
/// Interaction logic for IniSkinDesignerControl.xaml
/// </summary>
public partial class IniSkinDesignerControl : UserControl
{
public IniSkinDesignerControl()
{
InitializeComponent();
}
}
}

View File

@ -1,14 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using RainmeterStudio.Model;
namespace RainmeterStudio.Documents.Ini
{
/*public class IniSkinDesignerFactory : IDocumentEditorFactory
{
}*/
}

View File

@ -1,73 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using RainmeterStudio.Model;
using System.ComponentModel;
namespace RainmeterStudio.Documents.Text
{
public class TextDocument : IDocument
{
private Reference _reference;
private bool _isDirty;
/// <summary>
/// Gets or sets the text associated with this document
/// </summary>
public List<string> Lines
{
get; private set;
}
/// <summary>
/// Gets or sets the reference of this document
/// </summary>
public Reference Reference
{
get
{
return _reference;
}
set
{
_reference = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Reference"));
}
}
/// <summary>
/// Gets a property indicating if this file was modified and not saved
/// </summary>
public bool IsDirty
{
get
{
return _isDirty;
}
set
{
_isDirty = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("IsDirty"));
}
}
/// <summary>
/// Triggered when the value of a property changes
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Initializes the text document
/// </summary>
public TextDocument()
{
Lines = new List<string>();
}
}
}

View File

@ -1,25 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RainmeterStudio.Model;
namespace RainmeterStudio.Documents.Text
{
/// <summary>
/// A blank text document template
/// </summary>
[AutoRegister]
public class TextDocumentTemplate : DocumentTemplate
{
public TextDocumentTemplate()
: base("TextDocument", "txt")
{
}
public override IDocument CreateDocument()
{
return new TextDocument();
}
}
}

View File

@ -1,31 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using RainmeterStudio.Model;
namespace RainmeterStudio.Documents.Text
{
public class TextEditor : IDocumentEditor
{
private TextDocument _document;
private TextEditorControl _control;
public TextEditor(TextDocument document)
{
_document = document;
_control = new TextEditorControl(document);
}
public IDocument AttachedDocument
{
get { return _document; }
}
public System.Windows.UIElement EditorUI
{
get { return _control; }
}
}
}

View File

@ -1,11 +0,0 @@
<UserControl x:Class="RainmeterStudio.Documents.Text.TextEditorControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<TextBox Name="text" AcceptsReturn="True" />
</Grid>
</UserControl>

View File

@ -1,32 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace RainmeterStudio.Documents.Text
{
/// <summary>
/// Interaction logic for TextEditorControl.xaml
/// </summary>
public partial class TextEditorControl : UserControl
{
private TextDocument _document;
public TextEditorControl(TextDocument document)
{
InitializeComponent();
_document = document;
text.Text = document.Lines.Aggregate((a, b) => a + "\n" + b);
}
}
}

View File

@ -1,24 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using RainmeterStudio.Business;
using RainmeterStudio.Model;
namespace RainmeterStudio.Documents.Text
{
[AutoRegister]
public class TextEditorFactory : IDocumentEditorFactory
{
public IDocumentEditor CreateEditor(IDocument document)
{
return new TextEditor((TextDocument)document);
}
public bool CanEdit(Type type)
{
return type.Equals(typeof(TextDocument));
}
}
}

View File

@ -1,71 +0,0 @@
using System;
using System.IO;
using RainmeterStudio.Model;
namespace RainmeterStudio.Documents.Text
{
/// <summary>
/// Storage for text files
/// </summary>
[AutoRegister]
public class TextStorage : IDocumentStorage
{
/// <inheritdoc />
IDocument IDocumentStorage.Read(string path)
{
TextDocument document = new TextDocument();
document.Reference.Path = path;
document.Reference.Name = Path.GetFileName(path);
document.Lines.AddRange(File.ReadAllLines(path));
return document;
}
/// <inheritdoc />
public void Write(string path, IDocument document)
{
TextDocument textDocument = document as TextDocument;
if (textDocument == null)
throw new ArgumentException("Provided document is not supported by this storage.");
File.WriteAllLines(path, textDocument.Lines);
}
/// <inheritdoc />
public bool CanRead(string path)
{
// Open the file
FileStream file = File.OpenRead(path);
// Read a small chunk (1kb should be enough)
byte[] buffer = new byte[1024];
int read = file.Read(buffer, 0, buffer.Length);
// Close file
file.Close();
// Find 4 consecutive zero bytes
int cnt = 0;
for (int i = 0; i < read; i++)
{
// Count zero bytes
if (buffer[i] == 0)
++cnt;
else cnt = 0;
// Found > 4? Most likely binary file
if (cnt >= 4)
return false;
}
// Not found, probably text file
return true;
}
public bool CanWrite(Type documentType)
{
return documentType.Equals(typeof(TextDocument));
}
}
}

View File

@ -1,20 +0,0 @@
The MIT License (MIT)
Copyright (c) 2008 Ricardo Amores Hernández
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -5,7 +5,8 @@ using System.Reflection;
using System.Text;
using System.Windows;
using RainmeterStudio.Business;
using RainmeterStudio.Documents;
using RainmeterStudio.Core.Documents;
using RainmeterStudio.Core.Storage;
using RainmeterStudio.Storage;
using RainmeterStudio.UI;
using RainmeterStudio.UI.Controller;
@ -21,12 +22,19 @@ namespace RainmeterStudio
SplashScreen splash = new SplashScreen("Resources/splash.png");
splash.Show(true);
// Initialize managers
// Initialize project manager
ProjectStorage projectStorage = new ProjectStorage();
ProjectManager projectManager = new ProjectManager(projectStorage);
// Initialize document manager
DocumentManager documentManager = new DocumentManager();
documentManager.PerformAutoRegister();
// Initialize plugin manager
PluginManager pluginManager = new PluginManager();
pluginManager.AddRegisterType(typeof(IDocumentStorage), obj => documentManager.RegisterStorage((IDocumentStorage)obj));
pluginManager.AddRegisterType(typeof(DocumentTemplate), obj => documentManager.RegisterTemplate((DocumentTemplate)obj));
pluginManager.AddRegisterType(typeof(IDocumentEditorFactory), obj => documentManager.RegisterEditorFactory((IDocumentEditorFactory)obj));
pluginManager.LoadPlugins();
// Create & run app
var uiManager = new UIManager(projectManager, documentManager);

View File

@ -1,60 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RainmeterStudio.Documents;
namespace RainmeterStudio.Model.Events
{
public abstract class DocumentEventArgsBase : EventArgs
{
/// <summary>
/// Gets the newly created document editor
/// </summary>
public IDocumentEditor Editor { get; private set; }
/// <summary>
/// Gets the opened document
/// </summary>
public IDocument Document { get { return Editor.AttachedDocument; } }
/// <summary>
/// Initializes the DocumentOpenedEventArgs
/// </summary>
/// <param name="editor">The document editor</param>
public DocumentEventArgsBase(IDocumentEditor editor)
{
Editor = editor;
}
}
/// <summary>
/// Event arguments for the document opened event
/// </summary>
public class DocumentOpenedEventArgs : DocumentEventArgsBase
{
/// <summary>
/// Initializes the DocumentOpenedEventArgs
/// </summary>
/// <param name="editor">The document editor</param>
public DocumentOpenedEventArgs(IDocumentEditor editor)
: base(editor)
{
}
}
/// <summary>
/// Event arguments for the document closed event
/// </summary>
public class DocumentClosedEventArgs : DocumentEventArgsBase
{
/// <summary>
/// Initializes the DocumentClosedEventArgs
/// </summary>
/// <param name="editor">The document editor</param>
public DocumentClosedEventArgs(IDocumentEditor editor)
: base(editor)
{
}
}
}

View File

@ -1,14 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
namespace RainmeterStudio.Model
{
public interface IDocument : INotifyPropertyChanged
{
Reference Reference { get; }
bool IsDirty { get; set; }
}
}

View File

@ -1,247 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using RainmeterStudio.Storage;
namespace RainmeterStudio.Model
{
/// <summary>
/// Defines a Rainmeter Studio project
/// </summary>
public class Project
{
#region Name property
private string _name;
/// <summary>
/// Gets or sets the name of the project
/// </summary>
[XmlElement("name")]
public string Name
{
get
{
return _name;
}
set
{
_name = value;
if (Root != null)
Root.Data = new Reference(Name, Path);
}
}
private string _path;
#endregion
#region Path property
/// <summary>
/// Gets or sets the file path of this project
/// </summary>
[XmlIgnore]
public string Path
{
get
{
return _path;
}
set
{
_path = value;
if (Root != null)
Root.Data = new Reference(Name, Path);
}
}
#endregion
#region Author property
/// <summary>
/// Gets or sets the author of the project
/// </summary>
[XmlElement("author")]
public string Author { get; set; }
#endregion
#region Version property
/// <summary>
/// Gets or sets the version of the project
/// </summary>
[XmlIgnore]
public Version Version { get; set; }
/// <summary>
/// Gets or sets the string representation of the project version
/// </summary>
[XmlElement("version")]
public string VersionString
{
get
{
return Version.ToString();
}
set
{
Version = new Version(value);
}
}
#endregion
#region Auto-load file property
/// <summary>
/// Gets or sets the reference to the file to automatically load at package installation
/// </summary>
[XmlElement("autoLoadFile")]
public Reference AutoLoadFile { get; set; }
#endregion
#region Variable files property
/// <summary>
/// Gets or sets the list of variable files
/// </summary>
[XmlArray("variableFiles")]
public List<Reference> VariableFiles { get; set; }
#endregion
#region Minimum rainmeter & windows properties
/// <summary>
/// Gets or sets the minimum rainmeter version
/// </summary>
[XmlIgnore]
public Version MinimumRainmeter { get; set; }
/// <summary>
/// Gets or sets the string representation of the minimum rainmeter version
/// </summary>
[XmlElement("minimumRainmeter")]
public string MinimumRainmeterString
{
get
{
return MinimumRainmeter.ToString();
}
set
{
MinimumRainmeter = new Version(value);
}
}
/// <summary>
/// Gets or sets the minimum Windows version
/// </summary>
[XmlIgnore]
public Version MinimumWindows { get; set; }
/// <summary>
/// Gets or sets the string representation of the minimum Windows version
/// </summary>
[XmlElement("minimumWindows")]
public string MinimumWindowsString
{
get
{
return MinimumWindows.ToString();
}
set
{
MinimumWindows = new Version(value);
}
}
#endregion
#region Root property
/// <summary>
/// Gets or sets the root node
/// </summary>
[XmlIgnore]
public Tree<Reference> Root { get; set; }
/// <summary>
/// Gets or sets the serializable root node
/// </summary>
/// <remarks>Warning: not efficient</remarks>
[XmlElement("root")]
public SerializableTree<Reference> SerializableRoot
{
get
{
return Root.AsSerializableTree();
}
set
{
Root = value.AsTree();
}
}
#endregion
#region Constructor
/// <summary>
/// Initializes a project
/// </summary>
public Project()
{
Root = new Tree<Reference>();
VariableFiles = new List<Reference>();
Version = new Version();
MinimumRainmeter = new Version("3.1");
MinimumWindows = new Version("5.1");
}
#endregion
#region Equals
public override bool Equals(object obj)
{
Project other = obj as Project;
if (other == null)
return false;
bool res = String.Equals(Author, other.Author);
res &= Reference.Equals(AutoLoadFile, other.AutoLoadFile);
res &= Version.Equals(MinimumRainmeter, other.MinimumRainmeter);
res &= Version.Equals(MinimumWindows, other.MinimumWindows);
res &= String.Equals(Name, other.Name);
res &= Tree<Reference>.Equals(Root, other.Root);
res &= Version.Equals(Version, other.Version);
return res;
}
public override int GetHashCode()
{
int hash = (Author == null) ? 0 : Author.GetHashCode();
hash = hash * 7 + ((AutoLoadFile == null) ? 0 : AutoLoadFile.GetHashCode());
hash = hash * 7 + ((MinimumRainmeter == null) ? 0 : MinimumRainmeter.GetHashCode());
hash = hash * 7 + ((MinimumWindows == null) ? 0 : MinimumWindows.GetHashCode());
hash = hash * 7 + ((Name == null) ? 0 : Name.GetHashCode());
hash = hash * 7 + ((Root == null) ? 0 : Root.GetHashCode());
hash = hash * 7 + ((Version == null) ? 0 : Version.GetHashCode());
return hash;
}
#endregion
}
}

View File

@ -1,52 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
namespace RainmeterStudio.Model
{
public class Property : INotifyPropertyChanged
{
/// <summary>
/// Gets or sets the name of the property
/// </summary>
public string Name { get; private set; }
private object _value;
/// <summary>
/// Gets or sets the value of the property
/// </summary>
public object Value
{
get
{
return _value;
}
set
{
_value = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Value"));
}
}
/// <summary>
/// Triggered when the value changes
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Initializes this property
/// </summary>
/// <param name="name">Name of the property</param>
/// <param name="value">Value of the property</param>
public Property(string name, object value = null)
{
Name = name;
Value = value;
}
}
}

View File

@ -1,50 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
namespace RainmeterStudio.Model
{
/// <summary>
/// Reference to a file or folder
/// </summary>
public class Reference
{
[XmlAttribute("name")]
public string Name { get; set; }
[XmlAttribute("path")]
public string Path { get; set; }
public Reference()
{
}
public Reference(string name, string path = null)
{
Name = name;
Path = path;
}
public override bool Equals(object obj)
{
var other = obj as Reference;
// Types are different, so not equal
if (other == null)
return false;
// Compare using string equals
return String.Equals(Name, other.Name) && String.Equals(Path, other.Path);
}
public override int GetHashCode()
{
int hash = (Name == null) ? 0 : Name.GetHashCode();
hash = hash * 7 + ((Path == null) ? 0 : Path.GetHashCode());
return hash;
}
}
}

View File

@ -1,157 +0,0 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
namespace RainmeterStudio.Model
{
public class Tree<T> : IList<Tree<T>>
{
public T Data { get; set; }
public ObservableCollection<Tree<T>> Children { get; private set; }
public Tree()
{
Children = new ObservableCollection<Tree<T>>();
Data = default(T);
}
public Tree(T data)
{
Children = new ObservableCollection<Tree<T>>();
Data = data;
}
public int IndexOf(Tree<T> item)
{
return Children.IndexOf(item);
}
public void Insert(int index, Tree<T> item)
{
Children.Insert(index, item);
}
public void RemoveAt(int index)
{
Children.RemoveAt(index);
}
public Tree<T> this[int index]
{
get
{
return Children[index];
}
set
{
Children[index] = value;
}
}
public void Add(Tree<T> item)
{
Children.Add(item);
}
public void Clear()
{
Children.Clear();
}
public bool Contains(Tree<T> item)
{
return Children.Contains(item);
}
public void CopyTo(Tree<T>[] array, int arrayIndex)
{
Children.CopyTo(array, arrayIndex);
}
public int Count
{
get { return Children.Count; }
}
public bool IsReadOnly
{
get { return false; }
}
public bool Remove(Tree<T> item)
{
return Children.Remove(item);
}
public IEnumerator<Tree<T>> GetEnumerator()
{
return Children.GetEnumerator();
}
public int IndexOf(T item)
{
return Children.IndexOf(new Tree<T>(item));
}
public void Insert(int index, T item)
{
Children.Insert(index, new Tree<T>(item));
}
public void Add(T item)
{
Children.Add(new Tree<T>(item));
}
public bool Contains(T item)
{
return Children.Contains(new Tree<T>(item));
}
public void CopyTo(T[] array, int arrayIndex)
{
foreach (var node in Children)
array[arrayIndex++] = node.Data;
}
public bool Remove(T item)
{
return Children.Remove(new Tree<T>(item));
}
public override bool Equals(object obj)
{
Tree<T> other = obj as Tree<T>;
// Types are different, so not equal
if (other == null)
return false;
// Compare data
if (!object.Equals(Data, other.Data))
return false;
// Compare children array
return Children.SequenceEqual(other.Children);
}
public override int GetHashCode()
{
int hash = ((Data == null) ? 0 : Data.GetHashCode());
foreach (var c in Children)
hash = hash * 7 + c.GetHashCode();
return hash;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return Children.GetEnumerator();
}
}
}

View File

@ -7,7 +7,7 @@ using RainmeterStudio.Interop;
namespace RainmeterStudio
{
class Rainmeter
class RainmeterContext
{
#region Imports
@ -19,17 +19,17 @@ namespace RainmeterStudio
#endregion
private static Rainmeter _instance = null;
private static RainmeterContext _instance = null;
/// <summary>
/// Gets the single instance of this class
/// </summary>
public static Rainmeter Instance
public static RainmeterContext Instance
{
get
{
if (_instance == null)
_instance = new Rainmeter();
_instance = new RainmeterContext();
return _instance;
}
@ -39,7 +39,7 @@ namespace RainmeterStudio
#region Constructor, finalizer
private Rainmeter()
private RainmeterContext()
{
_handle = Rainmeter_Initialize();
@ -47,7 +47,7 @@ namespace RainmeterStudio
throw new Exception("Failed to initialize native library.");
}
~Rainmeter()
~RainmeterContext()
{
Rainmeter_Finalize(_handle);
}

View File

@ -3,9 +3,9 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace RainmeterStudio.Documents
namespace RainmeterStudio.Rainmeter.DataTypes
{
public class AutoRegisterAttribute : Attribute
public class Action
{
}
}

View File

@ -0,0 +1,63 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace RainmeterStudio.Rainmeter.DataTypes
{
public abstract class Bang
{
/// <summary>
/// Argument info
/// </summary>
public class ArgumentInfo
{
public string Name { get; set; }
public Type DataType { get; set; }
public ArgumentInfo(string name, Type dataType)
{
Name = name;
DataType = dataType;
}
}
/// <summary>
/// Gets the function name of the bang
/// </summary>
public abstract string FunctionName { get; }
/// <summary>
/// Gets the list of arguments
/// </summary>
public abstract IEnumerable<ArgumentInfo> Arguments { get; }
/// <summary>
/// Executes the bang
/// </summary>
public void Execute(params object[] args)
{
}
/// <summary>
/// Gets the string representation of this bang
/// </summary>
/// <returns>String representation</returns>
public override string ToString()
{
StringBuilder builder = new StringBuilder();
builder.AppendFormat("!{0}", FunctionName);
foreach (var arg in Arguments.Select(x => x.ToString()))
{
if (arg.Any(Char.IsWhiteSpace))
builder.AppendFormat(@" ""{0}""", arg);
else builder.AppendFormat(" {0}", arg);
}
return builder.ToString();
}
}
}

View File

@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace RainmeterStudio.Rainmeter
{
/// <summary>
/// Represents a group
/// </summary>
/// <remarks>
/// Skins, meters, and measures can be categorized into groups to allow
/// easier control with group bangs. For example, the !HideMeterGroup
/// bang may be used to hide multiple meters in a single bang (compared
/// to !HideMeter statements for each meter).
/// </remarks>
public abstract class Group
{
#region Imports
[DllImport("Rainmeter.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern bool Group_BelongsToGroup(out bool result, Int32 handle, string group);
[DllImport("Rainmeter.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern bool Group_Destroy(Int32 handle);
#endregion
/// <summary>
/// Gets or sets the associated handle of this object
/// </summary>
protected Int32 Handle { get; private set; }
/// <summary>
/// Tests if belongs to a group
/// </summary>
/// <param name="group">Group name</param>
/// <returns>True if belongs</returns>
public bool BelongsToGroup(string group)
{
bool result;
if (!Group_BelongsToGroup(out result, Handle, group))
throw new ExternalException("Belongs to group failed.");
return result;
}
/// <summary>
/// Initializes this group
/// </summary>
/// <param name="handle">The handle</param>
protected Group(Int32 handle)
{
Handle = handle;
}
/// <summary>
/// Finalizer
/// </summary>
~Group()
{
Group_Destroy(Handle);
}
}
}

View File

@ -3,9 +3,9 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace RainmeterStudio.Model
namespace RainmeterStudio.Rainmeter
{
public class RainmeterConfig
public class Measure
{
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace RainmeterStudio.Rainmeter
{
public abstract class Meter : Group
{
public Meter(int handle)
: base(handle)
{
}
}
}

View File

@ -0,0 +1,174 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace RainmeterStudio.Rainmeter
{
public abstract class Section : Group
{
#region Imports
[DllImport("Rainmeter.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool Section_GetName(out string result, Int32 handle);
[DllImport("Rainmeter.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool Section_GetOriginalName(out string result, Int32 handle);
[DllImport("Rainmeter.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool Section_HasDynamicVariables(out bool result, Int32 handle);
[DllImport("Rainmeter.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool Section_SetDynamicVariables(Int32 handle, bool value);
[DllImport("Rainmeter.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool Section_ResetUpdateCounter(Int32 handle);
[DllImport("Rainmeter.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool Section_GetUpdateCounter(out int result, Int32 handle);
[DllImport("Rainmeter.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool Section_GetUpdateDivider(out int result, Int32 handle);
[DllImport("Rainmeter.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool Section_GetOnUpdateAction(out string result, Int32 handle);
[DllImport("Rainmeter.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool Section_DoUpdateAction(Int32 handle);
[DllImport("Rainmeter.dll", CallingConvention = CallingConvention.Cdecl)]
static extern bool Section_Destroy(Int32 handle);
#endregion
protected Section(Int32 handle)
: base(handle)
{
}
~Section()
{
Section_Destroy(Handle);
}
/// <summary>
/// Gets the name of the section
/// </summary>
public string Name
{
get
{
string name;
if (!Section_GetName(out name, Handle))
throw new ExternalException("Get name failed.");
return name;
}
}
/// <summary>
/// Gets the original name of the section
/// </summary>
public string OriginalName
{
get
{
string name;
if (!Section_GetOriginalName(out name, Handle))
throw new ExternalException("Get original name failed.");
return name;
}
}
/// <summary>
/// Gets a value indicating if this section has dynamic variables
/// </summary>
public bool HasDynamicVariables
{
get
{
bool result;
if (!Section_HasDynamicVariables(out result, Handle))
throw new ExternalException("Get dynamic variables has failed.");
return result;
}
set
{
if (!Section_SetDynamicVariables(Handle, value))
throw new ExternalException("Set dynamic variables has failed.");
}
}
/// <summary>
/// Resets the update counter
/// </summary>
public void ResetUpdateCounter()
{
if (!Section_ResetUpdateCounter(Handle))
throw new ExternalException("Reset update counter has failed.");
}
/// <summary>
/// Gets the update counter
/// </summary>
public int UpdateCounter
{
get
{
int result;
if (!Section_GetUpdateCounter(out result, Handle))
throw new ExternalException("Get update counter has failed.");
return result;
}
}
/// <summary>
/// Gets the update divider
/// </summary>
public int UpdateDivider
{
get
{
int result;
if (!Section_GetUpdateDivider(out result, Handle))
throw new ExternalException("Get update divider has failed.");
return result;
}
}
/// <summary>
/// Gets the update divider
/// </summary>
public string OnUpdateAction
{
get
{
string result;
if (!Section_GetOnUpdateAction(out result, Handle))
throw new ExternalException("Get on update action has failed.");
return result;
}
}
/// <summary>
/// Executes the update action
/// </summary>
public void DoUpdateAction()
{
if (!Section_DoUpdateAction(Handle))
throw new ExternalException("Do update action has failed.");
}
}
}

View File

@ -35,9 +35,6 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="INIFileParser">
<HintPath>..\packages\ini-parser.2.1.1\lib\INIFileParser.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
@ -71,39 +68,17 @@
<SubType>Designer</SubType>
</Page>
<Compile Include="Business\DocumentManager.cs" />
<Compile Include="Business\PluginManager.cs" />
<Compile Include="Business\ProjectManager.cs" />
<Compile Include="Documents\AutoRegisterAttribute.cs" />
<Compile Include="Documents\DocumentEditorFeatures\ICustomDocumentTitleProvider.cs" />
<Compile Include="Documents\DocumentEditorFeatures\ISelectionPropertiesProvider.cs" />
<Compile Include="Documents\DocumentEditorFeatures\IToolboxProvider.cs" />
<Compile Include="Documents\DocumentEditorFeatures\IUndoSupport.cs" />
<Compile Include="Documents\IDocumentEditor.cs" />
<Compile Include="Documents\IDocumentEditorFactory.cs" />
<Compile Include="Documents\IDocumentStorage.cs" />
<Compile Include="Documents\Text\TextDocument.cs" />
<Compile Include="Documents\Text\TextDocumentTemplate.cs" />
<Compile Include="Documents\Text\TextEditorControl.xaml.cs">
<DependentUpon>TextEditorControl.xaml</DependentUpon>
</Compile>
<Compile Include="Documents\Text\TextStorage.cs" />
<Compile Include="MainClass.cs" />
<Compile Include="Documents\DocumentTemplate_.cs" />
<Compile Include="Model\IDocument.cs" />
<Compile Include="Documents\Ini\IniDocument.cs" />
<Compile Include="Documents\Ini\IniSkinDesigner.cs" />
<Compile Include="Documents\Ini\IniSkinDesignerControl.xaml.cs">
<DependentUpon>IniSkinDesignerControl.xaml</DependentUpon>
</Compile>
<Compile Include="Documents\Ini\IniSkinDesignerFactory.cs" />
<Compile Include="Documents\Text\TextEditor.cs" />
<Compile Include="Documents\Text\TextEditorFactory.cs" />
<Compile Include="Interop\NativeLibrary.cs" />
<Compile Include="Model\Project.cs" />
<Compile Include="Model\Property.cs" />
<Compile Include="Model\RainmeterConfig.cs" />
<Compile Include="Model\Reference.cs" />
<Compile Include="Model\Tree.cs" />
<Compile Include="Rainmeter.cs" />
<Compile Include="Rainmeter\DataTypes\Action.cs" />
<Compile Include="Rainmeter\DataTypes\Bang.cs" />
<Compile Include="Rainmeter\Group.cs" />
<Compile Include="Rainmeter\Measure.cs" />
<Compile Include="Rainmeter\Meter.cs" />
<Compile Include="Rainmeter\Section.cs" />
<Compile Include="Resources\Icons.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
@ -115,8 +90,6 @@
<DependentUpon>Strings.resx</DependentUpon>
</Compile>
<Compile Include="Storage\ProjectStorage.cs" />
<Compile Include="Storage\SkinDirectory.cs" />
<Compile Include="Storage\SerializableTree.cs" />
<Compile Include="UI\Command.cs" />
<Compile Include="UI\Controller\IconProvider.cs" />
<Compile Include="UI\Controller\ProjectController.cs" />
@ -125,7 +98,6 @@
<DependentUpon>CreateDocumentDialog.xaml</DependentUpon>
</Compile>
<Compile Include="UI\Controller\DocumentController.cs" />
<Compile Include="Model\Events\DocumentOpenedEventArgs.cs" />
<Compile Include="UI\Dialogs\CreateProjectDialog.xaml.cs">
<DependentUpon>CreateProjectDialog.xaml</DependentUpon>
</Compile>
@ -135,17 +107,6 @@
<Compile Include="UI\UIManager.cs" />
<Compile Include="UI\ViewModel\DocumentTemplateViewModel.cs" />
<Compile Include="UI\ViewModel\ReferenceViewModel.cs" />
<Compile Include="Utils\DirectoryHelper.cs" />
<Compile Include="Utils\LinqExtension.cs" />
<Compile Include="Utils\TreeExtensions.cs" />
<Page Include="Documents\Ini\IniSkinDesignerControl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Documents\Text\TextEditorControl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="UI\Dialogs\CreateDocumentDialog.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@ -206,7 +167,6 @@
<LastGenOutput>Strings.Designer.cs</LastGenOutput>
</EmbeddedResource>
<None Include="app.config" />
<None Include="LICENSE" />
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
@ -265,6 +225,15 @@
<ItemGroup>
<Resource Include="Resources\Icons\16\folder_project.png" />
</ItemGroup>
<ItemGroup>
<WCFMetadata Include="Service References\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\RainmeterStudio.Core\RainmeterStudio.Core.csproj">
<Project>{1d2a4896-af31-4e82-a84f-4e218067701f}</Project>
<Name>RainmeterStudio.Core</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.

View File

@ -4,7 +4,7 @@ using System.IO;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using RainmeterStudio.Model;
using RainmeterStudio.Core.Model;
namespace RainmeterStudio.Storage
{

View File

@ -1,92 +0,0 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using RainmeterStudio.Model;
namespace RainmeterStudio.Storage
{
/// <summary>
/// A special type of tree that implements a very small subset of tree operations, and can be serialized
/// </summary>
/// <typeparam name="T"></typeparam>
public class SerializableTree<T>
{
/// <summary>
/// Gets or sets the attached data
/// </summary>
[XmlElement("data")]
public T Data { get; set; }
/// <summary>
/// Gets or sets the list of children
/// </summary>
[XmlArray("children"), XmlArrayItem("child")]
public List<SerializableTree<T>> Children { get; set; }
/// <summary>
/// Initializes the serializable tree
/// </summary>
public SerializableTree()
{
Children = new List<SerializableTree<T>>();
Data = default(T);
}
/// <summary>
/// Initializes the serializable tree with specified data
/// </summary>
/// <param name="data">Data</param>
public SerializableTree(T data)
{
Children = new List<SerializableTree<T>>();
Data = data;
}
}
/// <summary>
/// Extension methods for converting to and from serializable trees
/// </summary>
public static class SerializableTreeExtensions
{
/// <summary>
/// Converts tree into a serializable tree
/// </summary>
/// <typeparam name="T">Data type of tree</typeparam>
/// <param name="root">Root node</param>
/// <returns>Serializable tree</returns>
public static SerializableTree<T> AsSerializableTree<T>(this Tree<T> root)
{
// Convert current node
SerializableTree<T> sRoot = new SerializableTree<T>(root.Data);
// Add children
foreach (var child in root.Children)
sRoot.Children.Add(AsSerializableTree(child));
// Return root
return sRoot;
}
/// <summary>
/// Converts serializable tree into a tree
/// </summary>
/// <typeparam name="T">Data type of tree</typeparam>
/// <param name="root">Root node</param>
/// <returns>Tree</returns>
public static Tree<T> AsTree<T>(this SerializableTree<T> root)
{
// Convert current node
Tree<T> sRoot = new Tree<T>(root.Data);
// Add children
foreach (var child in root.Children)
sRoot.Add(AsTree(child));
// Return root
return sRoot;
}
}
}

View File

@ -1,25 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
namespace RainmeterStudio.Storage
{
public static class SkinDirectory
{
private static string _path = null;
public static string Path
{
get
{
return "";
}
set
{
}
}
}
}

View File

@ -1,11 +1,4 @@
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;
using RainmeterStudio.Business;
using RainmeterStudio.Documents.Text;
using System.Windows;
namespace RainmeterStudio.UI
{

View File

@ -1,15 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RainmeterStudio.Business;
using RainmeterStudio.UI.Dialogs;
using RainmeterStudio.Model.Events;
using RainmeterStudio.Model;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using RainmeterStudio.Documents;
using RainmeterStudio.Business;
using RainmeterStudio.Core.Documents;
using RainmeterStudio.Core.Model.Events;
using RainmeterStudio.UI.Dialogs;
namespace RainmeterStudio.UI.Controller
{

View File

@ -6,7 +6,7 @@ using System.Text;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using RainmeterStudio.Model;
using RainmeterStudio.Core.Model;
namespace RainmeterStudio.UI.Controller
{

View File

@ -1,14 +1,9 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using Microsoft.Win32;
using RainmeterStudio.Business;
using RainmeterStudio.Model;
using RainmeterStudio.Core.Model;
using RainmeterStudio.UI.Dialogs;
namespace RainmeterStudio.UI.Controller

View File

@ -12,8 +12,7 @@ using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using RainmeterStudio.Business;
using RainmeterStudio.Documents;
using RainmeterStudio.Model;
using RainmeterStudio.Core.Documents;
namespace RainmeterStudio.UI.Dialogs
{

View File

@ -12,8 +12,7 @@ using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using RainmeterStudio.Business;
using RainmeterStudio.Documents;
using RainmeterStudio.Model;
using RainmeterStudio.Core.Documents;
namespace RainmeterStudio.UI.Dialogs
{

View File

@ -12,7 +12,7 @@ using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using RainmeterStudio.Business;
using RainmeterStudio.Model.Events;
using RainmeterStudio.Core.Model.Events;
using RainmeterStudio.Storage;
using RainmeterStudio.UI.Controller;
using Xceed.Wpf.AvalonDock.Layout;

View File

@ -14,12 +14,12 @@ using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using RainmeterStudio.Core.Model;
using RainmeterStudio.Core.Utils;
using RainmeterStudio.Interop;
using RainmeterStudio.Model;
using RainmeterStudio.Storage;
using RainmeterStudio.UI.Controller;
using RainmeterStudio.UI.ViewModel;
using RainmeterStudio.Utils;
namespace RainmeterStudio.UI
{

View File

@ -3,8 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media;
using RainmeterStudio.Documents;
using RainmeterStudio.Model;
using RainmeterStudio.Core.Documents;
using RainmeterStudio.UI.Controller;
namespace RainmeterStudio.UI.ViewModel

View File

@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using RainmeterStudio.Model;
using RainmeterStudio.Core.Model;
namespace RainmeterStudio.UI.ViewModel
{

View File

@ -1,51 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using RainmeterStudio.Model;
namespace RainmeterStudio.Utils
{
public static class DirectoryHelper
{
/// <summary>
/// Gets a tree of the folder structure
/// </summary>
/// <param name="folder">Folder</param>
/// <returns>A tree</returns>
public static Tree<Reference> GetFolderTree(string folder)
{
// Build tree object
Reference reference = new Reference(Path.GetFileName(folder), folder);
Tree<Reference> tree = new Tree<Reference>(reference);
// Navigate folder structure
if (Directory.Exists(folder))
{
foreach (var item in Directory.EnumerateDirectories(folder)
.Concat(Directory.EnumerateFiles(folder)))
{
tree.Add(GetFolderTree(item));
}
}
// Return tree
return tree;
}
/// <summary>
/// Returns true if two paths are equal
/// </summary>
/// <param name="path1">First path</param>
/// <param name="path2">Second path</param>
/// <returns>True if the paths are equal</returns>
public static bool PathsEqual(string path1, string path2)
{
path1 = System.IO.Path.GetFullPath(path1);
path2 = System.IO.Path.GetFullPath(path2);
return String.Equals(path1, path2, StringComparison.InvariantCultureIgnoreCase);
}
}
}

View File

@ -1,25 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace RainmeterStudio.Utils
{
/// <summary>
/// Linq extensions
/// </summary>
public static class LinqExtensions
{
/// <summary>
/// Applies action on every item from the container
/// </summary>
/// <typeparam name="T">Enumerable type</typeparam>
/// <param name="container">Container</param>
/// <param name="action">Action</param>
public static void ForEach<T> (this IEnumerable<T> container, Action<T> action)
{
foreach (var obj in container)
action(obj);
}
}
}

View File

@ -1,162 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RainmeterStudio.Model;
namespace RainmeterStudio.Utils
{
/// <summary>
/// Extension methods for trees
/// </summary>
public static class TreeExtensions
{
/// <summary>
/// Tree traversal orders
/// </summary>
public enum TreeTraversalOrder
{
BreadthFirst,
DepthFirst,
DepthFirstPreOrder = DepthFirst,
DepthFirstPostOrder
}
/// <summary>
/// Traverses a tree
/// </summary>
/// <typeparam name="T">Tree data type</typeparam>
/// <param name="root">Root node of tree</param>
/// <param name="order">Traversal order</param>
/// <returns>An enumeration of the nodes in the specified traverse order</returns>
public static IEnumerable<Tree<T>> Traverse<T>(this Tree<T> root, TreeTraversalOrder order = TreeTraversalOrder.BreadthFirst)
{
if (order == TreeTraversalOrder.BreadthFirst)
return TraverseBF(root);
else return TraverseDF(root, order);
}
private static IEnumerable<Tree<T>> TraverseDF<T>(this Tree<T> root, TreeTraversalOrder order)
{
// Preorder - return root first
if (order == TreeTraversalOrder.DepthFirstPreOrder)
yield return root;
// Return children
foreach (var child in root.Children)
foreach (var node in TraverseDF(child, order))
yield return node;
// Postorder - return root last
if (order == TreeTraversalOrder.DepthFirstPostOrder)
yield return root;
}
private static IEnumerable<Tree<T>> TraverseBF<T>(this Tree<T> root)
{
// Create a queue containing the root
Queue<Tree<T>> queue = new Queue<Tree<T>>();
queue.Enqueue(root);
// While there are elements in the queue
while (queue.Count > 0)
{
// Return next node in tree
var node = queue.Dequeue();
yield return node;
// Enqueue node's children
foreach (var child in node.Children)
queue.Enqueue(child);
}
}
/// <summary>
/// Applies an action to every node of the tree
/// </summary>
/// <typeparam name="T">Tree data type</typeparam>
/// <param name="root">Root node of tree</param>
/// <param name="action">Action to apply</param>
/// <param name="order">Traversal order</param>
public static void Apply<T>(this Tree<T> root, Action<Tree<T>> action, TreeTraversalOrder order = TreeTraversalOrder.BreadthFirst)
{
// Safety check
if (action == null)
return;
// Apply action
foreach (var node in Traverse(root, order))
action(node);
}
/// <summary>
/// Applies an action to every node of the tree
/// </summary>
/// <typeparam name="T">Tree data type</typeparam>
/// <param name="root">Root node of tree</param>
/// <param name="action">Action to apply</param>
/// <param name="order">Traversal order</param>
public static void ApplyToData<T>(this Tree<T> root, Action<T> action, TreeTraversalOrder order = TreeTraversalOrder.BreadthFirst)
where T : class
{
// Safety check
if (action == null)
return;
// Apply action
foreach (var node in Traverse(root, order))
action(node.Data);
}
/// <summary>
/// Rebuilds the tree by applying the specified transform function
/// </summary>
/// <typeparam name="T">Data type of tree</typeparam>
/// <typeparam name="TResult">Data type of rebuilt tree</typeparam>
/// <param name="root">The root node</param>
/// <param name="transformFunction">The transform function</param>
/// <returns>The transformed tree</returns>
public static Tree<TResult> Transform<T,TResult>(this Tree<T> root, Func<Tree<T>, Tree<TResult>> transformFunction)
{
// Safety check
if (transformFunction == null)
throw new ArgumentNullException("Transform function cannot be null.");
// Build root
Tree<TResult> resRoot = transformFunction(root);
// Add children
foreach (var node in root.Children)
resRoot.Children.Add(Transform(node, transformFunction));
// Return
return resRoot;
}
/// <summary>
/// Rebuilds the tree by applying the specified transform function
/// </summary>
/// <typeparam name="T">Data type of tree</typeparam>
/// <typeparam name="TResult">Data type of rebuilt tree</typeparam>
/// <param name="root">The root node</param>
/// <param name="transformFunction">The transform function</param>
/// <returns>The transformed tree</returns>
public static Tree<TResult> TransformData<T, TResult>(this Tree<T> root, Func<T, TResult> transformFunction)
{
// Safety check
if (transformFunction == null)
throw new ArgumentNullException("Transform function cannot be null.");
// Build root
Tree<TResult> resRoot = new Tree<TResult>(transformFunction(root.Data));
// Add children
foreach (var node in root.Children)
resRoot.Children.Add(TransformData(node, transformFunction));
// Return
return resRoot;
}
}
}

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AvalonDock" version="2.0.2000" targetFramework="net40" />
<package id="ini-parser" version="2.1.1" targetFramework="net40" />
</packages>