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