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