• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
BookmarkContextMenuController(gfx::NativeWindow parent_window,BookmarkContextMenuControllerDelegate * delegate,Profile * profile,PageNavigator * navigator,const BookmarkNode * parent,const std::vector<const BookmarkNode * > & selection)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 
~BookmarkContextMenuController()45 BookmarkContextMenuController::~BookmarkContextMenuController() {
46   if (model_)
47     model_->RemoveObserver(this);
48 }
49 
BuildMenu()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 
AddItem(int id,int localization_id)90 void BookmarkContextMenuController::AddItem(int id, int localization_id) {
91   menu_model_->AddItemWithStringId(id, localization_id);
92 }
93 
AddSeparator()94 void BookmarkContextMenuController::AddSeparator() {
95   menu_model_->AddSeparator();
96 }
97 
AddCheckboxItem(int id,int localization_id)98 void BookmarkContextMenuController::AddCheckboxItem(int id,
99                                                     int localization_id) {
100   menu_model_->AddCheckItemWithStringId(id, localization_id);
101 }
102 
ExecuteCommand(int id)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 
IsCommandIdChecked(int command_id) const237 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 
IsCommandIdEnabled(int command_id) const242 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 
GetAcceleratorForCommandId(int command_id,ui::Accelerator * accelerator)292 bool BookmarkContextMenuController::GetAcceleratorForCommandId(
293     int command_id,
294     ui::Accelerator* accelerator) {
295   return false;
296 }
297 
BookmarkModelChanged()298 void BookmarkContextMenuController::BookmarkModelChanged() {
299   if (delegate_)
300     delegate_->CloseMenu();
301 }
302 
HasURLs() const303 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