OLD | NEW |
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_shelf_model.h" | 5 #include "chrome/browser/extensions/extension_shelf_model.h" |
6 | 6 |
7 #include "base/stl_util-inl.h" | 7 #include "base/stl_util-inl.h" |
8 #include "chrome/browser/browser.h" | 8 #include "chrome/browser/browser.h" |
9 #include "chrome/browser/profile.h" | 9 #include "chrome/browser/profile.h" |
10 #include "chrome/browser/extensions/extension_host.h" | 10 #include "chrome/browser/extensions/extension_host.h" |
(...skipping 21 matching lines...) Expand all Loading... |
32 Source<ExtensionPrefs>(prefs_)); | 32 Source<ExtensionPrefs>(prefs_)); |
33 ready_ = service->is_ready(); | 33 ready_ = service->is_ready(); |
34 if (ready_) { | 34 if (ready_) { |
35 AddExtensions(service->extensions()); | 35 AddExtensions(service->extensions()); |
36 SortToolstrips(); | 36 SortToolstrips(); |
37 } | 37 } |
38 } | 38 } |
39 } | 39 } |
40 | 40 |
41 ExtensionShelfModel::~ExtensionShelfModel() { | 41 ExtensionShelfModel::~ExtensionShelfModel() { |
| 42 FOR_EACH_OBSERVER(ExtensionShelfModelObserver, observers_, |
| 43 ShelfModelDeleting()); |
| 44 |
42 while (observers_.size()) | 45 while (observers_.size()) |
43 observers_.RemoveObserver(observers_.GetElementAt(0)); | 46 observers_.RemoveObserver(observers_.GetElementAt(0)); |
44 | 47 |
45 ExtensionToolstrips::iterator t; | 48 for (iterator t = toolstrips_.begin(); t != toolstrips_.end(); ++t) |
46 for (t = toolstrips_.begin(); t != toolstrips_.end(); ++t) | |
47 delete t->host; | 49 delete t->host; |
48 toolstrips_.clear(); | 50 toolstrips_.clear(); |
49 } | 51 } |
50 | 52 |
51 void ExtensionShelfModel::AddObserver(ExtensionShelfModelObserver* observer) { | 53 void ExtensionShelfModel::AddObserver(ExtensionShelfModelObserver* observer) { |
52 observers_.AddObserver(observer); | 54 observers_.AddObserver(observer); |
53 } | 55 } |
54 | 56 |
55 void ExtensionShelfModel::RemoveObserver( | 57 void ExtensionShelfModel::RemoveObserver( |
56 ExtensionShelfModelObserver* observer) { | 58 ExtensionShelfModelObserver* observer) { |
57 observers_.RemoveObserver(observer); | 59 observers_.RemoveObserver(observer); |
58 } | 60 } |
59 | 61 |
60 void ExtensionShelfModel::AppendToolstrip(const ToolstripItem& toolstrip) { | 62 void ExtensionShelfModel::AppendToolstrip(const ToolstripItem& toolstrip) { |
61 InsertToolstripAt(count(), toolstrip); | 63 InsertToolstripAt(count(), toolstrip); |
62 } | 64 } |
63 | 65 |
64 void ExtensionShelfModel::InsertToolstripAt(int index, | 66 void ExtensionShelfModel::InsertToolstripAt(int index, |
65 const ToolstripItem& toolstrip) { | 67 const ToolstripItem& toolstrip) { |
66 toolstrips_.insert(toolstrips_.begin() + index, toolstrip); | 68 toolstrips_.insert(toolstrips_.begin() + index, toolstrip); |
67 if (ready_) { | 69 if (ready_) { |
68 FOR_EACH_OBSERVER(ExtensionShelfModelObserver, observers_, | 70 FOR_EACH_OBSERVER(ExtensionShelfModelObserver, observers_, |
69 ToolstripInsertedAt(toolstrip.host, index)); | 71 ToolstripInsertedAt(toolstrip.host, index)); |
70 } | 72 } |
71 } | 73 } |
72 | 74 |
73 void ExtensionShelfModel::RemoveToolstripAt(int index) { | 75 void ExtensionShelfModel::RemoveToolstripAt(int index) { |
74 ExtensionHost* host = ToolstripAt(index); | 76 ExtensionHost* host = ToolstripAt(index).host; |
75 FOR_EACH_OBSERVER(ExtensionShelfModelObserver, observers_, | 77 FOR_EACH_OBSERVER(ExtensionShelfModelObserver, observers_, |
76 ToolstripRemovingAt(host, index)); | 78 ToolstripRemovingAt(host, index)); |
77 toolstrips_.erase(toolstrips_.begin() + index); | 79 toolstrips_.erase(toolstrips_.begin() + index); |
78 delete host; | 80 delete host; |
79 } | 81 } |
80 | 82 |
81 void ExtensionShelfModel::MoveToolstripAt(int index, int to_index) { | 83 void ExtensionShelfModel::MoveToolstripAt(int index, int to_index) { |
82 DCHECK(index >= 0); | 84 DCHECK(index >= 0); |
83 DCHECK(to_index >= 0); | 85 DCHECK(to_index >= 0); |
84 if (index == to_index) | 86 if (index == to_index) |
85 return; | 87 return; |
86 | 88 |
87 ToolstripItem toolstrip = toolstrips_[index]; | 89 ToolstripItem toolstrip = toolstrips_[index]; |
88 toolstrips_.erase(toolstrips_.begin() + index); | 90 toolstrips_.erase(toolstrips_.begin() + index); |
89 toolstrips_.insert(toolstrips_.begin() + to_index, toolstrip); | 91 toolstrips_.insert(toolstrips_.begin() + to_index, toolstrip); |
90 | 92 |
91 FOR_EACH_OBSERVER(ExtensionShelfModelObserver, observers_, | 93 FOR_EACH_OBSERVER(ExtensionShelfModelObserver, observers_, |
92 ToolstripMoved(toolstrip.host, index, to_index)); | 94 ToolstripMoved(toolstrip.host, index, to_index)); |
93 | 95 |
94 UpdatePrefs(); | 96 UpdatePrefs(); |
95 } | 97 } |
96 | 98 |
97 int ExtensionShelfModel::IndexOfToolstrip(ExtensionHost* toolstrip) { | 99 int ExtensionShelfModel::IndexOfHost(ExtensionHost* host) { |
98 ExtensionToolstrips::iterator i; | 100 for (iterator i = toolstrips_.begin(); i != toolstrips_.end(); ++i) { |
99 for (i = toolstrips_.begin(); i != toolstrips_.end(); ++i) { | 101 if (i->host == host) |
100 if (i->host == toolstrip) | |
101 return i - toolstrips_.begin(); | 102 return i - toolstrips_.begin(); |
102 } | 103 } |
103 return -1; | 104 return -1; |
104 } | 105 } |
105 | 106 |
106 ExtensionHost* ExtensionShelfModel::ToolstripAt(int index) { | 107 ExtensionShelfModel::iterator ExtensionShelfModel::ToolstripForHost( |
107 DCHECK(index >= 0); | 108 ExtensionHost* host) { |
108 return toolstrips_[index].host; | 109 for (iterator i = toolstrips_.begin(); i != toolstrips_.end(); ++i) { |
| 110 if (i->host == host) |
| 111 return i; |
| 112 } |
| 113 return toolstrips_.end(); |
109 } | 114 } |
110 | 115 |
111 Extension::ToolstripInfo& ExtensionShelfModel::ToolstripInfoAt(int index) { | 116 const ExtensionShelfModel::ToolstripItem& ExtensionShelfModel::ToolstripAt( |
| 117 int index) { |
112 DCHECK(index >= 0); | 118 DCHECK(index >= 0); |
113 return toolstrips_[index].info; | 119 return toolstrips_[index]; |
114 } | |
115 | |
116 void* ExtensionShelfModel::ToolstripDataAt(int index) { | |
117 DCHECK(index >= 0); | |
118 return toolstrips_[index].data; | |
119 } | 120 } |
120 | 121 |
121 void ExtensionShelfModel::SetToolstripDataAt(int index, void* data) { | 122 void ExtensionShelfModel::SetToolstripDataAt(int index, void* data) { |
122 DCHECK(index >= 0); | 123 DCHECK(index >= 0); |
123 toolstrips_[index].data = data; | 124 toolstrips_[index].data = data; |
124 } | 125 } |
125 | 126 |
| 127 void ExtensionShelfModel::ExpandToolstrip(iterator toolstrip, |
| 128 const GURL& url, int height) { |
| 129 if (toolstrip == end()) |
| 130 return; |
| 131 toolstrip->height = height; |
| 132 toolstrip->url = url; |
| 133 FOR_EACH_OBSERVER(ExtensionShelfModelObserver, observers_, |
| 134 ToolstripChanged(toolstrip)); |
| 135 } |
| 136 |
| 137 void ExtensionShelfModel::CollapseToolstrip(iterator toolstrip, |
| 138 const GURL& url) { |
| 139 if (toolstrip == end()) |
| 140 return; |
| 141 toolstrip->height = 0; |
| 142 toolstrip->url = url; |
| 143 FOR_EACH_OBSERVER(ExtensionShelfModelObserver, observers_, |
| 144 ToolstripChanged(toolstrip)); |
| 145 } |
| 146 |
126 void ExtensionShelfModel::Observe(NotificationType type, | 147 void ExtensionShelfModel::Observe(NotificationType type, |
127 const NotificationSource& source, | 148 const NotificationSource& source, |
128 const NotificationDetails& details) { | 149 const NotificationDetails& details) { |
129 switch (type.value) { | 150 switch (type.value) { |
130 case NotificationType::EXTENSIONS_LOADED: | 151 case NotificationType::EXTENSIONS_LOADED: |
131 if (ready_) | 152 if (ready_) |
132 AddExtensions(Details<ExtensionList>(details).ptr()); | 153 AddExtensions(Details<ExtensionList>(details).ptr()); |
133 break; | 154 break; |
134 case NotificationType::EXTENSION_UNLOADED: | 155 case NotificationType::EXTENSION_UNLOADED: |
135 RemoveExtension(Details<Extension>(details).ptr()); | 156 RemoveExtension(Details<Extension>(details).ptr()); |
136 break; | 157 break; |
137 case NotificationType::EXTENSIONS_READY: | 158 case NotificationType::EXTENSIONS_READY: |
138 if (browser_->profile()->GetExtensionsService()) { | 159 if (browser_->profile()->GetExtensionsService()) { |
139 AddExtensions(browser_->profile()->GetExtensionsService()->extensions())
; | 160 AddExtensions( |
| 161 browser_->profile()->GetExtensionsService()->extensions()); |
140 SortToolstrips(); | 162 SortToolstrips(); |
141 } | 163 } |
142 ready_ = true; | 164 ready_ = true; |
143 break; | 165 break; |
144 case NotificationType::EXTENSION_SHELF_MODEL_CHANGED: | 166 case NotificationType::EXTENSION_SHELF_MODEL_CHANGED: |
145 // Ignore changes that this model originated. | 167 // Ignore changes that this model originated. |
146 if (Details<ExtensionShelfModel>(details).ptr() != this) | 168 if (Details<ExtensionShelfModel>(details).ptr() != this) |
147 SortToolstrips(); | 169 SortToolstrips(); |
148 break; | 170 break; |
149 default: | 171 default: |
(...skipping 10 matching lines...) Expand all Loading... |
160 return; | 182 return; |
161 | 183 |
162 for (std::vector<Extension::ToolstripInfo>::const_iterator toolstrip = | 184 for (std::vector<Extension::ToolstripInfo>::const_iterator toolstrip = |
163 extension->toolstrips().begin(); | 185 extension->toolstrips().begin(); |
164 toolstrip != extension->toolstrips().end(); ++toolstrip) { | 186 toolstrip != extension->toolstrips().end(); ++toolstrip) { |
165 GURL url = toolstrip->toolstrip; | 187 GURL url = toolstrip->toolstrip; |
166 ToolstripItem item; | 188 ToolstripItem item; |
167 item.host = manager->CreateView(extension, url, browser_); | 189 item.host = manager->CreateView(extension, url, browser_); |
168 item.info = *toolstrip; | 190 item.info = *toolstrip; |
169 item.data = NULL; | 191 item.data = NULL; |
| 192 item.height = 0; |
170 AppendToolstrip(item); | 193 AppendToolstrip(item); |
171 } | 194 } |
172 } | 195 } |
173 | 196 |
174 void ExtensionShelfModel::AddExtensions(const ExtensionList* extensions) { | 197 void ExtensionShelfModel::AddExtensions(const ExtensionList* extensions) { |
175 if (extensions->size()) { | 198 if (extensions->size()) { |
176 ExtensionList::const_iterator extension = extensions->begin(); | 199 ExtensionList::const_iterator extension = extensions->begin(); |
177 for (; extension != extensions->end(); ++extension) | 200 for (; extension != extensions->end(); ++extension) |
178 AddExtension(*extension); | 201 AddExtension(*extension); |
179 } | 202 } |
180 } | 203 } |
181 | 204 |
182 void ExtensionShelfModel::RemoveExtension(Extension* extension) { | 205 void ExtensionShelfModel::RemoveExtension(Extension* extension) { |
183 bool changed = false; | 206 bool changed = false; |
184 for (int i = count() - 1; i >= 0; --i) { | 207 for (int i = count() - 1; i >= 0; --i) { |
185 ExtensionHost* t = ToolstripAt(i); | 208 ExtensionHost* t = ToolstripAt(i).host; |
186 if (t->extension()->id() == extension->id()) { | 209 if (t->extension()->id() == extension->id()) { |
187 changed = true; | 210 changed = true; |
188 RemoveToolstripAt(i); | 211 RemoveToolstripAt(i); |
189 | 212 |
190 // There can be more than one toolstrip per extension, so we have to keep | 213 // There can be more than one toolstrip per extension, so we have to keep |
191 // looping even after finding a match. | 214 // looping even after finding a match. |
192 } | 215 } |
193 } | 216 } |
194 if (changed) | 217 if (changed) |
195 UpdatePrefs(); | 218 UpdatePrefs(); |
196 } | 219 } |
197 | 220 |
198 void ExtensionShelfModel::UpdatePrefs() { | 221 void ExtensionShelfModel::UpdatePrefs() { |
199 if (!prefs_) | 222 if (!prefs_) |
200 return; | 223 return; |
201 | 224 |
202 // It's easiest to just rebuild the list each time. | 225 // It's easiest to just rebuild the list each time. |
203 ExtensionPrefs::URLList urls; | 226 ExtensionPrefs::URLList urls; |
204 for (int i = 0; i < count(); ++i) | 227 for (int i = 0; i < count(); ++i) |
205 urls.push_back(ToolstripAt(i)->GetURL()); | 228 urls.push_back(ToolstripAt(i).host->GetURL()); |
206 prefs_->SetShelfToolstripOrder(urls); | 229 prefs_->SetShelfToolstripOrder(urls); |
207 | 230 |
208 NotificationService::current()->Notify( | 231 NotificationService::current()->Notify( |
209 NotificationType::EXTENSION_SHELF_MODEL_CHANGED, | 232 NotificationType::EXTENSION_SHELF_MODEL_CHANGED, |
210 Source<ExtensionPrefs>(prefs_), | 233 Source<ExtensionPrefs>(prefs_), |
211 Details<ExtensionShelfModel>(this)); | 234 Details<ExtensionShelfModel>(this)); |
212 } | 235 } |
213 | 236 |
214 void ExtensionShelfModel::SortToolstrips() { | 237 void ExtensionShelfModel::SortToolstrips() { |
215 ExtensionPrefs::URLList urls = prefs_->GetShelfToolstripOrder(); | 238 ExtensionPrefs::URLList urls = prefs_->GetShelfToolstripOrder(); |
216 ExtensionToolstrips copy = | 239 ToolstripList copy = |
217 ExtensionToolstrips(toolstrips_.begin(), toolstrips_.end()); | 240 ToolstripList(toolstrips_.begin(), toolstrips_.end()); |
218 toolstrips_.clear(); | 241 toolstrips_.clear(); |
219 | 242 |
220 // Go through the urls and find the matching toolstrip, re-adding it to the | 243 // Go through the urls and find the matching toolstrip, re-adding it to the |
221 // new list in the proper order. | 244 // new list in the proper order. |
222 for (size_t i = 0; i < urls.size(); ++i) { | 245 for (size_t i = 0; i < urls.size(); ++i) { |
223 GURL& url = urls[i]; | 246 GURL& url = urls[i]; |
224 for (ExtensionToolstrips::iterator toolstrip = copy.begin(); | 247 for (iterator toolstrip = copy.begin(); |
225 toolstrip != copy.end(); ++toolstrip) { | 248 toolstrip != copy.end(); ++toolstrip) { |
226 if (url == toolstrip->host->GetURL()) { | 249 if (url == toolstrip->host->GetURL()) { |
227 // Note that it's technically possible for the same URL to appear in | 250 // Note that it's technically possible for the same URL to appear in |
228 // multiple toolstrips, so we don't do any testing for uniqueness. | 251 // multiple toolstrips, so we don't do any testing for uniqueness. |
229 toolstrips_.push_back(*toolstrip); | 252 toolstrips_.push_back(*toolstrip); |
230 | 253 |
231 // Remove the toolstrip from the list so we don't have to iterate over | 254 // Remove the toolstrip from the list so we don't have to iterate over |
232 // it next time. | 255 // it next time. |
233 copy.erase(toolstrip); | 256 copy.erase(toolstrip); |
234 break; | 257 break; |
235 } | 258 } |
236 } | 259 } |
237 } | 260 } |
238 | 261 |
239 // Any toolstrips remaining in |copy| were somehow missing from the prefs, | 262 // Any toolstrips remaining in |copy| were somehow missing from the prefs, |
240 // so just append them to the end. | 263 // so just append them to the end. |
241 for (ExtensionToolstrips::iterator toolstrip = copy.begin(); | 264 for (iterator toolstrip = copy.begin(); |
242 toolstrip != copy.end(); ++toolstrip) { | 265 toolstrip != copy.end(); ++toolstrip) { |
243 toolstrips_.push_back(*toolstrip); | 266 toolstrips_.push_back(*toolstrip); |
244 } | 267 } |
245 | 268 |
246 FOR_EACH_OBSERVER(ExtensionShelfModelObserver, observers_, | 269 FOR_EACH_OBSERVER(ExtensionShelfModelObserver, observers_, |
247 ShelfModelReloaded()); | 270 ShelfModelReloaded()); |
248 } | 271 } |
OLD | NEW |