| 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 |