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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/ash/app_list/apps_model_builder.h"
6
7 #include "base/i18n/case_conversion.h"
8 #include "base/utf_string_conversions.h"
9 #include "chrome/browser/browser_process.h"
10 #include "chrome/browser/extensions/extension_service.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/ui/ash/app_list/extension_app_item.h"
13 #include "chrome/common/chrome_notification_types.h"
14 #include "chrome/common/extensions/extension.h"
15 #include "content/public/browser/notification_service.h"
16 #include "ui/base/l10n/l10n_util_collator.h"
17
18 using extensions::Extension;
19
20 namespace {
21
22 const char* kSpecialApps[] = {
23 extension_misc::kChromeAppId,
24 extension_misc::kWebStoreAppId,
25 };
26
27 // ModelItemSortData provides a string key to sort with
28 // l10n_util::StringComparator.
29 struct ModelItemSortData {
30 explicit ModelItemSortData(app_list::AppListItemModel* app)
31 : app(app),
32 key(base::i18n::ToLower(UTF8ToUTF16(app->title()))) {
33 }
34
35 // Needed by StringComparator<Element> in SortVectorWithStringKey, which uses
36 // this method to get a key to sort.
37 const string16& GetStringKey() const {
38 return key;
39 }
40
41 app_list::AppListItemModel* app;
42 string16 key;
43 };
44
45 // Returns true if given |extension_id| is listed in kSpecialApps.
46 bool IsSpecialApp(const std::string& extension_id) {
47 for (size_t i = 0; i < arraysize(kSpecialApps); ++i) {
48 if (extension_id == kSpecialApps[i])
49 return true;
50 }
51
52 return false;
53 }
54
55 } // namespace
56
57 AppsModelBuilder::AppsModelBuilder(Profile* profile,
58 app_list::AppListModel::Apps* model)
59 : profile_(profile),
60 model_(model),
61 special_apps_count_(0) {
62 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
63 content::Source<Profile>(profile_));
64 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
65 content::Source<Profile>(profile_));
66 registrar_.Add(this, chrome::NOTIFICATION_APP_INSTALLED_TO_APPLIST,
67 content::Source<Profile>(profile_));
68 }
69
70 AppsModelBuilder::~AppsModelBuilder() {
71 }
72
73 void AppsModelBuilder::Build() {
74 DCHECK(model_ && model_->item_count() == 0);
75 CreateSpecialApps();
76
77 Apps apps;
78 GetExtensionApps(&apps);
79
80 SortAndPopulateModel(apps);
81 HighlightApp();
82 }
83
84 void AppsModelBuilder::SortAndPopulateModel(const Apps& apps) {
85 // Just return if there is nothing to populate.
86 if (apps.empty())
87 return;
88
89 // Sort apps case insensitive alphabetically.
90 std::vector<ModelItemSortData> sorted;
91 for (Apps::const_iterator it = apps.begin(); it != apps.end(); ++it)
92 sorted.push_back(ModelItemSortData(*it));
93
94 l10n_util::SortVectorWithStringKey(g_browser_process->GetApplicationLocale(),
95 &sorted,
96 false /* needs_stable_sort */);
97 for (std::vector<ModelItemSortData>::const_iterator it = sorted.begin();
98 it != sorted.end();
99 ++it) {
100 model_->Add(it->app);
101 }
102 }
103
104 void AppsModelBuilder::InsertItemByTitle(app_list::AppListItemModel* app) {
105 DCHECK(model_);
106
107 icu::Locale locale(g_browser_process->GetApplicationLocale().c_str());
108 UErrorCode error = U_ZERO_ERROR;
109 scoped_ptr<icu::Collator> collator(
110 icu::Collator::createInstance(locale, error));
111 if (U_FAILURE(error))
112 collator.reset();
113
114 l10n_util::StringComparator<string16> c(collator.get());
115 ModelItemSortData data(app);
116 for (size_t i = special_apps_count_; i < model_->item_count(); ++i) {
117 ModelItemSortData current(model_->GetItemAt(i));
118 if (!c(current.key, data.key)) {
119 model_->AddAt(i, app);
120 return;
121 }
122 }
123 model_->Add(app);
124 }
125
126 void AppsModelBuilder::GetExtensionApps(Apps* apps) {
127 DCHECK(profile_);
128 ExtensionService* service = profile_->GetExtensionService();
129 if (!service)
130 return;
131
132 // Get extension apps.
133 const ExtensionSet* extensions = service->extensions();
134 for (ExtensionSet::const_iterator app = extensions->begin();
135 app != extensions->end(); ++app) {
136 if ((*app)->ShouldDisplayInLauncher() &&
137 !IsSpecialApp((*app)->id())) {
138 apps->push_back(new ExtensionAppItem(profile_, *app));
139 }
140 }
141 }
142
143 void AppsModelBuilder::CreateSpecialApps() {
144 DCHECK(model_ && model_->item_count() == 0);
145
146 bool is_guest_session = Profile::IsGuestSession();
147 ExtensionService* service = profile_->GetExtensionService();
148 DCHECK(service);
149 for (size_t i = 0; i < arraysize(kSpecialApps); ++i) {
150 const std::string extension_id(kSpecialApps[i]);
151 if (is_guest_session && extension_id == extension_misc::kWebStoreAppId)
152 continue;
153
154 const Extension* extension = service->GetInstalledExtension(extension_id);
155 DCHECK(extension);
156
157 model_->Add(new ExtensionAppItem(profile_, extension));
158 }
159
160 special_apps_count_ = model_->item_count();
161 }
162
163 int AppsModelBuilder::FindApp(const std::string& app_id) {
164 DCHECK(model_);
165 for (size_t i = special_apps_count_; i < model_->item_count(); ++i) {
166 ChromeAppListItem* app =
167 static_cast<ChromeAppListItem*>(model_->GetItemAt(i));
168 if (app->type() != ChromeAppListItem::TYPE_APP)
169 continue;
170
171 ExtensionAppItem* extension_item = static_cast<ExtensionAppItem*>(app);
172 if (extension_item->extension_id() == app_id)
173 return i;
174 }
175
176 return -1;
177 }
178
179 void AppsModelBuilder::HighlightApp() {
180 DCHECK(model_);
181 if (highlight_app_id_.empty())
182 return;
183
184 int index = FindApp(highlight_app_id_);
185 if (index == -1)
186 return;
187
188 model_->GetItemAt(index)->SetHighlighted(true);
189 highlight_app_id_.clear();
190 }
191
192 void AppsModelBuilder::Observe(int type,
193 const content::NotificationSource& source,
194 const content::NotificationDetails& details) {
195 switch (type) {
196 case chrome::NOTIFICATION_EXTENSION_LOADED: {
197 const Extension* extension =
198 content::Details<const Extension>(details).ptr();
199 if (!extension->ShouldDisplayInLauncher())
200 return;
201
202 if (FindApp(extension->id()) != -1)
203 return;
204
205 InsertItemByTitle(new ExtensionAppItem(profile_, extension));
206 HighlightApp();
207 break;
208 }
209 case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
210 const Extension* extension =
211 content::Details<extensions::UnloadedExtensionInfo>(
212 details)->extension;
213 int index = FindApp(extension->id());
214 if (index >= 0)
215 model_->DeleteAt(index);
216 break;
217 }
218 case chrome::NOTIFICATION_APP_INSTALLED_TO_APPLIST: {
219 highlight_app_id_ = *content::Details<const std::string>(details).ptr();
220 HighlightApp();
221 break;
222 }
223 default:
224 NOTREACHED();
225 }
226 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698