Commits

Ivan Vučica committed c43cb8b

Some old work on drag&drop, copy paste, etc (cca May 4th 2012)

  • Participants
  • Parent commits 96092e0

Comments (0)

Files changed (5)

OPML/OPMLAppDelegate.m

 #import "OPMLOpenURLDialog.h"
 #import "OPMLPreferences.h"
 #import "OPMLDocument.h"
+#import "OPMLOutline.h"
+#import "OPMLOutline+ViewRelated.h"
 
 @implementation OPMLAppDelegate
 
 {
     [_preferences release]; _preferences = nil;
 }
+-(void)applicationDidFinishLaunching:(NSNotification *)notification
+{
+    [NSApp registerServicesMenuSendTypes:[NSArray arrayWithObjects:OPMLOutline_NodeDragAndDropPboardType, NSPasteboardTypeString, nil] returnTypes:[NSArray arrayWithObject:NSPasteboardTypeString]];
+}
 -(void)dealloc
 {
     [_preferences release];

OPML/OPMLDocument.m

     [self expandUsingExpansionState];
     [self scrollUsingVertScrollState];
     
+    // Allow dropping of nodes into node list
+    [_outlineView registerForDraggedTypes:[NSArray arrayWithObjects:OPMLOutline_NodeDragAndDropPboardType, nil]];
+    
     /*
     NSWindow * window = [[[self windowControllers] objectAtIndex:0] window];
     NSText * fe = [window fieldEditor:YES forObject:nil];

OPML/OPMLOutline+ViewRelated.h

 #if !GNUSTEP
 <NSOutlineViewDataSource, NSOutlineViewDelegate>
 #endif
+- (NSArray *)writablePasteboardTypes;
+@end
 
-@end
+extern NSString *OPMLOutline_NodeDragAndDropPboardType;
+
+#if GNUSTEP
+#define NSPasteboardTypeString NSStringPboardType
+#endif

OPML/OPMLOutline+ViewRelated.m

 #import "OPMLOutline+ViewRelated.h"
 #import "OPMLOutline+Private.h"
 #import "OPMLOutlineXMLElement.h"
+#import "OPMLOutlineView.h"
+
+NSString *OPMLOutline_NodeDragAndDropPboardType = @"OPMLOutline_NodeDragAndDropPboardType";
 
 #if GNUSTEP
 #warning This is probably defined somewhere.
     //[cell setImage:[NSImage imageNamed:@"NSAddTemplate"]];
     
 }
+- (NSArray *)writablePasteboardTypes {
+    return [NSArray arrayWithObjects:
+            NSPasteboardTypeString,
+            OPMLOutline_NodeDragAndDropPboardType, 
+            
+            nil];
+}
+
+- (BOOL)outlineView:(NSOutlineView *)outlineView
+         writeItems:(NSArray *)items
+       toPasteboard:(NSPasteboard *)pasteboard
+{
+    if(items.count > 1)
+        return NO;
+    OPMLOutlineXMLElement * element = [items objectAtIndex:0];
+    NSString * xpath = [element XPath];
+    NSString * xml = [element XMLString];
+    NSDictionary * dict = [NSDictionary dictionaryWithObjectsAndKeys:xpath, @"xpath", xml, @"xml", nil];
+    
+    [pasteboard declareTypes:[self writablePasteboardTypes]
+                       owner:self];
+    
+    [pasteboard setData:[NSKeyedArchiver archivedDataWithRootObject:dict]
+                forType:OPMLOutline_NodeDragAndDropPboardType];
+    [pasteboard setString:xml
+                  forType:NSPasteboardTypeString];
+    return YES;
+}
+- (NSDragOperation)outlineView:(NSOutlineView *)outlineView
+                  validateDrop:(id<NSDraggingInfo>)info
+                  proposedItem:(id)item
+            proposedChildIndex:(NSInteger)index
+{
+    /*
+    NSLog(@"validating drop into %p", outlineView);
+    NSLog(@"Proposed item %p", item);
+     */
+    
+    NSPasteboard* pboard = [info draggingPasteboard];
+    OPMLOutlineView* sourceOutline = [info draggingSource];
+    NSData * incomingData = [pboard dataForType:OPMLOutline_NodeDragAndDropPboardType];
+    NSDictionary * incomingDict = [NSKeyedUnarchiver unarchiveObjectWithData:incomingData];
+    NSString * incomingXPath = [incomingDict objectForKey:@"xpath"];
+    NSString * incomingXML = [incomingDict objectForKey:@"xml"];
+#pragma unused(incomingXML)
+    
+    if(outlineView != sourceOutline)
+        return NSDragOperationCopy & [info draggingSourceOperationMask];
+    
+    id draggedItem = [[self nodesForXPath:incomingXPath error:nil] objectAtIndex:0];
+    
+    if(!item)
+        item = [self bodyNode];
+    
+    NSMutableArray * queue = [NSMutableArray arrayWithObject:draggedItem];
+    while([queue count])
+    {
+        OPMLOutlineXMLElement * frontItem = [queue objectAtIndex:0];
+        if(frontItem == item)
+            return NSDragOperationNone;
+        [queue addObjectsFromArray:[frontItem children]];
+        [queue removeObjectAtIndex:0];
+    }
+    
+    return NSDragOperationMove & [info draggingSourceOperationMask];
+}
+- (BOOL)outlineView:(NSOutlineView *)outlineView
+         acceptDrop:(id<NSDraggingInfo>)info
+               item:(id)item
+         childIndex:(NSInteger)index
+{
+    NSPasteboard* pboard = [info draggingPasteboard];
+    OPMLOutlineView* sourceOutline = [info draggingSource];
+    NSData * incomingData = [pboard dataForType:OPMLOutline_NodeDragAndDropPboardType];
+    NSDictionary * incomingDict = [NSKeyedUnarchiver unarchiveObjectWithData:incomingData];
+    NSString * incomingXPath = [incomingDict objectForKey:@"xpath"];
+    NSString * incomingXML = [incomingDict objectForKey:@"xml"];
+
+    // Move the specified row to its new location...
+    
+    return YES;
+}
+
+
 
 @end

