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 + + com.apple.InterfaceBuilder.CocoaPlugin + 2844 + + + YES + NSButton + NSButtonCell + NSCustomObject + NSView + NSWindowTemplate + + + YES + com.apple.InterfaceBuilder.CocoaPlugin + + + PluginDependencyRecalculationVersion + + + + YES + + CancelFindWindowController + + + FirstResponder + + + NSApplication + + + 1 + 2 + {{131, 74}, {398, 100}} + 611844096 + Searching... + CancelFindWindow + + + + + 256 + + YES + + + 268 + {{158, 13}, {82, 32}} + + + _NS:9 + YES + + 67108864 + 134217728 + Cancel + + LucidaGrande + 13 + 1044 + + _NS:9 + + -2038284288 + 129 + + Gw + 200 + 25 + + NO + + + {398, 100} + + + + {{0, 0}, {1280, 778}} + {10000000000000, 10000000000000} + YES + + + + + 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 @@ + +