From ec7bb0a4760399a19746c2c0900788bafddd8524 Mon Sep 17 00:00:00 2001 From: Matthias Neeracher Date: Sun, 21 Aug 2011 19:28:43 +0200 Subject: [PATCH] Implement dragging into annotation table --- Medianno/MAAnno.h | 3 ++ Medianno/MAAnno.mm | 13 +++++++- Medianno/MADocWindow.h | 7 ++-- Medianno/MADocWindow.mm | 16 +++++++--- Medianno/MADragging.mm | 62 ++++++++++++++++++++++++++++++++++++ Medianno/MATagDescription.h | 3 ++ Medianno/MATagDescription.mm | 8 ++++- 7 files changed, 103 insertions(+), 9 deletions(-) diff --git a/Medianno/MAAnno.h b/Medianno/MAAnno.h index 039840a..582fe97 100644 --- a/Medianno/MAAnno.h +++ b/Medianno/MAAnno.h @@ -11,6 +11,8 @@ #import @class MATag; +@class MAMedia; +@class MADocument; @interface MAAnno : NSManagedObject { @private @@ -22,6 +24,7 @@ - (QTTime)qtLocation; - (NSString *)exportText; +- (MAAnno *)copyToDocument:(MADocument *)doc withMedia:(MAMedia *)media; /* * Tags are never manipulated through the tag objects, but always through diff --git a/Medianno/MAAnno.mm b/Medianno/MAAnno.mm index 4d9894e..6603ed7 100644 --- a/Medianno/MAAnno.mm +++ b/Medianno/MAAnno.mm @@ -9,6 +9,7 @@ #import "MAAnno.h" #import "MATag.h" #import "MATagDescription.h" +#import "MADocument.h" #import @@ -114,7 +115,6 @@ return [NSSet setWithObject:@"tags"]; } - - (NSString *)exportText { NSMutableString * text = [NSMutableString stringWithFormat:@"%@\t%@", self.location, self.notes]; @@ -123,4 +123,15 @@ return text; } +- (MAAnno *)copyToDocument:(MADocument *)doc withMedia:(MAMedia *)media; +{ + MAAnno * anno = [doc addAnnotationForMedia:media location:QTTimeFromString(self.location)]; + anno.notes = self.notes; + NSMutableArray * tagDescs = [NSMutableArray array]; + for (MATagDescription * tag in self.tagDescriptions) + [tagDescs addObject:[tag copyToDocument:doc withMedia:media]]; + anno.tagDescriptions = tagDescs; + + return anno; +} @end diff --git a/Medianno/MADocWindow.h b/Medianno/MADocWindow.h index 1e5af8b..c490fd9 100644 --- a/Medianno/MADocWindow.h +++ b/Medianno/MADocWindow.h @@ -10,15 +10,17 @@ #import @class MAMovieWindow; +@class MAMedia; -@interface MADocWindow : NSWindowController { +@interface MADocWindow : NSWindowController + +{ IBOutlet NSArrayController* mediaController; IBOutlet NSArrayController* annotationController; IBOutlet QTMovieView * movieView; IBOutlet NSTableView * mediaTable; IBOutlet NSTableView * annotationTable; IBOutlet NSView * textExportAccessoryView; - IBOutlet MAMovieWindow * moviePanel; QTMovie * currentMovie; NSString * currentMovieTitle; QTTime lastMovieTime; @@ -39,6 +41,7 @@ - (QTTime)currentMovieTime; - (void)moviePanelDidAppear; - (void)moviePanelDidClose; +- (MAMedia *)currentMedia; @end diff --git a/Medianno/MADocWindow.mm b/Medianno/MADocWindow.mm index 9703030..1c612ad 100644 --- a/Medianno/MADocWindow.mm +++ b/Medianno/MADocWindow.mm @@ -93,8 +93,7 @@ static const char * kMADocWindowObserver = "MADocWindowObserver"; // // Current movie changed // - if ([[mediaController selectionIndexes] count] > 0) { - MAMedia * currentMedia = [[mediaController selectedObjects] objectAtIndex:0]; + if (MAMedia * currentMedia = [self currentMedia]) { currentMovie = [[QTMovie alloc] initWithFile:[currentMedia media] error:nil]; currentMovieTitle = [currentMedia name]; } else { @@ -108,6 +107,14 @@ static const char * kMADocWindowObserver = "MADocWindowObserver"; #pragma mark Media management +- (MAMedia *)currentMedia +{ + if ([[mediaController selectionIndexes] count] > 0) + return [[mediaController selectedObjects] objectAtIndex:0]; + else + return nil; +} + - (QTTime)currentMovieTime { return [currentMovie currentTime]; @@ -369,7 +376,7 @@ static NSTimeInterval sLastSkip = 0.0; { [currentMovie stop]; QTTime location = [self currentMovieTime]; - MAAnno * anno = [[self document] addAnnotationForMedia:[[mediaController selectedObjects] objectAtIndex:0] location:location]; + MAAnno * anno = [[self document] addAnnotationForMedia:[self currentMedia] location:location]; [annotationController setSelectedObjects:[NSArray arrayWithObject:anno]]; [annotationTable editColumn:[annotationTable columnWithIdentifier:@"tags"] row:[annotationController selectionIndex] @@ -433,8 +440,7 @@ static NSTimeInterval sLastSkip = 0.0; NSArray * lines = [text componentsSeparatedByString:@"\n"]; if ([lines count] > 0) { MADocument * doc = [self document]; - MAMedia * media = - [mediaController selectionIndex] != NSNotFound ? [[mediaController selectedObjects] objectAtIndex:0] : nil; + MAMedia * media = [self currentMedia]; // // Detect whether we start with a tag // diff --git a/Medianno/MADragging.mm b/Medianno/MADragging.mm index 1a61c1d..df74d26 100644 --- a/Medianno/MADragging.mm +++ b/Medianno/MADragging.mm @@ -11,6 +11,8 @@ #import "MAAnno.h" #import "MAMedia.h" +#include + #define kMADragType @"org.aereperennius.medianno" @interface MAPasteboardData : NSObject { @@ -66,6 +68,9 @@ - (void)registerOurDragTypes { + [mediaTable registerForDraggedTypes: + [NSArray arrayWithObjects:kMADragType,NSFilenamesPboardType, nil]]; + [annotationTable setDraggingSourceOperationMask:NSDragOperationEvery forLocal:NO]; [annotationTable setVerticalMotionCanBeginDrag:NO]; [annotationTable registerForDraggedTypes: @@ -81,6 +86,63 @@ return YES; } +- (Class)classOfDraggedObjects:(id)drag +{ + NSArray * dragObjects = (NSArray *)[drag longValue]; + + return [dragObjects count] ? [[dragObjects objectAtIndex:0] class] : nil; +} + +- (NSDragOperation)tableView:(NSTableView *)tableView validateDrop:(id)info proposedRow:(NSInteger)row proposedDropOperation:(NSTableViewDropOperation)dropOperation +{ + // + // We don't allow within-table dragging + // + if (tableView == [info draggingSource]) + return NSDragOperationNone; + NSPasteboard * pb = [info draggingPasteboard]; + if (id drag = [pb propertyListForType:kMADragType]) { + // + // We don't allow media drops in annotation table + // + Class dragClass = [self classOfDraggedObjects:drag]; + if (tableView == annotationTable) { + if (dragClass == [MAMedia class] || (dragClass == [MAAnno class] && ![self currentMedia])) + return NSDragOperationNone; + [tableView setDropRow:row dropOperation:NSTableViewDropAbove]; + } else { + if (dragClass == [MAMedia class] || dragClass == [MATagDescription class]) { + [tableView setDropRow:row dropOperation:NSTableViewDropAbove]; + } else { + row = std::min(row, [[mediaController arrangedObjects] count]-1); + [tableView setDropRow:row dropOperation:NSTableViewDropOn]; + } + } + return NSDragOperationCopy; + } + return NSDragOperationNone; +} + +- (BOOL)tableView:(NSTableView *)tableView acceptDrop:(id)info row:(NSInteger)row dropOperation:(NSTableViewDropOperation)dropOperation +{ + NSPasteboard * pb = [info draggingPasteboard]; + MADocument * doc = [self document]; + MAMedia * media = nil; + + if (tableView == annotationTable) { + media = [self currentMedia]; + } else if (dropOperation == NSTableViewDropOn) { + NSArray * allMedia = [mediaController arrangedObjects]; + if (row >= 0 && row < [allMedia count]) + media = [allMedia objectAtIndex:row]; + } + + if (id drag = [pb propertyListForType:kMADragType]) + for (id obj in (NSArray *)[drag longValue]) + [obj copyToDocument:doc withMedia:media]; + return YES; +} + @end @implementation MATagWindow (Dragging) diff --git a/Medianno/MATagDescription.h b/Medianno/MATagDescription.h index b1baf88..8ccea50 100644 --- a/Medianno/MATagDescription.h +++ b/Medianno/MATagDescription.h @@ -10,6 +10,8 @@ #import @class MATag; +@class MADocument; +@class MAMedia; @interface MATagDescription : NSManagedObject { @private @@ -19,6 +21,7 @@ @property (nonatomic, retain) NSSet *uses; - (NSString *)exportText; +- (MATagDescription *)copyToDocument:(MADocument *)doc withMedia:(MAMedia *)media; @end diff --git a/Medianno/MATagDescription.mm b/Medianno/MATagDescription.mm index ed47b9b..81bef41 100644 --- a/Medianno/MATagDescription.mm +++ b/Medianno/MATagDescription.mm @@ -8,7 +8,7 @@ #import "MATagDescription.h" #import "MATag.h" - +#import "MADocument.h" @implementation MATagDescription @dynamic name; @@ -30,4 +30,10 @@ [tag.annotation didChangeValueForKey:@"tags"]; [self didChangeValueForKey:@"name"]; } + +- (MATagDescription *)copyToDocument:(MADocument *)doc withMedia:(id)media +{ + return [doc tagDescriptionForName:self.name notes:self.notes]; +} + @end