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

Unified Diff: chrome/browser/ui/views/web_intent_picker_views.cc

Issue 12225076: Delete most web intents code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 10 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/views/web_intent_picker_views.cc
diff --git a/chrome/browser/ui/views/web_intent_picker_views.cc b/chrome/browser/ui/views/web_intent_picker_views.cc
deleted file mode 100644
index a1e555e1c21cf993a0d21ad4c16249215a7db677..0000000000000000000000000000000000000000
--- a/chrome/browser/ui/views/web_intent_picker_views.cc
+++ /dev/null
@@ -1,1601 +0,0 @@
-// 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 <algorithm>
-#include <vector>
-
-#include "base/memory/scoped_vector.h"
-#include "base/time.h"
-#include "base/timer.h"
-#include "base/utf_string_conversions.h"
-#include "chrome/browser/download/download_util.h"
-#include "chrome/browser/tab_contents/tab_util.h"
-#include "chrome/browser/ui/browser_finder.h"
-#include "chrome/browser/ui/browser_navigator.h"
-#include "chrome/browser/ui/chrome_style.h"
-#include "chrome/browser/ui/intents/web_intent_inline_disposition_delegate.h"
-#include "chrome/browser/ui/intents/web_intent_picker.h"
-#include "chrome/browser/ui/intents/web_intent_picker_delegate.h"
-#include "chrome/browser/ui/intents/web_intent_picker_model.h"
-#include "chrome/browser/ui/intents/web_intent_picker_model_observer.h"
-#include "chrome/browser/ui/views/constrained_window_views.h"
-#include "chrome/browser/ui/views/frame/browser_view.h"
-#include "chrome/browser/ui/views/location_bar/location_icon_view.h"
-#include "chrome/browser/ui/views/toolbar_view.h"
-#include "chrome/common/extensions/extension_constants.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_contents_view.h"
-#include "grit/chromium_strings.h"
-#include "grit/generated_resources.h"
-#include "grit/google_chrome_strings.h"
-#include "grit/theme_resources.h"
-#include "grit/ui_resources.h"
-#include "ipc/ipc_message.h"
-#include "third_party/skia/include/core/SkColor.h"
-#include "ui/base/l10n/l10n_util.h"
-#include "ui/base/resource/resource_bundle.h"
-#include "ui/base/text/text_elider.h"
-#include "ui/gfx/canvas.h"
-#include "ui/gfx/image/image.h"
-#include "ui/gfx/image/image_skia_operations.h"
-#include "ui/views/border.h"
-#include "ui/views/controls/button/image_button.h"
-#include "ui/views/controls/button/text_button.h"
-#include "ui/views/controls/image_view.h"
-#include "ui/views/controls/label.h"
-#include "ui/views/controls/link.h"
-#include "ui/views/controls/link_listener.h"
-#include "ui/views/controls/separator.h"
-#include "ui/views/controls/throbber.h"
-#include "ui/views/controls/webview/webview.h"
-#include "ui/views/layout/box_layout.h"
-#include "ui/views/layout/fill_layout.h"
-#include "ui/views/layout/grid_layout.h"
-#include "ui/views/layout/layout_constants.h"
-#include "ui/views/view.h"
-#include "ui/views/widget/widget.h"
-#include "ui/views/window/dialog_delegate.h"
-#include "ui/views/window/non_client_view.h"
-
-using content::WebContents;
-using views::GridLayout;
-
-namespace {
-
-// The color used to dim disabled elements.
-const SkColor kHalfOpacityWhite = SkColorSetARGB(128, 255, 255, 255);
-
-// The color used to display an enabled label.
-const SkColor kEnabledLabelColor = SkColorSetRGB(51, 51, 51);
-
-// The color used to display an enabled link.
-const SkColor kEnabledLinkColor = SkColorSetRGB(17, 85, 204);
-
-// The color used to display a disabled link.
-const SkColor kDisabledLinkColor = SkColorSetRGB(128, 128, 128);
-
-// The time between successive throbber frames in milliseconds.
-const int kThrobberFrameTimeMs = 50;
-
-// Width of IntentView action button in pixels
-const int kButtonWidth = 130;
-
-// Minimum number of action buttons - fill up with suggestions as needed.
-const int kMinRowCount = 4;
-
-// Maximum number of action buttons - do not add suggestions to reach.
-const int kMaxRowCount = 8;
-
-// The vertical padding around the UI elements in the waiting view.
-const int kWaitingViewVerticalPadding = 40;
-
-// Enables or disables all child views of |view|.
-void EnableChildViews(views::View* view, bool enabled) {
- for (int i = 0; i < view->child_count(); ++i) {
- views::View* child = view->child_at(i);
- child->SetEnabled(enabled);
- }
-}
-
-// Create a "close" button.
-views::ImageButton* CreateCloseButton(views::ButtonListener* listener) {
- ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
- views::ImageButton* close_button = new views::ImageButton(listener);
- close_button->SetImage(views::CustomButton::STATE_NORMAL,
- rb.GetImageSkiaNamed(IDR_CLOSE_DIALOG));
- close_button->SetImage(views::CustomButton::STATE_HOVERED,
- rb.GetImageSkiaNamed(IDR_CLOSE_DIALOG_H));
- close_button->SetImage(views::CustomButton::STATE_PRESSED,
- rb.GetImageSkiaNamed(IDR_CLOSE_DIALOG_P));
- return close_button;
-}
-
-// Creates a label.
-views::Label* CreateLabel() {
- views::Label* label = new views::Label();
- label->SetEnabledColor(kEnabledLabelColor);
- label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
- return label;
-}
-
-// Creates a title-style label.
-views::Label* CreateTitleLabel() {
- views::Label* label = CreateLabel();
- label->SetFont(ui::ResourceBundle::GetSharedInstance().GetFont(
- ui::ResourceBundle::MediumFont));
- const int kLabelBuiltinTopPadding = 5;
- label->set_border(views::Border::CreateEmptyBorder(
- WebIntentPicker::kContentAreaBorder -
- chrome_style::kCloseButtonPadding -
- kLabelBuiltinTopPadding,
- 0, 0, 0));
- return label;
-}
-
-// Creates a link.
-views::Link* CreateLink() {
- views::Link* link = new views::Link();
- link->SetEnabledColor(kEnabledLinkColor);
- link->SetDisabledColor(kDisabledLinkColor);
- link->SetHorizontalAlignment(gfx::ALIGN_LEFT);
- return link;
-}
-
-// Creates a header for the inline disposition dialog.
-views::View* CreateInlineDispositionHeader(
- views::ImageView* app_icon,
- views::Label* app_title,
- views::Link* use_another_service_link) {
- views::View* header = new views::View();
- views::GridLayout* grid_layout = new views::GridLayout(header);
- const int kIconBuiltinTopPadding = 6;
- grid_layout->SetInsets(
- WebIntentPicker::kContentAreaBorder -
- chrome_style::kCloseButtonPadding -
- kIconBuiltinTopPadding,
- 0, 0, 0);
- header->SetLayoutManager(grid_layout);
- views::ColumnSet* header_cs = grid_layout->AddColumnSet(0);
- header_cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
- GridLayout::USE_PREF, 0, 0); // App icon.
- header_cs->AddPaddingColumn(0, WebIntentPicker::kIconTextPadding);
- header_cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1,
- GridLayout::USE_PREF, 0, 0); // App title.
- header_cs->AddPaddingColumn(0, views::kUnrelatedControlHorizontalSpacing);
- header_cs->AddColumn(GridLayout::TRAILING, GridLayout::CENTER, 0,
- GridLayout::USE_PREF, 0, 0); // Use another app link.
- grid_layout->StartRow(0, 0);
- grid_layout->AddView(app_icon);
- grid_layout->AddView(app_title);
- grid_layout->AddView(use_another_service_link);
- header->Layout();
- return header;
-}
-
-// Checks whether the inline disposition dialog should show the link for using
-// another service.
-bool IsUseAnotherServiceVisible(WebIntentPickerModel* model) {
- DCHECK(model);
- return model->show_use_another_service() &&
- (model->GetInstalledServiceCount() > 1 ||
- model->GetSuggestedExtensionCount());
-}
-
-
-// StarsView -------------------------------------------------------------------
-
-// A view that displays 5 stars: empty, full or half full, given a rating in
-// the range [0,5].
-class StarsView : public views::View {
- public:
- explicit StarsView(double rating);
- virtual ~StarsView();
-
- private:
- // The star rating to display, in the range [0,5].
- double rating_;
-
- DISALLOW_COPY_AND_ASSIGN(StarsView);
-};
-
-StarsView::StarsView(double rating)
- : rating_(rating) {
- const int kSpacing = 1; // Spacing between stars in pixels.
-
- ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
- SetLayoutManager(
- new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, kSpacing));
-
- for (int i = 0; i < 5; ++i) {
- views::ImageView* image = new views::ImageView();
- image->SetImage(rb.GetImageSkiaNamed(
- WebIntentPicker::GetNthStarImageIdFromCWSRating(rating, i)));
- AddChildView(image);
- }
-
- // TODO(binji): Add tooltip with text rating
- // "Average Rating: X.XX stars (YYYYY)"
- // Y = "1: Hated it, 2: Disliked it, 3: It was okay, 4: Liked it,
- // 5: Loved it"
- // Choose Y based on rounded X.
-}
-
-StarsView::~StarsView() {
-}
-
-
-// ThrobberNativeTextButton ----------------------------------------------------
-
-// A native text button that can display a throbber in place of its icon. Much
-// of the logic of this class is copied from ui/views/controls/throbber.h.
-class ThrobberNativeTextButton : public views::NativeTextButton {
- public:
- ThrobberNativeTextButton(views::ButtonListener* listener,
- const string16& text);
- virtual ~ThrobberNativeTextButton();
-
- // Start or stop the throbber.
- void StartThrobber();
- void StopThrobber();
-
- // Set the throbber bitmap to use. IDR_THROBBER is used by default.
- void SetFrames(const gfx::ImageSkia* frames);
-
- // Provide a preferred size, accomodating buttons wider than their text.
- virtual gfx::Size GetPreferredSize() OVERRIDE;
-
- // Set the width desired for this button.
- void set_preferred_width(int width) { preferred_width_ = width; }
-
- protected:
- virtual const gfx::ImageSkia& GetImageToPaint() const OVERRIDE;
-
- private:
- // The timer callback to schedule painting this view.
- void Run();
-
- // Image that contains the throbber frames.
- const gfx::ImageSkia* frames_;
-
- // The currently displayed frame, given to GetImageToPaint.
- mutable gfx::ImageSkia this_frame_;
-
- // How long one frame is displayed.
- base::TimeDelta frame_time_;
-
- // Used to schedule Run calls.
- base::RepeatingTimer<ThrobberNativeTextButton> timer_;
-
- // How many frames we have.
- int frame_count_;
-
- // Time when StartThrobber was called.
- base::TimeTicks start_time_;
-
- // Whether the throbber is shown an animating.
- bool running_;
-
- // The width this button should assume.
- int preferred_width_;
-
- DISALLOW_COPY_AND_ASSIGN(ThrobberNativeTextButton);
-};
-
-ThrobberNativeTextButton::ThrobberNativeTextButton(
- views::ButtonListener* listener, const string16& text)
- : NativeTextButton(listener, text),
- frame_time_(base::TimeDelta::FromMilliseconds(kThrobberFrameTimeMs)),
- frame_count_(0),
- running_(false),
- preferred_width_(0) {
- SetFrames(ui::ResourceBundle::GetSharedInstance().GetImageNamed(
- IDR_THROBBER).ToImageSkia());
-}
-
-ThrobberNativeTextButton::~ThrobberNativeTextButton() {
- StopThrobber();
-}
-
-void ThrobberNativeTextButton::StartThrobber() {
- if (running_)
- return;
-
- start_time_ = base::TimeTicks::Now();
- timer_.Start(FROM_HERE, frame_time_, this, &ThrobberNativeTextButton::Run);
- running_ = true;
-
- SchedulePaint();
-}
-
-void ThrobberNativeTextButton::StopThrobber() {
- if (!running_)
- return;
-
- timer_.Stop();
- running_ = false;
-}
-
-void ThrobberNativeTextButton::SetFrames(const gfx::ImageSkia* frames) {
- frames_ = frames;
- DCHECK(frames_->width() > 0 && frames_->height() > 0);
- DCHECK(frames_->width() % frames_->height() == 0);
- frame_count_ = frames_->width() / frames_->height();
- PreferredSizeChanged();
-}
-
-gfx::Size ThrobberNativeTextButton::GetPreferredSize() {
- gfx::Size size = NativeTextButton::GetPreferredSize();
- if (preferred_width_)
- size.set_width(preferred_width_);
- return size;
-}
-
-const gfx::ImageSkia& ThrobberNativeTextButton::GetImageToPaint() const {
- if (!running_)
- return NativeTextButton::GetImageToPaint();
-
- const base::TimeDelta elapsed_time = base::TimeTicks::Now() - start_time_;
- const int current_frame =
- static_cast<int>(elapsed_time / frame_time_) % frame_count_;
- const int image_size = frames_->height();
- const int image_offset = current_frame * image_size;
-
- gfx::Rect subset_rect(image_offset, 0, image_size, image_size);
- this_frame_ = gfx::ImageSkiaOperations::ExtractSubset(*frames_, subset_rect);
- return this_frame_;
-}
-
-void ThrobberNativeTextButton::Run() {
- DCHECK(running_);
-
- SchedulePaint();
-}
-
-
-// SpinnerProgressIndicator ----------------------------------------------------
-class SpinnerProgressIndicator : public views::View {
- public:
- SpinnerProgressIndicator();
- virtual ~SpinnerProgressIndicator();
-
- void SetPercentDone(int percent);
- void SetIndeterminate(bool indetereminate);
-
- // Overridden from views::View.
- virtual void Paint(gfx::Canvas* canvas) OVERRIDE;
- virtual gfx::Size GetPreferredSize() OVERRIDE;
-
- private:
- void UpdateTimer();
- int GetProgressAngle();
-
- static const int kTimerIntervalMs = 1000 / 30;
- static const int kSpinRateDegreesPerSecond = 270;
-
- int percent_done_;
- int indeterminate_;
-
- base::TimeTicks start_time_;
- base::RepeatingTimer<SpinnerProgressIndicator> timer_;
-
- DISALLOW_COPY_AND_ASSIGN(SpinnerProgressIndicator);
-};
-
-SpinnerProgressIndicator::SpinnerProgressIndicator()
- : percent_done_(0),
- indeterminate_(true) {}
-
-SpinnerProgressIndicator::~SpinnerProgressIndicator() {
-}
-
-void SpinnerProgressIndicator::SetPercentDone(int percent) {
- percent_done_ = percent;
- SchedulePaint();
- UpdateTimer();
-}
-
-void SpinnerProgressIndicator::SetIndeterminate(bool indetereminate) {
- indeterminate_ = indetereminate;
- SchedulePaint();
- UpdateTimer();
-}
-
-void SpinnerProgressIndicator::Paint(gfx::Canvas* canvas) {
- ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
- gfx::ImageSkia* fg = rb.GetImageSkiaNamed(IDR_WEB_INTENT_PROGRESS_FOREGROUND);
- gfx::ImageSkia* bg = rb.GetImageSkiaNamed(IDR_WEB_INTENT_PROGRESS_BACKGROUND);
- download_util::PaintCustomDownloadProgress(
- canvas,
- *bg,
- *fg,
- fg->width(),
- bounds(),
- GetProgressAngle(),
- indeterminate_ ? -1 : percent_done_);
-}
-
-gfx::Size SpinnerProgressIndicator::GetPreferredSize() {
- ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
- gfx::ImageSkia* fg = rb.GetImageSkiaNamed(IDR_WEB_INTENT_PROGRESS_FOREGROUND);
- return fg->size();
-}
-
-void SpinnerProgressIndicator::UpdateTimer() {
- if (!parent() || !indeterminate_) {
- timer_.Stop();
- return;
- }
-
- if (!timer_.IsRunning()) {
- start_time_ = base::TimeTicks::Now();
- timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(kTimerIntervalMs),
- this, &SpinnerProgressIndicator::SchedulePaint);
- }
-}
-
-int SpinnerProgressIndicator::GetProgressAngle() {
- if (!indeterminate_)
- return download_util::kStartAngleDegrees;
- base::TimeDelta delta = base::TimeTicks::Now() - start_time_;
- int angle = delta.InSecondsF() * kSpinRateDegreesPerSecond;
- return angle % 360;
-}
-
-
-// WaitingView ----------------------------------------------------------
-class WaitingView : public views::View {
- public:
- WaitingView(views::ButtonListener* listener, bool use_close_button);
- virtual ~WaitingView();
-
- private:
- DISALLOW_COPY_AND_ASSIGN(WaitingView);
-};
-
-WaitingView::WaitingView(views::ButtonListener* listener,
- bool use_close_button) {
- views::GridLayout* layout = new views::GridLayout(this);
- layout->set_minimum_size(gfx::Size(WebIntentPicker::kWindowMinWidth, 0));
- const int kMessageBuiltinBottomPadding = 3;
- layout->SetInsets(chrome_style::kCloseButtonPadding,
- 0,
- kWaitingViewVerticalPadding - kMessageBuiltinBottomPadding,
- 0);
- SetLayoutManager(layout);
-
- enum GridLayoutColumnSets {
- HEADER_ROW,
- CONTENT_ROW,
- };
- views::ColumnSet* header_cs = layout->AddColumnSet(HEADER_ROW);
- header_cs->AddPaddingColumn(1, 1);
- header_cs->AddColumn(GridLayout::TRAILING, GridLayout::LEADING, 0,
- GridLayout::USE_PREF, 0, 0);
- header_cs->AddPaddingColumn(
- 0, chrome_style::kCloseButtonPadding);
-
- views::ColumnSet* content_cs = layout->AddColumnSet(CONTENT_ROW);
- content_cs->AddPaddingColumn(0, views::kPanelHorizIndentation);
- content_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 1,
- GridLayout::USE_PREF, 0, 0);
- content_cs->AddPaddingColumn(0, views::kPanelHorizIndentation);
-
- // Close button
- layout->StartRow(0, HEADER_ROW);
- views::ImageButton* close_button = CreateCloseButton(listener);
- layout->AddView(close_button);
- close_button->SetVisible(use_close_button);
-
- // Throbber
- layout->AddPaddingRow(0,
- kWaitingViewVerticalPadding -
- chrome_style::kCloseButtonPadding -
- close_button->GetPreferredSize().height());
- layout->StartRow(0, CONTENT_ROW);
- SpinnerProgressIndicator* throbber = new SpinnerProgressIndicator();
- layout->AddView(throbber);
-
- // Message
- const int kMessageBuiltinTopPadding = 5;
- layout->AddPaddingRow(0,
- chrome_style::kRowPadding -
- kMessageBuiltinTopPadding);
- layout->StartRow(0, CONTENT_ROW);
- views::Label* label = CreateLabel();
- label->SetHorizontalAlignment(gfx::ALIGN_CENTER);
- label->SetText(l10n_util::GetStringUTF16(IDS_INTENT_PICKER_WAIT_FOR_CWS));
- layout->AddView(label);
-
- // Start the throbber.
- throbber->SetIndeterminate(true);
-}
-
-WaitingView::~WaitingView() {
-}
-
-
-// IntentRowView --------------------------------------------------
-
-// A view for each row in the IntentsView. It displays information
-// for both installed and suggested intent handlers.
-class IntentRowView : public views::View,
- public views::ButtonListener,
- public views::LinkListener {
- public:
- enum ActionType {
- ACTION_UNKNOWN,
- ACTION_INSTALL,
- ACTION_INVOKE
- };
-
- class Delegate {
- public:
- // Called when the user clicks the "Add to Chrome" button.
- virtual void OnExtensionInstallClicked(const std::string& extension_id) = 0;
-
- // Called when the user clicks the extension title link.
- virtual void OnExtensionLinkClicked(
- const std::string& extension_id,
- WindowOpenDisposition disposition) = 0;
-
- // Called when the action button is clicked. |type| indicates the requested
- // kind of action, and |tag| identifies the service or extension to
- // operate on.
- virtual void OnActionButtonClicked(ActionType type, size_t tag) = 0;
-
- protected:
- virtual ~Delegate() {}
- };
-
- virtual ~IntentRowView();
-
- // Creates a new view for |service| or |extension| depending on which
- // value is not NULL.
- static IntentRowView* CreateHandlerRow(
- const WebIntentPickerModel::InstalledService* service,
- const WebIntentPickerModel::SuggestedExtension* extension,
- int tag,
- IntentRowView::Delegate* delegate,
- int preferred_width);
-
- // ButtonListener implementation.
- virtual void ButtonPressed(views::Button* sender,
- const ui::Event& event) OVERRIDE;
-
- // LinkListener implementation.
- virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE;
-
- // Start an animating throbber for this row, and hide the star rating and the
- // install button.
- void StartThrobber();
-
- void MarkBusy(const std::string& extension_id);
-
- // Stop the throbber for this row, and show the star rating and the install
- // button.
- void StopThrobber();
-
- protected:
- virtual void OnEnabledChanged() OVERRIDE;
-
- virtual void PaintChildren(gfx::Canvas* canvas) OVERRIDE;
-
- private:
- IntentRowView(ActionType type, size_t tag);
-
- // Gets the proper message string associated with |type_|.
- string16 GetActionButtonMessage();
-
- // Identifier for the suggested extension displayed in this row.
- std::string extension_id_;
-
- // A delegate to respond to button presses and clicked links.
- Delegate* delegate_;
-
- // The icon of the extension.
- views::ImageView* icon_;
-
- // The title of the extension, which links to the CWS detailed description of
- // this extension.
- views::View* title_link_;
-
- // The star rating of this extension.
- StarsView* stars_;
-
- // A button to install the extension.
- ThrobberNativeTextButton* install_button_;
-
- // The type of action that is invoked from the row's button.
- ActionType type_;
-
- // A tag identifying the data associated with this row. For both installed
- // and suggested services, this is an index into the respective collections
- // on the WebIntentPickerModel.
- size_t tag_;
-
- DISALLOW_COPY_AND_ASSIGN(IntentRowView);
-};
-
-IntentRowView::IntentRowView(ActionType type, size_t tag)
- : delegate_(NULL),
- icon_(NULL),
- title_link_(NULL),
- stars_(NULL),
- install_button_(NULL),
- type_(type),
- tag_(tag) {}
-
-IntentRowView* IntentRowView::CreateHandlerRow(
- const WebIntentPickerModel::InstalledService* service,
- const WebIntentPickerModel::SuggestedExtension* extension,
- int tag,
- IntentRowView::Delegate* delegate,
- int preferred_width) {
-
- // one or the other must be set...exclusively
- DCHECK((service != NULL || extension != NULL) &&
- (service == NULL || extension == NULL));
-
-
- const string16& title = (service != NULL)
- ? service->title : extension->title;
-
- // TODO(groby): Once links are properly sized (see SuggestionRowViewLayout
- // refactor notes), can simply SetElideBehavior(views::Label::ELIDE_AT_END).
- // Note: Verify that views links do not treat empty space at the end as
- // part of the link, if this change happens.
- string16 elided_title = ui::ElideText(title, gfx::Font(),
- WebIntentPicker::kTitleLinkMaxWidth,
- ui::ELIDE_AT_END);
-
- const gfx::ImageSkia* icon = NULL;
- StarsView* stars = NULL;
- views::Label* label = NULL;
- IntentRowView* view;
- if (service != NULL) {
- view = new IntentRowView(ACTION_INVOKE, tag);
- icon = service->favicon.ToImageSkia();
- label = CreateLabel();
- label->SetText(elided_title);
- } else {
- view = new IntentRowView(ACTION_INSTALL, tag);
- view->extension_id_ = extension->id;
- icon = extension->icon.ToImageSkia();
- views::Link* link = CreateLink();
- link->SetText(elided_title);
- link->set_listener(view);
- label = link;
- stars = new StarsView(extension->average_rating);
- }
-
- view->delegate_ = delegate;
-
- views::GridLayout* grid_layout = new views::GridLayout(view);
- view->SetLayoutManager(grid_layout);
-
- views::ColumnSet* columns = grid_layout->AddColumnSet(0);
- columns->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 0,
- GridLayout::USE_PREF, 0, 0); // Icon.
- columns->AddPaddingColumn(0, WebIntentPicker::kIconTextPadding);
- columns->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1,
- GridLayout::FIXED, WebIntentPicker::kTitleLinkMaxWidth, 0);
- const int kStarRatingHorizontalSpacing = 20;
- columns->AddPaddingColumn(0, kStarRatingHorizontalSpacing);
- if (stars != NULL) {
- columns->AddColumn(GridLayout::TRAILING, GridLayout::CENTER, 0,
- GridLayout::USE_PREF, 0, 0); // Star rating.
- columns->AddPaddingColumn(0, kStarRatingHorizontalSpacing);
- }
- columns->AddColumn(GridLayout::TRAILING, GridLayout::CENTER, 0,
- GridLayout::FIXED, preferred_width, 0); // Button.
-
- grid_layout->StartRow(0, 0);
-
- view->icon_ = new views::ImageView();
- view->icon_->SetImage(icon);
- grid_layout->AddView(view->icon_);
-
- view->title_link_ = label;
- grid_layout->AddView(view->title_link_);
-
- if (stars != NULL) {
- view->stars_ = stars;
- grid_layout->AddView(view->stars_);
- }
-
- view->install_button_ = new ThrobberNativeTextButton(
- view, view->GetActionButtonMessage());
- view->install_button_->set_preferred_width(preferred_width);
- grid_layout->AddView(view->install_button_);
-
- return view;
-}
-
-IntentRowView::~IntentRowView() {}
-
-void IntentRowView::ButtonPressed(views::Button* sender,
- const ui::Event& event) {
- if (type_ == ACTION_INSTALL)
- delegate_->OnExtensionInstallClicked(extension_id_);
- else
- delegate_->OnActionButtonClicked(type_, tag_);
-}
-
-void IntentRowView::LinkClicked(views::Link* source,
- int event_flags) {
- delegate_->OnExtensionLinkClicked(
- extension_id_, ui::DispositionFromEventFlags(event_flags));
-}
-
-void IntentRowView::MarkBusy(const std::string& extension_id) {
- SetEnabled(false);
- if (extension_id == extension_id_)
- StartThrobber();
-}
-
-void IntentRowView::StartThrobber() {
- install_button_->StartThrobber();
- install_button_->SetText(string16());
-}
-
-void IntentRowView::StopThrobber() {
- install_button_->StopThrobber();
- install_button_->SetText(GetActionButtonMessage());
-}
-
-void IntentRowView::OnEnabledChanged() {
- title_link_->SetEnabled(enabled());
- if (stars_)
- stars_->SetEnabled(enabled());
- install_button_->SetEnabled(enabled());
- View::OnEnabledChanged();
- Layout();
-}
-
-void IntentRowView::PaintChildren(gfx::Canvas* canvas) {
- View::PaintChildren(canvas);
- if (!enabled())
- canvas->FillRect(GetLocalBounds(), kHalfOpacityWhite);
-}
-
-string16 IntentRowView::GetActionButtonMessage() {
- int message_id = 0;
-
- if (type_ == ACTION_INVOKE)
- message_id = IDS_INTENT_PICKER_SELECT_INTENT;
- else if (type_ == ACTION_INSTALL)
- message_id = IDS_INTENT_PICKER_INSTALL_EXTENSION;
- else
- NOTREACHED();
-
- return l10n_util::GetStringUTF16(message_id);
-}
-
-
-// IntentsView -----------------------------------------------------
-
-// A view that contains both installed services and suggested extensions
-// from the Chrome Web Store that provide an intent service matching the
-// action/type pair.
-class IntentsView : public views::View {
- public:
- IntentsView(const WebIntentPickerModel* model,
- IntentRowView::Delegate* delegate);
-
- virtual ~IntentsView();
-
- // Update the view to the new model data.
- void Update();
-
- // Show the install throbber for the row containing |extension_id|. This
- // function also hides hides and disables other buttons and links.
- void StartThrobber(const std::string& extension_id);
-
- // Hide the install throbber. This function re-enables all buttons and links.
- void StopThrobber();
-
- // Adjusts a given width to account for language-specific strings.
- int AdjustWidth(int old_width);
-
- protected:
- virtual void OnEnabledChanged() OVERRIDE;
-
- private:
- const WebIntentPickerModel* model_;
- IntentRowView::Delegate* delegate_;
-
- // Width for the action button, adjusted to be wide enough for all possible
- // strings.
- int button_width_;
-
- DISALLOW_COPY_AND_ASSIGN(IntentsView);
-};
-
-IntentsView::IntentsView(
- const WebIntentPickerModel* model,
- IntentRowView::Delegate* delegate)
- : model_(model),
- delegate_(delegate),
- button_width_(0){
- Update();
-}
-
-IntentsView::~IntentsView() {
-}
-
-void IntentsView::Update() {
- RemoveAllChildViews(true);
-
- ThrobberNativeTextButton size_helper(
- NULL, l10n_util::GetStringUTF16(IDS_INTENT_PICKER_INSTALL_EXTENSION));
- size_helper.SetText(
- l10n_util::GetStringUTF16(IDS_INTENT_PICKER_SELECT_INTENT));
- button_width_ = std::max(
- kButtonWidth, size_helper.GetPreferredSize().width());
-
- const int kAppRowVerticalSpacing = 10;
- views::BoxLayout* layout = new views::BoxLayout(views::BoxLayout::kVertical,
- 0, 0, kAppRowVerticalSpacing);
- SetLayoutManager(layout);
-
- int available_rows = kMaxRowCount;
-
- for (size_t i = 0;
- available_rows > 0 && i < model_->GetInstalledServiceCount();
- ++i, --available_rows) {
- const WebIntentPickerModel::InstalledService& service =
- model_->GetInstalledServiceAt(i);
- AddChildView(IntentRowView::CreateHandlerRow(&service, NULL, i,
- delegate_, button_width_));
- }
-
- // Only fill up with suggestions if we filled less than kMinRowCount rows.
- available_rows -= (kMaxRowCount - kMinRowCount);
-
- for (size_t i = 0;
- available_rows > 0 && i < model_->GetSuggestedExtensionCount();
- ++i, --available_rows) {
- const WebIntentPickerModel::SuggestedExtension& extension =
- model_->GetSuggestedExtensionAt(i);
- AddChildView(IntentRowView::CreateHandlerRow(NULL, &extension, i,
- delegate_, button_width_));
- }
-}
-
-void IntentsView::StartThrobber(const std::string& extension_id) {
- for (int i = 0; i < child_count(); ++i)
- static_cast<IntentRowView*>(child_at(i))->MarkBusy(extension_id);
-}
-
-void IntentsView::StopThrobber() {
- for (int i = 0; i < child_count(); ++i) {
- IntentRowView* row =
- static_cast<IntentRowView*>(child_at(i));
- row->SetEnabled(true);
- row->StopThrobber();
- }
-}
-
-int IntentsView::AdjustWidth(int old_width) {
- return old_width - kButtonWidth + button_width_;
-}
-
-void IntentsView::OnEnabledChanged() {
- EnableChildViews(this, enabled());
- View::OnEnabledChanged();
-}
-
-} // namespace
-
-
-// WebIntentPickerViews --------------------------------------------------------
-
-// Views implementation of WebIntentPicker.
-class WebIntentPickerViews : public views::ButtonListener,
- public views::WidgetDelegate,
- public views::LinkListener,
- public WebIntentPicker,
- public WebIntentPickerModelObserver,
- public IntentRowView::Delegate {
- public:
- WebIntentPickerViews(WebContents* web_contents,
- WebIntentPickerDelegate* delegate,
- WebIntentPickerModel* model);
- virtual ~WebIntentPickerViews();
-
- // views::ButtonListener implementation.
- // This method is called when the user cancels the picker dialog.
- virtual void ButtonPressed(views::Button* sender,
- const ui::Event& event) OVERRIDE;
-
- // views::WidgetDelegate implementation.
- virtual void WindowClosing() OVERRIDE;
- virtual void DeleteDelegate() OVERRIDE;
- virtual views::Widget* GetWidget() OVERRIDE;
- virtual const views::Widget* GetWidget() const OVERRIDE;
- virtual views::View* GetContentsView() OVERRIDE;
-
- // LinkListener implementation.
- virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE;
-
- // WebIntentPicker implementation.
- virtual void Close() OVERRIDE;
- virtual void SetActionString(const string16& action) OVERRIDE;
- virtual void OnExtensionInstallSuccess(const std::string& id) OVERRIDE;
- virtual void OnExtensionInstallFailure(const std::string& id) OVERRIDE;
- virtual void OnInlineDispositionAutoResize(const gfx::Size& size) OVERRIDE;
- virtual void OnPendingAsyncCompleted() OVERRIDE;
- virtual void InvalidateDelegate() OVERRIDE;
- virtual void OnInlineDispositionWebContentsLoaded(
- content::WebContents* web_contents) OVERRIDE;
-
- // WebIntentPickerModelObserver implementation.
- virtual void OnModelChanged(WebIntentPickerModel* model) OVERRIDE;
- virtual void OnFaviconChanged(WebIntentPickerModel* model,
- size_t index) OVERRIDE;
- virtual void OnExtensionIconChanged(WebIntentPickerModel* model,
- const std::string& extension_id) OVERRIDE;
- virtual void OnInlineDisposition(const string16& title,
- const GURL& url) OVERRIDE;
-
- // SuggestedExtensionsRowView::Delegate implementation.
- virtual void OnExtensionInstallClicked(
- const std::string& extension_id) OVERRIDE;
- virtual void OnExtensionLinkClicked(
- const std::string& extension_id,
- WindowOpenDisposition disposition) OVERRIDE;
- virtual void OnActionButtonClicked(
- IntentRowView::ActionType type,
- size_t tag) OVERRIDE;
-
- private:
- enum WebIntentPickerViewsState {
- INITIAL,
- WAITING,
- NO_SERVICES,
- LIST_SERVICES,
- INLINE_SERVICE,
- } state_;
-
- // Update picker contents to reflect the current state of the model.
- void UpdateContents();
-
- // Shows a spinner and notifies the user that we are waiting for information
- // from the Chrome Web Store.
- void ShowWaitingForSuggestions();
-
- // Updates the dialog with the list of available services, suggestions,
- // and a nice link to CWS to find more suggestions. This is the "Main"
- // view of the picker.
- void ShowAvailableServices();
-
- // Informs the user that there are no services available to handle
- // the intent, and that there are no suggestions from the Chrome Web Store.
- void ShowNoServicesMessage();
-
- // Restore the contents of the picker to the initial contents.
- void ResetContents();
-
- // Resize the constrained window to the size of its contents.
- void SizeToContents();
-
- // Clear the contents of the picker.
- void ClearContents();
-
- // Returns the service selection question text used in the title
- // of the picker.
- const string16 GetActionTitle();
-
- // Refresh the icon for the inline disposition service that is being
- // displayed.
- void RefreshInlineServiceIcon();
-
- // Refresh the extensions control in the picker.
- void RefreshExtensions();
-
- // A weak pointer to the WebIntentPickerDelegate to notify when the user
- // chooses a service or cancels.
- WebIntentPickerDelegate* delegate_;
-
- // A weak pointer to the picker model.
- WebIntentPickerModel* model_;
-
- // A weak pointer to the action string label.
- // Created locally, owned by Views.
- views::Label* action_label_;
-
- // A weak pointer to the intents view.
- // Created locally, owned by Views view hierarchy.
- IntentsView* extensions_;
-
- // Delegate for inline disposition tab contents.
- scoped_ptr<WebIntentInlineDispositionDelegate> inline_disposition_delegate_;
-
- // A weak pointer to the WebContents this picker is in.
- WebContents* web_contents_;
-
- // A weak pointer to the WebView that hosts the WebContents being displayed.
- // Created locally, owned by Views.
- views::WebView* webview_;
-
- // A weak pointer to the view that contains all other views in the picker.
- // Created locally, owned by Views.
- views::View* contents_;
-
- // A weak pointer to the constrained window.
- // Created locally, owned by Views.
- ConstrainedWindowViews* window_;
-
- // A weak pointer to the more suggestions link.
- // Created locally, owned by Views.
- views::Link* more_suggestions_link_;
-
- // The icon for the inline disposition service.
- views::ImageView* inline_service_icon_;
-
- // A weak pointer to the choose another service link.
- // Created locally, owned by Views.
- views::Link* choose_another_service_link_;
-
- // Weak pointer to "Waiting for CWS" display. Owned by parent view.
- WaitingView* waiting_view_;
-
- // The text for the current action.
- string16 action_text_;
-
- // Ownership of the WebContents we are displaying in the inline disposition.
- scoped_ptr<WebContents> inline_web_contents_;
-
- // Indicate if dialog should display its own close button.
- // TODO(groby): Only relevant until new WebContentsModalDialog is implemented,
- // from then on always true.
- bool use_close_button_;
-
- // Signals if the picker can be closed. False during extension install.
- bool can_close_;
-
- DISALLOW_COPY_AND_ASSIGN(WebIntentPickerViews);
-};
-
-// static
-WebIntentPicker* WebIntentPicker::Create(content::WebContents* web_contents,
- WebIntentPickerDelegate* delegate,
- WebIntentPickerModel* model) {
- return new WebIntentPickerViews(web_contents, delegate, model);
-}
-
-WebIntentPickerViews::WebIntentPickerViews(WebContents* web_contents,
- WebIntentPickerDelegate* delegate,
- WebIntentPickerModel* model)
- : state_(INITIAL),
- delegate_(delegate),
- model_(model),
- action_label_(NULL),
- extensions_(NULL),
- web_contents_(web_contents),
- webview_(new views::WebView(
- Profile::FromBrowserContext(web_contents->GetBrowserContext()))),
- window_(NULL),
- more_suggestions_link_(NULL),
- inline_service_icon_(NULL),
- choose_another_service_link_(NULL),
- waiting_view_(NULL),
- can_close_(true) {
- use_close_button_ = false;
-
- model_->set_observer(this);
- contents_ = new views::View();
- contents_->set_background(views::Background::CreateSolidBackground(
- chrome_style::GetBackgroundColor()));
-
- // Show the dialog.
- window_ = ConstrainedWindowViews::Create(web_contents, this);
- if (model_->IsInlineDisposition())
- OnInlineDisposition(string16(), model_->inline_disposition_url());
- else
- UpdateContents();
-}
-
-WebIntentPickerViews::~WebIntentPickerViews() {
- model_->set_observer(NULL);
-}
-
-void WebIntentPickerViews::ButtonPressed(views::Button* sender,
- const ui::Event& event) {
- DCHECK(delegate_);
- delegate_->OnUserCancelledPickerDialog();
-}
-
-void WebIntentPickerViews::WindowClosing() {
- if (delegate_)
- delegate_->OnClosing();
-}
-
-void WebIntentPickerViews::DeleteDelegate() {
- delete this;
-}
-
-views::Widget* WebIntentPickerViews::GetWidget() {
- return contents_->GetWidget();
-}
-
-const views::Widget* WebIntentPickerViews::GetWidget() const {
- return contents_->GetWidget();
-}
-
-views::View* WebIntentPickerViews::GetContentsView() {
- return contents_;
-}
-
-void WebIntentPickerViews::LinkClicked(views::Link* source, int event_flags) {
- DCHECK(delegate_);
- if (source == more_suggestions_link_) {
- delegate_->OnSuggestionsLinkClicked(
- ui::DispositionFromEventFlags(event_flags));
- } else if (source == choose_another_service_link_) {
- // Signal cancellation of inline disposition.
- delegate_->OnChooseAnotherService();
- ResetContents();
- } else {
- NOTREACHED();
- }
-}
-
-void WebIntentPickerViews::Close() {
- window_->CloseWebContentsModalDialog();
-}
-
-void WebIntentPickerViews::SetActionString(const string16& action) {
- action_text_ = action;
- if (action_label_) {
- action_label_->SetText(GetActionTitle());
- contents_->Layout();
- SizeToContents();
- }
-}
-
-void WebIntentPickerViews::OnExtensionInstallSuccess(const std::string& id) {
- can_close_ = true;
-}
-
-void WebIntentPickerViews::OnExtensionInstallFailure(const std::string& id) {
- extensions_->StopThrobber();
- extensions_->SetEnabled(true);
- more_suggestions_link_->SetEnabled(true);
- can_close_ = true;
- contents_->Layout();
- SizeToContents();
-
- // TODO(binji): What to display to user on failure?
-}
-
-void WebIntentPickerViews::OnInlineDispositionAutoResize(
- const gfx::Size& size) {
- webview_->SetPreferredSize(size);
- contents_->Layout();
- SizeToContents();
-}
-
-void WebIntentPickerViews::OnPendingAsyncCompleted() {
- UpdateContents();
-}
-
-void WebIntentPickerViews::InvalidateDelegate() {
- delegate_ = NULL;
-}
-
-void WebIntentPickerViews::ShowNoServicesMessage() {
- if (state_ == NO_SERVICES)
- return;
- state_ = NO_SERVICES;
-
- ClearContents();
- views::GridLayout* layout = new views::GridLayout(contents_);
- layout->set_minimum_size(gfx::Size(WebIntentPicker::kWindowMinWidth, 0));
- const int kContentBuiltinBottomPadding = 3;
- layout->SetInsets(chrome_style::kCloseButtonPadding,
- 0,
- chrome_style::kClientBottomPadding -
- kContentBuiltinBottomPadding,
- 0);
- contents_->SetLayoutManager(layout);
-
- enum GridLayoutColumnSets {
- HEADER_ROW,
- CONTENT_ROW,
- };
- views::ColumnSet* header_cs = layout->AddColumnSet(HEADER_ROW);
- header_cs->AddPaddingColumn(
- 0, chrome_style::kHorizontalPadding);
- header_cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1,
- GridLayout::USE_PREF, 0, 0); // Title
- header_cs->AddColumn(GridLayout::TRAILING, GridLayout::LEADING, 0,
- GridLayout::USE_PREF, 0, 0); // Close button
- header_cs->AddPaddingColumn(
- 0, chrome_style::kCloseButtonPadding);
-
- views::ColumnSet* content_cs = layout->AddColumnSet(CONTENT_ROW);
- content_cs->AddPaddingColumn(
- 0, chrome_style::kHorizontalPadding);
- content_cs->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1,
- GridLayout::USE_PREF, 0, 0); // Body
- content_cs->AddPaddingColumn(
- 0, chrome_style::kHorizontalPadding);
-
- // Header
- layout->StartRow(0, HEADER_ROW);
- views::Label* title = CreateTitleLabel();
- title->SetText(l10n_util::GetStringUTF16(
- IDS_INTENT_PICKER_NO_SERVICES_TITLE));
- layout->AddView(title);
-
- views::ImageButton* close_button = CreateCloseButton(this);
- layout->AddView(close_button);
- close_button->SetVisible(use_close_button_);
-
- // Content
- const int kHeaderBuiltinBottomPadding = 4;
- const int kContentBuiltinTopPadding = 5;
- layout->AddPaddingRow(0,
- chrome_style::kRowPadding -
- kHeaderBuiltinBottomPadding -
- kContentBuiltinTopPadding);
- layout->StartRow(0, CONTENT_ROW);
- views::Label* body = CreateLabel();
- body->SetMultiLine(true);
- body->SetText(l10n_util::GetStringUTF16(IDS_INTENT_PICKER_NO_SERVICES));
- layout->AddView(body);
-
- int height = contents_->GetHeightForWidth(WebIntentPicker::kWindowMinWidth);
- contents_->SetSize(gfx::Size(WebIntentPicker::kWindowMinWidth, height));
- contents_->Layout();
-}
-
-void WebIntentPickerViews::OnInlineDispositionWebContentsLoaded(
- content::WebContents* web_contents) {
- if (state_ == INLINE_SERVICE)
- return;
- state_ = INLINE_SERVICE;
-
- // Replace the picker with the inline disposition.
- ClearContents();
- views::GridLayout* grid_layout = new views::GridLayout(contents_);
- grid_layout->set_minimum_size(gfx::Size(WebIntentPicker::kWindowMinWidth, 0));
- grid_layout->SetInsets(chrome_style::kCloseButtonPadding, 0,
- chrome_style::kClientBottomPadding, 0);
- contents_->SetLayoutManager(grid_layout);
-
- enum GridLayoutColumnSets {
- HEADER_ROW,
- SEPARATOR_ROW,
- WEB_CONTENTS_ROW,
- };
- views::ColumnSet* header_cs = grid_layout->AddColumnSet(HEADER_ROW);
- header_cs->AddPaddingColumn(
- 0, chrome_style::kHorizontalPadding);
- header_cs->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1,
- GridLayout::USE_PREF, 0, 0); // Icon, title, link.
- header_cs->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing);
- header_cs->AddColumn(GridLayout::TRAILING, GridLayout::LEADING, 0,
- GridLayout::USE_PREF, 0, 0); // Close button.
- header_cs->AddPaddingColumn(
- 0, chrome_style::kCloseButtonPadding);
-
- views::ColumnSet* sep_cs = grid_layout->AddColumnSet(SEPARATOR_ROW);
- sep_cs->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1,
- GridLayout::USE_PREF, 0, 0); // Separator.
-
- views::ColumnSet* contents_cs = grid_layout->AddColumnSet(WEB_CONTENTS_ROW);
- contents_cs->AddPaddingColumn(0, 1);
- contents_cs->AddColumn(GridLayout::CENTER, GridLayout::CENTER, 1,
- GridLayout::USE_PREF, 0, 0); // Web contents.
- contents_cs->AddPaddingColumn(0, 1);
-
- // Header.
- grid_layout->StartRow(0, HEADER_ROW);
-
- const WebIntentPickerModel::InstalledService* service =
- model_->GetInstalledServiceWithURL(model_->inline_disposition_url());
-
- if (!inline_service_icon_)
- inline_service_icon_ = new views::ImageView();
- inline_service_icon_->SetImage(service->favicon.ToImageSkia());
-
- views::Label* title = CreateLabel();
- title->SetText(ui::ElideText(
- service->title, title->font(), kTitleLinkMaxWidth, ui::ELIDE_AT_END));
-
- if (!choose_another_service_link_)
- choose_another_service_link_ = CreateLink();
- choose_another_service_link_->SetText(l10n_util::GetStringUTF16(
- IDS_INTENT_PICKER_USE_ALTERNATE_SERVICE));
- choose_another_service_link_->set_listener(this);
-
- grid_layout->AddView(CreateInlineDispositionHeader(
- inline_service_icon_, title, choose_another_service_link_));
- choose_another_service_link_->SetVisible(IsUseAnotherServiceVisible(model_));
-
- views::ImageButton* close_button = CreateCloseButton(this);
- grid_layout->AddView(close_button);
- close_button->SetVisible(use_close_button_);
-
- // Separator.
- const int kHeaderBuiltinBottomPadding = 4;
- grid_layout->AddPaddingRow(0,
- chrome_style::kRowPadding -
- kHeaderBuiltinBottomPadding);
- grid_layout->StartRow(0, SEPARATOR_ROW);
- grid_layout->AddView(new views::Separator());
-
- // Inline web contents.
- const int kSeparatorBottomPadding = 3;
- grid_layout->AddPaddingRow(0, kSeparatorBottomPadding);
- grid_layout->StartRow(0, WEB_CONTENTS_ROW);
- grid_layout->AddView(webview_);
-
- contents_->Layout();
- SizeToContents();
-}
-
-void WebIntentPickerViews::OnModelChanged(WebIntentPickerModel* model) {
- if (state_ == WAITING && !model->IsWaitingForSuggestions())
- UpdateContents();
-
- if (choose_another_service_link_) {
- choose_another_service_link_->SetVisible(IsUseAnotherServiceVisible(model));
- contents_->Layout();
- SizeToContents();
- }
-
- if (extensions_)
- RefreshExtensions();
-}
-
-void WebIntentPickerViews::OnFaviconChanged(WebIntentPickerModel* model,
- size_t index) {
- // TODO(groby): Update favicons on extensions_;
- if (inline_service_icon_)
- RefreshInlineServiceIcon();
- if (extensions_)
- RefreshExtensions();
-}
-
-void WebIntentPickerViews::OnExtensionIconChanged(
- WebIntentPickerModel* model,
- const std::string& extension_id) {
- OnFaviconChanged(model, -1);
-}
-
-void WebIntentPickerViews::OnInlineDisposition(
- const string16&, const GURL& url) {
- DCHECK(delegate_);
- Profile* profile =
- Profile::FromBrowserContext(web_contents_->GetBrowserContext());
- if (!webview_)
- webview_ = new views::WebView(profile);
-
- inline_web_contents_.reset(
- delegate_->CreateWebContentsForInlineDisposition(profile, url));
-
- // Does not take ownership, so we keep a scoped_ptr
- // for the WebContents locally.
- webview_->SetWebContents(inline_web_contents_.get());
- Browser* browser = chrome::FindBrowserWithWebContents(web_contents_);
- inline_disposition_delegate_.reset(
- new WebIntentInlineDispositionDelegate(this, inline_web_contents_.get(),
- browser));
-
- inline_web_contents_->GetController().LoadURL(
- url,
- content::Referrer(),
- content::PAGE_TRANSITION_AUTO_TOPLEVEL,
- std::string());
-
- // Disable all buttons.
- // TODO(groby): Add throbber for inline dispo - see http://crbug.com/142519.
- if (extensions_)
- extensions_->SetEnabled(false);
- if (more_suggestions_link_)
- more_suggestions_link_->SetEnabled(false);
- contents_->Layout();
-}
-
-void WebIntentPickerViews::OnExtensionInstallClicked(
- const std::string& extension_id) {
- DCHECK(delegate_);
- can_close_ = false;
- extensions_->StartThrobber(extension_id);
- more_suggestions_link_->SetEnabled(false);
- contents_->Layout();
- delegate_->OnExtensionInstallRequested(extension_id);
-}
-
-void WebIntentPickerViews::OnExtensionLinkClicked(
- const std::string& extension_id,
- WindowOpenDisposition disposition) {
- DCHECK(delegate_);
- delegate_->OnExtensionLinkClicked(extension_id, disposition);
-}
-
-void WebIntentPickerViews::OnActionButtonClicked(
- IntentRowView::ActionType type, size_t tag) {
- DCHECK(delegate_);
- DCHECK_EQ(IntentRowView::ACTION_INVOKE, type);
- const WebIntentPickerModel::InstalledService& service =
- model_->GetInstalledServiceAt(tag);
- delegate_->OnServiceChosen(service.url, service.disposition,
- WebIntentPickerDelegate::kEnableDefaults);
-}
-
-void WebIntentPickerViews::UpdateContents() {
- if (model_ && model_->IsInlineDisposition())
- return;
-
- if (model_ && model_->IsWaitingForSuggestions()) {
- ShowWaitingForSuggestions();
- } else if (model_ && (model_->GetInstalledServiceCount() ||
- model_->GetSuggestedExtensionCount())) {
- ShowAvailableServices();
- } else {
- ShowNoServicesMessage();
- }
- SizeToContents();
-}
-
-void WebIntentPickerViews::ShowWaitingForSuggestions() {
- if (state_ == WAITING)
- return;
- state_ = WAITING;
- ClearContents();
- contents_->SetLayoutManager(new views::FillLayout());
- waiting_view_ = new WaitingView(this, use_close_button_);
- contents_->AddChildView(waiting_view_);
- int height = contents_->GetHeightForWidth(kWindowMinWidth);
- contents_->SetSize(gfx::Size(kWindowMinWidth, height));
- contents_->Layout();
-}
-
-const string16 WebIntentPickerViews::GetActionTitle() {
- return action_text_.empty() ?
- l10n_util::GetStringUTF16(IDS_INTENT_PICKER_CHOOSE_SERVICE) :
- action_text_;
-}
-
-void WebIntentPickerViews::ShowAvailableServices() {
- ClearContents();
- state_ = LIST_SERVICES;
- extensions_ = new IntentsView(model_, this);
- gfx::Size min_size = gfx::Size(extensions_->AdjustWidth(kWindowMinWidth), 0);
-
- views::GridLayout* grid_layout = new views::GridLayout(contents_);
- grid_layout->set_minimum_size(min_size);
- const int kIconBuiltinBottomPadding = 4;
- grid_layout->SetInsets(chrome_style::kCloseButtonPadding,
- 0,
- chrome_style::kClientBottomPadding -
- kIconBuiltinBottomPadding,
- 0);
- contents_->SetLayoutManager(grid_layout);
-
- enum GridLayoutColumnSets {
- HEADER_ROW,
- CONTENT_ROW,
- };
- views::ColumnSet* header_cs = grid_layout->AddColumnSet(HEADER_ROW);
- header_cs->AddPaddingColumn(
- 0, chrome_style::kHorizontalPadding);
- header_cs->AddColumn(GridLayout::LEADING, GridLayout::CENTER, 1,
- GridLayout::USE_PREF, 0, 0); // Action title
- header_cs->AddColumn(GridLayout::TRAILING, GridLayout::LEADING, 0,
- GridLayout::USE_PREF, 0, 0); // Close button
- header_cs->AddPaddingColumn(
- 0, chrome_style::kCloseButtonPadding);
-
- views::ColumnSet* content_cs = grid_layout->AddColumnSet(CONTENT_ROW);
- content_cs->AddPaddingColumn(
- 0, chrome_style::kHorizontalPadding);
- content_cs->AddColumn(GridLayout::FILL, GridLayout::CENTER, 1,
- GridLayout::USE_PREF, 0, 0); // Content.
- content_cs->AddPaddingColumn(
- 0, chrome_style::kHorizontalPadding);
-
- // Header.
- grid_layout->StartRow(0, HEADER_ROW);
- if (!action_label_)
- action_label_ = CreateTitleLabel();
- action_label_->SetText(GetActionTitle());
- grid_layout->AddView(action_label_);
-
- views::ImageButton* close_button = CreateCloseButton(this);
- grid_layout->AddView(close_button);
- close_button->SetVisible(use_close_button_);
-
- // Extensions.
- const int kHeaderBuiltinBottomPadding = 4;
- grid_layout->AddPaddingRow(0,
- chrome_style::kRowPadding -
- kHeaderBuiltinBottomPadding);
- grid_layout->StartRow(0, CONTENT_ROW);
- grid_layout->AddView(extensions_);
-
-
- // Row with "more suggestions" link.
- const int kIconBuiltinTopPadding = 6;
- grid_layout->AddPaddingRow(0,
- chrome_style::kRowPadding -
- kIconBuiltinTopPadding);
- grid_layout->StartRow(0, CONTENT_ROW);
- views::View* more_view = new views::View();
- more_view->SetLayoutManager(new views::BoxLayout(
- views::BoxLayout::kHorizontal, 0, 0, kIconTextPadding));
- views::ImageView* icon = new views::ImageView();
- icon->SetImage(ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
- IDR_WEBSTORE_ICON_16));
- more_view->AddChildView(icon);
- if (!more_suggestions_link_)
- more_suggestions_link_ = CreateLink();
- more_suggestions_link_->SetText(
- l10n_util::GetStringUTF16(IDS_FIND_MORE_INTENT_HANDLER_MESSAGE));
- more_suggestions_link_->set_listener(this);
- more_view->AddChildView(more_suggestions_link_);
- grid_layout->AddView(more_view, 1, 1,
- GridLayout::LEADING, GridLayout::CENTER);
-
- contents_->Layout();
-}
-
-void WebIntentPickerViews::ResetContents() {
- // Abandon both web contents and webview.
- webview_->SetWebContents(NULL);
- inline_web_contents_.reset();
- webview_ = NULL;
-
- // Re-initialize the UI.
- UpdateContents();
-
- // Restore previous state.
- if (extensions_)
- extensions_->Update();
- if (action_label_)
- action_label_->SetText(action_text_);
- contents_->Layout();
- SizeToContents();
-}
-
-void WebIntentPickerViews::SizeToContents() {
- gfx::Size client_size = contents_->GetPreferredSize();
- gfx::Rect client_bounds(client_size);
- gfx::Rect new_window_bounds = window_->non_client_view()->frame_view()->
- GetWindowBoundsForClientBounds(client_bounds);
- window_->CenterWindow(new_window_bounds.size());
-}
-
-void WebIntentPickerViews::ClearContents() {
- DCHECK(contents_);
- // The call RemoveAllChildViews(true) deletes all children of |contents|. If
- // we do not set our weak pointers to NULL, then they will continue to point
- // to where the deleted objects used to be, i.e. unitialized memory. This
- // would cause hard-to-explain crashes.
- contents_->RemoveAllChildViews(true);
- action_label_ = NULL;
- extensions_ = NULL;
- more_suggestions_link_ = NULL;
- inline_service_icon_ = NULL;
- choose_another_service_link_ = NULL;
-}
-
-void WebIntentPickerViews::RefreshInlineServiceIcon() {
- DCHECK(inline_service_icon_);
- const WebIntentPickerModel::InstalledService* inline_service =
- model_->GetInstalledServiceWithURL(model_->inline_disposition_url());
- if (inline_service)
- inline_service_icon_->SetImage(inline_service->favicon.ToImageSkia());
-}
-
-void WebIntentPickerViews::RefreshExtensions() {
- DCHECK(extensions_);
- extensions_->Update();
- contents_->Layout();
- SizeToContents();
-}

Powered by Google App Engine
This is Rietveld 408576698