diff --git a/src/AddIns/DisplayBindings/ResourceEditor/Project/ResourceEditor.addin b/src/AddIns/DisplayBindings/ResourceEditor/Project/ResourceEditor.addin index 1d3c34c203..b688d29433 100644 --- a/src/AddIns/DisplayBindings/ResourceEditor/Project/ResourceEditor.addin +++ b/src/AddIns/DisplayBindings/ResourceEditor/Project/ResourceEditor.addin @@ -30,30 +30,28 @@ + class="ResourceEditor.Commands.AddNewFileCommand" /> - - - - - - + + + + diff --git a/src/AddIns/DisplayBindings/ResourceEditor/Project/ResourceEditor.csproj b/src/AddIns/DisplayBindings/ResourceEditor/Project/ResourceEditor.csproj index 58b4161739..3c6e01d491 100644 --- a/src/AddIns/DisplayBindings/ResourceEditor/Project/ResourceEditor.csproj +++ b/src/AddIns/DisplayBindings/ResourceEditor/Project/ResourceEditor.csproj @@ -40,49 +40,60 @@ ..\..\..\..\..\AddIns\DisplayBindings\ResourceEditor\ + + 3.0 + + + 3.0 + + + 4.0 + + + - + - - Component + + + + BinaryView.xaml + Code - - UserControl + + BooleanView.xaml + Code - - Component + + ImageViewBase.xaml + Code - - Component + + InPlaceEditLabel.xaml + Code - - Component + + + + ResourceEditorView.xaml + Code - - Component - - - - UserControl - - - - Component - - - Component + + + TextView.xaml + Code Always @@ -108,6 +119,10 @@ ICSharpCode.Core False + + {7E4A7172-7FF5-48D0-B719-7CD959DD1AC9} + ICSharpCode.Core.Presentation + {857CA1A3-FC88-4BE0-AB6A-D1EE772AB288} ICSharpCode.Core.WinForms @@ -119,5 +134,17 @@ False + + + + + + + + + + + + \ No newline at end of file diff --git a/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/BitmapExtensions.cs b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/BitmapExtensions.cs new file mode 100644 index 0000000000..f5348e36e2 --- /dev/null +++ b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/BitmapExtensions.cs @@ -0,0 +1,50 @@ +// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Runtime.InteropServices; +using System.Windows; +using System.Windows.Interop; +using System.Windows.Media.Imaging; + +namespace ResourceEditor +{ + /// + /// Bitmap conversion extensions for WinForms -> WPF + /// + public static class BitmapExtensions + { + [DllImport("gdi32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool DeleteObject(IntPtr hObject); + + public static BitmapSource ToBitmapSource(this System.Drawing.Bitmap bitmap) + { + BitmapSource bs; + IntPtr hBitmap = bitmap.GetHbitmap(); + try { + bs = Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, + Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); + bs.Freeze(); + } finally { + DeleteObject(hBitmap); + } + return bs; + } + } +} diff --git a/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/AddNewFileCommand.cs b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/AddNewFileCommand.cs index 29672f20a0..3473396345 100644 --- a/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/AddNewFileCommand.cs +++ b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/AddNewFileCommand.cs @@ -17,86 +17,83 @@ // DEALINGS IN THE SOFTWARE. using System; -using System.Drawing; using System.IO; using System.Runtime.Serialization.Formatters.Binary; -using System.Windows.Forms; using ICSharpCode.Core; using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Gui; +using Microsoft.Win32; +using ResourceEditor.ViewModels; -namespace ResourceEditor +namespace ResourceEditor.Commands { - class AddNewFileCommand : AbstractMenuCommand + class AddNewFileCommand : ResourceItemCommand { - public override void Run() + public override void ExecuteWithResourceItems(System.Collections.Generic.IEnumerable resourceItems) { - ResourceEditorControl editor = ((ResourceEditWrapper)SD.Workbench.ActiveViewContent).ResourceEditor; +// if (editor.ResourceList.WriteProtected) { +// return; +// } - if(editor.ResourceList.WriteProtected) { - return; - } - - using (OpenFileDialog fdiag = new OpenFileDialog()) { - fdiag.AddExtension = true; - fdiag.Filter = StringParser.Parse("${res:SharpDevelop.FileFilter.AllFiles}|*.*"); - fdiag.Multiselect = true; - fdiag.CheckFileExists = true; + var editor = ResourceEditor; + OpenFileDialog fdiag = new OpenFileDialog(); + fdiag.AddExtension = true; + fdiag.Filter = StringParser.Parse("${res:SharpDevelop.FileFilter.AllFiles}|*.*"); + fdiag.Multiselect = true; + fdiag.CheckFileExists = true; - if (fdiag.ShowDialog(SD.WinForms.MainWin32Window) == DialogResult.OK) { - foreach (string filename in fdiag.FileNames) { - string oresname = Path.ChangeExtension(Path.GetFileName(filename), null); - if (oresname == "") oresname = "new"; + if ((bool)fdiag.ShowDialog()) { + foreach (string filename in fdiag.FileNames) { + string oresname = Path.ChangeExtension(Path.GetFileName(filename), null); + if (oresname == "") + oresname = "new"; - string resname = oresname; + string resname = oresname; - int i = 0; + int i = 0; TestName: - if (editor.ResourceList.Resources.ContainsKey(resname)) { - if (i == 10) { - continue; - } - i++; - resname = oresname + "_" + i.ToString(); - goto TestName; - } - - object tmp = loadResource(filename); - if (tmp == null) { + if (editor.ContainsResourceName(resname)) { + if (i == 10) { continue; } - editor.ResourceList.Resources.Add(resname, new ResourceItem(resname, tmp)); + i++; + resname = oresname + "_" + i; + goto TestName; + } + object tmp = LoadResource(filename); + if (tmp == null) { + continue; } - editor.ResourceList.InitializeListView(); + editor.ResourceItems.Add(new ResourceItem(editor, resname, tmp)); } } - editor.ResourceList.OnChanged(); } - object loadResource(string name) + object LoadResource(string name) { switch (Path.GetExtension(name).ToUpperInvariant()) { case ".CUR": try { - return new Cursor(name); + return new System.Windows.Forms.Cursor(name); } catch { return null; } case ".ICO": try { - return new Icon(name); + return new System.Drawing.Icon(name); } catch { return null; } default: - // try to read a bitmap + // Try to read a bitmap try { - return new Bitmap(name); - } catch {} + return new System.Drawing.Bitmap(name); + } catch { + } - // try to read a serialized object + // Try to read a serialized object try { Stream r = File.Open(name, FileMode.Open); try { @@ -104,20 +101,21 @@ namespace ResourceEditor object o = c.Deserialize(r); r.Close(); return o; - } catch { r.Close(); } - } catch { } + } catch { + r.Close(); + } + } catch { + } - // try to read a byte array :) + // Try to read a byte array try { FileStream s = new FileStream(name, FileMode.Open); BinaryReader r = new BinaryReader(s); - Byte[] d = new Byte[(int) s.Length]; - d = r.ReadBytes((int) s.Length); + Byte[] d = new Byte[(int)s.Length]; + d = r.ReadBytes((int)s.Length); s.Close(); return d; - } catch(Exception) { - - + } catch (Exception) { string message = ResourceService.GetString("ResourceEditor.Messages.CantLoadResource"); MessageService.ShowWarning(message + " " + name + "."); } diff --git a/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/AddStringEntryCommand.cs b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/AddStringEntryCommand.cs index 8b5b4fa376..bde41d841a 100644 --- a/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/AddStringEntryCommand.cs +++ b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/AddStringEntryCommand.cs @@ -20,35 +20,33 @@ using System; using System.Windows.Forms; using ICSharpCode.Core; using ICSharpCode.SharpDevelop; +using ResourceEditor.ViewModels; -namespace ResourceEditor +namespace ResourceEditor.Commands { - class AddStringCommand : AbstractMenuCommand + class AddStringCommand : ResourceItemCommand { - public override void Run() + public override void ExecuteWithResourceItems(System.Collections.Generic.IEnumerable resourceItems) { - ResourceEditorControl editor = ((ResourceEditWrapper)SD.Workbench.ActiveViewContent).ResourceEditor; - - if(editor.ResourceList.WriteProtected) { - return; - } - +// if(editor.ResourceList.WriteProtected) { +// return; +// } +// + var editor = ResourceEditor; int count = 1; string newNameBase = " new string entry "; - string newName = newNameBase + count.ToString(); - string type = "System.String"; + string newName = newNameBase + count; - while(editor.ResourceList.Resources.ContainsKey(newName)) { + while (editor.ContainsResourceName(newName)) { count++; - newName = newNameBase + count.ToString(); + newName = newNameBase + count; } - ResourceItem item = new ResourceItem(newName, ""); - editor.ResourceList.Resources.Add(newName, item); - ListViewItem lv = new ListViewItem(new string[] { newName, type, "" }, item.ImageIndex); - editor.ResourceList.Items.Add(lv); - editor.ResourceList.OnChanged(); - lv.BeginEdit(); + ResourceItem item = new ResourceItem(editor, newName, ""); + editor.ResourceItems.Add(item); + editor.SelectedItems.Clear(); + editor.SelectedItems.Add(item); + editor.StartEditing(); } } } diff --git a/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/CopyResourceNameCommand.cs b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/CopyResourceNameCommand.cs index 93de120f94..4adb6e4b4e 100644 --- a/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/CopyResourceNameCommand.cs +++ b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/CopyResourceNameCommand.cs @@ -17,21 +17,22 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Linq; using System.Windows.Forms; using ICSharpCode.Core; using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Gui; +using ResourceEditor.ViewModels; -namespace ResourceEditor +namespace ResourceEditor.Commands { - class CopyResourceNameCommand : AbstractMenuCommand + class CopyResourceNameCommand : ResourceItemCommand { - public override void Run() + public override void ExecuteWithResourceItems(System.Collections.Generic.IEnumerable resourceItems) { - ResourceEditorControl editor = ((ResourceEditWrapper)SD.Workbench.ActiveViewContent).ResourceEditor; - - if(editor.ResourceList.SelectedItems.Count > 0) { - Clipboard.SetText(editor.ResourceList.SelectedItems[0].Text); + var firstSelectedItem = resourceItems.First(); + if (firstSelectedItem != null) { + Clipboard.SetText(firstSelectedItem.Name); } } } diff --git a/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/EditCommentCommand.cs b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/EditCommentCommand.cs index 9ca56f1a82..10b3d72c0b 100644 --- a/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/EditCommentCommand.cs +++ b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/EditCommentCommand.cs @@ -17,25 +17,23 @@ // DEALINGS IN THE SOFTWARE. using System; +using System.Linq; using ICSharpCode.Core; using ICSharpCode.SharpDevelop; +using ResourceEditor.ViewModels; -namespace ResourceEditor +namespace ResourceEditor.Commands { - class EditCommentCommand : AbstractMenuCommand + class EditCommentCommand : ResourceItemCommand { - public override void Run() + public override void ExecuteWithResourceItems(System.Collections.Generic.IEnumerable resourceItems) { - ResourceEditorControl editor = ((ResourceEditWrapper)SD.Workbench.ActiveViewContent).ResourceEditor; - if (editor.ResourceList.SelectedItems.Count != 0) { - var item = editor.ResourceList.SelectedItems[0].SubItems[3]; - string resourceName = editor.ResourceList.SelectedItems[0].Text; - string newValue = SD.MessageService.ShowInputBox("${res:ResourceEditor.ResourceEdit.ContextMenu.EditComment}", - "${res:ResourceEditor.ResourceEdit.ContextMenu.EditCommentText}", - item.Text); - if (newValue != null && newValue != item.Text) { - editor.ResourceList.SetCommentValue(resourceName, newValue); - } + var selectedItem = resourceItems.First(); + string newValue = SD.MessageService.ShowInputBox("${res:ResourceEditor.ResourceEdit.ContextMenu.EditComment}", + "${res:ResourceEditor.ResourceEdit.ContextMenu.EditCommentText}", + selectedItem.Comment); + if (newValue != null && newValue != selectedItem.Comment) { + selectedItem.Comment = newValue; } } } diff --git a/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/RenameEntryCommand.cs b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/RenameEntryCommand.cs index a374788e8b..f64c1bde83 100644 --- a/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/RenameEntryCommand.cs +++ b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/RenameEntryCommand.cs @@ -19,18 +19,17 @@ using System; using ICSharpCode.Core; using ICSharpCode.SharpDevelop; +using ResourceEditor.ViewModels; -namespace ResourceEditor +namespace ResourceEditor.Commands { - class RenameEntryCommand : AbstractMenuCommand + class RenameEntryCommand : ResourceItemCommand { - public override void Run() + public override void ExecuteWithResourceItems(System.Collections.Generic.IEnumerable resourceItems) { - ResourceEditorControl editor = ((ResourceEditWrapper)SD.Workbench.ActiveViewContent).ResourceEditor; - - if(editor.ResourceList.SelectedItems.Count != 0) { - editor.ResourceList.SelectedItems[0].BeginEdit(); - } + var editor = ResourceEditor; + if (editor != null) + editor.StartEditing(); } } } diff --git a/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/ResourceItemCommand.cs b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/ResourceItemCommand.cs new file mode 100644 index 0000000000..ba1a0aa692 --- /dev/null +++ b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/ResourceItemCommand.cs @@ -0,0 +1,107 @@ +// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections.Generic; +using System.Linq; +using ICSharpCode.SharpDevelop; +using ResourceEditor.ViewModels; + +namespace ResourceEditor.Commands +{ + /// + /// Represents a -related command. + /// + public class ResourceItemCommand : SimpleCommand + { + /// + /// Defines whether this command supports multiselection of items. + /// If not, command will be disabled by default, when more than 1 item is selected. + /// + public virtual bool SupportsMultiSelections { + get { + return false; + } + } + + /// + /// Returns list of resource item types for which this command may be enabled or null to allow any type. + /// + public virtual IEnumerable AllowedTypes { + get { + return null; + } + } + + public override bool CanExecute(object parameter) + { + if (ResourceEditor == null) + return false; + + var selectedResourceItems = GetSelectedItems(); + if (!selectedResourceItems.Any()) + return false; + if (!SupportsMultiSelections && (selectedResourceItems.Count() > 1)) + return false; + + return CanExecuteWithResourceItems(selectedResourceItems); + } + + /// + /// Checks whether this command can be executed for the current set of selected resource items. + /// + /// List of selected resource items. Will always contain at least one element. + /// True, when command can be executed, false otherwise. + public virtual bool CanExecuteWithResourceItems(IEnumerable resourceItems) + { + return true; + } + + public override void Execute(object parameter) + { + var selectedResourceItems = GetSelectedItems(); + if (!selectedResourceItems.Any()) + return; + if (!SupportsMultiSelections && (selectedResourceItems.Count() > 1)) + return; + ExecuteWithResourceItems(selectedResourceItems); + } + + /// + /// Executes command for the given set of selected resource items. + /// + /// List of selected resource items. Will always contain at least one element. + public virtual void ExecuteWithResourceItems(IEnumerable resourceItems) + { + } + + public ResourceEditorViewModel ResourceEditor { + get { + return ((ResourceEditViewContent) SD.Workbench.ActiveViewContent).ResourceEditor; + } + } + + IEnumerable GetSelectedItems() + { + var editor = ResourceEditor; + if (editor != null) + return editor.SelectedItems.OfType() ?? new ResourceEditor.ViewModels.ResourceItem[0]; + return new ResourceEditor.ViewModels.ResourceItem[0]; + } + } +} diff --git a/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/SaveEntryAsCommand.cs b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/SaveEntryAsCommand.cs index e6cf8a4a99..b41b673ddb 100644 --- a/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/SaveEntryAsCommand.cs +++ b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/SaveEntryAsCommand.cs @@ -19,73 +19,74 @@ using System; using System.Drawing; using System.IO; -using System.Windows.Forms; +using System.Linq; using ICSharpCode.Core; using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Gui; +using Microsoft.Win32; +using ResourceEditor.ViewModels; -namespace ResourceEditor +namespace ResourceEditor.Commands { - class SaveEntryAsCommand : AbstractMenuCommand + class SaveEntryAsCommand : ResourceItemCommand { - public override void Run() - { - ResourceEditorControl editor = ((ResourceEditWrapper)SD.Workbench.ActiveViewContent).ResourceEditor; - ResourceList list = editor.ResourceList; - - if(list.SelectedItems.Count != 1) { - return; - } - - string key = list.SelectedItems[0].Text; - if(! list.Resources.ContainsKey(key)) { - return; + public override System.Collections.Generic.IEnumerable AllowedTypes { + get { + return new ResourceItemEditorType[] { + ResourceItemEditorType.Bitmap, + ResourceItemEditorType.Icon, + ResourceItemEditorType.Cursor, + ResourceItemEditorType.Binary + }; } + } + + public override void ExecuteWithResourceItems(System.Collections.Generic.IEnumerable resourceItems) + { + var firstSelectedItem = resourceItems.First(); - ResourceItem item = list.Resources[key]; - SaveFileDialog sdialog = new SaveFileDialog(); + var sdialog = new Microsoft.Win32.SaveFileDialog(); sdialog.AddExtension = true; - sdialog.FileName = key; + sdialog.FileName = firstSelectedItem.Name; - if (item.ResourceValue is Bitmap) { - sdialog.Filter = StringParser.Parse("${res:SharpDevelop.FileFilter.ImageFiles} (*.png)|*.png"); - sdialog.DefaultExt = ".png"; - } else if (item.ResourceValue is Icon) { - sdialog.Filter = StringParser.Parse("${res:SharpDevelop.FileFilter.Icons}|*.ico"); - sdialog.DefaultExt = ".ico"; - } else if (item.ResourceValue is Cursor) { - sdialog.Filter = StringParser.Parse("${res:SharpDevelop.FileFilter.CursorFiles} (*.cur)|*.cur"); - sdialog.DefaultExt = ".cur"; - } else if (item.ResourceValue is byte[]){ - sdialog.Filter = StringParser.Parse("${res:SharpDevelop.FileFilter.BinaryFiles} (*.*)|*.*"); - sdialog.DefaultExt = ".bin"; + if (firstSelectedItem.ResourceValue is System.Drawing.Bitmap) { + sdialog.Filter = StringParser.Parse("${res:SharpDevelop.FileFilter.ImageFiles} (*.png)|*.png"); + sdialog.DefaultExt = ".png"; + } else if (firstSelectedItem.ResourceValue is System.Drawing.Icon) { + sdialog.Filter = StringParser.Parse("${res:SharpDevelop.FileFilter.Icons}|*.ico"); + sdialog.DefaultExt = ".ico"; + } else if (firstSelectedItem.ResourceValue is System.Windows.Forms.Cursor) { + sdialog.Filter = StringParser.Parse("${res:SharpDevelop.FileFilter.CursorFiles} (*.cur)|*.cur"); + sdialog.DefaultExt = ".cur"; + } else if (firstSelectedItem.ResourceValue is byte[]) { + sdialog.Filter = StringParser.Parse("${res:SharpDevelop.FileFilter.BinaryFiles} (*.*)|*.*"); + sdialog.DefaultExt = ".bin"; } else { return; } - DialogResult dr = sdialog.ShowDialog(SD.WinForms.MainWin32Window); - sdialog.Dispose(); - if (dr != DialogResult.OK) { + bool? dr = sdialog.ShowDialog(); + if (!dr.HasValue || !dr.Value) { return; } try { - if (item.ResourceValue is Icon) { + if (firstSelectedItem.ResourceValue is Icon) { FileStream fstr = new FileStream(sdialog.FileName, FileMode.Create); - ((Icon)item.ResourceValue).Save(fstr); + ((Icon) firstSelectedItem.ResourceValue).Save(fstr); fstr.Close(); - } else if(item.ResourceValue is Image) { - Image img = (Image)item.ResourceValue; + } else if (firstSelectedItem.ResourceValue is Image) { + Image img = (Image) firstSelectedItem.ResourceValue; img.Save(sdialog.FileName); } else { FileStream fstr = new FileStream(sdialog.FileName, FileMode.Create); BinaryWriter wr = new BinaryWriter(fstr); - wr.Write((byte[])item.ResourceValue); + wr.Write((byte[]) firstSelectedItem.ResourceValue); fstr.Close(); } - } catch(Exception ex) { - MessageBox.Show(ex.Message, "Can't save resource to " + sdialog.FileName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation); + } catch (Exception ex) { + SD.MessageService.ShowWarning("Can't save resource to " + sdialog.FileName + ": " + ex.Message); } } } diff --git a/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/ResourceEditorDisplayBinding.cs b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/ResourceEditorDisplayBinding.cs index 6fc0f754c0..6b38c9f829 100644 --- a/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/ResourceEditorDisplayBinding.cs +++ b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/ResourceEditorDisplayBinding.cs @@ -27,6 +27,8 @@ using ICSharpCode.SharpDevelop; using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.SharpDevelop.WinForms; using ICSharpCode.SharpDevelop.Workbench; +using ResourceEditor.ViewModels; +using ResourceEditor.Views; namespace ResourceEditor { @@ -39,7 +41,7 @@ namespace ResourceEditor public IViewContent CreateContentForFile(OpenedFile file) { - return new ResourceEditWrapper(file); + return new ResourceEditViewContent(file); } public bool IsPreferredBindingForFile(FileName fileName) @@ -53,211 +55,60 @@ namespace ResourceEditor } } - public class ResourceEditWrapper : AbstractViewContentHandlingLoadErrors, IClipboardHandler + public class ResourceEditViewContent : AbstractViewContentHandlingLoadErrors { - ResourceEditorControl resourceEditor = new ResourceEditorControl(); + readonly ResourceEditorViewModel resourceEditor = new ResourceEditorViewModel(); + readonly ResourceEditorView resourceEditorView = new ResourceEditorView(); - public ResourceEditorControl ResourceEditor { - get { return resourceEditor; } + public ResourceEditViewContent(OpenedFile file) + { + this.TabPageText = "Resource editor"; + resourceEditor.View = resourceEditorView; + + // Register different resource item viewers + resourceEditor.AddItemView(ResourceItemEditorType.String, new Views.TextView()); + resourceEditor.AddItemView(ResourceItemEditorType.Bitmap, new Views.ImageViewBase()); + resourceEditor.DirtyStateChanged += (sender, e) => { + if (e.IsDirty) + SetDirty(sender, new EventArgs()); + }; + + UserContent = resourceEditorView; +// resourceEditor.ResourceList.Changed += SetDirty; +// resourceEditor.ResourceList.ItemSelectionChanged += (sender, e) => SD.WinForms.InvalidateCommands(); + this.Files.Add(file); } + public ResourceEditorViewModel ResourceEditor { + get { return resourceEditor; } + } + public override bool IsReadOnly { get { return false; } } - + void SetDirty(object sender, EventArgs e) { PrimaryFile.MakeDirty(); - SD.WinForms.InvalidateCommands(); - } - - public ResourceEditWrapper(OpenedFile file) - { - this.TabPageText = "Resource editor"; - UserContent = resourceEditor; - resourceEditor.ResourceList.Changed += SetDirty; - resourceEditor.ResourceList.ItemSelectionChanged += (sender, e) => SD.WinForms.InvalidateCommands(); - this.Files.Add(file); +// SD.WinForms.InvalidateCommands(); } public override void Dispose() { base.Dispose(); - resourceEditor.Dispose(); +// resourceEditor.Dispose(); } protected override void LoadInternal(OpenedFile file, Stream stream) { - resourceEditor.ResourceList.LoadFile(file.FileName, stream); + resourceEditor.LoadFile(file.FileName, stream); } protected override void SaveInternal(OpenedFile file, Stream stream) { - resourceEditor.ResourceList.SaveFile(file.FileName, stream); - } - - - public bool EnableCut - { - get { - if (resourceEditor.ResourceList.IsEditing) { - return false; - } - return resourceEditor.ResourceList.SelectedItems.Count > 0; - } - } - - public bool EnableCopy - { - get { - if (resourceEditor.ResourceList.IsEditing) { - return false; - } - return resourceEditor.ResourceList.SelectedItems.Count > 0; - } - } - - public bool EnablePaste - { - get { - if (resourceEditor.ResourceList.IsEditing) { - return false; - } - return true; - } - } - - public bool EnableDelete - { - get { - if (resourceEditor.ResourceList.IsEditing) { - return false; - } - return resourceEditor.ResourceList.SelectedItems.Count > 0; - } - } - - public bool EnableSelectAll - { - get { - if (resourceEditor.ResourceList.IsEditing) { - return false; - } - return true; - } - } - - public void Cut() - { - if (resourceEditor.ResourceList.WriteProtected || resourceEditor.ResourceList.SelectedItems.Count < 1) - return; - - Hashtable tmphash = new Hashtable(); - foreach (ListViewItem item in resourceEditor.ResourceList.SelectedItems) { - tmphash.Add(item.Text, resourceEditor.ResourceList.Resources[item.Text].ResourceValue); - resourceEditor.ResourceList.Resources.Remove(item.Text); - resourceEditor.ResourceList.Items.Remove(item); - } - resourceEditor.ResourceList.OnChanged(); - SD.Clipboard.SetDataObject(tmphash); - } - - public void Copy() - { - if (resourceEditor.ResourceList.SelectedItems.Count < 1) { - return; - } - - Hashtable tmphash = new Hashtable(); - foreach (ListViewItem item in resourceEditor.ResourceList.SelectedItems) { - object resourceValue = GetClonedResource(resourceEditor.ResourceList.Resources[item.Text].ResourceValue); - tmphash.Add(item.Text, resourceValue); // copy a clone to clipboard - } - SD.Clipboard.SetDataObject(tmphash); - } - - public void Paste() - { - if (resourceEditor.ResourceList.WriteProtected) { - return; - } - - IDataObject dob = Clipboard.GetDataObject(); - if (dob == null) - return; - - if (dob.GetDataPresent(typeof(Hashtable).FullName)) { - Hashtable tmphash = (Hashtable)dob.GetData(typeof(Hashtable)); - foreach (DictionaryEntry entry in tmphash) { - - object resourceValue = GetClonedResource(entry.Value); - ResourceItem item; - - if (!resourceEditor.ResourceList.Resources.ContainsKey((string)entry.Key)) { - item = new ResourceItem(entry.Key.ToString(), resourceValue); - } else { - int count = 1; - string newNameBase = entry.Key.ToString() + " "; - string newName = newNameBase + count.ToString(); - - while(resourceEditor.ResourceList.Resources.ContainsKey(newName)) { - count++; - newName = newNameBase + count.ToString(); - } - item = new ResourceItem(newName, resourceValue); - } - resourceEditor.ResourceList.Resources.Add(item.Name, item); - resourceEditor.ResourceList.OnChanged(); - } - resourceEditor.ResourceList.InitializeListView(); - } - } - - /// - /// Clones a resource if the - /// is cloneable. - /// - /// A resource to clone. - /// A cloned resource if the object implements - /// the ICloneable interface, otherwise the - /// object. - object GetClonedResource(object resource) - { - object clonedResource = null; - - ICloneable cloneableResource = resource as ICloneable; - if (cloneableResource != null) { - clonedResource = cloneableResource.Clone(); - } else { - clonedResource = resource; - } - - return clonedResource; - } - - public void Delete() - { - var resourceList = resourceEditor.ResourceList; - if (resourceList.WriteProtected || resourceList.SelectedItems.Count == 0) - return; - if (!SD.MessageService.AskQuestion("${res:ResourceEditor.DeleteEntry.Confirm}", "${res:ResourceEditor.DeleteEntry.Title}")) - return; - - foreach (ListViewItem item in resourceList.SelectedItems) { - resourceList.Resources.Remove(item.Text); - resourceList.Items.Remove(item); - // and set dirty flag - resourceList.OnChanged(); - } - } - - public void SelectAll() - { - foreach (ListViewItem i in resourceEditor.ResourceList.Items) { - i.Selected=true; - } + resourceEditor.SaveFile(file.FileName, stream); } } } diff --git a/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/ViewModels/ResourceEditorViewModel.cs b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/ViewModels/ResourceEditorViewModel.cs new file mode 100644 index 0000000000..58869076fc --- /dev/null +++ b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/ViewModels/ResourceEditorViewModel.cs @@ -0,0 +1,481 @@ +// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Collections.Specialized; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.IO; +using System.Linq; +using System.Resources; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using ICSharpCode.Core; +using ICSharpCode.SharpDevelop; +using ICSharpCode.SharpDevelop.Project; +using ICSharpCode.SharpDevelop.Project.Commands; +using ResourceEditor.Views; + +namespace ResourceEditor.ViewModels +{ + public class ChangedDirtyStateEventArgs : EventArgs + { + public ChangedDirtyStateEventArgs(bool isDirty) + { + this.IsDirty = isDirty; + } + + public bool IsDirty { + get; + private set; + } + } + + /// + /// Main view model for resource editor. + /// + public class ResourceEditorViewModel : DependencyObject + { + readonly ObservableCollection resourceItems; + readonly HashSet resourceItemNames; + readonly ObservableCollection metadataItems; + readonly Dictionary itemViews; + bool longUpdateRunning; + ResourceItem editedResourceItem; + string originalNameOfEditedItem; + + IResourceEditorView view; + + public event EventHandler DirtyStateChanged; + + public static readonly DependencyProperty SearchTermProperty = + DependencyProperty.Register("SearchTerm", typeof(string), typeof(ResourceEditorViewModel), + new FrameworkPropertyMetadata()); + + public string SearchTerm { + get { return (string) GetValue(SearchTermProperty); } + set { SetValue(SearchTermProperty, value); } + } + + public IList SelectedItems { + get { + if (view != null) { + return view.SelectedItems; + } + + return null; + } + } + + public ResourceEditorViewModel() + { + resourceItems = new ObservableCollection(); + resourceItemNames = new HashSet(); + metadataItems = new ObservableCollection(); + itemViews = new Dictionary(); + } + + public ObservableCollection ResourceItems { + get { + return resourceItems; + } + } + + /// + /// Checks whether a resource name is existing in currently open file. + /// + /// Resource name to check. + /// True if name exists, false otherwise. + public bool ContainsResourceName(string name) + { + return resourceItemNames.Contains(name); + } + + public void AddItemView(ResourceItemEditorType itemType, IResourceItemView view) + { + itemViews[itemType] = view; + } + + public IResourceEditorView View { + get { + return view; + } + set { + if (view != null) { + view.SelectionChanged -= View_SelectionChanged; + view.EditingStarted -= View_EditingStarted; + view.EditingFinished -= View_EditingFinished; + view.EditingCancelled -= View_EditingCancelled; + ResourceItems.CollectionChanged -= ResourceItems_CollectionChanged; + } + + view = value; + if (view != null) { + // Bind this model to new view + view.DataContext = this; + view.CommandBindings.Add(new CommandBinding(ApplicationCommands.Cut, (s, e) => Cut(), (s, e) => e.CanExecute = EnableCut)); + view.CommandBindings.Add(new CommandBinding(ApplicationCommands.Copy, (s, e) => Copy(), (s, e) => e.CanExecute = EnableCopy)); + view.CommandBindings.Add(new CommandBinding(ApplicationCommands.Paste, (s, e) => Paste(), (s, e) => e.CanExecute = EnablePaste)); + view.CommandBindings.Add(new CommandBinding(ApplicationCommands.Delete, (s, e) => Delete(), (s, e) => e.CanExecute = EnableDelete)); + view.CommandBindings.Add(new CommandBinding(ApplicationCommands.SelectAll, (s, e) => SelectAll(), (s, e) => e.CanExecute = EnableSelectAll)); + + view.FilterPredicate = resourceItem => { + if (SearchTerm != null) + return resourceItem.Name.IndexOf(SearchTerm, StringComparison.OrdinalIgnoreCase) >= 0; + return true; + }; + view.SelectionChanged += View_SelectionChanged; + view.EditingStarted += View_EditingStarted; + view.EditingFinished += View_EditingFinished; + view.EditingCancelled += View_EditingCancelled; + ResourceItems.CollectionChanged += ResourceItems_CollectionChanged; + } + } + } + + void ResourceItems_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) + { + switch (e.Action) { + case NotifyCollectionChangedAction.Remove: + if (e.OldItems != null) { + var oldItems = e.OldItems.OfType(); + foreach (var item in oldItems) { + resourceItemNames.Remove(item.Name); + } + } + break; + case NotifyCollectionChangedAction.Add: + if (e.NewItems != null) { + var newItems = e.NewItems.OfType(); + foreach (var item in newItems) { + if (!resourceItemNames.Contains(item.Name)) + resourceItemNames.Add(item.Name); + } + } + break; + case NotifyCollectionChangedAction.Reset: + resourceItemNames.Clear(); + break; + } + + // Changes in collection of ResourceItems => make dirty + MakeDirty(); + } + + void View_SelectionChanged(object sender, EventArgs e) + { + if (longUpdateRunning) + return; + + ResourceItem selectedItem = SelectedItems.OfType().FirstOrDefault(); + if (selectedItem != null) { + if (itemViews.ContainsKey(selectedItem.ResourceType)) { + var itemView = itemViews[selectedItem.ResourceType]; + itemView.ResourceItem = selectedItem; + view.SetItemView(itemView); + } + } + } + + void OnChangedDirtyState(bool isDirty) + { + if (DirtyStateChanged != null) { + DirtyStateChanged(this, new ChangedDirtyStateEventArgs(isDirty)); + } + } + + public void MakeDirty() + { + OnChangedDirtyState(true); + } + + public void StartEditing() + { +// if (editedResourceItem != null) { +// editedResourceItem.IsEditing = false; +// editedResourceItem = null; +// originalNameOfEditedItem = null; +// } + + // Start editing currently selected item + var firstSelectedItem = SelectedItems.OfType().FirstOrDefault(); + if (firstSelectedItem != null) { + editedResourceItem = firstSelectedItem; + originalNameOfEditedItem = editedResourceItem.Name; + firstSelectedItem.IsEditing = true; + } + } + + void View_EditingStarted(object sender, EventArgs e) + { + StartEditing(); + } + + void View_EditingFinished(object sender, EventArgs e) + { +// if (editedResourceItem != null) { +// editedResourceItem.IsEditing = false; +// editedResourceItem = null; +// originalNameOfEditedItem = null; +// MakeDirty(); +// } + } + + void View_EditingCancelled(object sender, EventArgs e) + { +// if (editedResourceItem != null) { +// editedResourceItem.IsEditing = false; +// editedResourceItem.Name = originalNameOfEditedItem; +// editedResourceItem = null; +// originalNameOfEditedItem = null; +// } + } + + void StartUpdate() + { + // When loading many items at once, temporarily unbind view from model + view.DataContext = null; + } + + void EndUpdate() + { + view.DataContext = this; + } + + public void LoadFile(FileName filename, Stream stream) + { + StartUpdate(); + + resourceItems.Clear(); + metadataItems.Clear(); + switch (Path.GetExtension(filename).ToLowerInvariant()) { + case ".resx": + ResXResourceReader rx = new ResXResourceReader(stream); + ITypeResolutionService typeResolver = null; + rx.BasePath = Path.GetDirectoryName(filename); + rx.UseResXDataNodes = true; + IDictionaryEnumerator n = rx.GetEnumerator(); + while (n.MoveNext()) { + ResXDataNode node = (ResXDataNode) n.Value; + resourceItems.Add(new ResourceItem(this, node.Name, node.GetValue(typeResolver), node.Comment)); + } + + n = rx.GetMetadataEnumerator(); + while (n.MoveNext()) { + ResXDataNode node = (ResXDataNode) n.Value; + metadataItems.Add(new ResourceItem(this, node.Name, node.GetValue(typeResolver))); + } + + rx.Close(); + break; + case ".resources": + ResourceReader rr = null; + try { + rr = new ResourceReader(stream); + foreach (DictionaryEntry entry in rr) { + resourceItems.Add(new ResourceItem(this, entry.Key.ToString(), entry.Value)); + } + } finally { + if (rr != null) { + rr.Close(); + } + } + break; + } + + EndUpdate(); + } + + public void SaveFile(FileName filename, Stream stream) + { + switch (Path.GetExtension(filename).ToLowerInvariant()) { + case ".resx": + // write XML resource + ResXResourceWriter rxw = new ResXResourceWriter(stream, t => ResXConverter.ConvertTypeName(t, filename)); + foreach (ResourceItem entry in resourceItems) { + if (entry != null) { + rxw.AddResource(entry.ToResXDataNode(t => ResXConverter.ConvertTypeName(t, filename))); + } + } + foreach (ResourceItem entry in metadataItems) { + if (entry != null) { + rxw.AddMetadata(entry.Name, entry.ResourceValue); + } + } + rxw.Generate(); + rxw.Close(); + break; + default: + // write default resource + ResourceWriter rw = new ResourceWriter(stream); + foreach (ResourceItem entry in resourceItems) { + rw.AddResource(entry.Name, entry.ResourceValue); + } + rw.Generate(); + rw.Close(); + break; + } + } + + #region Standard clipboard commands + + public bool EnableCut { + get { + return SelectedItems.Count > 0; + } + } + + public bool EnableCopy { + get { + return SelectedItems.Count > 0; + } + } + + public bool EnablePaste { + get { + return true; + } + } + + public bool EnableDelete { + get { + return SelectedItems.Count > 0; + } + } + + public bool EnableSelectAll { + get { + return true; + } + } + + public void Cut() + { + // if (resourceEditor.ResourceList.WriteProtected || resourceEditor.ResourceList.SelectedItems.Count < 1) + // return; + if (SelectedItems.Count == 0) + return; + + Hashtable tmphash = new Hashtable(); + foreach (var selectedItem in SelectedItems.OfType().ToList()) { + tmphash.Add(selectedItem.Name, selectedItem.ResourceValue); + resourceItems.Remove(selectedItem); + } + SD.Clipboard.SetDataObject(tmphash); + } + + public void Copy() + { + if (SelectedItems.Count == 0) + return; + + Hashtable tmphash = new Hashtable(); + foreach (var selectedItem in SelectedItems.OfType().ToList()) { + object resourceValue = GetClonedResource(selectedItem.ResourceValue); + tmphash.Add(selectedItem.Name, resourceValue); + } + SD.Clipboard.SetDataObject(tmphash); + } + + public void Paste() + { + // if (resourceEditor.ResourceList.WriteProtected) { + // return; + // } + + IDataObject dob = Clipboard.GetDataObject(); + if (dob == null) + return; + + if (dob.GetDataPresent(typeof(Hashtable).FullName)) { + Hashtable tmphash = (Hashtable) dob.GetData(typeof(Hashtable)); + foreach (DictionaryEntry entry in tmphash) { + object resourceValue = GetClonedResource(entry.Value); + ResourceItem item; + + if (!resourceItemNames.Contains((string) entry.Key)) { + item = new ResourceItem(this, entry.Key.ToString(), resourceValue); + } else { + int count = 1; + string newNameBase = entry.Key + " "; + string newName = newNameBase + count; + + while (resourceItemNames.Contains(newName)) { + count++; + newName = newNameBase + count; + } + item = new ResourceItem(this, newName, resourceValue); + } + resourceItems.Add(item); + // TODO Set selection to new element? + } + } + } + + /// + /// Clones a resource if the + /// is cloneable. + /// + /// A resource to clone. + /// A cloned resource if the object implements + /// the ICloneable interface, otherwise the + /// object. + object GetClonedResource(object resource) + { + object clonedResource = null; + + ICloneable cloneableResource = resource as ICloneable; + if (cloneableResource != null) { + clonedResource = cloneableResource.Clone(); + } else { + clonedResource = resource; + } + + return clonedResource; + } + + public void Delete() + { +// if (resourceList.WriteProtected || resourceList.SelectedItems.Count == 0) +// return; + + if (SelectedItems.Count > 0) { + if (!SD.MessageService.AskQuestion("${res:ResourceEditor.DeleteEntry.Confirm}", "${res:ResourceEditor.DeleteEntry.Title}")) + return; + + foreach (var item in SelectedItems.OfType().ToList()) { + resourceItems.Remove(item); + } + } + } + + public void SelectAll() + { + longUpdateRunning = true; + foreach (var i in resourceItems) + SelectedItems.Add(i); + longUpdateRunning = false; + } + + #endregion + } +} diff --git a/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/ViewModels/ResourceItem.cs b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/ViewModels/ResourceItem.cs new file mode 100644 index 0000000000..a5e3ada11b --- /dev/null +++ b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/ViewModels/ResourceItem.cs @@ -0,0 +1,245 @@ +// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.ComponentModel; +using System.Drawing; +using System.Resources; +using System.Windows; +using System.Windows.Forms; +using ICSharpCode.SharpDevelop; + +namespace ResourceEditor.ViewModels +{ + /// + /// Defines the type of resource item supported by editor. + /// + public enum ResourceItemEditorType + { + Unknown, + String, + Boolean, + Bitmap, + Icon, + Cursor, + Binary + } + + public class ResourceItem : DependencyObject + { + ResourceItemEditorType resourceType; + ResourceEditorViewModel resourceEditor; + string nameBeforeEditing; + + public ResourceItem(ResourceEditorViewModel resourceEditor, string name, object resourceValue) + { + this.resourceEditor = resourceEditor; + this.Name = name; + this.ResourceValue = resourceValue; + this.resourceType = GetResourceTypeFromValue(resourceValue); + } + + public ResourceItem(ResourceEditorViewModel resourceEditor, string name, object resourceValue, string comment) + { + this.resourceEditor = resourceEditor; + this.Name = name; + this.ResourceValue = resourceValue; + this.resourceType = GetResourceTypeFromValue(resourceValue); + this.Comment = comment; + } + + public static readonly DependencyProperty NameProperty = + DependencyProperty.Register("Name", typeof(string), typeof(ResourceItem), + new FrameworkPropertyMetadata()); + + public string Name { + get { return (string)GetValue(NameProperty); } + set { SetValue(NameProperty, value); } + } + + public static readonly DependencyProperty ResourceValueProperty = + DependencyProperty.Register("ResourceValue", typeof(object), typeof(ResourceItem), + new FrameworkPropertyMetadata()); + + public object ResourceValue { + get { return (object)GetValue(ResourceValueProperty); } + set { SetValue(ResourceValueProperty, value); } + } + + public string DisplayedResourceType { + get { + return ResourceValue == null ? "(Nothing/null)" : ResourceValue.GetType().FullName; + } + } + + public ResourceItemEditorType ResourceType { + get { + return resourceType; + } + } + + public static readonly DependencyProperty IsEditingProperty = + DependencyProperty.Register("IsEditing", typeof(bool), typeof(ResourceItem), + new FrameworkPropertyMetadata()); + + public bool IsEditing { + get { return (bool)GetValue(IsEditingProperty); } + set { SetValue(IsEditingProperty, value); } + } + + protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) + { + base.OnPropertyChanged(e); + + if (e.Property == IsEditingProperty) { + bool previouslyEditing = (bool)e.OldValue; + bool isEditing = (bool)e.NewValue; + if (!previouslyEditing && isEditing) { + // Save initial name to compare it later on cancellation + nameBeforeEditing = Name; + } else if (previouslyEditing && !isEditing) { + // Make dirty, if name has changed after finishing edit + if (nameBeforeEditing != Name) { + // Check if new name is valid + if (!String.IsNullOrEmpty(Name) && !resourceEditor.ContainsResourceName(Name)) { + resourceEditor.MakeDirty(); + } else { + // New name was not valid, revert it to the value before editing + Name = nameBeforeEditing; + } + } + } + } else { + resourceEditor.MakeDirty(); + } + } + + ResourceItemEditorType GetResourceTypeFromValue(object val) + { + if (this.ResourceValue == null) { + return ResourceItemEditorType.Unknown; + } + switch (this.ResourceValue.GetType().ToString()) { + case "System.String": + return ResourceItemEditorType.String; + case "System.Drawing.Bitmap": + return ResourceItemEditorType.Bitmap; + case "System.Drawing.Icon": + return ResourceItemEditorType.Icon; + case "System.Windows.Forms.Cursor": + return ResourceItemEditorType.Cursor; + case "System.Byte[]": + return ResourceItemEditorType.Binary; + case "System.Boolean": + return ResourceItemEditorType.Boolean; + default: + return ResourceItemEditorType.Unknown; + } + } + + public string Content { + get { + return ToString(); + } + } + + public static readonly DependencyProperty CommentProperty = + DependencyProperty.Register("Comment", typeof(string), typeof(ResourceItem), + new FrameworkPropertyMetadata()); + + public string Comment { + get { return (string)GetValue(CommentProperty); } + set { SetValue(CommentProperty, value); } + } + + public override string ToString() + { + if (ResourceValue == null) { + return "(Nothing/null)"; + } + + string type = ResourceValue.GetType().FullName; + string tmp = String.Empty; + + switch (type) { + case "System.String": + tmp = ResourceValue.ToString(); + break; + case "System.Byte[]": + tmp = "[Size = " + ((byte[])ResourceValue).Length + "]"; + break; + case "System.Drawing.Bitmap": + Bitmap bmp = ResourceValue as Bitmap; + tmp = "[Width = " + bmp.Size.Width + ", Height = " + bmp.Size.Height + "]"; + break; + case "System.Drawing.Icon": + Icon icon = ResourceValue as Icon; + tmp = "[Width = " + icon.Size.Width + ", Height = " + icon.Size.Height + "]"; + break; + case "System.Windows.Forms.Cursor": + Cursor c = ResourceValue as Cursor; + tmp = "[Width = " + c.Size.Width + ", Height = " + c.Size.Height + "]"; + break; + case "System.Boolean": + tmp = ResourceValue.ToString(); + break; + default: + tmp = ResourceValue.ToString(); + break; + } + return tmp; + } + + public ResXDataNode ToResXDataNode(Func typeNameConverter = null) + { + var node = new ResXDataNode(Name, ResourceValue, typeNameConverter) { + Comment = Comment + }; + return node; + } + + public bool UpdateFromFile() + { + var fileDialog = new Microsoft.Win32.OpenFileDialog(); + fileDialog.AddExtension = true; + fileDialog.Filter = "All files (*.*)|*.*"; + fileDialog.CheckFileExists = true; + + if (fileDialog.ShowDialog().Value) { + object newValue = null; + switch (resourceType) { + case ResourceItemEditorType.Bitmap: + try { + newValue = new Bitmap(fileDialog.FileName); + } catch { + SD.MessageService.ShowWarning("Can't load bitmap file."); + return false; + } + break; + } + + if (newValue != null) { + ResourceValue = newValue; + return true; + } + } + + return false; + } + } +} diff --git a/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Views/BinaryView.xaml b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Views/BinaryView.xaml new file mode 100644 index 0000000000..bbf7b5621b --- /dev/null +++ b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Views/BinaryView.xaml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Views/BinaryView.xaml.cs b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Views/BinaryView.xaml.cs new file mode 100644 index 0000000000..cc310d86ec --- /dev/null +++ b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Views/BinaryView.xaml.cs @@ -0,0 +1,41 @@ +// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections.Generic; +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; + +namespace ResourceEditor.Views +{ + /// + /// Interaction logic for BinaryView.xaml + /// + public partial class BinaryView : UserControl + { + public BinaryView() + { + InitializeComponent(); + } + } +} \ No newline at end of file diff --git a/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Views/BooleanView.xaml b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Views/BooleanView.xaml new file mode 100644 index 0000000000..fb14f41549 --- /dev/null +++ b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Views/BooleanView.xaml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Views/BooleanView.xaml.cs b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Views/BooleanView.xaml.cs new file mode 100644 index 0000000000..f5055919ac --- /dev/null +++ b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Views/BooleanView.xaml.cs @@ -0,0 +1,41 @@ +// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections.Generic; +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; + +namespace ResourceEditor.Views +{ + /// + /// Interaction logic for BooleanView.xaml + /// + public partial class BooleanView : UserControl + { + public BooleanView() + { + InitializeComponent(); + } + } +} \ No newline at end of file diff --git a/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Views/IResourceEditorView.cs b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Views/IResourceEditorView.cs new file mode 100644 index 0000000000..b7a4d4e7b7 --- /dev/null +++ b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Views/IResourceEditorView.cs @@ -0,0 +1,58 @@ +// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this +// software and associated documentation files (the "Software"), to deal in the Software +// without restriction, including without limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons +// to whom the Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or +// substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE +// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Windows; +using System.Windows.Input; + +namespace ResourceEditor.Views +{ + /// + /// Base interface for resource editor main views. + /// + public interface IResourceEditorView + { + CommandBindingCollection CommandBindings { + get; + } + + event EventHandler SelectionChanged; + IList SelectedItems { + get; + } + + event EventHandler EditingStarted; + event EventHandler EditingFinished; + event EventHandler EditingCancelled; + + void SetItemView(IResourceItemView view); + + object DataContext { + get; + set; + } + + Predicate FilterPredicate { + get; + set; + } + } +} diff --git a/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/ClipboardCommands.cs b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Views/IResourceItemView.cs similarity index 80% rename from src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/ClipboardCommands.cs rename to src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Views/IResourceItemView.cs index 835846c92f..9e8a7a9163 100644 --- a/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Commands/ClipboardCommands.cs +++ b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Views/IResourceItemView.cs @@ -16,21 +16,18 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. + using System; -using ICSharpCode.Core; -using ICSharpCode.SharpDevelop; +using System.Windows; -namespace ResourceEditor +namespace ResourceEditor.Views { - - class SelectAllCommand : AbstractMenuCommand + /// + /// Interface for resource item views. + /// + public interface IResourceItemView { - public override void Run() - { - ResourceEditWrapper editor = (ResourceEditWrapper)SD.Workbench.ActiveViewContent; - - editor.SelectAll(); - } + ResourceEditor.ViewModels.ResourceItem ResourceItem { get; set; } + FrameworkElement UIControl { get; } } - } diff --git a/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Views/ImageViewBase.xaml b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Views/ImageViewBase.xaml new file mode 100644 index 0000000000..782a0202e3 --- /dev/null +++ b/src/AddIns/DisplayBindings/ResourceEditor/Project/Src/Views/ImageViewBase.xaml @@ -0,0 +1,19 @@ + + + + + + + +