Add the ability to open multiple bookmarks or history items in new tabs/windows from the context menu, and with command-double-click (bug 285182).

This commit is contained in:
smfr%smfr.org 2005-06-23 18:10:56 +00:00
Родитель 511a6bddbf
Коммит 7c1e2f8626
9 изменённых файлов: 313 добавлений и 183 удалений

Просмотреть файл

@ -204,7 +204,8 @@
-(NSMenu*)menuForEvent:(NSEvent*)aEvent -(NSMenu*)menuForEvent:(NSEvent*)aEvent
{ {
lastEventWasMenu = YES; lastEventWasMenu = YES;
return [[BookmarkManager sharedBookmarkManager] contextMenuForItem:[self bookmarkItem] fromView:nil target:self]; NSArray* theItemArray = [NSArray arrayWithObject:[self bookmarkItem]];
return [[BookmarkManager sharedBookmarkManager] contextMenuForItems:theItemArray fromView:nil target:self];
} }
// //

Просмотреть файл

@ -102,7 +102,7 @@ enum {
-(NSArray *)searchBookmarksContainer:(BookmarkFolder*)container forString:(NSString *)searchString inFieldWithTag:(int)tag; -(NSArray *)searchBookmarksContainer:(BookmarkFolder*)container forString:(NSString *)searchString inFieldWithTag:(int)tag;
-(unsigned) firstUserCollection; -(unsigned) firstUserCollection;
-(BOOL) isDropValid:(NSArray *)items toFolder:(BookmarkFolder *)parent; -(BOOL) isDropValid:(NSArray *)items toFolder:(BookmarkFolder *)parent;
-(NSMenu *)contextMenuForItem:(id)item fromView:(BookmarkOutlineView *)outlineView target:(id)target; -(NSMenu *)contextMenuForItems:(NSArray*)items fromView:(BookmarkOutlineView *)outlineView target:(id)target;
// Reading bookmark files // Reading bookmark files
-(BOOL) readBookmarks; -(BOOL) readBookmarks;

Просмотреть файл

@ -484,27 +484,51 @@ static unsigned gFirstUserCollection = 0;
// unified context menu generator for all kinds of bookmarks // unified context menu generator for all kinds of bookmarks
// this can be called from a bookmark outline view // this can be called from a bookmark outline view
// or from a bookmark button, which should pass a nil outlineView // or from a bookmark button, which should pass a nil outlineView
- (NSMenu *)contextMenuForItem:(id)item fromView:(BookmarkOutlineView *)outlineView target:(id)target - (NSMenu *)contextMenuForItems:(NSArray*)items fromView:(BookmarkOutlineView *)outlineView target:(id)target
{ {
// don't do anything if item == nil if ([items count] == 0) return nil;
if (!item)
return nil; BOOL itemsContainsFolder = NO;
BOOL itemsContainsBookmark = NO;
BOOL multipleItems = ([items count] > 1);
NSEnumerator* itemsEnum = [items objectEnumerator];
id curItem;
while ((curItem = [itemsEnum nextObject]))
{
itemsContainsFolder |= [curItem isKindOfClass:[BookmarkFolder class]];
itemsContainsBookmark |= [curItem isKindOfClass:[Bookmark class]];
}
// All the methods in this context menu need to be able to handle > 1 item
// being selected, and the selected items containing a mixture of folders
// and bookmarks.
NSMenu * contextMenu = [[[NSMenu alloc] initWithTitle:@"notitle"] autorelease]; NSMenu * contextMenu = [[[NSMenu alloc] initWithTitle:@"notitle"] autorelease];
BOOL isFolder = [item isKindOfClass:[BookmarkFolder class]]; NSString * menuTitle = nil;
NSString * menuTitle;
// open in new window // open in new window(s)
if (isFolder) if (itemsContainsFolder && [items count] == 1)
menuTitle = NSLocalizedString(@"Open Tabs in New Window", @""); menuTitle = NSLocalizedString(@"Open Tabs in New Window", @"");
else if (multipleItems)
menuTitle = NSLocalizedString(@"Open in New Windows", @"");
else else
menuTitle = NSLocalizedString(@"Open in New Window", @""); menuTitle = NSLocalizedString(@"Open in New Window", @"");
NSMenuItem *menuItem = [[[NSMenuItem alloc] initWithTitle:menuTitle action:@selector(openBookmarkInNewWindow:) keyEquivalent:@""] autorelease]; NSMenuItem *menuItem = [[[NSMenuItem alloc] initWithTitle:menuTitle action:@selector(openBookmarkInNewWindow:) keyEquivalent:@""] autorelease];
[menuItem setTarget:target]; [menuItem setTarget:target];
[contextMenu addItem:menuItem]; [contextMenu addItem:menuItem];
// open in new tab // open in new tabs in new window
if (isFolder) if (multipleItems)
{
menuTitle = NSLocalizedString(@"Open in Tabs in New Window", @"");
menuItem = [[[NSMenuItem alloc] initWithTitle:menuTitle action:@selector(openBookmarksInTabsInNewWindow:) keyEquivalent:@""] autorelease];
[menuItem setTarget:target];
[contextMenu addItem:menuItem];
}
// open in new tab in current window
if (itemsContainsFolder || multipleItems)
menuTitle = NSLocalizedString(@"Open in New Tabs", @""); menuTitle = NSLocalizedString(@"Open in New Tabs", @"");
else else
menuTitle = NSLocalizedString(@"Open in New Tab", @""); menuTitle = NSLocalizedString(@"Open in New Tab", @"");
@ -512,7 +536,7 @@ static unsigned gFirstUserCollection = 0;
[menuItem setTarget:target]; [menuItem setTarget:target];
[contextMenu addItem:menuItem]; [contextMenu addItem:menuItem];
if (!outlineView || ([outlineView numberOfSelectedRows] == 1)) { if (!outlineView || ([items count] == 1)) {
[contextMenu addItem:[NSMenuItem separatorItem]]; [contextMenu addItem:[NSMenuItem separatorItem]];
menuTitle = NSLocalizedString(@"Get Info", @""); menuTitle = NSLocalizedString(@"Get Info", @"");
menuItem = [[[NSMenuItem alloc] initWithTitle:menuTitle action:@selector(showBookmarkInfo:) keyEquivalent:@""] autorelease]; menuItem = [[[NSMenuItem alloc] initWithTitle:menuTitle action:@selector(showBookmarkInfo:) keyEquivalent:@""] autorelease];
@ -520,10 +544,10 @@ static unsigned gFirstUserCollection = 0;
[contextMenu addItem:menuItem]; [contextMenu addItem:menuItem];
} }
if ([item isKindOfClass:[BookmarkFolder class]]) { if (([items count] == 1) && itemsContainsFolder) {
menuTitle = NSLocalizedString(@"Use as Dock Menu", @""); menuTitle = NSLocalizedString(@"Use as Dock Menu", @"");
menuItem = [[[NSMenuItem alloc] initWithTitle:menuTitle action:@selector(makeDockMenu:) keyEquivalent:@""] autorelease]; menuItem = [[[NSMenuItem alloc] initWithTitle:menuTitle action:@selector(makeDockMenu:) keyEquivalent:@""] autorelease];
[menuItem setTarget:item]; [menuItem setTarget:[items objectAtIndex:0]];
[contextMenu addItem:menuItem]; [contextMenu addItem:menuItem];
} }

Просмотреть файл

@ -130,6 +130,7 @@
-(IBAction) openBookmark: (id)aSender; -(IBAction) openBookmark: (id)aSender;
-(IBAction) openBookmarkInNewTab:(id)aSender; -(IBAction) openBookmarkInNewTab:(id)aSender;
-(IBAction) openBookmarkInNewWindow:(id)aSender; -(IBAction) openBookmarkInNewWindow:(id)aSender;
-(IBAction) openBookmarksInTabsInNewWindow:(id)aSender;
-(IBAction) deleteBookmarks:(id)aSender; -(IBAction) deleteBookmarks:(id)aSender;
-(IBAction) showBookmarkInfo:(id)aSender; -(IBAction) showBookmarkInfo:(id)aSender;
-(IBAction) locateBookmark:(id)aSender; -(IBAction) locateBookmark:(id)aSender;

Просмотреть файл

@ -446,17 +446,8 @@ static const int kDisabledQuicksearchPopupItemTag = 9999;
} }
} }
// create array of items we need to delete. Deleting items out of of the // create array of items we need to delete.
// selection array is problematic for some reason. NSArray* itemsToDelete = [mBookmarksOutlineView selectedItems];
NSMutableArray *itemsToDelete = [[NSMutableArray alloc] init];
selRows = [mBookmarksOutlineView selectedRowEnumerator];
for (NSNumber* currIndex = [selRows nextObject];
currIndex != nil;
currIndex = [selRows nextObject]) {
index = [currIndex intValue];
BookmarkItem* item = [mBookmarksOutlineView itemAtRow: index];
[itemsToDelete addObject: item];
}
// delete all bookmarks that are in our array // delete all bookmarks that are in our array
int count = [itemsToDelete count]; int count = [itemsToDelete count];
@ -464,7 +455,6 @@ static const int kDisabledQuicksearchPopupItemTag = 9999;
doomedItem = [itemsToDelete objectAtIndex:i]; doomedItem = [itemsToDelete objectAtIndex:i];
[[doomedItem parent] deleteChild:doomedItem]; [[doomedItem parent] deleteChild:doomedItem];
} }
[itemsToDelete release];
// restore selection to location near last item deleted or last item // restore selection to location near last item deleted or last item
int total = [mBookmarksOutlineView numberOfRows]; int total = [mBookmarksOutlineView numberOfRows];
@ -475,93 +465,134 @@ static const int kDisabledQuicksearchPopupItemTag = 9999;
-(IBAction)openBookmark: (id)aSender -(IBAction)openBookmark: (id)aSender
{ {
id item = nil; NSArray* items = nil;
if (aSender == mBookmarksOutlineView) { if ([aSender isKindOfClass:[BookmarkItem class]])
int index = [mBookmarksOutlineView selectedRow]; items = [NSArray arrayWithObject:aSender];
if (index == -1) else
return; items = [mBookmarksOutlineView selectedItems];
item = [mBookmarksOutlineView itemAtRow: index];
} else if ([aSender isKindOfClass:[BookmarkItem class]])
item = aSender;
if (!item) NSEnumerator* itemsEnum = [items objectEnumerator];
return; id curItem;
// see if it's a rendezvous item while ((curItem = [itemsEnum nextObject]))
id parent = [item parent];
if (![parent isKindOfClass:[BookmarkItem class]]) {
[[NetworkServices sharedNetworkServices] attemptResolveService:[parent intValue] forSender:item];
mOpenActionFlag = kOpenBookmarkAction;
return;
}
// handling toggling of folders
if ([item isKindOfClass:[BookmarkFolder class]])
{ {
if (![item isGroup]) // see if it's a rendezvous item
id parent = [curItem parent];
if (![parent isKindOfClass:[BookmarkItem class]])
{ {
if ([mBookmarksOutlineView isItemExpanded:item]) [[NetworkServices sharedNetworkServices] attemptResolveService:[parent intValue] forSender:curItem];
[mBookmarksOutlineView collapseItem: item]; mOpenActionFlag = kOpenBookmarkAction;
else }
[mBookmarksOutlineView expandItem: item]; else if ([curItem isKindOfClass:[BookmarkFolder class]])
return; {
if (![curItem isGroup])
{
if ([mBookmarksOutlineView isItemExpanded:curItem])
[mBookmarksOutlineView collapseItem: curItem];
else
[mBookmarksOutlineView expandItem: curItem];
}
}
else
{
// otherwise follow the standard bookmark opening behavior
[[NSApp delegate] loadBookmark:curItem withWindowController:mBrowserWindowController openBehavior:eBookmarkOpenBehaviorDefault];
} }
} }
// otherwise follow the standard bookmark opening behavior
[[NSApp delegate] loadBookmark:item withWindowController:mBrowserWindowController openBehavior:eBookmarkOpenBehaviorDefault];
} }
-(IBAction)openBookmarkInNewTab:(id)aSender -(IBAction)openBookmarkInNewTab:(id)aSender
{ {
id item = nil; NSArray* items = nil;
if ([aSender isKindOfClass:[BookmarkItem class]])
items = [NSArray arrayWithObject:aSender];
else
items = [mBookmarksOutlineView selectedItems];
if (![aSender isKindOfClass:[BookmarkItem class]]) { NSEnumerator* itemsEnum = [items objectEnumerator];
int index = [mBookmarksOutlineView selectedRow]; id curItem;
if (index == -1) while ((curItem = [itemsEnum nextObject]))
return; {
if ([mBookmarksOutlineView numberOfSelectedRows] == 1) // see if it's a rendezvous item
item = [mBookmarksOutlineView itemAtRow:index]; id parent = [curItem parent];
} else if (![parent isKindOfClass:[BookmarkItem class]])
item = aSender; {
[[NetworkServices sharedNetworkServices] attemptResolveService:[parent intValue] forSender:curItem];
if (!item)
return;
// see if it's a rendezvous item
id parent = [item parent];
if (![parent isKindOfClass:[BookmarkItem class]]) {
[[NetworkServices sharedNetworkServices] attemptResolveService:[parent intValue] forSender:item];
mOpenActionFlag = kOpenInNewTabAction; mOpenActionFlag = kOpenInNewTabAction;
return; }
} else
{
// otherwise follow the standard bookmark opening behavior
[[NSApp delegate] loadBookmark:curItem withWindowController:mBrowserWindowController openBehavior:eBookmarkOpenBehaviorNewTabDefault];
}
}
}
// otherwise follow the standard bookmark opening behavior -(IBAction)openBookmarksInTabsInNewWindow:(id)aSender
[[NSApp delegate] loadBookmark:item withWindowController:mBrowserWindowController openBehavior:eBookmarkOpenBehaviorNewTabDefault]; {
NSArray* items = nil;
if ([aSender isKindOfClass:[BookmarkItem class]])
items = [NSArray arrayWithObject:aSender];
else
items = [mBookmarksOutlineView selectedItems];
// make url array
NSMutableArray* urlArray = [NSMutableArray arrayWithCapacity:[items count]];
NSEnumerator* itemsEnum = [items objectEnumerator];
id curItem;
while ((curItem = [itemsEnum nextObject]))
{
// see if it's a rendezvous item (this won't open in the new window, because we suck)
id parent = [curItem parent];
if (![parent isKindOfClass:[BookmarkItem class]])
{
[[NetworkServices sharedNetworkServices] attemptResolveService:[parent intValue] forSender:curItem];
mOpenActionFlag = kOpenInNewTabAction;
}
else
{
if ([curItem isKindOfClass:[Bookmark class]])
[urlArray addObject:[curItem url]];
else if ([curItem isKindOfClass:[BookmarkFolder class]])
[urlArray addObjectsFromArray:[curItem childURLs]];
}
}
// make new window
BOOL loadNewTabsInBackgroundPref = [[PreferenceManager sharedInstance] getBooleanPref:"browser.tabs.loadInBackground" withSuccess:NULL];
NSWindow* behindWindow = nil;
if (loadNewTabsInBackgroundPref)
behindWindow = [mBrowserWindowController window];
[[NSApp delegate] openBrowserWindowWithURLs:urlArray behind:behindWindow allowPopups:NO];
} }
-(IBAction)openBookmarkInNewWindow:(id)aSender -(IBAction)openBookmarkInNewWindow:(id)aSender
{ {
id item = nil; NSArray* items = nil;
if (![aSender isKindOfClass:[BookmarkItem class]]) { if ([aSender isKindOfClass:[BookmarkItem class]])
int index = [mBookmarksOutlineView selectedRow]; items = [NSArray arrayWithObject:aSender];
if (index == -1) else
return; items = [mBookmarksOutlineView selectedItems];
if ([mBookmarksOutlineView numberOfSelectedRows] == 1)
item = [mBookmarksOutlineView itemAtRow:index];
} else
item = aSender;
if (!item)
return;
// see if it's a rendezvous item NSEnumerator* itemsEnum = [items objectEnumerator];
id parent = [item parent]; id curItem;
if (![parent isKindOfClass:[BookmarkItem class]]) { while ((curItem = [itemsEnum nextObject]))
[[NetworkServices sharedNetworkServices] attemptResolveService:[parent intValue] forSender:item]; {
mOpenActionFlag = kOpenInNewWindowAction; // see if it's a rendezvous item
return; id parent = [curItem parent];
if (![parent isKindOfClass:[BookmarkItem class]])
{
[[NetworkServices sharedNetworkServices] attemptResolveService:[parent intValue] forSender:curItem];
mOpenActionFlag = kOpenInNewWindowAction;
}
else
{
// otherwise follow the standard bookmark opening behavior
[[NSApp delegate] loadBookmark:curItem withWindowController:mBrowserWindowController openBehavior:eBookmarkOpenBehaviorNewWindowDefault];
}
} }
// otherwise follow the standard bookmark opening behavior
[[NSApp delegate] loadBookmark:item withWindowController:mBrowserWindowController openBehavior:eBookmarkOpenBehaviorNewWindowDefault];
} }
-(IBAction)showBookmarkInfo:(id)aSender -(IBAction)showBookmarkInfo:(id)aSender
@ -598,15 +629,7 @@ static const int kDisabledQuicksearchPopupItemTag = 9999;
- (IBAction)copy:(id)aSender - (IBAction)copy:(id)aSender
{ {
// Get the list of bookmark items that are selected [self copyBookmarks:[mBookmarksOutlineView selectedItems] toPasteboard:[NSPasteboard generalPasteboard]];
NSMutableArray *bookmarkItemsToCopy = [NSMutableArray array];
NSEnumerator* selRows = [mBookmarksOutlineView selectedRowEnumerator];
id curSelectedRow;
while ((curSelectedRow = [selRows nextObject])) {
[bookmarkItemsToCopy addObject: [mBookmarksOutlineView itemAtRow:[curSelectedRow intValue]]];
}
[self copyBookmarks:bookmarkItemsToCopy toPasteboard:[NSPasteboard generalPasteboard]];
} }
@ -1386,9 +1409,9 @@ static const int kDisabledQuicksearchPopupItemTag = 9999;
return nil; return nil;
} }
- (NSMenu *)outlineView:(NSOutlineView *)outlineView contextMenuForItem:(id)item - (NSMenu *)outlineView:(NSOutlineView *)outlineView contextMenuForItems:(NSArray*)items
{ {
return [[BookmarkManager sharedBookmarkManager] contextMenuForItem:item fromView:outlineView target:self]; return [[BookmarkManager sharedBookmarkManager] contextMenuForItems:items fromView:outlineView target:self];
} }
- (BOOL)outlineView:(NSOutlineView*)inOutlineView columnHasIcon:(NSTableColumn*)inColumn - (BOOL)outlineView:(NSOutlineView*)inOutlineView columnHasIcon:(NSTableColumn*)inColumn
@ -1661,10 +1684,9 @@ static const int kDisabledQuicksearchPopupItemTag = 9999;
} }
else else
{ {
int index = [mBookmarksOutlineView selectedRow]; NSArray* selectedBMs = [mBookmarksOutlineView selectedItems];
BookmarkItem* item = [mBookmarksOutlineView itemAtRow:index]; if ([selectedBMs count] > 0)
if (item) actionMenu = [[BookmarkManager sharedBookmarkManager] contextMenuForItems:selectedBMs fromView:mBookmarksOutlineView target:self];
actionMenu = [[BookmarkManager sharedBookmarkManager] contextMenuForItem:item fromView:mBookmarksOutlineView target:self];
else else
actionMenu = mActionMenuBookmarks; actionMenu = mActionMenuBookmarks;
} }

