forked from mirrors/NBTExplorer
Working clipboard support, albeit by hacks.
This commit is contained in:
parent
45dac1389d
commit
e11c0c4d9d
7 changed files with 261 additions and 9 deletions
|
@ -4,10 +4,8 @@
|
||||||
<dict>
|
<dict>
|
||||||
<key>CFBundleDocumentTypes</key>
|
<key>CFBundleDocumentTypes</key>
|
||||||
<array/>
|
<array/>
|
||||||
<key>CFBundleIconFiles</key>
|
<key>CFBundleIconFile</key>
|
||||||
<array>
|
<string>nbte.icns</string>
|
||||||
<string>dead_bush.icns</string>
|
|
||||||
</array>
|
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
<string>jaquadro.NBTExplorer</string>
|
<string>jaquadro.NBTExplorer</string>
|
||||||
<key>CFBundleName</key>
|
<key>CFBundleName</key>
|
||||||
|
|
|
@ -156,6 +156,21 @@ namespace NBTExplorer
|
||||||
get { return _menuInsertCompound; }
|
get { return _menuInsertCompound; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
partial void ActionCut (MonoMac.Foundation.NSObject sender)
|
||||||
|
{
|
||||||
|
mainWindowController.Window.ActionCut();
|
||||||
|
}
|
||||||
|
|
||||||
|
partial void ActionCopy (MonoMac.Foundation.NSObject sender)
|
||||||
|
{
|
||||||
|
mainWindowController.Window.ActionCopy();
|
||||||
|
}
|
||||||
|
|
||||||
|
partial void ActionPaste (MonoMac.Foundation.NSObject sender)
|
||||||
|
{
|
||||||
|
mainWindowController.Window.ActionPaste();
|
||||||
|
}
|
||||||
|
|
||||||
partial void ActionRename (NSObject sender)
|
partial void ActionRename (NSObject sender)
|
||||||
{
|
{
|
||||||
mainWindowController.Window.ActionRenameValue();
|
mainWindowController.Window.ActionRenameValue();
|
||||||
|
|
|
@ -33,6 +33,7 @@ namespace NBTExplorer
|
||||||
{
|
{
|
||||||
InitializeIconRegistry();
|
InitializeIconRegistry();
|
||||||
FormHandlers.Register();
|
FormHandlers.Register();
|
||||||
|
NbtClipboardController.Initialize(new NbtClipboardControllerMac());
|
||||||
}
|
}
|
||||||
|
|
||||||
private AppDelegate _appDelegate;
|
private AppDelegate _appDelegate;
|
||||||
|
@ -360,6 +361,21 @@ namespace NBTExplorer
|
||||||
get { return _mainOutlineView.ItemAtRow (_mainOutlineView.SelectedRow) as TreeDataNode; }
|
get { return _mainOutlineView.ItemAtRow (_mainOutlineView.SelectedRow) as TreeDataNode; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ActionCopy ()
|
||||||
|
{
|
||||||
|
CopyNode (SelectedNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ActionCut ()
|
||||||
|
{
|
||||||
|
CutNode (SelectedNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ActionPaste ()
|
||||||
|
{
|
||||||
|
PasteNode (SelectedNode);
|
||||||
|
}
|
||||||
|
|
||||||
public void ActionEditValue ()
|
public void ActionEditValue ()
|
||||||
{
|
{
|
||||||
EditNode(SelectedNode);
|
EditNode(SelectedNode);
|
||||||
|
@ -440,6 +456,48 @@ namespace NBTExplorer
|
||||||
CreateNode (SelectedNode, TagType.TAG_COMPOUND);
|
CreateNode (SelectedNode, TagType.TAG_COMPOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CopyNode (TreeDataNode node)
|
||||||
|
{
|
||||||
|
if (node == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!node.Data.CanCopyNode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
node.Data.CopyNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CutNode (TreeDataNode node)
|
||||||
|
{
|
||||||
|
if (node == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!node.Data.CanCutNode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (node.Data.CutNode()) {
|
||||||
|
TreeDataNode parent = node.Parent;
|
||||||
|
UpdateUI(parent.Data);
|
||||||
|
node.Remove();
|
||||||
|
_mainOutlineView.ReloadItem(parent, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PasteNode (TreeDataNode node)
|
||||||
|
{
|
||||||
|
if (node == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!node.Data.CanPasteIntoNode)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (node.Data.PasteNode()) {
|
||||||
|
//node.Text = dataNode.NodeDisplay;
|
||||||
|
RefreshChildNodes(node, node.Data);
|
||||||
|
UpdateUI(node.Data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void EditNode (TreeDataNode node)
|
private void EditNode (TreeDataNode node)
|
||||||
{
|
{
|
||||||
if (node == null)
|
if (node == null)
|
||||||
|
@ -622,9 +680,9 @@ namespace NBTExplorer
|
||||||
_appDelegate.MenuInsertCompound.Enabled = node.CanCreateTag(TagType.TAG_COMPOUND);
|
_appDelegate.MenuInsertCompound.Enabled = node.CanCreateTag(TagType.TAG_COMPOUND);
|
||||||
|
|
||||||
_appDelegate.MenuSave.Enabled = CheckModifications();
|
_appDelegate.MenuSave.Enabled = CheckModifications();
|
||||||
_appDelegate.MenuCopy.Enabled = node.CanCopyNode;
|
_appDelegate.MenuCopy.Enabled = node.CanCopyNode && NbtClipboardController.IsInitialized;
|
||||||
_appDelegate.MenuCut.Enabled = node.CanCutNode;
|
_appDelegate.MenuCut.Enabled = node.CanCutNode && NbtClipboardController.IsInitialized;
|
||||||
_appDelegate.MenuPaste.Enabled = node.CanPasteIntoNode;
|
_appDelegate.MenuPaste.Enabled = node.CanPasteIntoNode && NbtClipboardController.IsInitialized;
|
||||||
_appDelegate.MenuDelete.Enabled = node.CanDeleteNode;
|
_appDelegate.MenuDelete.Enabled = node.CanDeleteNode;
|
||||||
_appDelegate.MenuEditValue.Enabled = node.CanEditNode;
|
_appDelegate.MenuEditValue.Enabled = node.CanEditNode;
|
||||||
_appDelegate.MenuRename.Enabled = node.CanRenameNode;
|
_appDelegate.MenuRename.Enabled = node.CanRenameNode;
|
||||||
|
|
175
Mac/NbtClipboardControllerMac.cs
Normal file
175
Mac/NbtClipboardControllerMac.cs
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
using System;
|
||||||
|
using MonoMac.AppKit;
|
||||||
|
using MonoMac.Foundation;
|
||||||
|
using MonoMac.ObjCRuntime;
|
||||||
|
using Substrate.Nbt;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace NBTExplorer.Mac
|
||||||
|
{
|
||||||
|
public class NbtClipboardControllerMac : INbtClipboardController
|
||||||
|
{
|
||||||
|
public void CopyToClipboard (NbtClipboardData data)
|
||||||
|
{
|
||||||
|
NbtClipboardDataMac dataItem = new NbtClipboardDataMac(data);
|
||||||
|
|
||||||
|
NSPasteboard pasteboard = NSPasteboard.GeneralPasteboard;
|
||||||
|
pasteboard.ClearContents();
|
||||||
|
pasteboard.WriteObjects(new NSPasteboardReading[] { dataItem });
|
||||||
|
}
|
||||||
|
|
||||||
|
public NbtClipboardData CopyFromClipboard ()
|
||||||
|
{
|
||||||
|
NSPasteboard pasteboard = NSPasteboard.GeneralPasteboard;
|
||||||
|
NSObject[] items = pasteboard.ReadObjectsForClasses (new NSPasteboardReading[] { NbtClipboardDataMac.Type }, new NSDictionary());
|
||||||
|
|
||||||
|
foreach (NbtClipboardDataMac item in items) {
|
||||||
|
if (item == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
TagNode node = item.Node;
|
||||||
|
if (node == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return new NbtClipboardData(item.Name, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ContainsData
|
||||||
|
{
|
||||||
|
get {
|
||||||
|
NSPasteboard pasteboard = NSPasteboard.GeneralPasteboard;
|
||||||
|
NSObject[] items = pasteboard.ReadObjectsForClasses (new NSPasteboardReading[] { NbtClipboardDataMac.Type }, new NSDictionary());
|
||||||
|
return items != null && items.Length > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Adopts("NSCoding")]
|
||||||
|
[Adopts("NSPasteboardReading")]
|
||||||
|
[Adopts("NSPasteboardWriting")]
|
||||||
|
[Register("NbtClipboardDataMac")]
|
||||||
|
public class NbtClipboardDataMac : NSPasteboardReading
|
||||||
|
{
|
||||||
|
static AdoptsAttribute _writingProtocol = new AdoptsAttribute ("NSPasteboardWriting");
|
||||||
|
static AdoptsAttribute _readingProtocol = new AdoptsAttribute ("NSPasteboardReading");
|
||||||
|
static AdoptsAttribute _codingProtocol = new AdoptsAttribute("NSCoding");
|
||||||
|
|
||||||
|
private static string _pasteboardItemName = "jaquadro.nbtexplorer.nbtClipboardDataMac";
|
||||||
|
|
||||||
|
public static NbtClipboardDataMac Type
|
||||||
|
{
|
||||||
|
get {
|
||||||
|
NbtClipboardDataMac inst = new NbtClipboardDataMac ();
|
||||||
|
return inst;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private string _name;
|
||||||
|
private byte[] _data;
|
||||||
|
|
||||||
|
private bool _bypassProtocolCheck = true;
|
||||||
|
|
||||||
|
private NbtClipboardDataMac ()
|
||||||
|
{
|
||||||
|
_name = "";
|
||||||
|
_data = new byte[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public NbtClipboardDataMac (NbtClipboardData data)
|
||||||
|
{
|
||||||
|
Name = data.Name;
|
||||||
|
Node = data.Node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool ConformsToProtocol (IntPtr protocol)
|
||||||
|
{
|
||||||
|
// XXX: This is a hack! There seems to be a bug in MonoMac resulting in different handle addresses
|
||||||
|
// for two protocols of (seemingly) the same name, so we have no way to make objc accept that we
|
||||||
|
// implement a given protocol. objc runtime method protocol_getName should be able to help us, but it
|
||||||
|
// crashes the runtime.
|
||||||
|
if (_bypassProtocolCheck)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (protocol == _readingProtocol.ProtocolHandle)
|
||||||
|
return true;
|
||||||
|
if (protocol == _writingProtocol.ProtocolHandle)
|
||||||
|
return true;
|
||||||
|
if (protocol == _codingProtocol.ProtocolHandle)
|
||||||
|
return true;
|
||||||
|
return base.ConformsToProtocol (protocol);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get { return _name; }
|
||||||
|
set { _name = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public TagNode Node
|
||||||
|
{
|
||||||
|
get { return NbtClipboardData.DeserializeNode(_data); }
|
||||||
|
set { _data = NbtClipboardData.SerializeNode(value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
[Export ("initWithCoder:")]
|
||||||
|
public NbtClipboardDataMac (NSCoder coder)
|
||||||
|
: base(NSObjectFlag.Empty)
|
||||||
|
{
|
||||||
|
_name = (NSString)coder.DecodeObject("name");
|
||||||
|
_data = coder.DecodeBytes("data");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Export ("encodeWithCoder:")]
|
||||||
|
public void Encode (NSCoder coder)
|
||||||
|
{
|
||||||
|
coder.Encode ((NSString)_name, "name");
|
||||||
|
coder.Encode (_data, "data");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Export("writableTypesForPasteboard:")]
|
||||||
|
public string[] GetWritableTypesForPasteboard (NSPasteboard pasteboard)
|
||||||
|
{
|
||||||
|
return new string[] { _pasteboardItemName };
|
||||||
|
}
|
||||||
|
|
||||||
|
[Export("pasteboardPropertyListForType:")]
|
||||||
|
public NSObject GetPasteboardPropertyListForType (string type)
|
||||||
|
{
|
||||||
|
if (type == _pasteboardItemName)
|
||||||
|
return NSKeyedArchiver.ArchivedDataWithRootObject(this);
|
||||||
|
else
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Export ("writingOptionsForType:pasteboard:")]
|
||||||
|
public NSPasteboardWritingOptions GetWritingOptionsForType (string type, NSPasteboard pasteboard)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string[] GetReadableTypesForPasteboard (NSPasteboard pasteboard)
|
||||||
|
{
|
||||||
|
return new string[] { _pasteboardItemName };
|
||||||
|
}
|
||||||
|
|
||||||
|
public override NSPasteboardReadingOptions GetReadingOptionsForType (string type, NSPasteboard pasteboard)
|
||||||
|
{
|
||||||
|
if (type == _pasteboardItemName)
|
||||||
|
return NSPasteboardReadingOptions.AsKeyedArchive;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// XXX: This is a hack. Not sure how to properly implement, but it's required either by pasteboard reading,
|
||||||
|
// or is a side-effect of our protocol conformance hack.
|
||||||
|
[Export("isSubclassOfClass:")]
|
||||||
|
public bool IsSubclassOf (NSObject cl)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -69,8 +69,8 @@
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System.Windows.Forms" />
|
<Reference Include="System.Windows.Forms" />
|
||||||
<Reference Include="System.Data" />
|
<Reference Include="System.Data" />
|
||||||
<Reference Include="MonoMac, Version=0.0.0.0, Culture=neutral">
|
<Reference Include="MonoMac">
|
||||||
<Private>False</Private>
|
<HintPath>..\monomac\src\MonoMac.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -183,6 +183,8 @@
|
||||||
<Compile Include="Mac\EditValueWindow.designer.cs">
|
<Compile Include="Mac\EditValueWindow.designer.cs">
|
||||||
<DependentUpon>EditValueWindow.cs</DependentUpon>
|
<DependentUpon>EditValueWindow.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="NbtClipboardController.cs" />
|
||||||
|
<Compile Include="Mac\NbtClipboardControllerMac.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<BundleResource Include="Resources\Dead_Bush.png" />
|
<BundleResource Include="Resources\Dead_Bush.png" />
|
||||||
|
@ -244,4 +246,8 @@
|
||||||
<InterfaceDefinition Include="Mac\CreateNodeWindow.xib" />
|
<InterfaceDefinition Include="Mac\CreateNodeWindow.xib" />
|
||||||
<InterfaceDefinition Include="Mac\EditValueWindow.xib" />
|
<InterfaceDefinition Include="Mac\EditValueWindow.xib" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="Resources\Dead_Bush_256.icns" />
|
||||||
|
<Content Include="nbte.icns" />
|
||||||
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
BIN
Resources/Dead_Bush_256.icns
Normal file
BIN
Resources/Dead_Bush_256.icns
Normal file
Binary file not shown.
BIN
nbte.icns
Normal file
BIN
nbte.icns
Normal file
Binary file not shown.
Loading…
Reference in a new issue