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