Only grant permissions to new extensions from sync if they have the expected version
[chromium-blink-merge.git] / chrome / browser / ui / bookmarks / bookmark_context_menu_controller.cc
blob7bc0256e156edaa64eb515de3b929ab85054e2ed
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 DCHECK(profile_);
55 DCHECK(model_->loaded());
56 menu_model_.reset(new ui::SimpleMenuModel(this));
57 model_->AddObserver(this);
59 BuildMenu();
62 BookmarkContextMenuController::~BookmarkContextMenuController() {
63 if (model_)
64 model_->RemoveObserver(this);
67 void BookmarkContextMenuController::BuildMenu() {
68 if (selection_.size() == 1 && selection_[0]->is_url()) {
69 AddItem(IDC_BOOKMARK_BAR_OPEN_ALL,
70 IDS_BOOKMARK_BAR_OPEN_IN_NEW_TAB);
71 AddItem(IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW,
72 IDS_BOOKMARK_BAR_OPEN_IN_NEW_WINDOW);
73 AddItem(IDC_BOOKMARK_BAR_OPEN_ALL_INCOGNITO,
74 IDS_BOOKMARK_BAR_OPEN_INCOGNITO);
75 } else {
76 AddItem(IDC_BOOKMARK_BAR_OPEN_ALL, IDS_BOOKMARK_BAR_OPEN_ALL);
77 AddItem(IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW,
78 IDS_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW);
79 AddItem(IDC_BOOKMARK_BAR_OPEN_ALL_INCOGNITO,
80 IDS_BOOKMARK_BAR_OPEN_ALL_INCOGNITO);
83 AddSeparator();
84 if (selection_.size() == 1 && selection_[0]->is_folder()) {
85 AddItem(IDC_BOOKMARK_BAR_RENAME_FOLDER, IDS_BOOKMARK_BAR_RENAME_FOLDER);
86 } else {
87 AddItem(IDC_BOOKMARK_BAR_EDIT, IDS_BOOKMARK_BAR_EDIT);
90 AddSeparator();
91 AddItem(IDC_CUT, IDS_CUT);
92 AddItem(IDC_COPY, IDS_COPY);
93 AddItem(IDC_PASTE, IDS_PASTE);
95 AddSeparator();
96 AddItem(IDC_BOOKMARK_BAR_REMOVE, IDS_BOOKMARK_BAR_REMOVE);
97 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
98 switches::kEnableBookmarkUndo)) {
99 AddItem(IDC_BOOKMARK_BAR_UNDO, IDS_BOOKMARK_BAR_UNDO);
100 AddItem(IDC_BOOKMARK_BAR_REDO, IDS_BOOKMARK_BAR_REDO);
103 AddSeparator();
104 AddItem(IDC_BOOKMARK_BAR_ADD_NEW_BOOKMARK, IDS_BOOKMARK_BAR_ADD_NEW_BOOKMARK);
105 AddItem(IDC_BOOKMARK_BAR_NEW_FOLDER, IDS_BOOKMARK_BAR_NEW_FOLDER);
107 AddSeparator();
108 AddItem(IDC_BOOKMARK_MANAGER, IDS_BOOKMARK_MANAGER);
109 // Use the native host desktop type in tests.
110 if (chrome::IsAppsShortcutEnabled(
111 profile_,
112 browser_ ? browser_->host_desktop_type()
113 : chrome::HOST_DESKTOP_TYPE_NATIVE)) {
114 AddCheckboxItem(IDC_BOOKMARK_BAR_SHOW_APPS_SHORTCUT,
115 IDS_BOOKMARK_BAR_SHOW_APPS_SHORTCUT);
117 AddCheckboxItem(IDC_BOOKMARK_BAR_SHOW_MANAGED_BOOKMARKS,
118 IDS_BOOKMARK_BAR_SHOW_MANAGED_BOOKMARKS_DEFAULT_NAME);
119 AddCheckboxItem(IDC_BOOKMARK_BAR_ALWAYS_SHOW, IDS_SHOW_BOOKMARK_BAR);
122 void BookmarkContextMenuController::AddItem(int id, int localization_id) {
123 menu_model_->AddItemWithStringId(id, localization_id);
126 void BookmarkContextMenuController::AddSeparator() {
127 menu_model_->AddSeparator(ui::NORMAL_SEPARATOR);
130 void BookmarkContextMenuController::AddCheckboxItem(int id,
131 int localization_id) {
132 menu_model_->AddCheckItemWithStringId(id, localization_id);
135 void BookmarkContextMenuController::ExecuteCommand(int id, int event_flags) {
136 if (delegate_)
137 delegate_->WillExecuteCommand(id, selection_);
139 switch (id) {
140 case IDC_BOOKMARK_BAR_OPEN_ALL:
141 case IDC_BOOKMARK_BAR_OPEN_ALL_INCOGNITO:
142 case IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW: {
143 WindowOpenDisposition initial_disposition;
144 if (id == IDC_BOOKMARK_BAR_OPEN_ALL) {
145 initial_disposition = NEW_BACKGROUND_TAB;
146 content::RecordAction(
147 UserMetricsAction("BookmarkBar_ContextMenu_OpenAll"));
148 } else if (id == IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW) {
149 initial_disposition = NEW_WINDOW;
150 content::RecordAction(
151 UserMetricsAction("BookmarkBar_ContextMenu_OpenAllInNewWindow"));
152 } else {
153 initial_disposition = OFF_THE_RECORD;
154 content::RecordAction(
155 UserMetricsAction("BookmarkBar_ContextMenu_OpenAllIncognito"));
157 chrome::OpenAll(parent_window_, navigator_, selection_,
158 initial_disposition, profile_);
159 break;
162 case IDC_BOOKMARK_BAR_RENAME_FOLDER:
163 case IDC_BOOKMARK_BAR_EDIT:
164 content::RecordAction(
165 UserMetricsAction("BookmarkBar_ContextMenu_Edit"));
167 if (selection_.size() != 1) {
168 NOTREACHED();
169 break;
172 BookmarkEditor::Show(
173 parent_window_,
174 profile_,
175 BookmarkEditor::EditDetails::EditNode(selection_[0]),
176 selection_[0]->is_url() ? BookmarkEditor::SHOW_TREE :
177 BookmarkEditor::NO_TREE);
178 break;
180 case IDC_BOOKMARK_BAR_UNDO: {
181 content::RecordAction(
182 UserMetricsAction("BookmarkBar_ContextMenu_Undo"));
183 BookmarkUndoServiceFactory::GetForProfile(profile_)->undo_manager()->
184 Undo();
185 break;
188 case IDC_BOOKMARK_BAR_REDO: {
189 content::RecordAction(
190 UserMetricsAction("BookmarkBar_ContextMenu_Redo"));
191 BookmarkUndoServiceFactory::GetForProfile(profile_)->undo_manager()->
192 Redo();
193 break;
196 case IDC_BOOKMARK_BAR_REMOVE: {
197 content::RecordAction(
198 UserMetricsAction("BookmarkBar_ContextMenu_Remove"));
200 for (size_t i = 0; i < selection_.size(); ++i) {
201 int index = selection_[i]->parent()->GetIndexOf(selection_[i]);
202 if (index > -1)
203 model_->Remove(selection_[i]);
205 selection_.clear();
206 break;
209 case IDC_BOOKMARK_BAR_ADD_NEW_BOOKMARK: {
210 content::RecordAction(
211 UserMetricsAction("BookmarkBar_ContextMenu_Add"));
213 int index;
214 const BookmarkNode* parent =
215 bookmarks::GetParentForNewNodes(parent_, selection_, &index);
216 GURL url;
217 base::string16 title;
218 chrome::GetURLAndTitleToBookmark(
219 browser_->tab_strip_model()->GetActiveWebContents(),
220 &url, &title);
221 BookmarkEditor::Show(parent_window_,
222 profile_,
223 BookmarkEditor::EditDetails::AddNodeInFolder(
224 parent, index, url, title),
225 BookmarkEditor::SHOW_TREE);
226 break;
229 case IDC_BOOKMARK_BAR_NEW_FOLDER: {
230 content::RecordAction(
231 UserMetricsAction("BookmarkBar_ContextMenu_NewFolder"));
233 int index;
234 const BookmarkNode* parent =
235 bookmarks::GetParentForNewNodes(parent_, selection_, &index);
236 BookmarkEditor::Show(
237 parent_window_,
238 profile_,
239 BookmarkEditor::EditDetails::AddFolder(parent, index),
240 BookmarkEditor::SHOW_TREE);
241 break;
244 case IDC_BOOKMARK_BAR_ALWAYS_SHOW:
245 chrome::ToggleBookmarkBarWhenVisible(profile_);
246 break;
248 case IDC_BOOKMARK_BAR_SHOW_APPS_SHORTCUT: {
249 PrefService* prefs = profile_->GetPrefs();
250 prefs->SetBoolean(
251 bookmarks::prefs::kShowAppsShortcutInBookmarkBar,
252 !prefs->GetBoolean(bookmarks::prefs::kShowAppsShortcutInBookmarkBar));
253 break;
256 case IDC_BOOKMARK_BAR_SHOW_MANAGED_BOOKMARKS: {
257 PrefService* prefs = profile_->GetPrefs();
258 prefs->SetBoolean(
259 bookmarks::prefs::kShowManagedBookmarksInBookmarkBar,
260 !prefs->GetBoolean(
261 bookmarks::prefs::kShowManagedBookmarksInBookmarkBar));
262 break;
265 case IDC_BOOKMARK_MANAGER: {
266 content::RecordAction(UserMetricsAction("ShowBookmarkManager"));
267 if (selection_.size() != 1)
268 chrome::ShowBookmarkManager(browser_);
269 else if (selection_[0]->is_folder())
270 chrome::ShowBookmarkManagerForNode(browser_, selection_[0]->id());
271 else if (parent_)
272 chrome::ShowBookmarkManagerForNode(browser_, parent_->id());
273 else
274 chrome::ShowBookmarkManager(browser_);
275 break;
278 case IDC_CUT:
279 bookmarks::CopyToClipboard(model_, selection_, true);
280 break;
282 case IDC_COPY:
283 bookmarks::CopyToClipboard(model_, selection_, false);
284 break;
286 case IDC_PASTE: {
287 int index;
288 const BookmarkNode* paste_target =
289 bookmarks::GetParentForNewNodes(parent_, selection_, &index);
290 if (!paste_target)
291 return;
293 bookmarks::PasteFromClipboard(model_, paste_target, index);
294 break;
297 default:
298 NOTREACHED();
301 if (delegate_)
302 delegate_->DidExecuteCommand(id);
305 bool BookmarkContextMenuController::IsItemForCommandIdDynamic(int command_id)
306 const {
307 return command_id == IDC_BOOKMARK_BAR_UNDO ||
308 command_id == IDC_BOOKMARK_BAR_REDO ||
309 command_id == IDC_BOOKMARK_BAR_SHOW_MANAGED_BOOKMARKS;
312 base::string16 BookmarkContextMenuController::GetLabelForCommandId(
313 int command_id) const {
314 if (command_id == IDC_BOOKMARK_BAR_UNDO) {
315 return BookmarkUndoServiceFactory::GetForProfile(profile_)->
316 undo_manager()->GetUndoLabel();
318 if (command_id == IDC_BOOKMARK_BAR_REDO) {
319 return BookmarkUndoServiceFactory::GetForProfile(profile_)->
320 undo_manager()->GetRedoLabel();
322 if (command_id == IDC_BOOKMARK_BAR_SHOW_MANAGED_BOOKMARKS) {
323 bookmarks::ManagedBookmarkService* managed =
324 ManagedBookmarkServiceFactory::GetForProfile(profile_);
325 return l10n_util::GetStringFUTF16(IDS_BOOKMARK_BAR_SHOW_MANAGED_BOOKMARKS,
326 managed->managed_node()->GetTitle());
329 NOTREACHED();
330 return base::string16();
333 bool BookmarkContextMenuController::IsCommandIdChecked(int command_id) const {
334 PrefService* prefs = profile_->GetPrefs();
335 if (command_id == IDC_BOOKMARK_BAR_ALWAYS_SHOW)
336 return prefs->GetBoolean(bookmarks::prefs::kShowBookmarkBar);
337 if (command_id == IDC_BOOKMARK_BAR_SHOW_MANAGED_BOOKMARKS)
338 return prefs->GetBoolean(
339 bookmarks::prefs::kShowManagedBookmarksInBookmarkBar);
341 DCHECK_EQ(IDC_BOOKMARK_BAR_SHOW_APPS_SHORTCUT, command_id);
342 return prefs->GetBoolean(bookmarks::prefs::kShowAppsShortcutInBookmarkBar);
345 bool BookmarkContextMenuController::IsCommandIdEnabled(int command_id) const {
346 PrefService* prefs = profile_->GetPrefs();
348 bool is_root_node = selection_.size() == 1 &&
349 selection_[0]->parent() == model_->root_node();
350 bool can_edit = prefs->GetBoolean(bookmarks::prefs::kEditBookmarksEnabled) &&
351 bookmarks::CanAllBeEditedByUser(model_->client(), selection_);
352 IncognitoModePrefs::Availability incognito_avail =
353 IncognitoModePrefs::GetAvailability(prefs);
355 switch (command_id) {
356 case IDC_BOOKMARK_BAR_OPEN_INCOGNITO:
357 return !profile_->IsOffTheRecord() &&
358 incognito_avail != IncognitoModePrefs::DISABLED;
360 case IDC_BOOKMARK_BAR_OPEN_ALL_INCOGNITO:
361 return chrome::HasBookmarkURLsAllowedInIncognitoMode(selection_, profile_)
363 !profile_->IsOffTheRecord() &&
364 incognito_avail != IncognitoModePrefs::DISABLED;
366 case IDC_BOOKMARK_BAR_OPEN_ALL:
367 return chrome::HasBookmarkURLs(selection_);
368 case IDC_BOOKMARK_BAR_OPEN_ALL_NEW_WINDOW:
369 return chrome::HasBookmarkURLs(selection_) &&
370 incognito_avail != IncognitoModePrefs::FORCED;
372 case IDC_BOOKMARK_BAR_RENAME_FOLDER:
373 case IDC_BOOKMARK_BAR_EDIT:
374 return selection_.size() == 1 && !is_root_node && can_edit;
376 case IDC_BOOKMARK_BAR_UNDO:
377 return can_edit &&
378 BookmarkUndoServiceFactory::GetForProfile(profile_)->
379 undo_manager()->undo_count() > 0;
381 case IDC_BOOKMARK_BAR_REDO:
382 return can_edit &&
383 BookmarkUndoServiceFactory::GetForProfile(profile_)->
384 undo_manager()->redo_count() > 0;
386 case IDC_BOOKMARK_BAR_REMOVE:
387 return !selection_.empty() && !is_root_node && can_edit;
389 case IDC_BOOKMARK_BAR_NEW_FOLDER:
390 case IDC_BOOKMARK_BAR_ADD_NEW_BOOKMARK:
391 return can_edit && model_->client()->CanBeEditedByUser(parent_) &&
392 bookmarks::GetParentForNewNodes(parent_, selection_, NULL) != NULL;
394 case IDC_BOOKMARK_BAR_ALWAYS_SHOW:
395 return !prefs->IsManagedPreference(bookmarks::prefs::kShowBookmarkBar);
397 case IDC_BOOKMARK_BAR_SHOW_APPS_SHORTCUT:
398 return !prefs->IsManagedPreference(
399 bookmarks::prefs::kShowAppsShortcutInBookmarkBar);
401 case IDC_COPY:
402 case IDC_CUT:
403 return !selection_.empty() && !is_root_node &&
404 (command_id == IDC_COPY || can_edit);
406 case IDC_PASTE:
407 // Paste to selection from the Bookmark Bar, to parent_ everywhere else
408 return can_edit &&
409 ((!selection_.empty() &&
410 bookmarks::CanPasteFromClipboard(model_, selection_[0])) ||
411 bookmarks::CanPasteFromClipboard(model_, parent_));
413 return true;
416 bool BookmarkContextMenuController::IsCommandIdVisible(int command_id) const {
417 if (command_id == IDC_BOOKMARK_BAR_SHOW_MANAGED_BOOKMARKS) {
418 // The option to hide the Managed Bookmarks folder is only available if
419 // there are any managed bookmarks configured at all.
420 bookmarks::ManagedBookmarkService* managed =
421 ManagedBookmarkServiceFactory::GetForProfile(profile_);
422 return !managed->managed_node()->empty();
425 return true;
428 bool BookmarkContextMenuController::GetAcceleratorForCommandId(
429 int command_id,
430 ui::Accelerator* accelerator) {
431 return false;
434 void BookmarkContextMenuController::BookmarkModelChanged() {
435 if (delegate_)
436 delegate_->CloseMenu();