diff options
Diffstat (limited to 'chrome/browser/cocoa')
6 files changed, 165 insertions, 51 deletions
diff --git a/chrome/browser/cocoa/bookmark_bar_controller.h b/chrome/browser/cocoa/bookmark_bar_controller.h index d7d34d6..d9183b4 100644 --- a/chrome/browser/cocoa/bookmark_bar_controller.h +++ b/chrome/browser/cocoa/bookmark_bar_controller.h @@ -261,6 +261,12 @@ willAnimateFromState:(bookmarks::VisualState)oldState // Import bookmarks from another browser. - (IBAction)importBookmarks:(id)sender; +// Provide a favIcon for a bookmark node. May return nil. +- (NSImage*)favIconForNode:(const BookmarkNode*)node; + +// Provide a contextual menu for a bookmark node. May return nil. +- (NSMenu*)contextMenuForNode:(const BookmarkNode*)node; + // Actions for manipulating bookmarks. // Open a normal bookmark or folder from a button, ... - (IBAction)openBookmark:(id)sender; @@ -272,7 +278,9 @@ willAnimateFromState:(bookmarks::VisualState)oldState - (IBAction)openBookmarkInNewWindow:(id)sender; - (IBAction)openBookmarkInIncognitoWindow:(id)sender; - (IBAction)editBookmark:(id)sender; +- (IBAction)cutBookmark:(id)sender; - (IBAction)copyBookmark:(id)sender; +- (IBAction)pasteBookmark:(id)sender; - (IBAction)deleteBookmark:(id)sender; // From a context menu over the bar, ... - (IBAction)openAllBookmarks:(id)sender; diff --git a/chrome/browser/cocoa/bookmark_bar_controller.mm b/chrome/browser/cocoa/bookmark_bar_controller.mm index fe0c17b..bb6895a 100644 --- a/chrome/browser/cocoa/bookmark_bar_controller.mm +++ b/chrome/browser/cocoa/bookmark_bar_controller.mm @@ -13,7 +13,6 @@ #include "chrome/browser/browser.h" #include "chrome/browser/browser_list.h" #import "chrome/browser/browser_theme_provider.h" -#import "chrome/browser/browser_window.h" #import "chrome/browser/cocoa/background_gradient_view.h" #import "chrome/browser/cocoa/bookmark_bar_bridge.h" #import "chrome/browser/cocoa/bookmark_bar_constants.h" @@ -1037,7 +1036,9 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { } if ((action == @selector(editBookmark:)) || - (action == @selector(deleteBookmark:))) { + (action == @selector(deleteBookmark:)) || + (action == @selector(cutBookmark:)) || + (action == @selector(copyBookmark:))) { // Don't allow edit/delete of the bar node, or of "Other Bookmarks" if ((node == nil) || (node == bookmarkModel_->other_node()) || @@ -1046,6 +1047,10 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { } } + if (action == @selector(pasteBookmark:) && + !bookmark_utils::CanPasteFromClipboard(node)) + return NO; + // If this is an incognito window, don't allow "open in incognito". if ((action == @selector(openBookmarkInIncognitoWindow:)) || (action == @selector(openAllBookmarksIncognitoWindow:))) { @@ -1195,9 +1200,10 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { [self closeAllBookmarkFolders]; // Folder controller, like many window controllers, owns itself. - folderController_ = [[BookmarkBarFolderController alloc] - initWithParentButton:parentButton - parentController:self]; + folderController_ = + [[BookmarkBarFolderController alloc] initWithParentButton:parentButton + parentController:nil + barController:self]; [folderController_ showWindow:self]; // Only BookmarkBarController has this; the @@ -1257,12 +1263,41 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { nil); } +- (IBAction)cutBookmark:(id)sender { + const BookmarkNode* node = [self nodeFromMenuItem:sender]; + if (node) { + std::vector<const BookmarkNode*> nodes; + nodes.push_back(node); + bookmark_utils::CopyToClipboard(bookmarkModel_, nodes, true); + } +} + - (IBAction)copyBookmark:(id)sender { const BookmarkNode* node = [self nodeFromMenuItem:sender]; if (node) { - NSPasteboard* pboard = [NSPasteboard generalPasteboard]; - [[self folderTarget] copyBookmarkNode:node - toPasteboard:pboard]; + std::vector<const BookmarkNode*> nodes; + nodes.push_back(node); + bookmark_utils::CopyToClipboard(bookmarkModel_, nodes, false); + } +} + +// Paste the copied node immediately after the node for which the context +// menu has been presented. +- (IBAction)pasteBookmark:(id)sender { + const BookmarkNode* node = [self nodeFromMenuItem:sender]; + if (node) { + const BookmarkNode* parent = node->GetParent(); + // Pasting into the bar but not onto any element in the bar causes the + // pasted node to be placed at the right end of the bar. + int index = -1; + if (node == bookmarkModel_->GetBookmarkBarNode()) { + parent = node; + } else { + index = parent->IndexOfChild(node) + 1; + if (index > parent->GetChildCount()) + index = -1; + } + bookmark_utils::PasteFromClipboard(bookmarkModel_, parent, index); } } @@ -1271,9 +1306,6 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { if (node) { bookmarkModel_->Remove(node->GetParent(), node->GetParent()->IndexOfChild(node)); - // TODO(jrg): don't close; rebuild. - // http://crbug.com/36614 - [self closeAllBookmarkFolders]; } } @@ -1602,9 +1634,11 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { return; // If this is a rebuild request while we have a folder open, close it. - if (folderController_) { + // TODO(mrossetti): Eliminate the need for this because it causes the folder + // menu to disappear after a cut/copy/paste/delete change. + // See: http://crbug.com/36614 + if (folderController_) [self closeAllBookmarkFolders]; - } // Brute force nuke and build. savedFrameWidth_ = NSWidth([[self view] frame]); diff --git a/chrome/browser/cocoa/bookmark_bar_folder_controller.h b/chrome/browser/cocoa/bookmark_bar_folder_controller.h index 64ae5f6..d13d51d 100644 --- a/chrome/browser/cocoa/bookmark_bar_folder_controller.h +++ b/chrome/browser/cocoa/bookmark_bar_folder_controller.h @@ -7,6 +7,7 @@ #include "base/scoped_nsobject.h" #import "chrome/browser/cocoa/bookmark_button.h" +@class BookmarkBarController; @class BookmarkBarFolderView; @class BookmarkFolderTarget; @@ -45,12 +46,12 @@ // strong pointers to our owning controller, so the entire chain // stays owned. - // Our parent controller. This may be another - // BookmarkBarFolderController (if we are a nested folder) or it may - // be the BookmarkBarController (if not). + // Our parent controller, if we are a nested folder, otherwise nil. // Strong to insure the object lives as long as we need it. - scoped_nsobject<NSObject<BookmarkButtonControllerProtocol> > - parentController_; + scoped_nsobject<BookmarkBarFolderController> parentController_; + + // The main bar controller from whence we or a parent sprang. + BookmarkBarController* barController_; // WEAK: It owns us. // Our buttons. We do not have buttons for nested folders. scoped_nsobject<NSMutableArray> buttons_; @@ -58,6 +59,12 @@ // The main view of this window (where the buttons go). IBOutlet BookmarkBarFolderView* mainView_; + // The context menu for a bookmark button which represents an URL. + IBOutlet NSMenu* buttonMenu_; + + // The context menu for a bookmark button which represents a folder. + IBOutlet NSMenu* folderMenu_; + // Like normal menus, hovering over a folder button causes it to // open. This variable is set when a hover is initiated (but has // not necessarily fired yet). @@ -88,12 +95,30 @@ CGFloat verticalScrollDelta_; } +// Designated initializer. - (id)initWithParentButton:(BookmarkButton*)button - parentController:(NSObject<BookmarkButtonControllerProtocol>*)controller; + parentController:(BookmarkBarFolderController*)parentController + barController:(BookmarkBarController*)barController; // Return the parent button that owns the bookmark folder we represent. - (BookmarkButton*)parentButton; +// Actions from a context menu over a button or folder. +- (IBAction)cutBookmark:(id)sender; +- (IBAction)copyBookmark:(id)sender; +- (IBAction)pasteBookmark:(id)sender; +- (IBAction)deleteBookmark:(id)sender; + +// Forwarded to the associated BookmarkBarController. +- (IBAction)addFolder:(id)sender; +- (IBAction)addPage:(id)sender; +- (IBAction)editBookmark:(id)sender; +- (IBAction)openAllBookmarks:(id)sender; +- (IBAction)openAllBookmarksIncognitoWindow:(id)sender; +- (IBAction)openAllBookmarksNewWindow:(id)sender; +- (IBAction)openBookmarkInIncognitoWindow:(id)sender; +- (IBAction)openBookmarkInNewForegroundTab:(id)sender; +- (IBAction)openBookmarkInNewWindow:(id)sender; @end diff --git a/chrome/browser/cocoa/bookmark_bar_folder_controller.mm b/chrome/browser/cocoa/bookmark_bar_folder_controller.mm index 8387264..ac2be62 100644 --- a/chrome/browser/cocoa/bookmark_bar_folder_controller.mm +++ b/chrome/browser/cocoa/bookmark_bar_folder_controller.mm @@ -6,6 +6,7 @@ #include "base/mac_util.h" #include "base/sys_string_conversions.h" #include "chrome/browser/bookmarks/bookmark_model.h" +#include "chrome/browser/bookmarks/bookmark_utils.h" #import "chrome/browser/browser_theme_provider.h" #import "chrome/browser/cocoa/bookmark_bar_constants.h" // namespace bookmarks #import "chrome/browser/cocoa/bookmark_bar_controller.h" // namespace bookmarks @@ -40,13 +41,15 @@ const CGFloat kBookmarkBarFolderScrollAmount = @implementation BookmarkBarFolderController - (id)initWithParentButton:(BookmarkButton*)button - parentController:(NSObject<BookmarkButtonControllerProtocol>*)controller { + parentController:(BookmarkBarFolderController*)parentController + barController:(BookmarkBarController*)barController { NSString* nibPath = [mac_util::MainAppBundle() pathForResource:@"BookmarkBarFolderWindow" ofType:@"nib"]; if ((self = [super initWithWindowNibPath:nibPath owner:self])) { parentButton_.reset([button retain]); - parentController_.reset([controller retain]); + parentController_.reset([parentController retain]); + barController_ = barController; // WEAK buttons_.reset([[NSMutableArray alloc] init]); folderTarget_.reset([[BookmarkFolderTarget alloc] initWithController:self]); [self configureWindow]; @@ -73,8 +76,8 @@ const CGFloat kBookmarkBarFolderScrollAmount = } - (NSCell*)cellForBookmarkNode:(const BookmarkNode*)child { - NSImage* image = child ? [self favIconForNode:child] : nil; - NSMenu* menu = [self contextMenuForNode:child]; + NSImage* image = child ? [barController_ favIconForNode:child] : nil; + NSMenu* menu = child ? child->is_folder() ? folderMenu_ : buttonMenu_ : nil; BookmarkBarFolderButtonCell* cell = [BookmarkBarFolderButtonCell buttonCellForNode:child contextMenu:menu @@ -83,14 +86,6 @@ const CGFloat kBookmarkBarFolderScrollAmount = return cell; } -- (NSImage*)favIconForNode:(const BookmarkNode*)node { - return node ? [parentController_ favIconForNode:node] : nil; -} - -- (NSMenu*)contextMenuForNode:(const BookmarkNode*)node { - return node ? [parentController_ contextMenuForNode:node] : nil; -} - // Redirect to our logic shared with BookmarkBarController. - (IBAction)openBookmarkFolderFromButton:(id)sender { [folderTarget_ openBookmarkFolderFromButton:sender]; @@ -413,7 +408,7 @@ const CGFloat kBookmarkBarFolderScrollAmount = // Recursively close all bookmark folders. - (void)closeAllBookmarkFolders { // Closing the top level implicitly closes all children. - [parentController_ closeAllBookmarkFolders]; + [barController_ closeAllBookmarkFolders]; } // Close our bookmark folder (a sub-controller) if we have one. @@ -622,7 +617,7 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { } - (BookmarkModel*)bookmarkModel { - return [parentController_ bookmarkModel]; + return [barController_ bookmarkModel]; } // TODO(jrg): ARGH more code dup. @@ -718,7 +713,8 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { } - (NSWindow*)parentWindow { - return [parentController_ parentWindow]; + return parentController_ ? [parentController_ parentWindow] : + [barController_ parentWindow]; } // Close the old hover-open bookmark folder, and open a new one. We @@ -769,20 +765,16 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { [parentController_ openAll:node disposition:disposition]; } -- (IBAction)openBookmark:(id)sender { - // Parent controller closes it all... - [parentController_ openBookmark:sender]; -} - // Add a new folder controller as triggered by the given folder button. - (void)addNewFolderControllerWithParentButton:(BookmarkButton*)parentButton { if (folderController_) [self closeAllBookmarkFolders]; // Folder controller, like many window controllers, owns itself. - folderController_ = [[BookmarkBarFolderController alloc] - initWithParentButton:parentButton - parentController:self]; + folderController_ = + [[BookmarkBarFolderController alloc] initWithParentButton:parentButton + parentController:self + barController:barController_]; [folderController_ showWindow:self]; } @@ -795,4 +787,62 @@ static BOOL ValueInRangeInclusive(CGFloat low, CGFloat value, CGFloat high) { [super close]; } +#pragma mark Methods Forwarded to BookmarkBarController + +- (IBAction)cutBookmark:(id)sender { + [barController_ cutBookmark:sender]; +} + +- (IBAction)copyBookmark:(id)sender { + [barController_ cutBookmark:sender]; +} + +- (IBAction)pasteBookmark:(id)sender { + [barController_ pasteBookmark:sender]; +} + +- (IBAction)deleteBookmark:(id)sender { + [barController_ deleteBookmark:sender]; +} + +- (IBAction)openBookmark:(id)sender { + [barController_ openBookmark:sender]; +} + +- (IBAction)addFolder:(id)sender { + [barController_ addFolder:sender]; +} + +- (IBAction)addPage:(id)sender { + [barController_ addPage:sender]; +} + +- (IBAction)editBookmark:(id)sender { + [barController_ editBookmark:sender]; +} + +- (IBAction)openAllBookmarks:(id)sender { + [barController_ openAllBookmarks:sender]; +} + +- (IBAction)openAllBookmarksIncognitoWindow:(id)sender { + [barController_ openAllBookmarksIncognitoWindow:sender]; +} + +- (IBAction)openAllBookmarksNewWindow:(id)sender { + [barController_ openAllBookmarksNewWindow:sender]; +} + +- (IBAction)openBookmarkInIncognitoWindow:(id)sender { + [barController_ openBookmarkInIncognitoWindow:sender]; +} + +- (IBAction)openBookmarkInNewForegroundTab:(id)sender { + [barController_ openBookmarkInNewForegroundTab:sender]; +} + +- (IBAction)openBookmarkInNewWindow:(id)sender { + [barController_ openBookmarkInNewWindow:sender]; +} + @end // BookmarkBarFolderController diff --git a/chrome/browser/cocoa/bookmark_bar_folder_controller_unittest.mm b/chrome/browser/cocoa/bookmark_bar_folder_controller_unittest.mm index 55b3d16..28e27ad 100644 --- a/chrome/browser/cocoa/bookmark_bar_folder_controller_unittest.mm +++ b/chrome/browser/cocoa/bookmark_bar_folder_controller_unittest.mm @@ -116,7 +116,8 @@ class BookmarkBarFolderControllerTest : public CocoaTest { objectAtIndex:0]; return [[BookmarkBarFolderControllerPong alloc] initWithParentButton:parentButton - parentController:parentBarController_]; + parentController:nil + barController:parentBarController_]; } }; @@ -171,7 +172,8 @@ TEST_F(BookmarkBarFolderControllerTest, Position) { scoped_nsobject<BookmarkBarFolderController> bbfc; bbfc.reset([[BookmarkBarFolderControllerLow alloc] initWithParentButton:parentButton - parentController:parentBarController_]); + parentController:nil + barController:parentBarController_]); NSPoint pt = [bbfc windowTopLeft]; EXPECT_EQ(pt.y, NSMinY([[parentBarController_ view] frame])); @@ -179,7 +181,8 @@ TEST_F(BookmarkBarFolderControllerTest, Position) { scoped_nsobject<BookmarkBarFolderController> bbfc2; bbfc2.reset([[BookmarkBarFolderControllerLow alloc] initWithParentButton:[[bbfc buttons] objectAtIndex:0] - parentController:bbfc.get()]); + parentController:bbfc.get() + barController:parentBarController_]); pt = [bbfc2 windowTopLeft]; EXPECT_EQ(pt.x, NSMaxX([[[bbfc.get() window] contentView] frame])); } diff --git a/chrome/browser/cocoa/bookmark_button.h b/chrome/browser/cocoa/bookmark_button.h index d00de54..39970ff 100644 --- a/chrome/browser/cocoa/bookmark_button.h +++ b/chrome/browser/cocoa/bookmark_button.h @@ -115,12 +115,6 @@ class ThemeProvider; // If there is a current folder controller, close it. - (void)addNewFolderControllerWithParentButton:(BookmarkButton*)parentButton; -// Provide a favIcon for a bookmark node. May return nil. -- (NSImage*)favIconForNode:(const BookmarkNode*)node; - -// Provide a contextual menu for a bookmark node. May return nil. -- (NSMenu*)contextMenuForNode:(const BookmarkNode*)node; - // Open all of the nodes for the given node with disposition. - (void)openAll:(const BookmarkNode*)node disposition:(WindowOpenDisposition)disposition; |