Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(302)

Side by Side Diff: chrome/browser/extensions/extension_toolbar_model.cc

Issue 10533086: Action box menu (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Action box menu Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/extension_toolbar_model.h" 5 #include "chrome/browser/extensions/extension_toolbar_model.h"
6 6
7 #include "chrome/browser/extensions/extension_browser_event_router.h" 7 #include "chrome/browser/extensions/extension_browser_event_router.h"
8 #include "chrome/browser/extensions/extension_prefs.h" 8 #include "chrome/browser/extensions/extension_prefs.h"
9 #include "chrome/browser/extensions/extension_service.h" 9 #include "chrome/browser/extensions/extension_service.h"
10 #include "chrome/browser/extensions/extension_tab_helper.h" 10 #include "chrome/browser/extensions/extension_tab_helper.h"
11 #include "chrome/browser/extensions/extension_tab_util.h" 11 #include "chrome/browser/extensions/extension_tab_util.h"
12 #include "chrome/browser/prefs/pref_service.h" 12 #include "chrome/browser/prefs/pref_service.h"
13 #include "chrome/browser/profiles/profile.h" 13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/ui/browser.h" 14 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/tab_contents/tab_contents.h" 15 #include "chrome/browser/ui/tab_contents/tab_contents.h"
16 #include "chrome/common/chrome_notification_types.h" 16 #include "chrome/common/chrome_notification_types.h"
17 #include "chrome/common/extensions/extension.h" 17 #include "chrome/common/extensions/extension.h"
18 #include "chrome/common/extensions/extension_switch_utils.h"
18 #include "chrome/common/pref_names.h" 19 #include "chrome/common/pref_names.h"
19 #include "content/public/browser/notification_details.h" 20 #include "content/public/browser/notification_details.h"
20 #include "content/public/browser/notification_source.h" 21 #include "content/public/browser/notification_source.h"
21 #include "content/public/browser/web_contents.h" 22 #include "content/public/browser/web_contents.h"
22 23
23 using extensions::Extension; 24 using extensions::Extension;
24 using extensions::ExtensionList; 25 using extensions::ExtensionList;
25 26
26 ExtensionToolbarModel::ExtensionToolbarModel(ExtensionService* service) 27 ExtensionToolbarModel::ExtensionToolbarModel(ExtensionService* service)
27 : service_(service), 28 : service_(service),
(...skipping 25 matching lines...) Expand all
53 observers_.RemoveObserver(observer); 54 observers_.RemoveObserver(observer);
54 } 55 }
55 56
56 void ExtensionToolbarModel::MoveBrowserAction(const Extension* extension, 57 void ExtensionToolbarModel::MoveBrowserAction(const Extension* extension,
57 int index) { 58 int index) {
58 ExtensionList::iterator pos = std::find(begin(), end(), extension); 59 ExtensionList::iterator pos = std::find(begin(), end(), extension);
59 if (pos == end()) { 60 if (pos == end()) {
60 NOTREACHED(); 61 NOTREACHED();
61 return; 62 return;
62 } 63 }
63 toolitems_.erase(pos); 64 toolbar_items_.erase(pos);
64 65
65 int i = 0; 66 int i = 0;
66 bool inserted = false; 67 bool inserted = false;
67 for (ExtensionList::iterator iter = begin(); iter != end(); ++iter, ++i) { 68 for (ExtensionList::iterator iter = begin(); iter != end(); ++iter, ++i) {
68 if (i == index) { 69 if (i == index) {
69 toolitems_.insert(iter, make_scoped_refptr(extension)); 70 toolbar_items_.insert(iter, make_scoped_refptr(extension));
70 inserted = true; 71 inserted = true;
71 break; 72 break;
72 } 73 }
73 } 74 }
74 75
75 if (!inserted) { 76 if (!inserted) {
76 DCHECK_EQ(index, static_cast<int>(toolitems_.size())); 77 DCHECK_EQ(index, static_cast<int>(toolbar_items_.size()));
77 index = toolitems_.size(); 78 index = toolbar_items_.size();
78 79
79 toolitems_.push_back(make_scoped_refptr(extension)); 80 toolbar_items_.push_back(make_scoped_refptr(extension));
80 } 81 }
81 82
82 FOR_EACH_OBSERVER(Observer, observers_, BrowserActionMoved(extension, index)); 83 FOR_EACH_OBSERVER(Observer, observers_, BrowserActionMoved(extension, index));
83 84
84 UpdatePrefs(); 85 UpdatePrefs();
85 } 86 }
86 87
87 ExtensionToolbarModel::Action ExtensionToolbarModel::ExecuteBrowserAction( 88 ExtensionToolbarModel::Action ExtensionToolbarModel::ExecuteBrowserAction(
88 const Extension* extension, 89 const Extension* extension,
89 Browser* browser, 90 Browser* browser,
(...skipping 24 matching lines...) Expand all
114 void ExtensionToolbarModel::SetVisibleIconCount(int count) { 115 void ExtensionToolbarModel::SetVisibleIconCount(int count) {
115 visible_icon_count_ = count == static_cast<int>(size()) ? -1 : count; 116 visible_icon_count_ = count == static_cast<int>(size()) ? -1 : count;
116 prefs_->SetInteger(prefs::kExtensionToolbarSize, visible_icon_count_); 117 prefs_->SetInteger(prefs::kExtensionToolbarSize, visible_icon_count_);
117 } 118 }
118 119
119 void ExtensionToolbarModel::Observe( 120 void ExtensionToolbarModel::Observe(
120 int type, 121 int type,
121 const content::NotificationSource& source, 122 const content::NotificationSource& source,
122 const content::NotificationDetails& details) { 123 const content::NotificationDetails& details) {
123 if (type == chrome::NOTIFICATION_EXTENSIONS_READY) { 124 if (type == chrome::NOTIFICATION_EXTENSIONS_READY) {
124 InitializeExtensionList(); 125 InitializeExtensionLists();
125 return; 126 return;
126 } 127 }
127 128
128 if (!service_->is_ready()) 129 if (!service_->is_ready())
129 return; 130 return;
130 131
131 const Extension* extension = NULL; 132 const Extension* extension = NULL;
132 if (type == chrome::NOTIFICATION_EXTENSION_UNLOADED) { 133 if (type == chrome::NOTIFICATION_EXTENSION_UNLOADED) {
133 extension = content::Details<extensions::UnloadedExtensionInfo>( 134 extension = content::Details<extensions::UnloadedExtensionInfo>(
134 details)->extension; 135 details)->extension;
135 } else { 136 } else {
136 extension = content::Details<const Extension>(details).ptr(); 137 extension = content::Details<const Extension>(details).ptr();
137 } 138 }
138 if (type == chrome::NOTIFICATION_EXTENSION_LOADED) { 139 if (type == chrome::NOTIFICATION_EXTENSION_LOADED) {
139 // We don't want to add the same extension twice. It may have already been 140 // We don't want to add the same extension twice. It may have already been
140 // added by EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED below, if the user 141 // added by EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED below, if the user
141 // hides the browser action and then disables and enables the extension. 142 // hides the browser action and then disables and enables the extension.
142 for (size_t i = 0; i < toolitems_.size(); i++) { 143 for (size_t i = 0; i < toolbar_items_.size(); i++) {
143 if (toolitems_[i].get() == extension) 144 if (toolbar_items_[i].get() == extension)
144 return; // Already exists. 145 return; // Already exists.
145 } 146 }
146 if (service_->extension_prefs()->GetBrowserActionVisibility(extension)) 147 if (service_->extension_prefs()->GetBrowserActionVisibility(extension))
147 AddExtension(extension); 148 AddExtension(extension);
148 } else if (type == chrome::NOTIFICATION_EXTENSION_UNLOADED) { 149 } else if (type == chrome::NOTIFICATION_EXTENSION_UNLOADED) {
149 RemoveExtension(extension); 150 RemoveExtension(extension);
150 } else if ( 151 } else if (
151 type == 152 type ==
152 chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED) { 153 chrome::NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED) {
153 if (service_->extension_prefs()->GetBrowserActionVisibility(extension)) 154 if (service_->extension_prefs()->GetBrowserActionVisibility(extension))
154 AddExtension(extension); 155 AddExtension(extension);
155 else 156 else
156 RemoveExtension(extension); 157 RemoveExtension(extension);
157 } else { 158 } else {
158 NOTREACHED() << "Received unexpected notification"; 159 NOTREACHED() << "Received unexpected notification";
159 } 160 }
160 } 161 }
161 162
162 void ExtensionToolbarModel::AddExtension(const Extension* extension) { 163 void ExtensionToolbarModel::AddExtension(const Extension* extension) {
163 // We only care about extensions with browser actions. 164 // We only care about extensions with browser actions.
164 if (!extension->browser_action()) 165 if (!extension->browser_action())
165 return; 166 return;
166 167
167 if (extension->id() == last_extension_removed_ && 168 if (extension->id() == last_extension_removed_ &&
168 last_extension_removed_index_ < toolitems_.size()) { 169 last_extension_removed_index_ < toolbar_items_.size()) {
169 toolitems_.insert(begin() + last_extension_removed_index_, 170 toolbar_items_.insert(begin() + last_extension_removed_index_,
170 make_scoped_refptr(extension)); 171 make_scoped_refptr(extension));
171 FOR_EACH_OBSERVER(Observer, observers_, 172 FOR_EACH_OBSERVER(Observer, observers_,
172 BrowserActionAdded(extension, last_extension_removed_index_)); 173 BrowserActionAdded(extension, last_extension_removed_index_));
173 } else { 174 } else {
174 toolitems_.push_back(make_scoped_refptr(extension)); 175 toolbar_items_.push_back(make_scoped_refptr(extension));
175 FOR_EACH_OBSERVER(Observer, observers_, 176 FOR_EACH_OBSERVER(Observer, observers_,
176 BrowserActionAdded(extension, toolitems_.size() - 1)); 177 BrowserActionAdded(extension, toolbar_items_.size() - 1));
177 } 178 }
178 179
179 last_extension_removed_ = ""; 180 last_extension_removed_ = "";
180 last_extension_removed_index_ = -1; 181 last_extension_removed_index_ = -1;
181 182
182 UpdatePrefs(); 183 UpdatePrefs();
183 } 184 }
184 185
185 void ExtensionToolbarModel::RemoveExtension(const Extension* extension) { 186 void ExtensionToolbarModel::RemoveExtension(const Extension* extension) {
186 ExtensionList::iterator pos = std::find(begin(), end(), extension); 187 ExtensionList::iterator pos = std::find(begin(), end(), extension);
187 if (pos == end()) { 188 if (pos == end()) {
188 return; 189 return;
189 } 190 }
190 191
191 last_extension_removed_ = extension->id(); 192 last_extension_removed_ = extension->id();
192 last_extension_removed_index_ = pos - begin(); 193 last_extension_removed_index_ = pos - begin();
193 194
194 toolitems_.erase(pos); 195 toolbar_items_.erase(pos);
195 FOR_EACH_OBSERVER(Observer, observers_, 196 FOR_EACH_OBSERVER(Observer, observers_,
196 BrowserActionRemoved(extension)); 197 BrowserActionRemoved(extension));
197 198
198 UpdatePrefs(); 199 UpdatePrefs();
199 } 200 }
200 201
201 // Combine the currently enabled extensions that have browser actions (which 202 // Combine the currently enabled extensions that have browser actions (which
202 // we get from the ExtensionService) with the ordering we get from the 203 // we get from the ExtensionService) with the ordering we get from the
203 // pref service. For robustness we use a somewhat inefficient process: 204 // pref service. For robustness we use a somewhat inefficient process:
204 // 1. Create a vector of extensions sorted by their pref values. This vector may 205 // 1. Create a vector of extensions sorted by their pref values. This vector may
205 // have holes. 206 // have holes.
206 // 2. Create a vector of extensions that did not have a pref value. 207 // 2. Create a vector of extensions that did not have a pref value.
207 // 3. Remove holes from the sorted vector and append the unsorted vector. 208 // 3. Remove holes from the sorted vector and append the unsorted vector.
208 void ExtensionToolbarModel::InitializeExtensionList() { 209 void ExtensionToolbarModel::InitializeExtensionLists() {
209 DCHECK(service_->is_ready()); 210 DCHECK(service_->is_ready());
210 211
211 std::vector<std::string> pref_order = service_->extension_prefs()-> 212 if (extensions::switch_utils::IsActionBoxEnabled())
212 GetToolbarOrder(); 213 PopulateForActionBoxMode();
214 else
215 PopulateForNonActionBoxMode();
216
217 UpdatePrefs();
218
219 extensions_initialized_ = true;
220 FOR_EACH_OBSERVER(Observer, observers_, ModelLoaded());
221 }
222
223 void ExtensionToolbarModel::PopulateForActionBoxMode() {
224 const std::vector<std::string> bar_order =
Aaron Boodman 2012/07/02 22:41:34 Nit: toolbar_order?
yefimt 2012/07/11 22:34:34 Done.
225 service_->extension_prefs()->GetToolbarOrder();
226 const std::vector<std::string> action_box_order =
227 service_->extension_prefs()->GetActionBoxOrder();
228
229 // Items that have a pref for their position.
230 ExtensionList bar_sorted;
231 bar_sorted.resize(bar_order.size(), NULL);
232 ExtensionList action_box_sorted;
233 action_box_sorted.resize(action_box_order.size(), NULL);
234
235 // The items that don't have a pref for their position.
236 ExtensionList bar_unsorted;
237 ExtensionList action_box_unsorted;
238
239 // Create the lists.
240 for (ExtensionSet::const_iterator it = service_->extensions()->begin();
241 it != service_->extensions()->end(); ++it) {
242 const Extension* extension = *it;
243 if (!extension->browser_action())
244 continue;
245
246 bool show_in_toolbar =
247 service_->extension_prefs()->GetBrowserActionVisibility(extension);
Aaron Boodman 2012/07/02 22:41:34 Do we need the pinned preference? Is it enough to
yefimt 2012/07/11 22:34:34 yes, I think pinned pref could be removed. I've ch
248
249 if (show_in_toolbar)
250 AddToProperList(extension, bar_order, &bar_sorted, &bar_unsorted);
251 else
252 AddToProperList(extension, action_box_order, &action_box_sorted,
253 &action_box_unsorted);
254 }
255
256 MergeLists(action_box_sorted, action_box_unsorted, &action_box_menu_items_);
257 MergeLists(bar_sorted, bar_unsorted, &toolbar_items_);
258
259 // Inform observers.
260 for (size_t i = 0; i < toolbar_items_.size(); i++) {
261 FOR_EACH_OBSERVER(Observer, observers_,
262 BrowserActionAdded(action_box_menu_items_[i], i));
263 FOR_EACH_OBSERVER(Observer, observers_,
264 BrowserActionAdded(toolbar_items_[i], i));
265 }
266 }
267
268 void ExtensionToolbarModel::AddToProperList(const Extension* extension,
269 const std::vector<std::string>& order,
270 ExtensionList* sorted,
271 ExtensionList* unsorted) {
272 std::vector<std::string>::const_iterator pos =
273 std::find(order.begin(), order.end(), extension->id());
274 if (pos != order.end()) {
275 int index = std::distance(order.begin(), pos);
276 sorted->at(index) = extension;
Aaron Boodman 2012/07/02 22:41:34 Nit: clearer to just say sorted[index] = extension
yefimt 2012/07/11 22:34:34 sorted is a pointer so it would be (*sorted)[index
tfarina 2012/07/12 01:21:43 No, don't use std::vector<T>::at. See Peter's rec
yefimt 2012/07/13 19:59:20 Done.
277 } else {
278 unsorted->push_back(make_scoped_refptr(extension));
279 }
280 }
281
282 void ExtensionToolbarModel::MergeLists(const ExtensionList& sorted,
283 const ExtensionList& unsorted,
284 ExtensionList* result_list) {
285 result_list->reserve(sorted.size() + unsorted.size());
286 for (ExtensionList::const_iterator iter = sorted.begin();
287 iter != sorted.end();
288 ++iter) {
289 if (*iter != NULL)
290 result_list->push_back(*iter);
291 }
292 result_list->insert(result_list->end(), unsorted.begin(), unsorted.end());
293 }
294
295 void ExtensionToolbarModel::PopulateForNonActionBoxMode() {
296 const std::vector<std::string> pref_order =
297 service_->extension_prefs()->GetToolbarOrder();
213 // Items that have a pref for their position. 298 // Items that have a pref for their position.
214 ExtensionList sorted; 299 ExtensionList sorted;
215 sorted.resize(pref_order.size(), NULL); 300 sorted.resize(pref_order.size(), NULL);
216 // The items that don't have a pref for their position. 301 // The items that don't have a pref for their position.
217 ExtensionList unsorted; 302 ExtensionList unsorted;
218 303
219 // Create the lists. 304 // Create the lists.
220 for (ExtensionSet::const_iterator it = service_->extensions()->begin(); 305 for (ExtensionSet::const_iterator it = service_->extensions()->begin();
221 it != service_->extensions()->end(); ++it) { 306 it != service_->extensions()->end(); ++it) {
222 const Extension* extension = *it; 307 const Extension* extension = *it;
223 if (!extension->browser_action()) 308 if (!extension->browser_action())
224 continue; 309 continue;
225 if (!service_->extension_prefs()->GetBrowserActionVisibility(extension)) 310 if (!service_->extension_prefs()->GetBrowserActionVisibility(extension))
226 continue; 311 continue;
227 312
228 std::vector<std::string>::iterator pos = 313 AddToProperList(extension, pref_order, &sorted, &unsorted);
229 std::find(pref_order.begin(), pref_order.end(), extension->id());
230 if (pos != pref_order.end()) {
231 int index = std::distance(pref_order.begin(), pos);
232 sorted[index] = extension;
233 } else {
234 unsorted.push_back(make_scoped_refptr(extension));
235 }
236 } 314 }
237 315
238 // Merge the lists. 316 MergeLists(sorted, unsorted, &toolbar_items_);
239 toolitems_.reserve(sorted.size() + unsorted.size());
240 for (ExtensionList::iterator iter = sorted.begin();
241 iter != sorted.end(); ++iter) {
242 if (*iter != NULL)
243 toolitems_.push_back(*iter);
244 }
245 toolitems_.insert(toolitems_.end(), unsorted.begin(), unsorted.end());
246 317
247 // Inform observers. 318 // Inform observers.
248 for (size_t i = 0; i < toolitems_.size(); i++) { 319 for (size_t i = 0; i < toolbar_items_.size(); i++) {
249 FOR_EACH_OBSERVER(Observer, observers_, 320 FOR_EACH_OBSERVER(Observer, observers_,
250 BrowserActionAdded(toolitems_[i], i)); 321 BrowserActionAdded(toolbar_items_[i], i));
251 } 322 }
252
253 UpdatePrefs();
254
255 extensions_initialized_ = true;
256 FOR_EACH_OBSERVER(Observer, observers_, ModelLoaded());
257 } 323 }
258 324
259 void ExtensionToolbarModel::UpdatePrefs() { 325 void ExtensionToolbarModel::UpdatePrefs() {
260 if (!service_->extension_prefs()) 326 if (!service_->extension_prefs())
261 return; 327 return;
262 328
263 std::vector<std::string> ids; 329 std::vector<std::string> ids;
264 ids.reserve(toolitems_.size()); 330 ids.reserve(toolbar_items_.size());
265 for (ExtensionList::iterator iter = begin(); iter != end(); ++iter) 331 for (ExtensionList::iterator iter = begin(); iter != end(); ++iter)
266 ids.push_back((*iter)->id()); 332 ids.push_back((*iter)->id());
267 service_->extension_prefs()->SetToolbarOrder(ids); 333 service_->extension_prefs()->SetToolbarOrder(ids);
334
335 ids.clear();
336 ids.reserve(action_box_menu_items_.size());
337 for (size_t i = 0; i < action_box_menu_items_.size(); ++i)
338 ids.push_back(action_box_menu_items_[i]->id());
339 service_->extension_prefs()->SetActionBoxOrder(ids);
268 } 340 }
269 341
270 const Extension* ExtensionToolbarModel::GetExtensionByIndex(int index) const { 342 const Extension* ExtensionToolbarModel::GetExtensionByIndex(int index) const {
271 return toolitems_[index]; 343 return toolbar_items_[index];
272 } 344 }
273 345
274 int ExtensionToolbarModel::IncognitoIndexToOriginal(int incognito_index) { 346 int ExtensionToolbarModel::IncognitoIndexToOriginal(int incognito_index) {
275 int original_index = 0, i = 0; 347 int original_index = 0, i = 0;
276 for (ExtensionList::iterator iter = begin(); iter != end(); 348 for (ExtensionList::iterator iter = begin(); iter != end();
277 ++iter, ++original_index) { 349 ++iter, ++original_index) {
278 if (service_->IsIncognitoEnabled((*iter)->id())) { 350 if (service_->IsIncognitoEnabled((*iter)->id())) {
279 if (incognito_index == i) 351 if (incognito_index == i)
280 break; 352 break;
281 ++i; 353 ++i;
282 } 354 }
283 } 355 }
284 return original_index; 356 return original_index;
285 } 357 }
286 358
287 int ExtensionToolbarModel::OriginalIndexToIncognito(int original_index) { 359 int ExtensionToolbarModel::OriginalIndexToIncognito(int original_index) {
288 int incognito_index = 0, i = 0; 360 int incognito_index = 0, i = 0;
289 for (ExtensionList::iterator iter = begin(); iter != end(); 361 for (ExtensionList::iterator iter = begin(); iter != end();
290 ++iter, ++i) { 362 ++iter, ++i) {
291 if (original_index == i) 363 if (original_index == i)
292 break; 364 break;
293 if (service_->IsIncognitoEnabled((*iter)->id())) 365 if (service_->IsIncognitoEnabled((*iter)->id()))
294 ++incognito_index; 366 ++incognito_index;
295 } 367 }
296 return incognito_index; 368 return incognito_index;
297 } 369 }
370
371 const Extension* ExtensionToolbarModel::GetActionBoxExtensionByIndex(
372 int index) const {
373 return action_box_menu_items_[index];
374 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698