Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(451)

Unified Diff: chrome/browser/ui/ash/app_list/apps_model_builder.cc

Issue 10828151: chrome: Copy app_list files from views/ to ash/ (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/ash/app_list/apps_model_builder.cc
diff --git a/chrome/browser/ui/ash/app_list/apps_model_builder.cc b/chrome/browser/ui/ash/app_list/apps_model_builder.cc
new file mode 100644
index 0000000000000000000000000000000000000000..47a97e85e51e40e2f66c5b1dc00f16e01470be23
--- /dev/null
+++ b/chrome/browser/ui/ash/app_list/apps_model_builder.cc
@@ -0,0 +1,226 @@
+// Copyright (c) 2012 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/ui/ash/app_list/apps_model_builder.h"
+
+#include "base/i18n/case_conversion.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/browser/browser_process.h"
+#include "chrome/browser/extensions/extension_service.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/ash/app_list/extension_app_item.h"
+#include "chrome/common/chrome_notification_types.h"
+#include "chrome/common/extensions/extension.h"
+#include "content/public/browser/notification_service.h"
+#include "ui/base/l10n/l10n_util_collator.h"
+
+using extensions::Extension;
+
+namespace {
+
+const char* kSpecialApps[] = {
+ extension_misc::kChromeAppId,
+ extension_misc::kWebStoreAppId,
+};
+
+// ModelItemSortData provides a string key to sort with
+// l10n_util::StringComparator.
+struct ModelItemSortData {
+ explicit ModelItemSortData(app_list::AppListItemModel* app)
+ : app(app),
+ key(base::i18n::ToLower(UTF8ToUTF16(app->title()))) {
+ }
+
+ // Needed by StringComparator<Element> in SortVectorWithStringKey, which uses
+ // this method to get a key to sort.
+ const string16& GetStringKey() const {
+ return key;
+ }
+
+ app_list::AppListItemModel* app;
+ string16 key;
+};
+
+// Returns true if given |extension_id| is listed in kSpecialApps.
+bool IsSpecialApp(const std::string& extension_id) {
+ for (size_t i = 0; i < arraysize(kSpecialApps); ++i) {
+ if (extension_id == kSpecialApps[i])
+ return true;
+ }
+
+ return false;
+}
+
+} // namespace
+
+AppsModelBuilder::AppsModelBuilder(Profile* profile,
+ app_list::AppListModel::Apps* model)
+ : profile_(profile),
+ model_(model),
+ special_apps_count_(0) {
+ registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
+ content::Source<Profile>(profile_));
+ registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
+ content::Source<Profile>(profile_));
+ registrar_.Add(this, chrome::NOTIFICATION_APP_INSTALLED_TO_APPLIST,
+ content::Source<Profile>(profile_));
+}
+
+AppsModelBuilder::~AppsModelBuilder() {
+}
+
+void AppsModelBuilder::Build() {
+ DCHECK(model_ && model_->item_count() == 0);
+ CreateSpecialApps();
+
+ Apps apps;
+ GetExtensionApps(&apps);
+
+ SortAndPopulateModel(apps);
+ HighlightApp();
+}
+
+void AppsModelBuilder::SortAndPopulateModel(const Apps& apps) {
+ // Just return if there is nothing to populate.
+ if (apps.empty())
+ return;
+
+ // Sort apps case insensitive alphabetically.
+ std::vector<ModelItemSortData> sorted;
+ for (Apps::const_iterator it = apps.begin(); it != apps.end(); ++it)
+ sorted.push_back(ModelItemSortData(*it));
+
+ l10n_util::SortVectorWithStringKey(g_browser_process->GetApplicationLocale(),
+ &sorted,
+ false /* needs_stable_sort */);
+ for (std::vector<ModelItemSortData>::const_iterator it = sorted.begin();
+ it != sorted.end();
+ ++it) {
+ model_->Add(it->app);
+ }
+}
+
+void AppsModelBuilder::InsertItemByTitle(app_list::AppListItemModel* app) {
+ DCHECK(model_);
+
+ icu::Locale locale(g_browser_process->GetApplicationLocale().c_str());
+ UErrorCode error = U_ZERO_ERROR;
+ scoped_ptr<icu::Collator> collator(
+ icu::Collator::createInstance(locale, error));
+ if (U_FAILURE(error))
+ collator.reset();
+
+ l10n_util::StringComparator<string16> c(collator.get());
+ ModelItemSortData data(app);
+ for (size_t i = special_apps_count_; i < model_->item_count(); ++i) {
+ ModelItemSortData current(model_->GetItemAt(i));
+ if (!c(current.key, data.key)) {
+ model_->AddAt(i, app);
+ return;
+ }
+ }
+ model_->Add(app);
+}
+
+void AppsModelBuilder::GetExtensionApps(Apps* apps) {
+ DCHECK(profile_);
+ ExtensionService* service = profile_->GetExtensionService();
+ if (!service)
+ return;
+
+ // Get extension apps.
+ const ExtensionSet* extensions = service->extensions();
+ for (ExtensionSet::const_iterator app = extensions->begin();
+ app != extensions->end(); ++app) {
+ if ((*app)->ShouldDisplayInLauncher() &&
+ !IsSpecialApp((*app)->id())) {
+ apps->push_back(new ExtensionAppItem(profile_, *app));
+ }
+ }
+}
+
+void AppsModelBuilder::CreateSpecialApps() {
+ DCHECK(model_ && model_->item_count() == 0);
+
+ bool is_guest_session = Profile::IsGuestSession();
+ ExtensionService* service = profile_->GetExtensionService();
+ DCHECK(service);
+ for (size_t i = 0; i < arraysize(kSpecialApps); ++i) {
+ const std::string extension_id(kSpecialApps[i]);
+ if (is_guest_session && extension_id == extension_misc::kWebStoreAppId)
+ continue;
+
+ const Extension* extension = service->GetInstalledExtension(extension_id);
+ DCHECK(extension);
+
+ model_->Add(new ExtensionAppItem(profile_, extension));
+ }
+
+ special_apps_count_ = model_->item_count();
+}
+
+int AppsModelBuilder::FindApp(const std::string& app_id) {
+ DCHECK(model_);
+ for (size_t i = special_apps_count_; i < model_->item_count(); ++i) {
+ ChromeAppListItem* app =
+ static_cast<ChromeAppListItem*>(model_->GetItemAt(i));
+ if (app->type() != ChromeAppListItem::TYPE_APP)
+ continue;
+
+ ExtensionAppItem* extension_item = static_cast<ExtensionAppItem*>(app);
+ if (extension_item->extension_id() == app_id)
+ return i;
+ }
+
+ return -1;
+}
+
+void AppsModelBuilder::HighlightApp() {
+ DCHECK(model_);
+ if (highlight_app_id_.empty())
+ return;
+
+ int index = FindApp(highlight_app_id_);
+ if (index == -1)
+ return;
+
+ model_->GetItemAt(index)->SetHighlighted(true);
+ highlight_app_id_.clear();
+}
+
+void AppsModelBuilder::Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) {
+ switch (type) {
+ case chrome::NOTIFICATION_EXTENSION_LOADED: {
+ const Extension* extension =
+ content::Details<const Extension>(details).ptr();
+ if (!extension->ShouldDisplayInLauncher())
+ return;
+
+ if (FindApp(extension->id()) != -1)
+ return;
+
+ InsertItemByTitle(new ExtensionAppItem(profile_, extension));
+ HighlightApp();
+ break;
+ }
+ case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
+ const Extension* extension =
+ content::Details<extensions::UnloadedExtensionInfo>(
+ details)->extension;
+ int index = FindApp(extension->id());
+ if (index >= 0)
+ model_->DeleteAt(index);
+ break;
+ }
+ case chrome::NOTIFICATION_APP_INSTALLED_TO_APPLIST: {
+ highlight_app_id_ = *content::Details<const std::string>(details).ptr();
+ HighlightApp();
+ break;
+ }
+ default:
+ NOTREACHED();
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698