summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorjrg@chromium.org <jrg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-23 23:56:19 +0000
committerjrg@chromium.org <jrg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-07-23 23:56:19 +0000
commitcb514b8024f425b974c680b06dcace135b32de39 (patch)
tree79a1530164118302eee0562b6bdf58f3a022f880 /chrome
parentb1e8cb31f85869171dcb383c7ec5e8176833ec04 (diff)
downloadchromium_src-cb514b8024f425b974c680b06dcace135b32de39.zip
chromium_src-cb514b8024f425b974c680b06dcace135b32de39.tar.gz
chromium_src-cb514b8024f425b974c680b06dcace135b32de39.tar.bz2
Added menus for bookmark bar folders. This is NOT based on the Cole
prototype; it is an attempt to get something functional in the short term, and have a visual baseline before doing something new. Added folder icons for bookmark bar folder buttons. Added an "off the side" button/menu for bookmark buttons which don't fit on the bar. Updated "Add page..." item to allow creating bookmarks in the folders (if selected over a folder button). BUG=http://crbug.com/8381 TEST=Here we go: 1) Make sure bookmark bar folders have the "folder" icon. 2) Right click on a folder --> Add Page, and add a bookmark. Make sure bookmark is now in the folder, not at the top level. 3) (Oh, you just implicitly verified you can open bookmark folders!) 4) Add 5 bookmarks then shrink the window thinner so all bookmark buttons don't fit. Make sure "off the right" button gets enabled (on right side of bar) and shows bookmarks in a pop-up menu (when clicked) that don't completely fit on the bar. 5) Make it super-wide so the all fit and make sure "off the right" button is disabled. 6) Add a bunch of bookmarks to a folder; make sure they all work. 7) Add nested folders (by editing the bookmark pref file and restarting Chrome) and make sure bookmark folder buttons have nested/cascading menus. Review URL: http://codereview.chromium.org/159286 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@21479 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/app/nibs/BookmarkBar.xib147
-rw-r--r--chrome/browser/cocoa/bookmark_bar_controller.h21
-rw-r--r--chrome/browser/cocoa/bookmark_bar_controller.mm208
-rw-r--r--chrome/browser/cocoa/bookmark_bar_controller_unittest.mm166
-rw-r--r--chrome/browser/cocoa/bookmark_bar_view.h25
-rw-r--r--chrome/browser/cocoa/bookmark_bar_view.mm22
-rw-r--r--chrome/browser/cocoa/bookmark_bar_view_unittest.mm58
-rw-r--r--chrome/browser/cocoa/bookmark_menu_bridge.mm26
-rw-r--r--chrome/browser/cocoa/bookmark_menu_cocoa_controller.h4
-rw-r--r--chrome/browser/cocoa/bookmark_menu_cocoa_controller.mm24
-rw-r--r--chrome/chrome.gyp5
11 files changed, 506 insertions, 200 deletions
diff --git a/chrome/app/nibs/BookmarkBar.xib b/chrome/app/nibs/BookmarkBar.xib
index e719a99..cc39ec8 100644
--- a/chrome/app/nibs/BookmarkBar.xib
+++ b/chrome/app/nibs/BookmarkBar.xib
@@ -39,9 +39,42 @@
<object class="NSCustomView" id="620641226">
<reference key="NSNextResponder"/>
<int key="NSvFlags">-2147483358</int>
- <string key="NSFrameSize">{468, 65}</string>
+ <object class="NSMutableArray" key="NSSubviews">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <object class="NSCustomView" id="610146462">
+ <reference key="NSNextResponder" ref="620641226"/>
+ <int key="NSvFlags">274</int>
+ <string key="NSFrameSize">{584, 144}</string>
+ <reference key="NSSuperview" ref="620641226"/>
+ <string key="NSClassName">NSView</string>
+ </object>
+ <object class="NSButton" id="1071220197">
+ <reference key="NSNextResponder" ref="620641226"/>
+ <int key="NSvFlags">305</int>
+ <string key="NSFrame">{{586, 2}, {14, 28}}</string>
+ <reference key="NSSuperview" ref="620641226"/>
+ <bool key="NSEnabled">YES</bool>
+ <object class="NSButtonCell" key="NSCell" id="1055451269">
+ <int key="NSCellFlags">67239424</int>
+ <int key="NSCellFlags2">134217728</int>
+ <string key="NSContents"/>
+ <reference key="NSControlView" ref="1071220197"/>
+ <int key="NSButtonFlags">-2042347265</int>
+ <int key="NSButtonFlags2">134</int>
+ <object class="NSCustomResource" key="NSNormalImage">
+ <string key="NSClassName">NSImage</string>
+ <string key="NSResourceName">chevron</string>
+ </object>
+ <string key="NSAlternateContents"/>
+ <string key="NSKeyEquivalent"/>
+ <int key="NSPeriodicDelay">400</int>
+ <int key="NSPeriodicInterval">75</int>
+ </object>
+ </object>
+ </object>
+ <string key="NSFrameSize">{600, 144}</string>
<reference key="NSSuperview"/>
- <string key="NSClassName">BookmarkBarView</string>
+ <string key="NSClassName">NSView</string>
</object>
<object class="NSMenu" id="183701277">
<string key="NSTitle"/>
@@ -283,14 +316,6 @@
</object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
- <string key="label">barContextualMenu_</string>
- <reference key="source" ref="620641226"/>
- <reference key="destination" ref="183701277"/>
- </object>
- <int key="connectionID">17</int>
- </object>
- <object class="IBConnectionRecord">
- <object class="IBOutletConnection" key="connection">
<string key="label">buttonContextMenu_</string>
<reference key="source" ref="1001"/>
<reference key="destination" ref="672481054"/>
@@ -441,6 +466,46 @@
</object>
<int key="connectionID">61</int>
</object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">buttonView_</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="610146462"/>
+ </object>
+ <int key="connectionID">65</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">offTheSideButton_</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="1071220197"/>
+ </object>
+ <int key="connectionID">66</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBActionConnection" key="connection">
+ <string key="label">openOffTheSideMenuFromButton:</string>
+ <reference key="source" ref="1001"/>
+ <reference key="destination" ref="1071220197"/>
+ </object>
+ <int key="connectionID">69</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">menu</string>
+ <reference key="source" ref="610146462"/>
+ <reference key="destination" ref="183701277"/>
+ </object>
+ <int key="connectionID">70</int>
+ </object>
+ <object class="IBConnectionRecord">
+ <object class="IBOutletConnection" key="connection">
+ <string key="label">menu</string>
+ <reference key="source" ref="620641226"/>
+ <reference key="destination" ref="183701277"/>
+ </object>
+ <int key="connectionID">71</int>
+ </object>
</object>
<object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects">
@@ -474,6 +539,11 @@
<object class="IBObjectRecord">
<int key="objectID">1</int>
<reference key="object" ref="620641226"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="610146462"/>
+ <reference ref="1071220197"/>
+ </object>
<reference key="parent" ref="1002"/>
</object>
<object class="IBObjectRecord">
@@ -638,6 +708,25 @@
<reference key="object" ref="1071747565"/>
<reference key="parent" ref="672481054"/>
</object>
+ <object class="IBObjectRecord">
+ <int key="objectID">62</int>
+ <reference key="object" ref="610146462"/>
+ <reference key="parent" ref="620641226"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">63</int>
+ <reference key="object" ref="1071220197"/>
+ <object class="NSMutableArray" key="children">
+ <bool key="EncodedWithXMLCoder">YES</bool>
+ <reference ref="1055451269"/>
+ </object>
+ <reference key="parent" ref="620641226"/>
+ </object>
+ <object class="IBObjectRecord">
+ <int key="objectID">64</int>
+ <reference key="object" ref="1055451269"/>
+ <reference key="parent" ref="1071220197"/>
+ </object>
</object>
</object>
<object class="NSMutableDictionary" key="flattenedProperties">
@@ -674,6 +763,9 @@
<string>4.IBPluginDependency</string>
<string>5.IBPluginDependency</string>
<string>6.IBPluginDependency</string>
+ <string>62.IBPluginDependency</string>
+ <string>63.IBPluginDependency</string>
+ <string>64.IBPluginDependency</string>
<string>7.IBPluginDependency</string>
<string>8.IBPluginDependency</string>
<string>9.IBPluginDependency</string>
@@ -683,7 +775,7 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
- <string>{{519, 625}, {468, 65}}</string>
+ <string>{{519, 546}, {600, 144}}</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
@@ -713,6 +805,9 @@
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
<string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
+ <string>com.apple.InterfaceBuilder.CocoaPlugin</string>
</object>
</object>
<object class="NSMutableDictionary" key="unlocalizedProperties">
@@ -735,20 +830,12 @@
</object>
</object>
<nil key="sourceID"/>
- <int key="maxID">61</int>
+ <int key="maxID">71</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
<bool key="EncodedWithXMLCoder">YES</bool>
<object class="IBPartialClassDescription">
- <string key="className">BackgroundGradientView</string>
- <string key="superclassName">NSView</string>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBProjectSource</string>
- <string key="minorKey">browser/cocoa/background_gradient_view.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
<string key="className">BookmarkBarController</string>
<string key="superclassName">NSViewController</string>
<object class="NSMutableDictionary" key="actions">
@@ -764,6 +851,8 @@
<string>openBookmarkInIncognitoWindow:</string>
<string>openBookmarkInNewForegroundTab:</string>
<string>openBookmarkInNewWindow:</string>
+ <string>openFolderMenuFromButton:</string>
+ <string>openOffTheSideMenuFromButton:</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
@@ -776,6 +865,8 @@
<string>id</string>
<string>id</string>
<string>id</string>
+ <string>id</string>
+ <string>id</string>
</object>
</object>
<object class="NSMutableDictionary" key="outlets">
@@ -783,12 +874,16 @@
<object class="NSMutableArray" key="dict.sortedKeys">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>buttonContextMenu_</string>
+ <string>buttonView_</string>
<string>delegate_</string>
+ <string>offTheSideButton_</string>
</object>
<object class="NSMutableArray" key="dict.values">
<bool key="EncodedWithXMLCoder">YES</bool>
<string>NSMenu</string>
+ <string>NSView</string>
<string>id</string>
+ <string>NSButton</string>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
@@ -797,18 +892,6 @@
</object>
</object>
<object class="IBPartialClassDescription">
- <string key="className">BookmarkBarView</string>
- <string key="superclassName">BackgroundGradientView</string>
- <object class="NSMutableDictionary" key="outlets">
- <string key="NS.key.0">barContextualMenu_</string>
- <string key="NS.object.0">NSMenu</string>
- </object>
- <object class="IBClassDescriptionSource" key="sourceIdentifier">
- <string key="majorKey">IBProjectSource</string>
- <string key="minorKey">browser/cocoa/bookmark_bar_view.h</string>
- </object>
- </object>
- <object class="IBPartialClassDescription">
<string key="className">NSObject</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
diff --git a/chrome/browser/cocoa/bookmark_bar_controller.h b/chrome/browser/cocoa/bookmark_bar_controller.h
index 40ea772..c035fc2 100644
--- a/chrome/browser/cocoa/bookmark_bar_controller.h
+++ b/chrome/browser/cocoa/bookmark_bar_controller.h
@@ -6,6 +6,7 @@
#define CHROME_BROWSER_COCOA_BOOKMARK_BAR_CONTROLLER_H_
#import <Cocoa/Cocoa.h>
+#include <map>
#include "base/scoped_nsobject.h"
#include "base/scoped_ptr.h"
@@ -42,6 +43,13 @@ class PrefService;
BOOL contentViewHasOffset_;
BOOL barShouldBeShown_;
+ // BookmarkNodes have a 64bit id. NSMenuItems have a 32bit tag used
+ // to represent the bookmark node they refer to. This map provides
+ // a mapping from one to the other, so we can properly identify the
+ // node from the item. When adding items in, we start with seedId_.
+ int32 seedId_;
+ std::map<int32,int64> menuTagMap_;
+
// Our bookmark buttons, ordered from L-->R.
scoped_nsobject<NSMutableArray> buttons_;
@@ -60,6 +68,8 @@ class PrefService;
// Delegate which can open URLs for us.
id<BookmarkURLOpener> delegate_; // weak
+ IBOutlet NSView* buttonView_;
+ IBOutlet NSButton* offTheSideButton_;
IBOutlet NSMenu* buttonContextMenu_;
}
@@ -88,6 +98,8 @@ class PrefService;
// Actions for manipulating bookmarks.
// From a button, ...
- (IBAction)openBookmark:(id)sender;
+- (IBAction)openFolderMenuFromButton:(id)sender;
+- (IBAction)openOffTheSideMenuFromButton:(id)sender;
// From a context menu over the button, ...
- (IBAction)openBookmarkInNewForegroundTab:(id)sender;
- (IBAction)openBookmarkInNewWindow:(id)sender;
@@ -100,7 +112,6 @@ class PrefService;
- (IBAction)addPage:(id)sender;
- (IBAction)addOrRenameFolder:(id)sender;
-
@end
// Redirects from BookmarkBarBridge, the C++ object which glues us to
@@ -125,13 +136,19 @@ class PrefService;
// These APIs should only be used by unit tests (or used internally).
-@interface BookmarkBarController(TestingAPI)
+@interface BookmarkBarController(InternalOrTestingAPI)
// Set the delegate for a unit test.
- (void)setDelegate:(id<BookmarkURLOpener>)delegate;
- (void)clearBookmarkBar;
+- (NSView*)buttonView;
- (NSArray*)buttons;
- (NSRect)frameForBookmarkButtonFromCell:(NSCell*)cell xOffset:(int*)xOffset;
- (void)checkForBookmarkButtonGrowth:(NSButton*)button;
+- (void)frameDidChange;
+- (BOOL)offTheSideButtonIsEnabled;
+- (NSMenu *)menuForFolderNode:(const BookmarkNode*)node;
+- (int64)nodeIdFromMenuTag:(int32)tag;
+- (int32)menuTagFromNodeId:(int64)menuid;
@end
#endif // CHROME_BROWSER_COCOA_BOOKMARK_BAR_CONTROLLER_H_
diff --git a/chrome/browser/cocoa/bookmark_bar_controller.mm b/chrome/browser/cocoa/bookmark_bar_controller.mm
index fd2e0fe..d32ecbf 100644
--- a/chrome/browser/cocoa/bookmark_bar_controller.mm
+++ b/chrome/browser/cocoa/bookmark_bar_controller.mm
@@ -10,10 +10,11 @@
#include "chrome/browser/browser_list.h"
#import "chrome/browser/cocoa/bookmark_bar_bridge.h"
#import "chrome/browser/cocoa/bookmark_bar_controller.h"
-#import "chrome/browser/cocoa/bookmark_bar_view.h"
#import "chrome/browser/cocoa/bookmark_button_cell.h"
#import "chrome/browser/cocoa/bookmark_editor_controller.h"
#import "chrome/browser/cocoa/bookmark_name_folder_controller.h"
+#import "chrome/browser/cocoa/bookmark_menu_cocoa_controller.h"
+#include "chrome/browser/cocoa/nsimage_cache.h"
#include "chrome/browser/profile.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
@@ -22,6 +23,10 @@
@interface BookmarkBarController(Private)
- (void)applyContentAreaOffset:(BOOL)apply immediately:(BOOL)immediately;
- (void)showBookmarkBar:(BOOL)enable immediately:(BOOL)immediately;
+- (void)addNode:(const BookmarkNode*)child toMenu:(NSMenu*)menu;
+- (void)addFolderNode:(const BookmarkNode*)node toMenu:(NSMenu*)menu;
+- (void)tagEmptyMenu:(NSMenu*)menu;
+- (void)clearMenuTagMap;
@end
namespace {
@@ -62,6 +67,11 @@ const CGFloat kBookmarkHorizontalPadding = 1.0;
return self;
}
+- (void)dealloc {
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+ [super dealloc];
+}
+
- (void)awakeFromNib {
// We default to NOT open, which means height=0.
DCHECK([[self view] isHidden]); // Hidden so it's OK to change.
@@ -81,6 +91,40 @@ const CGFloat kBookmarkHorizontalPadding = 1.0;
// Don't pass ourself along (as 'self') until our init is completely
// done. Thus, this call is (almost) last.
bridge_.reset(new BookmarkBarBridge(self, bookmarkModel_));
+
+ // When resized we may need to add new buttons, or remove them (if
+ // no longer visible), or add/remove the "off the side" menu.
+ [[self view] setPostsFrameChangedNotifications:YES];
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector(frameDidChange)
+ name:NSViewFrameDidChangeNotification
+ object:[self view]];
+}
+
+// Check if we should enable the off-the-side button.
+// TODO(jrg): when we are smarter about creating buttons (e.g. don't
+// bother creating buttons which aren't visible), we'll have to be
+// smarter here too.
+- (void)checkEnableOffTheSideButton {
+ NSButton* button = [buttons_ lastObject];
+ if ((!button) ||
+ (NSMaxX([button frame]) <=
+ NSMaxX([[button superview] frame]))) {
+ [offTheSideButton_ setEnabled:NO];
+ } else {
+ [offTheSideButton_ setEnabled:YES];
+ }
+}
+
+- (BOOL)offTheSideButtonIsEnabled {
+ return [offTheSideButton_ isEnabled];
+}
+
+// Called when our controlled frame has changed size.
+// TODO(jrg): be smarter (e.g. add/remove buttons as appropriate).
+- (void)frameDidChange {
+ [self checkEnableOffTheSideButton];
}
// Show or hide the bar based on the value of |show|. Handles
@@ -218,6 +262,120 @@ const CGFloat kBookmarkHorizontalPadding = 1.0;
[delegate_ openBookmarkURL:node->GetURL() disposition:CURRENT_TAB];
}
+// Given a NSMenuItem tag, return the appropriate bookmark node id.
+- (int64)nodeIdFromMenuTag:(int32)tag {
+ return menuTagMap_[tag];
+}
+
+// Create and return a new tag for the given node id.
+- (int32)menuTagFromNodeId:(int64)menuid {
+ int tag = seedId_++;
+ menuTagMap_[tag] = menuid;
+ return tag;
+}
+
+- (void)clearMenuTagMap {
+ seedId_ = 0;
+ menuTagMap_.clear();
+}
+
+// Recursively add the given bookmark node and all its children to
+// menu, one menu item per node.
+- (void)addNode:(const BookmarkNode*)child toMenu:(NSMenu*)menu {
+ NSString* title = [BookmarkMenuCocoaController menuTitleForNode:child];
+ NSMenuItem* item = [[[NSMenuItem alloc] initWithTitle:title
+ action:nil
+ keyEquivalent:@""] autorelease];
+ [menu addItem:item];
+ if (child->is_folder()) {
+ NSMenu* submenu = [[[NSMenu alloc] initWithTitle:title] autorelease];
+ [menu setSubmenu:submenu forItem:item];
+ if (child->GetChildCount()) {
+ [self addFolderNode:child toMenu:submenu]; // potentially recursive
+ } else {
+ [self tagEmptyMenu:submenu];
+ }
+ } else {
+ [item setTarget:self];
+ [item setAction:@selector(openBookmarkMenuItem:)];
+ [item setTag:[self menuTagFromNodeId:child->id()]];
+ // Add a tooltip
+ std::string url_string = child->GetURL().possibly_invalid_spec();
+ NSString* tooltip = [NSString stringWithFormat:@"%@\n%s",
+ base::SysWideToNSString(child->GetTitle()),
+ url_string.c_str()];
+ [item setToolTip:tooltip];
+
+ }
+}
+
+// Empty menus are odd; if empty, add something to look at.
+// Matches windows behavior.
+// TODO(jrg): localize.
+- (void)tagEmptyMenu:(NSMenu*)menu {
+ [menu addItem:[[[NSMenuItem alloc] initWithTitle:@"(empty)"
+ action:NULL
+ keyEquivalent:@""] autorelease]];
+}
+
+// Add the children of the given bookmark node (and their children...)
+// to menu, one menu item per node.
+- (void)addFolderNode:(const BookmarkNode*)node toMenu:(NSMenu*)menu {
+ for (int i = 0; i < node->GetChildCount(); i++) {
+ const BookmarkNode* child = node->GetChild(i);
+ [self addNode:child toMenu:menu];
+ }
+}
+
+// Return an autoreleased NSMenu that represents the given bookmark
+// folder node.
+- (NSMenu *)menuForFolderNode:(const BookmarkNode*)node {
+ if (!node->is_folder())
+ return nil;
+ NSString* title = base::SysWideToNSString(node->GetTitle());
+ NSMenu* menu = [[[NSMenu alloc] initWithTitle:title] autorelease];
+ [self addFolderNode:node toMenu:menu];
+
+ if (![menu numberOfItems]) {
+ [self tagEmptyMenu:menu];
+ }
+ return menu;
+}
+
+// Called from a Folder bookmark button.
+- (IBAction)openFolderMenuFromButton:(id)sender {
+ NSMenu* menu = [self menuForFolderNode:[self nodeFromButton:sender]];
+ if (menu) {
+ [NSMenu popUpContextMenu:menu
+ withEvent:[NSApp currentEvent]
+ forView:sender];
+ }
+}
+
+// TODO(jrg): cache the menu so we don't need to build it every time.
+// TODO(jrg): if we get smarter such that we don't even bother
+// creating buttons which aren't visible, we'll need to be smarter
+// here.
+- (IBAction)openOffTheSideMenuFromButton:(id)sender {
+ scoped_nsobject<NSMenu> menu([[NSMenu alloc] initWithTitle:@""]);
+ for (NSButton* each_button in buttons_.get()) {
+ if (NSMaxX([each_button frame]) >
+ NSMaxX([[each_button superview] frame])) {
+ [self addNode:[self nodeFromButton:each_button] toMenu:menu.get()];
+ }
+ }
+
+ // TODO(jrg): once we disable the button when the menu should be
+ // empty, remove this 'helper'.
+ if (![menu numberOfItems]) {
+ [self tagEmptyMenu:menu];
+ }
+
+ [NSMenu popUpContextMenu:menu
+ withEvent:[NSApp currentEvent]
+ forView:sender];
+}
+
// As a convention we set the menu's delegate to be the button's cell
// so we can easily obtain bookmark info. Convention applied in
// -[BookmarkButtonCell menu].
@@ -289,10 +447,15 @@ const CGFloat kBookmarkHorizontalPadding = 1.0;
[self openBookmarkNodesRecursive:node];
}
+// May be called from the bar or from a folder button.
+// If called from a button, that button becomes the parent.
- (IBAction)addPage:(id)sender {
+ const BookmarkNode* parent = [self nodeFromMenuItem:sender];
+ if (!parent)
+ parent = bookmarkModel_->GetBookmarkBarNode();
BookmarkEditor::Show([[[self view] window] contentView],
profile_,
- bookmarkModel_->GetBookmarkBarNode(),
+ parent,
nil,
BookmarkEditor::SHOW_TREE,
nil);
@@ -314,10 +477,16 @@ const CGFloat kBookmarkHorizontalPadding = 1.0;
// ends.
}
-// Delete all bookmarks from the bookmark bar.
+- (NSView*)buttonView {
+ return buttonView_;
+}
+
+// Delete all bookmarks from the bookmark bar, and reset knowledge of
+// bookmarks.
- (void)clearBookmarkBar {
[buttons_ makeObjectsPerformSelector:@selector(removeFromSuperview)];
[buttons_ removeAllObjects];
+ [self clearMenuTagMap];
}
// Return an autoreleased NSCell suitable for a bookmark button.
@@ -329,16 +498,19 @@ const CGFloat kBookmarkHorizontalPadding = 1.0;
DCHECK(cell);
[cell setRepresentedObject:[NSValue valueWithPointer:node]];
- // The favicon may be NULL if we haven't loaded it yet. Bookmarks
- // (and their icons) are loaded on the IO thread to speed launch.
- const SkBitmap& favicon = bookmarkModel_->GetFavIcon(node);
- if (!favicon.isNull()) {
- NSImage* image = gfx::SkBitmapToNSImage(favicon);
- if (image) {
- [cell setImage:image];
- [cell setImagePosition:NSImageLeft];
+ NSImage* image = NULL;
+ if (node->is_folder()) {
+ image = nsimage_cache::ImageNamed(@"bookmark_bar_folder.png");
+ } else {
+ const SkBitmap& favicon = bookmarkModel_->GetFavIcon(node);
+ if (!favicon.isNull()) {
+ image = gfx::SkBitmapToNSImage(favicon);
}
}
+ if (image) {
+ [cell setImage:image];
+ [cell setImagePosition:NSImageLeft];
+ }
[cell setTitle:title];
[cell setMenu:buttonContextMenu_];
return cell;
@@ -397,6 +569,12 @@ const CGFloat kBookmarkHorizontalPadding = 1.0;
}
}
+- (IBAction)openBookmarkMenuItem:(id)sender {
+ int64 tag = [self nodeIdFromMenuTag:[sender tag]];
+ const BookmarkNode* node = bookmarkModel_->GetNodeByID(tag);
+ [delegate_ openBookmarkURL:node->GetURL() disposition:CURRENT_TAB];
+}
+
// Add all items from the given model to our bookmark bar.
// TODO(jrg): lots of things!
// - bookmark folders (e.g. menu from the button)
@@ -427,9 +605,8 @@ const CGFloat kBookmarkHorizontalPadding = 1.0;
[button setCell:cell];
if (child->is_folder()) {
- // For now just disable the button if it's a folder.
- // TODO(jrg): recurse.
- [button setEnabled:NO];
+ [button setTarget:self];
+ [button setAction:@selector(openFolderMenuFromButton:)];
} else {
// Make the button do something
[button setTarget:self];
@@ -442,7 +619,7 @@ const CGFloat kBookmarkHorizontalPadding = 1.0;
[button setToolTip:tooltip];
}
// Finally, add it to the bookmark bar.
- [[self view] addSubview:button];
+ [buttonView_ addSubview:button];
}
}
@@ -456,6 +633,7 @@ const CGFloat kBookmarkHorizontalPadding = 1.0;
const BookmarkNode* node = model->GetBookmarkBarNode();
[self clearBookmarkBar];
[self addNodesToBar:node];
+ [self checkEnableOffTheSideButton];
}
- (void)beingDeleted:(BookmarkModel*)model {
diff --git a/chrome/browser/cocoa/bookmark_bar_controller_unittest.mm b/chrome/browser/cocoa/bookmark_bar_controller_unittest.mm
index 095e3bd..2f4b9f6 100644
--- a/chrome/browser/cocoa/bookmark_bar_controller_unittest.mm
+++ b/chrome/browser/cocoa/bookmark_bar_controller_unittest.mm
@@ -54,6 +54,24 @@
@end
+// Remember the number of times we've gotten a frameDidChange notification.
+@interface BookmarkBarControllerTogglePong : BookmarkBarController {
+@private
+ int toggles_;
+}
+@property (readonly) int toggles;
+@end
+
+@implementation BookmarkBarControllerTogglePong
+
+@synthesize toggles = toggles_;
+
+- (void)frameDidChange {
+ toggles_++;
+}
+
+@end
+
namespace {
@@ -78,16 +96,8 @@ class BookmarkBarControllerTest : public testing::Test {
webContentView:content_area_.get()
infoBarsView:infobar_view_.get()
delegate:nil]);
- [bar_ view]; // force loading of the nib
- // Awkwardness to look like we've been installed.
- [parent_view_ addSubview:[bar_ view]];
- NSRect frame = [[[bar_ view] superview] frame];
- frame.origin.y = 100;
- [[[bar_ view] superview] setFrame:frame];
-
- // make sure it's open so certain things aren't no-ops
- [bar_ toggleBookmarkBar];
+ InstallAndToggleBar(bar_.get());
// Create a menu/item to act like a sender
menu_.reset([[NSMenu alloc] initWithTitle:@"I_dont_care"]);
@@ -100,6 +110,20 @@ class BookmarkBarControllerTest : public testing::Test {
[menu_ setDelegate:cell_.get()];
}
+ void InstallAndToggleBar(BookmarkBarController* bar) {
+ // Force loading of the nib.
+ [bar view];
+ // Awkwardness to look like we've been installed.
+ [parent_view_ addSubview:[bar view]];
+ NSRect frame = [[[bar view] superview] frame];
+ frame.origin.y = 100;
+ [[[bar view] superview] setFrame:frame];
+
+ // make sure it's open so certain things aren't no-ops
+ [bar toggleBookmarkBar];
+ }
+
+
// Return a menu item that points to the right URL.
NSMenuItem* ItemForBookmarkBarMenu(GURL& gurl) {
node_.reset(new BookmarkNode(gurl));
@@ -158,6 +182,112 @@ TEST_F(BookmarkBarControllerTest, ShowHide) {
EXPECT_EQ([[bar_ view] frame].size.height, 0);
}
+// Make sure we're watching for frame change notifications.
+TEST_F(BookmarkBarControllerTest, FrameChangeNotification) {
+ scoped_nsobject<BookmarkBarControllerTogglePong> bar;
+ bar.reset(
+ [[BookmarkBarControllerTogglePong alloc]
+ initWithProfile:helper_.profile()
+ parentView:parent_view_.get()
+ webContentView:content_area_.get()
+ infoBarsView:infobar_view_.get()
+ delegate:nil]);
+ InstallAndToggleBar(bar.get());
+
+ EXPECT_GT([bar toggles], 0);
+
+ // Hard to force toggles -- simple whacking the frame is inadequate.
+ // TODO(jrg): find a way to set frame, force a toggle, and verify it.
+}
+
+// Confirm off the side button only enabled when reasonable.
+TEST_F(BookmarkBarControllerTest, OffTheSideButtonEnable) {
+ BookmarkModel* model = helper_.profile()->GetBookmarkModel();
+
+ [bar_ loaded:model];
+ EXPECT_FALSE([bar_ offTheSideButtonIsEnabled]);
+
+ for (int i = 0; i < 2; i++) {
+ model->SetURLStarred(GURL("http://www.foo.com"), L"small", true);
+ EXPECT_FALSE([bar_ offTheSideButtonIsEnabled]);
+ }
+
+ for (int i = 0; i < 20; i++) {
+ const BookmarkNode* parent = model->GetBookmarkBarNode();
+ model->AddURL(parent, parent->GetChildCount(),
+ L"super duper wide title",
+ GURL("http://superfriends.hall-of-justice.edu"));
+ }
+ EXPECT_TRUE([bar_ offTheSideButtonIsEnabled]);
+}
+
+TEST_F(BookmarkBarControllerTest, TagMap) {
+ int64 ids[] = { 1, 3, 4, 40, 400, 4000, 800000000, 2, 123456789 };
+ std::vector<int32> tags;
+
+ // Generate some tags
+ for (unsigned int i = 0; i < arraysize(ids); i++) {
+ tags.push_back([bar_ menuTagFromNodeId:ids[i]]);
+ }
+
+ // Confirm reverse mapping.
+ for (unsigned int i = 0; i < arraysize(ids); i++) {
+ EXPECT_EQ(ids[i], [bar_ nodeIdFromMenuTag:tags[i]]);
+ }
+
+ // Confirm uniqueness.
+ std::sort(tags.begin(), tags.end());
+ for (unsigned int i=0; i<(tags.size()-1); i++) {
+ EXPECT_NE(tags[i], tags[i+1]);
+ }
+}
+
+TEST_F(BookmarkBarControllerTest, MenuForFolderNode) {
+ BookmarkModel* model = helper_.profile()->GetBookmarkModel();
+
+ // First make sure something (e.g. "(empty)" string) is always present.
+ NSMenu* menu = [bar_ menuForFolderNode:model->GetBookmarkBarNode()];
+ EXPECT_GT([menu numberOfItems], 0);
+
+ // Test two bookmarks.
+ GURL gurl("http://www.foo.com");
+ model->SetURLStarred(gurl, L"small", true);
+ model->SetURLStarred(GURL("http://www.cnn.com"), L"bigger title", true);
+ menu = [bar_ menuForFolderNode:model->GetBookmarkBarNode()];
+ EXPECT_EQ([menu numberOfItems], 2);
+ NSMenuItem *item = [menu itemWithTitle:@"bigger title"];
+ EXPECT_TRUE(item);
+ item = [menu itemWithTitle:@"small"];
+ EXPECT_TRUE(item);
+ if (item) {
+ int64 tag = [bar_ nodeIdFromMenuTag:[item tag]];
+ const BookmarkNode* node = model->GetNodeByID(tag);
+ EXPECT_TRUE(node);
+ EXPECT_EQ(gurl, node->GetURL());
+ }
+
+ // Test with an actual folder as well
+ const BookmarkNode* parent = model->GetBookmarkBarNode();
+ const BookmarkNode* folder = model->AddGroup(parent,
+ parent->GetChildCount(),
+ L"group");
+ model->AddURL(folder, folder->GetChildCount(),
+ L"f1", GURL("http://framma-lamma.com"));
+ model->AddURL(folder, folder->GetChildCount(),
+ L"f2", GURL("http://framma-lamma-ding-dong.com"));
+ menu = [bar_ menuForFolderNode:model->GetBookmarkBarNode()];
+ EXPECT_EQ([menu numberOfItems], 3);
+
+ item = [menu itemWithTitle:@"group"];
+ EXPECT_TRUE(item);
+ EXPECT_TRUE([item hasSubmenu]);
+ NSMenu *submenu = [item submenu];
+ EXPECT_TRUE(submenu);
+ EXPECT_EQ(2, [submenu numberOfItems]);
+ EXPECT_TRUE([submenu itemWithTitle:@"f1"]);
+ EXPECT_TRUE([submenu itemWithTitle:@"f2"]);
+}
+
// Confirm openBookmark: forwards the request to the controller's delegate
TEST_F(BookmarkBarControllerTest, OpenBookmark) {
GURL gurl("http://walla.walla.ding.dong.com");
@@ -209,47 +339,47 @@ TEST_F(BookmarkBarControllerTest, OpenBookmarkFromMenus) {
TEST_F(BookmarkBarControllerTest, TestAddRemoveAndClear) {
BookmarkModel* model = helper_.profile()->GetBookmarkModel();
-
+ NSView* buttonView = [bar_ buttonView];
EXPECT_EQ(0U, [[bar_ buttons] count]);
- unsigned int initial_subview_count = [[[bar_ view] subviews] count];
+ unsigned int initial_subview_count = [[buttonView subviews] count];
// Make sure a redundant call doesn't choke
[bar_ clearBookmarkBar];
EXPECT_EQ(0U, [[bar_ buttons] count]);
- EXPECT_EQ(initial_subview_count, [[[bar_ view] subviews] count]);
+ EXPECT_EQ(initial_subview_count, [[buttonView subviews] count]);
GURL gurl1("http://superfriends.hall-of-justice.edu");
std::wstring title1(L"Protectors of the Universe");
model->SetURLStarred(gurl1, title1, true);
EXPECT_EQ(1U, [[bar_ buttons] count]);
- EXPECT_EQ(1+initial_subview_count, [[[bar_ view] subviews] count]);
+ EXPECT_EQ(1+initial_subview_count, [[buttonView subviews] count]);
GURL gurl2("http://legion-of-doom.gov");
std::wstring title2(L"Bad doodz");
model->SetURLStarred(gurl2, title2, true);
EXPECT_EQ(2U, [[bar_ buttons] count]);
- EXPECT_EQ(2+initial_subview_count, [[[bar_ view] subviews] count]);
+ EXPECT_EQ(2+initial_subview_count, [[buttonView subviews] count]);
for (int i = 0; i < 3; i++) {
// is_starred=false --> remove the bookmark
model->SetURLStarred(gurl2, title2, false);
EXPECT_EQ(1U, [[bar_ buttons] count]);
- EXPECT_EQ(1+initial_subview_count, [[[bar_ view] subviews] count]);
+ EXPECT_EQ(1+initial_subview_count, [[buttonView subviews] count]);
// and bring it back
model->SetURLStarred(gurl2, title2, true);
EXPECT_EQ(2U, [[bar_ buttons] count]);
- EXPECT_EQ(2+initial_subview_count, [[[bar_ view] subviews] count]);
+ EXPECT_EQ(2+initial_subview_count, [[buttonView subviews] count]);
}
[bar_ clearBookmarkBar];
EXPECT_EQ(0U, [[bar_ buttons] count]);
- EXPECT_EQ(initial_subview_count, [[[bar_ view] subviews] count]);
+ EXPECT_EQ(initial_subview_count, [[buttonView subviews] count]);
// Explicit test of loaded: since this is a convenient spot
[bar_ loaded:model];
EXPECT_EQ(2U, [[bar_ buttons] count]);
- EXPECT_EQ(2+initial_subview_count, [[[bar_ view] subviews] count]);
+ EXPECT_EQ(2+initial_subview_count, [[buttonView subviews] count]);
}
// Make sure that each button we add marches to the right and does not
diff --git a/chrome/browser/cocoa/bookmark_bar_view.h b/chrome/browser/cocoa/bookmark_bar_view.h
deleted file mode 100644
index c92cc7f..0000000
--- a/chrome/browser/cocoa/bookmark_bar_view.h
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_COCOA_BOOKMARK_BAR_VIEW_H_
-#define CHROME_BROWSER_COCOA_BOOKMARK_BAR_VIEW_H_
-
-#import <Cocoa/Cocoa.h>
-#import "chrome/browser/cocoa/background_gradient_view.h"
-
-// A view that handles any special rendering of the bookmark bar. At
-// this time it only draws a gradient like the toolbar. In the future
-// I expect changes for new features (themes, extensions, etc).
-
-@interface BookmarkBarView : BackgroundGradientView {
- @private
- IBOutlet NSMenu* barContextualMenu_;
-}
-@end
-
-@interface BookmarkBarView(TestingAPI)
-- (void)setContextMenu:(NSMenu*)menu;
-@end
-
-#endif // CHROME_BROWSER_COCOA_BOOKMARK_BAR_VIEW_H_
diff --git a/chrome/browser/cocoa/bookmark_bar_view.mm b/chrome/browser/cocoa/bookmark_bar_view.mm
deleted file mode 100644
index 9bdab26..0000000
--- a/chrome/browser/cocoa/bookmark_bar_view.mm
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/cocoa/bookmark_bar_view.h"
-
-@implementation BookmarkBarView
-
-// Only hit in a unit test.
-- (void)setContextMenu:(NSMenu*)menu {
- barContextualMenu_ = menu;
-}
-
-// Unlike controls, generic views don't have a well-defined context
-// menu (e.g. responds to the "menu" selector). So we add our own.
-- (NSMenu *)menuForEvent:(NSEvent *)event {
- if ([event type] == NSRightMouseDown)
- return barContextualMenu_;
- return nil;
-}
-
-@end
diff --git a/chrome/browser/cocoa/bookmark_bar_view_unittest.mm b/chrome/browser/cocoa/bookmark_bar_view_unittest.mm
deleted file mode 100644
index a1cb121..0000000
--- a/chrome/browser/cocoa/bookmark_bar_view_unittest.mm
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import <Cocoa/Cocoa.h>
-
-#import "chrome/browser/cocoa/bookmark_bar_view.h"
-#import "chrome/browser/cocoa/cocoa_test_helper.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-class BookmarkBarViewTest : public testing::Test {
- CocoaTestHelper cocoa_helper_; // Inits Cocoa, creates window, etc...
-};
-
-// Make sure we only get a menu from a right-click. Not left-click or keyDown.
-TEST_F(BookmarkBarViewTest, TestMenu) {
- scoped_nsobject<BookmarkBarView> view([[BookmarkBarView alloc]
- initWithFrame:NSMakeRect(0,0,10,10)]);
- EXPECT_TRUE(view.get());
-
- // Not loaded from a nib so we must set it explicitly
- scoped_nsobject<NSMenu> menu([[NSMenu alloc] initWithTitle:@"spork"]);
- [view setContextMenu:menu.get()];
-
- EXPECT_TRUE([view menuForEvent:[NSEvent mouseEventWithType:NSRightMouseDown
- location:NSMakePoint(0,0)
- modifierFlags:0
- timestamp:0
- windowNumber:0
- context:nil
- eventNumber:0
- clickCount:0
- pressure:0.0]]);
- EXPECT_FALSE([view menuForEvent:[NSEvent mouseEventWithType:NSLeftMouseDown
- location:NSMakePoint(0,0)
- modifierFlags:0
- timestamp:0
- windowNumber:0
- context:nil
- eventNumber:0
- clickCount:0
- pressure:0.0]]);
- EXPECT_FALSE([view menuForEvent:[NSEvent keyEventWithType:NSKeyDown
- location:NSMakePoint(0,0)
- modifierFlags:0
- timestamp:0
- windowNumber:0
- context:nil
- characters:@"x"
- charactersIgnoringModifiers:@"x"
- isARepeat:NO
- keyCode:7]]);
-
- [view setContextMenu:nil];
-}
-
-
-
diff --git a/chrome/browser/cocoa/bookmark_menu_bridge.mm b/chrome/browser/cocoa/bookmark_menu_bridge.mm
index f4d4c7d..d37ea02 100644
--- a/chrome/browser/cocoa/bookmark_menu_bridge.mm
+++ b/chrome/browser/cocoa/bookmark_menu_bridge.mm
@@ -170,31 +170,10 @@ void BookmarkMenuBridge::ClearBookmarkMenu(NSMenu* menu) {
}
}
-namespace {
-
-// Menus more than this many chars long will get trimmed
-const NSUInteger kMaximumMenuWidthInChars = 65;
-
-// When trimming, use this many chars from each side
-const NSUInteger kMenuTrimSizeInChars = 30;
-
-}
-
void BookmarkMenuBridge::AddNodeToMenu(const BookmarkNode* node, NSMenu* menu) {
for (int i = 0; i < node->GetChildCount(); i++) {
const BookmarkNode* child = node->GetChild(i);
- NSString* full_title = base::SysWideToNSString(child->GetTitle());
- NSString* title = full_title;
- if ([title length] > kMaximumMenuWidthInChars) {
- // TODO(jrg): add a better heuristic? I'd really like to trim this
- // by pixels, not by chars (font is not fixed width).
- // For Safari, it appears that menu names >60 chars get split up to
- // 30char + "..." + 30char.
- title = [NSString stringWithFormat:@"%@…%@",
- [title substringToIndex:kMenuTrimSizeInChars],
- [title substringFromIndex:([title length] -
- kMenuTrimSizeInChars)]];
- }
+ NSString* title = [BookmarkMenuCocoaController menuTitleForNode:child];
NSMenuItem* item = [[[NSMenuItem alloc] initWithTitle:title
action:nil
keyEquivalent:@""] autorelease];
@@ -209,7 +188,8 @@ void BookmarkMenuBridge::AddNodeToMenu(const BookmarkNode* node, NSMenu* menu) {
[item setTag:child->id()];
// Add a tooltip
std::string url_string = child->GetURL().possibly_invalid_spec();
- NSString* tooltip = [NSString stringWithFormat:@"%@\n%s", full_title,
+ NSString* tooltip = [NSString stringWithFormat:@"%@\n%s",
+ base::SysWideToNSString(child->GetTitle()),
url_string.c_str()];
[item setToolTip:tooltip];
diff --git a/chrome/browser/cocoa/bookmark_menu_cocoa_controller.h b/chrome/browser/cocoa/bookmark_menu_cocoa_controller.h
index b1e9bde..228773e 100644
--- a/chrome/browser/cocoa/bookmark_menu_cocoa_controller.h
+++ b/chrome/browser/cocoa/bookmark_menu_cocoa_controller.h
@@ -19,6 +19,10 @@ class BookmarkMenuBridge;
BookmarkMenuBridge* bridge_; // weak; owns me
}
+// Return an autoreleased string to be used as a menu title for the
+// given bookmark node.
++ (NSString*)menuTitleForNode:(const BookmarkNode*)node;
+
- (id)initWithBridge:(BookmarkMenuBridge *)bridge;
// Called by any Bookmark menu item.
diff --git a/chrome/browser/cocoa/bookmark_menu_cocoa_controller.mm b/chrome/browser/cocoa/bookmark_menu_cocoa_controller.mm
index a62103f..46f17bf 100644
--- a/chrome/browser/cocoa/bookmark_menu_cocoa_controller.mm
+++ b/chrome/browser/cocoa/bookmark_menu_cocoa_controller.mm
@@ -2,17 +2,37 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#import "chrome/browser/cocoa/bookmark_menu_cocoa_controller.h"
-
+#include "app/gfx/text_elider.h"
+#include "base/sys_string_conversions.h"
#include "chrome/browser/bookmarks/bookmark_model.h"
#include "chrome/browser/browser.h"
#import "chrome/browser/cocoa/bookmark_menu_bridge.h"
+#import "chrome/browser/cocoa/bookmark_menu_cocoa_controller.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/tab_contents/tab_contents.h"
#include "webkit/glue/window_open_disposition.h" // CURRENT_TAB
+namespace {
+
+// Menus more than this many pixels wide will get trimmed
+// TODO(jrg): ask UI dudes what a good value is.
+const NSUInteger kMaximumMenuPixelsWide = 300;
+
+}
+
@implementation BookmarkMenuCocoaController
++ (NSString*)menuTitleForNode:(const BookmarkNode*)node {
+ NSFont* nsfont = [NSFont menuBarFontOfSize:0]; // 0 means "default"
+ gfx::Font font = gfx::Font::CreateFont(base::SysNSStringToWide([nsfont
+ fontName]),
+ (int)[nsfont pointSize]);
+ std::wstring title = gfx::ElideText(node->GetTitle(),
+ font,
+ kMaximumMenuPixelsWide);
+ return base::SysWideToNSString(title);
+}
+
- (id)initWithBridge:(BookmarkMenuBridge *)bridge {
if ((self = [super init])) {
bridge_ = bridge;
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index c39beda..d23f1f0 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -746,8 +746,6 @@
'browser/cocoa/bookmark_bar_bridge.mm',
'browser/cocoa/bookmark_bar_controller.h',
'browser/cocoa/bookmark_bar_controller.mm',
- 'browser/cocoa/bookmark_bar_view.h',
- 'browser/cocoa/bookmark_bar_view.mm',
'browser/cocoa/bookmark_button_cell.h',
'browser/cocoa/bookmark_button_cell.mm',
'browser/cocoa/bookmark_editor_controller.h',
@@ -2663,6 +2661,8 @@
'app/nibs/TabView.xib',
'app/nibs/Toolbar.xib',
'app/theme/back_Template.pdf',
+ 'app/theme/bookmark_bar_folder.png',
+ 'app/theme/chevron.png', # TODO(jrg): get (and use) a pdf version
'app/theme/close_bar.pdf',
'app/theme/close_bar_h.pdf',
'app/theme/close_bar_p.pdf',
@@ -3699,7 +3699,6 @@
'browser/cocoa/blocked_popup_container_controller_unittest.mm',
'browser/cocoa/bookmark_bar_bridge_unittest.mm',
'browser/cocoa/bookmark_bar_controller_unittest.mm',
- 'browser/cocoa/bookmark_bar_view_unittest.mm',
'browser/cocoa/bookmark_button_cell_unittest.mm',
'browser/cocoa/bookmark_editor_controller_unittest.mm',
'browser/cocoa/bookmark_menu_bridge_unittest.mm',