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

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

Issue 487021: Persist the order of extensions in the browser action toolbar across sessions... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years 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) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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_prefs.h"
7 #include "chrome/browser/extensions/extensions_service.h" 8 #include "chrome/browser/extensions/extensions_service.h"
8 #include "chrome/common/extensions/extension.h" 9 #include "chrome/common/extensions/extension.h"
9 #include "chrome/common/notification_service.h" 10 #include "chrome/common/notification_service.h"
10 11
11 ExtensionToolbarModel::ExtensionToolbarModel(ExtensionsService* service) 12 ExtensionToolbarModel::ExtensionToolbarModel(ExtensionsService* service)
12 : service_(service) { 13 : service_(service) {
13 DCHECK(service_); 14 DCHECK(service_);
14 15
15 registrar_.Add(this, NotificationType::EXTENSION_LOADED, 16 registrar_.Add(this, NotificationType::EXTENSION_LOADED,
16 Source<Profile>(service_->profile())); 17 Source<Profile>(service_->profile()));
(...skipping 22 matching lines...) Expand all
39 if (pos == end()) { 40 if (pos == end()) {
40 NOTREACHED(); 41 NOTREACHED();
41 return; 42 return;
42 } 43 }
43 toolitems_.erase(pos); 44 toolitems_.erase(pos);
44 45
45 int i = 0; 46 int i = 0;
46 bool inserted = false; 47 bool inserted = false;
47 for (ExtensionList::iterator iter = begin(); iter != end(); ++iter, ++i) { 48 for (ExtensionList::iterator iter = begin(); iter != end(); ++iter, ++i) {
48 if (i == index) { 49 if (i == index) {
49 toolitems_.insert(pos, extension); 50 toolitems_.insert(iter, extension);
50 inserted = true; 51 inserted = true;
51 break; 52 break;
52 } 53 }
53 } 54 }
54 55
55 if (!inserted) { 56 if (!inserted) {
56 DCHECK_EQ(index, static_cast<int>(toolitems_.size())); 57 DCHECK_EQ(index, static_cast<int>(toolitems_.size()));
57 index = toolitems_.size(); 58 index = toolitems_.size();
58 59
59 toolitems_.push_back(extension); 60 toolitems_.push_back(extension);
60 } 61 }
61 62
62 FOR_EACH_OBSERVER(Observer, observers_, BrowserActionMoved(extension, index)); 63 FOR_EACH_OBSERVER(Observer, observers_, BrowserActionMoved(extension, index));
64
65 UpdatePrefs();
63 } 66 }
64 67
65 void ExtensionToolbarModel::Observe(NotificationType type, 68 void ExtensionToolbarModel::Observe(NotificationType type,
66 const NotificationSource& source, 69 const NotificationSource& source,
67 const NotificationDetails& details) { 70 const NotificationDetails& details) {
68 if (type == NotificationType::EXTENSIONS_READY) { 71 if (type == NotificationType::EXTENSIONS_READY) {
69 for (size_t i = 0; i < service_->extensions()->size(); ++i) { 72 InitializeExtensionList();
70 Extension* extension = service_->GetExtensionById(
71 service_->extensions()->at(i)->id(), false);
72 AddExtension(extension);
73 }
74 return; 73 return;
75 } 74 }
76 75
77 if (!service_->is_ready()) 76 if (!service_->is_ready())
78 return; 77 return;
79 78
80 Extension* extension = Details<Extension>(details).ptr(); 79 Extension* extension = Details<Extension>(details).ptr();
81 if (type == NotificationType::EXTENSION_LOADED) { 80 if (type == NotificationType::EXTENSION_LOADED) {
82 AddExtension(extension); 81 AddExtension(extension);
83 } else if (type == NotificationType::EXTENSION_UNLOADED || 82 } else if (type == NotificationType::EXTENSION_UNLOADED ||
84 type == NotificationType::EXTENSION_UNLOADED_DISABLED) { 83 type == NotificationType::EXTENSION_UNLOADED_DISABLED) {
85 RemoveExtension(extension); 84 RemoveExtension(extension);
86 } else { 85 } else {
87 NOTREACHED() << "Received unexpected notification"; 86 NOTREACHED() << "Received unexpected notification";
88 } 87 }
89 } 88 }
90 89
91 void ExtensionToolbarModel::AddExtension(Extension* extension) { 90 void ExtensionToolbarModel::AddExtension(Extension* extension) {
92 // We only care about extensions with browser actions. 91 // We only care about extensions with browser actions.
93 if (!extension->browser_action()) 92 if (!extension->browser_action())
94 return; 93 return;
95 94
96 toolitems_.push_back(extension); 95 toolitems_.push_back(extension);
97 FOR_EACH_OBSERVER(Observer, observers_, 96 FOR_EACH_OBSERVER(Observer, observers_,
98 BrowserActionAdded(extension, toolitems_.size() - 1)); 97 BrowserActionAdded(extension, toolitems_.size() - 1));
98
99 UpdatePrefs();
99 } 100 }
100 101
101 void ExtensionToolbarModel::RemoveExtension(Extension* extension) { 102 void ExtensionToolbarModel::RemoveExtension(Extension* extension) {
102 ExtensionList::iterator pos = std::find(begin(), end(), extension); 103 ExtensionList::iterator pos = std::find(begin(), end(), extension);
103 if (pos != end()) { 104 if (pos == end()) {
104 toolitems_.erase(pos); 105 return;
106 }
107
108 toolitems_.erase(pos);
109 FOR_EACH_OBSERVER(Observer, observers_,
110 BrowserActionRemoved(extension));
111
112 UpdatePrefs();
113 }
114
115 // Combine the currently enabled extensions that have browser actions (which
116 // we get from the ExtensionsService) with the ordering we get from the
117 // pref service. For robustness we use a somewhat inefficient process:
118 // 1. Create a vector of extensions sorted by their pref values. This vector may
119 // have holes.
120 // 2. Create a vector of extensions that did not have a pref value.
121 // 3. Remove holes from the sorted vector and append the unsorted vector.
122 void ExtensionToolbarModel::InitializeExtensionList() {
123 DCHECK(service_->is_ready());
124
125 std::vector<std::string> pref_order = service_->extension_prefs()->
126 GetToolbarOrder();
127 // Items that have a pref for their position.
128 ExtensionList sorted;
129 sorted.resize(pref_order.size(), NULL);
130 // The items that don't have a pref for their position.
131 ExtensionList unsorted;
132
133 // Create the lists.
134 for (size_t i = 0; i < service_->extensions()->size(); ++i) {
135 Extension* extension = service_->GetExtensionById(
136 service_->extensions()->at(i)->id(), false);
tony 2009/12/11 19:59:38 Nit: Doesn't at(i) return the extension you want?
Evan Stade 2009/12/11 20:04:20 hmm, so it does. Don't I feel stupid.
137 if (!extension->browser_action())
138 continue;
139
140 std::vector<std::string>::iterator pos =
141 std::find(pref_order.begin(), pref_order.end(), extension->id());
142 if (pos != pref_order.end()) {
143 int index = std::distance(pref_order.begin(), pos);
144 sorted[index] = extension;
145 } else {
146 unsorted.push_back(extension);
147 }
148 }
149
150 // Merge the lists.
151 toolitems_.reserve(sorted.size() + unsorted.size());
152 for (ExtensionList::iterator iter = sorted.begin();
153 iter != sorted.end(); ++iter) {
154 if (*iter != NULL)
155 toolitems_.push_back(*iter);
156 }
157 toolitems_.insert(toolitems_.end(), unsorted.begin(), unsorted.end());
158
159 // Inform observers.
160 for (size_t i = 0; i < toolitems_.size(); i++) {
105 FOR_EACH_OBSERVER(Observer, observers_, 161 FOR_EACH_OBSERVER(Observer, observers_,
106 BrowserActionRemoved(extension)); 162 BrowserActionAdded(toolitems_[i], i));
107 } 163 }
164
165 UpdatePrefs();
108 } 166 }
167
168 void ExtensionToolbarModel::UpdatePrefs() {
169 if (!service_->extension_prefs())
170 return;
171
172 std::vector<std::string> ids;
173 ids.reserve(toolitems_.size());
174 for (ExtensionList::iterator iter = begin(); iter != end(); ++iter)
175 ids.push_back((*iter)->id());
176 service_->extension_prefs()->SetToolbarOrder(ids);
177 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_toolbar_model.h ('k') | chrome/browser/gtk/browser_actions_toolbar_gtk.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698