diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-07 22:34:31 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-07 22:34:31 +0000 |
commit | e0360f2cca48cf72be469c936783c10d037af292 (patch) | |
tree | b0fcb4f5a8de7a177af436df6bbfc7a87b6ab2d0 | |
parent | f891c9df37709735c6f188e163f57e6ee12cf25c (diff) | |
download | chromium_src-e0360f2cca48cf72be469c936783c10d037af292.zip chromium_src-e0360f2cca48cf72be469c936783c10d037af292.tar.gz chromium_src-e0360f2cca48cf72be469c936783c10d037af292.tar.bz2 |
Extensions: create a simple model for the browser action buttons toolstrip and use it on Linux.
TODO: persist the order of buttons
TODO: use the model on windows, mac
TODO: let the view change the order of buttons
My plan for persisting the order is just to write/read a simple text file to/from disk, one extension id per line. Similar to the bookmark model, except that is structured data (because they try to hold more information).
BUG=26990
Review URL: http://codereview.chromium.org/462026
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@34005 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/extensions/extension_toolbar_model.cc | 79 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_toolbar_model.h | 64 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_service.cc | 3 | ||||
-rw-r--r-- | chrome/browser/extensions/extensions_service.h | 7 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_actions_toolbar_gtk.cc | 58 | ||||
-rw-r--r-- | chrome/browser/gtk/browser_actions_toolbar_gtk.h | 16 | ||||
-rwxr-xr-x | chrome/chrome_browser.gypi | 2 |
7 files changed, 185 insertions, 44 deletions
diff --git a/chrome/browser/extensions/extension_toolbar_model.cc b/chrome/browser/extensions/extension_toolbar_model.cc new file mode 100644 index 0000000..39856cf --- /dev/null +++ b/chrome/browser/extensions/extension_toolbar_model.cc @@ -0,0 +1,79 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/extensions/extension_toolbar_model.h" + +#include "chrome/browser/extensions/extensions_service.h" +#include "chrome/common/extensions/extension.h" +#include "chrome/common/notification_service.h" + +ExtensionToolbarModel::ExtensionToolbarModel(ExtensionsService* service) + : service_(service) { + DCHECK(service_); + + registrar_.Add(this, NotificationType::EXTENSION_LOADED, + Source<Profile>(service_->profile())); + registrar_.Add(this, NotificationType::EXTENSION_UNLOADED, + Source<Profile>(service_->profile())); + registrar_.Add(this, NotificationType::EXTENSION_UNLOADED_DISABLED, + Source<Profile>(service_->profile())); + registrar_.Add(this, NotificationType::EXTENSIONS_READY, + Source<Profile>(service_->profile())); +} + +ExtensionToolbarModel::~ExtensionToolbarModel() { +} + +void ExtensionToolbarModel::AddObserver(Observer* observer) { + observers_.AddObserver(observer); +} + +void ExtensionToolbarModel::RemoveObserver(Observer* observer) { + observers_.RemoveObserver(observer); +} + +void ExtensionToolbarModel::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + if (type == NotificationType::EXTENSIONS_READY) { + for (size_t i = 0; i < service_->extensions()->size(); ++i) { + Extension* extension = service_->GetExtensionById( + service_->extensions()->at(i)->id(), false); + AddExtension(extension); + } + return; + } + + if (!service_->is_ready()) + return; + + Extension* extension = Details<Extension>(details).ptr(); + if (type == NotificationType::EXTENSION_LOADED) { + AddExtension(extension); + } else if (type == NotificationType::EXTENSION_UNLOADED || + type == NotificationType::EXTENSION_UNLOADED_DISABLED) { + RemoveExtension(extension); + } else { + NOTREACHED() << "Received unexpected notification"; + } +} + +void ExtensionToolbarModel::AddExtension(Extension* extension) { + // We only care about extensions with browser actions. + if (!extension->browser_action()) + return; + + toolitems_.push_back(extension); + FOR_EACH_OBSERVER(Observer, observers_, + BrowserActionAdded(extension, toolitems_.size() - 1)); +} + +void ExtensionToolbarModel::RemoveExtension(Extension* extension) { + ExtensionList::iterator pos = std::find(begin(), end(), extension); + if (pos != end()) { + toolitems_.erase(pos); + FOR_EACH_OBSERVER(Observer, observers_, + BrowserActionRemoved(extension)); + } +} diff --git a/chrome/browser/extensions/extension_toolbar_model.h b/chrome/browser/extensions/extension_toolbar_model.h new file mode 100644 index 0000000..d02dc0f --- /dev/null +++ b/chrome/browser/extensions/extension_toolbar_model.h @@ -0,0 +1,64 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_TOOLBAR_MODEL_H_ +#define CHROME_BROWSER_EXTENSIONS_EXTENSION_TOOLBAR_MODEL_H_ + +#include "base/observer_list.h" +#include "chrome/common/extensions/extension.h" +#include "chrome/common/notification_observer.h" +#include "chrome/common/notification_registrar.h" + +class ExtensionsService; + +// Model for the browser actions toolbar. +class ExtensionToolbarModel : public NotificationObserver { + public: + explicit ExtensionToolbarModel(ExtensionsService* service); + ~ExtensionToolbarModel(); + + // A class which is informed of changes to the model; represents the view of + // MVC. + class Observer { + public: + // An extension with a browser action button has been added, and should go + // in the toolbar at |index|. + virtual void BrowserActionAdded(Extension* extension, int index) {} + + // The browser action button for |extension| should no longer show. + virtual void BrowserActionRemoved(Extension* extension) {} + }; + + void AddObserver(Observer* observer); + void RemoveObserver(Observer* observer); + + ExtensionList::iterator begin() { + return toolitems_.begin(); + } + + ExtensionList::iterator end() { + return toolitems_.end(); + } + + private: + // NotificationObserver implementation. + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + + // Our observers. + ObserverList<Observer> observers_; + + void AddExtension(Extension* extension); + void RemoveExtension(Extension* extension); + + // Our ExtensionsService, guaranteed to outlive us. + ExtensionsService* service_; + + // Ordered list of browser action buttons. + ExtensionList toolitems_; + + NotificationRegistrar registrar_; +}; +#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_TOOLBAR_MODEL_H_ diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc index 7af9133..2ae7f5e 100644 --- a/chrome/browser/extensions/extensions_service.cc +++ b/chrome/browser/extensions/extensions_service.cc @@ -91,7 +91,8 @@ ExtensionsService::ExtensionsService(Profile* profile, install_directory_(install_directory), extensions_enabled_(true), show_extensions_prompts_(true), - ready_(false) { + ready_(false), + ALLOW_THIS_IN_INITIALIZER_LIST(toolbar_model_(this)) { // Figure out if extension installation should be enabled. if (command_line->HasSwitch(switches::kDisableExtensions)) { extensions_enabled_ = false; diff --git a/chrome/browser/extensions/extensions_service.h b/chrome/browser/extensions/extensions_service.h index 79fdc10..0492538 100644 --- a/chrome/browser/extensions/extensions_service.h +++ b/chrome/browser/extensions/extensions_service.h @@ -20,6 +20,7 @@ #include "chrome/browser/chrome_thread.h" #include "chrome/browser/extensions/extension_prefs.h" #include "chrome/browser/extensions/extension_process_manager.h" +#include "chrome/browser/extensions/extension_toolbar_model.h" #include "chrome/browser/extensions/extensions_quota_service.h" #include "chrome/browser/extensions/external_extension_provider.h" #include "chrome/browser/extensions/sandboxed_extension_unpacker.h" @@ -32,6 +33,7 @@ class Browser; class DictionaryValue; class Extension; class ExtensionsServiceBackend; +class ExtensionToolbarModel; class ExtensionUpdater; class GURL; class PrefService; @@ -213,6 +215,8 @@ class ExtensionsService // Note that this may return NULL if autoupdate is not turned on. ExtensionUpdater* updater() { return updater_.get(); } + ExtensionToolbarModel* toolbar_model() { return &toolbar_model_; } + ExtensionsQuotaService* quota_service() { return "a_service_; } // Notify the frontend that there was an error loading an extension. @@ -292,6 +296,9 @@ class ExtensionsService // Our extension updater, if updates are turned on. scoped_refptr<ExtensionUpdater> updater_; + // The model that tracks extensions with BrowserAction buttons. + ExtensionToolbarModel toolbar_model_; + // Map of inspector cookies that are detached, waiting for an extension to be // reloaded. typedef std::map<std::string, int> OrphanedDevTools; diff --git a/chrome/browser/gtk/browser_actions_toolbar_gtk.cc b/chrome/browser/gtk/browser_actions_toolbar_gtk.cc index 4399923..91ea423 100644 --- a/chrome/browser/gtk/browser_actions_toolbar_gtk.cc +++ b/chrome/browser/gtk/browser_actions_toolbar_gtk.cc @@ -203,18 +203,20 @@ class BrowserActionButton : public NotificationObserver, BrowserActionsToolbarGtk::BrowserActionsToolbarGtk(Browser* browser) : browser_(browser), profile_(browser->profile()), + model_(NULL), hbox_(gtk_hbox_new(FALSE, kBrowserActionButtonPadding)) { - registrar_.Add(this, NotificationType::EXTENSION_LOADED, - Source<Profile>(profile_)); - registrar_.Add(this, NotificationType::EXTENSION_UNLOADED, - Source<Profile>(profile_)); - registrar_.Add(this, NotificationType::EXTENSION_UNLOADED_DISABLED, - Source<Profile>(profile_)); - - CreateAllButtons(); + ExtensionsService* extension_service = profile_->GetExtensionsService(); + // The |extension_service| can be NULL in Incognito. + if (extension_service) { + model_ = extension_service->toolbar_model(); + model_->AddObserver(this); + CreateAllButtons(); + } } BrowserActionsToolbarGtk::~BrowserActionsToolbarGtk() { + if (model_) + model_->RemoveObserver(this); hbox_.Destroy(); } @@ -233,38 +235,14 @@ void BrowserActionsToolbarGtk::Update() { } } -void BrowserActionsToolbarGtk::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { - Extension* extension = Details<Extension>(details).ptr(); - - if (type == NotificationType::EXTENSION_LOADED) { - CreateButtonForExtension(extension); - } else if (type == NotificationType::EXTENSION_UNLOADED || - type == NotificationType::EXTENSION_UNLOADED_DISABLED) { - RemoveButtonForExtension(extension); - } else { - NOTREACHED() << "Received unexpected notification"; - } -} - void BrowserActionsToolbarGtk::CreateAllButtons() { - ExtensionsService* extension_service = profile_->GetExtensionsService(); - if (!extension_service) // The |extension_service| can be NULL in Incognito. - return; - - for (size_t i = 0; i < extension_service->extensions()->size(); ++i) { - Extension* extension = extension_service->GetExtensionById( - extension_service->extensions()->at(i)->id(), false); - CreateButtonForExtension(extension); + for (ExtensionList::iterator iter = model_->begin(); + iter != model_->end(); ++iter) { + CreateButtonForExtension(*iter); } } void BrowserActionsToolbarGtk::CreateButtonForExtension(Extension* extension) { - // Only show extensions with browser actions. - if (!extension->browser_action()) - return; - RemoveButtonForExtension(extension); linked_ptr<BrowserActionButton> button( new BrowserActionButton(this, extension)); @@ -286,3 +264,13 @@ void BrowserActionsToolbarGtk::UpdateVisibility() { else gtk_widget_show(widget()); } + +void BrowserActionsToolbarGtk::BrowserActionAdded(Extension* extension, + int index) { + // TODO(estade): respect |index|. + CreateButtonForExtension(extension); +} + +void BrowserActionsToolbarGtk::BrowserActionRemoved(Extension* extension) { + RemoveButtonForExtension(extension); +} diff --git a/chrome/browser/gtk/browser_actions_toolbar_gtk.h b/chrome/browser/gtk/browser_actions_toolbar_gtk.h index 015b5c9..ceee599b 100644 --- a/chrome/browser/gtk/browser_actions_toolbar_gtk.h +++ b/chrome/browser/gtk/browser_actions_toolbar_gtk.h @@ -9,6 +9,7 @@ #include <string> #include "base/linked_ptr.h" +#include "chrome/browser/extensions/extension_toolbar_model.h" #include "chrome/common/notification_observer.h" #include "chrome/common/notification_registrar.h" #include "chrome/common/owned_widget_gtk.h" @@ -20,7 +21,7 @@ class Profile; typedef struct _GtkWidget GtkWidget; -class BrowserActionsToolbarGtk : public NotificationObserver { +class BrowserActionsToolbarGtk : public ExtensionToolbarModel::Observer { public: explicit BrowserActionsToolbarGtk(Browser* browser); ~BrowserActionsToolbarGtk(); @@ -37,11 +38,6 @@ class BrowserActionsToolbarGtk : public NotificationObserver { // Update the display of all buttons. void Update(); - // NotificationObserver implementation. - void Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details); - private: // Query the extensions service for all extensions with browser actions, // and create the UI for them. @@ -60,13 +56,17 @@ class BrowserActionsToolbarGtk : public NotificationObserver { // to show. void UpdateVisibility(); + // ExtensionToolbarModel::Observer implementation. + virtual void BrowserActionAdded(Extension* extension, int index); + virtual void BrowserActionRemoved(Extension* extension); + Browser* browser_; Profile* profile_; - OwnedWidgetGtk hbox_; + ExtensionToolbarModel* model_; - NotificationRegistrar registrar_; + OwnedWidgetGtk hbox_; // Map from extension ID to BrowserActionButton, which is a wrapper for // a chrome button and related functionality. There should be one entry diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 5999495..8a88319 100755 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -686,6 +686,8 @@ 'browser/extensions/extension_tabs_module_constants.h', 'browser/extensions/extension_test_api.cc', 'browser/extensions/extension_test_api.h', + 'browser/extensions/extension_toolbar_model.cc', + 'browser/extensions/extension_toolbar_model.h', 'browser/extensions/extension_toolstrip_api.cc', 'browser/extensions/extension_toolstrip_api.h', 'browser/extensions/extension_updater.cc', |