Commit 6942cecd authored by tfarina@chromium.org's avatar tfarina@chromium.org

chrome: Copy app_list files from views/ to ash/

BUG=125846
R=ben@chromium.org

Review URL: https://chromiumcodereview.appspot.com/10828151

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@150053 0039d316-1c4b-4281-b951-d872f2087c98
parent 2b469919
...@@ -2,7 +2,14 @@ include_rules = [ ...@@ -2,7 +2,14 @@ include_rules = [
"-chrome/browser/ui/views", "-chrome/browser/ui/views",
# TODO(tfarina): Remove all these. crbug.com/125846. # TODO(tfarina): Remove all these. crbug.com/125846.
# DO NOT ADD ANY MORE ITEMS TO THE LIST BELOW! # DO NOT ADD ANY MORE ITEMS TO THE LIST BELOW!
"!chrome/browser/ui/views/ash/app_list/app_list_view_delegate.h",
"!chrome/browser/ui/views/ash/app_list/apps_model_builder.h",
"!chrome/browser/ui/views/ash/app_list/chrome_app_list_item.h",
"!chrome/browser/ui/views/ash/app_list/extension_app_item.h",
"!chrome/browser/ui/views/ash/app_list/search_builder.h",
"!chrome/browser/ui/views/ash/chrome_shell_delegate.h", "!chrome/browser/ui/views/ash/chrome_shell_delegate.h",
"!chrome/browser/ui/views/ash/extension_utils.h",
"!chrome/browser/ui/views/ash/launcher/chrome_launcher_controller.h",
"!chrome/browser/ui/views/ash/panel_view_aura.h", "!chrome/browser/ui/views/ash/panel_view_aura.h",
"!chrome/browser/ui/views/find_bar_host.h", "!chrome/browser/ui/views/find_bar_host.h",
"!chrome/browser/ui/views/frame/browser_frame.h", "!chrome/browser/ui/views/frame/browser_frame.h",
......
// 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/views/ash/app_list/app_list_view_delegate.h"
#include "ash/shell.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/views/ash/app_list/apps_model_builder.h"
#include "chrome/browser/ui/views/ash/app_list/chrome_app_list_item.h"
#include "chrome/browser/ui/views/ash/app_list/search_builder.h"
AppListViewDelegate::AppListViewDelegate() {
}
AppListViewDelegate::~AppListViewDelegate() {
}
void AppListViewDelegate::SetModel(app_list::AppListModel* model) {
if (model) {
Profile* profile = ProfileManager::GetDefaultProfileOrOffTheRecord();
apps_builder_.reset(new AppsModelBuilder(profile, model->apps()));
apps_builder_->Build();
search_builder_.reset(new SearchBuilder(profile,
model->search_box(),
model->results()));
} else {
apps_builder_.reset();
search_builder_.reset();
}
}
void AppListViewDelegate::ActivateAppListItem(
app_list::AppListItemModel* item,
int event_flags) {
static_cast<ChromeAppListItem*>(item)->Activate(event_flags);
}
void AppListViewDelegate::StartSearch() {
if (search_builder_.get())
search_builder_->StartSearch();
}
void AppListViewDelegate::StopSearch() {
if (search_builder_.get())
search_builder_->StopSearch();
}
void AppListViewDelegate::OpenSearchResult(
const app_list::SearchResult& result,
int event_flags) {
if (search_builder_.get())
search_builder_->OpenResult(result, event_flags);
}
void AppListViewDelegate::Close() {
DCHECK(ash::Shell::HasInstance());
if (ash::Shell::GetInstance()->GetAppListTargetVisibility())
ash::Shell::GetInstance()->ToggleAppList();
}
// 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.
#ifndef CHROME_BROWSER_UI_VIEWS_ASH_APP_LIST_APP_LIST_VIEW_DELEGATE_H_
#define CHROME_BROWSER_UI_VIEWS_ASH_APP_LIST_APP_LIST_VIEW_DELEGATE_H_
#include <string>
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "ui/app_list/app_list_view_delegate.h"
class AppsModelBuilder;
class SearchBuilder;
class AppListViewDelegate : public app_list::AppListViewDelegate {
public:
AppListViewDelegate();
virtual ~AppListViewDelegate();
private:
// Overridden from app_list::AppListViewDelegate:
virtual void SetModel(app_list::AppListModel* model) OVERRIDE;
virtual void ActivateAppListItem(app_list::AppListItemModel* item,
int event_flags) OVERRIDE;
virtual void StartSearch() OVERRIDE;
virtual void StopSearch() OVERRIDE;
virtual void OpenSearchResult(const app_list::SearchResult& result,
int event_flags) OVERRIDE;
virtual void Close() OVERRIDE;
scoped_ptr<AppsModelBuilder> apps_builder_;
scoped_ptr<SearchBuilder> search_builder_;
DISALLOW_COPY_AND_ASSIGN(AppListViewDelegate);
};
#endif // CHROME_BROWSER_UI_VIEWS_ASH_APP_LIST_APP_LIST_VIEW_DELEGATE_H_
// 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/views/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/views/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();
}
}
// 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.
#ifndef CHROME_BROWSER_UI_VIEWS_ASH_APP_LIST_APPS_MODEL_BUILDER_H_
#define CHROME_BROWSER_UI_VIEWS_ASH_APP_LIST_APPS_MODEL_BUILDER_H_
#include <string>
#include <vector>
#include "base/gtest_prod_util.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "ui/app_list/app_list_model.h"
class Profile;
class AppsModelBuilder : public content::NotificationObserver {
public:
AppsModelBuilder(Profile* profile, app_list::AppListModel::Apps* model);
virtual ~AppsModelBuilder();
// Populates the model.
void Build();
private:
typedef std::vector<app_list::AppListItemModel*> Apps;
FRIEND_TEST_ALL_PREFIXES(AppsModelBuilderTest, GetExtensionApps);
FRIEND_TEST_ALL_PREFIXES(AppsModelBuilderTest, SortAndPopulateModel);
FRIEND_TEST_ALL_PREFIXES(AppsModelBuilderTest, InsertItemByTitle);
void SortAndPopulateModel(const Apps& apps);
void InsertItemByTitle(app_list::AppListItemModel* app);
void GetExtensionApps(Apps* apps);
void CreateSpecialApps();
// Returns the index of the application app with |app_id| in |model_|. If
// no match is found, returns -1.
int FindApp(const std::string& app_id);
// Sets the application app with |highlight_app_id_| in |model_| as
// highlighted. If such an app is found, reset |highlight_app_id_| so that it
// is highlighted once per install notification.
void HighlightApp();
// content::NotificationObserver
virtual void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
Profile* profile_;
// Sub apps model of AppListModel that represents apps grid view.
app_list::AppListModel::Apps* model_;
// Number of special apps in the model. Special apps index should be ranged
// from [0, special_apps_count_ - 1].
int special_apps_count_;
std::string highlight_app_id_;
content::NotificationRegistrar registrar_;
DISALLOW_COPY_AND_ASSIGN(AppsModelBuilder);
};
#endif // CHROME_BROWSER_UI_VIEWS_ASH_APP_LIST_APPS_MODEL_BUILDER_H_
// 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/views/ash/app_list/apps_model_builder.h"
#include <string>
#include "base/file_path.h"
#include "base/memory/scoped_ptr.h"
#include "base/stl_util.h"
#include "chrome/browser/extensions/extension_service_unittest.h"
#include "chrome/test/base/testing_profile.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/app_list/app_list_item_model.h"
namespace {
class TestAppListItemModel : public app_list::AppListItemModel {
public:
explicit TestAppListItemModel(const std::string& title) {
SetTitle(title);
}
private:
DISALLOW_COPY_AND_ASSIGN(TestAppListItemModel);
};
// Get a string of all apps in |model| joined with ','.
std::string GetModelContent(app_list::AppListModel::Apps* model) {
std::string content;
for (size_t i = 0; i < model->item_count(); ++i) {
if (i > 0)
content += ',';
content += model->GetItemAt(i)->title();
}
return content;
}
} // namespace
class AppsModelBuilderTest : public ExtensionServiceTestBase {
public:
AppsModelBuilderTest() {}
virtual ~AppsModelBuilderTest() {}
};
TEST_F(AppsModelBuilderTest, GetExtensionApps) {
// Load "app_list" extensions test profile. The test profile has 4 extensions:
// 1 dummy extension, 2 packaged extension apps and 1 hosted extension app.
FilePath source_install_dir = data_dir_
.AppendASCII("app_list")
.AppendASCII("Extensions");
FilePath pref_path = source_install_dir
.DirName()
.AppendASCII("Preferences");
InitializeInstalledExtensionService(pref_path, source_install_dir);
service_->Init();
// There should be 4 extensions in the test profile.
const ExtensionSet* extensions = service_->extensions();
ASSERT_EQ(static_cast<size_t>(4), extensions->size());
AppsModelBuilder builder(profile_.get(), NULL);
AppsModelBuilder::Apps apps;
builder.GetExtensionApps(&apps);
// The apps list would have 3 extension apps in the profile.
EXPECT_EQ(static_cast<size_t>(3), apps.size());
EXPECT_EQ("Hosted App", apps[0]->title());
EXPECT_EQ("Packaged App 1", apps[1]->title());
EXPECT_EQ("Packaged App 2", apps[2]->title());
STLDeleteElements(&apps);
}
TEST_F(AppsModelBuilderTest, SortAndPopulateModel) {
const char* kInput[] = {
"CB", "Ca", "B", "a",
};
const char* kExpected = "a,B,Ca,CB";
scoped_ptr<app_list::AppListModel::Apps> model(
new app_list::AppListModel::Apps);
AppsModelBuilder::Apps apps;
for (size_t i = 0; i < arraysize(kInput); ++i)
apps.push_back(new TestAppListItemModel(kInput[i]));
AppsModelBuilder builder(profile_.get(), model.get());
builder.SortAndPopulateModel(apps);
EXPECT_EQ(kExpected, GetModelContent(model.get()));
}
TEST_F(AppsModelBuilderTest, InsertItemByTitle) {
scoped_ptr<app_list::AppListModel::Apps> model(
new app_list::AppListModel::Apps);
AppsModelBuilder builder(profile_.get(), model.get());
const char* kInput[] = {
"CB", "Ca", "B", "a", "z", "D"
};
const char* kExpected = "a,B,Ca,CB,D,z";
for (size_t i = 0; i < arraysize(kInput); ++i)
builder.InsertItemByTitle(new TestAppListItemModel(kInput[i]));
EXPECT_EQ(kExpected, GetModelContent(model.get()));
}
// 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.
#ifndef CHROME_BROWSER_UI_VIEWS_ASH_APP_LIST_CHROME_APP_LIST_ITEM_H_
#define CHROME_BROWSER_UI_VIEWS_ASH_APP_LIST_CHROME_APP_LIST_ITEM_H_
#include "ui/app_list/app_list_item_model.h"
// Base class of all chrome app list items. Chrome's AppListViewDelegate assumes
// all items are derived from this class and calls Activate when an item is
// activated.
class ChromeAppListItem : public app_list::AppListItemModel {
public:
enum Type {
TYPE_APP,
TYPE_OTHER,
};
// Activates the item. |event_flags| holds flags of a mouse/keyboard event
// associated with this activation.
virtual void Activate(int event_flags) = 0;
Type type() const {
return type_;
}
protected:
explicit ChromeAppListItem(Type type) : type_(type) {}
virtual ~ChromeAppListItem() {}
private:
Type type_;
DISALLOW_COPY_AND_ASSIGN(ChromeAppListItem);
};
#endif // CHROME_BROWSER_UI_VIEWS_ASH_APP_LIST_CHROME_APP_LIST_ITEM_H_
This diff is collapsed.
// 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.
#ifndef CHROME_BROWSER_UI_VIEWS_ASH_APP_LIST_EXTENSION_APP_ITEM_H_
#define CHROME_BROWSER_UI_VIEWS_ASH_APP_LIST_EXTENSION_APP_ITEM_H_
#include <string>
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/extensions/image_loading_tracker.h"
#include "chrome/browser/ui/views/ash/app_list/chrome_app_list_item.h"
#include "ui/base/models/simple_menu_model.h"
class ExtensionResource;
class Profile;
class SkBitmap;
namespace extensions {
class Extension;
}
// ExtensionAppItem represents an extension app in app list.
class ExtensionAppItem : public ChromeAppListItem,
public ImageLoadingTracker::Observer,
public ui::SimpleMenuModel::Delegate {
public:
ExtensionAppItem(Profile* profile, const extensions::Extension* extension);
virtual ~ExtensionAppItem();
// Gets extension associated with this model. Returns NULL if extension
// no longer exists.
const extensions::Extension* GetExtension() const;
const std::string& extension_id() const {
return extension_id_;
}
private:
// Loads extension icon.
void LoadImage(const extensions::Extension* extension);
void ShowExtensionOptions();
void StartExtensionUninstall();
// Overridden from ImageLoadingTracker::Observer:
virtual void OnImageLoaded(const gfx::Image& image,
const std::string& extension_id,
int tracker_index) OVERRIDE;
// Overridden from ui::SimpleMenuModel::Delegate:
virtual bool IsItemForCommandIdDynamic(int command_id) const OVERRIDE;
virtual string16 GetLabelForCommandId(int command_id) const OVERRIDE;
virtual bool IsCommandIdChecked(int command_id) const OVERRIDE;
virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE;
virtual bool GetAcceleratorForCommandId(
int command_id,
ui::Accelerator* acclelrator) OVERRIDE;
virtual void ExecuteCommand(int command_id) OVERRIDE;
// Overridden from ChromeAppListItem:
virtual void Activate(int event_flags) OVERRIDE;
virtual ui::MenuModel* GetContextMenuModel() OVERRIDE;
Profile* profile_;
const std::string extension_id_;
scoped_ptr<ImageLoadingTracker> tracker_;
scoped_ptr<ui::SimpleMenuModel> context_menu_model_;
DISALLOW_COPY_AND_ASSIGN(ExtensionAppItem);
};
#endif // CHROME_BROWSER_UI_VIEWS_ASH_APP_LIST_EXTENSION_APP_ITEM_H_
// 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/views/ash/app_list/search_builder.h"
#include <string>
#include "base/command_line.h"
#include "chrome/browser/autocomplete/autocomplete_controller.h"
#include "chrome/browser/autocomplete/autocomplete_input.h"
#include "chrome/browser/autocomplete/autocomplete_match.h"
#include "chrome/browser/autocomplete/autocomplete_result.h"
#include "chrome/browser/autocomplete/extension_app_provider.h"
#include "chrome/browser/event_disposition.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/image_loading_tracker.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/views/ash/extension_utils.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_icon_set.h"
#include "chrome/common/url_constants.h"
#include "content/public/browser/web_contents.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "ui/app_list/app_list_switches.h"
#include "ui/app_list/search_box_model.h"
#include "ui/app_list/search_result.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
namespace {
int ACMatchStyleToTagStyle(int styles) {
int tag_styles = 0;
if (styles & ACMatchClassification::URL)
tag_styles |= app_list::SearchResult::Tag::URL;
if (styles & ACMatchClassification::MATCH)
tag_styles |= app_list::SearchResult::Tag::MATCH;
if (styles & ACMatchClassification::DIM)
tag_styles |= app_list::SearchResult::Tag::DIM;
return tag_styles;
}
// Translates ACMatchClassifications into SearchResult tags.
void ACMatchClassificationsToTags(
const string16& text,
const ACMatchClassifications& text_classes,
app_list::SearchResult::Tags* tags) {
int tag_styles = app_list::SearchResult::Tag::NONE;
size_t tag_start = 0;
for (size_t i = 0; i < text_classes.size(); ++i) {
const ACMatchClassification& text_class = text_classes[i];
// Closes current tag.
if (tag_styles != app_list::SearchResult::Tag::NONE) {
tags->push_back(app_list::SearchResult::Tag(
tag_styles, tag_start, text_class.offset));
tag_styles = app_list::SearchResult::Tag::NONE;
}
if (text_class.style == ACMatchClassification::NONE)
continue;
tag_start = text_class.offset;
tag_styles = ACMatchStyleToTagStyle(text_class.style);
}
if (tag_styles != app_list::SearchResult::Tag::NONE) {
tags->push_back(app_list::SearchResult::Tag(
tag_styles, tag_start, text.length()));
}
}
const extensions::Extension* GetExtensionByURL(Profile* profile,
const GURL& url) {
ExtensionService* service = profile->GetExtensionService();
// Need to explicitly get chrome app because it does not override new tab and
// not having a web extent to include new tab url, thus GetInstalledApp does
// not find it.
return url.spec() == chrome::kChromeUINewTabURL ?
service->extensions()->GetByID(extension_misc::kChromeAppId) :
service->GetInstalledApp(url);
}
// SearchBuildResult is an app list SearchResult built from an
// AutocompleteMatch.
class SearchBuilderResult : public app_list::SearchResult,
public ImageLoadingTracker::Observer {
public:
SearchBuilderResult(Profile* profile,
const AutocompleteMatch& match)
: profile_(profile),
match_(match) {
UpdateIcon();
UpdateTitleAndDetails();
}
const AutocompleteMatch& match() const {
return match_;
}
private:
void UpdateIcon() {
if (match_.type == AutocompleteMatch::EXTENSION_APP) {
const extensions::Extension* extension =
GetExtensionByURL(profile_, match_.destination_url);
if (extension) {
LoadExtensionIcon(extension);
return;
}
}
int resource_id = match_.starred ?
IDR_OMNIBOX_STAR : AutocompleteMatch::TypeToIcon(match_.type);
SetIcon(*ui::ResourceBundle::GetSharedInstance().GetBitmapNamed(
resource_id));
}
void LoadExtensionIcon(const extensions::Extension* extension) {
tracker_.reset(new ImageLoadingTracker(this));
// TODO(xiyuan): Fix this for HD.
tracker_->LoadImage(extension,
extension->GetIconResource(
ExtensionIconSet::EXTENSION_ICON_SMALL,
ExtensionIconSet::MATCH_BIGGER),
gfx::Size(ExtensionIconSet::EXTENSION_ICON_SMALL,
ExtensionIconSet::EXTENSION_ICON_SMALL),
ImageLoadingTracker::DONT_CACHE);
}
void UpdateTitleAndDetails() {
set_title(match_.contents);
app_list::SearchResult::Tags title_tags;
ACMatchClassificationsToTags(match_.contents,
match_.contents_class,
&title_tags);
set_title_tags(title_tags);
set_details(match_.description);
app_list::SearchResult::Tags details_tags;
ACMatchClassificationsToTags(match_.description,
match_.description_class,
&details_tags);
set_details_tags(details_tags);
}
// Overridden from ImageLoadingTracker::Observer:
virtual void OnImageLoaded(const gfx::Image& image,
const std::string& extension_id,
int tracker_index) OVERRIDE {
if (!image.IsEmpty()) {
SetIcon(*image.ToSkBitmap());
return;
}
SetIcon(profile_->GetExtensionService()->GetOmniboxPopupIcon(extension_id));
}
Profile* profile_;
AutocompleteMatch match_;
scoped_ptr<ImageLoadingTracker> tracker_;
DISALLOW_COPY_AND_ASSIGN(SearchBuilderResult);
};
} // namespace
SearchBuilder::SearchBuilder(
Profile* profile,
app_list::SearchBoxModel* search_box,
app_list::AppListModel::SearchResults* results)
: profile_(profile),
search_box_(search_box),
results_(results) {
search_box_->SetHintText(
l10n_util::GetStringUTF16(IDS_SEARCH_BOX_HINT));
search_box_->SetIcon(*ui::ResourceBundle::GetSharedInstance().
GetImageSkiaNamed(IDR_OMNIBOX_SEARCH));
if (CommandLine::ForCurrentProcess()->HasSwitch(
app_list::switches::kAppListShowAppsOnly)) {
// ExtensionAppProvider is a synchronous provider and does not really need a
// listener.
apps_provider_ = new ExtensionAppProvider(NULL, profile);
} else {
controller_.reset(new AutocompleteController(profile, this));
}
}
SearchBuilder::~SearchBuilder() {
}
void SearchBuilder::StartSearch() {
const string16& user_text = search_box_->text();
if (controller_.get()) {
// Omnibox features such as keyword selection/accepting and instant query
// are not implemented.
// TODO(xiyuan): Figure out the features that need to support here.
controller_->Start(user_text, string16(), false, false, true,
AutocompleteInput::ALL_MATCHES);
} else {
AutocompleteInput input(user_text, string16(), false, false, true,
AutocompleteInput::ALL_MATCHES);
apps_provider_->Start(input, false);
// ExtensionAppProvider is a synchronous provider and results are ready
// after returning from Start.
AutocompleteResult ac_result;
ac_result.AppendMatches(apps_provider_->matches());
ac_result.SortAndCull(input);
PopulateFromACResult(ac_result);
}
}
void SearchBuilder::StopSearch() {
if (controller_.get())
controller_->Stop(true);
else
apps_provider_->Stop(true);
}
void SearchBuilder::OpenResult(const app_list::SearchResult& result,
int event_flags) {
const SearchBuilderResult* builder_result =
static_cast<const SearchBuilderResult*>(&result);
const AutocompleteMatch& match = builder_result->match();
if (match.type == AutocompleteMatch::EXTENSION_APP) {
const extensions::Extension* extension =
GetExtensionByURL(profile_, match.destination_url);
if (extension)
extension_utils::OpenExtension(profile_, extension, event_flags);
} else {
WindowOpenDisposition disposition =
chrome::DispositionFromEventFlags(event_flags);
Browser* browser = browser::FindOrCreateTabbedBrowser(profile_);
if (disposition == CURRENT_TAB) {
// If current tab is not NTP, change disposition to NEW_FOREGROUND_TAB.
const GURL& url = chrome::GetActiveWebContents(browser) ?
chrome::GetActiveWebContents(browser)->GetURL() : GURL();
if (!url.SchemeIs(chrome::kChromeUIScheme) ||
url.host() != chrome::kChromeUINewTabHost) {
disposition = NEW_FOREGROUND_TAB;
}
}
// TODO(xiyuan): What should we do for alternate url case?
browser->OpenURL(
content::OpenURLParams(match.destination_url,
content::Referrer(),
disposition,
match.transition,
false));
}
}
void SearchBuilder::PopulateFromACResult(const AutocompleteResult& ac_result) {
results_->DeleteAll();
for (ACMatches::const_iterator it = ac_result.begin();
it != ac_result.end();
++it) {
results_->Add(new SearchBuilderResult(profile_, *it));
}
}
void SearchBuilder::OnResultChanged(bool default_match_changed) {
// TODO(xiyuan): Handle default match properly.
const AutocompleteResult& ac_result = controller_->result();
PopulateFromACResult(ac_result);
}
// 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.
#ifndef CHROME_BROWSER_UI_VIEWS_ASH_APP_LIST_SEARCH_BUILDER_H_
#define CHROME_BROWSER_UI_VIEWS_ASH_APP_LIST_SEARCH_BUILDER_H_
#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/autocomplete/autocomplete_controller_delegate.h"
#include "ui/app_list/app_list_model.h"
namespace app_list {
class SearchBoxModel;
class SearchResult;
}
class AutocompleteController;
class AutocompleteResult;
class ExtensionAppProvider;
class Profile;
// SearchBuilder creates app list search results via AutoCompleteController.
class SearchBuilder : public AutocompleteControllerDelegate {
public:
SearchBuilder(Profile* profile,
app_list::SearchBoxModel* search_box,
app_list::AppListModel::SearchResults* results);
virtual ~SearchBuilder();
void StartSearch();
void StopSearch();
void OpenResult(const app_list::SearchResult& result, int event_flags);
private:
// Populates result list from AutocompleteResult.
void PopulateFromACResult(const AutocompleteResult& result);
// AutocompleteControllerDelegate overrides:
virtual void OnResultChanged(bool default_match_changed) OVERRIDE;
Profile* profile_;
// Sub models of AppListModel that represent search box and result list.
app_list::SearchBoxModel* search_box_;
app_list::AppListModel::SearchResults* results_;
// The omnibox AutocompleteController that collects/sorts/dup-
// eliminates the results as they come in.
scoped_ptr<AutocompleteController> controller_;
// ExtensionAppProvider used for apps only mode. If apps only mode becomes the
// only mode, remove the AutocompleteController above. Otherwise, remove this.
scoped_refptr<ExtensionAppProvider> apps_provider_;
DISALLOW_COPY_AND_ASSIGN(SearchBuilder);
};
#endif // CHROME_BROWSER_UI_VIEWS_ASH_APP_LIST_SEARCH_BUILDER_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment