Home | History | Annotate | Download | only in bookmarks
      1 // Copyright (c) 2011 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 #include "chrome/browser/bookmarks/bookmark_context_menu_controller.h"
      6 
      7 #include "base/compiler_specific.h"
      8 #include "chrome/app/chrome_command_ids.h"
      9 #include "chrome/browser/bookmarks/bookmark_editor.h"
     10 #include "chrome/browser/bookmarks/bookmark_folder_editor_controller.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/prefs/pref_service.h"
     15 #include "chrome/browser/profiles/profile.h"
     16 #include "chrome/browser/ui/browser.h"
     17 #include "chrome/browser/ui/browser_list.h"
     18 #include "chrome/common/pref_names.h"
     19 #include "content/browser/tab_contents/page_navigator.h"
     20 #include "grit/generated_resources.h"
     21 #include "ui/base/l10n/l10n_util.h"
     22 
     23 BookmarkContextMenuController::BookmarkContextMenuController(
     24     gfx::NativeWindow parent_window,
     25     BookmarkContextMenuControllerDelegate* delegate,
     26     Profile* profile,
     27     PageNavigator* navigator,
     28     const BookmarkNode* parent,
     29     const std::vector<const BookmarkNode*>& selection)
     30     : parent_window_(parent_window),
     31       delegate_(delegate),
     32       profile_(profile),
     33       navigator_(navigator),
     34       parent_(parent),
     35       selection_(selection),
     36       model_(profile->GetBookmarkModel()) {
     37   DCHECK(profile_);
     38   DCHECK(model_->IsLoaded());
     39   menu_model_.reset(new ui::SimpleMenuModel(this));
     40   model_->AddObserver(this);
     41 
     42   BuildMenu();
     43 }
     44 
     45 BookmarkContextMenuController::~BookmarkContextMenuController() {
     46   if (model_)
     47     model_->RemoveObserver(this);
     48 }
     49 
     50 void BookmarkContextMenuController::BuildMenu() {
     51   if (selection_.size() == 1 && selection_[0]->is_url()) {
     52     AddItem(IDC_BOOKMARK_BAR_OPEN_ALL,
     53             IDS_BOOMARK_BAR_OPEN_IN_NEW_TAB);
     54     AddItem(IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW,
     55             IDS_BOOMARK_BAR_OPEN_IN_NEW_WINDOW);
     56     AddItem(IDC_BOOKMARK_BAR_OPEN_ALL_INCOGNITO,
     57             IDS_BOOMARK_BAR_OPEN_INCOGNITO);
     58   } else {
     59     AddItem(IDC_BOOKMARK_BAR_OPEN_ALL, IDS_BOOMARK_BAR_OPEN_ALL);
     60     AddItem(IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW,
     61         IDS_BOOMARK_BAR_OPEN_ALL_NEW_WINDOW);
     62     AddItem(IDC_BOOKMARK_BAR_OPEN_ALL_INCOGNITO,
     63         IDS_BOOMARK_BAR_OPEN_ALL_INCOGNITO);
     64   }
     65 
     66   AddSeparator();
     67   if (selection_.size() == 1 && selection_[0]->is_folder()) {
     68     AddItem(IDC_BOOKMARK_BAR_RENAME_FOLDER, IDS_BOOKMARK_BAR_RENAME_FOLDER);
     69   } else {
     70     AddItem(IDC_BOOKMARK_BAR_EDIT, IDS_BOOKMARK_BAR_EDIT);
     71   }
     72 
     73   AddSeparator();
     74   AddItem(IDC_CUT, IDS_CUT);
     75   AddItem(IDC_COPY, IDS_COPY);
     76   AddItem(IDC_PASTE, IDS_PASTE);
     77 
     78   AddSeparator();
     79   AddItem(IDC_BOOKMARK_BAR_REMOVE, IDS_BOOKMARK_BAR_REMOVE);
     80 
     81   AddSeparator();
     82   AddItem(IDC_BOOKMARK_BAR_ADD_NEW_BOOKMARK, IDS_BOOMARK_BAR_ADD_NEW_BOOKMARK);
     83   AddItem(IDC_BOOKMARK_BAR_NEW_FOLDER, IDS_BOOMARK_BAR_NEW_FOLDER);
     84 
     85   AddSeparator();
     86   AddItem(IDC_BOOKMARK_MANAGER, IDS_BOOKMARK_MANAGER);
     87   AddCheckboxItem(IDC_BOOKMARK_BAR_ALWAYS_SHOW, IDS_BOOMARK_BAR_ALWAYS_SHOW);
     88 }
     89 
     90 void BookmarkContextMenuController::AddItem(int id, int localization_id) {
     91   menu_model_->AddItemWithStringId(id, localization_id);
     92 }
     93 
     94 void BookmarkContextMenuController::AddSeparator() {
     95   menu_model_->AddSeparator();
     96 }
     97 
     98 void BookmarkContextMenuController::AddCheckboxItem(int id,
     99                                                     int localization_id) {
    100   menu_model_->AddCheckItemWithStringId(id, localization_id);
    101 }
    102 
    103 void BookmarkContextMenuController::ExecuteCommand(int id) {
    104   if (delegate_)
    105     delegate_->WillExecuteCommand();
    106 
    107   switch (id) {
    108     case IDC_BOOKMARK_BAR_OPEN_ALL:
    109     case IDC_BOOKMARK_BAR_OPEN_ALL_INCOGNITO:
    110     case IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW: {
    111       WindowOpenDisposition initial_disposition;
    112       if (id == IDC_BOOKMARK_BAR_OPEN_ALL) {
    113         initial_disposition = NEW_FOREGROUND_TAB;
    114         UserMetrics::RecordAction(
    115             UserMetricsAction("BookmarkBar_ContextMenu_OpenAll"),
    116             profile_);
    117       } else if (id == IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW) {
    118         initial_disposition = NEW_WINDOW;
    119         UserMetrics::RecordAction(
    120                 UserMetricsAction("BookmarkBar_ContextMenu_OpenAllInNewWindow"),
    121                 profile_);
    122       } else {
    123         initial_disposition = OFF_THE_RECORD;
    124         UserMetrics::RecordAction(
    125             UserMetricsAction("BookmarkBar_ContextMenu_OpenAllIncognito"),
    126             profile_);
    127       }
    128       bookmark_utils::OpenAll(parent_window_, profile_, navigator_, selection_,
    129                               initial_disposition);
    130       break;
    131     }
    132 
    133     case IDC_BOOKMARK_BAR_RENAME_FOLDER:
    134     case IDC_BOOKMARK_BAR_EDIT:
    135       UserMetrics::RecordAction(
    136           UserMetricsAction("BookmarkBar_ContextMenu_Edit"),
    137           profile_);
    138 
    139       if (selection_.size() != 1) {
    140         NOTREACHED();
    141         break;
    142       }
    143 
    144       if (selection_[0]->is_url()) {
    145         BookmarkEditor::Show(parent_window_, profile_, parent_,
    146                              BookmarkEditor::EditDetails(selection_[0]),
    147                              BookmarkEditor::SHOW_TREE);
    148       } else {
    149         BookmarkFolderEditorController::Show(profile_, parent_window_,
    150             selection_[0], -1,
    151             BookmarkFolderEditorController::EXISTING_BOOKMARK);
    152       }
    153       break;
    154 
    155     case IDC_BOOKMARK_BAR_REMOVE: {
    156       UserMetrics::RecordAction(
    157           UserMetricsAction("BookmarkBar_ContextMenu_Remove"),
    158           profile_);
    159 
    160       for (size_t i = 0; i < selection_.size(); ++i) {
    161         int index = selection_[i]->parent()->GetIndexOf(selection_[i]);
    162         if (index > -1)
    163           model_->Remove(selection_[i]->parent(), index);
    164       }
    165       selection_.clear();
    166       break;
    167     }
    168 
    169     case IDC_BOOKMARK_BAR_ADD_NEW_BOOKMARK: {
    170       UserMetrics::RecordAction(
    171           UserMetricsAction("BookmarkBar_ContextMenu_Add"),
    172           profile_);
    173 
    174       // TODO: this should honor the index from GetParentForNewNodes.
    175       BookmarkEditor::Show(
    176           parent_window_, profile_,
    177           bookmark_utils::GetParentForNewNodes(parent_, selection_, NULL),
    178           BookmarkEditor::EditDetails(), BookmarkEditor::SHOW_TREE);
    179       break;
    180     }
    181 
    182     case IDC_BOOKMARK_BAR_NEW_FOLDER: {
    183       UserMetrics::RecordAction(
    184           UserMetricsAction("BookmarkBar_ContextMenu_NewFolder"),
    185           profile_);
    186       int index;
    187       const BookmarkNode* parent =
    188           bookmark_utils::GetParentForNewNodes(parent_, selection_, &index);
    189       BookmarkFolderEditorController::Show(profile_, parent_window_, parent,
    190           index, BookmarkFolderEditorController::NEW_BOOKMARK);
    191       break;
    192     }
    193 
    194     case IDC_BOOKMARK_BAR_ALWAYS_SHOW:
    195       bookmark_utils::ToggleWhenVisible(profile_);
    196       break;
    197 
    198     case IDC_BOOKMARK_MANAGER:
    199       UserMetrics::RecordAction(UserMetricsAction("ShowBookmarkManager"),
    200                                 profile_);
    201       {
    202         Browser* browser = BrowserList::GetLastActiveWithProfile(profile_);
    203         if (browser)
    204           browser->OpenBookmarkManager();
    205         else
    206           NOTREACHED();
    207       }
    208       break;
    209 
    210     case IDC_CUT:
    211       bookmark_utils::CopyToClipboard(model_, selection_, true);
    212       break;
    213 
    214     case IDC_COPY:
    215       bookmark_utils::CopyToClipboard(model_, selection_, false);
    216       break;
    217 
    218     case IDC_PASTE: {
    219       int index;
    220       const BookmarkNode* paste_target =
    221           bookmark_utils::GetParentForNewNodes(parent_, selection_, &index);
    222       if (!paste_target)
    223         return;
    224 
    225       bookmark_utils::PasteFromClipboard(model_, paste_target, index);
    226       break;
    227     }
    228 
    229     default:
    230       NOTREACHED();
    231   }
    232 
    233   if (delegate_)
    234     delegate_->DidExecuteCommand();
    235 }
    236 
    237 bool BookmarkContextMenuController::IsCommandIdChecked(int command_id) const {
    238   DCHECK(command_id == IDC_BOOKMARK_BAR_ALWAYS_SHOW);
    239   return profile_->GetPrefs()->GetBoolean(prefs::kShowBookmarkBar);
    240 }
    241 
    242 bool BookmarkContextMenuController::IsCommandIdEnabled(int command_id) const {
    243   bool is_root_node =
    244       (selection_.size() == 1 &&
    245        selection_[0]->parent() == model_->root_node());
    246   bool can_edit =
    247       profile_->GetPrefs()->GetBoolean(prefs::kEditBookmarksEnabled);
    248   switch (command_id) {
    249     case IDC_BOOKMARK_BAR_OPEN_INCOGNITO:
    250       return !profile_->IsOffTheRecord() &&
    251              profile_->GetPrefs()->GetBoolean(prefs::kIncognitoEnabled);
    252 
    253     case IDC_BOOKMARK_BAR_OPEN_ALL_INCOGNITO:
    254       return HasURLs() && !profile_->IsOffTheRecord() &&
    255              profile_->GetPrefs()->GetBoolean(prefs::kIncognitoEnabled);
    256 
    257     case IDC_BOOKMARK_BAR_OPEN_ALL:
    258     case IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW:
    259       return HasURLs();
    260 
    261     case IDC_BOOKMARK_BAR_RENAME_FOLDER:
    262     case IDC_BOOKMARK_BAR_EDIT:
    263       return selection_.size() == 1 && !is_root_node && can_edit;
    264 
    265     case IDC_BOOKMARK_BAR_REMOVE:
    266       return !selection_.empty() && !is_root_node && can_edit;
    267 
    268     case IDC_BOOKMARK_BAR_NEW_FOLDER:
    269     case IDC_BOOKMARK_BAR_ADD_NEW_BOOKMARK:
    270       return can_edit && bookmark_utils::GetParentForNewNodes(
    271           parent_, selection_, NULL) != NULL;
    272 
    273     case IDC_BOOKMARK_BAR_ALWAYS_SHOW:
    274       return !profile_->GetPrefs()->IsManagedPreference(
    275           prefs::kEnableBookmarkBar);
    276 
    277     case IDC_COPY:
    278     case IDC_CUT:
    279       return !selection_.empty() && !is_root_node &&
    280              (command_id == IDC_COPY || can_edit);
    281 
    282     case IDC_PASTE:
    283       // Paste to selection from the Bookmark Bar, to parent_ everywhere else
    284       return can_edit &&
    285              ((!selection_.empty() &&
    286                bookmark_utils::CanPasteFromClipboard(selection_[0])) ||
    287               bookmark_utils::CanPasteFromClipboard(parent_));
    288   }
    289   return true;
    290 }
    291 
    292 bool BookmarkContextMenuController::GetAcceleratorForCommandId(
    293     int command_id,
    294     ui::Accelerator* accelerator) {
    295   return false;
    296 }
    297 
    298 void BookmarkContextMenuController::BookmarkModelChanged() {
    299   if (delegate_)
    300     delegate_->CloseMenu();
    301 }
    302 
    303 bool BookmarkContextMenuController::HasURLs() const {
    304   for (size_t i = 0; i < selection_.size(); ++i) {
    305     if (bookmark_utils::NodeHasURLs(selection_[i]))
    306       return true;
    307   }
    308   return false;
    309 }
    310