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:
		@@ -109,40 +109,5 @@ namespace RainmeterStudio.Core.Model
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        #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.Collections.Generic;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Xml.Serialization;
 | 
			
		||||
@@ -9,27 +10,89 @@ namespace RainmeterStudio.Core.Model
 | 
			
		||||
    /// <summary>
 | 
			
		||||
    /// Reference to a file or folder
 | 
			
		||||
    /// </summary>
 | 
			
		||||
    public class Reference
 | 
			
		||||
    [DebuggerDisplay("ProjectPath = {ProjectPath}, StoragePath = {StoragePath}")]
 | 
			
		||||
    public struct Reference
 | 
			
		||||
    {
 | 
			
		||||
        private string[] _projectPath;
 | 
			
		||||
        private string _storagePath;
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets the name of the reference
 | 
			
		||||
        /// </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>
 | 
			
		||||
        /// 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>
 | 
			
		||||
        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>
 | 
			
		||||
        /// Initializes the reference
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <param name="name">Name of reference</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;
 | 
			
		||||
            Path = path;
 | 
			
		||||
            _storagePath = filePath;
 | 
			
		||||
 | 
			
		||||
            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>
 | 
			
		||||
@@ -39,14 +102,20 @@ namespace RainmeterStudio.Core.Model
 | 
			
		||||
        /// <returns>True if objects are equal</returns>
 | 
			
		||||
        public override bool Equals(object obj)
 | 
			
		||||
        {
 | 
			
		||||
            var other = obj as Reference;
 | 
			
		||||
            
 | 
			
		||||
            // Types are different, so not equal
 | 
			
		||||
            if (other == null)
 | 
			
		||||
                return false;
 | 
			
		||||
            if (obj is Reference)
 | 
			
		||||
            {
 | 
			
		||||
                Reference other = (Reference)obj;
 | 
			
		||||
 | 
			
		||||
            // Compare using string equals
 | 
			
		||||
            return String.Equals(Name, other.Name) && String.Equals(Path, other.Path);
 | 
			
		||||
                // 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;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
@@ -55,10 +124,28 @@ namespace RainmeterStudio.Core.Model
 | 
			
		||||
        /// <returns>Hash code</returns>
 | 
			
		||||
        public override int GetHashCode()
 | 
			
		||||
        {
 | 
			
		||||
            int hash = (Name == null) ? 0 : Name.GetHashCode();
 | 
			
		||||
            hash = hash * 7 + ((Path == null) ? 0 : Path.GetHashCode());
 | 
			
		||||
            int hash = (_projectPath == null) ? 0 : _projectPath.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>
 | 
			
		||||
        /// Gets the string representation of this reference
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public override string ToString()
 | 
			
		||||
        {
 | 
			
		||||
            return ProjectPath;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,11 @@
 | 
			
		||||
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
 | 
			
		||||
{
 | 
			
		||||
@@ -15,38 +17,38 @@ namespace RainmeterStudio.Core.Storage
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the name of the reference
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        [XmlElement("name")]
 | 
			
		||||
        public string Name
 | 
			
		||||
        [XmlElement("storagePath")]
 | 
			
		||||
        public string StoragePath
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                if (Reference != null)
 | 
			
		||||
                    return Reference.Name;
 | 
			
		||||
                // Return only relative paths
 | 
			
		||||
                if (Path.IsPathRooted(Reference.StoragePath))
 | 
			
		||||
                {
 | 
			
		||||
                    return PathHelper.GetRelativePath(Reference.StoragePath);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                return null;
 | 
			
		||||
                return Reference.StoragePath;
 | 
			
		||||
            }
 | 
			
		||||
            set
 | 
			
		||||
            {
 | 
			
		||||
                Reference = new Reference(value, Path);
 | 
			
		||||
                Reference = new Reference(value, ProjectPath);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Gets or sets the path of the reference
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        [XmlElement("path")]
 | 
			
		||||
        public string Path
 | 
			
		||||
        [XmlElement("projectPath")]
 | 
			
		||||
        public string ProjectPath
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                if (Reference != null)
 | 
			
		||||
                    return Reference.Path;
 | 
			
		||||
 | 
			
		||||
                return null;
 | 
			
		||||
                return Reference.ProjectPath;
 | 
			
		||||
            }
 | 
			
		||||
            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)
 | 
			
		||||
        {
 | 
			
		||||
            Reference = reference;
 | 
			
		||||
 
 | 
			
		||||
@@ -39,5 +39,37 @@ namespace RainmeterStudio.Core.Utils
 | 
			
		||||
 | 
			
		||||
            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
 | 
			
		||||
            Assert.IsNotNull(res);
 | 
			
		||||
            Assert.AreEqual(project, res);
 | 
			
		||||
            Assert.AreEqual(project.GetHashCode(), res.GetHashCode());
 | 
			
		||||
            Assert.AreEqual(project.Author, res.Author);
 | 
			
		||||
            Assert.AreEqual(project.AutoLoadFile, res.AutoLoadFile);
 | 
			
		||||
            Assert.AreEqual(project.MinimumRainmeter, res.MinimumRainmeter);
 | 
			
		||||
@@ -65,8 +63,6 @@ namespace RainmeterStudio.Tests.Storage
 | 
			
		||||
 | 
			
		||||
            // Test results
 | 
			
		||||
            Assert.IsNotNull(res);
 | 
			
		||||
            Assert.AreEqual(project, res);
 | 
			
		||||
            Assert.AreEqual(project.GetHashCode(), res.GetHashCode());
 | 
			
		||||
            Assert.AreEqual(project.Author, res.Author);
 | 
			
		||||
            Assert.AreEqual(project.AutoLoadFile, res.AutoLoadFile);
 | 
			
		||||
            Assert.AreEqual(project.MinimumRainmeter, res.MinimumRainmeter);
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,7 @@
 | 
			
		||||
             mc:Ignorable="d" 
 | 
			
		||||
             d:DesignHeight="300" d:DesignWidth="300">
 | 
			
		||||
    <Grid>
 | 
			
		||||
        <TextBox Name="text" AcceptsReturn="True" />
 | 
			
		||||
        <TextBox Name="text" AcceptsReturn="True"
 | 
			
		||||
                 TextChanged="text_TextChanged"/>
 | 
			
		||||
    </Grid>
 | 
			
		||||
</UserControl>
 | 
			
		||||
 
 | 
			
		||||
@@ -32,5 +32,10 @@ namespace RainmeterStudio.TextEditorPlugin
 | 
			
		||||
            
 | 
			
		||||
            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
 | 
			
		||||
            var storage = FindStorage(document);
 | 
			
		||||
 | 
			
		||||
            if (document.Reference == null)
 | 
			
		||||
            if (document.Reference.StoragePath == null)
 | 
			
		||||
                throw new ArgumentException("Reference cannot be empty");
 | 
			
		||||
 | 
			
		||||
            // Save
 | 
			
		||||
            storage.Write(document.Reference.Path, document);
 | 
			
		||||
            storage.Write(document.Reference.StoragePath, document);
 | 
			
		||||
 | 
			
		||||
            // Clear dirty flag
 | 
			
		||||
            document.IsDirty = false;
 | 
			
		||||
 
 | 
			
		||||
@@ -90,6 +90,9 @@
 | 
			
		||||
    <Compile Include="UI\Controller\IconProvider.cs" />
 | 
			
		||||
    <Compile Include="UI\Controller\ProjectController.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">
 | 
			
		||||
      <DependentUpon>CreateDocumentDialog.xaml</DependentUpon>
 | 
			
		||||
    </Compile>
 | 
			
		||||
@@ -104,6 +107,10 @@
 | 
			
		||||
    <Compile Include="UI\ViewModel\DocumentTemplateViewModel.cs" />
 | 
			
		||||
    <Compile Include="UI\ViewModel\ProjectTemplateViewModel.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">
 | 
			
		||||
      <SubType>Designer</SubType>
 | 
			
		||||
      <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>
 | 
			
		||||
        ///   Looks up a localized string similar to _Close.
 | 
			
		||||
        /// </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>
 | 
			
		||||
        ///   Looks up a localized string similar to All files.
 | 
			
		||||
        /// </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>
 | 
			
		||||
        ///   Looks up a localized string similar to _File.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
 
 | 
			
		||||
@@ -240,4 +240,19 @@
 | 
			
		||||
  <data name="CreateProjectDialog_Browse_Title" xml:space="preserve">
 | 
			
		||||
    <value>Select project path</value>
 | 
			
		||||
  </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>
 | 
			
		||||
@@ -34,6 +34,8 @@ namespace RainmeterStudio.UI.Controller
 | 
			
		||||
 | 
			
		||||
        public Command DocumentOpenCommand { get; private set; }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        #endregion
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
@@ -65,6 +67,11 @@ namespace RainmeterStudio.UI.Controller
 | 
			
		||||
            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()
 | 
			
		||||
        {
 | 
			
		||||
            // Show dialog
 | 
			
		||||
@@ -83,7 +90,7 @@ namespace RainmeterStudio.UI.Controller
 | 
			
		||||
            // Set the reference
 | 
			
		||||
            var name = dialog.SelectedName;
 | 
			
		||||
 | 
			
		||||
            string folder = OwnerWindow.ProjectPanel.ActiveItem.Data.Path;
 | 
			
		||||
            string folder = OwnerWindow.ProjectPanel.ActiveItem.Data.StoragePath;
 | 
			
		||||
            if (!Directory.Exists(folder))
 | 
			
		||||
                folder = Path.GetDirectoryName(folder);
 | 
			
		||||
 | 
			
		||||
@@ -97,12 +104,59 @@ namespace RainmeterStudio.UI.Controller
 | 
			
		||||
            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
 | 
			
		||||
            DocumentManager.Create(format);
 | 
			
		||||
            if (!editor.AttachedDocument.Reference.IsOnStorage())
 | 
			
		||||
            {
 | 
			
		||||
                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>
 | 
			
		||||
        /// Gets a list of document templates view models
 | 
			
		||||
        /// </summary>
 | 
			
		||||
 
 | 
			
		||||
@@ -32,11 +32,11 @@ namespace RainmeterStudio.UI.Controller
 | 
			
		||||
            // Resource name
 | 
			
		||||
            string key = "ProjectItem";
 | 
			
		||||
 | 
			
		||||
            if (Directory.Exists(item.Path))
 | 
			
		||||
            if (Directory.Exists(item.StoragePath))
 | 
			
		||||
                key += "Directory";
 | 
			
		||||
 | 
			
		||||
            else if (File.Exists(item.Path))
 | 
			
		||||
                key += "_" + Path.GetExtension(item.Path).Substring(1);
 | 
			
		||||
            else if (File.Exists(item.StoragePath))
 | 
			
		||||
                key += "_" + Path.GetExtension(item.StoragePath).Substring(1);
 | 
			
		||||
 | 
			
		||||
            else key += "None";
 | 
			
		||||
 | 
			
		||||
@@ -55,10 +55,9 @@ namespace RainmeterStudio.UI.Controller
 | 
			
		||||
    {
 | 
			
		||||
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
 | 
			
		||||
        {
 | 
			
		||||
            var reference = value as Reference;
 | 
			
		||||
            if (reference != null)
 | 
			
		||||
            if (value is Reference)
 | 
			
		||||
            {
 | 
			
		||||
                return IconProvider.GetProjectItemIcon(reference);
 | 
			
		||||
                return IconProvider.GetProjectItemIcon((Reference)value);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            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.Shapes;
 | 
			
		||||
using RainmeterStudio.Business;
 | 
			
		||||
using RainmeterStudio.Core.Documents;
 | 
			
		||||
using RainmeterStudio.Core.Model.Events;
 | 
			
		||||
using RainmeterStudio.Storage;
 | 
			
		||||
using RainmeterStudio.UI.Controller;
 | 
			
		||||
@@ -30,6 +31,8 @@ namespace RainmeterStudio.UI
 | 
			
		||||
 | 
			
		||||
        public ProjectPanel ProjectPanel { get { return projectPanel; } }
 | 
			
		||||
 | 
			
		||||
        private Dictionary<LayoutDocument, IDocumentEditor> _openedDocuments = new Dictionary<LayoutDocument, IDocumentEditor>();
 | 
			
		||||
 | 
			
		||||
        public MainWindow(ProjectController projCtrl, DocumentController docCtrl)
 | 
			
		||||
        {
 | 
			
		||||
            InitializeComponent();
 | 
			
		||||
@@ -52,18 +55,52 @@ namespace RainmeterStudio.UI
 | 
			
		||||
 | 
			
		||||
        void documentController_DocumentOpened(object sender, DocumentOpenedEventArgs e)
 | 
			
		||||
        {
 | 
			
		||||
            // Spawn a new window
 | 
			
		||||
            // Create a new panel
 | 
			
		||||
            LayoutDocument document = new LayoutDocument();
 | 
			
		||||
            _openedDocuments.Add(document, e.Editor);
 | 
			
		||||
 | 
			
		||||
            document.Content = e.Editor.EditorUI;
 | 
			
		||||
            document.Title = (e.Editor.AttachedDocument.Reference == null) ? "New document" : e.Editor.AttachedDocument.Reference.Name;
 | 
			
		||||
            document.Closing += document_Closing;
 | 
			
		||||
            document.Closed += document_Closed;
 | 
			
		||||
 | 
			
		||||
            documentPane.Children.Add(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)
 | 
			
		||||
        {
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            switch (MessageBox.Show("Are you sure?", "", MessageBoxButton.YesNoCancel, MessageBoxImage.Question))
 | 
			
		||||
            {
 | 
			
		||||
                case MessageBoxResult.Yes:
 | 
			
		||||
 
 | 
			
		||||
@@ -162,7 +162,7 @@ namespace RainmeterStudio.UI.Panels
 | 
			
		||||
            refTree.Data = Controller.ActiveProject.Root.Data;
 | 
			
		||||
 | 
			
		||||
            // 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);
 | 
			
		||||
 | 
			
		||||
            // Transform to reference view model and return
 | 
			
		||||
 
 | 
			
		||||
@@ -37,7 +37,7 @@ namespace RainmeterStudio.UI.ViewModel
 | 
			
		||||
        {
 | 
			
		||||
            get
 | 
			
		||||
            {
 | 
			
		||||
                return Reference.Data.Path;
 | 
			
		||||
                return Reference.Data.StoragePath;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user