OPML/OPMLOutlineView.m

 //
 
 #import "OPMLOutlineView.h"
+#import "OPMLOutline+ViewRelated.h"
 
 #if GNUSTEP
 #define CGRect NSRect
     frame.size.height = [self rowHeight];
     return frame;
 }
+- (id)validRequestorForSendType:(NSString *)sendType returnType:(NSString *)returnType
+{
+    NSLog(@"Inquiring about %@ and %@", sendType, returnType);
+    if([sendType isEqualToString:OPMLOutline_NodeDragAndDropPboardType] && [returnType isEqualToString:NSPasteboardTypeString])
+        return self;
+    if([sendType isEqualToString:NSPasteboardTypeString] && [returnType isEqualToString:NSPasteboardTypeString])
+        return self;
+    
+    if(sendType == nil && [returnType isEqualToString:NSPasteboardTypeString])
+        return self;
+    
+    if([sendType isEqualToString:OPMLOutline_NodeDragAndDropPboardType] && returnType == nil)
+        return self;
+    if([sendType isEqualToString:NSPasteboardTypeString] && returnType == nil)
+        return self;
+    
+    return [super validRequestorForSendType:sendType returnType:returnType];
+}
+- (BOOL)writeSelectionToPasteboard:(NSPasteboard *)pboard types:(NSArray *)types
+{
+    return [[self dataSource] outlineView:self 
+                               writeItems:[NSArray arrayWithObject:[self itemAtRow:[self selectedRow]]]
+                             toPasteboard:pboard];
+}
+
+- (IBAction)copy:(id)sender
+{
+    NSPasteboard * pboard = [NSPasteboard generalPasteboard];
+    [self writeSelectionToPasteboard:pboard types:[((OPMLOutline*)[self dataSource]) writablePasteboardTypes]];
+}
+
+- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal
+{
+    if(isLocal)
+        return NSDragOperationMove | NSDragOperationCopy;
+    else
+        return NSDragOperationCopy;
+}
 @end