From a700d4c1286815af58bf2473ccfa0eaca60cb381 Mon Sep 17 00:00:00 2001 From: Justin Aquadro Date: Sun, 6 Oct 2013 21:43:12 -0400 Subject: [PATCH 1/2] Add text-based array editing; open editing for Mono-based runtimes --- Model/TagByteArrayDataNode.cs | 11 +- Model/TagIntArrayDataNode.cs | 11 +- NBTExplorer.csproj | 4 +- Windows/EditHex.Designer.cs | 81 ++---- Windows/EditHex.cs | 432 +++++++++++++++++++++++++++----- Windows/FindReplace.Designer.cs | 11 + Windows/FindReplace.resx | 66 ++--- 7 files changed, 442 insertions(+), 174 deletions(-) diff --git a/Model/TagByteArrayDataNode.cs b/Model/TagByteArrayDataNode.cs index 0ed183b..d55995c 100644 --- a/Model/TagByteArrayDataNode.cs +++ b/Model/TagByteArrayDataNode.cs @@ -16,7 +16,11 @@ namespace NBTExplorer.Model public override bool CanEditNode { - get { return !IsMono(); } +#if WINDOWS + get { return true; } +#else + get { return false; } +#endif } public override bool EditNode () @@ -28,10 +32,5 @@ namespace NBTExplorer.Model { get { return NodeDisplayPrefix + Tag.Data.Length + " bytes"; } } - - private bool IsMono () - { - return Type.GetType("Mono.Runtime") != null; - } } } diff --git a/Model/TagIntArrayDataNode.cs b/Model/TagIntArrayDataNode.cs index a11bb98..bb07359 100644 --- a/Model/TagIntArrayDataNode.cs +++ b/Model/TagIntArrayDataNode.cs @@ -16,7 +16,11 @@ namespace NBTExplorer.Model public override bool CanEditNode { - get { return !IsMono(); } +#if WINDOWS + get { return true; } +#else + get { return false; } +#endif } public override bool EditNode () @@ -28,10 +32,5 @@ namespace NBTExplorer.Model { get { return NodeDisplayPrefix + Tag.Data.Length + " integers"; } } - - private bool IsMono () - { - return Type.GetType("Mono.Runtime") != null; - } } } diff --git a/NBTExplorer.csproj b/NBTExplorer.csproj index 3008101..04eeda1 100644 --- a/NBTExplorer.csproj +++ b/NBTExplorer.csproj @@ -38,7 +38,7 @@ True bin\Debug\ - DEBUG;TRACE + TRACE;DEBUG;WINDOWS full AnyCPU bin\Debug\NBTExplorer.exe.CodeAnalysisLog.xml @@ -55,7 +55,7 @@ bin\Release\ - TRACE + TRACE;WINDOWS True pdbonly AnyCPU diff --git a/Windows/EditHex.Designer.cs b/Windows/EditHex.Designer.cs index 1df36d4..51c525d 100644 --- a/Windows/EditHex.Designer.cs +++ b/Windows/EditHex.Designer.cs @@ -28,62 +28,28 @@ private void InitializeComponent () { this.statusStrip1 = new System.Windows.Forms.StatusStrip(); - this._curPositionLabel = new System.Windows.Forms.ToolStripStatusLabel(); - this._curElementLabel = new System.Windows.Forms.ToolStripStatusLabel(); - this._space = new System.Windows.Forms.ToolStripStatusLabel(); - this._insertStateLabel = new System.Windows.Forms.ToolStripStatusLabel(); this._buttonCancel = new System.Windows.Forms.Button(); this._buttonOK = new System.Windows.Forms.Button(); - this.hexBox1 = new Be.Windows.Forms.HexBox(); this._buttonImport = new System.Windows.Forms.Button(); this._buttonExport = new System.Windows.Forms.Button(); + this.viewTabs = new System.Windows.Forms.TabControl(); this.statusStrip1.SuspendLayout(); + this.viewTabs.SuspendLayout(); this.SuspendLayout(); // // statusStrip1 // - this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { - this._curPositionLabel, - this._curElementLabel, - this._space, - this._insertStateLabel}); this.statusStrip1.Location = new System.Drawing.Point(0, 333); this.statusStrip1.Name = "statusStrip1"; - this.statusStrip1.Size = new System.Drawing.Size(516, 22); + this.statusStrip1.Size = new System.Drawing.Size(532, 22); this.statusStrip1.TabIndex = 1; this.statusStrip1.Text = "statusStrip1"; // - // _curPositionLabel - // - this._curPositionLabel.AutoSize = false; - this._curPositionLabel.Name = "_curPositionLabel"; - this._curPositionLabel.Size = new System.Drawing.Size(100, 17); - this._curPositionLabel.Text = "0000"; - // - // _curElementLabel - // - this._curElementLabel.Name = "_curElementLabel"; - this._curElementLabel.Size = new System.Drawing.Size(59, 17); - this._curElementLabel.Text = "Element 0"; - this._curElementLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft; - // - // _space - // - this._space.Name = "_space"; - this._space.Size = new System.Drawing.Size(284, 17); - this._space.Spring = true; - // - // _insertStateLabel - // - this._insertStateLabel.Name = "_insertStateLabel"; - this._insertStateLabel.Size = new System.Drawing.Size(58, 17); - this._insertStateLabel.Text = "Overwrite"; - // // _buttonCancel // this._buttonCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this._buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this._buttonCancel.Location = new System.Drawing.Point(348, 307); + this._buttonCancel.Location = new System.Drawing.Point(364, 307); this._buttonCancel.Name = "_buttonCancel"; this._buttonCancel.Size = new System.Drawing.Size(75, 23); this._buttonCancel.TabIndex = 13; @@ -93,7 +59,7 @@ // _buttonOK // this._buttonOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this._buttonOK.Location = new System.Drawing.Point(429, 307); + this._buttonOK.Location = new System.Drawing.Point(445, 307); this._buttonOK.Name = "_buttonOK"; this._buttonOK.Size = new System.Drawing.Size(75, 23); this._buttonOK.TabIndex = 12; @@ -101,22 +67,6 @@ this._buttonOK.UseVisualStyleBackColor = true; this._buttonOK.Click += new System.EventHandler(this._buttonOK_Click); // - // hexBox1 - // - this.hexBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) - | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.hexBox1.Font = new System.Drawing.Font("Courier New", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0))); - this.hexBox1.LineInfoForeColor = System.Drawing.Color.Empty; - this.hexBox1.LineInfoVisible = true; - this.hexBox1.Location = new System.Drawing.Point(12, 12); - this.hexBox1.Name = "hexBox1"; - this.hexBox1.ReadOnly = true; - this.hexBox1.ShadowSelectionColor = System.Drawing.Color.FromArgb(((int)(((byte)(100)))), ((int)(((byte)(60)))), ((int)(((byte)(188)))), ((int)(((byte)(255))))); - this.hexBox1.Size = new System.Drawing.Size(492, 289); - this.hexBox1.TabIndex = 0; - this.hexBox1.VScrollBarVisible = true; - // // _buttonImport // this._buttonImport.Location = new System.Drawing.Point(12, 307); @@ -137,22 +87,33 @@ this._buttonExport.UseVisualStyleBackColor = true; this._buttonExport.Click += new System.EventHandler(this._buttonExport_Click); // + // viewTabs + // + this.viewTabs.Location = new System.Drawing.Point(12, 12); + this.viewTabs.Name = "viewTabs"; + this.viewTabs.SelectedIndex = 0; + this.viewTabs.Size = new System.Drawing.Size(508, 289); + this.viewTabs.TabIndex = 16; + // // HexEditor // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.CancelButton = this._buttonCancel; - this.ClientSize = new System.Drawing.Size(516, 355); + this.ClientSize = new System.Drawing.Size(532, 355); + this.Controls.Add(this.viewTabs); this.Controls.Add(this._buttonExport); this.Controls.Add(this._buttonImport); this.Controls.Add(this._buttonCancel); this.Controls.Add(this._buttonOK); this.Controls.Add(this.statusStrip1); - this.Controls.Add(this.hexBox1); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.Name = "HexEditor"; + this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; this.Text = "HexEditor"; this.statusStrip1.ResumeLayout(false); this.statusStrip1.PerformLayout(); + this.viewTabs.ResumeLayout(false); this.ResumeLayout(false); this.PerformLayout(); @@ -160,15 +121,11 @@ #endregion - private Be.Windows.Forms.HexBox hexBox1; private System.Windows.Forms.StatusStrip statusStrip1; - private System.Windows.Forms.ToolStripStatusLabel _curPositionLabel; private System.Windows.Forms.Button _buttonCancel; private System.Windows.Forms.Button _buttonOK; - private System.Windows.Forms.ToolStripStatusLabel _curElementLabel; - private System.Windows.Forms.ToolStripStatusLabel _space; - private System.Windows.Forms.ToolStripStatusLabel _insertStateLabel; private System.Windows.Forms.Button _buttonImport; private System.Windows.Forms.Button _buttonExport; + private System.Windows.Forms.TabControl viewTabs; } } \ No newline at end of file diff --git a/Windows/EditHex.cs b/Windows/EditHex.cs index 9adce63..7b3ce88 100644 --- a/Windows/EditHex.cs +++ b/Windows/EditHex.cs @@ -5,15 +5,277 @@ using System.IO; using System.Collections.Generic; using System.ComponentModel; using System.Text; +using System.Drawing; namespace NBTExplorer.Windows { public partial class HexEditor : Form { - private int _bytesPerElem; - private byte[] _data; - private bool _modified; - DynamicByteProvider _byteProvider; + private abstract class EditView + { + protected EditView (StatusStrip statusBar, int bytesPerElem) + { + BytesPerElem = bytesPerElem; + StatusBar = statusBar; + } + + public event EventHandler Modified; + + public int BytesPerElem { get; set; } + public StatusStrip StatusBar { get; set; } + + public abstract TabPage TabPage { get; } + + public abstract void Initialize (); + public abstract void Activate (); + public abstract byte[] GetRawData (); + public abstract void SetRawData (byte[] data); + + protected virtual void OnModified () + { + var ev = Modified; + if (ev != null) + ev(this, EventArgs.Empty); + } + } + + private class TextView : EditView + { + private TabPage _tabPage; + private TextBox _textBox; + + private ToolStripStatusLabel _elementLabel; + private ToolStripStatusLabel _spaceLabel; + + private Dictionary _elemIndex = new Dictionary(); + + public TextView (StatusStrip statusBar, int bytesPerElem) + : base(statusBar, bytesPerElem) + { } + + public override void Initialize () + { + _textBox = new TextBox() { + Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right, + Font = new Font("Courier New", 9F, FontStyle.Regular, GraphicsUnit.Point, 0), + Location = new Point(0, 0), + Margin = new Padding(0), + Multiline = true, + ScrollBars = ScrollBars.Vertical, + Size = new Size(500, 263), + TabIndex = 0, + MaxLength = 0, + }; + + _tabPage = new TabPage() { + Location = new Point(4, 22), + Padding = new Padding(3), + Size = new Size(500, 263), + TabIndex = 1, + Text = "Text View", + UseVisualStyleBackColor = true, + }; + + _tabPage.Controls.Add(_textBox); + + _textBox.TextChanged += (s, e) => { OnModified(); RebuildElementIndex(); }; + _textBox.PreviewKeyDown += (s, e) => { e.IsInputKey = true; }; + _textBox.KeyUp += (s, e) => { UpdateElementLabel(); }; + _textBox.MouseClick += (s, e) => { UpdateElementLabel(); }; + + InitializeStatusBar(); + } + + private void InitializeStatusBar () + { + _elementLabel = new ToolStripStatusLabel() { + Size = new Size(100, 17), + Text = "Element 0", + TextAlign = ContentAlignment.MiddleLeft, + }; + + _spaceLabel = new ToolStripStatusLabel() { + Spring = true, + }; + } + + public override void Activate () + { + StatusBar.Items.Clear(); + StatusBar.Items.AddRange(new ToolStripItem[] { + _elementLabel, _spaceLabel, + }); + } + + public override TabPage TabPage + { + get { return _tabPage; } + } + + public override byte[] GetRawData () + { + return HexEditor.TextToRaw(_textBox.Text, BytesPerElem); + } + + public override void SetRawData (byte[] data) + { + _textBox.Text = HexEditor.RawToText(data, BytesPerElem); + RebuildElementIndex(); + } + + private void RebuildElementIndex () + { + _elemIndex.Clear(); + + int element = 0; + String text = _textBox.Text; + bool lcw = true; + + for (int i = 0; i < text.Length; i++) { + bool w = IsWhiteSpace(text[i]); + if (lcw && !w) + _elemIndex[i] = element++; + lcw = w; + } + } + + private bool IsWhiteSpace (char c) + { + return c == ' ' || c == '\n' || c == '\r' || c == '\t'; + } + + private void UpdateElementLabel () + { + int index = _textBox.SelectionStart; + int element = 0; + + while (index >= 0 && !_elemIndex.TryGetValue(index, out element)) + index--; + + _elementLabel.Text = "Element " + element; + } + } + + private class HexView : EditView + { + private TabPage _tabPage; + private HexBox _hexBox; + + private ToolStripStatusLabel _positionLabel; + private ToolStripStatusLabel _elementLabel; + private ToolStripStatusLabel _spaceLabel; + private ToolStripStatusLabel _insertLabel; + + private DynamicByteProvider _byteProvider; + + public HexView (StatusStrip statusBar, int bytesPerElem) + : base(statusBar, bytesPerElem) + { } + + public override void Initialize () + { + _byteProvider = new DynamicByteProvider(new byte[0]); + _byteProvider.Changed += (o, e) => { OnModified(); }; + + _hexBox = new HexBox() { + Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right, + Font = new Font("Courier New", 9F, FontStyle.Regular, GraphicsUnit.Point, 0), + LineInfoForeColor = Color.Empty, + LineInfoVisible = true, + Location = new Point(0, 0), + ShadowSelectionColor = Color.FromArgb(100, 60, 188, 255), + Size = new Size(500, 263), + TabIndex = 0, + VScrollBarVisible = true, + ByteProvider = _byteProvider, + }; + + _tabPage = new TabPage() { + Location = new Point(4, 22), + Padding = new Padding(3), + Size = new Size(500, 263), + TabIndex = 0, + Text = "Hex View", + UseVisualStyleBackColor = true, + }; + + _tabPage.Controls.Add(_hexBox); + + _hexBox.HorizontalByteCountChanged += (s, e) => { UpdatePosition(); }; + _hexBox.CurrentLineChanged += (s, e) => { UpdatePosition(); }; + _hexBox.CurrentPositionInLineChanged += (s, e) => { UpdatePosition(); }; + + _hexBox.InsertActiveChanged += (s, e) => { _insertLabel.Text = (_hexBox.InsertActive) ? "Insert" : "Overwrite"; }; + + InitializeStatusBar(); + } + + private void InitializeStatusBar () + { + _positionLabel = new ToolStripStatusLabel() { + AutoSize = false, + Size = new Size(100, 17), + Text = "0000", + }; + + _elementLabel = new ToolStripStatusLabel() { + Size = new Size(59, 17), + Text = "Element 0", + TextAlign = ContentAlignment.MiddleLeft, + }; + + _spaceLabel = new ToolStripStatusLabel() { + Size = new Size(300, 17), + Spring = true, + }; + + _insertLabel = new ToolStripStatusLabel() { + Size = new Size(58, 17), + Text = (_hexBox.InsertActive) ? "Insert" : "Overwrite", + }; + } + + public override void Activate () + { + StatusBar.Items.Clear(); + StatusBar.Items.AddRange(new ToolStripItem[] { + _positionLabel, _elementLabel, _spaceLabel, _insertLabel, + }); + + UpdatePosition(); + } + + public override TabPage TabPage + { + get { return _tabPage; } + } + + public override byte[] GetRawData () + { + byte[] data = new byte[_byteProvider.Length]; + for (int i = 0; i < data.Length; i++) { + data[i] = _byteProvider.Bytes[i]; + } + + return data; + } + + public override void SetRawData (byte[] data) + { + _byteProvider = new DynamicByteProvider(data); + _byteProvider.Changed += (o, e2) => { OnModified(); }; + + _hexBox.ByteProvider = _byteProvider; + } + + private void UpdatePosition () + { + long pos = (_hexBox.CurrentLine - 1) * _hexBox.HorizontalByteCount + _hexBox.CurrentPositionInLine - 1; + + _positionLabel.Text = "0x" + pos.ToString("X4"); + _elementLabel.Text = "Element " + pos / BytesPerElem; + } + } private class FixedByteProvider : DynamicByteProvider { @@ -27,30 +289,60 @@ namespace NBTExplorer.Windows } } + private TabPage _previousPage; + private int _bytesPerElem; + private byte[] _data; + private bool _modified; + + private Dictionary _views = new Dictionary(); + public HexEditor (string tagName, byte[] data, int bytesPerElem) { InitializeComponent(); + EditView textView = new TextView(statusStrip1, bytesPerElem); + textView.Initialize(); + textView.SetRawData(data); + textView.Modified += (s, e) => { _modified = true; }; + + _views.Add(textView.TabPage, textView); + viewTabs.TabPages.Add(textView.TabPage); + + EditView hexView = null; + + if (!IsMono()) { + hexView = new HexView(statusStrip1, bytesPerElem); + hexView.Initialize(); + hexView.SetRawData(data); + hexView.Modified += (s, e) => { _modified = true; }; + + _views.Add(hexView.TabPage, hexView); + viewTabs.TabPages.Add(hexView.TabPage); + } + + if (bytesPerElem > 1 || IsMono()) { + textView.Activate(); + viewTabs.SelectedTab = textView.TabPage; + } + else { + hexView.Activate(); + viewTabs.SelectedTab = hexView.TabPage; + } + + viewTabs.Deselected += (o, e) => { _previousPage = e.TabPage; }; + viewTabs.Selecting += HandleTabChanged; + this.Text = "Editing: " + tagName; _bytesPerElem = bytesPerElem; - _curPositionLabel.Text = "0x0000"; - _curElementLabel.Text = "Element 0"; _data = new byte[data.Length]; Array.Copy(data, _data, data.Length); + } - _byteProvider = new DynamicByteProvider(_data); - _byteProvider.Changed += (o, e) => { _modified = true; }; - - hexBox1.ByteProvider = _byteProvider; - - hexBox1.HorizontalByteCountChanged += HexBox_HorizontalByteCountChanged; - hexBox1.CurrentLineChanged += HexBox_CurrentLineChanged; - hexBox1.CurrentPositionInLineChanged += HexBox_CurrentPositionInLineChanged; - hexBox1.InsertActiveChanged += HexBox_InsertActiveChanged; - - hexBox1.ReadOnly = false; + private bool IsMono () + { + return Type.GetType("Mono.Runtime") != null; } public byte[] Data @@ -63,89 +355,97 @@ namespace NBTExplorer.Windows get { return _modified; } } - private void HexBox_HorizontalByteCountChanged (object sender, EventArgs e) + private void HandleTabChanged (object sender, TabControlCancelEventArgs e) { - UpdatePosition(); - } + if (e.Action != TabControlAction.Selecting) + return; - private void HexBox_CurrentLineChanged (object sender, EventArgs e) - { - UpdatePosition(); - } + if (e.TabPage == _previousPage) + return; - private void HexBox_CurrentPositionInLineChanged (object sender, EventArgs e) - { - UpdatePosition(); - } + EditView oldView = _views[_previousPage]; + EditView newView = _views[e.TabPage]; - private void HexBox_InsertActiveChanged (object sender, EventArgs e) - { - if (hexBox1.InsertActive) - _insertStateLabel.Text = "Insert"; - else - _insertStateLabel.Text = "Overwrite"; - } + byte[] data = oldView.GetRawData(); + newView.SetRawData(data); - private void UpdatePosition () - { - long pos = (hexBox1.CurrentLine - 1) * hexBox1.HorizontalByteCount + hexBox1.CurrentPositionInLine - 1; - - _curPositionLabel.Text = "0x" + pos.ToString("X4"); - _curElementLabel.Text = "Element " + pos / _bytesPerElem; + newView.Activate(); } private void Apply () { - if (_data.Length != _byteProvider.Length) - _data = new byte[_byteProvider.Length]; - - for (int i = 0; i < _data.Length; i++) { - _data[i] = _byteProvider.Bytes[i]; - } + EditView view = _views[viewTabs.SelectedTab]; + _data = view.GetRawData(); DialogResult = DialogResult.OK; Close(); } private String RawToText (byte[] data) + { + return RawToText(data, _bytesPerElem); + } + + private static String RawToText (byte[] data, int bytesPerElem) + { + switch (bytesPerElem) { + case 1: return RawToText(data, bytesPerElem, 16); + case 2: return RawToText(data, bytesPerElem, 8); + case 4: return RawToText(data, bytesPerElem, 4); + case 8: return RawToText(data, bytesPerElem, 2); + default: return RawToText(data, bytesPerElem, 1); + } + } + + private static String RawToText (byte[] data, int bytesPerElem, int elementsPerLine) { StringBuilder builder = new StringBuilder(); - for (int i = 0; i < data.Length; i += _bytesPerElem) { - if (data.Length - i < _bytesPerElem) + for (int i = 0; i < data.Length; i += bytesPerElem) { + if (data.Length - i < bytesPerElem) break; - switch (_bytesPerElem) { + switch (bytesPerElem) { case 1: - builder.AppendLine(((sbyte)data[i]).ToString()); + builder.Append(((sbyte)data[i]).ToString()); break; case 2: - builder.AppendLine(BitConverter.ToInt16(data, i).ToString()); + builder.Append(BitConverter.ToInt16(data, i).ToString()); break; case 4: - builder.AppendLine(BitConverter.ToInt32(data, i).ToString()); + builder.Append(BitConverter.ToInt32(data, i).ToString()); break; case 8: - builder.AppendLine(BitConverter.ToInt64(data, i).ToString()); + builder.Append(BitConverter.ToInt64(data, i).ToString()); break; } + + if ((i / bytesPerElem) % elementsPerLine == elementsPerLine - 1) + builder.AppendLine(); + else + builder.Append(" "); } return builder.ToString(); } private byte[] TextToRaw (string text) + { + return TextToRaw(text, _bytesPerElem); + } + + private static byte[] TextToRaw (string text, int bytesPerElem) { string[] items = text.Split(null as char[], StringSplitOptions.RemoveEmptyEntries); - byte[] data = new byte[_bytesPerElem * items.Length]; + byte[] data = new byte[bytesPerElem * items.Length]; for (int i = 0; i < items.Length; i++) { - int index = i * _bytesPerElem; + int index = i * bytesPerElem; - switch (_bytesPerElem) { + switch (bytesPerElem) { case 1: sbyte val1; if (sbyte.TryParse(items[i], out val1)) @@ -188,10 +488,9 @@ namespace NBTExplorer.Windows _data = new byte[fstr.Length]; fstr.Read(_data, 0, (int)fstr.Length); - _byteProvider = new DynamicByteProvider(_data); - _byteProvider.Changed += (o, e) => { _modified = true; }; + EditView view = _views[viewTabs.SelectedTab]; + view.SetRawData(_data); - hexBox1.ByteProvider = _byteProvider; _modified = true; } } @@ -210,10 +509,9 @@ namespace NBTExplorer.Windows string text = System.Text.Encoding.UTF8.GetString(raw, 0, raw.Length); _data = TextToRaw(text); - _byteProvider = new DynamicByteProvider(_data); - _byteProvider.Changed += (o, e) => { _modified = true; }; + EditView view = _views[viewTabs.SelectedTab]; + view.SetRawData(_data); - hexBox1.ByteProvider = _byteProvider; _modified = true; } } @@ -226,7 +524,9 @@ namespace NBTExplorer.Windows { try { using (FileStream fstr = File.Open(path, FileMode.Create, FileAccess.Write, FileShare.None)) { - byte[] data = _byteProvider.Bytes.ToArray(); + EditView view = _views[viewTabs.SelectedTab]; + byte[] data = view.GetRawData(); + fstr.Write(data, 0, data.Length); } } @@ -239,7 +539,9 @@ namespace NBTExplorer.Windows { try { using (FileStream fstr = File.Open(path, FileMode.Create, FileAccess.Write, FileShare.None)) { - string text = RawToText(_byteProvider.Bytes.ToArray()); + EditView view = _views[viewTabs.SelectedTab]; + string text = RawToText(view.GetRawData()); + byte[] data = System.Text.Encoding.UTF8.GetBytes(text); fstr.Write(data, 0, data.Length); } diff --git a/Windows/FindReplace.Designer.cs b/Windows/FindReplace.Designer.cs index 0cdba2d..4c12d13 100644 --- a/Windows/FindReplace.Designer.cs +++ b/Windows/FindReplace.Designer.cs @@ -70,6 +70,7 @@ this._buttonReplace = new System.Windows.Forms.Button(); this._buttonReplaceAll = new System.Windows.Forms.Button(); this._buttonCancel = new System.Windows.Forms.Button(); + this.label1 = new System.Windows.Forms.Label(); this.groupBox1.SuspendLayout(); this.panel1.SuspendLayout(); this.toolStrip1.SuspendLayout(); @@ -537,11 +538,20 @@ this._buttonCancel.UseVisualStyleBackColor = true; this._buttonCancel.Click += new System.EventHandler(this._buttonCancel_Click); // + // label1 + // + this.label1.Location = new System.Drawing.Point(12, 420); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(358, 18); + this.label1.TabIndex = 6; + this.label1.Text = "Search Root: blahblahbnl/blf"; + // // FindReplace // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(463, 449); + this.Controls.Add(this.label1); this.Controls.Add(this._buttonCancel); this.Controls.Add(this._buttonReplaceAll); this.Controls.Add(this._buttonReplace); @@ -607,5 +617,6 @@ private System.Windows.Forms.ToolStripButton _tbFindGroupOr; private System.Windows.Forms.ToolStripButton _tbFindEdit; private System.Windows.Forms.ToolStripButton _tbReplaceEdit; + private System.Windows.Forms.Label label1; } } \ No newline at end of file diff --git a/Windows/FindReplace.resx b/Windows/FindReplace.resx index b475523..4fe0d37 100644 --- a/Windows/FindReplace.resx +++ b/Windows/FindReplace.resx @@ -125,7 +125,7 @@ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0 ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAABA - QgAAAk1TRnQBSQFMAgEBFAEAAZABAQGQAQEBEAEAARABAAT/ARkBAAj/AUIBTQE2BwABNgMAASgDAAFA + QgAAAk1TRnQBSQFMAgEBFAEAAZgBAQGYAQEBEAEAARABAAT/ARkBAAj/AUIBTQE2BwABNgMAASgDAAFA AwABYAMAAQEBAAEYBgABSP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AOEAA/8D/AP6GPgD+QP6A/wMAAP9 A/oS+AP5A/0D/2kAA/4D+QPxAboBogGKAbYBhgFWAbYBhgFWAbYBhgFWAbYBhgFWAbYBhgFWAbYBhgFW AbYBhgFWAbYBhgFWAbwBpAGNA/cMAAP8A/YD8wG8AcoBzQFVAZUBowFVAZUBowHQAdcB2QPzA/UD+wP/ @@ -443,48 +443,48 @@ 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 - BPSUqbbrmUHrAAAAAElFTkSuQmCC + jRhoq7V+MdqDwEHE0pEyKqdWzo0e1BimN7PbhUpI6mZzts2lxWJxupyzlemJd+c8h7aHPureZkR/QX3h + xb15f96vR0f8P++aUZT1GETy+qCYPX+Xq+HbYyg7wd+dSGLb0H69C3eyii4tK2itJeGZr/zN8/ZH/oFT + ZC7pcwmAjA43bLCFU5flvUuyszcZwUyXMnRoM02FKynHdGWl25zx2gPVJEBGhxs22MKBS7R2zZMqQ1qg + ZiqpF6Fqkg5XVvut7KyB4mPoADI63LBBBwcu0dLmyw7T/JrjTXUZUOHNL52GVb/tdZl5/EqMGunSjMVV + XDinX/ENudZn9c7ilIkqhQbH2ThcolnuqY0HNr7aJssMcAYrqTPauHfYLUZ0dt4HhtziPDqL60/3kBai + cIm9Jz1Zk4NNj3o3PlncYvQRLUaU9z5PGulipN/G+QFyvZtYn/vd9T3JLsIl9p+eIi/rErz5Zemd2soF + Bkhh+sbIWvjW08yc1l4IAmR0uGnGOD+6DnU8B5c4oIjJDikXi70WltFYC8G+sbxf7+AX2gcSwfsOPgaQ + 0eGmsRWC2B5sjwpw67+y5dRzxZEr6eJFHcveHi18NE1wH1Qj35dOqJJpgIxOLd2wwRZOXZbeVoldTfuU + 8sPK955j3Sx7vIOrHb2az7V2Mm6AjA43bLCF03CJLRLbGsUeiWaJJokdEtsb7JTYLYEbNtjCgftPH0H8 + BOvuqbJKJ3+QAAAAAElFTkSuQmCC iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIHSURBVDhPY6AZ2LWY2XnXYsa9ILxzMVM8VBg/2DKfQQLK - ZNg2j3Hf+9f9398/7P6zbQHjLqgwihoUsHEOU8KmuYz7Ns1lXr5xNrMHiP373cz/L67n/EWIMS8HiYPU - QrUhwIaZjPu/v5r8//3D9u8HN+ieB/G/vej///JU9I91MxlXH1yjc/7tpYbvX551/QfJQbUhwOrJTAfu + ZNg2j3Hf+9f939896PqzbQHjLqgwihoUsHEOU8KmuYz7Ns1lXr5xNrMHiP373cz/z69l/0WIMS8HiYPU + QrUhwIaZjPu/v5r8//3D9u8HN+ieB/G/vej///Jk9I91MxlXH1yjc/7txYbvX551/QfJQbUhwOrJTAfu nwj/8fRK4v9Xt4r/71+lceH9w+b/t08GftoHZL+8WfAfJAdSA1IL1YYAyycyWC3vZ1y5Z4XyzZPbLF48 upT6H4TvnA7+//Bi8n+QGEgOpAakFqoNEyzsYnZZ0M106PAmqw/Xjnr8B2EQGyQGkoMqwwSzWxms57Qx rt6x0ujmyc32L68cdvkPwjdO+IPpY5utX+5YonUTpAakFqoNAabWMx25eyL6x62T3v+vH3P5v3SS8OWT - W0w/3zsXBmaDxG6c8Ph/8qjPD5BaqDYE6KtgOnrntMv/E4fMfizqFrrSX8m44cRhsx/3zwf+B8mBxEBy - IDUgPlQbArQXMKS05DCeaMllXA9ke4Poy4fs/z694vMfJA4Tg7JToNpQgZUhgxSUyVCZzHjsxnH7v3f3 + W0w/3zsXBmaDxG6c8Ph/4qjPD5BaqDYE6KtgOnrntMv/E4fMfizqFrrSX8m44cRhsx/3zwf+B8mBxEBy + IDUgPlQbArQXMKS05DCeaMllXA9ke4PoSwft/z694vMfJA4Tg7JToNpQgZUhgxSUyVCZzHjs+jH7v3f3 2/+sTGI8BRVGUYMN8AKxIhCr+9kzVNRlclwAYXsThkSQGBArA7EAEDMCMVbAAcRiQAyyBRsWB2IuIMZp - AImAgQEA1wkcgSmiF0cAAAAASUVORK5CYII= + AImAgQEAt8ocdMBFm60AAAAASUVORK5CYII= @@ -734,12 +734,12 @@ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8 YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFySURBVDhPrdE/SAJhHMbx33FCY2PQ0NLUHK1SIFRE0VAR - Ev2DQoiGKBCSUBvKKIhAoxByyE5QEkEF0cIIgwpxaGsQDSoowv5B0BBvPvLey912UgdfDt73+dxy9C9P - 1kmm7LTJdjYlb6o5zZTXpr3DFoZzotPxhtZrR9vR68kGq2Q8tfy2Dl3qOTbYwnBOlJ6Uu2+9fTntB0JL - XaLggln3AWxhOCdKTZjmS8pc+THuYmoJ94Ao6ugR5whbGM6JkmOy770Q+mHFMFMrhu2i/P6sOEfYwnBO - FLfKe983AfZ56RNlPMOiuKtfd4ctDOdEMavs/yr42VtuRwQYtltqb2WxU3eHLQznRJFROfBxtcteslsi - YO1bG7YwnBOFRuTDyvk2e0qvGwpbGM6JgkOS8lz9RQ/JVUNhC8M5UWBQitwn3OwutmIobGE4J/L2Sqly - 1MFKx8uGwhaGc2qZaZcO1izSRT3BwOIDjdWaqjXXGQzsXx6iXy8F3Ygxdd78AAAAAElFTkSuQmCC + Ev2DQoiGKBCSUBvKKIhAoxByyBSURDgF0cIIgwpraGsQDSoowqQgaIg3H3nv5W47qYMvB+/7fG45+pcn + 6yRTdtpkO5uSN9WcZspr095hC8M50el4Q+u1o+3o/WSDlTOeWn5bhy71HBtsYTgnSk/K3ffevpz2A+Gl + LlFwwaz7ALYwnBOlJkzzxdBc6VlxMbWEe0AUc/SIc4QtDOdEyTHZV7kJ/7BChKkVInZRfn9WnCNsYTgn + Uqzy3vddgH1e+kQZz7BIcfXr7rCF4ZwobpX9X7d+VsntiAAjdkvtHVrs1N1hC8M5UXRUDnxc7bK37JYI + WPvWhi0M50ThEfmwfL7NXtLrhsIWhnOi4JAUeq3+oqfkqqGwheGcKDAoRR8TbvYQXzEUtjCcE3l7pVQp + 5mDF42VDYQvDObXMtEsHaxbpop5gYPGBxmpN1ZrrDAb2Lw/RLyRX3YSQMJUWAAAAAElFTkSuQmCC \ No newline at end of file From 276a5c6747813da330a132aab369539ec8734a10 Mon Sep 17 00:00:00 2001 From: Justin Aquadro Date: Sun, 6 Oct 2013 21:50:11 -0400 Subject: [PATCH 2/2] Update find menu/button appropriately at end of search --- Windows/MainForm.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Windows/MainForm.cs b/Windows/MainForm.cs index 8969055..d1eb4d8 100644 --- a/Windows/MainForm.cs +++ b/Windows/MainForm.cs @@ -348,6 +348,8 @@ namespace NBTExplorer.Windows if (_searchForm.ShowDialog(this) == DialogResult.Cancel) { worker.Cancel(); _searchState = null; + + UpdateUI(); } t.Join(); @@ -375,6 +377,9 @@ namespace NBTExplorer.Windows _searchForm = null; } + _searchState = null; + UpdateUI(); + MessageBox.Show("End of results"); }