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