Implemented project manager

This commit is contained in:
Tiberiu Chibici 2014-07-26 13:49:11 +03:00
parent 6eec29a3a7
commit 48972dfb52
18 changed files with 1028 additions and 52 deletions

View File

@ -51,7 +51,7 @@ namespace RainmeterStudio.Business
/// </summary> /// </summary>
/// <param name="format"></param> /// <param name="format"></param>
/// <param name="path"></param> /// <param name="path"></param>
public void Create(DocumentFormat format, string path) public void Create(DocumentTemplate format, string path)
{ {
// Create document // Create document
var document = format.Factory.CreateDocument(format, path); var document = format.Factory.CreateDocument(format, path);
@ -65,7 +65,7 @@ namespace RainmeterStudio.Business
DocumentOpened(this, new DocumentOpenedEventArgs(editor)); DocumentOpened(this, new DocumentOpenedEventArgs(editor));
} }
public IEnumerable<DocumentFormat> DocumentFormats public IEnumerable<DocumentTemplate> DocumentFormats
{ {
get get
{ {

View File

@ -3,14 +3,117 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using RainmeterStudio.Model; using RainmeterStudio.Model;
using RainmeterStudio.Storage;
namespace RainmeterStudio.Business namespace RainmeterStudio.Business
{ {
public class ProjectManager public class ProjectManager
{ {
#region Properties
/// <summary>
/// Gets the currently opened project
/// </summary>
public Project ActiveProject { get; protected set; } public Project ActiveProject { get; protected set; }
public void Open() { } /// <summary>
public void Close() { } /// Gets the currently opened project's path
/// </summary>
public string ActiveProjectPath { get; protected set; }
/// <summary>
/// Gets or sets the project storage
/// </summary>
protected ProjectStorage Storage { get; set; }
#endregion
#region Callbacks
/// <summary>
/// Called when a project is opened or the active project closes.
/// </summary>
public event EventHandler ActiveProjectChanged;
#endregion
/// <summary>
/// Initializes the project manager
/// </summary>
/// <param name="storage">Project storage</param>
public ProjectManager(ProjectStorage storage)
{
Storage = storage;
ActiveProject = null;
}
/// <summary>
/// Creates a new project
/// </summary>
/// <param name="name">Name of project</param>
/// <param name="path">Path of project file</param>
public void CreateProject(string name, string path)
{
// If there is an opened project, close it
if (ActiveProject != null)
Close();
// Create project object
ActiveProject = new Project();
ActiveProject.Name = name;
// Save to file
ActiveProjectPath = path;
SaveActiveProject();
// Raise event
if (ActiveProjectChanged != null)
ActiveProjectChanged(this, new EventArgs());
}
/// <summary>
/// Opens a project from disk
/// </summary>
/// <param name="path"></param>
public void OpenProject(string path)
{
// If there is an opened project, close it
if (ActiveProject != null)
Close();
// Open using storage
ActiveProject = Storage.Load(path);
ActiveProjectPath = path;
// Raise event
if (ActiveProjectChanged != null)
ActiveProjectChanged(this, new EventArgs());
}
/// <summary>
/// Saves the changes to the current project to disk
/// </summary>
public void SaveActiveProject()
{
// Safety check
if (ActiveProject == null)
throw new InvalidOperationException("Cannot save a project that is not opened.");
// Save
Storage.Save(ActiveProjectPath, ActiveProject);
}
/// <summary>
/// Closes an opened project
/// </summary>
public void Close()
{
ActiveProject = null;
ActiveProjectPath = null;
// Raise event
if (ActiveProjectChanged != null)
ActiveProjectChanged(this, new EventArgs());
}
} }
} }

View File

@ -19,11 +19,11 @@ namespace RainmeterStudio.Documents.Text
} }
/// <inheritdoc /> /// <inheritdoc />
public IEnumerable<DocumentFormat> CreateDocumentFormats public IEnumerable<DocumentTemplate> CreateDocumentFormats
{ {
get get
{ {
yield return new DocumentFormat() yield return new DocumentTemplate()
{ {
Name = Resources.Strings.DocumentFormat_TextFile_Name, Name = Resources.Strings.DocumentFormat_TextFile_Name,
Category = Resources.Strings.Category_Utility, Category = Resources.Strings.Category_Utility,
@ -48,7 +48,7 @@ namespace RainmeterStudio.Documents.Text
public IDocumentStorage Storage { get { return _storage; } } public IDocumentStorage Storage { get { return _storage; } }
public IDocument CreateDocument(DocumentFormat format, string path) public IDocument CreateDocument(DocumentTemplate format, string path)
{ {
var document = new TextDocument(); var document = new TextDocument();
document.FilePath = path; document.FilePath = path;

View File

@ -2,7 +2,7 @@
namespace RainmeterStudio.Model namespace RainmeterStudio.Model
{ {
public class DocumentFormat public class DocumentTemplate
{ {
public string Name { get; set; } public string Name { get; set; }
public ImageSource Icon { get; set; } public ImageSource Icon { get; set; }

View File

@ -16,7 +16,7 @@ namespace RainmeterStudio.Model
/// <summary> /// <summary>
/// Formats that will be used to populate the 'create document' dialog /// Formats that will be used to populate the 'create document' dialog
/// </summary> /// </summary>
IEnumerable<DocumentFormat> CreateDocumentFormats { get; } IEnumerable<DocumentTemplate> CreateDocumentFormats { get; }
/// <summary> /// <summary>
/// Creates a new editor object /// Creates a new editor object
@ -29,7 +29,7 @@ namespace RainmeterStudio.Model
/// Creates a new document /// Creates a new document
/// </summary> /// </summary>
/// <returns>A new document</returns> /// <returns>A new document</returns>
IDocument CreateDocument(DocumentFormat format, string path); IDocument CreateDocument(DocumentTemplate format, string path);
/// <summary> /// <summary>
/// Gets the storage of this factory /// Gets the storage of this factory

View File

@ -22,5 +22,16 @@ namespace RainmeterStudio.Properties {
return defaultInstance; return defaultInstance;
} }
} }
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public global::System.Windows.Input.KeyGestureConverter asdf {
get {
return ((global::System.Windows.Input.KeyGestureConverter)(this["asdf"]));
}
set {
this["asdf"] = value;
}
}
} }
} }

View File

@ -40,6 +40,7 @@
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Data" /> <Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Xaml" /> <Reference Include="System.Xaml" />
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
@ -95,6 +96,11 @@
<Compile Include="Model\Reference.cs" /> <Compile Include="Model\Reference.cs" />
<Compile Include="Model\Tree.cs" /> <Compile Include="Model\Tree.cs" />
<Compile Include="Rainmeter.cs" /> <Compile Include="Rainmeter.cs" />
<Compile Include="Resources\Icons.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Icons.resx</DependentUpon>
</Compile>
<Compile Include="Resources\Strings.Designer.cs"> <Compile Include="Resources\Strings.Designer.cs">
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>
@ -104,11 +110,15 @@
<Compile Include="Storage\ProjectStorage.cs" /> <Compile Include="Storage\ProjectStorage.cs" />
<Compile Include="Storage\SkinDirectory.cs" /> <Compile Include="Storage\SkinDirectory.cs" />
<Compile Include="UI\Command.cs" /> <Compile Include="UI\Command.cs" />
<Compile Include="UI\Controller\ProjectController.cs" />
<Compile Include="UI\Dialogs\CreateDocumentDialog.xaml.cs"> <Compile Include="UI\Dialogs\CreateDocumentDialog.xaml.cs">
<DependentUpon>CreateDocumentDialog.xaml</DependentUpon> <DependentUpon>CreateDocumentDialog.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="UI\Controller\DocumentController.cs" /> <Compile Include="UI\Controller\DocumentController.cs" />
<Compile Include="Model\Events\DocumentOpenedEventArgs.cs" /> <Compile Include="Model\Events\DocumentOpenedEventArgs.cs" />
<Compile Include="UI\Dialogs\CreateProjectDialog.xaml.cs">
<DependentUpon>CreateProjectDialog.xaml</DependentUpon>
</Compile>
<Compile Include="UI\SkinsPanel.xaml.cs"> <Compile Include="UI\SkinsPanel.xaml.cs">
<DependentUpon>SkinsPanel.xaml</DependentUpon> <DependentUpon>SkinsPanel.xaml</DependentUpon>
</Compile> </Compile>
@ -124,6 +134,10 @@
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
</Page> </Page>
<Page Include="UI\Dialogs\CreateProjectDialog.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="UI\MainWindow.xaml"> <Page Include="UI\MainWindow.xaml">
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType> <SubType>Designer</SubType>
@ -167,8 +181,12 @@
<Generator>ResXFileCodeGenerator</Generator> <Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput> <LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Include="Resources\Strings.resx"> <EmbeddedResource Include="Resources\Icons.resx">
<Generator>ResXFileCodeGenerator</Generator> <Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Icons.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Include="Resources\Strings.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>Strings.Designer.cs</LastGenOutput> <LastGenOutput>Strings.Designer.cs</LastGenOutput>
</EmbeddedResource> </EmbeddedResource>
<None Include="app.config" /> <None Include="app.config" />

View File

@ -0,0 +1,81 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.34014
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace RainmeterStudio.Resources {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Icons {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Icons() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("RainmeterStudio.Resources.Icons", typeof(Icons).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to /Resources/Icons/page_white_star_16.png.
/// </summary>
internal static string DocumentCreateCommand_Icon {
get {
return ResourceManager.GetString("DocumentCreateCommand_Icon", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to /Resources/Icons/project_star_16.png.
/// </summary>
internal static string ProjectCreateCommand_Icon {
get {
return ResourceManager.GetString("ProjectCreateCommand_Icon", resourceCulture);
}
}
}
}

View File

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="DocumentCreateCommand_Icon" xml:space="preserve">
<value>/Resources/Icons/page_white_star_16.png</value>
</data>
<data name="ProjectCreateCommand_Icon" xml:space="preserve">
<value>/Resources/Icons/project_star_16.png</value>
</data>
</root>

View File

@ -22,7 +22,7 @@ namespace RainmeterStudio.Resources {
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Strings { public class Strings {
private static global::System.Resources.ResourceManager resourceMan; private static global::System.Resources.ResourceManager resourceMan;
@ -36,7 +36,7 @@ namespace RainmeterStudio.Resources {
/// Returns the cached ResourceManager instance used by this class. /// Returns the cached ResourceManager instance used by this class.
/// </summary> /// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager { public static global::System.Resources.ResourceManager ResourceManager {
get { get {
if (object.ReferenceEquals(resourceMan, null)) { if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("RainmeterStudio.Resources.Strings", typeof(Strings).Assembly); global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("RainmeterStudio.Resources.Strings", typeof(Strings).Assembly);
@ -51,7 +51,7 @@ namespace RainmeterStudio.Resources {
/// resource lookups using this strongly typed resource class. /// resource lookups using this strongly typed resource class.
/// </summary> /// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture { public static global::System.Globalization.CultureInfo Culture {
get { get {
return resourceCulture; return resourceCulture;
} }
@ -63,16 +63,52 @@ namespace RainmeterStudio.Resources {
/// <summary> /// <summary>
/// Looks up a localized string similar to Utility. /// Looks up a localized string similar to Utility.
/// </summary> /// </summary>
internal static string Category_Utility { public static string Category_Utility {
get { get {
return ResourceManager.GetString("Category_Utility", resourceCulture); return ResourceManager.GetString("Category_Utility", resourceCulture);
} }
} }
/// <summary>
/// Looks up a localized string similar to Browse.
/// </summary>
public static string Dialog_Browse {
get {
return ResourceManager.GetString("Dialog_Browse", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Cancel.
/// </summary>
public static string Dialog_Cancel {
get {
return ResourceManager.GetString("Dialog_Cancel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Create.
/// </summary>
public static string Dialog_Create {
get {
return ResourceManager.GetString("Dialog_Create", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to OK.
/// </summary>
public static string Dialog_OK {
get {
return ResourceManager.GetString("Dialog_OK", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to _File.... /// Looks up a localized string similar to _File....
/// </summary> /// </summary>
internal static string DocumentCreateCommand_DisplayText { public static string DocumentCreateCommand_DisplayText {
get { get {
return ResourceManager.GetString("DocumentCreateCommand_DisplayText", resourceCulture); return ResourceManager.GetString("DocumentCreateCommand_DisplayText", resourceCulture);
} }
@ -81,7 +117,7 @@ namespace RainmeterStudio.Resources {
/// <summary> /// <summary>
/// Looks up a localized string similar to Creates a new file. /// Looks up a localized string similar to Creates a new file.
/// </summary> /// </summary>
internal static string DocumentCreateCommand_ToolTip { public static string DocumentCreateCommand_ToolTip {
get { get {
return ResourceManager.GetString("DocumentCreateCommand_ToolTip", resourceCulture); return ResourceManager.GetString("DocumentCreateCommand_ToolTip", resourceCulture);
} }
@ -90,7 +126,7 @@ namespace RainmeterStudio.Resources {
/// <summary> /// <summary>
/// Looks up a localized string similar to Text Editor. /// Looks up a localized string similar to Text Editor.
/// </summary> /// </summary>
internal static string DocumentEditor_Text_Name { public static string DocumentEditor_Text_Name {
get { get {
return ResourceManager.GetString("DocumentEditor_Text_Name", resourceCulture); return ResourceManager.GetString("DocumentEditor_Text_Name", resourceCulture);
} }
@ -99,7 +135,7 @@ namespace RainmeterStudio.Resources {
/// <summary> /// <summary>
/// Looks up a localized string similar to Blank text file. /// Looks up a localized string similar to Blank text file.
/// </summary> /// </summary>
internal static string DocumentFormat_TextFile_Description { public static string DocumentFormat_TextFile_Description {
get { get {
return ResourceManager.GetString("DocumentFormat_TextFile_Description", resourceCulture); return ResourceManager.GetString("DocumentFormat_TextFile_Description", resourceCulture);
} }
@ -108,10 +144,82 @@ namespace RainmeterStudio.Resources {
/// <summary> /// <summary>
/// Looks up a localized string similar to Text file. /// Looks up a localized string similar to Text file.
/// </summary> /// </summary>
internal static string DocumentFormat_TextFile_Name { public static string DocumentFormat_TextFile_Name {
get { get {
return ResourceManager.GetString("DocumentFormat_TextFile_Name", resourceCulture); return ResourceManager.GetString("DocumentFormat_TextFile_Name", resourceCulture);
} }
} }
/// <summary>
/// Looks up a localized string similar to _Project....
/// </summary>
public static string ProjectCreateCommand_DisplayText {
get {
return ResourceManager.GetString("ProjectCreateCommand_DisplayText", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Creates a new project.
/// </summary>
public static string ProjectCreateCommand_ToolTip {
get {
return ResourceManager.GetString("ProjectCreateCommand_ToolTip", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Location:.
/// </summary>
public static string ProjectCreateDialog_Location {
get {
return ResourceManager.GetString("ProjectCreateDialog_Location", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Set location as default.
/// </summary>
public static string ProjectCreateDialog_LocationDefault {
get {
return ResourceManager.GetString("ProjectCreateDialog_LocationDefault", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Name:.
/// </summary>
public static string ProjectCreateDialog_Name {
get {
return ResourceManager.GetString("ProjectCreateDialog_Name", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Path:.
/// </summary>
public static string ProjectCreateDialog_Path {
get {
return ResourceManager.GetString("ProjectCreateDialog_Path", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Create directory for project.
/// </summary>
public static string ProjectCreateDialog_PathCreateFolder {
get {
return ResourceManager.GetString("ProjectCreateDialog_PathCreateFolder", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Create project.
/// </summary>
public static string ProjectCreateDialog_Title {
get {
return ResourceManager.GetString("ProjectCreateDialog_Title", resourceCulture);
}
}
} }
} }

View File

@ -120,6 +120,18 @@
<data name="Category_Utility" xml:space="preserve"> <data name="Category_Utility" xml:space="preserve">
<value>Utility</value> <value>Utility</value>
</data> </data>
<data name="Dialog_Browse" xml:space="preserve">
<value>Browse</value>
</data>
<data name="Dialog_Cancel" xml:space="preserve">
<value>Cancel</value>
</data>
<data name="Dialog_Create" xml:space="preserve">
<value>Create</value>
</data>
<data name="Dialog_OK" xml:space="preserve">
<value>OK</value>
</data>
<data name="DocumentCreateCommand_DisplayText" xml:space="preserve"> <data name="DocumentCreateCommand_DisplayText" xml:space="preserve">
<value>_File...</value> <value>_File...</value>
</data> </data>
@ -135,4 +147,28 @@
<data name="DocumentFormat_TextFile_Name" xml:space="preserve"> <data name="DocumentFormat_TextFile_Name" xml:space="preserve">
<value>Text file</value> <value>Text file</value>
</data> </data>
<data name="ProjectCreateCommand_DisplayText" xml:space="preserve">
<value>_Project...</value>
</data>
<data name="ProjectCreateCommand_ToolTip" xml:space="preserve">
<value>Creates a new project</value>
</data>
<data name="ProjectCreateDialog_Location" xml:space="preserve">
<value>Location:</value>
</data>
<data name="ProjectCreateDialog_LocationDefault" xml:space="preserve">
<value>Set location as default</value>
</data>
<data name="ProjectCreateDialog_Name" xml:space="preserve">
<value>Name:</value>
</data>
<data name="ProjectCreateDialog_Path" xml:space="preserve">
<value>Path:</value>
</data>
<data name="ProjectCreateDialog_PathCreateFolder" xml:space="preserve">
<value>Create directory for project</value>
</data>
<data name="ProjectCreateDialog_Title" xml:space="preserve">
<value>Create project</value>
</data>
</root> </root>

View File

@ -16,7 +16,25 @@ namespace RainmeterStudio.UI.Controller
{ {
#region Commands #region Commands
public Command DocumentCreateCommand { get; private set; } public Command _documentCreateCommand;
public Command DocumentCreateCommand
{
get
{
if (_documentCreateCommand == null)
{
_documentCreateCommand = new Command("DocumentCreateCommand", () => CreateWindow())
{
DisplayText = Resources.Strings.DocumentCreateCommand_DisplayText,
Tooltip = Resources.Strings.DocumentCreateCommand_ToolTip,
Icon = new BitmapImage(new Uri(Resources.Icons.DocumentCreateCommand_Icon, UriKind.RelativeOrAbsolute)),
Shortcut = new KeyGesture(Key.N, ModifierKeys.Control)
};
}
return _documentCreateCommand;
}
}
#endregion #endregion
@ -37,16 +55,9 @@ namespace RainmeterStudio.UI.Controller
public DocumentController() public DocumentController()
{ {
DocumentCreateCommand = new Command("DocumentCreateCommand", () => CreateWindow())
{
DisplayText = Resources.Strings.DocumentCreateCommand_DisplayText,
Tooltip = Resources.Strings.DocumentCreateCommand_ToolTip,
Icon = new BitmapImage(new Uri("/Resources/Icons/page_white_star_16.png", UriKind.RelativeOrAbsolute)),
Shortcut = new KeyGesture(Key.N, ModifierKeys.Control)
};
} }
public void CreateWindow(DocumentFormat defaultFormat = null, string defaultPath = "") public void CreateWindow(DocumentTemplate defaultFormat = null, string defaultPath = "")
{ {
// Show dialog // Show dialog
var dialog = new CreateDocumentDialog() var dialog = new CreateDocumentDialog()
@ -67,7 +78,7 @@ namespace RainmeterStudio.UI.Controller
DocumentManager.Instance.Create(format, path); DocumentManager.Instance.Create(format, path);
} }
public void Create(DocumentFormat format, string path) public void Create(DocumentTemplate format, string path)
{ {
// Call manager // Call manager
DocumentManager.Instance.Create(format, path); DocumentManager.Instance.Create(format, path);

View File

@ -0,0 +1,148 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media.Imaging;
using RainmeterStudio.Business;
using RainmeterStudio.Model;
using RainmeterStudio.UI.Dialogs;
namespace RainmeterStudio.UI.Controller
{
public class ProjectController
{
#region Properties
/// <summary>
/// Gets the project manager
/// </summary>
protected ProjectManager Manager { get; private set; }
/// <summary>
/// Gets or sets the owner window. Used for creating dialogs.
/// </summary>
public Window OwnerWindow { get; set; }
/// <summary>
/// Gets the active project
/// </summary>
public Project ActiveProject
{
get
{
return Manager.ActiveProject;
}
}
/// <summary>
/// Gets the active project path
/// </summary>
public string ActiveProjectPath
{
get
{
return Manager.ActiveProjectPath;
}
}
#endregion
#region Callbacks
/// <summary>
/// Called when a project is opened or the active project closes.
/// </summary>
public event EventHandler ActiveProjectChanged
{
add
{
Manager.ActiveProjectChanged += value;
}
remove
{
Manager.ActiveProjectChanged -= value;
}
}
#endregion
#region Commands
private Command _projectCreateCommand;
public Command ProjectCreateCommand
{
get
{
if (_projectCreateCommand == null)
{
_projectCreateCommand = new Command("ProjectCreateComand", () => CreateProject())
{
DisplayText = Resources.Strings.ProjectCreateCommand_DisplayText,
Tooltip = Resources.Strings.ProjectCreateCommand_ToolTip,
Icon = new BitmapImage(new Uri(Resources.Icons.ProjectCreateCommand_Icon, UriKind.RelativeOrAbsolute)),
Shortcut = new KeyGesture(Key.N, ModifierKeys.Control | ModifierKeys.Shift)
};
}
return _projectCreateCommand;
}
}
#endregion
/// <summary>
/// Initializes the project controller
/// </summary>
/// <param name="manager">Project manager</param>
public ProjectController(ProjectManager manager)
{
Manager = manager;
}
/// <summary>
/// Displays the 'create project' dialog and creates a new project
/// </summary>
public void CreateProject(string name = null, string path = null)
{
// Create dialog
var dialog = new CreateProjectDialog();
dialog.Owner = OwnerWindow;
dialog.SelectedLocation = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "Rainmeter Studio Projects");
if (name != null)
dialog.Name = name;
if (path != null)
dialog.SelectedPath = path;
// Display
bool? res = dialog.ShowDialog();
if (!res.HasValue || !res.Value)
return;
string selectedPath = dialog.SelectedPath;
// Call manager
Manager.CreateProject(name, selectedPath); // TODO
}
/// <summary>
/// Displays an 'open file' dialog and opens an existing project
/// </summary>
/// <param name="path"></param>
public void OpenProject(string path = null)
{
}
/// <summary>
/// Closes the active project
/// </summary>
public void CloseProject()
{
}
}
}

View File

@ -24,11 +24,11 @@ namespace RainmeterStudio.UI.Dialogs
/// <summary> /// <summary>
/// Gets or sets the currently selected file format /// Gets or sets the currently selected file format
/// </summary> /// </summary>
public DocumentFormat SelectedFormat public DocumentTemplate SelectedFormat
{ {
get get
{ {
return listFormats.SelectedItem as DocumentFormat; return listFormats.SelectedItem as DocumentTemplate;
} }
set set
{ {

View File

@ -0,0 +1,102 @@
<Window x:Class="RainmeterStudio.UI.Dialogs.CreateProjectDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:r="clr-namespace:RainmeterStudio.Resources"
xmlns:toremove="clr-namespace:RainmeterStudio.Model"
Title="{x:Static r:Strings.ProjectCreateDialog_Title}" Height="320" Width="480"
WindowStartupLocation="CenterOwner"
WindowStyle="ToolWindow" ShowInTaskbar="False">
<Grid Background="WhiteSmoke">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListView Name="listTemplates" Grid.Row="0" SelectedIndex="0"
IsEnabled="False">
<!-- TODO: remove -->
<toremove:DocumentTemplate Name="Empty project"
Description="Create a new empty project" >
</toremove:DocumentTemplate>
<ListView.ItemTemplate>
<DataTemplate>
<DockPanel>
<Image DockPanel.Dock="Left" Source="{Binding Icon}"
Width="32" Height="32" Margin="2"
Stretch="Uniform" VerticalAlignment="Top" />
<StackPanel Orientation="Vertical" VerticalAlignment="Center">
<TextBlock Text="{Binding Name}" FontWeight="Bold" />
<TextBlock Text="{Binding Description}" />
</StackPanel>
</DockPanel>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock FontWeight="Bold" FontSize="13pt" Text="{Binding Name}" />
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<!-- Name -->
<TextBlock Grid.Row="0" Text="{x:Static r:Strings.ProjectCreateDialog_Name}" />
<TextBox Name="textName"
Grid.Row="0" Grid.Column="1"
TextChanged="textName_TextChanged"/>
<!-- Location -->
<TextBlock Grid.Row="1" Text="{x:Static r:Strings.ProjectCreateDialog_Location}" />
<ComboBox Name="textLocation" IsEditable="True"
Grid.Row="1" Grid.Column="1" />
<Button Grid.Row="1" Grid.Column="2" Content="{x:Static r:Strings.Dialog_Browse}"/>
<CheckBox Name="checkLocationDefault"
Grid.Row="1" Grid.Column="3"
Content="{x:Static r:Strings.ProjectCreateDialog_LocationDefault}"
VerticalAlignment="Center"/>
<!-- Path -->
<TextBlock Grid.Row="2" Text="{x:Static r:Strings.ProjectCreateDialog_Path}"/>
<ComboBox Name="textPath"
IsEditable="True"
Grid.Row="2" Grid.Column="1" />
<Button Grid.Row="2" Grid.Column="2" Content="{x:Static r:Strings.Dialog_Browse}" />
<CheckBox Name="checkCreateDirectory"
Grid.Row="2" Grid.Column="3"
Content="{x:Static r:Strings.ProjectCreateDialog_PathCreateFolder}"
IsChecked="True"
Checked="checkCreateDirectory_CheckChanged"
Unchecked="checkCreateDirectory_CheckChanged"
VerticalAlignment="Center"/>
</Grid>
<StackPanel Grid.Row="2" Orientation="Horizontal"
HorizontalAlignment="Right">
<Button Command="{Binding CreateCommand}" IsDefault="True" Content="{x:Static r:Strings.Dialog_Create}" />
<Button Command="{Binding CancelCommand}" IsCancel="True" Content="{x:Static r:Strings.Dialog_Cancel}" />
</StackPanel>
</Grid>
</Window>

View File

@ -0,0 +1,207 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
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.Business;
using RainmeterStudio.Model;
namespace RainmeterStudio.UI.Dialogs
{
/// <summary>
/// Interaction logic for CreateProjectDialog.xaml
/// </summary>
public partial class CreateProjectDialog : Window
{
#region Commands
private Command _createCommand;
public Command CreateCommand
{
get
{
if (_createCommand == null)
_createCommand = new Command("CreateCommand", Create, Validate);
return _createCommand;
}
}
private Command _cancelCommand;
public Command CancelCommand
{
get
{
if (_cancelCommand == null)
_cancelCommand = new Command("CancelCommand", Cancel);
return _cancelCommand;
}
}
#endregion
#region Properties
/// <summary>
/// Gets or sets the currently selected file format
/// </summary>
public DocumentTemplate SelectedTemplate
{
get
{
return listTemplates.SelectedItem as DocumentTemplate;
}
set
{
listTemplates.SelectedItem = value;
}
}
/// <summary>
/// Gets or sets the path
/// </summary>
public string SelectedName
{
get
{
return textName.Text;
}
set
{
textName.Text = value;
}
}
/// <summary>
/// Gets or sets the path
/// </summary>
public string SelectedLocation
{
get
{
return textLocation.Text;
}
set
{
textLocation.Text = value;
}
}
/// <summary>
/// Gets or sets the path
/// </summary>
public string SelectedPath
{
get
{
return textPath.Text;
}
set
{
textPath.Text = value;
_pathUserSet = true;
}
}
#endregion
#region Private fields
private bool _pathUserSet = false;
private bool _ignoreNextChange = false;
#endregion
public CreateProjectDialog()
{
InitializeComponent();
textLocation.AddHandler(TextBoxBase.TextChangedEvent, new TextChangedEventHandler(textLocation_TextChanged));
textPath.AddHandler(TextBoxBase.TextChangedEvent, new TextChangedEventHandler(textPath_TextChanged));
DataContext = this;
}
private void Create()
{
DialogResult = true;
Close();
}
private void Cancel()
{
DialogResult = false;
Close();
}
private bool Validate()
{
bool res = true;
res &= !String.IsNullOrWhiteSpace(textPath.Text);
res &= (listTemplates.SelectedItem != null);
return res;
}
private void UpdatePath()
{
if (!_pathUserSet)
{
// Start with location
string path = textLocation.Text;
try
{
// Combine with project directory
if (checkCreateDirectory.IsChecked.HasValue && checkCreateDirectory.IsChecked.Value)
path = System.IO.Path.Combine(path, textName.Text);
// Combine with project file name
path = System.IO.Path.Combine(path, textName.Text + ".rsproj");
// Set new value
_ignoreNextChange = true;
textPath.Text = path;
}
catch (ArgumentException)
{
}
}
}
private void textName_TextChanged(object sender, TextChangedEventArgs e)
{
UpdatePath();
}
private void textLocation_TextChanged(object sender, TextChangedEventArgs e)
{
UpdatePath();
}
private void textPath_TextChanged(object sender, TextChangedEventArgs e)
{
if (_ignoreNextChange)
{
_ignoreNextChange = false;
}
else
{
_pathUserSet = true;
}
}
private void checkCreateDirectory_CheckChanged(object sender, RoutedEventArgs e)
{
UpdatePath();
}
}
}

View File

@ -6,11 +6,27 @@
xmlns:adlayout="clr-namespace:Xceed.Wpf.AvalonDock.Layout;assembly=Xceed.Wpf.AvalonDock" xmlns:adlayout="clr-namespace:Xceed.Wpf.AvalonDock.Layout;assembly=Xceed.Wpf.AvalonDock"
Title="Rainmeter Studio" Height="350" Width="525" Title="Rainmeter Studio" Height="350" Width="525"
ResizeMode="CanResizeWithGrip" > ResizeMode="CanResizeWithGrip" >
<Window.Resources> <Window.Resources>
<Style x:Key="CommandMenuItemStyle" TargetType="MenuItem">
<Setter Property="Command" Value="{Binding}" />
<Setter Property="Header" Value="{Binding DisplayText}" />
<Setter Property="ToolTip" Value="{Binding Tooltip}" />
<Setter Property="InputGestureText" Value="{Binding ShortcutText}" />
</Style>
<Style x:Key="CommandButtonStyle" TargetType="Button">
<Setter Property="Command" Value="{Binding}" />
<Setter Property="ToolTip" Value="{Binding Tooltip}" />
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Image Width="16" Height="16" Source="{Binding Icon}" />
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources> </Window.Resources>
<Grid> <Grid>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
@ -27,19 +43,20 @@
<Menu Grid.Row="0" Grid.ColumnSpan="10"> <Menu Grid.Row="0" Grid.ColumnSpan="10">
<MenuItem Header="_File"> <MenuItem Header="_File">
<MenuItem Header="_New"> <MenuItem Header="_New">
<MenuItem DataContext="{Binding DocumentCreateCommand}" <MenuItem DataContext="{Binding DocumentController.DocumentCreateCommand}"
Command="{Binding}" Header="{Binding DisplayText}" ToolTip="{Binding Tooltip}" Style="{StaticResource CommandMenuItemStyle}" >
InputGestureText="{Binding ShortcutText}">
<MenuItem.Icon> <MenuItem.Icon>
<Image Source="{Binding Icon}" /> <Image Source="{Binding Icon}" />
</MenuItem.Icon> </MenuItem.Icon>
</MenuItem> </MenuItem>
<MenuItem Header="_Project..." Command="{Binding DocumentCreateCommand}"> <MenuItem DataContext="{Binding ProjectController.ProjectCreateCommand}"
Style="{StaticResource CommandMenuItemStyle}">
<MenuItem.Icon> <MenuItem.Icon>
<Image Source="/Resources/Icons/project_star_16.png" /> <Image Source="{Binding Icon}" />
</MenuItem.Icon> </MenuItem.Icon>
</MenuItem> </MenuItem>
</MenuItem> </MenuItem>
<Separator />
<MenuItem Header="_Open..." /> <MenuItem Header="_Open..." />
<Separator /> <Separator />
<MenuItem Header="_Close" /> <MenuItem Header="_Close" />
@ -59,10 +76,8 @@
<Image Width="16" Height="16" Source="/Resources/Icons/arrow_forward_16.png" /> <Image Width="16" Height="16" Source="/Resources/Icons/arrow_forward_16.png" />
</Button> </Button>
<Separator /> <Separator />
<Button DataContext="{Binding DocumentCreateCommand}" <Button DataContext="{Binding DocumentController.DocumentCreateCommand}"
Command="{Binding}" ToolTip="{Binding Tooltip}"> Style="{StaticResource CommandButtonStyle}" />
<Image Source="{Binding Icon}" />
</Button>
</ToolBar> </ToolBar>
</ToolBarTray> </ToolBarTray>
@ -109,7 +124,7 @@
Width="64" Height="8" Width="64" Height="8"
IsIndeterminate="True" IsIndeterminate="True"
Visibility="Collapsed" /> Visibility="Collapsed" />
<TextBlock Name="statusMessage">Ready</TextBlock> <TextBlock Name="statusMessage">Ready</TextBlock>
</StatusBar> </StatusBar>
</Grid> </Grid>

View File

@ -11,7 +11,9 @@ using System.Windows.Media;
using System.Windows.Media.Imaging; 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.Model.Events; using RainmeterStudio.Model.Events;
using RainmeterStudio.Storage;
using RainmeterStudio.UI.Controller; using RainmeterStudio.UI.Controller;
using Xceed.Wpf.AvalonDock.Layout; using Xceed.Wpf.AvalonDock.Layout;
@ -22,9 +24,8 @@ namespace RainmeterStudio.UI
/// </summary> /// </summary>
public partial class MainWindow : Window public partial class MainWindow : Window
{ {
private DocumentController documentController; public DocumentController DocumentController { get; set; }
public ProjectController ProjectController { get; set; }
public Command DocumentCreateCommand { get { return documentController.DocumentCreateCommand; } }
public MainWindow() public MainWindow()
{ {
@ -32,10 +33,19 @@ namespace RainmeterStudio.UI
this.DataContext = this; this.DataContext = this;
documentController = new DocumentController(); // Initialize project controller
documentController.OwnerWindow = this; // TODO: put this in main
documentController.DocumentOpened += documentController_DocumentOpened; ProjectStorage projectStorage = new ProjectStorage();
AddKeyBinding(documentController.DocumentCreateCommand); ProjectManager projectManager = new ProjectManager(projectStorage);
ProjectController = new Controller.ProjectController(projectManager);
ProjectController.OwnerWindow = this;
AddKeyBinding(ProjectController.ProjectCreateCommand);
// Initialize document controller
DocumentController = new DocumentController();
DocumentController.OwnerWindow = this;
DocumentController.DocumentOpened += documentController_DocumentOpened;
AddKeyBinding(DocumentController.DocumentCreateCommand);
} }
private void AddKeyBinding(Command c) private void AddKeyBinding(Command c)