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

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

Powered by Google App Engine
This is Rietveld 408576698