diff --git a/BookmarkListView.m b/BookmarkListView.m index 1b5951ee5c..f36ae8cfd0 100644 --- a/BookmarkListView.m +++ b/BookmarkListView.m @@ -191,10 +191,11 @@ - (BookmarkModel*)underlyingModel - (void)sync { [bookmarks removeAllObjects]; - int n = [underlyingModel numberOfBookmarksWithFilter:filter]; - for (int i = 0; i < n; ++i) { + NSArray* filteredBookmarks = [underlyingModel bookmarkIndicesMatchingFilter:filter]; + for (NSNumber* n in filteredBookmarks) { + int i = [n intValue]; //NSLog(@"Wrapper at %p add bookmark %@ at index %d", self, [[underlyingModel bookmarkAtIndex:i] objectForKey:KEY_NAME], i); - [bookmarks addObject:[[[BookmarkRow alloc] initWithBookmark:[underlyingModel bookmarkAtIndex:i withFilter:filter] + [bookmarks addObject:[[[BookmarkRow alloc] initWithBookmark:[underlyingModel bookmarkAtIndex:i] underlyingModel:underlyingModel] autorelease]]; } [self sort]; diff --git a/BookmarkModel.m b/BookmarkModel.m index 60b62d0d52..ec9df55e0b 100644 --- a/BookmarkModel.m +++ b/BookmarkModel.m @@ -121,6 +121,19 @@ - (NSArray*)parseFilter:(NSString*)filter return [filter componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; } +- (NSArray*)bookmarkIndicesMatchingFilter:(NSString*)filter +{ + NSMutableArray* result = [NSMutableArray arrayWithCapacity:[bookmarks_ count]]; + NSArray* tokens = [self parseFilter:filter]; + int count = [bookmarks_ count]; + for (int i = 0; i < count; ++i) { + if ([self doesBookmarkAtIndex:i matchFilter:tokens]) { + [result addObject:[NSNumber numberWithInt:i]]; + } + } + return result; +} + - (int)numberOfBookmarksWithFilter:(NSString*)filter { NSArray* tokens = [self parseFilter:filter]; @@ -251,9 +264,24 @@ - (int)convertFilteredIndex:(int)theIndex withFilter:(NSString*)filter return -1; } +- (void)removeBookmarksAtIndices:(NSArray*)indices +{ + NSArray* sorted = [indices sortedArrayUsingSelector:@selector(compare:)]; + for (int j = [sorted count] - 1; j >= 0; j--) { + int i = [[sorted objectAtIndex:j] intValue]; + assert(i >= 0); + + [bookmarks_ removeObjectAtIndex:i]; + if (![self defaultBookmark] && [bookmarks_ count]) { + [self setDefaultByGuid:[[bookmarks_ objectAtIndex:0] objectForKey:KEY_GUID]]; + } + } + [self postChangeNotification]; +} + - (void)removeBookmarkAtIndex:(int)i { - NSAssert(i >= 0, @"Bounds"); + assert(i >= 0); [bookmarks_ removeObjectAtIndex:i]; if (![self defaultBookmark] && [bookmarks_ count]) { [self setDefaultByGuid:[[bookmarks_ objectAtIndex:0] objectForKey:KEY_GUID]]; diff --git a/Headers/iTerm/BookmarkModel.h b/Headers/iTerm/BookmarkModel.h index 70343e9b60..30a855e104 100644 --- a/Headers/iTerm/BookmarkModel.h +++ b/Headers/iTerm/BookmarkModel.h @@ -39,6 +39,7 @@ typedef NSDictionary Bookmark; + (NSString*)freshGuid; - (int)numberOfBookmarks; - (int)numberOfBookmarksWithFilter:(NSString*)filter; +- (NSArray*)bookmarkIndicesMatchingFilter:(NSString*)filter; - (int)indexOfBookmarkWithGuid:(NSString*)guid; - (int)indexOfBookmarkWithGuid:(NSString*)guid withFilter:(NSString*)filter; - (Bookmark*)bookmarkAtIndex:(int)index; @@ -46,6 +47,7 @@ typedef NSDictionary Bookmark; - (void)addBookmark:(Bookmark*)bookmark; - (void)addBookmark:(Bookmark*)bookmark inSortedOrder:(BOOL)sort; - (void)removeBookmarkWithGuid:(NSString*)guid; +- (void)removeBookmarksAtIndices:(NSArray*)indices; - (void)removeBookmarkAtIndex:(int)index; - (void)removeBookmarkAtIndex:(int)index withFilter:(NSString*)filter; - (void)setBookmark:(Bookmark*)bookmark atIndex:(int)index; diff --git a/ITAddressBookMgr.m b/ITAddressBookMgr.m index a6f9d387c1..3b4bb4eeea 100644 --- a/ITAddressBookMgr.m +++ b/ITAddressBookMgr.m @@ -283,18 +283,16 @@ - (void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser didRemoveSer // remove host entry from this group NSMutableArray* toRemove = [[[NSMutableArray alloc] init] autorelease]; NSString* sftpName = [NSString stringWithFormat:@"%@-sftp", [aNetService name]]; - for (int i = 0; i < [[BookmarkModel sharedInstance] numberOfBookmarksWithFilter:@"bonjour"]; ++i) { - Bookmark* bookmark = [[BookmarkModel sharedInstance] bookmarkAtIndex:i withFilter:@"bonjour"]; + for (NSNumber* n in [[BookmarkModel sharedInstance] bookmarkIndicesMatchingFilter:@"bonjour"]) { + int i = [n intValue]; + Bookmark* bookmark = [[BookmarkModel sharedInstance] bookmarkAtIndex:i]; NSString* bookmarkName = [bookmark objectForKey:KEY_NAME]; if ([bookmarkName isEqualToString:[aNetService name]] || [bookmarkName isEqualToString:sftpName]) { [toRemove addObject:[NSNumber numberWithInt:i]]; } } - for (int i = [toRemove count]-1; i >= 0; --i) { - [[BookmarkModel sharedInstance] removeBookmarkAtIndex:[[toRemove objectAtIndex:i] intValue] withFilter:@"bonjour"]; - } - [toRemove removeAllObjects]; + [[BookmarkModel sharedInstance] removeBookmarksAtIndices:toRemove]; } + (NSString*)descFromFont:(NSFont*)font diff --git a/iTermController.m b/iTermController.m index bfd28f5211..1ecb6ebd7a 100644 --- a/iTermController.m +++ b/iTermController.m @@ -495,22 +495,36 @@ - (void)_addBookmarksForTag:(NSString*)tag toMenu:(NSMenu*)aMenu target:(id)aTar NSMenuItem* aMenuItem = [[NSMenuItem alloc] initWithTitle:tag action:@selector(noAction:) keyEquivalent:@""]; NSMenu* subMenu = [[[NSMenu alloc] init] autorelease]; int count = 0; + int MAX_MENU_ITEMS = 100; + if ([tag isEqualToString:@"bonjour"]) { + MAX_MENU_ITEMS = 50; + } for (int i = 0; i < [[BookmarkModel sharedInstance] numberOfBookmarks]; ++i) { Bookmark* bookmark = [[BookmarkModel sharedInstance] bookmarkAtIndex:i]; NSArray* tags = [bookmark objectForKey:KEY_TAGS]; for (int j = 0; j < [tags count]; ++j) { if ([tag localizedCaseInsensitiveCompare:[tags objectAtIndex:j]] == NSOrderedSame) { ++count; - [self _addBookmark:bookmark - toMenu:subMenu - target:aTarget - withShortcuts:withShortcuts - selector:selector - alternateSelector:alternateSelector]; + if (count <= MAX_MENU_ITEMS) { + [self _addBookmark:bookmark + toMenu:subMenu + target:aTarget + withShortcuts:withShortcuts + selector:selector + alternateSelector:alternateSelector]; + } break; } } } + if ([[BookmarkModel sharedInstance] numberOfBookmarks] > MAX_MENU_ITEMS) { + int overflow = [[BookmarkModel sharedInstance] numberOfBookmarks] - MAX_MENU_ITEMS; + NSMenuItem* overflowItem = [[NSMenuItem alloc] initWithTitle:[NSString stringWithFormat:@"[%d profiles not shown]", overflow] + action:nil + keyEquivalent:@""]; + [subMenu addItem:overflowItem]; + [overflowItem release]; + } [aMenuItem setSubmenu:subMenu]; [aMenuItem setTarget:self]; [aMenu addItem:aMenuItem];