Просмотреть файл

@ -68,6 +68,8 @@
-(void)setDeleteAction: (SEL)deleteAction; -(void)setDeleteAction: (SEL)deleteAction;
-(SEL)deleteAction; -(SEL)deleteAction;
- (NSArray*)selectedItems;
-(void)_editItem:(id)item; -(void)_editItem:(id)item;
-(void)_cancelEditItem; -(void)_cancelEditItem;
@ -99,6 +101,6 @@
@end @end
@interface NSObject (CHOutlineViewContextMenus) @interface NSObject (CHOutlineViewContextMenus)
- (NSMenu *)outlineView:(NSOutlineView *)outlineView contextMenuForItem:(id)item; - (NSMenu *)outlineView:(NSOutlineView *)outlineView contextMenuForItems:(NSArray*)items;
@end @end

Просмотреть файл

@ -106,6 +106,21 @@ static NSString* const kAutosaveSortDirectionKey = @"sort_descending";
mDelegateTooltipStringForItem = [anObject respondsToSelector:@selector(outlineView:tooltipStringForItem:)]; mDelegateTooltipStringForItem = [anObject respondsToSelector:@selector(outlineView:tooltipStringForItem:)];
} }
- (NSArray*)selectedItems
{
NSMutableArray* itemsArray = [NSMutableArray arrayWithCapacity:[self numberOfSelectedRows]];
NSEnumerator* rowEnum = [self selectedRowEnumerator];
NSNumber* currentRow = nil;
while ((currentRow = [rowEnum nextObject]))
{
id item = [self itemAtRow:[currentRow intValue]];
[itemsArray addObject:item];
}
return itemsArray;
}
-(void)keyDown:(NSEvent*)aEvent -(void)keyDown:(NSEvent*)aEvent
{ {
const unichar kForwardDeleteChar = 0xf728; // couldn't find this in any cocoa header const unichar kForwardDeleteChar = 0xf728; // couldn't find this in any cocoa header
@ -206,40 +221,39 @@ static NSString* const kAutosaveSortDirectionKey = @"sort_descending";
*/ */
- (NSMenu *)menuForEvent:(NSEvent *)theEvent - (NSMenu *)menuForEvent:(NSEvent *)theEvent
{ {
id item; NSPoint point = [self convertPoint:[theEvent locationInWindow] fromView:nil];
int rowIndex; int rowIndex = [self rowAtPoint:point];
NSPoint point;
point = [self convertPoint:[theEvent locationInWindow] fromView:nil];
rowIndex = [self rowAtPoint:point];
if (rowIndex >= 0) { if (rowIndex >= 0)
{
// There seems to be a bug in AppKit; selectRow is supposed to // There seems to be a bug in AppKit; selectRow is supposed to
// abort editing, but it doesn't, thus we do it manually. // abort editing, but it doesn't, thus we do it manually.
[self abortEditing]; [self abortEditing];
item = [self itemAtRow:rowIndex]; id item = [self itemAtRow:rowIndex];
if (item) { if (!item) return nil; // someone might want a menu on the blank area
id delegate = [self delegate];
// Make sure the item is the only selected one id delegate = [self delegate];
if (![delegate respondsToSelector:@selector(outlineView:shouldSelectItem:)] ||
[delegate outlineView:self shouldSelectItem:item]) // if we click on a selected item, don't deselect other stuff.
{ // otherwise, select just the current item.
// we don't want anything but what was right-clicked selected
// XXX sure we do. I should be able to context-click on a bunch of selected bookmarks // Make sure the item is the only selected one
// and say 'open in tabs'. However, the current delegate method prevents this, because if (![self isRowSelected:rowIndex])
// it only allows you to pass a single item. This needs fixing. {
[self deselectAll:nil]; BOOL shouldSelect = ![delegate respondsToSelector:@selector(outlineView:shouldSelectItem:)] ||
[self selectRow:rowIndex byExtendingSelection:NO]; [delegate outlineView:self shouldSelectItem:item];
} if (!shouldSelect)
return nil; // can't select it, so bail
if ([delegate respondsToSelector:@selector(outlineView:contextMenuForItem:)])
return [delegate outlineView:self contextMenuForItem:item]; [self selectRow:rowIndex byExtendingSelection:NO];
} else {
// no item, no context menu
return nil;
} }
if ([delegate respondsToSelector:@selector(outlineView:contextMenuForItems:)])
return [delegate outlineView:self contextMenuForItems:[self selectedItems]];
} }
else { else
{
[self deselectAll:self]; [self deselectAll:self];
} }

Просмотреть файл

@ -71,6 +71,7 @@
- (IBAction)openHistoryItem:(id)sender; - (IBAction)openHistoryItem:(id)sender;
- (IBAction)openHistoryItemInNewWindow:(id)aSender; - (IBAction)openHistoryItemInNewWindow:(id)aSender;
- (IBAction)openHistoryItemInNewTab:(id)aSender; - (IBAction)openHistoryItemInNewTab:(id)aSender;
- (IBAction)openHistoryItemsInTabsInNewWindow:(id)aSender;
- (IBAction)deleteHistoryItems:(id)sender; - (IBAction)deleteHistoryItems:(id)sender;

Просмотреть файл

@ -45,6 +45,7 @@
#import "PreferenceManager.h" #import "PreferenceManager.h"
#import "BrowserWindowController.h" #import "BrowserWindowController.h"
#import "BookmarkViewController.h" #import "BookmarkViewController.h"
#import "MainController.h"
#import "HistoryOutlineViewDelegate.h" #import "HistoryOutlineViewDelegate.h"
@ -73,7 +74,6 @@ static NSString* const kExpandedHistoryStatesDefaultsKey = @"history_expand_stat
- (void)historyChanged:(NSNotification *)notification; - (void)historyChanged:(NSNotification *)notification;
- (HistoryDataSource*)historyDataSource; - (HistoryDataSource*)historyDataSource;
- (NSArray*)selectedItems;
- (void)recursiveDeleteItem:(HistoryItem*)item; - (void)recursiveDeleteItem:(HistoryItem*)item;
- (void)saveViewToPrefs; - (void)saveViewToPrefs;
- (void)updateSortMenuState; - (void)updateSortMenuState;
@ -171,29 +171,38 @@ static NSString* const kExpandedHistoryStatesDefaultsKey = @"history_expand_stat
- (IBAction)openHistoryItem:(id)sender - (IBAction)openHistoryItem:(id)sender
{ {
int index = [mHistoryOutlineView selectedRow]; NSArray* selectedHistoryItems = [mHistoryOutlineView selectedItems];
if (index == -1) return; if ([selectedHistoryItems count] == 0) return;
id item = [mHistoryOutlineView itemAtRow:index]; // only do expand/collapse if just one item is selected
if (!item) return; id firstItem;
if (([selectedHistoryItems count] == 1) &&
if ([mHistoryOutlineView isExpandable:item]) (firstItem = [selectedHistoryItems objectAtIndex:0]) &&
[mHistoryOutlineView isExpandable:firstItem])
{ {
if ([mHistoryOutlineView isItemExpanded: item]) if ([mHistoryOutlineView isItemExpanded: firstItem])
[mHistoryOutlineView collapseItem:item]; [mHistoryOutlineView collapseItem:firstItem];
else else
[mHistoryOutlineView expandItem:item]; [mHistoryOutlineView expandItem:firstItem];
return;
} }
else
BOOL loadInBackground = [[PreferenceManager sharedInstance] getBooleanPref:"browser.tabs.loadInBackground" withSuccess:NULL];
BOOL openInTabs = [[PreferenceManager sharedInstance] getBooleanPref:"browser.tabs.opentabfor.middleclick" withSuccess:NULL];
BOOL cmdKeyDown = (GetCurrentKeyModifiers() & cmdKey) != 0;
NSEnumerator* itemEnum = [selectedHistoryItems objectEnumerator];
id curItem;
while ((curItem = [itemEnum nextObject]))
{ {
// The history view obeys the app preference for cmd-click -> open in new window or tab // The history view obeys the app preference for cmd-click -> open in new window or tab
if (![item isSiteItem]) return; if (![curItem isSiteItem]) continue;
NSString* url = [item url]; NSString* url = [curItem url];
BOOL loadInBackground = [[PreferenceManager sharedInstance] getBooleanPref:"browser.tabs.loadInBackground" withSuccess:NULL]; if (cmdKeyDown)
if (GetCurrentKeyModifiers() & cmdKey)
{ {
if ([[PreferenceManager sharedInstance] getBooleanPref:"browser.tabs.opentabfor.middleclick" withSuccess:NULL]) if (openInTabs)
[mBrowserWindowController openNewTabWithURL:url referrer:nil loadInBackground:loadInBackground allowPopups:NO]; [mBrowserWindowController openNewTabWithURL:url referrer:nil loadInBackground:loadInBackground allowPopups:NO];
else else
[mBrowserWindowController openNewWindowWithURL:url referrer: nil loadInBackground:loadInBackground allowPopups:NO]; [mBrowserWindowController openNewWindowWithURL:url referrer: nil loadInBackground:loadInBackground allowPopups:NO];
@ -205,15 +214,12 @@ static NSString* const kExpandedHistoryStatesDefaultsKey = @"history_expand_stat
- (IBAction)deleteHistoryItems:(id)sender - (IBAction)deleteHistoryItems:(id)sender
{ {
int index = [mHistoryOutlineView selectedRow];
if (index == -1)
return;
// If just 1 row was selected, keep it so the user can delete again immediately // If just 1 row was selected, keep it so the user can delete again immediately
BOOL clearSelectionWhenDone = ([mHistoryOutlineView numberOfSelectedRows] > 1); BOOL clearSelectionWhenDone = ([mHistoryOutlineView numberOfSelectedRows] > 1);
// make a list of doomed items first so the rows don't change under us // make a list of doomed items first so the rows don't change under us
NSArray* doomedItems = [self selectedItems]; NSArray* doomedItems = [mHistoryOutlineView selectedItems];
if ([doomedItems count] == 0) return;
// to avoid potentially many updates, disabled auto updating // to avoid potentially many updates, disabled auto updating
mUpdatesDisabled = YES; mUpdatesDisabled = YES;
@ -241,7 +247,7 @@ static NSString* const kExpandedHistoryStatesDefaultsKey = @"history_expand_stat
// called from context menu, assumes represented object has been set // called from context menu, assumes represented object has been set
- (IBAction)openHistoryItemInNewWindow:(id)aSender - (IBAction)openHistoryItemInNewWindow:(id)aSender
{ {
NSArray* itemsArray = [self selectedItems]; NSArray* itemsArray = [mHistoryOutlineView selectedItems];
BOOL backgroundLoad = [[PreferenceManager sharedInstance] getBooleanPref:"browser.tabs.loadInBackground" withSuccess:NULL]; BOOL backgroundLoad = [[PreferenceManager sharedInstance] getBooleanPref:"browser.tabs.loadInBackground" withSuccess:NULL];
@ -257,7 +263,7 @@ static NSString* const kExpandedHistoryStatesDefaultsKey = @"history_expand_stat
// called from context menu, assumes represented object has been set // called from context menu, assumes represented object has been set
- (IBAction)openHistoryItemInNewTab:(id)aSender - (IBAction)openHistoryItemInNewTab:(id)aSender
{ {
NSArray* itemsArray = [self selectedItems]; NSArray* itemsArray = [mHistoryOutlineView selectedItems];
BOOL backgroundLoad = [[PreferenceManager sharedInstance] getBooleanPref:"browser.tabs.loadInBackground" withSuccess:NULL]; BOOL backgroundLoad = [[PreferenceManager sharedInstance] getBooleanPref:"browser.tabs.loadInBackground" withSuccess:NULL];
@ -270,6 +276,31 @@ static NSString* const kExpandedHistoryStatesDefaultsKey = @"history_expand_stat
} }
} }
- (IBAction)openHistoryItemsInTabsInNewWindow:(id)aSender
{
NSArray* itemsArray = [mHistoryOutlineView selectedItems];
// make url array
NSMutableArray* urlArray = [NSMutableArray arrayWithCapacity:[itemsArray count]];
NSEnumerator* itemsEnum = [itemsArray objectEnumerator];
id curItem;
while ((curItem = [itemsEnum nextObject]))
{
if ([curItem isKindOfClass:[HistorySiteItem class]])
[urlArray addObject:[curItem url]];
}
// make new window
BOOL loadNewTabsInBackgroundPref = [[PreferenceManager sharedInstance] getBooleanPref:"browser.tabs.loadInBackground" withSuccess:NULL];
NSWindow* behindWindow = nil;
if (loadNewTabsInBackgroundPref)
behindWindow = [mBrowserWindowController window];
[[NSApp delegate] openBrowserWindowWithURLs:urlArray behind:behindWindow allowPopups:NO];
}
#pragma mark - #pragma mark -
- (IBAction)groupByDate:(id)sender - (IBAction)groupByDate:(id)sender
@ -345,13 +376,59 @@ static NSString* const kExpandedHistoryStatesDefaultsKey = @"history_expand_stat
} }
#endif #endif
- (NSMenu *)outlineView:(NSOutlineView *)outlineView contextMenuForItem:(id)item - (NSMenu *)outlineView:(NSOutlineView *)outlineView contextMenuForItems:(NSArray*)items
{ {
HistoryItem* historyItem = (HistoryItem*)item; unsigned int numSiteItems = 0;
if (![historyItem isKindOfClass:[HistorySiteItem class]])
return nil;
return mOutlinerContextMenu; NSEnumerator* itemsEnum = [items objectEnumerator];
id curItem;
while ((curItem = [itemsEnum nextObject]))
{
if ([curItem isKindOfClass:[HistorySiteItem class]])
++numSiteItems;
}
if (numSiteItems == 0)
return [outlineView menu];
NSMenu* contextMenu = [[[NSMenu alloc] initWithTitle:@"notitle"] autorelease];
NSMenuItem* menuItem = nil;
NSString* menuTitle = nil;
if (numSiteItems > 1)
menuTitle = NSLocalizedString(@"Open in New Windows", @"");
else
menuTitle = NSLocalizedString(@"Open in New Window", @"");
menuItem = [[[NSMenuItem alloc] initWithTitle:menuTitle action:@selector(openHistoryItemInNewWindow:) keyEquivalent:@""] autorelease];
[menuItem setTarget:self];
[contextMenu addItem:menuItem];
if (numSiteItems > 1)
menuTitle = NSLocalizedString(@"Open in New Tabs", @"");
else
menuTitle = NSLocalizedString(@"Open in New Tab", @"");
menuItem = [[[NSMenuItem alloc] initWithTitle:menuTitle action:@selector(openHistoryItemInNewTab:) keyEquivalent:@""] autorelease];
[menuItem setTarget:self];
[contextMenu addItem:menuItem];
if (numSiteItems > 1)
{
menuTitle = NSLocalizedString(@"Open in Tabs in New Window", @"");
menuItem = [[[NSMenuItem alloc] initWithTitle:menuTitle action:@selector(openHistoryItemsInTabsInNewWindow:) keyEquivalent:@""] autorelease];
[menuItem setTarget:self];
[contextMenu addItem:menuItem];
}
// space
[contextMenu addItem:[NSMenuItem separatorItem]];
// delete
menuTitle = NSLocalizedString(@"Delete", @"");
menuItem = [[[NSMenuItem alloc] initWithTitle:menuTitle action:@selector(deleteHistoryItems:) keyEquivalent:@""] autorelease];
[menuItem setTarget:self];
[contextMenu addItem:menuItem];
return contextMenu;
} }
- (void)outlineViewItemDidExpand:(NSNotification *)notification - (void)outlineViewItemDidExpand:(NSNotification *)notification
@ -381,6 +458,9 @@ static NSString* const kExpandedHistoryStatesDefaultsKey = @"history_expand_stat
if (action == @selector(openHistoryItemInNewTab:)) if (action == @selector(openHistoryItemInNewTab:))
return [self anyHistorySiteItemsSelected]; return [self anyHistorySiteItemsSelected];
if (action == @selector(openHistoryItemsInTabsInNewWindow:))
return [self anyHistorySiteItemsSelected];
if (action == @selector(deleteHistoryItems:)) if (action == @selector(deleteHistoryItems:))
return [self anyHistorySiteItemsSelected]; return [self anyHistorySiteItemsSelected];
@ -403,21 +483,6 @@ static NSString* const kExpandedHistoryStatesDefaultsKey = @"history_expand_stat
} }
} }
- (NSArray*)selectedItems
{
NSMutableArray* itemsArray = [NSMutableArray arrayWithCapacity:[mHistoryOutlineView numberOfSelectedRows]];
NSEnumerator* rowEnum = [mHistoryOutlineView selectedRowEnumerator];
NSNumber* currentRow = nil;
while ((currentRow = [rowEnum nextObject]))
{
HistoryItem * item = [mHistoryOutlineView itemAtRow:[currentRow intValue]];
[itemsArray addObject:item];
}
return itemsArray;
}
- (void)recursiveDeleteItem:(HistoryItem*)item - (void)recursiveDeleteItem:(HistoryItem*)item
{ {
if ([item isKindOfClass:[HistorySiteItem class]]) if ([item isKindOfClass:[HistorySiteItem class]])