diff --git a/Medianno/MAAnno.mm b/Medianno/MAAnno.mm index 25a6ebb..6b5eee6 100644 --- a/Medianno/MAAnno.mm +++ b/Medianno/MAAnno.mm @@ -64,7 +64,11 @@ - (void)setTagDescriptions:(NSArray *)tagDescriptions { NSManagedObjectContext *moc = [self managedObjectContext]; - + + NSSet * prevTags = self.tags; + for (MATag * tag in prevTags) + [moc deleteObject:tag]; + int seqNo = 0; std::vector tags; for (MATagDescription * tagDesc in tagDescriptions) { diff --git a/Medianno/MADocWindow.h b/Medianno/MADocWindow.h index b5e1581..18370dd 100644 --- a/Medianno/MADocWindow.h +++ b/Medianno/MADocWindow.h @@ -8,10 +8,12 @@ #import -@interface MADocWindow : NSWindowController { +@interface MADocWindow : NSWindowController { IBOutlet NSArrayController* mediaController; IBOutlet NSArrayController* annotationController; IBOutlet QTMovieView * movieView; + IBOutlet NSTokenField * tokenFieldProto; + IBOutlet NSTableColumn * tokenColumn; } - (IBAction)addMediaFiles:(id)sender; diff --git a/Medianno/MADocWindow.mm b/Medianno/MADocWindow.mm index 72d106d..6028232 100644 --- a/Medianno/MADocWindow.mm +++ b/Medianno/MADocWindow.mm @@ -26,6 +26,8 @@ [super windowDidLoad]; [mediaController setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"date" ascending:YES]]]; [annotationController setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"location" ascending:YES]]]; + NSCell * tokenCell = [tokenFieldProto cell]; + [tokenColumn setDataCell:tokenCell]; } #pragma mark Media management @@ -86,4 +88,21 @@ [[self document] addAnnotationForMedia:[[mediaController selectedObjects] objectAtIndex:0] location:location]; } +#pragma mark Tag token manipulation + +- (NSString *)tokenFieldCell:(NSTokenFieldCell *)tokenFieldCell displayStringForRepresentedObject:(id)representedObject +{ + return [representedObject name]; +} + +- (NSArray *)tokenFieldCell:(NSTokenFieldCell *)tokenFieldCell completionsForSubstring:(NSString *)substring indexOfToken:(NSInteger)tokenIndex indexOfSelectedItem:(NSInteger *)selectedIndex +{ + return [[self document] tagNamesMatchingPrefix:substring]; +} + +- (id)tokenFieldCell:(NSTokenFieldCell *)tokenFieldCell representedObjectForEditingString:(NSString *)editingString +{ + return [[self document] tagDescriptionForName:editingString]; +} + @end diff --git a/Medianno/MADocument.h b/Medianno/MADocument.h index 522ff6d..ba73f59 100644 --- a/Medianno/MADocument.h +++ b/Medianno/MADocument.h @@ -10,6 +10,7 @@ #import @class MAMedia; +@class MATagDescription; @interface MADocument : NSPersistentDocument { NSFileWrapper * mediaWrapper; @@ -17,5 +18,7 @@ - (void)addMediaURL:(NSURL *)url name:(NSString *)name date:(NSDate *)date copying:(BOOL)copying; - (void)addAnnotationForMedia:(MAMedia *)media location:(QTTime)location; +- (MATagDescription *)tagDescriptionForName:(NSString *)name; +- (NSArray *)tagNamesMatchingPrefix:(NSString *)prefix; @end diff --git a/Medianno/MADocument.mm b/Medianno/MADocument.mm index c701aab..dd6a8dd 100644 --- a/Medianno/MADocument.mm +++ b/Medianno/MADocument.mm @@ -11,8 +11,8 @@ #import "MAFolder.h" #import "MAMedia.h" #import "MAAnno.h" +#import "MATagDescription.h" -#pragma mark - #pragma mark MADocument @implementation MADocument @@ -53,7 +53,6 @@ return YES; } -#pragma mark - #pragma mark Folder management - (MAFolder *)inboxFolder @@ -64,7 +63,6 @@ return [[moc executeFetchRequest:inbox error:nil] objectAtIndex:0]; } -#pragma mark - #pragma mark Media management - (void)addMediaURL:(NSURL *)url name:(NSString *)name date:(NSDate *)date copying:(BOOL)copying @@ -80,7 +78,6 @@ media.folder= inbox; } -#pragma mark - #pragma mark Annotation management - (void)addAnnotationForMedia:(MAMedia *)media location:(QTTime)location @@ -93,4 +90,36 @@ [moc processPendingChanges]; } +#pragma mark Tag management + +- (MATagDescription *)tagDescriptionForName:(NSString *)name +{ + NSManagedObjectContext *moc = [self managedObjectContext]; + NSFetchRequest * fetch = [NSFetchRequest fetchRequestWithEntityName:@"MATagDescription"]; + [fetch setPredicate:[NSPredicate predicateWithFormat:@"name == %@", name]]; + NSArray * found = [moc executeFetchRequest:fetch error:nil]; + if (found && [found count]) { + return [found objectAtIndex:0]; + } else { + MATagDescription * tagDesc = [NSEntityDescription insertNewObjectForEntityForName:@"MATagDescription" inManagedObjectContext:moc]; + tagDesc.name = name; + tagDesc.notes= @""; + + return tagDesc; + } +} + +- (NSArray *)tagNamesMatchingPrefix:(NSString *)prefix +{ + NSManagedObjectContext *moc = [self managedObjectContext]; + NSFetchRequest * fetch = [NSFetchRequest fetchRequestWithEntityName:@"MATagDescription"]; + [fetch setPredicate:[NSPredicate predicateWithFormat:@"name BEGINSWITH %@", prefix]]; + + NSArray * descs = [moc executeFetchRequest:fetch error:nil]; + NSMutableArray * names = [NSMutableArray arrayWithCapacity:[descs count]]; + for (MATagDescription * desc in descs) + [names addObject:[desc name]]; + return names; +} + @end diff --git a/Medianno/MATag.h b/Medianno/MATag.h index bc36661..80f8da0 100644 --- a/Medianno/MATag.h +++ b/Medianno/MATag.h @@ -13,7 +13,7 @@ @interface MATag : NSManagedObject { @private } -@property (nonatomic) int seqNo; +@property (nonatomic) int16_t seqNo; @property (nonatomic, retain) NSManagedObject *tag; @property (nonatomic, retain) NSManagedObject *annotation; diff --git a/Medianno/en.lproj/MADocument.xib b/Medianno/en.lproj/MADocument.xib index 367b2c5..525e0d4 100644 --- a/Medianno/en.lproj/MADocument.xib +++ b/Medianno/en.lproj/MADocument.xib @@ -32,6 +32,8 @@ NSBox NSDateFormatter NSTableView + NSTokenField + NSTokenFieldCell NSCustomObject NSView NSWindowTemplate @@ -58,6 +60,57 @@ FirstResponder + + + -2147483380 + + YES + + YES + NSStringPboardType + + + {550, 22} + + + + _NS:3123 + YES + + 341966336 + 0 + + LucidaGrande + 10 + 16 + + _NS:3123 + + YES + + 6 + System + textBackgroundColor + + 3 + MQA + + + + 6 + System + controlTextColor + + 3 + MAA + + + + 0.0 + 0 + + 2 + 15 2 @@ -136,10 +189,7 @@ 6 System headerTextColor - - 3 - MAA - + @@ -161,12 +211,7 @@ MC42NjY2NjY2NjY3AA - - 6 - System - controlTextColor - - + 3 YES @@ -212,10 +257,7 @@ 6 System headerColor - - 3 - MQA - + @@ -499,7 +541,7 @@ 2 - 17 + 19 -2064384 @@ -572,7 +614,7 @@ - QSAAAEEgAABBmAAAQZgAAA + QSAAAEEgAABBqAAAQagAAA {1281, 599} @@ -593,12 +635,7 @@ 0 Box - - 6 - System - textBackgroundColor - - + 3 MCAwLjgwMDAwMDAxMTkAA @@ -942,6 +979,46 @@ 100160 + + + value: arrangedObjects.tagDescriptions + + + + + + value: arrangedObjects.tagDescriptions + value + arrangedObjects.tagDescriptions + 2 + + + 100172 + + + + tokenFieldProto + + + + 100173 + + + + tokenColumn + + + + 100174 + + + + delegate + + + + 100175 + @@ -1113,6 +1190,7 @@ 100041 + Token Field Cell - Text Cell 100042 @@ -1209,6 +1287,20 @@ AnnotationController + + 100161 + + + YES + + + + + + 100162 + + + @@ -1239,7 +1331,6 @@ 100038.IBPluginDependency 100039.IBPluginDependency 100040.IBPluginDependency - 100041.CustomClassName 100041.IBPluginDependency 100042.IBPluginDependency 100043.IBPluginDependency @@ -1252,6 +1343,8 @@ 100143.IBPluginDependency 100143.ibExternalFetchPredicateFormat 100148.IBPluginDependency + 100161.IBPluginDependency + 100162.IBPluginDependency 5.IBPluginDependency 5.IBWindowTemplateEditedContentRect 6.IBPluginDependency @@ -1282,7 +1375,6 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - NSTokenFieldCell com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -1293,7 +1385,9 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - name=='Inbox' AND parent==NULL + name == "Inbox" AND parent == nil + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin {{133, 170}, {507, 413}} @@ -1312,7 +1406,7 @@ - 100160 + 100175 @@ -1359,12 +1453,16 @@ annotationController mediaController movieView + tokenColumn + tokenFieldProto YES NSArrayController NSArrayController QTMovieView + NSTableColumn + NSTokenField @@ -1374,6 +1472,8 @@ annotationController mediaController movieView + tokenColumn + tokenFieldProto YES @@ -1389,6 +1489,14 @@ movieView QTMovieView + + tokenColumn + NSTableColumn + + + tokenFieldProto + NSTokenField +