Implement copy & paste
This commit is contained in:
parent
8c9f0ae12d
commit
bb4094f238
|
@ -38,6 +38,7 @@
|
||||||
- (IBAction)mediaSkipBackward:(id)sender;
|
- (IBAction)mediaSkipBackward:(id)sender;
|
||||||
- (IBAction)mediaSkipForward:(id)sender;
|
- (IBAction)mediaSkipForward:(id)sender;
|
||||||
- (IBAction)toggleMediaPlay:(id)sender;
|
- (IBAction)toggleMediaPlay:(id)sender;
|
||||||
|
- (IBAction)delete:(id)sender;
|
||||||
- (QTTime)currentMovieTime;
|
- (QTTime)currentMovieTime;
|
||||||
- (void)moviePanelDidAppear;
|
- (void)moviePanelDidAppear;
|
||||||
- (void)moviePanelDidClose;
|
- (void)moviePanelDidClose;
|
||||||
|
|
|
@ -282,6 +282,9 @@ static const char * kMADocWindowObserver = "MADocWindowObserver";
|
||||||
)
|
)
|
||||||
return YES;
|
return YES;
|
||||||
|
|
||||||
|
if ([item action] == @selector(paste:))
|
||||||
|
return [self canPaste];
|
||||||
|
|
||||||
NSMenuItem * menuItem = (NSMenuItem *)item;
|
NSMenuItem * menuItem = (NSMenuItem *)item;
|
||||||
if ([item action] == @selector(toggleMediaPlay:)) {
|
if ([item action] == @selector(toggleMediaPlay:)) {
|
||||||
if ([currentMovie rate] > 0.0f)
|
if ([currentMovie rate] > 0.0f)
|
||||||
|
|
|
@ -44,8 +44,11 @@
|
||||||
{
|
{
|
||||||
NSString * path = [url absoluteString];
|
NSString * path = [url absoluteString];
|
||||||
NSNumber * size;
|
NSNumber * size;
|
||||||
[url getResourceValue:&size forKey:NSURLFileSizeKey error:nil];
|
int64_t fileSize;
|
||||||
int64_t fileSize = [size longLongValue];
|
if ([url getResourceValue:&size forKey:NSURLFileSizeKey error:nil])
|
||||||
|
fileSize = [size longLongValue];
|
||||||
|
else
|
||||||
|
fileSize = 0;
|
||||||
NSTimeInterval fileDate = [date timeIntervalSinceReferenceDate];
|
NSTimeInterval fileDate = [date timeIntervalSinceReferenceDate];
|
||||||
|
|
||||||
NSManagedObjectContext *moc = [self managedObjectContext];
|
NSManagedObjectContext *moc = [self managedObjectContext];
|
||||||
|
|
|
@ -9,10 +9,16 @@
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import "MADocWindow.h"
|
#import "MADocWindow.h"
|
||||||
#import "MATagWindow.h"
|
#import "MATagWindow.h"
|
||||||
|
#import "MAAppController.h"
|
||||||
|
|
||||||
@interface MADocWindow (Dragging)
|
@interface MADocWindow (Dragging)
|
||||||
|
|
||||||
- (void)registerOurDragTypes;
|
- (void)registerOurDragTypes;
|
||||||
|
- (BOOL)canPaste;
|
||||||
|
|
||||||
|
- (IBAction)cut:(id)sender;
|
||||||
|
- (IBAction)copy:(id)sender;
|
||||||
|
- (IBAction)paste:(id)sender;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -20,4 +26,7 @@
|
||||||
|
|
||||||
- (void)registerOurDragTypes;
|
- (void)registerOurDragTypes;
|
||||||
|
|
||||||
|
- (IBAction)cut:(id)sender;
|
||||||
|
- (IBAction)copy:(id)sender;
|
||||||
|
|
||||||
@end
|
@end
|
|
@ -15,12 +15,15 @@
|
||||||
|
|
||||||
#define kMADragType @"org.aereperennius.medianno"
|
#define kMADragType @"org.aereperennius.medianno"
|
||||||
|
|
||||||
|
static NSPointerArray * sValidPasteboardData;
|
||||||
|
|
||||||
@interface MAPasteboardData : NSObject <NSPasteboardWriting> {
|
@interface MAPasteboardData : NSObject <NSPasteboardWriting> {
|
||||||
NSArray * contents;
|
NSArray * contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)initWithArray:(NSArray *)array;
|
- (id)initWithArray:(NSArray *)array;
|
||||||
+ (id)pasteboardDataWithArray:(NSArray *)array;
|
+ (id)pasteboardDataWithArray:(NSArray *)array;
|
||||||
|
+ (NSArray *)arrayFromPasteboard:(NSPasteboard *)pboard;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -28,8 +31,13 @@
|
||||||
|
|
||||||
- (id)initWithArray:(NSArray *)array
|
- (id)initWithArray:(NSArray *)array
|
||||||
{
|
{
|
||||||
|
if (!sValidPasteboardData)
|
||||||
|
sValidPasteboardData = [[NSPointerArray alloc] initWithOptions:NSPointerFunctionsZeroingWeakMemory];
|
||||||
self = [super init];
|
self = [super init];
|
||||||
contents = array;
|
contents = array;
|
||||||
|
if ([sValidPasteboardData count] > 10)
|
||||||
|
[sValidPasteboardData compact];
|
||||||
|
[sValidPasteboardData addPointer:contents];
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
@ -39,6 +47,17 @@
|
||||||
return [[[MAPasteboardData alloc] initWithArray:array] autorelease];
|
return [[[MAPasteboardData alloc] initWithArray:array] autorelease];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (NSArray *)arrayFromPasteboard:(NSPasteboard *)pboard
|
||||||
|
{
|
||||||
|
if (NSNumber * drag = [pboard propertyListForType:kMADragType]) {
|
||||||
|
NSArray * possibleArray = (NSArray *)[drag longValue];
|
||||||
|
for (NSUInteger count = [sValidPasteboardData count]; count--; )
|
||||||
|
if ([sValidPasteboardData pointerAtIndex:count] == possibleArray)
|
||||||
|
return possibleArray;
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
- (NSArray *)writableTypesForPasteboard:(NSPasteboard *)pasteboard
|
- (NSArray *)writableTypesForPasteboard:(NSPasteboard *)pasteboard
|
||||||
{
|
{
|
||||||
MAMedia * media;
|
MAMedia * media;
|
||||||
|
@ -96,10 +115,30 @@
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (Class)classOfDraggedObjects:(id)drag
|
- (IBAction)copy:(id)sender
|
||||||
{
|
{
|
||||||
NSArray * dragObjects = (NSArray *)[drag longValue];
|
NSPasteboard* pboard = [NSPasteboard pasteboardWithName:NSGeneralPboard];
|
||||||
|
NSResponder * responder = [[self window] firstResponder];
|
||||||
|
while (responder && responder != self) {
|
||||||
|
if (responder == mediaTable) {
|
||||||
|
[self tableView:mediaTable writeRowsWithIndexes:[mediaController selectionIndexes] toPasteboard:pboard];
|
||||||
|
break;
|
||||||
|
} else if (responder == annotationTable) {
|
||||||
|
[self tableView:annotationTable writeRowsWithIndexes:[annotationController selectionIndexes] toPasteboard:pboard];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
responder = [responder nextResponder];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)cut:(id)sender
|
||||||
|
{
|
||||||
|
[self copy:sender];
|
||||||
|
[self delete:sender];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (Class)classOfDraggedObjects:(NSArray *)dragObjects
|
||||||
|
{
|
||||||
return [dragObjects count] ? [[dragObjects objectAtIndex:0] class] : nil;
|
return [dragObjects count] ? [[dragObjects objectAtIndex:0] class] : nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,9 +149,9 @@
|
||||||
//
|
//
|
||||||
if (tableView == [info draggingSource])
|
if (tableView == [info draggingSource])
|
||||||
return NSDragOperationNone;
|
return NSDragOperationNone;
|
||||||
NSPasteboard * pb = [info draggingPasteboard];
|
NSPasteboard * pboard = [info draggingPasteboard];
|
||||||
id drag;
|
id drag;
|
||||||
if ((drag = [pb propertyListForType:kMADragType])) {
|
if ((drag = [MAPasteboardData arrayFromPasteboard:pboard])) {
|
||||||
//
|
//
|
||||||
// We don't allow media drops in annotation table
|
// We don't allow media drops in annotation table
|
||||||
//
|
//
|
||||||
|
@ -131,11 +170,11 @@
|
||||||
}
|
}
|
||||||
return NSDragOperationCopy;
|
return NSDragOperationCopy;
|
||||||
} else if (tableView == mediaTable) {
|
} else if (tableView == mediaTable) {
|
||||||
if ((drag = [pb propertyListForType:NSFilenamesPboardType])) {
|
if ((drag = [pboard propertyListForType:NSFilenamesPboardType])) {
|
||||||
[tableView setDropRow:row dropOperation:NSTableViewDropAbove];
|
[tableView setDropRow:row dropOperation:NSTableViewDropAbove];
|
||||||
return NSDragOperationLink;
|
return NSDragOperationLink;
|
||||||
} else if ((drag = [pb stringForType:(NSString *)kUTTypeURL])
|
} else if ((drag = [pboard stringForType:(NSString *)kUTTypeURL])
|
||||||
|| (drag = [pb stringForType:(NSString *)kUTTypeFileURL])
|
|| (drag = [pboard stringForType:(NSString *)kUTTypeFileURL])
|
||||||
) {
|
) {
|
||||||
[tableView setDropRow:row dropOperation:NSTableViewDropAbove];
|
[tableView setDropRow:row dropOperation:NSTableViewDropAbove];
|
||||||
return NSDragOperationLink;
|
return NSDragOperationLink;
|
||||||
|
@ -146,7 +185,7 @@
|
||||||
|
|
||||||
- (BOOL)tableView:(NSTableView *)tableView acceptDrop:(id<NSDraggingInfo>)info row:(NSInteger)row dropOperation:(NSTableViewDropOperation)dropOperation
|
- (BOOL)tableView:(NSTableView *)tableView acceptDrop:(id<NSDraggingInfo>)info row:(NSInteger)row dropOperation:(NSTableViewDropOperation)dropOperation
|
||||||
{
|
{
|
||||||
NSPasteboard * pb = [info draggingPasteboard];
|
NSPasteboard * pboard = [info draggingPasteboard];
|
||||||
MADocument * doc = [self document];
|
MADocument * doc = [self document];
|
||||||
MAMedia * media = nil;
|
MAMedia * media = nil;
|
||||||
|
|
||||||
|
@ -159,22 +198,69 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
id drag;
|
id drag;
|
||||||
if ((drag = [pb propertyListForType:kMADragType])) {
|
if ((drag = [MAPasteboardData arrayFromPasteboard:pboard])) {
|
||||||
for (id obj in (NSArray *)[drag longValue])
|
for (id obj in drag)
|
||||||
[obj copyToDocument:doc withMedia:media];
|
[obj copyToDocument:doc withMedia:media];
|
||||||
} else if ((drag = [pb propertyListForType:NSFilenamesPboardType])) {
|
} else if ((drag = [pboard propertyListForType:NSFilenamesPboardType])) {
|
||||||
NSMutableArray * urls = [NSMutableArray array];
|
NSMutableArray * urls = [NSMutableArray array];
|
||||||
for (NSString * path in drag)
|
for (NSString * path in drag)
|
||||||
[urls addObject:[NSURL fileURLWithPath:path]];
|
[urls addObject:[NSURL fileURLWithPath:path]];
|
||||||
[self addMedia:urls];
|
[self addMedia:urls];
|
||||||
} else if ((drag = [pb stringForType:(NSString *)kUTTypeURL])
|
} else if ((drag = [pboard stringForType:(NSString *)kUTTypeURL])
|
||||||
|| (drag = [pb stringForType:(NSString *)kUTTypeFileURL])
|
|| (drag = [pboard stringForType:(NSString *)kUTTypeFileURL])
|
||||||
) {
|
) {
|
||||||
[self addMedia:[NSArray arrayWithObject:[NSURL URLWithString:drag]]];
|
[self addMedia:[NSArray arrayWithObject:[NSURL URLWithString:drag]]];
|
||||||
}
|
}
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (IBAction)paste:(id)sender
|
||||||
|
{
|
||||||
|
NSPasteboard* pboard = [NSPasteboard pasteboardWithName:NSGeneralPboard];
|
||||||
|
MADocument * doc = [self document];
|
||||||
|
NSManagedObjectContext *moc = [doc managedObjectContext];
|
||||||
|
|
||||||
|
id drag;
|
||||||
|
if ((drag = [MAPasteboardData arrayFromPasteboard:pboard])) {
|
||||||
|
MAMedia * media = [self currentMedia];
|
||||||
|
for (id obj in drag)
|
||||||
|
if ([obj managedObjectContext] != moc)
|
||||||
|
[obj copyToDocument:doc withMedia:media];
|
||||||
|
} else if ((drag = [pboard propertyListForType:NSFilenamesPboardType])) {
|
||||||
|
NSMutableArray * urls = [NSMutableArray array];
|
||||||
|
for (NSString * path in drag)
|
||||||
|
[urls addObject:[NSURL fileURLWithPath:path]];
|
||||||
|
[self addMedia:urls];
|
||||||
|
} else if ((drag = [pboard stringForType:(NSString *)kUTTypeURL])
|
||||||
|
|| (drag = [pboard stringForType:(NSString *)kUTTypeFileURL])
|
||||||
|
) {
|
||||||
|
[self addMedia:[NSArray arrayWithObject:[NSURL URLWithString:drag]]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)canPaste
|
||||||
|
{
|
||||||
|
NSPasteboard* pboard = [NSPasteboard pasteboardWithName:NSGeneralPboard];
|
||||||
|
id drag;
|
||||||
|
if ((drag = [MAPasteboardData arrayFromPasteboard:pboard])) {
|
||||||
|
MAMedia * media = [self currentMedia];
|
||||||
|
if (![drag count])
|
||||||
|
return NO;
|
||||||
|
id obj = [drag objectAtIndex:0];
|
||||||
|
if ([obj managedObjectContext] == [[self document] managedObjectContext])
|
||||||
|
return NO;
|
||||||
|
else
|
||||||
|
return [obj class] != [MAAnno class] || media;
|
||||||
|
} else if ((drag = [pboard propertyListForType:NSFilenamesPboardType])) {
|
||||||
|
return YES;
|
||||||
|
} else if ((drag = [pboard stringForType:(NSString *)kUTTypeURL])
|
||||||
|
|| (drag = [pboard stringForType:(NSString *)kUTTypeFileURL])
|
||||||
|
) {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation MATagWindow (Dragging)
|
@implementation MATagWindow (Dragging)
|
||||||
|
@ -192,8 +278,18 @@
|
||||||
NSArray * objects = [[tagController arrangedObjects] objectsAtIndexes:rowIndexes];
|
NSArray * objects = [[tagController arrangedObjects] objectsAtIndexes:rowIndexes];
|
||||||
[pboard clearContents];
|
[pboard clearContents];
|
||||||
[pboard writeObjects:[NSArray arrayWithObject:[MAPasteboardData pasteboardDataWithArray:objects]]];
|
[pboard writeObjects:[NSArray arrayWithObject:[MAPasteboardData pasteboardDataWithArray:objects]]];
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (IBAction)copy:(id)sender
|
||||||
|
{
|
||||||
|
[self tableView:nil writeRowsWithIndexes:[tagController selectionIndexes] toPasteboard:[NSPasteboard pasteboardWithName:NSGeneralPboard]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)cut:(id)sender
|
||||||
|
{
|
||||||
|
[self copy:sender];
|
||||||
|
[self delete:sender];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
@property (assign) NSDocument * currentDocument;
|
@property (assign) NSDocument * currentDocument;
|
||||||
|
|
||||||
- (IBAction)toggleWindow:(id)sender;
|
- (IBAction)toggleWindow:(id)sender;
|
||||||
|
- (IBAction)delete:(id)sender;
|
||||||
|
|
||||||
- (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)item;
|
- (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)item;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
if (![self isWindowLoaded] || ![[self window] isVisible])
|
if (![self isWindowLoaded] || ![[self window] isVisible])
|
||||||
return NO;
|
return NO;
|
||||||
|
|
||||||
if ([item action] == @selector(delete:))
|
if ([item action] == @selector(delete:) || [item action] == @selector(cut:) || [item action] == @selector(copy:))
|
||||||
return [tagController selectionIndex] != NSNotFound;
|
return [tagController selectionIndex] != NSNotFound;
|
||||||
|
|
||||||
return NO;
|
return NO;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user