bookmark_menu_cocoa_controller.mm revision dc0f95d653279beabeb9817299e2902918ba123e
1// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#import "chrome/browser/ui/cocoa/bookmarks/bookmark_menu_cocoa_controller.h"
6
7#include "base/sys_string_conversions.h"
8#include "base/utf_string_conversions.h"
9#include "chrome/app/chrome_command_ids.h"  // IDC_BOOKMARK_MENU
10#import "chrome/browser/app_controller_mac.h"
11#include "chrome/browser/bookmarks/bookmark_model.h"
12#include "chrome/browser/bookmarks/bookmark_utils.h"
13#include "chrome/browser/metrics/user_metrics.h"
14#include "chrome/browser/ui/browser.h"
15#import "chrome/browser/ui/cocoa/bookmarks/bookmark_menu_bridge.h"
16#include "chrome/browser/ui/cocoa/event_utils.h"
17#include "ui/base/text/text_elider.h"
18
19namespace {
20
21// Menus more than this many pixels wide will get trimmed
22// TODO(jrg): ask UI dudes what a good value is.
23const NSUInteger kMaximumMenuPixelsWide = 300;
24
25}
26
27@implementation BookmarkMenuCocoaController
28
29+ (NSString*)menuTitleForNode:(const BookmarkNode*)node {
30  NSFont* nsfont = [NSFont menuBarFontOfSize:0];  // 0 means "default"
31  gfx::Font font(base::SysNSStringToUTF16([nsfont fontName]),
32                 static_cast<int>([nsfont pointSize]));
33  string16 title = ui::ElideText(node->GetTitle(),
34                                 font,
35                                 kMaximumMenuPixelsWide,
36                                 false);
37  return base::SysUTF16ToNSString(title);
38}
39
40- (id)initWithBridge:(BookmarkMenuBridge *)bridge {
41  if ((self = [super init])) {
42    bridge_ = bridge;
43    DCHECK(bridge_);
44    [[self menu] setDelegate:self];
45  }
46  return self;
47}
48
49- (void)dealloc {
50  [[self menu] setDelegate:nil];
51  [super dealloc];
52}
53
54- (NSMenu*)menu {
55  return [[[NSApp mainMenu] itemWithTag:IDC_BOOKMARK_MENU] submenu];
56}
57
58- (BOOL)validateMenuItem:(NSMenuItem*)menuItem {
59  AppController* controller = [NSApp delegate];
60  return [controller keyWindowIsNotModal];
61}
62
63// NSMenu delegate method: called just before menu is displayed.
64- (void)menuNeedsUpdate:(NSMenu*)menu {
65  bridge_->UpdateMenu(menu);
66}
67
68// Return the a BookmarkNode that has the given id (called
69// "identifier" here to avoid conflict with objc's concept of "id").
70- (const BookmarkNode*)nodeForIdentifier:(int)identifier {
71  return bridge_->GetBookmarkModel()->GetNodeByID(identifier);
72}
73
74// Open the URL of the given BookmarkNode in the current tab.
75- (void)openURLForNode:(const BookmarkNode*)node {
76  Browser* browser = Browser::GetTabbedBrowser(bridge_->GetProfile(), true);
77  if (!browser)
78    browser = Browser::Create(bridge_->GetProfile());
79  WindowOpenDisposition disposition =
80      event_utils::WindowOpenDispositionFromNSEvent([NSApp currentEvent]);
81  browser->OpenURL(node->GetURL(), GURL(), disposition,
82                   PageTransition::AUTO_BOOKMARK);
83}
84
85// Open sites under BookmarkNode with the specified disposition.
86- (void)openAll:(NSInteger)tag
87    withDisposition:(WindowOpenDisposition)disposition {
88  int identifier = tag;
89
90  const BookmarkNode* node = [self nodeForIdentifier:identifier];
91  DCHECK(node);
92
93  Browser* browser = Browser::GetTabbedBrowser(bridge_->GetProfile(), true);
94  if (!browser)
95    browser = Browser::Create(bridge_->GetProfile());
96  DCHECK(browser);
97
98  if (!node || !browser)
99    return; // shouldn't be reached
100
101  bookmark_utils::OpenAll(NULL, browser->profile(), browser, node,
102                          disposition);
103
104  const char* metrics_action = NULL;
105  if (disposition == NEW_FOREGROUND_TAB) {
106    metrics_action = "OpenAllBookmarks";
107  } else if (disposition == NEW_WINDOW) {
108    metrics_action = "OpenAllBookmarksNewWindow";
109  } else {
110    metrics_action = "OpenAllBookmarksIncognitoWindow";
111  }
112  UserMetrics::RecordAction(UserMetricsAction(metrics_action),
113                            browser->profile());
114}
115
116- (IBAction)openBookmarkMenuItem:(id)sender {
117  NSInteger tag = [sender tag];
118  int identifier = tag;
119  const BookmarkNode* node = [self nodeForIdentifier:identifier];
120  DCHECK(node);
121  if (!node)
122    return;  // shouldn't be reached
123
124  [self openURLForNode:node];
125}
126
127- (IBAction)openAllBookmarks:(id)sender {
128  [self openAll:[sender tag] withDisposition:NEW_FOREGROUND_TAB];
129}
130
131- (IBAction)openAllBookmarksNewWindow:(id)sender {
132  [self openAll:[sender tag] withDisposition:NEW_WINDOW];
133}
134
135- (IBAction)openAllBookmarksIncognitoWindow:(id)sender {
136  [self openAll:[sender tag] withDisposition:OFF_THE_RECORD];
137}
138
139@end  // BookmarkMenuCocoaController
140
141