mirror of
https://github.com/chibicitiberiu/rainmeter-studio.git
synced 2024-02-24 04:33:31 +00:00
Added project item commands, work on project manager, implemented project manager tests
This commit is contained in:
@ -3,9 +3,14 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Windows;
|
||||
using System.Xml.Serialization;
|
||||
using RainmeterStudio.Core.Model;
|
||||
using RainmeterStudio.Core.Storage;
|
||||
using RainmeterStudio.Core.Utils;
|
||||
using RainmeterStudio.Editor.ProjectEditor;
|
||||
using RainmeterStudio.Storage;
|
||||
|
||||
namespace RainmeterStudio.Business
|
||||
{
|
||||
@ -20,11 +25,6 @@ namespace RainmeterStudio.Business
|
||||
/// </summary>
|
||||
public Project ActiveProject { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the project storage
|
||||
/// </summary>
|
||||
protected ProjectStorage Storage { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
@ -42,9 +42,8 @@ namespace RainmeterStudio.Business
|
||||
/// Initializes the project manager
|
||||
/// </summary>
|
||||
/// <param name="storage">Project storage</param>
|
||||
public ProjectManager(ProjectStorage storage)
|
||||
public ProjectManager()
|
||||
{
|
||||
Storage = storage;
|
||||
ActiveProject = null;
|
||||
}
|
||||
|
||||
@ -69,7 +68,10 @@ namespace RainmeterStudio.Business
|
||||
ActiveProject.Path = path;
|
||||
|
||||
// Save to file
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
||||
string directory = Path.GetDirectoryName(path);
|
||||
if (!String.IsNullOrEmpty(directory))
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
||||
|
||||
SaveActiveProject();
|
||||
|
||||
// Raise event
|
||||
@ -81,14 +83,14 @@ namespace RainmeterStudio.Business
|
||||
/// Opens a project from disk
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
public void OpenProject(string path)
|
||||
public void OpenProject(string path)
|
||||
{
|
||||
// If there is an opened project, close it
|
||||
if (ActiveProject != null)
|
||||
Close();
|
||||
|
||||
// Open using storage
|
||||
ActiveProject = Storage.Read(path);
|
||||
ActiveProject = ProjectStorage.Read(path);
|
||||
ActiveProject.Path = path;
|
||||
|
||||
// Raise event
|
||||
@ -106,13 +108,13 @@ namespace RainmeterStudio.Business
|
||||
throw new InvalidOperationException("Cannot save a project that is not opened.");
|
||||
|
||||
// Save
|
||||
Storage.Write(ActiveProject);
|
||||
ProjectStorage.Write(ActiveProject);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Closes an opened project
|
||||
/// </summary>
|
||||
public void Close()
|
||||
public void Close()
|
||||
{
|
||||
ActiveProject = null;
|
||||
|
||||
@ -133,12 +135,245 @@ namespace RainmeterStudio.Business
|
||||
{
|
||||
_projectTemplates.Add(template);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of existing project templates
|
||||
/// </summary>
|
||||
public IEnumerable<IProjectTemplate> ProjectTemplates { get { return _projectTemplates; } }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Project item operations
|
||||
|
||||
[Serializable]
|
||||
protected struct ClipboardData
|
||||
{
|
||||
public bool Cut;
|
||||
public string QualifiedName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Places a project item in the clipboard, and marks it for deletion
|
||||
/// </summary>
|
||||
/// <param name="ref">Project item to cut</param>
|
||||
public void ProjectItemCutClipboard(Reference @ref)
|
||||
{
|
||||
var dataFormat = DataFormats.GetDataFormat(typeof(ClipboardData).FullName);
|
||||
|
||||
ClipboardData data = new ClipboardData();
|
||||
data.Cut = true;
|
||||
data.QualifiedName = @ref.QualifiedName;
|
||||
|
||||
Clipboard.SetData(dataFormat.Name, data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Places a project item in the clipboard
|
||||
/// </summary>
|
||||
/// <param name="ref">Project item to copy</param>
|
||||
public void ProjectItemCopyClipboard(Reference @ref)
|
||||
{
|
||||
var dataFormat = DataFormats.GetDataFormat(typeof(ClipboardData).FullName);
|
||||
|
||||
ClipboardData data = new ClipboardData();
|
||||
data.Cut = false;
|
||||
data.QualifiedName = @ref.QualifiedName;
|
||||
|
||||
Clipboard.SetData(dataFormat.Name, data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pastes a project item from clipboard
|
||||
/// </summary>
|
||||
/// <param name="dest">Destination</param>
|
||||
public void ProjectItemPasteClipboard(Reference dest)
|
||||
{
|
||||
var dataFormat = DataFormats.GetDataFormat(typeof(ClipboardData).FullName);
|
||||
|
||||
if (Clipboard.ContainsData(dataFormat.Name))
|
||||
{
|
||||
ClipboardData data = (ClipboardData)Clipboard.GetData(dataFormat.Name);
|
||||
var reference = ActiveProject.Root.GetReference(data.QualifiedName);
|
||||
|
||||
if (data.Cut)
|
||||
{
|
||||
ProjectItemMove(reference, dest);
|
||||
Clipboard.Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
ProjectItemCopy(reference, dest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Moves a project item to another folder
|
||||
/// </summary>
|
||||
/// <param name="ref">Project item to move</param>
|
||||
/// <param name="dest">Destination folder</param>
|
||||
public void ProjectItemMove(Reference @ref, Reference dest)
|
||||
{
|
||||
// Move storage file
|
||||
string refPath = Path.GetFileName(@ref.StoragePath.TrimEnd('\\'));
|
||||
string destinationPath = (dest.TargetKind == ReferenceTargetKind.Directory) ? dest.StoragePath : Path.GetDirectoryName(dest.StoragePath);
|
||||
string newPath = Path.Combine(destinationPath, refPath);
|
||||
|
||||
if (@ref.TargetKind == ReferenceTargetKind.Directory)
|
||||
{
|
||||
Directory.Move(@ref.StoragePath, newPath);
|
||||
|
||||
// Update children
|
||||
UpdateRenameChildren(@ref, @ref.StoragePath, newPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
File.Move(@ref.StoragePath, newPath);
|
||||
}
|
||||
|
||||
// Set up reference object
|
||||
@ref.Unparent();
|
||||
@ref.StoragePath = newPath;
|
||||
dest.Add(@ref);
|
||||
}
|
||||
|
||||
private void UpdateRenameChildren(Reference root, string oldPath, string newPath)
|
||||
{
|
||||
foreach (var pair in root.ChildrenDictionary)
|
||||
{
|
||||
pair.Value.StoragePath = pair.Value.StoragePath.Replace(oldPath, newPath);
|
||||
UpdateRenameChildren(pair.Value, oldPath, newPath);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a copy of a project item to another folder
|
||||
/// </summary>
|
||||
/// <param name="ref">Project item to copy</param>
|
||||
/// <param name="dest">Destination folder</param>
|
||||
/// <returns>Reference to the copy</returns>
|
||||
public Reference ProjectItemCopy(Reference @ref, Reference dest)
|
||||
{
|
||||
// Create a clone reference
|
||||
var copyRef = (Reference)@ref.Clone();
|
||||
|
||||
// Copy storage file
|
||||
string refPath = Path.GetFileName(@ref.StoragePath.TrimEnd('\\'));
|
||||
string destinationPath = (dest.TargetKind == ReferenceTargetKind.Directory) ? dest.StoragePath : Path.GetDirectoryName(dest.StoragePath);
|
||||
string newPath = Path.Combine(destinationPath, refPath);
|
||||
|
||||
if (@ref.TargetKind == ReferenceTargetKind.Directory)
|
||||
{
|
||||
DirectoryHelper.CopyDirectory(@ref.StoragePath, newPath);
|
||||
|
||||
// Update children
|
||||
UpdateRenameChildren(copyRef, copyRef.StoragePath, newPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find a nonconflicting file name
|
||||
newPath = GetNonConflictingPath(refPath, destinationPath);
|
||||
|
||||
// Copy
|
||||
File.Copy(@ref.StoragePath, newPath);
|
||||
}
|
||||
|
||||
// Parent reference
|
||||
copyRef.Name = Path.GetFileName(newPath);
|
||||
copyRef.StoragePath = newPath;
|
||||
dest.Add(copyRef);
|
||||
return copyRef;
|
||||
}
|
||||
|
||||
private static string GetNonConflictingPath(string filename, string destinationPath)
|
||||
{
|
||||
// Initial path - destination path + file name
|
||||
string newPath = Path.Combine(destinationPath, filename);
|
||||
|
||||
// Initial number
|
||||
int i = 1;
|
||||
|
||||
// Try to find if there already is a number
|
||||
var match = Regex.Match(newPath, "_([0-9])$");
|
||||
if (match.Success)
|
||||
{
|
||||
i = Int32.Parse(match.Groups[1].Value);
|
||||
}
|
||||
|
||||
// Find non-conflicting number
|
||||
while (File.Exists(newPath))
|
||||
{
|
||||
++i;
|
||||
newPath = Path.Combine(destinationPath, Path.GetFileNameWithoutExtension(filename) + "_" + i.ToString() + Path.GetExtension(filename));
|
||||
}
|
||||
|
||||
return newPath;
|
||||
}
|
||||
|
||||
public void ProjectItemRename(Reference @ref, string newName)
|
||||
{
|
||||
// Rename on disk
|
||||
string refPath = @ref.StoragePath.TrimEnd('\\');
|
||||
string refDir = Path.GetDirectoryName(refPath);
|
||||
string newPath = Path.Combine(refDir, newName);
|
||||
|
||||
if (@ref.TargetKind == ReferenceTargetKind.Directory)
|
||||
{
|
||||
Directory.Move(refPath, newPath);
|
||||
newPath += '\\';
|
||||
}
|
||||
else
|
||||
{
|
||||
File.Move(refPath, newPath);
|
||||
}
|
||||
|
||||
// Set reference
|
||||
@ref.Name = newName;
|
||||
@ref.StoragePath = newPath;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a project item
|
||||
/// </summary>
|
||||
/// <param name="ref"></param>
|
||||
public void ProjectItemDelete(Reference @ref, bool fromDisk)
|
||||
{
|
||||
if (fromDisk)
|
||||
{
|
||||
if (@ref.TargetKind == ReferenceTargetKind.File)
|
||||
File.Delete(@ref.StoragePath);
|
||||
|
||||
else Directory.Delete(@ref.StoragePath, true);
|
||||
}
|
||||
|
||||
@ref.Unparent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if there is a project item in the clipboard
|
||||
/// </summary>
|
||||
/// <returns>True if there is a project item in the clipboard</returns>
|
||||
public bool HaveProjectItemInClipboard()
|
||||
{
|
||||
var dataFormat = DataFormats.GetDataFormat(typeof(ClipboardData).FullName);
|
||||
return Clipboard.ContainsData(dataFormat.Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new folder with given name
|
||||
/// </summary>
|
||||
/// <param name="name">Name of folder</param>
|
||||
/// <param name="parent">Parent folder</param>
|
||||
public void CreateFolder(string name, Reference parent)
|
||||
{
|
||||
string dir = (parent.TargetKind == ReferenceTargetKind.Directory) ?
|
||||
parent.StoragePath : Path.GetDirectoryName(parent.StoragePath);
|
||||
string newDirPath = Path.Combine(dir, name);
|
||||
|
||||
Directory.CreateDirectory(newDirPath);
|
||||
parent.Add(new Reference(name, newDirPath, ReferenceTargetKind.Directory));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user