diff options
author | Lluis Sanchez <llsan@microsoft.com> | 2019-02-16 15:01:45 +0300 |
---|---|---|
committer | Lluis Sanchez <llsan@microsoft.com> | 2019-02-18 15:16:02 +0300 |
commit | eb8ee9fcd25dbd3cda9536419d888d86dfd1801c (patch) | |
tree | 482d02e334947957061dd1d4c50a60bca4259e40 /main/src/addins/MonoDevelop.HexEditor | |
parent | 90f99e5e9dc6ab82669a7387aad5c0ec5d3695b3 (diff) |
Implemented hex editor as a document controller
Diffstat (limited to 'main/src/addins/MonoDevelop.HexEditor')
14 files changed, 197 insertions, 406 deletions
diff --git a/main/src/addins/MonoDevelop.HexEditor/Mono.MHex.Data/Buffer.cs b/main/src/addins/MonoDevelop.HexEditor/Mono.MHex.Data/Buffer.cs index 31f8c29d7a..04865de09c 100644 --- a/main/src/addins/MonoDevelop.HexEditor/Mono.MHex.Data/Buffer.cs +++ b/main/src/addins/MonoDevelop.HexEditor/Mono.MHex.Data/Buffer.cs @@ -35,10 +35,7 @@ namespace Mono.MHex.Data long Length { get; } - byte[] Bytes { - get; - } - + byte[] GetBytes (long offset, int count); } diff --git a/main/src/addins/MonoDevelop.HexEditor/Mono.MHex.Data/HexEditorData.cs b/main/src/addins/MonoDevelop.HexEditor/Mono.MHex.Data/HexEditorData.cs index 091e09268b..04233c1cf6 100644 --- a/main/src/addins/MonoDevelop.HexEditor/Mono.MHex.Data/HexEditorData.cs +++ b/main/src/addins/MonoDevelop.HexEditor/Mono.MHex.Data/HexEditorData.cs @@ -32,198 +32,179 @@ namespace Mono.MHex.Data { class HexEditorData { + ByteBuffer byteBuffer; + PieceTable pieceTable = new PieceTable (); + + public event EventHandler<UndoOperationEventArgs> Undone; + public event EventHandler<UndoOperationEventArgs> Redone; + public event EventHandler Changed; + + public ByteBuffer ByteBuffer { + get => byteBuffer; + set { + if (byteBuffer != value) { + if (byteBuffer != null) + UnsubscribeBufferEvents (); + byteBuffer = value; + if (byteBuffer != null) + SubscribeBufferEvents (); + OnChanged (); + } + } + } + public ScrollAdjustment HAdjustment { get; set; } - + public ScrollAdjustment VAdjustment { get; set; } - + public Caret Caret { get; private set; } - + public int BytesInRow { get; set; } - + public double LineHeight { get; set; } - + public EditMode EditMode { get; set; } - + List<long> bookmarks = new List<long> (); public List<long> Bookmarks { get { return bookmarks; } } - + public long Length { get { - return pieceTable.Length; + return ByteBuffer.Length; } } - - public byte[] Bytes { + + public byte [] Bytes { get { - return GetBytes (0, (int)Length); + return ByteBuffer.GetBytes (0, (int)Length); } } - - public byte[] GetBytes (long offset, int count) + + public byte [] GetBytes (long offset, int count) { - if (count == 0) - return new byte[0]; - var node = pieceTable.GetTreeNodeAtOffset (offset); - if (node == null) - return new byte[0]; - long nodeOffset = node.value.CalcOffset (node); - long nodeEndOffset = nodeOffset + node.value.Length; - if (offset + count < nodeEndOffset) - return node.value.GetBytes (this, nodeOffset, offset, count); - byte[] nodeBytes = node.value.GetBytes (this, nodeOffset, offset, (int)(nodeEndOffset - offset)); - - byte[] result = new byte[count]; - if (nodeBytes.Length > 0) { - nodeBytes.CopyTo (result, 0); - GetBytes (offset + nodeBytes.Length, count - nodeBytes.Length).CopyTo (result, nodeBytes.Length); - } - return result; + return ByteBuffer.GetBytes (offset, count); } - + public byte GetByte (long offset) { - return GetBytes (offset, 1)[0]; + return ByteBuffer.GetBytes (offset, 1) [0]; } - + public HexEditorData () { + ByteBuffer = new ByteBuffer (); Caret = new Caret (this); VAdjustment = new ScrollAdjustment (); HAdjustment = new ScrollAdjustment (); } - - PieceTable pieceTable = new PieceTable (); - internal IBuffer buffer; - + + void SubscribeBufferEvents () + { + byteBuffer.Undone += ByteBuffer_Undone; + byteBuffer.Redone += ByteBuffer_Redone; + byteBuffer.Replaced += ByteBuffer_Replaced; + } + + void UnsubscribeBufferEvents () + { + byteBuffer.Undone -= ByteBuffer_Undone; + byteBuffer.Redone -= ByteBuffer_Redone; + byteBuffer.Replaced -= ByteBuffer_Replaced; + } + + void ByteBuffer_Undone (object sender, UndoOperationEventArgs e) + { + Caret.Offset = e.BufferOffset; + Undone?.Invoke (this, e); + } + + void ByteBuffer_Redone (object sender, UndoOperationEventArgs e) + { + Caret.Offset = e.BufferOffset; + Redone?.Invoke (this, e); + } + + void ByteBuffer_Replaced (object sender, ReplaceEventArgs e) + { + OnChanged (); + } + + void OnChanged () + { + Changed?.Invoke (this, EventArgs.Empty); + } + public IBuffer Buffer { - get { - return this.buffer; + get { + return ByteBuffer.Buffer; } - set { - this.buffer = value; - pieceTable.SetBuffer (buffer); + set { + ByteBuffer.Buffer = value; OnBufferChanged (EventArgs.Empty); } } - - internal List<byte> addBuffer = new List<byte> (); - + protected virtual void OnBufferChanged (EventArgs e) { EventHandler handler = this.BufferChanged; if (handler != null) handler (this, e); } - + public event EventHandler BufferChanged; - - public void Replace (long offset, long count, params byte[] data) - { - if (!isInUndo) - BeginAtomicUndo (); - if (count > 0) - pieceTable.Remove (offset, count); - if (data != null && data.Length > 0) { - int addBufferOffset = addBuffer.Count; - long length = data.Length; - addBuffer.AddRange (data); - pieceTable.Insert (offset, addBufferOffset, length); - } - OnReplaced (new ReplaceEventArgs (offset, count, data)); - if (!isInUndo) - EndAtomicUndo (); - } - - public void Insert (long offset, params byte[] data) - { - if (!isInUndo) - BeginAtomicUndo (); - int addBufferOffset = addBuffer.Count; - long length = data.Length; - addBuffer.AddRange (data); - pieceTable.Insert (offset, addBufferOffset, length); - OnReplaced (new ReplaceEventArgs (offset, 0, data)); - if (!isInUndo) - EndAtomicUndo (); - } - - public void Remove (ISegment segment) - { - Remove (segment.Offset, segment.Length); - } - - public void Remove (long offset, long count) - { - if (!isInUndo) - BeginAtomicUndo (); - pieceTable.Remove (offset, count); - OnReplaced (new ReplaceEventArgs (offset, count, null)); - if (!isInUndo) - EndAtomicUndo (); - if (Length == 0) - Insert (0, new byte[] {0}); - } - + public void UpdateLine (long line) { Updates.Add (new LineUpdateRequest (line)); OnUpdateRequested (EventArgs.Empty); } - + public void UpdateMargin (Type marginType, long line) { Updates.Add (new MarginLineUpdateRequest (marginType, line)); OnUpdateRequested (EventArgs.Empty); } - + internal List<UpdateRequest> Updates = new List<UpdateRequest> (); - + protected virtual void OnUpdateRequested (EventArgs e) { EventHandler handler = this.UpdateRequested; if (handler != null) handler (this, e); } - + public event EventHandler UpdateRequested; - - protected virtual void OnReplaced (ReplaceEventArgs args) - { - if (Replaced != null) - Replaced (this, args); - } - - public event EventHandler<ReplaceEventArgs> Replaced; - + #region Selection public bool IsSomethingSelected { get { - return MainSelection != null && MainSelection.Anchor != MainSelection.Lead; + return MainSelection != null && MainSelection.Anchor != MainSelection.Lead; } } - + public SelectionMode SelectionMode { get { return MainSelection != null ? MainSelection.SelectionMode : SelectionMode.Normal; @@ -232,7 +213,7 @@ namespace Mono.MHex.Data MainSelection.SelectionMode = value; } } - + Selection mainSelection = null; public Selection MainSelection { get { @@ -252,7 +233,7 @@ namespace Mono.MHex.Data } } } - + public void ClearSelection () { if (!this.IsSomethingSelected) @@ -260,14 +241,14 @@ namespace Mono.MHex.Data MainSelection = null; OnSelectionChanged (EventArgs.Empty); } - + public void SetSelection (long anchor, long lead) { anchor = System.Math.Min (Length, System.Math.Max (0, anchor)); lead = System.Math.Min (Length, System.Math.Max (0, lead)); MainSelection = new Selection (anchor, lead); } - + public void DeleteSelection () { if (!this.IsSomethingSelected) @@ -275,182 +256,32 @@ namespace Mono.MHex.Data long start = MainSelection.Segment.Offset; switch (MainSelection.SelectionMode) { case SelectionMode.Normal: - Remove (MainSelection.Segment); + ByteBuffer.Remove (MainSelection.Segment); break; case SelectionMode.Block: throw new NotImplementedException (); } - + MainSelection = null; Caret.Offset = start; OnSelectionChanged (EventArgs.Empty); - + } - + public void ExtendSelectionTo (long offset) { offset = System.Math.Min (Length, System.Math.Max (0, offset)); - if (MainSelection == null) + if (MainSelection == null) MainSelection = new Selection (offset, offset); MainSelection.Lead = offset; } - + public event EventHandler SelectionChanged; protected virtual void OnSelectionChanged (EventArgs args) { - if (SelectionChanged != null) + if (SelectionChanged != null) SelectionChanged (this, args); } #endregion - - #region Undo/Redo - public class CaretPosition - { - long Offset { - get; - set; - } - int SubPosition { - get; - set; - } - - public CaretPosition (Caret caret) - { - Offset = caret.Offset; - SubPosition = caret.SubPosition; - } - - public void Set (Caret caret) - { - caret.Offset = Offset; - caret.SubPosition = SubPosition; - } - } - - public class UndoOperation - { - internal RedBlackTree<PieceTable.TreeNode>.RedBlackTreeNode undoNode; - internal CaretPosition undoCaret; - - internal RedBlackTree<PieceTable.TreeNode>.RedBlackTreeNode redoNode; - internal CaretPosition redoCaret; - - public UndoOperation() - { - } - - public virtual void Undo (HexEditorData data) - { - if (undoNode == null) - throw new NullReferenceException ("undoNode == null"); - data.pieceTable.tree.Root = undoNode; - undoCaret.Set (data.Caret); - } - - public virtual void Redo (HexEditorData data) - { - if (redoNode == null) - throw new NullReferenceException ("redoNode == null"); - data.pieceTable.tree.Root = redoNode; - redoCaret.Set (data.Caret); - } - } - - Stack<UndoOperation> undoStack = new Stack<UndoOperation> (); - Stack<UndoOperation> redoStack = new Stack<UndoOperation> (); - UndoOperation currentAtomicOperation; - - public bool EnableUndo { - get { - return undoStack.Count > 0; - } - } - - public bool EnableRedo { - get { - return redoStack.Count > 0; - } - } - - bool isInUndo = false; - int atomicUndoLevel; - public void BeginAtomicUndo () - { - if (currentAtomicOperation == null) { - currentAtomicOperation = new UndoOperation (); - currentAtomicOperation.undoNode = pieceTable.tree.Root.Clone (); - currentAtomicOperation.undoCaret = new CaretPosition (Caret); - } - atomicUndoLevel++; - } - - public void EndAtomicUndo () - { - atomicUndoLevel--; - - if (atomicUndoLevel == 0 && currentAtomicOperation != null) { - currentAtomicOperation.redoNode = pieceTable.tree.Root.Clone (); - currentAtomicOperation.redoCaret = new CaretPosition (Caret); - undoStack.Push (currentAtomicOperation); - redoStack.Clear (); - currentAtomicOperation = null; - } - } - public class UndoOperationEventArgs : EventArgs - { - public UndoOperation Operation { - get; - private set; - } - - public UndoOperationEventArgs (UndoOperation operation) - { - this.Operation = operation; - } - } - public void Undo () - { - if (undoStack.Count <= 0) - return; - isInUndo = true; - UndoOperation operation = undoStack.Pop (); - operation.Undo (this); - redoStack.Push (operation); - isInUndo = false; - OnUndone (new UndoOperationEventArgs (operation)); - } - - internal protected virtual void OnUndone (UndoOperationEventArgs e) - { - EventHandler<UndoOperationEventArgs> handler = this.Undone; - if (handler != null) - handler (this, e); - } - - public event EventHandler<UndoOperationEventArgs> Undone; - - public void Redo () - { - if (redoStack.Count <= 0) - return; - isInUndo = true; - UndoOperation operation = redoStack.Pop (); - operation.Redo (this); - undoStack.Push (operation); - isInUndo = false; - OnRedone (new UndoOperationEventArgs (operation)); - } - - internal protected virtual void OnRedone (UndoOperationEventArgs e) - { - EventHandler<UndoOperationEventArgs> handler = this.Redone; - if (handler != null) - handler (this, e); - } - - public event EventHandler<UndoOperationEventArgs> Redone; - - #endregion } } diff --git a/main/src/addins/MonoDevelop.HexEditor/Mono.MHex.Data/ISegment.cs b/main/src/addins/MonoDevelop.HexEditor/Mono.MHex.Data/ISegment.cs index 8b41958b10..96c261b748 100644 --- a/main/src/addins/MonoDevelop.HexEditor/Mono.MHex.Data/ISegment.cs +++ b/main/src/addins/MonoDevelop.HexEditor/Mono.MHex.Data/ISegment.cs @@ -28,7 +28,7 @@ using System; namespace Mono.MHex.Data { - interface ISegment + public interface ISegment { long Offset { get; diff --git a/main/src/addins/MonoDevelop.HexEditor/Mono.MHex.Data/PieceTable.cs b/main/src/addins/MonoDevelop.HexEditor/Mono.MHex.Data/PieceTable.cs index 7b8696cccd..7c3de43a3d 100644 --- a/main/src/addins/MonoDevelop.HexEditor/Mono.MHex.Data/PieceTable.cs +++ b/main/src/addins/MonoDevelop.HexEditor/Mono.MHex.Data/PieceTable.cs @@ -63,7 +63,7 @@ namespace Mono.MHex.Data this.Length = length; } - public abstract byte[] GetBytes (HexEditorData hexEditorData, long myOffset, long offset, int count); + public abstract byte[] GetBytes (ByteBuffer byteBuffer, long myOffset, long offset, int count); public TreeNode SplitRight (long leftLength) { @@ -85,9 +85,9 @@ namespace Mono.MHex.Data this.BufferOffset = bufferOffset; } - public override byte[] GetBytes (HexEditorData hexEditorData, long myOffset, long offset, int count) + public override byte[] GetBytes (ByteBuffer byteBuffer, long myOffset, long offset, int count) { - return hexEditorData.buffer.GetBytes (BufferOffset + offset - myOffset, count); + return byteBuffer.Buffer.GetBytes (BufferOffset + offset - myOffset, count); } protected override TreeNode InternalSplitRight (long leftLength) @@ -120,13 +120,9 @@ namespace Mono.MHex.Data this.AddBufferOffset = addBufferOffset; } - public override byte[] GetBytes (HexEditorData hexEditorData, long myOffset, long offset, int count) + public override byte[] GetBytes (ByteBuffer byteBuffer, long myOffset, long offset, int count) { - byte[] result = new byte[count]; - for (int i = 0, j = (int)(AddBufferOffset + offset - myOffset); i < result.Length; i++, j++) { - result[i] = hexEditorData.addBuffer [j]; - } - return result; + return byteBuffer.AddBuffer.GetBytes (AddBufferOffset + offset - myOffset, count); } protected override TreeNode InternalSplitRight (long leftLength) diff --git a/main/src/addins/MonoDevelop.HexEditor/Mono.MHex.Data/ReplaceEventArgs.cs b/main/src/addins/MonoDevelop.HexEditor/Mono.MHex.Data/ReplaceEventArgs.cs index 42afd72741..dbeff4c8bd 100644 --- a/main/src/addins/MonoDevelop.HexEditor/Mono.MHex.Data/ReplaceEventArgs.cs +++ b/main/src/addins/MonoDevelop.HexEditor/Mono.MHex.Data/ReplaceEventArgs.cs @@ -28,7 +28,7 @@ using System; namespace Mono.MHex.Data { - class ReplaceEventArgs : System.EventArgs + public class ReplaceEventArgs : System.EventArgs { public long Offset { get; diff --git a/main/src/addins/MonoDevelop.HexEditor/Mono.MHex/DeleteActions.cs b/main/src/addins/MonoDevelop.HexEditor/Mono.MHex/DeleteActions.cs index 63e33ac18b..3c55e2c6fd 100644 --- a/main/src/addins/MonoDevelop.HexEditor/Mono.MHex/DeleteActions.cs +++ b/main/src/addins/MonoDevelop.HexEditor/Mono.MHex/DeleteActions.cs @@ -39,7 +39,7 @@ namespace Mono.MHex } if (data.Caret.Offset == 0) return; - data.Remove (data.Caret.Offset - 1, 1); + data.ByteBuffer.Remove (data.Caret.Offset - 1, 1); data.Caret.Offset--; } @@ -51,7 +51,7 @@ namespace Mono.MHex } if (data.Caret.Offset >= data.Length) return; - data.Remove (data.Caret.Offset, 1); + data.ByteBuffer.Remove (data.Caret.Offset, 1); data.UpdateLine (data.Caret.Line); } } diff --git a/main/src/addins/MonoDevelop.HexEditor/Mono.MHex/HexEditor.cs b/main/src/addins/MonoDevelop.HexEditor/Mono.MHex/HexEditor.cs index c6bf1290fc..febad60b57 100644 --- a/main/src/addins/MonoDevelop.HexEditor/Mono.MHex/HexEditor.cs +++ b/main/src/addins/MonoDevelop.HexEditor/Mono.MHex/HexEditor.cs @@ -140,11 +140,9 @@ namespace Mono.MHex Repaint (); }; HexEditorData.SelectionChanged += HexEditorDataSelectionChanged; - HexEditorData.Replaced += delegate(object sender, ReplaceEventArgs e) { - if (e.Count > 0) { - PurgeLayoutCaches (); - Repaint (); - } + HexEditorData.Changed += delegate { + PurgeLayoutCaches (); + Repaint (); }; style = new HexEditorStyle (); diff --git a/main/src/addins/MonoDevelop.HexEditor/Mono.MHex/MiscActions.cs b/main/src/addins/MonoDevelop.HexEditor/Mono.MHex/MiscActions.cs index 282df176bd..02175895d8 100644 --- a/main/src/addins/MonoDevelop.HexEditor/Mono.MHex/MiscActions.cs +++ b/main/src/addins/MonoDevelop.HexEditor/Mono.MHex/MiscActions.cs @@ -39,12 +39,12 @@ namespace Mono.MHex public static void Undo (HexEditorData data) { - data.Undo (); + data.ByteBuffer.Undo (); } public static void Redo (HexEditorData data) { - data.Redo (); + data.ByteBuffer.Redo (); } } } diff --git a/main/src/addins/MonoDevelop.HexEditor/Mono.MHex/SimpleEditMode.cs b/main/src/addins/MonoDevelop.HexEditor/Mono.MHex/SimpleEditMode.cs index 29db8e9ab0..a24ffe9f77 100644 --- a/main/src/addins/MonoDevelop.HexEditor/Mono.MHex/SimpleEditMode.cs +++ b/main/src/addins/MonoDevelop.HexEditor/Mono.MHex/SimpleEditMode.cs @@ -198,9 +198,9 @@ namespace Mono.MHex if (HexEditorData.Caret.InTextEditor) { if ((char.IsLetterOrDigit (ch) || char.IsPunctuation (ch) || ch == ' ') && unicodeChar <= 255) { if (HexEditorData.Caret.IsInsertMode) { - HexEditorData.Insert (HexEditorData.Caret.Offset, (byte)unicodeChar); + HexEditorData.ByteBuffer.Insert (HexEditorData.Caret.Offset, (byte)unicodeChar); } else { - HexEditorData.Replace (HexEditorData.Caret.Offset, 1, (byte)unicodeChar); + HexEditorData.ByteBuffer.Replace (HexEditorData.Caret.Offset, 1, (byte)unicodeChar); } Editor.Margins.ForEach (margin => margin.PurgeLayoutCache ()); CaretMoveActions.Right (HexEditorData); @@ -210,13 +210,13 @@ namespace Mono.MHex int idx = hex.IndexOf (char.ToUpper (ch)); if (idx >= 0) { if (HexEditorData.Caret.Offset >= HexEditorData.Length) - HexEditorData.Insert (HexEditorData.Length, 0); + HexEditorData.ByteBuffer.Insert (HexEditorData.Length, 0); if (HexEditorData.Caret.IsInsertMode && HexEditorData.Caret.SubPosition == 0) { - HexEditorData.Insert (HexEditorData.Caret.Offset, (byte)(idx * 0x10)); + HexEditorData.ByteBuffer.Insert (HexEditorData.Caret.Offset, (byte)(idx * 0x10)); } else { byte cur = HexEditorData.GetByte (HexEditorData.Caret.Offset); int newByte = HexEditorData.Caret.SubPosition == 0 ? cur & 0xF | idx * 0x10 : cur & 0xF0 | idx; - HexEditorData.Replace (HexEditorData.Caret.Offset, 1, (byte)newByte); + HexEditorData.ByteBuffer.Replace (HexEditorData.Caret.Offset, 1, (byte)newByte); } Editor.Margins.ForEach (margin => margin.PurgeLayoutCache ()); CaretMoveActions.Right (HexEditorData); diff --git a/main/src/addins/MonoDevelop.HexEditor/MonoDevelop.HexEditor.addin.xml b/main/src/addins/MonoDevelop.HexEditor/MonoDevelop.HexEditor.addin.xml index 16f966780b..b88ac38199 100644 --- a/main/src/addins/MonoDevelop.HexEditor/MonoDevelop.HexEditor.addin.xml +++ b/main/src/addins/MonoDevelop.HexEditor/MonoDevelop.HexEditor.addin.xml @@ -4,12 +4,6 @@ <Command id = "MonoDevelop.HexEditor.Commands.ShowHexEditor" _label = "Open with _hex editor" /> </Extension> --> - <Extension path = "/MonoDevelop/Ide/DisplayBindings"> - <DisplayBinding - id = "HexEditor" - insertafter ="AssemblyBrowser" - class = "MonoDevelop.HexEditor.HexEditorDisplayBinding" /> - </Extension> <!-- <Extension path = "/MonoDevelop/Ide/Pads/ProjectPad"> <NodeBuilder id = "HexEditorNodeExtension" class = "MonoDevelop.HexEditor.HexEditorNodeExtension"/> diff --git a/main/src/addins/MonoDevelop.HexEditor/MonoDevelop.HexEditor.csproj b/main/src/addins/MonoDevelop.HexEditor/MonoDevelop.HexEditor.csproj index 197ce48210..a2ffa3c2dd 100644 --- a/main/src/addins/MonoDevelop.HexEditor/MonoDevelop.HexEditor.csproj +++ b/main/src/addins/MonoDevelop.HexEditor/MonoDevelop.HexEditor.csproj @@ -49,13 +49,14 @@ <Compile Include="Mono.MHex\HexEditorOptions.cs" /> <Compile Include="Mono.MHex\DeleteActions.cs" /> <Compile Include="Mono.MHex.Data\ReplaceEventArgs.cs" /> - <Compile Include="MonoDevelop.HexEditor\DisplayBinding.cs" /> <Compile Include="MonoDevelop.HexEditor\HexEditorView.cs" /> <Compile Include="MonoDevelop.HexEditor\MonoDevelopHexEditorStyle.cs" /> <Compile Include="MonoDevelop.HexEditor\HexEditorNodeExtension.cs" /> <Compile Include="AddinInfo.cs" /> <Compile Include="MonoDevelop.HexEditor\HexEditorVisualizer.cs" /> <Compile Include="Mono.MHex\HexEditorDebugger.cs" /> + <Compile Include="Mono.MHex.Data\ByteBufferModel.cs" /> + <Compile Include="Mono.MHex.Data\ByteBuffer.cs" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..\..\core\MonoDevelop.Core\MonoDevelop.Core.csproj"> diff --git a/main/src/addins/MonoDevelop.HexEditor/MonoDevelop.HexEditor/DisplayBinding.cs b/main/src/addins/MonoDevelop.HexEditor/MonoDevelop.HexEditor/DisplayBinding.cs deleted file mode 100644 index 11c6c884fc..0000000000 --- a/main/src/addins/MonoDevelop.HexEditor/MonoDevelop.HexEditor/DisplayBinding.cs +++ /dev/null @@ -1,55 +0,0 @@ -// -// DisplayBinding.cs -// -// Author: -// Mike Krüger <mkrueger@novell.com> -// -// Copyright (c) 2009 Novell, Inc (http://www.novell.com) -// -// 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.IO; -using MonoDevelop.Core; -using MonoDevelop.Ide.Gui; -using MonoDevelop.Projects; - -namespace MonoDevelop.HexEditor -{ - class HexEditorDisplayBinding : IViewDisplayBinding - { - public string Name { - get { - return GettextCatalog.GetString ("Hex Editor"); - } - } - - public ViewContent CreateContent (FilePath fileName, string mimeType, Project ownerProject) - { - - return new HexEditorView (); - } - - public bool CanHandle (FilePath fileName, string mimeType, Project ownerProject) - { - return true; - } - - public bool CanUseAsDefault { get { return false; } } - } -} diff --git a/main/src/addins/MonoDevelop.HexEditor/MonoDevelop.HexEditor/HexEditorNodeExtension.cs b/main/src/addins/MonoDevelop.HexEditor/MonoDevelop.HexEditor/HexEditorNodeExtension.cs index 8f6a0721d7..86df40940d 100644 --- a/main/src/addins/MonoDevelop.HexEditor/MonoDevelop.HexEditor/HexEditorNodeExtension.cs +++ b/main/src/addins/MonoDevelop.HexEditor/MonoDevelop.HexEditor/HexEditorNodeExtension.cs @@ -51,15 +51,15 @@ namespace MonoDevelop.HexEditor class HexEditorCommandHandler: NodeCommandHandler { [CommandHandler (Commands.ShowHexEditor)] - protected void OnShowHexEditor () + protected async void OnShowHexEditor () { HexEditorView view = new HexEditorView (); ProjectFile file = CurrentNode.DataItem as ProjectFile; if (file != null) - view.Load (file.FilePath); + await view.Load (file.FilePath); - IdeApp.Workbench.OpenDocument (view, true); + await IdeApp.Workbench.OpenDocument (view, true); } } diff --git a/main/src/addins/MonoDevelop.HexEditor/MonoDevelop.HexEditor/HexEditorView.cs b/main/src/addins/MonoDevelop.HexEditor/MonoDevelop.HexEditor/HexEditorView.cs index f23c5fc900..091d4735e7 100644 --- a/main/src/addins/MonoDevelop.HexEditor/MonoDevelop.HexEditor/HexEditorView.cs +++ b/main/src/addins/MonoDevelop.HexEditor/MonoDevelop.HexEditor/HexEditorView.cs @@ -1,4 +1,4 @@ -// +// // HexEditorView.cs // // Author: @@ -34,36 +34,79 @@ using Xwt; using MonoDevelop.Ide.Fonts; using MonoDevelop.Ide.Editor; using System.Threading.Tasks; +using MonoDevelop.Ide.Gui.Documents; +using MonoDevelop.Components; +using MonoDevelop.Core; +using System.Threading; +using MonoDevelop.Ide; namespace MonoDevelop.HexEditor { - class HexEditorView : AbstractXwtViewContent, IUndoHandler, IBookmarkBuffer, IZoomable + [ExportFileDocumentController (MimeType = "*", CanUseAsDefault = false, Name = "Hex Editor", Role = DocumentControllerRole.Tool)] + class HexEditorView : FileDocumentController, IUndoHandler, IBookmarkBuffer, IZoomable { - Mono.MHex.HexEditor hexEditor = new Mono.MHex.HexEditor (); - ScrollView window ; - - public override Xwt.Widget Widget { - get { - return window; - } - } - - public HexEditorView () + Mono.MHex.HexEditor hexEditor; + ScrollView window; + + protected override Type FileModelType => typeof (ByteBufferModel); + + protected override async Task<Control> OnGetViewControlAsync (CancellationToken token, DocumentViewContent view) { + hexEditor = new Mono.MHex.HexEditor (); + hexEditor.HexEditorData.ByteBuffer = ((ByteBufferModel)Model).ByteBuffer; hexEditor.HexEditorStyle = new MonoDevelopHexEditorStyle (hexEditor); SetOptions (); DefaultSourceEditorOptions.Instance.Changed += Instance_Changed; - hexEditor.HexEditorData.Replaced += delegate { - this.IsDirty = true; + hexEditor.HexEditorData.Changed += delegate { + this.HasUnsavedChanges = true; }; window = new ScrollView (hexEditor); + await LoadContent (); + + hexEditor.SetFocus (); + + return new XwtControl (window); + } + + public Task Load (FilePath filePath) + { + return Initialize (new FileDescriptor (filePath, null, null)); + } + + async Task LoadContent () + { + var model = (ByteBufferModel)Model; + await model.Load (); + hexEditor.HexEditorData.ByteBuffer = model.ByteBuffer; } - public override void Dispose () + protected override bool OnCanAssignModel (Type type) { - ((MonoDevelopHexEditorStyle)hexEditor.HexEditorStyle).Dispose (); - DefaultSourceEditorOptions.Instance.Changed -= Instance_Changed; - base.Dispose (); + return typeof (ByteBufferModel).IsAssignableFrom (type); + } + + protected override void OnModelChanged (DocumentModel oldModel, DocumentModel newModel) + { + if (oldModel != null) + ((ByteBufferModel)oldModel).ByteBufferInstanceChanged -= Handle_ByteBufferInstanceChanged; + if (newModel != null) + ((ByteBufferModel)newModel).ByteBufferInstanceChanged += Handle_ByteBufferInstanceChanged; + base.OnModelChanged (oldModel, newModel); + } + + void Handle_ByteBufferInstanceChanged (object sender, EventArgs e) + { + if (hexEditor != null) + hexEditor.HexEditorData.ByteBuffer = ((ByteBufferModel)Model).ByteBuffer; + } + + protected override void OnDispose () + { + if (hexEditor != null) { + ((MonoDevelopHexEditorStyle)hexEditor.HexEditorStyle).Dispose (); + DefaultSourceEditorOptions.Instance.Changed -= Instance_Changed; + } + base.OnDispose (); } void Instance_Changed (object sender, EventArgs e) @@ -73,42 +116,28 @@ namespace MonoDevelop.HexEditor void SetOptions () { - var name = FontService.FilterFontName (FontService.GetUnderlyingFontName ("Editor")); + var name = IdeServices.FontService.FilterFontName (IdeServices.FontService.GetUnderlyingFontName ("Editor")); hexEditor.Options.FontName = name; hexEditor.PurgeLayoutCaches (); hexEditor.Repaint (); } - public override Task Save (FileSaveInformation fileSaveInformation) + protected override Task OnSave () { - File.WriteAllBytes (fileSaveInformation.FileName, hexEditor.HexEditorData.Bytes); - ContentName = fileSaveInformation.FileName; - this.IsDirty = false; + File.WriteAllBytes (FilePath, hexEditor.HexEditorData.Bytes); + this.HasUnsavedChanges = false; return Task.FromResult (true); } - public override async Task Load (FileOpenInformation fileOpenInformation) - { - var fileName = fileOpenInformation.FileName; - using (Stream stream = File.OpenRead (fileName)) { - hexEditor.HexEditorData.Buffer = await ArrayBuffer.LoadAsync (stream); - } - - ContentName = fileName; - this.IsDirty = false; - hexEditor.SetFocus (); - } - - #region IUndoHandler implementation void IUndoHandler.Undo () { - hexEditor.HexEditorData.Undo (); + hexEditor.HexEditorData.ByteBuffer.Undo (); } void IUndoHandler.Redo () { - hexEditor.HexEditorData.Redo (); + hexEditor.HexEditorData.ByteBuffer.Redo (); } class UndoGroup : IDisposable @@ -120,13 +149,13 @@ namespace MonoDevelop.HexEditor if (data == null) throw new ArgumentNullException ("data"); this.data = data; - data.BeginAtomicUndo (); + data.ByteBuffer.BeginAtomicUndo (); } public void Dispose () { if (data != null) { - data.EndAtomicUndo (); + data.ByteBuffer.EndAtomicUndo (); data = null; } } @@ -139,14 +168,14 @@ namespace MonoDevelop.HexEditor bool IUndoHandler.EnableUndo { get { - return hexEditor.HexEditorData.EnableUndo; + return hexEditor.HexEditorData.ByteBuffer.CanUndo; } } bool IUndoHandler.EnableRedo { get { - return hexEditor.HexEditorData.EnableRedo; + return hexEditor.HexEditorData.ByteBuffer.CanRedo; } } |