Elim cr-checkbox
[chromium-blink-merge.git] / chrome / browser / ui / bookmarks / bookmark_context_menu_controller.cc
blobcd4afd227953ccee4cbca0cdede87ad4b2fa5038
1 // Copyright (c) 2012 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.
5 #include "chrome/browser/ui/bookmarks/bookmark_context_menu_controller.h"
7 #include "base/command_line.h"
8 #include "base/compiler_specific.h"
9 #include "base/prefs/pref_service.h"
10 #include "chrome/app/chrome_command_ids.h"
11 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
12 #include "chrome/browser/bookmarks/managed_bookmark_service_factory.h"
13 #include "chrome/browser/prefs/incognito_mode_prefs.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/ui/bookmarks/bookmark_editor.h"
16 #include "chrome/browser/ui/bookmarks/bookmark_utils.h"
17 #include "chrome/browser/ui/browser.h"
18 #include "chrome/browser/ui/chrome_pages.h"
19 #include "chrome/browser/ui/tabs/tab_strip_model.h"
20 #include "chrome/browser/undo/bookmark_undo_service_factory.h"
21 #include "chrome/common/chrome_switches.h"
22 #include "chrome/common/pref_names.h"
23 #include "chrome/grit/generated_resources.h"
24 #include "components/bookmarks/browser/bookmark_client.h"
25 #include "components/bookmarks/browser/bookmark_model.h"
26 #include "components/bookmarks/browser/bookmark_utils.h"
27 #include "components/bookmarks/managed/managed_bookmark_service.h"
28 #include "components/undo/bookmark_undo_service.h"
29 #include "content/public/browser/page_navigator.h"
30 #include "content/public/browser/user_metrics.h"
31 #include "grit/components_strings.h"
32 #include "ui/base/l10n/l10n_util.h"
34 using base::UserMetricsAction;
35 using bookmarks::BookmarkNode;
36 using content::PageNavigator;
38 BookmarkContextMenuController::BookmarkContextMenuController(
39 gfx::NativeWindow parent_window,
40 BookmarkContextMenuControllerDelegate* delegate,
41 Browser* browser,
42 Profile* profile,
43 PageNavigator* navigator,
44 const BookmarkNode* parent,
45 const std::vector<const BookmarkNode*>& selection)
46 : parent_window_(parent_window),
47 delegate_(delegate),
48 browser_(browser),
49 profile_(profile),
50 navigator_(navigator),
51 parent_(parent),
52 selection_(selection),
53 model_(BookmarkModelFactory::GetForProfile(profile)),
54 weak_factory_(this) {
55 DCHECK(profile_);
56 DCHECK(model_->loaded());
57 menu_model_.reset(new ui::SimpleMenuModel(this));
58 model_->AddObserver(this);
60 BuildMenu();
63 BookmarkContextMenuController::~BookmarkContextMenuController() {
64 if (model_)
65 model_->RemoveObserver(this);
68 void BookmarkContextMenuController::BuildMenu() {
69 if (selection_.size() == 1 && selection_[0]->is_url()) {
70 AddItem(IDC_BOOKMARK_BAR_OPEN_ALL,
71 IDS_BOOKMARK_BAR_OPEN_IN_NEW_TAB);
72 AddItem(IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW,
73 IDS_BOOKMARK_BAR_OPEN_IN_NEW_WINDOW);
74 AddItem(IDC_BOOKMARK_BAR_OPEN_ALL_INCOGNITO,
75 IDS_BOOKMARK_BAR_OPEN_INCOGNITO);
76 } else {
77 AddItem(IDC_BOOKMARK_BAR_OPEN_ALL, IDS_BOOKMARK_BAR_OPEN_ALL);
78 AddItem(IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW,
79 IDS_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW);
80 AddItem(IDC_BOOKMARK_BAR_OPEN_ALL_INCOGNITO,
81 IDS_BOOKMARK_BAR_OPEN_ALL_INCOGNITO);
84 AddSeparator();
85 if (selection_.size() == 1 && selection_[0]->is_folder()) {
86 AddItem(IDC_BOOKMARK_BAR_RENAME_FOLDER, IDS_BOOKMARK_BAR_RENAME_FOLDER);
87 } else {
88 AddItem(IDC_BOOKMARK_BAR_EDIT, IDS_BOOKMARK_BAR_EDIT);
91 AddSeparator();
92 AddItem(IDC_CUT, IDS_CUT);
93 AddItem(IDC_COPY, IDS_COPY);
94 AddItem(IDC_PASTE, IDS_PASTE);
96 AddSeparator();
97 AddItem(IDC_BOOKMARK_BAR_REMOVE, IDS_BOOKMARK_BAR_REMOVE);
98 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
99 switches::kEnableBookmarkUndo)) {
100 AddItem(IDC_BOOKMARK_BAR_UNDO, IDS_BOOKMARK_BAR_UNDO);
101 AddItem(IDC_BOOKMARK_BAR_REDO, IDS_BOOKMARK_BAR_REDO);
104 AddSeparator();
105 AddItem(IDC_BOOKMARK_BAR_ADD_NEW_BOOKMARK, IDS_BOOKMARK_BAR_ADD_NEW_BOOKMARK);
106 AddItem(IDC_BOOKMARK_BAR_NEW_FOLDER, IDS_BOOKMARK_BAR_NEW_FOLDER);
108 AddSeparator();
109 AddItem(IDC_BOOKMARK_MANAGER, IDS_BOOKMARK_MANAGER);
110 // Use the native host desktop type in tests.
111 if (chrome::IsAppsShortcutEnabled(
112 profile_,
113 browser_ ? browser_->host_desktop_type()
114 : chrome::HOST_DESKTOP_TYPE_NATIVE)) {
115 AddCheckboxItem(IDC_BOOKMARK_BAR_SHOW_APPS_SHORTCUT,
116 IDS_BOOKMARK_BAR_SHOW_APPS_SHORTCUT);
118 AddCheckboxItem(IDC_BOOKMARK_BAR_SHOW_MANAGED_BOOKMARKS,
119 IDS_BOOKMARK_BAR_SHOW_MANAGED_BOOKMARKS_DEFAULT_NAME);
120 AddCheckboxItem(IDC_BOOKMARK_BAR_ALWAYS_SHOW, IDS_SHOW_BOOKMARK_BAR);
123 void BookmarkContextMenuController::AddItem(int id, int localization_id) {
124 menu_model_->AddItemWithStringId(id, localization_id);
127 void BookmarkContextMenuController::AddSeparator() {
128 menu_model_->AddSeparator(ui::NORMAL_SEPARATOR);
131 void BookmarkContextMenuController::AddCheckboxItem(int id,
132 int localization_id) {
133 menu_model_->AddCheckItemWithStringId(id, localization_id);
136 void BookmarkContextMenuController::ExecuteCommand(int id, int event_flags) {
137 if (delegate_)
138 delegate_->WillExecuteCommand(id, selection_);
140 base::WeakPtr<BookmarkContextMenuController> ref(weak_factory_.GetWeakPtr());
142 switch (id) {
143 case IDC_BOOKMARK_BAR_OPEN_ALL:
144 case IDC_BOOKMARK_BAR_OPEN_ALL_INCOGNITO:
145 case IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW: {
146 WindowOpenDisposition initial_disposition;
147 if (id == IDC_BOOKMARK_BAR_OPEN_ALL) {
148 initial_disposition = NEW_BACKGROUND_TAB;
149 content::RecordAction(
150 UserMetricsAction("BookmarkBar_ContextMenu_OpenAll"));
151 } else if (id == IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW) {
152 initial_disposition = NEW_WINDOW;
153 content::RecordAction(
154 UserMetricsAction("BookmarkBar_ContextMenu_OpenAllInNewWindow"));
155 } else {
156 initial_disposition = OFF_THE_RECORD;
157 content::RecordAction(
158 UserMetricsAction("BookmarkBar_ContextMenu_OpenAllIncognito"));
160 chrome::OpenAll(parent_window_, navigator_, selection_,
161 initial_disposition, profile_);
162 break;
165 case IDC_BOOKMARK_BAR_RENAME_FOLDER:
166 case IDC_BOOKMARK_BAR_EDIT:
167 content::RecordAction(
168 UserMetricsAction("BookmarkBar_ContextMenu_Edit"));
170 if (selection_.size() != 1) {
171 NOTREACHED();
172 break;
175 BookmarkEditor::Show(
176 parent_window_,
177 profile_,
178 BookmarkEditor::EditDetails::EditNode(selection_[0]),
179 selection_[0]->is_url() ? BookmarkEditor::SHOW_TREE :
180 BookmarkEditor::NO_TREE);
181 break;
183 case IDC_BOOKMARK_BAR_UNDO: {
184 content::RecordAction(
185 UserMetricsAction("BookmarkBar_ContextMenu_Undo"));
186 BookmarkUndoServiceFactory::GetForProfile(profile_)->undo_manager()->
187 Undo();
188 break;
191 case IDC_BOOKMARK_BAR_REDO: {
192 content::RecordAction(
193 UserMetricsAction("BookmarkBar_ContextMenu_Redo"));
194 BookmarkUndoServiceFactory::GetForProfile(profile_)->undo_manager()->
195 Redo();
196 break;
199 case IDC_BOOKMARK_BAR_REMOVE: {
200 content::RecordAction(
201 UserMetricsAction("BookmarkBar_ContextMenu_Remove"));
203 for (size_t i = 0; i < selection_.size(); ++i) {
204 int index = selection_[i]->parent()->GetIndexOf(selection_[i]);
205 if (index > -1)
206 model_->Remove(selection_[i]);
208 selection_.clear();
209 break;
212 case IDC_BOOKMARK_BAR_ADD_NEW_BOOKMARK: {
213 content::RecordAction(
214 UserMetricsAction("BookmarkBar_ContextMenu_Add"));
216 int index;
217 const BookmarkNode* parent =
218 bookmarks::GetParentForNewNodes(parent_, selection_, &index);
219 GURL url;
220 base::string16 title;
221 chrome::GetURLAndTitleToBookmark(
222 browser_->tab_strip_model()->GetActiveWebContents(),
223 &url, &title);
224 BookmarkEditor::Show(parent_window_,
225 profile_,
226 BookmarkEditor::EditDetails::AddNodeInFolder(
227 parent, index, url, title),
228 BookmarkEditor::SHOW_TREE);
229 break;
232 case IDC_BOOKMARK_BAR_NEW_FOLDER: {
233 content::RecordAction(
234 UserMetricsAction("BookmarkBar_ContextMenu_NewFolder"));
236 int index;
237 const BookmarkNode* parent =
238 bookmarks::GetParentForNewNodes(parent_, selection_, &index);
239 BookmarkEditor::Show(
240 parent_window_,
241 profile_,
242 BookmarkEditor::EditDetails::AddFolder(parent, index),
243 BookmarkEditor::SHOW_TREE);
244 break;
247 case IDC_BOOKMARK_BAR_ALWAYS_SHOW:
248 chrome::ToggleBookmarkBarWhenVisible(profile_);
249 break;
251 case IDC_BOOKMARK_BAR_SHOW_APPS_SHORTCUT: {
252 PrefService* prefs = profile_->GetPrefs();
253 prefs->SetBoolean(
254 bookmarks::prefs::kShowAppsShortcutInBookmarkBar,
255 !prefs->GetBoolean(bookmarks::prefs::kShowAppsShortcutInBookmarkBar));
256 break;
259 case IDC_BOOKMARK_BAR_SHOW_MANAGED_BOOKMARKS: {
260 PrefService* prefs = profile_->GetPrefs();
261 prefs->SetBoolean(
262 bookmarks::prefs::kShowManagedBookmarksInBookmarkBar,
263 !prefs->GetBoolean(
264 bookmarks::prefs::kShowManagedBookmarksInBookmarkBar));
265 break;
268 case IDC_BOOKMARK_MANAGER: {
269 content::RecordAction(UserMetricsAction("ShowBookmarkManager"));
270 if (selection_.size() != 1)
271 chrome::ShowBookmarkManager(browser_);
272 else if (selection_[0]->is_folder())
273 chrome::ShowBookmarkManagerForNode(browser_, selection_[0]->id());
274 else if (parent_)
275 chrome::ShowBookmarkManagerForNode(browser_, parent_->id());
276 else
277 chrome::ShowBookmarkManager(browser_);
278 break;
281 case IDC_CUT:
282 bookmarks::CopyToClipboard(model_, selection_, true);
283 break;
285 case IDC_COPY:
286 bookmarks::CopyToClipboard(model_, selection_, false);
287 break;
289 case IDC_PASTE: {
290 int index;
291 const BookmarkNode* paste_target =
292 bookmarks::GetParentForNewNodes(parent_, selection_, &index);
293 if (!paste_target)
294 return;
296 bookmarks::PasteFromClipboard(model_, paste_target, index);
297 break;
300 default:
301 NOTREACHED();
304 // It's possible executing the command resulted in deleting |this|.
305 if (!ref)
306 return;
308 if (delegate_)
309 delegate_->DidExecuteCommand(id);
312 bool BookmarkContextMenuController::IsItemForCommandIdDynamic(int command_id)
313 const {
314 return command_id == IDC_BOOKMARK_BAR_UNDO ||
315 command_id == IDC_BOOKMARK_BAR_REDO ||
316 command_id == IDC_BOOKMARK_BAR_SHOW_MANAGED_BOOKMARKS;
319 base::string16 BookmarkContextMenuController::GetLabelForCommandId(
320 int command_id) const {
321 if (command_id == IDC_BOOKMARK_BAR_UNDO) {
322 return BookmarkUndoServiceFactory::GetForProfile(profile_)->
323 undo_manager()->GetUndoLabel();
325 if (command_id == IDC_BOOKMARK_BAR_REDO) {
326 return BookmarkUndoServiceFactory::GetForProfile(profile_)->
327 undo_manager()->GetRedoLabel();
329 if (command_id == IDC_BOOKMARK_BAR_SHOW_MANAGED_BOOKMARKS) {
330 bookmarks::ManagedBookmarkService* managed =
331 ManagedBookmarkServiceFactory::GetForProfile(profile_);
332 return l10n_util::GetStringFUTF16(IDS_BOOKMARK_BAR_SHOW_MANAGED_BOOKMARKS,
333 managed->managed_node()->GetTitle());
336 NOTREACHED();
337 return base::string16();
340 bool BookmarkContextMenuController::IsCommandIdChecked(int command_id) const {
341 PrefService* prefs = profile_->GetPrefs();
342 if (command_id == IDC_BOOKMARK_BAR_ALWAYS_SHOW)
343 return prefs->GetBoolean(bookmarks::prefs::kShowBookmarkBar);
344 if (command_id == IDC_BOOKMARK_BAR_SHOW_MANAGED_BOOKMARKS)
345 return prefs->GetBoolean(
346 bookmarks::prefs::kShowManagedBookmarksInBookmarkBar);
348 DCHECK_EQ(IDC_BOOKMARK_BAR_SHOW_APPS_SHORTCUT, command_id);
349 return prefs->GetBoolean(bookmarks::prefs::kShowAppsShortcutInBookmarkBar);
352 bool BookmarkContextMenuController::IsCommandIdEnabled(int command_id) const {
353 PrefService* prefs = profile_->GetPrefs();
355 bool is_root_node = selection_.size() == 1 &&
356 selection_[0]->parent() == model_->root_node();
357 bool can_edit = prefs->GetBoolean(bookmarks::prefs::kEditBookmarksEnabled) &&
358 bookmarks::CanAllBeEditedByUser(model_->client(), selection_);
359 IncognitoModePrefs::Availability incognito_avail =
360 IncognitoModePrefs::GetAvailability(prefs);
362 switch (command_id) {
363 case IDC_BOOKMARK_BAR_OPEN_INCOGNITO:
364 return !profile_->IsOffTheRecord() &&
365 incognito_avail != IncognitoModePrefs::DISABLED;
367 case IDC_BOOKMARK_BAR_OPEN_ALL_INCOGNITO:
368 return chrome::HasBookmarkURLsAllowedInIncognitoMode(selection_, profile_)
370 !profile_->IsOffTheRecord() &&
371 incognito_avail != IncognitoModePrefs::DISABLED;
373 case IDC_BOOKMARK_BAR_OPEN_ALL:
374 return chrome::HasBookmarkURLs(selection_);
375 case IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW:
376 return chrome::HasBookmarkURLs(selection_) &&
377 incognito_avail != IncognitoModePrefs::FORCED;
379 case IDC_BOOKMARK_BAR_RENAME_FOLDER:
380 case IDC_BOOKMARK_BAR_EDIT:
381 return selection_.size() == 1 && !is_root_node && can_edit;
383 case IDC_BOOKMARK_BAR_UNDO:
384 return can_edit &&
385 BookmarkUndoServiceFactory::GetForProfile(profile_)->
386 undo_manager()->undo_count() > 0;
388 case IDC_BOOKMARK_BAR_REDO:
389 return can_edit &&
390 BookmarkUndoServiceFactory::GetForProfile(profile_)->
391 undo_manager()->redo_count() > 0;
393 case IDC_BOOKMARK_BAR_REMOVE:
394 return !selection_.empty() && !is_root_node && can_edit;
396 case IDC_BOOKMARK_BAR_NEW_FOLDER:
397 case IDC_BOOKMARK_BAR_ADD_NEW_BOOKMARK:
398 return can_edit && model_->client()->CanBeEditedByUser(parent_) &&
399 bookmarks::GetParentForNewNodes(parent_, selection_, NULL) != NULL;
401 case IDC_BOOKMARK_BAR_ALWAYS_SHOW:
402 return !prefs->IsManagedPreference(bookmarks::prefs::kShowBookmarkBar);
404 case IDC_BOOKMARK_BAR_SHOW_APPS_SHORTCUT:
405 return !prefs->IsManagedPreference(
406 bookmarks::prefs::kShowAppsShortcutInBookmarkBar);
408 case IDC_COPY:
409 case IDC_CUT:
410 return !selection_.empty() && !is_root_node &&
411 (command_id == IDC_COPY || can_edit);
413 case IDC_PASTE:
414 // Paste to selection from the Bookmark Bar, to parent_ everywhere else
415 return can_edit &&
416 ((!selection_.empty() &&
417 bookmarks::CanPasteFromClipboard(model_, selection_[0])) ||
418 bookmarks::CanPasteFromClipboard(model_, parent_));
420 return true;
423 bool BookmarkContextMenuController::IsCommandIdVisible(int command_id) const {
424 if (command_id == IDC_BOOKMARK_BAR_SHOW_MANAGED_BOOKMARKS) {
425 // The option to hide the Managed Bookmarks folder is only available if
426 // there are any managed bookmarks configured at all.
427 bookmarks::ManagedBookmarkService* managed =
428 ManagedBookmarkServiceFactory::GetForProfile(profile_);
429 return !managed->managed_node()->empty();
432 return true;
435 bool BookmarkContextMenuController::GetAcceleratorForCommandId(
436 int command_id,
437 ui::Accelerator* accelerator) {
438 return false;
441 void BookmarkContextMenuController::BookmarkModelChanged() {
442 if (delegate_)
443 delegate_->CloseMenu();