Rewrote references

This commit is contained in:
2014-08-31 14:41:24 +03:00
parent 520eed12a6
commit 10aa72176e
24 changed files with 1182 additions and 475 deletions

View File

@ -100,7 +100,7 @@ namespace RainmeterStudio.Business
throw new InvalidOperationException("Cannot save a project that is not opened.");
// Save
Storage.Save(ActiveProject.Path, ActiveProject);
Storage.Save(ActiveProject);
}
/// <summary>

View File

@ -9,7 +9,7 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>RainmeterStudio</RootNamespace>
<AssemblyName>RainmeterStudio</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
@ -24,6 +24,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@ -33,6 +34,7 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />

View File

@ -9,37 +9,61 @@ using RainmeterStudio.Core.Storage;
namespace RainmeterStudio.Storage
{
/// <summary>
/// Project storage, loads and saves project files
/// </summary>
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)
{
// Open file
var file = File.OpenText(path);
// Deserialize file
var serializer = new XmlSerializer(typeof(SerializableProject), new XmlRootAttribute("project"));
SerializableProject project = serializer.Deserialize(file) as SerializableProject;
var serializer = new XmlSerializer(typeof(Project), new XmlRootAttribute("project"));
Project project = serializer.Deserialize(file) as Project;
if (project != null)
{
project.Path = path;
}
// Clean up
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
var file = File.OpenWrite(path);
// Serialize file
var sProject = new SerializableProject(project);
var serializer = new XmlSerializer(typeof(SerializableProject), new XmlRootAttribute("project"));
serializer.Serialize(file, sProject);
var serializer = new XmlSerializer(typeof(Project), new XmlRootAttribute("project"));
serializer.Serialize(file, project);
// Clean up
file.Close();
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);
}
}
}

View File

@ -90,7 +90,7 @@ namespace RainmeterStudio.UI.Controller
// Set the reference
var name = dialog.SelectedName;
string folder = OwnerWindow.ProjectPanel.ActiveItem.Data.StoragePath;
string folder = OwnerWindow.ProjectPanel.ActiveItem.StoragePath;
if (!Directory.Exists(folder))
folder = Path.GetDirectoryName(folder);

View File

@ -32,12 +32,23 @@ namespace RainmeterStudio.UI.Controller
// Resource name
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";
}
else if (File.Exists(item.StoragePath))
key += "_" + Path.GetExtension(item.StoragePath).Substring(1);
// None
else key += "None";
// Get icon

View File

@ -13,6 +13,7 @@ using System.Windows.Navigation;
using System.Windows.Shapes;
using RainmeterStudio.Business;
using RainmeterStudio.Core.Documents;
using RainmeterStudio.Core.Model;
using RainmeterStudio.Core.Model.Events;
using RainmeterStudio.Storage;
using RainmeterStudio.UI.Controller;
@ -70,22 +71,24 @@ namespace RainmeterStudio.UI
e.Document.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler((obj, args) =>
{
string documentName;
if (!e.Document.Reference.IsInProject())
// Get title
if (!ProjectController.ActiveProject.Contains(e.Document.Reference))
{
documentName = e.Document.Reference.StoragePath;
if (documentName == null)
documentName = "New document";
documentName = e.Document.Reference.StoragePath ?? "New document";
}
else
{
documentName = e.Document.Reference.Name;
}
// Is document dirty? Append star
if (e.Document.IsDirty)
{
documentName += "*";
}
// Set document title
document.Title = documentName;
});
}

View File

@ -46,8 +46,8 @@
<TreeView Grid.Row="2" Name="treeProjectItems">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="{Binding Data.IsExpanded, Mode=TwoWay}" />
<Setter Property="IsSelected" Value="{Binding Data.IsSelected, Mode=TwoWay}" />
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
<EventSetter Event="Expanded" Handler="TreeViewItem_ExpandedOrCollapsed" />
<EventSetter Event="Collapsed" Handler="TreeViewItem_ExpandedOrCollapsed" />
</Style>
@ -55,8 +55,8 @@
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<DockPanel LastChildFill="True">
<Image DockPanel.Dock="Left" Width="16" Height="16" Source="{Binding Data.Reference.Data, Converter={StaticResource IconConverter}}" />
<TextBlock Text="{Binding Data.Name}" />
<Image DockPanel.Dock="Left" Width="16" Height="16" Source="{Binding Reference, Converter={StaticResource IconConverter}}" />
<TextBlock Text="{Binding Name}" />
</DockPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>

