diff options
author | erikkay@google.com <erikkay@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-19 20:19:13 +0000 |
---|---|---|
committer | erikkay@google.com <erikkay@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-19 20:19:13 +0000 |
commit | e81dba3039c19788d9fb58038816430078db7fd9 (patch) | |
tree | e10de1c875e1a93f02d95bb6650ae7055edef5c8 /chrome/browser/extensions/extension_shelf_model.cc | |
parent | 40b5462b21d0c41ef6acc57a9da7ba5c3d44c0fe (diff) | |
download | chromium_src-e81dba3039c19788d9fb58038816430078db7fd9.zip chromium_src-e81dba3039c19788d9fb58038816430078db7fd9.tar.gz chromium_src-e81dba3039c19788d9fb58038816430078db7fd9.tar.bz2 |
part 3 of toolstrip dragging - persist the drag order
Also notify other browser windows of changes to the order.
BUG=http://code.google.com/p/chromium/issues/detail?id=12123
TEST=browser_tests.exe --gtest_filter=ExtensionShelfModelTest.*
Review URL: http://codereview.chromium.org/131114
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@18845 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions/extension_shelf_model.cc')
-rw-r--r-- | chrome/browser/extensions/extension_shelf_model.cc | 147 |
1 files changed, 119 insertions, 28 deletions
diff --git a/chrome/browser/extensions/extension_shelf_model.cc b/chrome/browser/extensions/extension_shelf_model.cc index 6cda271..70013e5 100644 --- a/chrome/browser/extensions/extension_shelf_model.cc +++ b/chrome/browser/extensions/extension_shelf_model.cc @@ -14,18 +14,31 @@ ///////////////////////////// -ExtensionShelfModel::ExtensionShelfModel(Browser* browser) : browser_(browser) { +ExtensionShelfModel::ExtensionShelfModel(Browser* browser) + : browser_(browser), ready_(false) { // Watch extensions loaded and unloaded notifications. - registrar_.Add(this, NotificationType::EXTENSIONS_LOADED, + registrar_.Add(this, NotificationType::EXTENSION_INSTALLED, NotificationService::AllSources()); registrar_.Add(this, NotificationType::EXTENSION_UNLOADED, NotificationService::AllSources()); + registrar_.Add(this, NotificationType::EXTENSIONS_LOADED, + NotificationService::AllSources()); + registrar_.Add(this, NotificationType::EXTENSIONS_READY, + NotificationService::AllSources()); // Add any already-loaded extensions now, since we missed the notification for // those. ExtensionsService* service = browser_->profile()->GetExtensionsService(); - if (service) // This can be null in unit tests. - AddExtensions(service->extensions()); + if (service) { // This can be null in unit tests. + prefs_ = browser_->profile()->GetExtensionsService()->extension_prefs(); + registrar_.Add(this, NotificationType::EXTENSION_SHELF_MODEL_CHANGED, + Source<ExtensionPrefs>(prefs_)); + ready_ = service->is_ready(); + if (ready_) { + AddExtensions(service->extensions()); + SortToolstrips(); + } + } } ExtensionShelfModel::~ExtensionShelfModel() { @@ -53,8 +66,10 @@ void ExtensionShelfModel::AppendToolstrip(ExtensionHost* toolstrip) { void ExtensionShelfModel::InsertToolstripAt(int index, ExtensionHost* toolstrip) { toolstrips_.insert(toolstrips_.begin() + index, toolstrip); - FOR_EACH_OBSERVER(ExtensionShelfModelObserver, observers_, - ToolstripInsertedAt(toolstrip, index)); + if (ready_) { + FOR_EACH_OBSERVER(ExtensionShelfModelObserver, observers_, + ToolstripInsertedAt(toolstrip, index)); + } } void ExtensionShelfModel::RemoveToolstripAt(int index) { @@ -75,10 +90,12 @@ void ExtensionShelfModel::MoveToolstripAt(int index, int to_index) { FOR_EACH_OBSERVER(ExtensionShelfModelObserver, observers_, ToolstripMoved(toolstrip, index, to_index)); + + UpdatePrefs(); } int ExtensionShelfModel::IndexOfToolstrip(ExtensionHost* toolstrip) { - ExtensionToolstripList::iterator i = + ExtensionToolstrips::iterator i = std::find(toolstrips_.begin(), toolstrips_.end(), toolstrip); if (i == toolstrips_.end()) return -1; @@ -93,49 +110,123 @@ void ExtensionShelfModel::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { switch (type.value) { - case NotificationType::EXTENSIONS_LOADED: { - const ExtensionList* extensions = Details<ExtensionList>(details).ptr(); - AddExtensions(extensions); + case NotificationType::EXTENSION_INSTALLED: + if (ready_) { + AddExtension(Details<Extension>(details).ptr()); + UpdatePrefs(); + } break; - } - case NotificationType::EXTENSION_UNLOADED: { - Extension* extension = Details<Extension>(details).ptr(); - RemoveExtension(extension); + case NotificationType::EXTENSIONS_LOADED: + if (ready_) + AddExtensions(Details<ExtensionList>(details).ptr()); + break; + case NotificationType::EXTENSION_UNLOADED: + RemoveExtension(Details<Extension>(details).ptr()); + break; + case NotificationType::EXTENSIONS_READY: + AddExtensions(browser_->profile()->GetExtensionsService()->extensions()); + SortToolstrips(); + ready_ = true; + break; + case NotificationType::EXTENSION_SHELF_MODEL_CHANGED: + // Ignore changes that this model originated. + if (Details<ExtensionShelfModel>(details).ptr() != this) + SortToolstrips(); break; - } default: DCHECK(false) << "Unhandled notification of type: " << type.value; break; } } -void ExtensionShelfModel::AddExtensions(const ExtensionList* extensions) { +void ExtensionShelfModel::AddExtension(Extension* extension) { ExtensionProcessManager* manager = browser_->profile()->GetExtensionProcessManager(); + DCHECK(manager); if (!manager) return; - for (ExtensionList::const_iterator extension = extensions->begin(); - extension != extensions->end(); ++extension) { - for (std::vector<std::string>::const_iterator toolstrip_path = - (*extension)->toolstrips().begin(); - toolstrip_path != (*extension)->toolstrips().end(); ++toolstrip_path) { - ExtensionHost* host = - manager->CreateView(*extension, - (*extension)->GetResourceURL(*toolstrip_path), - browser_); - AppendToolstrip(host); - } + for (std::vector<std::string>::const_iterator toolstrip_path = + extension->toolstrips().begin(); + toolstrip_path != extension->toolstrips().end(); ++toolstrip_path) { + GURL url = extension->GetResourceURL(*toolstrip_path); + ExtensionHost* host = manager->CreateView(extension, url, browser_); + AppendToolstrip(host); + } +} + +void ExtensionShelfModel::AddExtensions(const ExtensionList* extensions) { + if (extensions->size()) { + ExtensionList::const_iterator extension = extensions->begin(); + for (; extension != extensions->end(); ++extension) + AddExtension(*extension); } } -void ExtensionShelfModel::RemoveExtension(const Extension* extension) { +void ExtensionShelfModel::RemoveExtension(Extension* extension) { + bool changed = false; for (int i = count() - 1; i >= 0; --i) { ExtensionHost* t = ToolstripAt(i); if (t->extension()->id() == extension->id()) { + changed = true; RemoveToolstripAt(i); + // There can be more than one toolstrip per extension, so we have to keep // looping even after finding a match. } } + if (changed) + UpdatePrefs(); +} + +void ExtensionShelfModel::UpdatePrefs() { + if (!prefs_) + return; + + // It's easiest to just rebuild the list each time. + ExtensionPrefs::URLList urls; + for (int i = 0; i < count(); ++i) + urls.push_back(ToolstripAt(i)->GetURL()); + prefs_->SetShelfToolstripOrder(urls); + + NotificationService::current()->Notify( + NotificationType::EXTENSION_SHELF_MODEL_CHANGED, + Source<ExtensionPrefs>(prefs_), + Details<ExtensionShelfModel>(this)); +} + +void ExtensionShelfModel::SortToolstrips() { + ExtensionPrefs::URLList urls = prefs_->GetShelfToolstripOrder(); + ExtensionToolstrips copy = + ExtensionToolstrips(toolstrips_.begin(), toolstrips_.end()); + toolstrips_.clear(); + + // Go through the urls and find the matching toolstrip, re-adding it to the + // new list in the proper order. + for (size_t i = 0; i < urls.size(); ++i) { + GURL& url = urls[i]; + for (ExtensionToolstrips::iterator toolstrip = copy.begin(); + toolstrip != copy.end(); ++toolstrip) { + if (url == (*toolstrip)->GetURL()) { + // Note that it's technically possible for the same URL to appear in + // multiple toolstrips, so we don't do any testing for uniqueness. + toolstrips_.push_back(*toolstrip); + + // Remove the toolstrip from the list so we don't have to iterate over + // it next time. + copy.erase(toolstrip); + break; + } + } + } + + // Any toolstrips remaining in |copy| were somehow missing from the prefs, + // so just append them to the end. + for (ExtensionToolstrips::iterator toolstrip = copy.begin(); + toolstrip != copy.end(); ++toolstrip) { + toolstrips_.push_back(*toolstrip); + } + + FOR_EACH_OBSERVER(ExtensionShelfModelObserver, observers_, + ShelfModelReloaded()); } |