mirror of
https://github.com/chibicitiberiu/rainmeter-studio.git
synced 2024-02-24 04:33:31 +00:00
Rewrote Reference class
This commit is contained in:
parent
a3fdc31caa
commit
520eed12a6
@ -109,40 +109,5 @@ namespace RainmeterStudio.Core.Model
|
|||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Xml.Serialization;
|
using System.Xml.Serialization;
|
||||||
@ -9,27 +10,89 @@ namespace RainmeterStudio.Core.Model
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reference to a file or folder
|
/// Reference to a file or folder
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Reference
|
[DebuggerDisplay("ProjectPath = {ProjectPath}, StoragePath = {StoragePath}")]
|
||||||
|
public struct Reference
|
||||||
{
|
{
|
||||||
|
private string[] _projectPath;
|
||||||
|
private string _storagePath;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the name of the reference
|
/// Gets the name of the reference
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Name { get; private set; }
|
public string Name
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
// Try to get the last item from the project path
|
||||||
|
if (_projectPath != null && _projectPath.Length > 0)
|
||||||
|
return _projectPath[_projectPath.Length - 1];
|
||||||
|
|
||||||
|
// None found, return null
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the path of the reference
|
/// Gets the path to the file on the disk. If reference is in a project, the path should be relative.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Path { get; private set; }
|
public string StoragePath
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _storagePath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the qualified path
|
||||||
|
/// </summary>
|
||||||
|
public string ProjectPath
|
||||||
|
{
|
||||||
|
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="path">Path to item referenced</param>
|
||||||
public Reference(string name, string path = null)
|
public Reference(string filePath, string projectPath = null)
|
||||||
{
|
{
|
||||||
Name = name;
|
_storagePath = filePath;
|
||||||
Path = path;
|
|
||||||
|
if (projectPath != null)
|
||||||
|
{
|
||||||
|
_projectPath = projectPath.Split('/').Skip(1).ToArray();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_projectPath = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the reference points to a project item
|
||||||
|
/// </summary>
|
||||||
|
public bool IsInProject()
|
||||||
|
{
|
||||||
|
return (_projectPath != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the reference has a file on disk
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public bool IsOnStorage()
|
||||||
|
{
|
||||||
|
return (_storagePath != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -39,14 +102,20 @@ namespace RainmeterStudio.Core.Model
|
|||||||
/// <returns>True if objects are equal</returns>
|
/// <returns>True if objects are equal</returns>
|
||||||
public override bool Equals(object obj)
|
public override bool Equals(object obj)
|
||||||
{
|
{
|
||||||
var other = obj as Reference;
|
if (obj is Reference)
|
||||||
|
{
|
||||||
// Types are different, so not equal
|
Reference other = (Reference)obj;
|
||||||
if (other == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Compare using string equals
|
// 2 references are equal if they point to the same project item
|
||||||
return String.Equals(Name, other.Name) && String.Equals(Path, other.Path);
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -55,10 +124,28 @@ namespace RainmeterStudio.Core.Model
|
|||||||
/// <returns>Hash code</returns>
|
/// <returns>Hash code</returns>
|
||||||
public override int GetHashCode()
|
public override int GetHashCode()
|
||||||
{
|
{
|
||||||
int hash = (Name == null) ? 0 : Name.GetHashCode();
|
int hash = (_projectPath == null) ? 0 : _projectPath.GetHashCode();
|
||||||
hash = hash * 7 + ((Path == null) ? 0 : Path.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;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the string representation of this reference
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return ProjectPath;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Xml.Serialization;
|
using System.Xml.Serialization;
|
||||||
using RainmeterStudio.Core.Model;
|
using RainmeterStudio.Core.Model;
|
||||||
|
using RainmeterStudio.Core.Utils;
|
||||||
|
|
||||||
namespace RainmeterStudio.Core.Storage
|
namespace RainmeterStudio.Core.Storage
|
||||||
{
|
{
|
||||||
@ -15,38 +17,38 @@ namespace RainmeterStudio.Core.Storage
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the name of the reference
|
/// Gets or sets the name of the reference
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[XmlElement("name")]
|
[XmlElement("storagePath")]
|
||||||
public string Name
|
public string StoragePath
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (Reference != null)
|
// Return only relative paths
|
||||||
return Reference.Name;
|
if (Path.IsPathRooted(Reference.StoragePath))
|
||||||
|
{
|
||||||
|
return PathHelper.GetRelativePath(Reference.StoragePath);
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return Reference.StoragePath;
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
Reference = new Reference(value, Path);
|
Reference = new Reference(value, ProjectPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the path of the reference
|
/// Gets or sets the path of the reference
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[XmlElement("path")]
|
[XmlElement("projectPath")]
|
||||||
public string Path
|
public string ProjectPath
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (Reference != null)
|
return Reference.ProjectPath;
|
||||||
return Reference.Path;
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
Reference = new Reference(Name, value);
|
Reference = new Reference(StoragePath, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,6 +69,10 @@ namespace RainmeterStudio.Core.Storage
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes this serializable reference
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="reference">Reference to use</param>
|
||||||
public SerializableReference(Reference reference)
|
public SerializableReference(Reference reference)
|
||||||
{
|
{
|
||||||
Reference = reference;
|
Reference = reference;
|
||||||
|
@ -39,5 +39,37 @@ namespace RainmeterStudio.Core.Utils
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts an absolute path to a path relative to current working directory
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">Absolute path</param>
|
||||||
|
/// <returns>Relative path</returns>
|
||||||
|
public static string GetRelativePath(string path)
|
||||||
|
{
|
||||||
|
return GetRelativePath(path, Environment.CurrentDirectory);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts an absolute path to a relative path
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">Absolute path to file</param>
|
||||||
|
/// <param name="relativeTo">Relative reference</param>
|
||||||
|
/// <returns>Relative path</returns>
|
||||||
|
public static string GetRelativePath(string path, string relativeTo)
|
||||||
|
{
|
||||||
|
Uri pathUri = new Uri(path);
|
||||||
|
|
||||||
|
// Folder must end in backslash
|
||||||
|
if (!relativeTo.EndsWith(Path.DirectorySeparatorChar.ToString()))
|
||||||
|
{
|
||||||
|
relativeTo += Path.DirectorySeparatorChar;
|
||||||
|
}
|
||||||
|
|
||||||
|
Uri folderUri = new Uri(relativeTo);
|
||||||
|
Uri relativePath = pathUri.MakeRelativeUri(folderUri);
|
||||||
|
|
||||||
|
return Uri.UnescapeDataString(relativeTo.ToString().Replace('/', Path.DirectorySeparatorChar));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,8 +39,6 @@ namespace RainmeterStudio.Tests.Storage
|
|||||||
|
|
||||||
// Verify results
|
// Verify results
|
||||||
Assert.IsNotNull(res);
|
Assert.IsNotNull(res);
|
||||||
Assert.AreEqual(project, res);
|
|
||||||
Assert.AreEqual(project.GetHashCode(), res.GetHashCode());
|
|
||||||
Assert.AreEqual(project.Author, res.Author);
|
Assert.AreEqual(project.Author, res.Author);
|
||||||
Assert.AreEqual(project.AutoLoadFile, res.AutoLoadFile);
|
Assert.AreEqual(project.AutoLoadFile, res.AutoLoadFile);
|
||||||
Assert.AreEqual(project.MinimumRainmeter, res.MinimumRainmeter);
|
Assert.AreEqual(project.MinimumRainmeter, res.MinimumRainmeter);
|
||||||
@ -65,8 +63,6 @@ namespace RainmeterStudio.Tests.Storage
|
|||||||
|
|
||||||
// Test results
|
// Test results
|
||||||
Assert.IsNotNull(res);
|
Assert.IsNotNull(res);
|
||||||
Assert.AreEqual(project, res);
|
|
||||||
Assert.AreEqual(project.GetHashCode(), res.GetHashCode());
|
|
||||||
Assert.AreEqual(project.Author, res.Author);
|
Assert.AreEqual(project.Author, res.Author);
|
||||||
Assert.AreEqual(project.AutoLoadFile, res.AutoLoadFile);
|
Assert.AreEqual(project.AutoLoadFile, res.AutoLoadFile);
|
||||||
Assert.AreEqual(project.MinimumRainmeter, res.MinimumRainmeter);
|
Assert.AreEqual(project.MinimumRainmeter, res.MinimumRainmeter);
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DesignHeight="300" d:DesignWidth="300">
|
d:DesignHeight="300" d:DesignWidth="300">
|
||||||
<Grid>
|
<Grid>
|
||||||
<TextBox Name="text" AcceptsReturn="True" />
|
<TextBox Name="text" AcceptsReturn="True"
|
||||||
|
TextChanged="text_TextChanged"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
@ -32,5 +32,10 @@ namespace RainmeterStudio.TextEditorPlugin
|
|||||||
|
|
||||||
text.Text = txt.ToString();
|
text.Text = txt.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void text_TextChanged(object sender, TextChangedEventArgs e)
|
||||||
|
{
|
||||||
|
_document.IsDirty = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,11 +152,11 @@ namespace RainmeterStudio.Business
|
|||||||
// Find a storage
|
// Find a storage
|
||||||
var storage = FindStorage(document);
|
var storage = FindStorage(document);
|
||||||
|
|
||||||
if (document.Reference == null)
|
if (document.Reference.StoragePath == null)
|
||||||
throw new ArgumentException("Reference cannot be empty");
|
throw new ArgumentException("Reference cannot be empty");
|
||||||
|
|
||||||
// Save
|
// Save
|
||||||
storage.Write(document.Reference.Path, document);
|
storage.Write(document.Reference.StoragePath, document);
|
||||||
|
|
||||||
// Clear dirty flag
|
// Clear dirty flag
|
||||||
document.IsDirty = false;
|
document.IsDirty = false;
|
||||||
|
@ -90,6 +90,9 @@
|
|||||||
<Compile Include="UI\Controller\IconProvider.cs" />
|
<Compile Include="UI\Controller\IconProvider.cs" />
|
||||||
<Compile Include="UI\Controller\ProjectController.cs" />
|
<Compile Include="UI\Controller\ProjectController.cs" />
|
||||||
<Compile Include="Business\SettingsProvider.cs" />
|
<Compile Include="Business\SettingsProvider.cs" />
|
||||||
|
<Compile Include="UI\Dialogs\CloseUnsavedDialog.xaml.cs">
|
||||||
|
<DependentUpon>CloseUnsavedDialog.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="UI\Dialogs\CreateDocumentDialog.xaml.cs">
|
<Compile Include="UI\Dialogs\CreateDocumentDialog.xaml.cs">
|
||||||
<DependentUpon>CreateDocumentDialog.xaml</DependentUpon>
|
<DependentUpon>CreateDocumentDialog.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
@ -104,6 +107,10 @@
|
|||||||
<Compile Include="UI\ViewModel\DocumentTemplateViewModel.cs" />
|
<Compile Include="UI\ViewModel\DocumentTemplateViewModel.cs" />
|
||||||
<Compile Include="UI\ViewModel\ProjectTemplateViewModel.cs" />
|
<Compile Include="UI\ViewModel\ProjectTemplateViewModel.cs" />
|
||||||
<Compile Include="UI\ViewModel\ReferenceViewModel.cs" />
|
<Compile Include="UI\ViewModel\ReferenceViewModel.cs" />
|
||||||
|
<Page Include="UI\Dialogs\CloseUnsavedDialog.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
<Page Include="UI\Dialogs\CreateDocumentDialog.xaml">
|
<Page Include="UI\Dialogs\CreateDocumentDialog.xaml">
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
45
RainmeterStudio/Resources/Strings.Designer.cs
generated
45
RainmeterStudio/Resources/Strings.Designer.cs
generated
@ -60,6 +60,33 @@ namespace RainmeterStudio.Resources {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to The following files have unsaved changes:.
|
||||||
|
/// </summary>
|
||||||
|
public static string CloseUnsavedDialog_Message {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("CloseUnsavedDialog_Message", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Do you want to save these changes?.
|
||||||
|
/// </summary>
|
||||||
|
public static string CloseUnsavedDialog_Question {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("CloseUnsavedDialog_Question", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Unsaved changes.
|
||||||
|
/// </summary>
|
||||||
|
public static string CloseUnsavedDialog_Title {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("CloseUnsavedDialog_Title", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to _Close.
|
/// Looks up a localized string similar to _Close.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -339,6 +366,15 @@ namespace RainmeterStudio.Resources {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Do_n't save.
|
||||||
|
/// </summary>
|
||||||
|
public static string Dialog_DoNotSave {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Dialog_DoNotSave", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to All files.
|
/// Looks up a localized string similar to All files.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -375,6 +411,15 @@ namespace RainmeterStudio.Resources {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to _Save.
|
||||||
|
/// </summary>
|
||||||
|
public static string Dialog_Save {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("Dialog_Save", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to _File.
|
/// Looks up a localized string similar to _File.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -240,4 +240,19 @@
|
|||||||
<data name="CreateProjectDialog_Browse_Title" xml:space="preserve">
|
<data name="CreateProjectDialog_Browse_Title" xml:space="preserve">
|
||||||
<value>Select project path</value>
|
<value>Select project path</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="CloseUnsavedDialog_Message" xml:space="preserve">
|
||||||
|
<value>The following files have unsaved changes:</value>
|
||||||
|
</data>
|
||||||
|
<data name="CloseUnsavedDialog_Question" xml:space="preserve">
|
||||||
|
<value>Do you want to save these changes?</value>
|
||||||
|
</data>
|
||||||
|
<data name="CloseUnsavedDialog_Title" xml:space="preserve">
|
||||||
|
<value>Unsaved changes</value>
|
||||||
|
</data>
|
||||||
|
<data name="Dialog_DoNotSave" xml:space="preserve">
|
||||||
|
<value>Do_n't save</value>
|
||||||
|
</data>
|
||||||
|
<data name="Dialog_Save" xml:space="preserve">
|
||||||
|
<value>_Save</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
@ -34,6 +34,8 @@ namespace RainmeterStudio.UI.Controller
|
|||||||
|
|
||||||
public Command DocumentOpenCommand { get; private set; }
|
public Command DocumentOpenCommand { get; private set; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -65,6 +67,11 @@ namespace RainmeterStudio.UI.Controller
|
|||||||
ProjectManager.ActiveProjectChanged += new EventHandler((obj, e) => DocumentCreateCommand.NotifyCanExecuteChanged());
|
ProjectManager.ActiveProjectChanged += new EventHandler((obj, e) => DocumentCreateCommand.NotifyCanExecuteChanged());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Document operations
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Shows the new item dialog, and creates a new document
|
||||||
|
/// </summary>
|
||||||
public void Create()
|
public void Create()
|
||||||
{
|
{
|
||||||
// Show dialog
|
// Show dialog
|
||||||
@ -83,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.Path;
|
string folder = OwnerWindow.ProjectPanel.ActiveItem.Data.StoragePath;
|
||||||
if (!Directory.Exists(folder))
|
if (!Directory.Exists(folder))
|
||||||
folder = Path.GetDirectoryName(folder);
|
folder = Path.GetDirectoryName(folder);
|
||||||
|
|
||||||
@ -97,12 +104,59 @@ namespace RainmeterStudio.UI.Controller
|
|||||||
OwnerWindow.ProjectPanel.ActiveItem.Add(reference);
|
OwnerWindow.ProjectPanel.ActiveItem.Add(reference);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Create(IDocumentTemplate format)
|
/// <summary>
|
||||||
|
/// Saves the document opened in specified editor
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="editor">Editor</param>
|
||||||
|
public void Save(IDocumentEditor editor)
|
||||||
{
|
{
|
||||||
// Call manager
|
if (!editor.AttachedDocument.Reference.IsOnStorage())
|
||||||
DocumentManager.Create(format);
|
{
|
||||||
|
SaveAs(editor);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SaveAs(IDocumentEditor editor)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Closes an active document.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="editor">The document editor attached</param>
|
||||||
|
/// <returns>True if closed successfully</returns>
|
||||||
|
/// <remarks>Shows the 'are you sure' prompt if there are unsaved edits.</remarks>
|
||||||
|
public bool Close(IDocumentEditor editor)
|
||||||
|
{
|
||||||
|
// Show the 'are you sure' prompt if necesary
|
||||||
|
if (editor.AttachedDocument.IsDirty)
|
||||||
|
{
|
||||||
|
bool? res = CloseUnsavedDialog.ShowDialog(OwnerWindow, editor.AttachedDocument);
|
||||||
|
if (res.HasValue)
|
||||||
|
{
|
||||||
|
// Save
|
||||||
|
if (res.Value)
|
||||||
|
{
|
||||||
|
Save(editor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close
|
||||||
|
DocumentManager.Close(editor);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a list of document templates view models
|
/// Gets a list of document templates view models
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -32,11 +32,11 @@ namespace RainmeterStudio.UI.Controller
|
|||||||
// Resource name
|
// Resource name
|
||||||
string key = "ProjectItem";
|
string key = "ProjectItem";
|
||||||
|
|
||||||
if (Directory.Exists(item.Path))
|
if (Directory.Exists(item.StoragePath))
|
||||||
key += "Directory";
|
key += "Directory";
|
||||||
|
|
||||||
else if (File.Exists(item.Path))
|
else if (File.Exists(item.StoragePath))
|
||||||
key += "_" + Path.GetExtension(item.Path).Substring(1);
|
key += "_" + Path.GetExtension(item.StoragePath).Substring(1);
|
||||||
|
|
||||||
else key += "None";
|
else key += "None";
|
||||||
|
|
||||||
@ -55,10 +55,9 @@ namespace RainmeterStudio.UI.Controller
|
|||||||
{
|
{
|
||||||
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
|
||||||
{
|
{
|
||||||
var reference = value as Reference;
|
if (value is Reference)
|
||||||
if (reference != null)
|
|
||||||
{
|
{
|
||||||
return IconProvider.GetProjectItemIcon(reference);
|
return IconProvider.GetProjectItemIcon((Reference)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
41
RainmeterStudio/UI/Dialogs/CloseUnsavedDialog.xaml
Normal file
41
RainmeterStudio/UI/Dialogs/CloseUnsavedDialog.xaml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<Window x:Class="RainmeterStudio.UI.Dialogs.CloseUnsavedDialog"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:r="clr-namespace:RainmeterStudio.Resources"
|
||||||
|
Title="{x:Static r:Strings.CloseUnsavedDialog_Title}" Height="200" Width="320"
|
||||||
|
WindowStartupLocation="CenterOwner"
|
||||||
|
WindowStyle="ToolWindow" ShowInTaskbar="False"
|
||||||
|
Background="WhiteSmoke" >
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<TextBlock Grid.Row="0" Text="{x:Static r:Strings.CloseUnsavedDialog_Message }"
|
||||||
|
Margin="4"/>
|
||||||
|
|
||||||
|
<ScrollViewer Grid.Row="1"
|
||||||
|
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
||||||
|
ScrollViewer.VerticalScrollBarVisibility="Auto">
|
||||||
|
|
||||||
|
<TextBlock Name="textFiles"
|
||||||
|
Margin="4" Padding="4"
|
||||||
|
Background="White"/>
|
||||||
|
|
||||||
|
</ScrollViewer>
|
||||||
|
|
||||||
|
<TextBlock Grid.Row="2" Text="{x:Static r:Strings.CloseUnsavedDialog_Question }"
|
||||||
|
Margin="4"/>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="3" Orientation="Horizontal"
|
||||||
|
HorizontalAlignment="Right">
|
||||||
|
<Button Name="buttonSave" Content="{x:Static r:Strings.Dialog_Save}" IsDefault="True" Margin="1px" Click="buttonSave_Click" />
|
||||||
|
<Button Name="buttonDoNotSave" Content="{x:Static r:Strings.Dialog_DoNotSave}" Margin="1px" Click="buttonDoNotSave_Click" />
|
||||||
|
<Button Name="buttonCancel" Content="{x:Static r:Strings.Dialog_Cancel}" IsCancel="True" Margin="1px" Click="buttonCancel_Click" />
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
</Grid>
|
||||||
|
</Window>
|
103
RainmeterStudio/UI/Dialogs/CloseUnsavedDialog.xaml.cs
Normal file
103
RainmeterStudio/UI/Dialogs/CloseUnsavedDialog.xaml.cs
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
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.Shapes;
|
||||||
|
using RainmeterStudio.Core.Model;
|
||||||
|
|
||||||
|
namespace RainmeterStudio.UI.Dialogs
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for CloseUnsavedDialog.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class CloseUnsavedDialog : Window
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Displays the dialog and returns the result
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="unsavedDocuments">List of unsaved documents</param>
|
||||||
|
/// <returns>Dialog result</returns>
|
||||||
|
public static bool? ShowDialog(IEnumerable<IDocument> unsavedDocuments)
|
||||||
|
{
|
||||||
|
var dialog = new CloseUnsavedDialog(unsavedDocuments);
|
||||||
|
return dialog.ShowDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Displays the dialog and returns the result
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="owner">Owner window</param>
|
||||||
|
/// <param name="unsavedDocuments">List of unsaved documents</param>
|
||||||
|
/// <returns>Dialog result</returns>
|
||||||
|
public static bool? ShowDialog(Window owner, IEnumerable<IDocument> unsavedDocuments)
|
||||||
|
{
|
||||||
|
var dialog = new CloseUnsavedDialog(unsavedDocuments);
|
||||||
|
dialog.Owner = owner;
|
||||||
|
return dialog.ShowDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Displays the dialog and returns the result
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="owner">Owner window</param>
|
||||||
|
/// <param name="unsavedDocuments">List of unsaved documents</param>
|
||||||
|
/// <returns>Dialog result</returns>
|
||||||
|
public static bool? ShowDialog(Window owner, params IDocument[] unsavedDocuments)
|
||||||
|
{
|
||||||
|
var dialog = new CloseUnsavedDialog(unsavedDocuments);
|
||||||
|
dialog.Owner = owner;
|
||||||
|
return dialog.ShowDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes the dialog
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="unsavedDocuments">List of unsaved documents</param>
|
||||||
|
public CloseUnsavedDialog(IEnumerable<IDocument> unsavedDocuments)
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
textFiles.Inlines.AddRange(unsavedDocuments.SelectMany(GetInlines));
|
||||||
|
}
|
||||||
|
|
||||||
|
private IEnumerable<Inline> GetInlines(IDocument doc)
|
||||||
|
{
|
||||||
|
var folder = System.IO.Path.GetDirectoryName(doc.Reference.StoragePath);
|
||||||
|
|
||||||
|
yield return new Run(folder)
|
||||||
|
{
|
||||||
|
Foreground = Brushes.DarkGray
|
||||||
|
};
|
||||||
|
|
||||||
|
yield return new Run(doc.Reference.Name)
|
||||||
|
{
|
||||||
|
FontWeight = FontWeights.Bold
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buttonSave_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
DialogResult = true;
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buttonDoNotSave_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
DialogResult = false;
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buttonCancel_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
DialogResult = null;
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -12,6 +12,7 @@ using System.Windows.Media.Imaging;
|
|||||||
using System.Windows.Navigation;
|
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.Model.Events;
|
using RainmeterStudio.Core.Model.Events;
|
||||||
using RainmeterStudio.Storage;
|
using RainmeterStudio.Storage;
|
||||||
using RainmeterStudio.UI.Controller;
|
using RainmeterStudio.UI.Controller;
|
||||||
@ -30,6 +31,8 @@ namespace RainmeterStudio.UI
|
|||||||
|
|
||||||
public ProjectPanel ProjectPanel { get { return projectPanel; } }
|
public ProjectPanel ProjectPanel { get { return projectPanel; } }
|
||||||
|
|
||||||
|
private Dictionary<LayoutDocument, IDocumentEditor> _openedDocuments = new Dictionary<LayoutDocument, IDocumentEditor>();
|
||||||
|
|
||||||
public MainWindow(ProjectController projCtrl, DocumentController docCtrl)
|
public MainWindow(ProjectController projCtrl, DocumentController docCtrl)
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
@ -52,18 +55,52 @@ namespace RainmeterStudio.UI
|
|||||||
|
|
||||||
void documentController_DocumentOpened(object sender, DocumentOpenedEventArgs e)
|
void documentController_DocumentOpened(object sender, DocumentOpenedEventArgs e)
|
||||||
{
|
{
|
||||||
// Spawn a new window
|
// Create a new panel
|
||||||
LayoutDocument document = new LayoutDocument();
|
LayoutDocument document = new LayoutDocument();
|
||||||
|
_openedDocuments.Add(document, e.Editor);
|
||||||
|
|
||||||
document.Content = e.Editor.EditorUI;
|
document.Content = e.Editor.EditorUI;
|
||||||
document.Title = (e.Editor.AttachedDocument.Reference == null) ? "New document" : e.Editor.AttachedDocument.Reference.Name;
|
|
||||||
document.Closing += document_Closing;
|
document.Closing += document_Closing;
|
||||||
|
document.Closed += document_Closed;
|
||||||
|
|
||||||
documentPane.Children.Add(document);
|
documentPane.Children.Add(document);
|
||||||
documentPane.SelectedContentIndex = documentPane.IndexOf(document);
|
documentPane.SelectedContentIndex = documentPane.IndexOf(document);
|
||||||
|
|
||||||
|
|
||||||
|
e.Document.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler((obj, args) =>
|
||||||
|
{
|
||||||
|
string documentName;
|
||||||
|
|
||||||
|
if (!e.Document.Reference.IsInProject())
|
||||||
|
{
|
||||||
|
documentName = e.Document.Reference.StoragePath;
|
||||||
|
|
||||||
|
if (documentName == null)
|
||||||
|
documentName = "New document";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
documentName = e.Document.Reference.Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.Document.IsDirty)
|
||||||
|
documentName += "*";
|
||||||
|
|
||||||
|
document.Title = documentName;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void document_Closed(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
var layoutDocument = (LayoutDocument)sender;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void document_Closing(object sender, System.ComponentModel.CancelEventArgs e)
|
void document_Closing(object sender, System.ComponentModel.CancelEventArgs e)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
switch (MessageBox.Show("Are you sure?", "", MessageBoxButton.YesNoCancel, MessageBoxImage.Question))
|
switch (MessageBox.Show("Are you sure?", "", MessageBoxButton.YesNoCancel, MessageBoxImage.Question))
|
||||||
{
|
{
|
||||||
case MessageBoxResult.Yes:
|
case MessageBoxResult.Yes:
|
||||||
|
@ -162,7 +162,7 @@ namespace RainmeterStudio.UI.Panels
|
|||||||
refTree.Data = Controller.ActiveProject.Root.Data;
|
refTree.Data = Controller.ActiveProject.Root.Data;
|
||||||
|
|
||||||
// Remove the project file from the list
|
// Remove the project file from the list
|
||||||
Tree<Reference> project = refTree.First(x => DirectoryHelper.PathsEqual(x.Data.Path, Controller.ActiveProjectPath));
|
Tree<Reference> project = refTree.First(x => DirectoryHelper.PathsEqual(x.Data.StoragePath, Controller.ActiveProjectPath));
|
||||||
refTree.Remove(project);
|
refTree.Remove(project);
|
||||||
|
|
||||||
// Transform to reference view model and return
|
// Transform to reference view model and return
|
||||||
|
@ -37,7 +37,7 @@ namespace RainmeterStudio.UI.ViewModel
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Reference.Data.Path;
|
return Reference.Data.StoragePath;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user