summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions/extension_shelf_model.cc
diff options
context:
space:
mode:
authorerikkay@google.com <erikkay@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-19 20:19:13 +0000
committererikkay@google.com <erikkay@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-19 20:19:13 +0000
commite81dba3039c19788d9fb58038816430078db7fd9 (patch)
treee10de1c875e1a93f02d95bb6650ae7055edef5c8 /chrome/browser/extensions/extension_shelf_model.cc
parent40b5462b21d0c41ef6acc57a9da7ba5c3d44c0fe (diff)
downloadchromium_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.cc147
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());
}