Home | History | Annotate | Download | only in bookmarks
      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 
     19 namespace {
     20 
     21 // Menus more than this many pixels wide will get trimmed
     22 // TODO(jrg): ask UI dudes what a good value is.
     23 const 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