View File

@ -67,7 +67,7 @@ namespace RainmeterStudio.UI.Panels
/// <summary>
/// Gets the selected tree view item
/// </summary>
public Tree<Reference> ActiveItem
public Reference ActiveItem
{
get
{
@ -136,57 +136,36 @@ namespace RainmeterStudio.UI.Panels
this.IsEnabled = true;
// Get tree
Tree<ReferenceViewModel> tree;
Reference refTree;
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
{
tree = GetProjectItems();
refTree = Controller.ActiveProject.Root;
}
// Add tree to tree view
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()
{
// Get tree
var tree = treeProjectItems.Items[0] as Tree<ReferenceViewModel>;
var tree = treeProjectItems.Items[0] as ReferenceViewModel;
if (tree == null)
return;
// Expand all
tree.Apply((node) => node.Data.IsExpanded = true);
tree.TreeExpand(true);
// Set can expand property
CanExpand = false;
@ -195,12 +174,12 @@ namespace RainmeterStudio.UI.Panels
private void CollapseAll()
{
// Get tree
var tree = treeProjectItems.Items[0] as Tree<ReferenceViewModel>;
var tree = treeProjectItems.Items[0] as ReferenceViewModel;
if (tree == null)
return;
// Expand all
tree.Apply((node) => node.Data.IsExpanded = false);
tree.TreeExpand(false);
// Set can expand property
CanExpand = true;
@ -209,12 +188,12 @@ namespace RainmeterStudio.UI.Panels
void TreeViewItem_ExpandedOrCollapsed(object sender, RoutedEventArgs e)
{
// Get tree
var tree = treeProjectItems.Items[0] as Tree<ReferenceViewModel>;
var tree = treeProjectItems.Items[0] as ReferenceViewModel;
if (tree == null)
return;
// We can expand if the root is not expanded
CanExpand = (!tree.Data.IsExpanded);
CanExpand = (!tree.IsExpanded);
}
}
}

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Text;
@ -10,14 +11,16 @@ namespace RainmeterStudio.UI.ViewModel
/// <summary>
/// Contains the view model of a reference
/// </summary>
public class ReferenceViewModel : INotifyPropertyChanged
public class ReferenceViewModel : INotifyPropertyChanged, INotifyCollectionChanged
{
private List<ReferenceViewModel> _children = null;
#region Properties
/// <summary>
/// Gets the linked reference
/// </summary>
public Tree<Reference> Reference { get; private set; }
public Reference Reference { get; private set; }
/// <summary>
/// Gets or sets the name
@ -26,7 +29,7 @@ namespace RainmeterStudio.UI.ViewModel
{
get
{
return Reference.Data.Name;
return Reference.Name;
}
}
@ -37,10 +40,20 @@ namespace RainmeterStudio.UI.ViewModel
{
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;
@ -101,11 +114,70 @@ namespace RainmeterStudio.UI.ViewModel
/// Creates a new instance of reference view model
/// </summary>
/// <param name="reference">Reference</param>
public ReferenceViewModel(Tree<Reference> reference)
public ReferenceViewModel(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
#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;
}
}

View File

@ -1,17 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<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" />
<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"/>
</sectionGroup>
</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>
<setting name="Command_ProjectCreateCommand_Shortcut" serializeAs="String">
<value>Ctrl+Shift+N</value>
</setting>
<setting name="Command_ProjectPanel_RefreshCommand_Shortcut"
serializeAs="String">
<setting name="Command_ProjectPanel_RefreshCommand_Shortcut" serializeAs="String">
<value>F5</value>
</setting>
<setting name="Command_DocumentCreateCommand_Shortcut" serializeAs="String">
@ -39,10 +38,10 @@
<value>10</value>
</setting>
<setting name="CreateProjectDialog_RecentLocations" serializeAs="String">
<value />
<value/>
</setting>
<setting name="Project_SavedLocation" serializeAs="String">
<value />
<value/>
</setting>
<setting name="CreateProjectDialog_CreateDirectoryCheckbox" serializeAs="String">
<value>True</value>