diff --git a/Mac/AppDelegate.cs b/Mac/AppDelegate.cs
index 08a210d..dd649cb 100644
--- a/Mac/AppDelegate.cs
+++ b/Mac/AppDelegate.cs
@@ -21,6 +21,11 @@ namespace NBTExplorer
mainWindowController.Window.AppDelegate = this;
}
+ public override bool ApplicationShouldTerminateAfterLastWindowClosed (NSApplication sender)
+ {
+ return true;
+ }
+
public NSMenuItem MenuAbout
{
get { return _menuAbout; }
@@ -156,17 +161,37 @@ namespace NBTExplorer
get { return _menuInsertCompound; }
}
- partial void ActionCut (MonoMac.Foundation.NSObject sender)
+ partial void ActionOpen (NSObject sender)
+ {
+ mainWindowController.Window.ActionOpen();
+ }
+
+ partial void ActionOpenFolder (NSObject sender)
+ {
+ mainWindowController.Window.ActionOpenFolder();
+ }
+
+ partial void ActionOpenMinecraft (NSObject sender)
+ {
+ mainWindowController.Window.ActionOpenMinecraft();
+ }
+
+ partial void ActionSave (NSObject sender)
+ {
+ mainWindowController.Window.ActionSave();
+ }
+
+ partial void ActionCut (NSObject sender)
{
mainWindowController.Window.ActionCut();
}
- partial void ActionCopy (MonoMac.Foundation.NSObject sender)
+ partial void ActionCopy (NSObject sender)
{
mainWindowController.Window.ActionCopy();
}
- partial void ActionPaste (MonoMac.Foundation.NSObject sender)
+ partial void ActionPaste (NSObject sender)
{
mainWindowController.Window.ActionPaste();
}
@@ -196,6 +221,16 @@ namespace NBTExplorer
mainWindowController.Window.ActionMoveNodeDown();
}
+ partial void ActionFind (NSObject sender)
+ {
+ mainWindowController.Window.ActionFind();
+ }
+
+ partial void ActionFindNext (NSObject sender)
+ {
+ mainWindowController.Window.ActionFindNext();
+ }
+
partial void ActionInsertByte (NSObject sender)
{
mainWindowController.Window.ActionInsertByteTag();
diff --git a/Mac/CancelFindWindow.cs b/Mac/CancelFindWindow.cs
new file mode 100644
index 0000000..6e8a630
--- /dev/null
+++ b/Mac/CancelFindWindow.cs
@@ -0,0 +1,35 @@
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using MonoMac.Foundation;
+using MonoMac.AppKit;
+
+namespace NBTExplorer.Mac
+{
+ public partial class CancelFindWindow : MonoMac.AppKit.NSWindow
+ {
+ #region Constructors
+
+ // Called when created from unmanaged code
+ public CancelFindWindow (IntPtr handle) : base (handle)
+ {
+ Initialize ();
+ }
+
+ // Called when created directly from a XIB file
+ [Export ("initWithCoder:")]
+ public CancelFindWindow (NSCoder coder) : base (coder)
+ {
+ Initialize ();
+ }
+
+ // Shared initialization code
+ void Initialize ()
+ {
+ }
+
+ #endregion
+ }
+}
+
diff --git a/Mac/CancelFindWindow.designer.cs b/Mac/CancelFindWindow.designer.cs
new file mode 100644
index 0000000..495d8c5
--- /dev/null
+++ b/Mac/CancelFindWindow.designer.cs
@@ -0,0 +1,30 @@
+// WARNING
+//
+// This file has been generated automatically by MonoDevelop to store outlets and
+// actions made in the Xcode designer. If it is removed, they will be lost.
+// Manual changes to this file may not be handled correctly.
+//
+using MonoMac.Foundation;
+
+namespace NBTExplorer.Mac
+{
+ [Register ("CancelFindWindowController")]
+ partial class CancelFindWindowController
+ {
+ [Action ("ActionCancel:")]
+ partial void ActionCancel (MonoMac.Foundation.NSObject sender);
+
+ void ReleaseDesignerOutlets ()
+ {
+ }
+ }
+
+ [Register ("CancelFindWindow")]
+ partial class CancelFindWindow
+ {
+
+ void ReleaseDesignerOutlets ()
+ {
+ }
+ }
+}
diff --git a/Mac/CancelFindWindow.xib b/Mac/CancelFindWindow.xib
new file mode 100644
index 0000000..acbf9f7
--- /dev/null
+++ b/Mac/CancelFindWindow.xib
@@ -0,0 +1,246 @@
+
+
+
+ 1080
+ 12C2034
+ 2844
+ 1187.34
+ 625.00
+
+
+
+
+
+
+
+ YES
+
+
+ window
+
+
+
+ 6
+
+
+
+ ActionCancel:
+
+
+
+ 9
+
+
+
+
+ YES
+
+ 0
+
+ YES
+
+
+
+
+
+ -2
+
+
+ File's Owner
+
+
+ -1
+
+
+ First Responder
+
+
+ -3
+
+
+ Application
+
+
+ 2
+
+
+ YES
+
+
+
+
+
+ 3
+
+
+ YES
+
+
+
+
+
+ 7
+
+
+ YES
+
+
+
+
+
+ 8
+
+
+
+
+
+
+ YES
+
+ YES
+ -1.IBPluginDependency
+ -2.IBPluginDependency
+ -3.IBPluginDependency
+ 2.IBPluginDependency
+ 2.IBWindowTemplateEditedContentRect
+ 2.NSWindowTemplate.visibleAtLaunch
+ 3.IBPluginDependency
+ 7.IBPluginDependency
+ 8.IBPluginDependency
+
+
+ YES
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ {{319, 371}, {606, 354}}
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+
+
+ YES
+
+
+
+
+
+ YES
+
+
+
+
+ 9
+
+
+
+ YES
+
+ CancelFindWindow
+ NSWindow
+
+ IBProjectSource
+ ./Classes/CancelFindWindow.h
+
+
+
+ CancelFindWindowController
+ NSWindowController
+
+ IBProjectSource
+ ./Classes/CancelFindWindowController.h
+
+
+
+
+ 0
+ IBCocoaFramework
+
+ com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3
+
+
+ YES
+ 3
+
+
diff --git a/Mac/CancelFindWindowController.cs b/Mac/CancelFindWindowController.cs
new file mode 100644
index 0000000..0c59f84
--- /dev/null
+++ b/Mac/CancelFindWindowController.cs
@@ -0,0 +1,64 @@
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using MonoMac.Foundation;
+using MonoMac.AppKit;
+
+namespace NBTExplorer.Mac
+{
+ public partial class CancelFindWindowController : MonoMac.AppKit.NSWindowController
+ {
+ #region Constructors
+
+ // Called when created from unmanaged code
+ public CancelFindWindowController (IntPtr handle) : base (handle)
+ {
+ Initialize ();
+ }
+
+ // Called when created directly from a XIB file
+ [Export ("initWithCoder:")]
+ public CancelFindWindowController (NSCoder coder) : base (coder)
+ {
+ Initialize ();
+ }
+
+ // Call to load from the XIB/NIB file
+ public CancelFindWindowController () : base ("CancelFindWindow")
+ {
+ Initialize ();
+ }
+
+ // Shared initialization code
+ void Initialize ()
+ {
+ }
+
+ #endregion
+
+ //strongly typed window accessor
+ public new CancelFindWindow Window
+ {
+ get {
+ return (CancelFindWindow)base.Window;
+ }
+ }
+
+ public void Accept ()
+ {
+ NSApplication.SharedApplication.StopModalWithCode((int)ModalResult.OK);
+ }
+
+ public void Cancel ()
+ {
+ NSApplication.SharedApplication.StopModalWithCode((int)ModalResult.Cancel);
+ }
+
+ partial void ActionCancel (MonoMac.Foundation.NSObject sender)
+ {
+ NSApplication.SharedApplication.StopModalWithCode((int)ModalResult.Cancel);
+ }
+ }
+}
+
diff --git a/Mac/FindWindow.cs b/Mac/FindWindow.cs
new file mode 100644
index 0000000..a406f21
--- /dev/null
+++ b/Mac/FindWindow.cs
@@ -0,0 +1,35 @@
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using MonoMac.Foundation;
+using MonoMac.AppKit;
+
+namespace NBTExplorer.Mac
+{
+ public partial class FindWindow : MonoMac.AppKit.NSWindow
+ {
+ #region Constructors
+
+ // Called when created from unmanaged code
+ public FindWindow (IntPtr handle) : base (handle)
+ {
+ Initialize ();
+ }
+
+ // Called when created directly from a XIB file
+ [Export ("initWithCoder:")]
+ public FindWindow (NSCoder coder) : base (coder)
+ {
+ Initialize ();
+ }
+
+ // Shared initialization code
+ void Initialize ()
+ {
+ }
+
+ #endregion
+ }
+}
+
diff --git a/Mac/FindWindow.designer.cs b/Mac/FindWindow.designer.cs
new file mode 100644
index 0000000..9602078
--- /dev/null
+++ b/Mac/FindWindow.designer.cs
@@ -0,0 +1,64 @@
+// WARNING
+//
+// This file has been generated automatically by MonoDevelop to store outlets and
+// actions made in the Xcode designer. If it is removed, they will be lost.
+// Manual changes to this file may not be handled correctly.
+//
+using MonoMac.Foundation;
+
+namespace NBTExplorer.Mac
+{
+ [Register ("FindWindowController")]
+ partial class FindWindowController
+ {
+ [Outlet]
+ MonoMac.AppKit.NSButton _nameToggle { get; set; }
+
+ [Outlet]
+ MonoMac.AppKit.NSButton _valueToggle { get; set; }
+
+ [Outlet]
+ MonoMac.AppKit.NSTextField _nameField { get; set; }
+
+ [Outlet]
+ MonoMac.AppKit.NSTextField _valueField { get; set; }
+
+ [Action ("ActionFind:")]
+ partial void ActionFind (MonoMac.Foundation.NSObject sender);
+
+ [Action ("ActionCancel:")]
+ partial void ActionCancel (MonoMac.Foundation.NSObject sender);
+
+ void ReleaseDesignerOutlets ()
+ {
+ if (_nameToggle != null) {
+ _nameToggle.Dispose ();
+ _nameToggle = null;
+ }
+
+ if (_valueToggle != null) {
+ _valueToggle.Dispose ();
+ _valueToggle = null;
+ }
+
+ if (_nameField != null) {
+ _nameField.Dispose ();
+ _nameField = null;
+ }
+
+ if (_valueField != null) {
+ _valueField.Dispose ();
+ _valueField = null;
+ }
+ }
+ }
+
+ [Register ("FindWindow")]
+ partial class FindWindow
+ {
+
+ void ReleaseDesignerOutlets ()
+ {
+ }
+ }
+}
diff --git a/Mac/FindWindow.xib b/Mac/FindWindow.xib
new file mode 100644
index 0000000..baf0fcf
--- /dev/null
+++ b/Mac/FindWindow.xib
@@ -0,0 +1,611 @@
+
+
+
+ 1080
+ 12C2034
+ 2844
+ 1187.34
+ 625.00
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+ 2844
+
+
+ YES
+ NSButton
+ NSButtonCell
+ NSCustomObject
+ NSTextField
+ NSTextFieldCell
+ NSView
+ NSWindowTemplate
+
+
+ YES
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+
+ PluginDependencyRecalculationVersion
+
+
+
+ YES
+
+ FindWindowController
+
+
+ FirstResponder
+
+
+ NSApplication
+
+
+ 1
+ 2
+ {{131, 74}, {421, 118}}
+ 611844096
+ Find
+ FindWindow
+
+
+
+
+ 256
+
+ YES
+
+
+ 268
+ {{18, 82}, {61, 18}}
+
+
+
+ _NS:9
+ YES
+
+ -2080374784
+ 268435456
+ Name:
+
+ LucidaGrande
+ 13
+ 1044
+
+ _NS:9
+
+ 1211912448
+ 2
+
+ NSImage
+ NSSwitch
+
+
+ NSSwitch
+
+
+
+ 200
+ 25
+
+ NO
+
+
+
+ 268
+ {{18, 50}, {61, 18}}
+
+
+
+ _NS:9
+ YES
+
+ 67108864
+ 268435456
+ Value:
+
+ _NS:9
+
+ 1211912448
+ 2
+
+
+
+
+ 200
+ 25
+
+ NO
+
+
+
+ 268
+ {{102, 81}, {299, 22}}
+
+
+
+ _NS:9
+ YES
+
+ -1804599231
+ 272630784
+
+
+ _NS:9
+
+ YES
+
+ 6
+ System
+ textBackgroundColor
+
+ 3
+ MQA
+
+
+
+ 6
+ System
+ textColor
+
+ 3
+ MAA
+
+
+
+ NO
+
+
+
+ 268
+ {{102, 49}, {299, 22}}
+
+
+
+ _NS:9
+ YES
+
+ -1804599231
+ 272630784
+
+
+ _NS:9
+
+ YES
+
+
+
+ NO
+
+
+
+ 268
+ {{325, 13}, {82, 32}}
+
+
+
+ _NS:9
+ YES
+
+ 67108864
+ 134217728
+ Find
+
+ _NS:9
+
+ -2038284288
+ 129
+
+ DQ
+ 200
+ 25
+
+ NO
+
+
+
+ 268
+ {{243, 13}, {82, 32}}
+
+
+
+ _NS:9
+ YES
+
+ 67108864
+ 134217728
+ Cancel
+
+ _NS:9
+
+ -2038284288
+ 129
+
+ Gw
+ 200
+ 25
+
+ NO
+
+
+ {421, 118}
+
+
+
+
+ {{0, 0}, {1600, 1178}}
+ {10000000000000, 10000000000000}
+ YES
+
+
+
+
+ YES
+
+
+ window
+
+
+
+ 6
+
+
+
+ _nameToggle
+
+
+
+ 25
+
+
+
+ _valueToggle
+
+
+
+ 26
+
+
+
+ _nameField
+
+
+
+ 27
+
+
+
+ _valueField
+
+
+
+ 28
+
+
+
+ ActionFind:
+
+
+
+ 29
+
+
+
+ ActionCancel:
+
+
+
+ 30
+
+
+
+
+ YES
+
+ 0
+
+ YES
+
+
+
+
+
+ -2
+
+
+ File's Owner
+
+
+ -1
+
+
+ First Responder
+
+
+ -3
+
+
+ Application
+
+
+ 2
+
+
+ YES
+
+
+
+
+
+ 3
+
+
+ YES
+
+
+
+
+
+
+
+
+
+
+ 7
+
+
+ YES
+
+
+
+
+
+ 8
+
+
+
+
+ 9
+
+
+ YES
+
+
+
+
+
+ 10
+
+
+
+
+ 11
+
+
+ YES
+
+
+
+
+
+ 12
+
+
+
+
+ 13
+
+
+ YES
+
+
+
+
+
+ 14
+
+
+
+
+ 15
+
+
+ YES
+
+
+
+
+
+ 16
+
+
+
+
+ 17
+
+
+ YES
+
+
+
+
+
+ 18
+
+
+
+
+
+
+ YES
+
+ YES
+ -1.IBPluginDependency
+ -2.IBPluginDependency
+ -3.IBPluginDependency
+ 10.IBPluginDependency
+ 11.IBPluginDependency
+ 12.IBPluginDependency
+ 13.IBPluginDependency
+ 14.IBPluginDependency
+ 15.IBPluginDependency
+ 16.IBPluginDependency
+ 17.IBPluginDependency
+ 18.IBPluginDependency
+ 2.IBPluginDependency
+ 2.IBWindowTemplateEditedContentRect
+ 2.NSWindowTemplate.visibleAtLaunch
+ 3.IBPluginDependency
+ 7.IBPluginDependency
+ 8.IBPluginDependency
+ 9.IBPluginDependency
+
+
+ YES
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ {{319, 371}, {606, 354}}
+
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
+
+
+
+ YES
+
+
+
+
+
+ YES
+
+
+
+
+ 30
+
+
+
+ YES
+
+ FindWindow
+ NSWindow
+
+ IBProjectSource
+ ./Classes/FindWindow.h
+
+
+
+ FindWindowController
+ NSWindowController
+
+ YES
+
+ YES
+ ActionCancel:
+ ActionFind:
+
+
+ YES
+ id
+ id
+
+
+
+ YES
+
+ YES
+ ActionCancel:
+ ActionFind:
+
+
+ YES
+
+ ActionCancel:
+ id
+
+
+ ActionFind:
+ id
+
+
+
+
+ YES
+
+ YES
+ _nameField
+ _nameToggle
+ _valueField
+ _valueToggle
+
+
+ YES
+ NSTextField
+ NSButton
+ NSTextField
+ NSButton
+
+
+
+ YES
+
+ YES
+ _nameField
+ _nameToggle
+ _valueField
+ _valueToggle
+
+
+ YES
+
+ _nameField
+ NSTextField
+
+
+ _nameToggle
+ NSButton
+
+
+ _valueField
+ NSTextField
+
+
+ _valueToggle
+ NSButton
+
+
+
+
+ IBProjectSource
+ ./Classes/FindWindowController.h
+
+
+
+
+ 0
+ IBCocoaFramework
+
+ com.apple.InterfaceBuilder.CocoaPlugin.InterfaceBuilder3
+
+
+ YES
+ 3
+
+ NSSwitch
+ {15, 15}
+
+
+
diff --git a/Mac/FindWindowController.cs b/Mac/FindWindowController.cs
new file mode 100644
index 0000000..4441673
--- /dev/null
+++ b/Mac/FindWindowController.cs
@@ -0,0 +1,79 @@
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using MonoMac.Foundation;
+using MonoMac.AppKit;
+
+namespace NBTExplorer.Mac
+{
+ public partial class FindWindowController : MonoMac.AppKit.NSWindowController
+ {
+ #region Constructors
+
+ // Called when created from unmanaged code
+ public FindWindowController (IntPtr handle) : base (handle)
+ {
+ Initialize ();
+ }
+
+ // Called when created directly from a XIB file
+ [Export ("initWithCoder:")]
+ public FindWindowController (NSCoder coder) : base (coder)
+ {
+ Initialize ();
+ }
+
+ // Call to load from the XIB/NIB file
+ public FindWindowController () : base ("FindWindow")
+ {
+ Initialize ();
+ }
+
+ // Shared initialization code
+ void Initialize ()
+ {
+ }
+
+ #endregion
+
+ //strongly typed window accessor
+ public new FindWindow Window
+ {
+ get {
+ return (FindWindow)base.Window;
+ }
+ }
+
+ public bool MatchName
+ {
+ get { return _nameToggle.State == NSCellStateValue.On; }
+ }
+
+ public bool MatchValue
+ {
+ get { return _valueToggle.State == NSCellStateValue.On; }
+ }
+
+ public string NameToken
+ {
+ get { return _nameField.StringValue; }
+ }
+
+ public string ValueToken
+ {
+ get { return _valueField.StringValue; }
+ }
+
+ partial void ActionFind (NSObject sender)
+ {
+ NSApplication.SharedApplication.StopModalWithCode((int)ModalResult.OK);
+ }
+
+ partial void ActionCancel (NSObject sender)
+ {
+ NSApplication.SharedApplication.StopModalWithCode((int)ModalResult.Cancel);
+ }
+ }
+}
+
diff --git a/Mac/MainWindow.cs b/Mac/MainWindow.cs
index 6f638ba..ef16bd9 100644
--- a/Mac/MainWindow.cs
+++ b/Mac/MainWindow.cs
@@ -8,6 +8,7 @@ using NBTExplorer.Mac;
using System.IO;
using NBTExplorer.Model;
using Substrate.Nbt;
+using System.Threading;
namespace NBTExplorer
{
@@ -31,6 +32,7 @@ namespace NBTExplorer
// Shared initialization code
void Initialize ()
{
+ Delegate = new WindowDelegate(this);
InitializeIconRegistry();
FormHandlers.Register();
NbtClipboardController.Initialize(new NbtClipboardControllerMac());
@@ -98,6 +100,22 @@ namespace NBTExplorer
}
}
+ public class WindowDelegate : NSWindowDelegate
+ {
+ private MainWindow _main;
+
+ public WindowDelegate (MainWindow main) {
+ _main = main;
+ }
+
+ public override bool WindowShouldClose (NSObject sender)
+ {
+ //Settings.Default.RecentFiles = Settings.Default.RecentFiles;
+ //Settings.Default.Save();
+ return _main.ConfirmExit();
+ }
+ }
+
public class MyDelegate : NSOutlineViewDelegate
{
private MainWindow _main;
@@ -163,11 +181,16 @@ namespace NBTExplorer
#region Actions
- partial void ActionOpenFolder (MonoMac.Foundation.NSObject sender)
+ partial void ActionOpenFolder (NSObject sender)
{
OpenFolder ();
}
+ partial void ActionSave (NSObject sender)
+ {
+ ActionSave ();
+ }
+
#endregion
private string _openFolderPath = null;
@@ -189,6 +212,23 @@ namespace NBTExplorer
UpdateUI();
}
+ private void OpenFile ()
+ {
+ NSOpenPanel opanel = new NSOpenPanel ();
+ opanel.CanChooseDirectories = false;
+ opanel.CanChooseFiles = true;
+ //opanel.AllowsMultipleSelection = true;
+
+ if (opanel.RunModal() == (int)NSPanelButtonType.Ok) {
+ List paths = new List();
+ foreach (var url in opanel.Urls)
+ paths.Add(url.Path);
+ OpenPaths(paths);
+ }
+
+ UpdateUI();
+ }
+
private void OpenMinecraftDirectory ()
{
try {
@@ -203,7 +243,7 @@ namespace NBTExplorer
OpenPaths(new string[] { path });
}
catch (Exception e) {
- //NSAlert.WithMessage("Could not open default Minecraft save directory", "OK", null, null, null).RunModal();
+ NSAlert.WithMessage("Operation Failed", "OK", null, null, "Could not open default Minecraft save directory").RunModal();
Console.WriteLine(e.Message);
try {
@@ -219,7 +259,7 @@ namespace NBTExplorer
UpdateUI();
}
- private void OpenPaths (string[] paths)
+ private void OpenPaths (IEnumerable paths)
{
_dataSource.Nodes.Clear ();
_mainOutlineView.ReloadData ();
@@ -242,37 +282,6 @@ namespace NBTExplorer
_mainOutlineView.ReloadData();
UpdateUI();
- // UpdateOpenMenu();
-
- /*_nodeTree.Nodes.Clear();
-
- foreach (string path in paths) {
- if (Directory.Exists(path)) {
- DirectoryDataNode node = new DirectoryDataNode(path);
- _nodeTree.Nodes.Add(CreateUnexpandedNode(node));
-
- AddPathToHistory(Settings.Default.RecentDirectories, path);
- }
- else if (File.Exists(path)) {
- DataNode node = null;
- foreach (var item in FileTypeRegistry.RegisteredTypes) {
- if (item.Value.NamePatternTest(path))
- node = item.Value.NodeCreate(path);
- }
-
- if (node != null) {
- _nodeTree.Nodes.Add(CreateUnexpandedNode(node));
- AddPathToHistory(Settings.Default.RecentFiles, path);
- }
- }
- }
-
- if (_nodeTree.Nodes.Count > 0) {
- _nodeTree.Nodes[0].Expand();
- }
-
- UpdateUI();
- UpdateOpenMenu();*/
}
private void ExpandNode (TreeDataNode node)
@@ -302,7 +311,7 @@ namespace NBTExplorer
if (node == null || !node.IsExpanded)
return;
- /*Console.WriteLine("Collapse Node: " + node.Data.NodeDisplay);
+ Console.WriteLine("Collapse Node: " + node.Data.NodeDisplay);
DataNode backNode = node.Data;
if (backNode.IsModified)
@@ -311,7 +320,7 @@ namespace NBTExplorer
backNode.Collapse();
node.IsExpanded = false;
- node.Nodes.Clear();*/
+ node.Nodes.Clear();
}
private void RefreshChildNodes (TreeDataNode node, DataNode dataNode)
@@ -361,6 +370,29 @@ namespace NBTExplorer
get { return _mainOutlineView.ItemAtRow (_mainOutlineView.SelectedRow) as TreeDataNode; }
}
+ public void ActionOpen ()
+ {
+ if (ConfirmOpen())
+ OpenFile();
+ }
+
+ public void ActionOpenFolder ()
+ {
+ if (ConfirmOpen ())
+ OpenFolder ();
+ }
+
+ public void ActionOpenMinecraft ()
+ {
+ if (ConfirmOpen ())
+ OpenMinecraftDirectory();
+ }
+
+ public void ActionSave ()
+ {
+ Save ();
+ }
+
public void ActionCopy ()
{
CopyNode (SelectedNode);
@@ -401,6 +433,16 @@ namespace NBTExplorer
MoveNodeDown (SelectedNode);
}
+ public void ActionFind ()
+ {
+ SearchNode (SelectedNode);
+ }
+
+ public void ActionFindNext ()
+ {
+ SearchNextNode();
+ }
+
public void ActionInsertByteTag ()
{
CreateNode (SelectedNode, TagType.TAG_BYTE);
@@ -567,50 +609,6 @@ namespace NBTExplorer
node.Data.ChangeRelativePosition(1);
RefreshChildNodes(node.Parent, node.Data.Parent);
}
-
- /*private void CopyNode (TreeNode node)
- {
- if (node == null || !(node.Tag is DataNode))
- return;
-
- DataNode dataNode = node.Tag as DataNode;
- if (!dataNode.CanCopyNode)
- return;
-
- dataNode.CopyNode();
- }
-
- private void CutNode (TreeNode node)
- {
- if (node == null || !(node.Tag is DataNode))
- return;
-
- DataNode dataNode = node.Tag as DataNode;
- if (!dataNode.CanCutNode)
- return;
-
- if (dataNode.CutNode()) {
- UpdateUI(node.Parent.Tag as DataNode);
- UpdateNodeText(node.Parent);
- node.Remove();
- }
- }
-
- private void PasteNode (TreeNode node)
- {
- if (node == null || !(node.Tag is DataNode))
- return;
-
- DataNode dataNode = node.Tag as DataNode;
- if (!dataNode.CanPasteIntoNode)
- return;
-
- if (dataNode.PasteNode()) {
- node.Text = dataNode.NodeDisplay;
- RefreshChildNodes(node, dataNode);
- UpdateUI(dataNode);
- }
- }*/
private void Save ()
{
@@ -621,16 +619,186 @@ namespace NBTExplorer
UpdateUI();
}
+
+ private static ModalResult RunWindow (NSWindowController controller)
+ {
+ int response = NSApplication.SharedApplication.RunModalForWindow (controller.Window);
+ controller.Window.Close();
+ controller.Window.OrderOut(null);
+
+ if (!Enum.IsDefined(typeof(ModalResult), response))
+ response = 0;
+
+ return (ModalResult)response;
+ }
+
+ private CancelFindWindowController _searchForm;
+ private SearchStateMac _searchState;
- /*private bool ConfirmExit ()
+ private void SearchNode (TreeDataNode node)
+ {
+ if (node == null)
+ return;
+
+ if (!node.Data.CanSearchNode)
+ return;
+
+ FindWindowController form = new FindWindowController();
+ if (RunWindow (form) != ModalResult.OK)
+ return;
+
+ _searchState = new SearchStateMac(this) {
+ RootNode = node.Data,
+ SearchName = form.NameToken,
+ SearchValue = form.ValueToken,
+ DiscoverCallback = SearchDiscoveryCallback,
+ CollapseCallback = SearchCollapseCallback,
+ EndCallback = SearchEndCallback,
+ };
+
+ SearchNextNode();
+ }
+
+ private void SearchNextNode ()
+ {
+ if (_searchState == null)
+ return;
+
+ SearchWorker worker = new SearchWorker (_searchState);
+
+ Thread t = new Thread (new ThreadStart (worker.Run));
+ t.IsBackground = true;
+ t.Start ();
+
+ _searchForm = new CancelFindWindowController ();
+ if (RunWindow (_searchForm) == ModalResult.Cancel) {
+ worker.Cancel();
+ _searchState = null;
+ }
+
+ t.Join();
+ }
+
+ private void SearchDiscoveryCallback (DataNode node)
+ {
+ Console.WriteLine ("Discovery: " + node.NodeDisplay);
+ TreeDataNode frontNode = FindFrontNode(node);
+ Console.WriteLine (" Front Node: " + frontNode.Data.NodeDisplay);
+ _mainOutlineView.SelectRow (_mainOutlineView.RowForItem(frontNode), false);
+ _mainOutlineView.ScrollRowToVisible(_mainOutlineView.RowForItem(frontNode));
+ //_nodeTree.SelectedNode = FindFrontNode(node);
+
+ if (_searchForm != null) {
+ _searchForm.Accept();
+ _searchForm = null;
+ }
+ }
+
+ private void SearchCollapseCallback (DataNode node)
+ {
+ CollapseBelow(node);
+ }
+
+ private void SearchEndCallback (DataNode node)
+ {
+ _searchForm.Cancel();
+ _searchForm = null;
+
+ NSAlert.WithMessage("End of Results", "OK", null, null, "").RunModal();
+ }
+
+ private TreeDataNode GetRootFromDataNodePath (DataNode node, out Stack hierarchy)
+ {
+ hierarchy = new Stack();
+ while (node != null) {
+ hierarchy.Push(node);
+ node = node.Parent;
+ }
+
+ DataNode rootDataNode = hierarchy.Pop();
+ TreeDataNode frontNode = null;
+ foreach (TreeDataNode child in _dataSource.Nodes) {
+ if (child.Data == rootDataNode)
+ frontNode = child;
+ }
+
+ return frontNode;
+ }
+
+ private TreeDataNode FindFrontNode (DataNode node)
+ {
+ Stack hierarchy;
+ TreeDataNode frontNode = GetRootFromDataNodePath(node, out hierarchy);
+
+ if (frontNode == null)
+ return null;
+
+ while (hierarchy.Count > 0) {
+ if (!frontNode.IsExpanded) {
+ _mainOutlineView.ExpandItem(frontNode);
+ _mainOutlineView.ReloadItem(frontNode);
+ }
+
+ DataNode childData = hierarchy.Pop();
+ foreach (TreeDataNode childFront in frontNode.Nodes) {
+ if (childFront.Data == childData) {
+ frontNode = childFront;
+ break;
+ }
+ }
+ }
+
+ return frontNode;
+ }
+
+ private void CollapseBelow (DataNode node)
+ {
+ Stack hierarchy;
+ TreeDataNode frontNode = GetRootFromDataNodePath (node, out hierarchy);
+
+ if (frontNode == null)
+ return;
+
+ while (hierarchy.Count > 0) {
+ if (!frontNode.IsExpanded)
+ return;
+
+ DataNode childData = hierarchy.Pop ();
+ foreach (TreeDataNode childFront in frontNode.Nodes) {
+ if (childFront.Data == childData) {
+ frontNode = childFront;
+ break;
+ }
+ }
+ }
+
+ if (frontNode.IsExpanded) {
+ _mainOutlineView.CollapseItem (frontNode);
+ frontNode.IsExpanded = false;
+ }
+ }
+
+ private bool ConfirmExit ()
{
if (CheckModifications()) {
- if (MessageBox.Show("You currently have unsaved changes. Close anyway?", "Unsaved Changes", MessageBoxButtons.OKCancel) != DialogResult.OK)
+ int id = NSAlert.WithMessage("Unsaved Changes", "OK", "Cancel", "", "You currently have unsaved changes. Close anyway?").RunModal();
+ if (id != 1)
return false;
}
return true;
- }*/
+ }
+
+ private bool ConfirmOpen ()
+ {
+ if (CheckModifications()) {
+ int id = NSAlert.WithMessage("Unsaved Changes", "OK", "Cancel", "", "You currently have unsaved changes. Open new location anyway?").RunModal();
+ if (id != 1)
+ return false;
+ }
+
+ return true;
+ }
private bool CheckModifications ()
{
@@ -656,7 +824,7 @@ namespace NBTExplorer
_appDelegate.MenuSave.Enabled = CheckModifications();
_appDelegate.MenuFind.Enabled = false;
- //_appDelegate.MenuFindNext.Enabled = _searchState != null;
+ _appDelegate.MenuFindNext.Enabled = _searchState != null;
_toolbarSave.Enabled = _appDelegate.MenuSave.Enabled;
}
@@ -689,7 +857,7 @@ namespace NBTExplorer
_appDelegate.MenuMoveUp.Enabled = node.CanMoveNodeUp;
_appDelegate.MenuMoveDown.Enabled = node.CanMoveNodeDown;
_appDelegate.MenuFind.Enabled = node.CanSearchNode;
- //_appDelegate.MenuFindNext.Enabled = _searchState != null;
+ _appDelegate.MenuFindNext.Enabled = _searchState != null;
_toolbarSave.Enabled = _appDelegate.MenuSave.Enabled;
}
diff --git a/Mac/MainWindow.xib b/Mac/MainWindow.xib
index 234f7aa..fae3f15 100644
--- a/Mac/MainWindow.xib
+++ b/Mac/MainWindow.xib
@@ -2,10 +2,10 @@
1080
- 12B2080
+ 12C2034
2844
- 1187
- 624.00
+ 1187.34
+ 625.00
com.apple.InterfaceBuilder.CocoaPlugin
2844
@@ -70,6 +70,7 @@
YES
0156226B-2E18-4406-BBE6-7C88F62B4E27
+ A7443D4A-610D-4239-8FC6-AD74A87D607E
B62CA8DD-7D49-4BF3-B4AB-417078852D8B
NSToolbarFlexibleSpaceItem
NSToolbarSpaceItem
@@ -93,7 +94,29 @@
{0, 0}
{0, 0}
YES
- YES
+ NO
+ -1
+ YES
+ 0
+
+
+
+ A7443D4A-610D-4239-8FC6-AD74A87D607E
+
+ Rename
+ Rename
+
+
+
+ NSImage
+ selection-input-24
+
+
+
+ {0, 0}
+ {0, 0}
+ YES
+ NO
-1
YES
0
@@ -115,7 +138,7 @@
{0, 0}
{0, 0}
YES
- YES
+ NO
-1
YES
0
@@ -182,17 +205,20 @@
-
+
YES
+
YES
+
+
@@ -338,6 +364,7 @@
{{1, 544}, {761, 15}}
+
_NS:60
NO
1
@@ -527,6 +554,7 @@
+
@@ -619,6 +647,11 @@
+
+ 78
+
+
+
@@ -650,6 +683,7 @@
72.IBPluginDependency
73.IBPluginDependency
74.IBPluginDependency
+ 78.IBPluginDependency
YES
@@ -678,6 +712,7 @@
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
com.apple.InterfaceBuilder.CocoaPlugin
+ com.apple.InterfaceBuilder.CocoaPlugin
@@ -692,7 +727,7 @@
- 77
+ 78
@@ -824,6 +859,7 @@
NSMenuMixedState
disk-24
folder-open-24
+ selection-input-24
YES
@@ -831,6 +867,7 @@
{10, 3}
{24, 24}
{24, 24}
+ {24, 24}
diff --git a/Mac/SearchStateMac.cs b/Mac/SearchStateMac.cs
new file mode 100644
index 0000000..9a9499b
--- /dev/null
+++ b/Mac/SearchStateMac.cs
@@ -0,0 +1,61 @@
+using System;
+using MonoMac.AppKit;
+using NBTExplorer.Model;
+using System.Collections.Generic;
+
+namespace NBTExplorer.Mac
+{
+ public class SearchStateMac : ISearchState
+ {
+ private NSWindow _sender;
+
+ public SearchStateMac (NSWindow sender)
+ {
+ _sender = sender;
+ }
+
+ public Action DiscoverCallback { get; set; }
+ public Action ProgressCallback { get; set; }
+ public Action CollapseCallback { get; set; }
+ public Action EndCallback { get; set; }
+
+ #region ISearchState
+
+ public DataNode RootNode { get; set; }
+ public string SearchName { get; set; }
+ public string SearchValue { get; set; }
+
+ public IEnumerator State { get; set; }
+
+ public void InvokeDiscoverCallback (DataNode node)
+ {
+ if (_sender != null && DiscoverCallback != null)
+ _sender.BeginInvokeOnMainThread(delegate { DiscoverCallback(node); });
+ //_sender.BeginInvokeOnMainThread(DiscoverCallback, new object[] { node });
+ }
+
+ public void InvokeProgressCallback (DataNode node)
+ {
+ if (_sender != null && ProgressCallback != null)
+ _sender.BeginInvokeOnMainThread(delegate { ProgressCallback(node); });
+ //_sender.BeginInvokeOnMainThread(ProgressCallback, new object[] { node });
+ }
+
+ public void InvokeCollapseCallback (DataNode node)
+ {
+ if (_sender != null && CollapseCallback != null)
+ _sender.BeginInvokeOnMainThread(delegate { CollapseCallback(node); });
+ //_sender.BeginInvokeOnMainThread(CollapseCallback, new object[] { node });
+ }
+
+ public void InvokeEndCallback (DataNode node)
+ {
+ if (_sender != null && EndCallback != null)
+ _sender.BeginInvokeOnMainThread(delegate { EndCallback(node); });
+ //_sender.BeginInvokeOnMainThread(EndCallback, new object[] { node });
+ }
+
+ #endregion
+ }
+}
+
diff --git a/Mac/TreeDataNode.cs b/Mac/TreeDataNode.cs
index 4f48e18..5683ae9 100644
--- a/Mac/TreeDataNode.cs
+++ b/Mac/TreeDataNode.cs
@@ -53,7 +53,7 @@ namespace NBTExplorer.Mac
public bool HasChildren
{
- get { return _children.Count > 0 || _dataNode.HasUnexpandedChildren; }
+ get { return _children.Count > 0 || _dataNode.Nodes.Count > 0 || _dataNode.HasUnexpandedChildren; }
}
public void AddNode (TreeDataNode node)
diff --git a/Mac/TreeDataSource.cs b/Mac/TreeDataSource.cs
index 2791c2e..5361c65 100644
--- a/Mac/TreeDataSource.cs
+++ b/Mac/TreeDataSource.cs
@@ -51,8 +51,9 @@ namespace NBTExplorer.Mac
public override bool ItemExpandable (NSOutlineView outlineView, NSObject item)
{
TreeDataNode nodeItem = item as TreeDataNode;
- if (nodeItem != null)
+ if (nodeItem != null) {
return nodeItem.HasChildren;
+ }
return false;
}
diff --git a/NBTExplorerMac.csproj b/NBTExplorerMac.csproj
index 347a7bc..40c75bb 100644
--- a/NBTExplorerMac.csproj
+++ b/NBTExplorerMac.csproj
@@ -185,6 +185,17 @@
+
+
+
+
+ FindWindow.cs
+
+
+
+
+ CancelFindWindow.cs
+
@@ -245,6 +256,8 @@
+
+