mirror of
https://github.com/chibicitiberiu/rainmeter-studio.git
synced 2024-02-24 04:33:31 +00:00
Rewrote references
This commit is contained in:
parent
520eed12a6
commit
10aa72176e
@ -4,6 +4,8 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Xml.Serialization;
|
using System.Xml.Serialization;
|
||||||
using RainmeterStudio.Core.Storage;
|
using RainmeterStudio.Core.Storage;
|
||||||
|
using RainmeterStudio.Core.Utils;
|
||||||
|
using Version = RainmeterStudio.Core.Utils.Version;
|
||||||
|
|
||||||
namespace RainmeterStudio.Core.Model
|
namespace RainmeterStudio.Core.Model
|
||||||
{
|
{
|
||||||
@ -12,85 +14,114 @@ namespace RainmeterStudio.Core.Model
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class Project
|
public class Project
|
||||||
{
|
{
|
||||||
#region Private fields
|
|
||||||
|
|
||||||
private string _name;
|
|
||||||
private string _path;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the name of the project
|
/// Gets or sets the name of the project
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[XmlElement(ElementName = "name", Order = 1)]
|
||||||
public string Name
|
public string Name
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return _name;
|
return Root.Name;
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_name = value;
|
Root.Name = value;
|
||||||
|
|
||||||
if (Root != null)
|
|
||||||
Root.Data = new Reference(Name, Path);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the file path of this project
|
/// Gets or sets the file path of this project
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[XmlIgnore]
|
||||||
public string Path
|
public string Path
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return _path;
|
return Root.StoragePath;
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_path = value;
|
Root.StoragePath = value;
|
||||||
|
|
||||||
if (Root != null)
|
|
||||||
Root.Data = new Reference(Name, Path);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the author of the project
|
/// Gets or sets the author of the project
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[XmlElement(ElementName = "author", Order = 2)]
|
||||||
public string Author { get; set; }
|
public string Author { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the version of the project
|
/// Gets or sets the version of the project
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[XmlElement(ElementName = "version", Order = 3)]
|
||||||
public Version Version { get; set; }
|
public Version Version { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the reference to the file to automatically load at package installation
|
/// Gets or sets the reference to the file that automatically loads at package installation
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[XmlIgnore]
|
||||||
public Reference AutoLoadFile { get; set; }
|
public Reference AutoLoadFile { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the qualified name of the auto load file
|
||||||
|
/// </summary>
|
||||||
|
[XmlElement(ElementName = "autoLoadFile", Order = 7)]
|
||||||
|
public string AutoLoadFileQualifiedName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return ((AutoLoadFile == null) ? null : AutoLoadFile.QualifiedName);
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
AutoLoadFile = Root.GetReference(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the list of variable files
|
/// Gets or sets the list of variable files
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[XmlIgnore]
|
||||||
public List<Reference> VariableFiles { get; set; }
|
public List<Reference> VariableFiles { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the list of variable files qualified names
|
||||||
|
/// </summary>
|
||||||
|
[XmlArray(ElementName = "variableFiles", Order = 8)]
|
||||||
|
public string[] VariableFilesQualifiedNames
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return VariableFiles.Select(x => x.QualifiedName).ToArray();
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
VariableFiles.Clear();
|
||||||
|
VariableFiles.AddRange(value.Select(x => Root.GetReference(x)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the minimum rainmeter version
|
/// Gets or sets the minimum rainmeter version
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[XmlElement(ElementName = "minimumRainmeter", Order = 4)]
|
||||||
public Version MinimumRainmeter { get; set; }
|
public Version MinimumRainmeter { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the minimum Windows version
|
/// Gets or sets the minimum Windows version
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[XmlElement(ElementName = "minimumWindows", Order = 5)]
|
||||||
public Version MinimumWindows { get; set; }
|
public Version MinimumWindows { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the root node
|
/// Gets or sets the root node
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Tree<Reference> Root { get; set; }
|
[XmlElement(ElementName = "root", Order = 6)]
|
||||||
|
public Reference Root { get; set; }
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -101,7 +132,7 @@ namespace RainmeterStudio.Core.Model
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Project()
|
public Project()
|
||||||
{
|
{
|
||||||
Root = new Tree<Reference>();
|
Root = new Reference(String.Empty);
|
||||||
VariableFiles = new List<Reference>();
|
VariableFiles = new List<Reference>();
|
||||||
Version = new Version();
|
Version = new Version();
|
||||||
MinimumRainmeter = new Version("3.1");
|
MinimumRainmeter = new Version("3.1");
|
||||||
@ -109,5 +140,20 @@ namespace RainmeterStudio.Core.Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
#region Operations
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks for reference in project
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="reference">Reference</param>
|
||||||
|
/// <returns>True if reference was found</returns>
|
||||||
|
public bool Contains(Reference reference)
|
||||||
|
{
|
||||||
|
return Root.TreeContains(reference);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,90 +1,153 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Collections.Specialized;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Xml.Serialization;
|
using System.Xml.Serialization;
|
||||||
|
using RainmeterStudio.Core.Utils;
|
||||||
|
|
||||||
namespace RainmeterStudio.Core.Model
|
namespace RainmeterStudio.Core.Model
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reference to a file or folder
|
/// Reference to a file or folder
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DebuggerDisplay("ProjectPath = {ProjectPath}, StoragePath = {StoragePath}")]
|
[DebuggerDisplay("QualifiedName = {QualifiedName}, StoragePath = {StoragePath}")]
|
||||||
public struct Reference
|
public class Reference : INotifyCollectionChanged
|
||||||
{
|
{
|
||||||
private string[] _projectPath;
|
private Dictionary<string, Reference> _children;
|
||||||
private string _storagePath;
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the parent of this reference
|
||||||
|
/// </summary>
|
||||||
|
[XmlIgnore]
|
||||||
|
public Reference Parent { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the children references
|
||||||
|
/// </summary>
|
||||||
|
[XmlIgnore]
|
||||||
|
public ReadOnlyDictionary<string, Reference> ChildrenDictionary
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return new ReadOnlyDictionary<string,Reference>(_children);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets children
|
||||||
|
/// </summary>
|
||||||
|
[XmlArray("children")]
|
||||||
|
public Reference[] Children
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _children.Values.ToArray();
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
value.ForEach(Add);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the name of the reference
|
/// Gets the name of the reference
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[XmlAttribute("name")]
|
||||||
public string Name
|
public string Name
|
||||||
|
{
|
||||||
|
get; set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the full qualified name of this reference
|
||||||
|
/// </summary>
|
||||||
|
[XmlIgnore]
|
||||||
|
public string QualifiedName
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
// Try to get the last item from the project path
|
if (Parent == null)
|
||||||
if (_projectPath != null && _projectPath.Length > 0)
|
{
|
||||||
return _projectPath[_projectPath.Length - 1];
|
// Return name
|
||||||
|
return Name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If it has a parent, get the parent's name
|
||||||
|
return Parent.QualifiedName + '/' + Name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// None found, return null
|
/// <summary>
|
||||||
return null;
|
/// Gets the parts of the full qualified name of this reference
|
||||||
|
/// </summary>
|
||||||
|
[XmlIgnore]
|
||||||
|
public IEnumerable<string> QualifiedParts
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (Parent == null)
|
||||||
|
{
|
||||||
|
return Enumerable.Repeat(Name, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Parent.QualifiedParts.Append(Name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the path to the file on the disk. If reference is in a project, the path should be relative.
|
/// Gets the path to the file on the disk. If reference is in a project, the path should be relative.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
[XmlAttribute("storagePath")]
|
||||||
public string StoragePath
|
public string StoragePath
|
||||||
{
|
{
|
||||||
get
|
get;
|
||||||
{
|
set;
|
||||||
return _storagePath;
|
}
|
||||||
}
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes the reference
|
||||||
|
/// </summary>
|
||||||
|
public Reference()
|
||||||
|
: this(null, null)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the qualified path
|
/// Initializes the reference
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string ProjectPath
|
/// <param name="projectPath">Project path to item referenced</param>
|
||||||
|
public Reference(string name)
|
||||||
|
: this(name, null)
|
||||||
{
|
{
|
||||||
get
|
|
||||||
{
|
|
||||||
if (_projectPath != null)
|
|
||||||
{
|
|
||||||
return _projectPath.Aggregate(String.Empty, (a, b) => a + "/" + b);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes the reference
|
/// Initializes the reference
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">Name of reference</param>
|
/// <param name="name">Name of reference</param>
|
||||||
/// <param name="path">Path to item referenced</param>
|
/// <param name="storagePath">Path to item on disk</param>
|
||||||
public Reference(string filePath, string projectPath = null)
|
public Reference(string name, string storagePath)
|
||||||
{
|
{
|
||||||
_storagePath = filePath;
|
StoragePath = storagePath;
|
||||||
|
Name = name;
|
||||||
if (projectPath != null)
|
_children = new Dictionary<string, Reference>();
|
||||||
{
|
|
||||||
_projectPath = projectPath.Split('/').Skip(1).ToArray();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_projectPath = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
#endregion
|
||||||
/// Checks if the reference points to a project item
|
|
||||||
/// </summary>
|
|
||||||
public bool IsInProject()
|
|
||||||
{
|
|
||||||
return (_projectPath != null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if the reference has a file on disk
|
/// Checks if the reference has a file on disk
|
||||||
@ -92,7 +155,90 @@ namespace RainmeterStudio.Core.Model
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public bool IsOnStorage()
|
public bool IsOnStorage()
|
||||||
{
|
{
|
||||||
return (_storagePath != null);
|
return (StoragePath != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds a child reference
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="reference"></param>
|
||||||
|
public void Add(Reference reference)
|
||||||
|
{
|
||||||
|
// Make sure object is not parented yet
|
||||||
|
if (reference.Parent != null)
|
||||||
|
throw new ArgumentException("Reference must be removed from its current parent first.");
|
||||||
|
|
||||||
|
// Add and parent
|
||||||
|
reference.Parent = this;
|
||||||
|
_children.Add(reference.Name, reference);
|
||||||
|
|
||||||
|
// Trigger event
|
||||||
|
if (CollectionChanged != null)
|
||||||
|
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, reference));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes a reference
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="reference">Reference to remove</param>
|
||||||
|
/// <returns>True if removed successfully</returns>
|
||||||
|
public bool Remove(Reference reference)
|
||||||
|
{
|
||||||
|
// Make sure we are the parent
|
||||||
|
if (reference.Parent != this)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Remove
|
||||||
|
reference.Parent = null;
|
||||||
|
bool res = _children.Remove(reference.Name);
|
||||||
|
|
||||||
|
// Trigger event
|
||||||
|
if (CollectionChanged != null)
|
||||||
|
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, reference));
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes this reference from its parent
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True if unparented successfully</returns>
|
||||||
|
public bool Unparent()
|
||||||
|
{
|
||||||
|
if (Parent != null)
|
||||||
|
return Parent.Remove(this);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes all children
|
||||||
|
/// </summary>
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
// Unparent
|
||||||
|
foreach (var pair in _children)
|
||||||
|
{
|
||||||
|
pair.Value.Parent = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear
|
||||||
|
_children.Clear();
|
||||||
|
|
||||||
|
// Trigger event
|
||||||
|
if (CollectionChanged != null)
|
||||||
|
CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the number of children
|
||||||
|
/// </summary>
|
||||||
|
public int Count
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _children.Count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -105,14 +251,7 @@ namespace RainmeterStudio.Core.Model
|
|||||||
if (obj is Reference)
|
if (obj is Reference)
|
||||||
{
|
{
|
||||||
Reference other = (Reference)obj;
|
Reference other = (Reference)obj;
|
||||||
|
return (String.Equals(QualifiedName, other.QualifiedName));
|
||||||
// 2 references are equal if they point to the same project item
|
|
||||||
if (_projectPath != null && other._projectPath != null)
|
|
||||||
return _projectPath.SequenceEqual(other._projectPath);
|
|
||||||
|
|
||||||
// If there is no project item, compare storage paths
|
|
||||||
if (_projectPath == null && other._projectPath == null)
|
|
||||||
return String.Equals(_storagePath, other._storagePath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -124,28 +263,114 @@ namespace RainmeterStudio.Core.Model
|
|||||||
/// <returns>Hash code</returns>
|
/// <returns>Hash code</returns>
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
int hash = (_projectPath == null) ? 0 : _projectPath.GetHashCode();
|
return QualifiedName.GetHashCode();
|
||||||
|
|
||||||
if (_projectPath != null)
|
|
||||||
{
|
|
||||||
foreach (var item in _projectPath)
|
|
||||||
hash = hash * 7 + item.GetHashCode();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
hash = hash * 2113 + ((_storagePath == null) ? 0 : _storagePath.GetHashCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
return hash;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the string representation of this reference
|
/// Gets the string representation of this reference
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns>String representation</returns>
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return ProjectPath;
|
return QualifiedName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Triggered when children are added or removed.
|
||||||
|
/// </summary>
|
||||||
|
public event NotifyCollectionChangedEventHandler CollectionChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Provides useful methods for references
|
||||||
|
/// </summary>
|
||||||
|
public static class ReferenceExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Tries to get a reference from the same tree having specified qualified name
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="this">Reference contained in the tree</param>
|
||||||
|
/// <param name="qualifiedName">Full qualified name</param>
|
||||||
|
/// <param name="output">Found reference</param>
|
||||||
|
/// <returns>True if succeeded to find the reference</returns>
|
||||||
|
public static bool TryGetReference(this Reference @this, string qualifiedName, out Reference output)
|
||||||
|
{
|
||||||
|
var thisQualifiedName = @this.QualifiedName;
|
||||||
|
|
||||||
|
// Am I the reference? return myself
|
||||||
|
if (qualifiedName.Equals(thisQualifiedName))
|
||||||
|
{
|
||||||
|
output = @this;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Qualified name is a child, look child up
|
||||||
|
else if (qualifiedName.StartsWith(thisQualifiedName))
|
||||||
|
{
|
||||||
|
int startIndex = thisQualifiedName.Length + 1;
|
||||||
|
int endIndex = qualifiedName.IndexOf('/', startIndex);
|
||||||
|
|
||||||
|
string child;
|
||||||
|
Reference childRef;
|
||||||
|
|
||||||
|
if (endIndex < 0)
|
||||||
|
{
|
||||||
|
child = qualifiedName.Substring(startIndex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
child = qualifiedName.Substring(startIndex, endIndex - startIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to get child
|
||||||
|
if (@this.ChildrenDictionary.TryGetValue(child, out childRef))
|
||||||
|
{
|
||||||
|
return childRef.TryGetReference(qualifiedName, out output);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Qualified name is not a child and not 'this', so ask parent to find it
|
||||||
|
else if (@this.Parent != null)
|
||||||
|
{
|
||||||
|
return @this.Parent.TryGetReference(qualifiedName, out output);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Failed to find child
|
||||||
|
output = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a reference from the same tree having specified qualified name
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="this">Reference contained in the tree</param>
|
||||||
|
/// <param name="qualifiedName">Full qualified name</param>
|
||||||
|
/// <returns>Found reference</returns>
|
||||||
|
/// <exception cref="ArgumentException">If qualified name not found</exception>
|
||||||
|
public static Reference GetReference(this Reference @this, string qualifiedName)
|
||||||
|
{
|
||||||
|
Reference res;
|
||||||
|
|
||||||
|
if (TryGetReference(@this, qualifiedName, out res))
|
||||||
|
{
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Could not find reference.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if a reference is in the same tree as this
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="this">Reference that is in the tree we search in</param>
|
||||||
|
/// <param name="other">Reference to search</param>
|
||||||
|
/// <returns>True if the tree contains the reference.</returns>
|
||||||
|
public static bool TreeContains(this Reference @this, Reference reference)
|
||||||
|
{
|
||||||
|
Reference temp;
|
||||||
|
return TryGetReference(@this, reference.QualifiedName, out temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -153,5 +153,10 @@ namespace RainmeterStudio.Core.Model
|
|||||||
{
|
{
|
||||||
return Children.GetEnumerator();
|
return Children.GetEnumerator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void TreeExpand(bool p)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,9 @@
|
|||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>RainmeterStudio.Core</RootNamespace>
|
<RootNamespace>RainmeterStudio.Core</RootNamespace>
|
||||||
<AssemblyName>RainmeterStudio.Core</AssemblyName>
|
<AssemblyName>RainmeterStudio.Core</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<TargetFrameworkProfile />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
@ -21,6 +22,7 @@
|
|||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
@ -29,6 +31,7 @@
|
|||||||
<DefineConstants>TRACE</DefineConstants>
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="PresentationCore" />
|
<Reference Include="PresentationCore" />
|
||||||
@ -62,8 +65,6 @@
|
|||||||
<Compile Include="Model\Reference.cs" />
|
<Compile Include="Model\Reference.cs" />
|
||||||
<Compile Include="Model\Tree.cs" />
|
<Compile Include="Model\Tree.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="Storage\SerializableProject.cs" />
|
|
||||||
<Compile Include="Storage\SerializableReference.cs" />
|
|
||||||
<Compile Include="Storage\SerializableTree.cs" />
|
<Compile Include="Storage\SerializableTree.cs" />
|
||||||
<Compile Include="Utils\DirectoryHelper.cs" />
|
<Compile Include="Utils\DirectoryHelper.cs" />
|
||||||
<Compile Include="Utils\InputHelper.cs" />
|
<Compile Include="Utils\InputHelper.cs" />
|
||||||
@ -71,6 +72,7 @@
|
|||||||
<Compile Include="Utils\BitmapHelper.cs" />
|
<Compile Include="Utils\BitmapHelper.cs" />
|
||||||
<Compile Include="Utils\PathHelper.cs" />
|
<Compile Include="Utils\PathHelper.cs" />
|
||||||
<Compile Include="Utils\TreeExtensions.cs" />
|
<Compile Include="Utils\TreeExtensions.cs" />
|
||||||
|
<Compile Include="Utils\Version.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||||
|
@ -1,212 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Xml.Serialization;
|
|
||||||
using RainmeterStudio.Core.Model;
|
|
||||||
using RainmeterStudio.Core.Utils;
|
|
||||||
|
|
||||||
namespace RainmeterStudio.Core.Storage
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Helper class to serialize or deserialize project objects
|
|
||||||
/// </summary>
|
|
||||||
public class SerializableProject
|
|
||||||
{
|
|
||||||
private Project _project;
|
|
||||||
private SerializableReference _autoLoadFile;
|
|
||||||
private List<SerializableReference> _variableFiles;
|
|
||||||
private SerializableTree<SerializableReference> _root;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the project
|
|
||||||
/// </summary>
|
|
||||||
[XmlIgnore]
|
|
||||||
public Project Project
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
_project.AutoLoadFile = _autoLoadFile.Reference;
|
|
||||||
_project.VariableFiles = _variableFiles.Select(x => x.Reference).ToList();
|
|
||||||
_project.Root = _root.AsTree().TransformData(x => x.Reference);
|
|
||||||
return _project;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_project = value;
|
|
||||||
UpdateSelf();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the project name
|
|
||||||
/// </summary>
|
|
||||||
[XmlElement("name")]
|
|
||||||
public string Name
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return Project.Name;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Project.Name = value;
|
|
||||||
UpdateSelf();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the project path
|
|
||||||
/// </summary>
|
|
||||||
[XmlIgnore]
|
|
||||||
public string Path
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return Project.Path;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Project.Path = value;
|
|
||||||
UpdateSelf();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the author of the project
|
|
||||||
/// </summary>
|
|
||||||
[XmlElement("author")]
|
|
||||||
public string Author
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return Project.Author;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Project.Author = value;
|
|
||||||
UpdateSelf();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the project version
|
|
||||||
/// </summary>
|
|
||||||
[XmlElement("version")]
|
|
||||||
public string Version
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return Project.Version.ToString();
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Project.Version = new Version(value);
|
|
||||||
UpdateSelf();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the reference to the file to automatically load at package installation
|
|
||||||
/// </summary>
|
|
||||||
[XmlElement("autoLoadFile")]
|
|
||||||
public SerializableReference AutoLoadFile
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _autoLoadFile;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_autoLoadFile = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the list of variable files
|
|
||||||
/// </summary>
|
|
||||||
[XmlArray("variableFiles")]
|
|
||||||
public List<SerializableReference> VariableFiles
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _variableFiles;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_variableFiles = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the minimum rainmeter version
|
|
||||||
/// </summary>
|
|
||||||
public string MinimumRainmeter
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return Project.MinimumRainmeter.ToString();
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Project.MinimumRainmeter = new Version(value);
|
|
||||||
UpdateSelf();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the minimum Windows version
|
|
||||||
/// </summary>
|
|
||||||
public string MinimumWindows
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return Project.MinimumWindows.ToString();
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Project.MinimumWindows = new Version(value);
|
|
||||||
UpdateSelf();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the root node
|
|
||||||
/// </summary>
|
|
||||||
public SerializableTree<SerializableReference> Root
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return _root;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
_root = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes the serializable project
|
|
||||||
/// </summary>
|
|
||||||
public SerializableProject()
|
|
||||||
{
|
|
||||||
Project = new Project();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes the serializable project
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="project">Base project</param>
|
|
||||||
public SerializableProject(Project project)
|
|
||||||
{
|
|
||||||
Project = project;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateSelf()
|
|
||||||
{
|
|
||||||
_autoLoadFile = new SerializableReference(_project.AutoLoadFile);
|
|
||||||
_variableFiles = _project.VariableFiles.Select(x => new SerializableReference(x)).ToList();
|
|
||||||
_root = _project.Root.TransformData(x => new SerializableReference(x)).AsSerializableTree();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,81 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Xml.Serialization;
|
|
||||||
using RainmeterStudio.Core.Model;
|
|
||||||
using RainmeterStudio.Core.Utils;
|
|
||||||
|
|
||||||
namespace RainmeterStudio.Core.Storage
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a reference that can be serialized
|
|
||||||
/// </summary>
|
|
||||||
public class SerializableReference
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the name of the reference
|
|
||||||
/// </summary>
|
|
||||||
[XmlElement("storagePath")]
|
|
||||||
public string StoragePath
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
// Return only relative paths
|
|
||||||
if (Path.IsPathRooted(Reference.StoragePath))
|
|
||||||
{
|
|
||||||
return PathHelper.GetRelativePath(Reference.StoragePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Reference.StoragePath;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Reference = new Reference(value, ProjectPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the path of the reference
|
|
||||||
/// </summary>
|
|
||||||
[XmlElement("projectPath")]
|
|
||||||
public string ProjectPath
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return Reference.ProjectPath;
|
|
||||||
}
|
|
||||||
set
|
|
||||||
{
|
|
||||||
Reference = new Reference(StoragePath, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the (immutable) reference
|
|
||||||
/// </summary>
|
|
||||||
[XmlIgnore]
|
|
||||||
public Reference Reference
|
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes this serializable reference
|
|
||||||
/// </summary>
|
|
||||||
public SerializableReference()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes this serializable reference
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="reference">Reference to use</param>
|
|
||||||
public SerializableReference(Reference reference)
|
|
||||||
{
|
|
||||||
Reference = reference;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -14,24 +14,23 @@ namespace RainmeterStudio.Core.Utils
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="folder">Folder</param>
|
/// <param name="folder">Folder</param>
|
||||||
/// <returns>A tree</returns>
|
/// <returns>A tree</returns>
|
||||||
public static Tree<Reference> GetFolderTree(string folder)
|
public static Reference GetFolderTree(string folder)
|
||||||
{
|
{
|
||||||
// Build tree object
|
// Build tree object
|
||||||
Reference reference = new Reference(Path.GetFileName(folder), folder);
|
Reference refTree = new Reference(Path.GetFileName(folder), folder);
|
||||||
Tree<Reference> tree = new Tree<Reference>(reference);
|
|
||||||
|
|
||||||
// Navigate folder structure
|
// Navigate folder structure
|
||||||
if (Directory.Exists(folder))
|
if (Directory.Exists(folder))
|
||||||
{
|
{
|
||||||
foreach (var item in Directory.EnumerateDirectories(folder)
|
foreach (var item in Directory.EnumerateDirectories(folder)
|
||||||
.Concat(Directory.EnumerateFiles(folder)))
|
.Concat(Directory.EnumerateFiles(folder)))
|
||||||
{
|
{
|
||||||
tree.Add(GetFolderTree(item));
|
refTree.Add(GetFolderTree(item));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return tree
|
// Return tree
|
||||||
return tree;
|
return refTree;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
435
RainmeterStudio.Core/Utils/Version.cs
Normal file
435
RainmeterStudio.Core/Utils/Version.cs
Normal file
@ -0,0 +1,435 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Serialization;
|
||||||
|
|
||||||
|
namespace RainmeterStudio.Core.Utils
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Serializable version of the System.Version class.
|
||||||
|
/// </summary>
|
||||||
|
public class Version : ICloneable, IComparable
|
||||||
|
{
|
||||||
|
private int _major, _minor, _build, _revision;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the major.
|
||||||
|
/// </summary>
|
||||||
|
/// <value></value>
|
||||||
|
[XmlAttribute("major")]
|
||||||
|
public int Major
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _major;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value < 0)
|
||||||
|
throw new ArgumentOutOfRangeException("Major out of range.");
|
||||||
|
|
||||||
|
_major = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the minor.
|
||||||
|
/// </summary>
|
||||||
|
/// <value></value>
|
||||||
|
[XmlAttribute("minor")]
|
||||||
|
public int Minor
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _minor;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value < -1)
|
||||||
|
throw new ArgumentOutOfRangeException("Minor out of range.");
|
||||||
|
|
||||||
|
_minor = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the build.
|
||||||
|
/// </summary>
|
||||||
|
/// <value></value>
|
||||||
|
[XmlAttribute("build")]
|
||||||
|
public int Build
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _build;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value < -1)
|
||||||
|
throw new ArgumentOutOfRangeException("Build out of range.");
|
||||||
|
|
||||||
|
_build = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the revision.
|
||||||
|
/// </summary>
|
||||||
|
/// <value></value>
|
||||||
|
[XmlAttribute("revision")]
|
||||||
|
public int Revision
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _revision;
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value < -1)
|
||||||
|
throw new ArgumentOutOfRangeException("Revision out of range.");
|
||||||
|
|
||||||
|
_revision = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of version.
|
||||||
|
/// </summary>
|
||||||
|
public Version()
|
||||||
|
{
|
||||||
|
Major = 1;
|
||||||
|
Minor = 0;
|
||||||
|
Revision = -1;
|
||||||
|
Build = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of Version.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="version">Version string</param>
|
||||||
|
public Version(string version)
|
||||||
|
{
|
||||||
|
// Parse
|
||||||
|
int major, minor, revision, build;
|
||||||
|
Parse(version, out major, out minor, out build, out revision);
|
||||||
|
|
||||||
|
// Commit
|
||||||
|
Major = major;
|
||||||
|
Minor = minor;
|
||||||
|
Build = build;
|
||||||
|
Revision = revision;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of Version.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="major">Major</param>
|
||||||
|
public Version(int major)
|
||||||
|
: this(major, -1, -1, -1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of Version.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="major">Major</param>
|
||||||
|
/// <param name="minor">Minor</param>
|
||||||
|
public Version(int major, int minor)
|
||||||
|
: this(major, minor, -1, -1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of Version.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="major">Major</param>
|
||||||
|
/// <param name="minor">Minor</param>
|
||||||
|
/// <param name="build">Build</param>
|
||||||
|
public Version(int major, int minor, int build)
|
||||||
|
: this(major, minor, build, -1)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new instance of Version.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="major">Major</param>
|
||||||
|
/// <param name="minor">Minor</param>
|
||||||
|
/// <param name="build">Build</param>
|
||||||
|
/// <param name="revision">Revision</param>
|
||||||
|
public Version(int major, int minor, int build, int revision)
|
||||||
|
{
|
||||||
|
Major = major;
|
||||||
|
Minor = minor;
|
||||||
|
Build = build;
|
||||||
|
Revision = revision;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region ICloneable Members
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clones this instance.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public object Clone()
|
||||||
|
{
|
||||||
|
return new Version(Major, Minor, Build, Revision);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IComparable Members
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Compares to another object.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">Other object</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public int CompareTo(object obj)
|
||||||
|
{
|
||||||
|
if (obj == null)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Version version = obj as Version;
|
||||||
|
|
||||||
|
if (version == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Argument must be version");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Major != version.Major)
|
||||||
|
{
|
||||||
|
return (Major - version.Major);
|
||||||
|
}
|
||||||
|
if (Minor != version.Minor)
|
||||||
|
{
|
||||||
|
return (Minor - version.Minor);
|
||||||
|
}
|
||||||
|
if (Build != version.Build)
|
||||||
|
{
|
||||||
|
return (Build - version.Build);
|
||||||
|
}
|
||||||
|
if (Revision != version.Revision)
|
||||||
|
{
|
||||||
|
return (Revision - version.Revision);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
/// <summary>
|
||||||
|
/// Equalss the specified obj.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj">Obj.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
Version version = obj as Version;
|
||||||
|
|
||||||
|
if (version == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return this.CompareTo(obj) == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the hash code.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
int hash = Major;
|
||||||
|
hash = hash * 7 + Minor;
|
||||||
|
hash = hash * 7 + Build;
|
||||||
|
hash = hash * 7 + Revision;
|
||||||
|
return Revision;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Equals operator.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="v1">first object</param>
|
||||||
|
/// <param name="v2">second object</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static bool operator ==(Version v1, Version v2)
|
||||||
|
{
|
||||||
|
return Object.Equals(v1, v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Not equals operator.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="v1">first object</param>
|
||||||
|
/// <param name="v2">second object</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static bool operator !=(Version v1, Version v2)
|
||||||
|
{
|
||||||
|
return !Object.Equals(v1, v2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Greater than operator.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="v1">first object</param>
|
||||||
|
/// <param name="v2">second object</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static bool operator >(Version v1, Version v2)
|
||||||
|
{
|
||||||
|
return v1.CompareTo(v2) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Greater or equal than operator.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="v1">first object</param>
|
||||||
|
/// <param name="v2">second object</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static bool operator >=(Version v1, Version v2)
|
||||||
|
{
|
||||||
|
return v1.CompareTo(v2) >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Less than operator.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="v1">first object</param>
|
||||||
|
/// <param name="v2">second object</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static bool operator <(Version v1, Version v2)
|
||||||
|
{
|
||||||
|
return v1.CompareTo(v2) < 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Less or equal than operator.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="v1">first object</param>
|
||||||
|
/// <param name="v2">second object</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static bool operator <=(Version v1, Version v2)
|
||||||
|
{
|
||||||
|
return v1.CompareTo(v2) <= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts to string.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>String representation</returns>
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
|
||||||
|
builder.Append(Major);
|
||||||
|
|
||||||
|
if (Minor >= 0)
|
||||||
|
{
|
||||||
|
builder.Append('.');
|
||||||
|
builder.Append(Minor);
|
||||||
|
|
||||||
|
if (Build >= 0)
|
||||||
|
{
|
||||||
|
builder.Append('.');
|
||||||
|
builder.Append(Build);
|
||||||
|
|
||||||
|
if (Revision > 0)
|
||||||
|
{
|
||||||
|
builder.Append('.');
|
||||||
|
builder.Append(Revision);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts to string.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fieldCount">Field count</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public string ToString(int fieldCount)
|
||||||
|
{
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
|
||||||
|
if (fieldCount > 0)
|
||||||
|
{
|
||||||
|
builder.Append(Major);
|
||||||
|
|
||||||
|
if (Minor >= 0 && fieldCount > 1)
|
||||||
|
{
|
||||||
|
builder.Append('.');
|
||||||
|
builder.Append(Minor);
|
||||||
|
|
||||||
|
if (Build >= 0 && fieldCount > 2)
|
||||||
|
{
|
||||||
|
builder.Append('.');
|
||||||
|
builder.Append(Build);
|
||||||
|
|
||||||
|
if (Revision > 0 && fieldCount > 3)
|
||||||
|
{
|
||||||
|
builder.Append('.');
|
||||||
|
builder.Append(Revision);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Parses a string
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value"></param>
|
||||||
|
private static void Parse(string value, out int major, out int minor, out int build, out int revision)
|
||||||
|
{
|
||||||
|
// Sanity check
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentNullException("version");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Split into fields
|
||||||
|
string[] fields = value.Split('.');
|
||||||
|
|
||||||
|
major = 0;
|
||||||
|
minor = -1;
|
||||||
|
build = -1;
|
||||||
|
revision = -1;
|
||||||
|
|
||||||
|
if (fields.Length > 4)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Invalid version string.");
|
||||||
|
}
|
||||||
|
if (fields.Length > 3)
|
||||||
|
{
|
||||||
|
revision = int.Parse(fields[3], CultureInfo.InvariantCulture);
|
||||||
|
}
|
||||||
|
if (fields.Length > 2)
|
||||||
|
{
|
||||||
|
build = int.Parse(fields[2], CultureInfo.InvariantCulture);
|
||||||
|
}
|
||||||
|
if (fields.Length > 1)
|
||||||
|
{
|
||||||
|
minor = int.Parse(fields[1], CultureInfo.InvariantCulture);
|
||||||
|
}
|
||||||
|
if (fields.Length > 0)
|
||||||
|
{
|
||||||
|
major = int.Parse(fields[0], CultureInfo.InvariantCulture);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Invalid version string.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -9,8 +9,9 @@
|
|||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>RainmeterStudio.Rainmeter</RootNamespace>
|
<RootNamespace>RainmeterStudio.Rainmeter</RootNamespace>
|
||||||
<AssemblyName>RainmeterStudio.Rainmeter</AssemblyName>
|
<AssemblyName>RainmeterStudio.Rainmeter</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<TargetFrameworkProfile />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
@ -21,6 +22,7 @@
|
|||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
@ -29,6 +31,7 @@
|
|||||||
<DefineConstants>TRACE</DefineConstants>
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
|
@ -9,8 +9,9 @@
|
|||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>RainmeterStudio.SkinDesignerPlugin</RootNamespace>
|
<RootNamespace>RainmeterStudio.SkinDesignerPlugin</RootNamespace>
|
||||||
<AssemblyName>RainmeterStudio.SkinDesignerPlugin</AssemblyName>
|
<AssemblyName>RainmeterStudio.SkinDesignerPlugin</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<TargetFrameworkProfile />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
@ -21,6 +22,7 @@
|
|||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
@ -29,6 +31,7 @@
|
|||||||
<DefineConstants>TRACE</DefineConstants>
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="PresentationCore" />
|
<Reference Include="PresentationCore" />
|
||||||
|
184
RainmeterStudio.Tests/Model/ReferenceTest.cs
Normal file
184
RainmeterStudio.Tests/Model/ReferenceTest.cs
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using RainmeterStudio.Core.Model;
|
||||||
|
|
||||||
|
namespace RainmeterStudio.Tests.Model
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Tests the reference class
|
||||||
|
/// </summary>
|
||||||
|
[TestClass]
|
||||||
|
public class ReferenceTest
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Tests the constructors of the reference class
|
||||||
|
/// </summary>
|
||||||
|
[TestMethod]
|
||||||
|
public void ReferenceConstructorTest()
|
||||||
|
{
|
||||||
|
Reference root = new Reference("root", "D:\\Data\\Project");
|
||||||
|
Reference file = new Reference("f ile__asdf.txt");
|
||||||
|
|
||||||
|
// Test root
|
||||||
|
Assert.AreEqual("root", root.Name);
|
||||||
|
Assert.IsNull(root.Parent);
|
||||||
|
Assert.AreEqual("root", root.QualifiedName);
|
||||||
|
Assert.AreEqual("D:\\Data\\Project", root.StoragePath);
|
||||||
|
Assert.IsTrue(Enumerable.Repeat("root", 1).SequenceEqual(root.QualifiedParts));
|
||||||
|
|
||||||
|
// Test file
|
||||||
|
Assert.AreEqual("f ile__asdf.txt", file.Name);
|
||||||
|
Assert.IsNull(file.Parent);
|
||||||
|
Assert.AreEqual("f ile__asdf.txt", file.QualifiedName);
|
||||||
|
Assert.IsNull(file.StoragePath);
|
||||||
|
Assert.IsTrue(Enumerable.Repeat("f ile__asdf.txt", 1).SequenceEqual(file.QualifiedParts));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests parenting in the reference class
|
||||||
|
/// </summary>
|
||||||
|
[TestMethod]
|
||||||
|
public void ReferenceParentingTest()
|
||||||
|
{
|
||||||
|
Reference root = new Reference(String.Empty, "D:\\Data\\Project");
|
||||||
|
Reference folder1 = new Reference("folder1");
|
||||||
|
Reference folder2 = new Reference("folder 2");
|
||||||
|
Reference file1 = new Reference("file1");
|
||||||
|
Reference file2 = new Reference("file2.txt");
|
||||||
|
Reference file3 = new Reference("file 3.png");
|
||||||
|
|
||||||
|
root.Add(folder1);
|
||||||
|
root.Add(file3);
|
||||||
|
folder1.Add(file1);
|
||||||
|
folder1.Add(folder2);
|
||||||
|
folder2.Add(file2);
|
||||||
|
|
||||||
|
Assert.IsNull(root.Parent);
|
||||||
|
Assert.AreEqual(2, root.ChildrenDictionary.Count);
|
||||||
|
Assert.AreEqual(root, folder1.Parent);
|
||||||
|
Assert.AreEqual(root, file3.Parent);
|
||||||
|
|
||||||
|
Assert.AreEqual(2, folder1.ChildrenDictionary.Count);
|
||||||
|
Assert.AreEqual(folder1, folder2.Parent);
|
||||||
|
Assert.AreEqual(folder1, file1.Parent);
|
||||||
|
|
||||||
|
Assert.IsNotNull(folder2.Children.FirstOrDefault(x => x == file2));
|
||||||
|
|
||||||
|
// Unparent something
|
||||||
|
file3.Unparent();
|
||||||
|
Assert.IsNull(file3.Parent);
|
||||||
|
Assert.IsNull(root.Children.FirstOrDefault(x => x == file3));
|
||||||
|
Assert.AreEqual(1, root.ChildrenDictionary.Count);
|
||||||
|
|
||||||
|
// Remove something
|
||||||
|
root.Remove(folder1);
|
||||||
|
Assert.IsNull(folder1.Parent);
|
||||||
|
Assert.AreEqual(0, root.ChildrenDictionary.Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests qualified names in the reference class
|
||||||
|
/// </summary>
|
||||||
|
[TestMethod]
|
||||||
|
public void ReferenceQualifiedNameTest()
|
||||||
|
{
|
||||||
|
Reference root = new Reference(String.Empty, "D:\\Data\\Project");
|
||||||
|
Reference folder1 = new Reference("folder1");
|
||||||
|
Reference folder2 = new Reference("folder 2");
|
||||||
|
Reference file1 = new Reference("file1");
|
||||||
|
Reference file2 = new Reference("file2.txt");
|
||||||
|
Reference file3 = new Reference("file 3.png");
|
||||||
|
|
||||||
|
root.Add(folder1);
|
||||||
|
root.Add(file3);
|
||||||
|
folder1.Add(file1);
|
||||||
|
folder1.Add(folder2);
|
||||||
|
folder2.Add(file2);
|
||||||
|
|
||||||
|
// Test qualified names
|
||||||
|
Assert.AreEqual(String.Empty, root.QualifiedName);
|
||||||
|
Assert.AreEqual("/folder1", folder1.QualifiedName);
|
||||||
|
Assert.AreEqual("/folder1/folder 2", folder2.QualifiedName);
|
||||||
|
Assert.AreEqual("/folder1/file1", file1.QualifiedName);
|
||||||
|
Assert.AreEqual("/folder1/folder 2/file2.txt", file2.QualifiedName);
|
||||||
|
Assert.AreEqual("/file 3.png", file3.QualifiedName);
|
||||||
|
|
||||||
|
// Test qualified parts
|
||||||
|
Assert.IsTrue(new[] { String.Empty }
|
||||||
|
.SequenceEqual(root.QualifiedParts));
|
||||||
|
|
||||||
|
Assert.IsTrue(new[] { String.Empty, "folder1" }
|
||||||
|
.SequenceEqual(folder1.QualifiedParts));
|
||||||
|
|
||||||
|
Assert.IsTrue(new[] { String.Empty, "folder1", "folder 2" }
|
||||||
|
.SequenceEqual(folder2.QualifiedParts));
|
||||||
|
|
||||||
|
Assert.IsTrue(new[] { String.Empty, "folder1", "file1" }
|
||||||
|
.SequenceEqual(file1.QualifiedParts));
|
||||||
|
|
||||||
|
Assert.IsTrue(new[] { String.Empty, "folder1", "folder 2", "file2.txt" }
|
||||||
|
.SequenceEqual(file2.QualifiedParts));
|
||||||
|
|
||||||
|
Assert.IsTrue(new[] { String.Empty, "file 3.png" }
|
||||||
|
.SequenceEqual(file3.QualifiedParts));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests the 'get reference' extension methods
|
||||||
|
/// </summary>
|
||||||
|
[TestMethod]
|
||||||
|
public void ReferenceGetReferenceTest()
|
||||||
|
{
|
||||||
|
Reference root = new Reference(String.Empty, "D:\\Data\\Project");
|
||||||
|
Reference folder1 = new Reference("folder1");
|
||||||
|
Reference folder2 = new Reference("folder 2");
|
||||||
|
Reference file1 = new Reference("file1");
|
||||||
|
Reference file2 = new Reference("file2.txt");
|
||||||
|
Reference file3 = new Reference("file 3.png");
|
||||||
|
|
||||||
|
root.Add(folder1);
|
||||||
|
root.Add(file3);
|
||||||
|
folder1.Add(file1);
|
||||||
|
folder1.Add(folder2);
|
||||||
|
folder2.Add(file2);
|
||||||
|
|
||||||
|
// Test 'get reference' method
|
||||||
|
Assert.AreEqual(root, root.GetReference(""));
|
||||||
|
Assert.AreEqual(folder2, root.GetReference("/folder1/folder 2"));
|
||||||
|
Assert.AreEqual(file3, file2.GetReference("/file 3.png"));
|
||||||
|
Assert.AreEqual(file2, file2.GetReference("/folder1/folder 2/file2.txt"));
|
||||||
|
Assert.AreEqual(file2, file3.GetReference("/folder1/folder 2/file2.txt"));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
file3.GetReference("/file 3.png/some nonexistant file");
|
||||||
|
Assert.Fail();
|
||||||
|
}
|
||||||
|
catch (ArgumentException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test 'try get reference' method
|
||||||
|
Reference res;
|
||||||
|
|
||||||
|
Assert.IsTrue(root.TryGetReference("", out res));
|
||||||
|
Assert.AreEqual(root, res);
|
||||||
|
|
||||||
|
Assert.IsTrue(root.TryGetReference("/folder1/folder 2", out res));
|
||||||
|
Assert.AreEqual(folder2, res);
|
||||||
|
|
||||||
|
Assert.IsTrue(file2.TryGetReference("/file 3.png", out res));
|
||||||
|
Assert.AreEqual(file3, res);
|
||||||
|
|
||||||
|
Assert.IsTrue(file2.TryGetReference("/folder1/folder 2/file2.txt", out res));
|
||||||
|
Assert.AreEqual(file2, res);
|
||||||
|
|
||||||
|
Assert.IsTrue(file3.TryGetReference("/folder1/folder 2/file2.txt", out res));
|
||||||
|
Assert.AreEqual(file2, res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,7 +8,7 @@
|
|||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>RainmeterStudio.Tests</RootNamespace>
|
<RootNamespace>RainmeterStudio.Tests</RootNamespace>
|
||||||
<AssemblyName>RainmeterStudio.Tests</AssemblyName>
|
<AssemblyName>RainmeterStudio.Tests</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
|
||||||
@ -16,6 +16,7 @@
|
|||||||
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
|
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
|
||||||
<IsCodedUITest>False</IsCodedUITest>
|
<IsCodedUITest>False</IsCodedUITest>
|
||||||
<TestProjectType>UnitTest</TestProjectType>
|
<TestProjectType>UnitTest</TestProjectType>
|
||||||
|
<TargetFrameworkProfile />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
@ -26,6 +27,7 @@
|
|||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
@ -34,6 +36,7 @@
|
|||||||
<DefineConstants>TRACE</DefineConstants>
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
@ -54,6 +57,7 @@
|
|||||||
</Otherwise>
|
</Otherwise>
|
||||||
</Choose>
|
</Choose>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Model\ReferenceTest.cs" />
|
||||||
<Compile Include="Storage\ProjectStorageTest.cs" />
|
<Compile Include="Storage\ProjectStorageTest.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -6,6 +6,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|||||||
using RainmeterStudio.Storage;
|
using RainmeterStudio.Storage;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using RainmeterStudio.Core.Model;
|
using RainmeterStudio.Core.Model;
|
||||||
|
using Version = RainmeterStudio.Core.Utils.Version;
|
||||||
|
|
||||||
namespace RainmeterStudio.Tests.Storage
|
namespace RainmeterStudio.Tests.Storage
|
||||||
{
|
{
|
||||||
@ -34,7 +35,7 @@ namespace RainmeterStudio.Tests.Storage
|
|||||||
Project project = CreateProject();
|
Project project = CreateProject();
|
||||||
|
|
||||||
// Save and load
|
// Save and load
|
||||||
ProjectStorage.Save(filename, project);
|
ProjectStorage.Save(project, filename);
|
||||||
Project res = ProjectStorage.Load(filename);
|
Project res = ProjectStorage.Load(filename);
|
||||||
|
|
||||||
// Verify results
|
// Verify results
|
||||||
@ -58,7 +59,7 @@ namespace RainmeterStudio.Tests.Storage
|
|||||||
Project project = new Project();
|
Project project = new Project();
|
||||||
|
|
||||||
// Save and load project
|
// Save and load project
|
||||||
ProjectStorage.Save(filename, project);
|
ProjectStorage.Save(project, filename);
|
||||||
Project res = ProjectStorage.Load(filename);
|
Project res = ProjectStorage.Load(filename);
|
||||||
|
|
||||||
// Test results
|
// Test results
|
||||||
@ -76,11 +77,11 @@ namespace RainmeterStudio.Tests.Storage
|
|||||||
private Project CreateProject()
|
private Project CreateProject()
|
||||||
{
|
{
|
||||||
// Create some file references
|
// Create some file references
|
||||||
Reference folder1 = new Reference("folder1");
|
Reference folder1 = new Reference("folder1", "folder1");
|
||||||
Reference folder2 = new Reference("folder2");
|
Reference folder2 = new Reference("folder2", "folder2");
|
||||||
Reference file1 = new Reference("file1.txt");
|
Reference file1 = new Reference("file1.txt", "folder1/file1.txt");
|
||||||
Reference file2 = new Reference("file2.ini");
|
Reference file2 = new Reference("file2.ini", "folder2/file2.ini");
|
||||||
Reference file3 = new Reference("file3.bmp");
|
Reference file3 = new Reference("file3.bmp", "file3.bmp");
|
||||||
|
|
||||||
// Create a project
|
// Create a project
|
||||||
Project project = new Project();
|
Project project = new Project();
|
||||||
@ -96,8 +97,8 @@ namespace RainmeterStudio.Tests.Storage
|
|||||||
// Set project references
|
// Set project references
|
||||||
project.Root.Add(folder1);
|
project.Root.Add(folder1);
|
||||||
project.Root.Add(folder2);
|
project.Root.Add(folder2);
|
||||||
project.Root[0].Add(file1);
|
folder1.Add(file1);
|
||||||
project.Root[1].Add(file2);
|
folder2.Add(file2);
|
||||||
project.Root.Add(file3);
|
project.Root.Add(file3);
|
||||||
|
|
||||||
return project;
|
return project;
|
||||||
|
@ -9,8 +9,9 @@
|
|||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>RainmeterStudio.TextEditorPlugin</RootNamespace>
|
<RootNamespace>RainmeterStudio.TextEditorPlugin</RootNamespace>
|
||||||
<AssemblyName>RainmeterStudio.TextEditorPlugin</AssemblyName>
|
<AssemblyName>RainmeterStudio.TextEditorPlugin</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<TargetFrameworkProfile />
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
@ -21,6 +22,7 @@
|
|||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
<PlatformTarget>x86</PlatformTarget>
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<DebugType>pdbonly</DebugType>
|
<DebugType>pdbonly</DebugType>
|
||||||
@ -29,6 +31,7 @@
|
|||||||
<DefineConstants>TRACE</DefineConstants>
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="PresentationCore" />
|
<Reference Include="PresentationCore" />
|
||||||
|
@ -100,7 +100,7 @@ namespace RainmeterStudio.Business
|
|||||||
throw new InvalidOperationException("Cannot save a project that is not opened.");
|
throw new InvalidOperationException("Cannot save a project that is not opened.");
|
||||||
|
|
||||||
// Save
|
// Save
|
||||||
Storage.Save(ActiveProject.Path, ActiveProject);
|
Storage.Save(ActiveProject);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
<RootNamespace>RainmeterStudio</RootNamespace>
|
<RootNamespace>RainmeterStudio</RootNamespace>
|
||||||
<AssemblyName>RainmeterStudio</AssemblyName>
|
<AssemblyName>RainmeterStudio</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||||
<FileAlignment>512</FileAlignment>
|
<FileAlignment>512</FileAlignment>
|
||||||
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
@ -24,6 +24,7 @@
|
|||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
@ -33,6 +34,7 @@
|
|||||||
<DefineConstants>TRACE</DefineConstants>
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
<ErrorReport>prompt</ErrorReport>
|
<ErrorReport>prompt</ErrorReport>
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<Prefer32Bit>false</Prefer32Bit>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
|
@ -9,37 +9,61 @@ using RainmeterStudio.Core.Storage;
|
|||||||
|
|
||||||
namespace RainmeterStudio.Storage
|
namespace RainmeterStudio.Storage
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Project storage, loads and saves project files
|
||||||
|
/// </summary>
|
||||||
public class ProjectStorage
|
public class ProjectStorage
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Loads a project from file
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">Path to file to load</param>
|
||||||
|
/// <returns>Loaded project</returns>
|
||||||
public Project Load(string path)
|
public Project Load(string path)
|
||||||
{
|
{
|
||||||
// Open file
|
// Open file
|
||||||
var file = File.OpenText(path);
|
var file = File.OpenText(path);
|
||||||
|
|
||||||
// Deserialize file
|
// Deserialize file
|
||||||
var serializer = new XmlSerializer(typeof(SerializableProject), new XmlRootAttribute("project"));
|
var serializer = new XmlSerializer(typeof(Project), new XmlRootAttribute("project"));
|
||||||
SerializableProject project = serializer.Deserialize(file) as SerializableProject;
|
Project project = serializer.Deserialize(file) as Project;
|
||||||
|
|
||||||
if (project != null)
|
if (project != null)
|
||||||
|
{
|
||||||
project.Path = path;
|
project.Path = path;
|
||||||
|
}
|
||||||
|
|
||||||
// Clean up
|
// Clean up
|
||||||
file.Close();
|
file.Close();
|
||||||
return project.Project;
|
return project;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Save(string path, Project project)
|
/// <summary>
|
||||||
|
/// Saves a project to file
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="project">Project to save</param>
|
||||||
|
/// <param name="path">File to save to</param>
|
||||||
|
public void Save(Project project, string path)
|
||||||
{
|
{
|
||||||
// Open file
|
// Open file
|
||||||
var file = File.OpenWrite(path);
|
var file = File.OpenWrite(path);
|
||||||
|
|
||||||
// Serialize file
|
// Serialize file
|
||||||
var sProject = new SerializableProject(project);
|
var serializer = new XmlSerializer(typeof(Project), new XmlRootAttribute("project"));
|
||||||
var serializer = new XmlSerializer(typeof(SerializableProject), new XmlRootAttribute("project"));
|
serializer.Serialize(file, project);
|
||||||
serializer.Serialize(file, sProject);
|
|
||||||
|
|
||||||
// Clean up
|
// Clean up
|
||||||
file.Close();
|
file.Close();
|
||||||
project.Path = path;
|
project.Path = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Saves a project
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="project">Saves a project to the path specified in the 'Path' property</param>
|
||||||
|
public void Save(Project project)
|
||||||
|
{
|
||||||
|
Save(project, project.Path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ namespace RainmeterStudio.UI.Controller
|
|||||||
// Set the reference
|
// Set the reference
|
||||||
var name = dialog.SelectedName;
|
var name = dialog.SelectedName;
|
||||||
|
|
||||||
string folder = OwnerWindow.ProjectPanel.ActiveItem.Data.StoragePath;
|
string folder = OwnerWindow.ProjectPanel.ActiveItem.StoragePath;
|
||||||
if (!Directory.Exists(folder))
|
if (!Directory.Exists(folder))
|
||||||
folder = Path.GetDirectoryName(folder);
|
folder = Path.GetDirectoryName(folder);
|
||||||
|
|
||||||
|
@ -32,12 +32,23 @@ namespace RainmeterStudio.UI.Controller
|
|||||||
// Resource name
|
// Resource name
|
||||||
string key = "ProjectItem";
|
string key = "ProjectItem";
|
||||||
|
|
||||||
if (Directory.Exists(item.StoragePath))
|
// Is a file?
|
||||||
|
if (File.Exists(item.StoragePath))
|
||||||
|
{
|
||||||
|
if (String.IsNullOrEmpty(Path.GetExtension(item.StoragePath)))
|
||||||
|
key += "Unknown";
|
||||||
|
|
||||||
|
else
|
||||||
|
key += "_" + Path.GetExtension(item.StoragePath).Substring(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not a file, try to figure out if a directory
|
||||||
|
else if (item.Count > 0 || Directory.Exists(item.StoragePath))
|
||||||
|
{
|
||||||
key += "Directory";
|
key += "Directory";
|
||||||
|
}
|
||||||
|
|
||||||
else if (File.Exists(item.StoragePath))
|
// None
|
||||||
key += "_" + Path.GetExtension(item.StoragePath).Substring(1);
|
|
||||||
|
|
||||||
else key += "None";
|
else key += "None";
|
||||||
|
|
||||||
// Get icon
|
// Get icon
|
||||||
|
@ -13,6 +13,7 @@ using System.Windows.Navigation;
|
|||||||
using System.Windows.Shapes;
|
using System.Windows.Shapes;
|
||||||
using RainmeterStudio.Business;
|
using RainmeterStudio.Business;
|
||||||
using RainmeterStudio.Core.Documents;
|
using RainmeterStudio.Core.Documents;
|
||||||
|
using RainmeterStudio.Core.Model;
|
||||||
using RainmeterStudio.Core.Model.Events;
|
using RainmeterStudio.Core.Model.Events;
|
||||||
using RainmeterStudio.Storage;
|
using RainmeterStudio.Storage;
|
||||||
using RainmeterStudio.UI.Controller;
|
using RainmeterStudio.UI.Controller;
|
||||||
@ -70,22 +71,24 @@ namespace RainmeterStudio.UI
|
|||||||
e.Document.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler((obj, args) =>
|
e.Document.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler((obj, args) =>
|
||||||
{
|
{
|
||||||
string documentName;
|
string documentName;
|
||||||
|
|
||||||
if (!e.Document.Reference.IsInProject())
|
// Get title
|
||||||
|
if (!ProjectController.ActiveProject.Contains(e.Document.Reference))
|
||||||
{
|
{
|
||||||
documentName = e.Document.Reference.StoragePath;
|
documentName = e.Document.Reference.StoragePath ?? "New document";
|
||||||
|
|
||||||
if (documentName == null)
|
|
||||||
documentName = "New document";
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
documentName = e.Document.Reference.Name;
|
documentName = e.Document.Reference.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Is document dirty? Append star
|
||||||
if (e.Document.IsDirty)
|
if (e.Document.IsDirty)
|
||||||
|
{
|
||||||
documentName += "*";
|
documentName += "*";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set document title
|
||||||
document.Title = documentName;
|
document.Title = documentName;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -46,8 +46,8 @@
|
|||||||
<TreeView Grid.Row="2" Name="treeProjectItems">
|
<TreeView Grid.Row="2" Name="treeProjectItems">
|
||||||
<TreeView.ItemContainerStyle>
|
<TreeView.ItemContainerStyle>
|
||||||
<Style TargetType="{x:Type TreeViewItem}">
|
<Style TargetType="{x:Type TreeViewItem}">
|
||||||
<Setter Property="IsExpanded" Value="{Binding Data.IsExpanded, Mode=TwoWay}" />
|
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
|
||||||
<Setter Property="IsSelected" Value="{Binding Data.IsSelected, Mode=TwoWay}" />
|
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
|
||||||
<EventSetter Event="Expanded" Handler="TreeViewItem_ExpandedOrCollapsed" />
|
<EventSetter Event="Expanded" Handler="TreeViewItem_ExpandedOrCollapsed" />
|
||||||
<EventSetter Event="Collapsed" Handler="TreeViewItem_ExpandedOrCollapsed" />
|
<EventSetter Event="Collapsed" Handler="TreeViewItem_ExpandedOrCollapsed" />
|
||||||
</Style>
|
</Style>
|
||||||
@ -55,8 +55,8 @@
|
|||||||
<TreeView.ItemTemplate>
|
<TreeView.ItemTemplate>
|
||||||
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
|
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
|
||||||
<DockPanel LastChildFill="True">
|
<DockPanel LastChildFill="True">
|
||||||
<Image DockPanel.Dock="Left" Width="16" Height="16" Source="{Binding Data.Reference.Data, Converter={StaticResource IconConverter}}" />
|
<Image DockPanel.Dock="Left" Width="16" Height="16" Source="{Binding Reference, Converter={StaticResource IconConverter}}" />
|
||||||
<TextBlock Text="{Binding Data.Name}" />
|
<TextBlock Text="{Binding Name}" />
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
</HierarchicalDataTemplate>
|
</HierarchicalDataTemplate>
|
||||||
</TreeView.ItemTemplate>
|
</TreeView.ItemTemplate>
|
||||||
|
@ -67,7 +67,7 @@ namespace RainmeterStudio.UI.Panels
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the selected tree view item
|
/// Gets the selected tree view item
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Tree<Reference> ActiveItem
|
public Reference ActiveItem
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@ -136,57 +136,36 @@ namespace RainmeterStudio.UI.Panels
|
|||||||
this.IsEnabled = true;
|
this.IsEnabled = true;
|
||||||
|
|
||||||
// Get tree
|
// Get tree
|
||||||
Tree<ReferenceViewModel> tree;
|
Reference refTree;
|
||||||
|
|
||||||
if (toggleShowAllFiles.IsChecked.HasValue && toggleShowAllFiles.IsChecked.Value)
|
if (toggleShowAllFiles.IsChecked.HasValue && toggleShowAllFiles.IsChecked.Value)
|
||||||
{
|
{
|
||||||
tree = GetAllFiles();
|
// Get directory name
|
||||||
|
string projectFolder = System.IO.Path.GetDirectoryName(Controller.ActiveProjectPath);
|
||||||
|
|
||||||
|
// Get folder tree
|
||||||
|
refTree = DirectoryHelper.GetFolderTree(projectFolder);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tree = GetProjectItems();
|
refTree = Controller.ActiveProject.Root;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add tree to tree view
|
// Add tree to tree view
|
||||||
treeProjectItems.Items.Clear();
|
treeProjectItems.Items.Clear();
|
||||||
treeProjectItems.Items.Add(tree);
|
treeProjectItems.Items.Add(new ReferenceViewModel(refTree));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Tree<ReferenceViewModel> GetAllFiles()
|
|
||||||
{
|
|
||||||
// Get directory name
|
|
||||||
string projectFolder = System.IO.Path.GetDirectoryName(Controller.ActiveProjectPath);
|
|
||||||
|
|
||||||
// Get folder tree
|
|
||||||
Tree<Reference> refTree = DirectoryHelper.GetFolderTree(projectFolder);
|
|
||||||
refTree.Data = Controller.ActiveProject.Root.Data;
|
|
||||||
|
|
||||||
// Remove the project file from the list
|
|
||||||
Tree<Reference> project = refTree.First(x => DirectoryHelper.PathsEqual(x.Data.StoragePath, Controller.ActiveProjectPath));
|
|
||||||
refTree.Remove(project);
|
|
||||||
|
|
||||||
// Transform to reference view model and return
|
|
||||||
return refTree.Transform<Reference, ReferenceViewModel>((node) => new Tree<ReferenceViewModel>(new ReferenceViewModel(node)));
|
|
||||||
}
|
|
||||||
|
|
||||||
private Tree<ReferenceViewModel> GetProjectItems()
|
|
||||||
{
|
|
||||||
// Get project items
|
|
||||||
Tree<Reference> refTree = Controller.ActiveProject.Root;
|
|
||||||
|
|
||||||
// Transform to reference view model and return
|
|
||||||
return refTree.Transform<Reference, ReferenceViewModel>((node) => new Tree<ReferenceViewModel>(new ReferenceViewModel(node)));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ExpandAll()
|
private void ExpandAll()
|
||||||
{
|
{
|
||||||
// Get tree
|
// Get tree
|
||||||
var tree = treeProjectItems.Items[0] as Tree<ReferenceViewModel>;
|
var tree = treeProjectItems.Items[0] as ReferenceViewModel;
|
||||||
if (tree == null)
|
if (tree == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Expand all
|
// Expand all
|
||||||
tree.Apply((node) => node.Data.IsExpanded = true);
|
tree.TreeExpand(true);
|
||||||
|
|
||||||
// Set can expand property
|
// Set can expand property
|
||||||
CanExpand = false;
|
CanExpand = false;
|
||||||
@ -195,12 +174,12 @@ namespace RainmeterStudio.UI.Panels
|
|||||||
private void CollapseAll()
|
private void CollapseAll()
|
||||||
{
|
{
|
||||||
// Get tree
|
// Get tree
|
||||||
var tree = treeProjectItems.Items[0] as Tree<ReferenceViewModel>;
|
var tree = treeProjectItems.Items[0] as ReferenceViewModel;
|
||||||
if (tree == null)
|
if (tree == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Expand all
|
// Expand all
|
||||||
tree.Apply((node) => node.Data.IsExpanded = false);
|
tree.TreeExpand(false);
|
||||||
|
|
||||||
// Set can expand property
|
// Set can expand property
|
||||||
CanExpand = true;
|
CanExpand = true;
|
||||||
@ -209,12 +188,12 @@ namespace RainmeterStudio.UI.Panels
|
|||||||
void TreeViewItem_ExpandedOrCollapsed(object sender, RoutedEventArgs e)
|
void TreeViewItem_ExpandedOrCollapsed(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
// Get tree
|
// Get tree
|
||||||
var tree = treeProjectItems.Items[0] as Tree<ReferenceViewModel>;
|
var tree = treeProjectItems.Items[0] as ReferenceViewModel;
|
||||||
if (tree == null)
|
if (tree == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// We can expand if the root is not expanded
|
// We can expand if the root is not expanded
|
||||||
CanExpand = (!tree.Data.IsExpanded);
|
CanExpand = (!tree.IsExpanded);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Specialized;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
@ -10,14 +11,16 @@ namespace RainmeterStudio.UI.ViewModel
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contains the view model of a reference
|
/// Contains the view model of a reference
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ReferenceViewModel : INotifyPropertyChanged
|
public class ReferenceViewModel : INotifyPropertyChanged, INotifyCollectionChanged
|
||||||
{
|
{
|
||||||
|
private List<ReferenceViewModel> _children = null;
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the linked reference
|
/// Gets the linked reference
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Tree<Reference> Reference { get; private set; }
|
public Reference Reference { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the name
|
/// Gets or sets the name
|
||||||
@ -26,7 +29,7 @@ namespace RainmeterStudio.UI.ViewModel
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Reference.Data.Name;
|
return Reference.Name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,10 +40,20 @@ namespace RainmeterStudio.UI.ViewModel
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Reference.Data.StoragePath;
|
return Reference.StoragePath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets an enumerable of this object's children
|
||||||
|
/// </summary>
|
||||||
|
public IEnumerable<ReferenceViewModel> Children
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _children;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private bool _isExpanded = true;
|
private bool _isExpanded = true;
|
||||||
|
|
||||||
@ -101,11 +114,70 @@ namespace RainmeterStudio.UI.ViewModel
|
|||||||
/// Creates a new instance of reference view model
|
/// Creates a new instance of reference view model
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="reference">Reference</param>
|
/// <param name="reference">Reference</param>
|
||||||
public ReferenceViewModel(Tree<Reference> reference)
|
public ReferenceViewModel(Reference reference)
|
||||||
{
|
{
|
||||||
Reference = reference;
|
Reference = reference;
|
||||||
|
Reference.CollectionChanged += Reference_CollectionChanged;
|
||||||
|
UpdateChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Reference_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||||
|
{
|
||||||
|
List<ReferenceViewModel> newItems = new List<ReferenceViewModel>();
|
||||||
|
List<ReferenceViewModel> oldItems = new List<ReferenceViewModel>();
|
||||||
|
|
||||||
|
// Update collection
|
||||||
|
switch (e.Action)
|
||||||
|
{
|
||||||
|
case NotifyCollectionChangedAction.Add:
|
||||||
|
newItems = e.NewItems.Cast<Reference>().Select(x => new ReferenceViewModel(x)).ToList();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NotifyCollectionChangedAction.Remove:
|
||||||
|
oldItems = _children.Where(x => e.OldItems.Contains(x.Reference)).ToList();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NotifyCollectionChangedAction.Replace:
|
||||||
|
newItems = e.NewItems.Cast<Reference>().Select(x => new ReferenceViewModel(x)).ToList();
|
||||||
|
oldItems = _children.Where(x => e.OldItems.Contains(x.Reference)).ToList();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
UpdateChildren();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_children.RemoveAll(oldItems.Contains);
|
||||||
|
_children.AddRange(newItems);
|
||||||
|
|
||||||
|
// Pass event
|
||||||
|
if (CollectionChanged != null)
|
||||||
|
CollectionChanged(this, new NotifyCollectionChangedEventArgs(e.Action, newItems, oldItems));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Operations
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the 'IsExpanded' property for the entire subtree
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">Value to set</param>
|
||||||
|
public void TreeExpand(bool value)
|
||||||
|
{
|
||||||
|
IsExpanded = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateChildren()
|
||||||
|
{
|
||||||
|
_children = Reference.Children.Select(x => new ReferenceViewModel(x)).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Triggered when the linked reference collection changes
|
||||||
|
/// </summary>
|
||||||
|
public event NotifyCollectionChangedEventHandler CollectionChanged;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,16 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<configuration>
|
<configuration>
|
||||||
<configSections>
|
<configSections>
|
||||||
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
|
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
<section name="RainmeterStudio.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
|
<section name="RainmeterStudio.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
|
||||||
</sectionGroup>
|
</sectionGroup>
|
||||||
</configSections>
|
</configSections>
|
||||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup><userSettings>
|
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup><userSettings>
|
||||||
<RainmeterStudio.Properties.Settings>
|
<RainmeterStudio.Properties.Settings>
|
||||||
<setting name="Command_ProjectCreateCommand_Shortcut" serializeAs="String">
|
<setting name="Command_ProjectCreateCommand_Shortcut" serializeAs="String">
|
||||||
<value>Ctrl+Shift+N</value>
|
<value>Ctrl+Shift+N</value>
|
||||||
</setting>
|
</setting>
|
||||||
<setting name="Command_ProjectPanel_RefreshCommand_Shortcut"
|
<setting name="Command_ProjectPanel_RefreshCommand_Shortcut" serializeAs="String">
|
||||||
serializeAs="String">
|
|
||||||
<value>F5</value>
|
<value>F5</value>
|
||||||
</setting>
|
</setting>
|
||||||
<setting name="Command_DocumentCreateCommand_Shortcut" serializeAs="String">
|
<setting name="Command_DocumentCreateCommand_Shortcut" serializeAs="String">
|
||||||
@ -39,10 +38,10 @@
|
|||||||
<value>10</value>
|
<value>10</value>
|
||||||
</setting>
|
</setting>
|
||||||
<setting name="CreateProjectDialog_RecentLocations" serializeAs="String">
|
<setting name="CreateProjectDialog_RecentLocations" serializeAs="String">
|
||||||
<value />
|
<value/>
|
||||||
</setting>
|
</setting>
|
||||||
<setting name="Project_SavedLocation" serializeAs="String">
|
<setting name="Project_SavedLocation" serializeAs="String">
|
||||||
<value />
|
<value/>
|
||||||
</setting>
|
</setting>
|
||||||
<setting name="CreateProjectDialog_CreateDirectoryCheckbox" serializeAs="String">
|
<setting name="CreateProjectDialog_CreateDirectoryCheckbox" serializeAs="String">
|
||||||
<value>True</value>
|
<value>True</value>
|
||||||
|
Loading…
Reference in New Issue
Block a user