diff options
author | finnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-24 16:03:23 +0000 |
---|---|---|
committer | finnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-24 16:03:23 +0000 |
commit | c0f9bf1d9efa6ce1e6442d5f5fb82ff637d6405c (patch) | |
tree | 4683feaf9970a558d064c5d19d108d24d279de21 | |
parent | aeaf2b2fa41307829e1a9ba4f51fa95ba2b54732 (diff) | |
download | chromium_src-c0f9bf1d9efa6ce1e6442d5f5fb82ff637d6405c.zip chromium_src-c0f9bf1d9efa6ce1e6442d5f5fb82ff637d6405c.tar.gz chromium_src-c0f9bf1d9efa6ce1e6442d5f5fb82ff637d6405c.tar.bz2 |
Add a first run bubble to show after installing an extension app.
This is similar to what we show when installing a page action or
browser action, albeit with a slightly different text.
Also disable the install warning for extension apps, for the time
being.
And finally, in tab_strip.cc I accidentally checked in a comment,
which I had commented out during testing. It was supposed to be
on (related to my last cl).
BUG=None
TEST=Install an extension app, notice a first run bubble instead
of a installation warning. The first run bubble should have a
checkbox allowing you to create a desktop shortcut.
Review URL: http://codereview.chromium.org/1693008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@45537 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/app/generated_resources.grd | 3 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_install_ui.cc | 11 | ||||
-rw-r--r-- | chrome/browser/views/extensions/extension_installed_bubble.cc | 91 | ||||
-rw-r--r-- | chrome/browser/views/extensions/extension_installed_bubble.h | 9 | ||||
-rw-r--r-- | chrome/browser/views/tabs/tab_strip.cc | 2 | ||||
-rw-r--r-- | views/controls/button/checkbox.cc | 15 | ||||
-rw-r--r-- | views/controls/button/checkbox.h | 1 |
7 files changed, 112 insertions, 20 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index c9d30c1..2dde198 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -3458,6 +3458,9 @@ each locale. --> <message name="IDS_MANAGE_EXTENSIONS" desc="The 'Manage Extensions...' text in the context menu for when right-clicking on extension icons"> Manage extensions... </message> + <message name="IDS_EXTENSION_APP_INSTALLED_MANAGE_INFO" desc="Text displayed in the InfoBubble when an extension app is installed, with instructions on how to manage them"> + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque feugiat, magna quis vestibulum malesuada, lazy euros facilitatus nibbles, you faucibus purus lacus ac dolor! + </message> <message name="IDS_EXTENSION_INSTALLED_MANAGE_INFO" desc="Text displayed in the InfoBubble with instructions on how to find the chrome://extensions/ management page"> You can manage your installed extensions by clicking Extensions in the Tools menu. </message> diff --git a/chrome/browser/extensions/extension_install_ui.cc b/chrome/browser/extensions/extension_install_ui.cc index fa3bf46..801dee0 100644 --- a/chrome/browser/extensions/extension_install_ui.cc +++ b/chrome/browser/extensions/extension_install_ui.cc @@ -186,10 +186,8 @@ void ExtensionInstallUI::OnInstallSuccess(Extension* extension) { return; } - if (extension->GetFullLaunchURL().is_valid()) { + if (extension->GetFullLaunchURL().is_valid()) Browser::OpenApplicationTab(profile_, extension); - return; - } // GetLastActiveWithProfile will fail on the build bots. This needs to be // implemented differently if any test is created which depends on @@ -252,6 +250,13 @@ void ExtensionInstallUI::OnImageLoaded( switch (prompt_type_) { case INSTALL_PROMPT: { + if (extension_->GetFullLaunchURL().is_valid()) { + // Special case extension apps to not show the install dialog. + // TODO(finnur): http://crbug.com/42443: Don't do this for all apps. + delegate_->InstallUIProceed(false); // |create_app_shortcut|. + return; + } + NotificationService* service = NotificationService::current(); service->Notify(NotificationType::EXTENSION_WILL_SHOW_CONFIRM_DIALOG, Source<ExtensionInstallUI>(this), diff --git a/chrome/browser/views/extensions/extension_installed_bubble.cc b/chrome/browser/views/extensions/extension_installed_bubble.cc index 65fa333..61d4768 100644 --- a/chrome/browser/views/extensions/extension_installed_bubble.cc +++ b/chrome/browser/views/extensions/extension_installed_bubble.cc @@ -9,15 +9,19 @@ #include "base/message_loop.h" #include "chrome/browser/browser.h" #include "chrome/browser/browser_window.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/shell_integration.h" #include "chrome/browser/views/browser_actions_container.h" #include "chrome/browser/views/frame/browser_view.h" #include "chrome/browser/views/location_bar_view.h" #include "chrome/browser/views/toolbar_view.h" +#include "chrome/browser/web_applications/web_app.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/notification_service.h" #include "chrome/common/notification_type.h" #include "grit/generated_resources.h" #include "grit/theme_resources.h" +#include "views/controls/button/checkbox.h" #include "views/controls/button/image_button.h" #include "views/controls/label.h" #include "views/standard_layout.h" @@ -52,6 +56,8 @@ const int kAnimationWaitTime = 50; // How often we retry when waiting for browser action animation to end. const int kAnimationWaitMaxRetry = 10; +} // namespace + // InstalledBubbleContent is the content view which is placed in the // ExtensionInstalledBubble. It displays the install icon and explanatory // text about the installed extension. @@ -62,7 +68,8 @@ class InstalledBubbleContent : public views::View, ExtensionInstalledBubble::BubbleType type, SkBitmap* icon) : type_(type), - info_(NULL) { + info_(NULL), + create_shortcut_(false) { ResourceBundle& rb = ResourceBundle::GetSharedInstance(); const gfx::Font& font = rb.GetFont(ResourceBundle::BaseFont); @@ -92,8 +99,12 @@ class InstalledBubbleContent : public views::View, AddChildView(info_); } - manage_ = new views::Label(l10n_util::GetString( - IDS_EXTENSION_INSTALLED_MANAGE_INFO)); + std::wstring text; + if (type_ == ExtensionInstalledBubble::EXTENSION_APP) + text = l10n_util::GetString(IDS_EXTENSION_APP_INSTALLED_MANAGE_INFO); + else + text = l10n_util::GetString(IDS_EXTENSION_INSTALLED_MANAGE_INFO); + manage_ = new views::Label(text); manage_->SetFont(font); manage_->SetMultiLine(true); manage_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); @@ -107,12 +118,29 @@ class InstalledBubbleContent : public views::View, close_button_->SetImage(views::CustomButton::BS_PUSHED, rb.GetBitmapNamed(IDR_CLOSE_BAR_P)); AddChildView(close_button_); + + if (type_ == ExtensionInstalledBubble::EXTENSION_APP) { + create_shortcut_view_ = new views::Checkbox( + l10n_util::GetString(IDS_EXTENSION_PROMPT_CREATE_SHORTCUT)); + create_shortcut_view_->set_listener(this); + create_shortcut_view_->SetMultiLine(true); + AddChildView(create_shortcut_view_); + } } + // Whether to create a shortcut once the bubble closes. + bool create_shortcut() { return create_shortcut_;} + virtual void ButtonPressed( views::Button* sender, const views::Event& event) { - GetWidget()->Close(); + if (sender == close_button_) { + GetWidget()->Close(); + } else if (sender == create_shortcut_view_) { + create_shortcut_ = create_shortcut_view_->checked(); + } else { + NOTREACHED() << "Unknown view"; + } } private: @@ -133,6 +161,10 @@ class InstalledBubbleContent : public views::View, } height += manage_->GetHeightForWidth(kRightColumnWidth); height += kVertOuterMargin; + if (type_ == ExtensionInstalledBubble::EXTENSION_APP) { + height += create_shortcut_view_->GetHeightForWidth(kRightColumnWidth); + height += kVertInnerMargin; + } return gfx::Size(width, std::max(height, kIconSize + 2 * kVertOuterMargin)); } @@ -162,28 +194,41 @@ class InstalledBubbleContent : public views::View, manage_->SizeToFit(kRightColumnWidth); manage_->SetX(x); manage_->SetY(y); + y += manage_->height(); + y += kVertInnerMargin; + + gfx::Size sz; + if (type_ == ExtensionInstalledBubble::EXTENSION_APP) { + sz.set_height( + create_shortcut_view_->GetHeightForWidth(kRightColumnWidth)); + sz.set_width(kRightColumnWidth); + create_shortcut_view_->SetBounds(x, y, sz.width(), sz.height()); + y += create_shortcut_view_->height(); + y += kVertInnerMargin; + } x += kRightColumnWidth + 2*kPanelHorizMargin + kHorizOuterMargin - close_button_->GetPreferredSize().width(); y = kVertOuterMargin; - gfx::Size sz = close_button_->GetPreferredSize(); + sz = close_button_->GetPreferredSize(); // x-1 & y-1 is just slop to get the close button visually aligned with the // title text and bubble arrow. close_button_->SetBounds(x - 1, y - 1, sz.width(), sz.height()); -} + } ExtensionInstalledBubble::BubbleType type_; views::ImageView* icon_; views::Label* heading_; views::Label* info_; views::Label* manage_; + views::Checkbox* create_shortcut_view_; views::ImageButton* close_button_; + bool create_shortcut_; + DISALLOW_COPY_AND_ASSIGN(InstalledBubbleContent); }; -} // namespace - void ExtensionInstalledBubble::Show(Extension *extension, Browser *browser, SkBitmap icon) { new ExtensionInstalledBubble(extension, browser, icon); @@ -198,7 +243,9 @@ ExtensionInstalledBubble::ExtensionInstalledBubble(Extension *extension, animation_wait_retries_(0) { AddRef(); // Balanced in InfoBubbleClosing. - if (extension_->browser_action()) { + if (extension->GetFullLaunchURL().is_valid()) { + type_ = EXTENSION_APP; + } else if (extension_->browser_action()) { type_ = BROWSER_ACTION; } else if (extension->page_action() && !extension->page_action()->default_icon_path().empty()) { @@ -266,6 +313,11 @@ void ExtensionInstalledBubble::ShowInternal() { reference_view = location_bar_view->GetPageActionView( extension_->page_action()); DCHECK(reference_view); + } else if (type_ == EXTENSION_APP) { + TabStrip* tabstrip = browser_view->tabstrip()->AsTabStrip(); + Tab* tab = tabstrip->GetSelectedTab(); + DCHECK(tab->app()); + reference_view = tab; } // Default case. @@ -278,20 +330,35 @@ void ExtensionInstalledBubble::ShowInternal() { bounds.set_x(origin.x()); bounds.set_y(origin.y()); - views::View* bubble_content = new InstalledBubbleContent(extension_, type_, + bubble_content_ = new InstalledBubbleContent(extension_, type_, &icon_); - InfoBubble::Show(browser_view->GetWindow(), bounds, bubble_content, this); + InfoBubble::Show(browser_view->GetWindow(), bounds, bubble_content_, this); } // InfoBubbleDelegate void ExtensionInstalledBubble::InfoBubbleClosing(InfoBubble* info_bubble, bool closed_by_escape) { - if (extension_->page_action()) { + if (type_ == PAGE_ACTION) { BrowserView* browser_view = BrowserView::GetBrowserViewForNativeWindow( browser_->window()->GetNativeHandle()); browser_view->GetLocationBarView()->SetPreviewEnabledPageAction( extension_->page_action(), false); // preview_enabled + } else if (type_ == EXTENSION_APP) { + if (bubble_content_->create_shortcut()) { + ShellIntegration::ShortcutInfo shortcut_info; + shortcut_info.url = extension_->GetFullLaunchURL(); + shortcut_info.extension_id = UTF8ToUTF16(extension_->id()); + shortcut_info.title = UTF8ToUTF16(extension_->name()); + shortcut_info.description = UTF8ToUTF16(extension_->description()); + shortcut_info.favicon = icon_; + shortcut_info.create_on_desktop = true; + shortcut_info.create_in_applications_menu = false; + shortcut_info.create_in_quick_launch_bar = false; + web_app::CreateShortcut(browser_->profile()->GetPath(), shortcut_info, + NULL); + } } + Release(); // Balanced in ctor. } diff --git a/chrome/browser/views/extensions/extension_installed_bubble.h b/chrome/browser/views/extensions/extension_installed_bubble.h index 53c68e5..c49515d 100644 --- a/chrome/browser/views/extensions/extension_installed_bubble.h +++ b/chrome/browser/views/extensions/extension_installed_bubble.h @@ -13,6 +13,7 @@ class Browser; class Extension; +class InstalledBubbleContent; class SkBitmap; // Provides feedback to the user upon successful installation of an @@ -30,10 +31,11 @@ class ExtensionInstalledBubble public NotificationObserver, public base::RefCountedThreadSafe<ExtensionInstalledBubble> { public: - // The behavior and content of this InfoBubble comes in three varieties. + // The behavior and content of this InfoBubble comes in these varieties: enum BubbleType { BROWSER_ACTION, PAGE_ACTION, + EXTENSION_APP, GENERIC }; @@ -69,10 +71,11 @@ class ExtensionInstalledBubble // origin side anchor. virtual bool PreferOriginSideAnchor() { return false; } - Extension *extension_; - Browser *browser_; + Extension* extension_; + Browser* browser_; SkBitmap icon_; NotificationRegistrar registrar_; + InstalledBubbleContent* bubble_content_; BubbleType type_; // How many times we've deferred due to animations being in progress. diff --git a/chrome/browser/views/tabs/tab_strip.cc b/chrome/browser/views/tabs/tab_strip.cc index a28ff52b..e9ccb09 100644 --- a/chrome/browser/views/tabs/tab_strip.cc +++ b/chrome/browser/views/tabs/tab_strip.cc @@ -1600,7 +1600,7 @@ void TabStrip::StartMoveTabAnimation(int from_model_index, TabData data = {tab, gfx::Rect()}; tab->set_mini(model_->IsMiniTab(to_model_index)); - //tab->set_app(model_->IsAppTab(to_model_index)); + tab->set_app(model_->IsAppTab(to_model_index)); tab->SetBlocked(model_->IsTabBlocked(to_model_index)); int to_tab_data_index = ModelIndexToTabDataIndex(to_model_index); diff --git a/views/controls/button/checkbox.cc b/views/controls/button/checkbox.cc index 1fcbea3..967d5eb 100644 --- a/views/controls/button/checkbox.cc +++ b/views/controls/button/checkbox.cc @@ -72,6 +72,19 @@ gfx::Size Checkbox::GetPreferredSize() { return prefsize; } +int Checkbox::GetHeightForWidth(int w) { + if (!native_wrapper_) + return 0; + + gfx::Size prefsize = native_wrapper_->GetView()->GetPreferredSize(); + if (native_wrapper_->UsesNativeLabel()) + return prefsize.height(); + + int width = prefsize.width() + kCheckboxLabelSpacing + + kLabelFocusPaddingHorizontal * 2; + return label_->GetHeightForWidth(std::max(prefsize.height(), w - width)); +} + void Checkbox::Layout() { if (!native_wrapper_) return; @@ -162,7 +175,7 @@ bool Checkbox::GetAccessibleRole(AccessibilityTypes::Role* role) { bool Checkbox::GetAccessibleState(AccessibilityTypes::State* state) { DCHECK(state); - + *state = checked() ? AccessibilityTypes::STATE_CHECKED : 0; return true; } diff --git a/views/controls/button/checkbox.h b/views/controls/button/checkbox.h index bea240a..736c095 100644 --- a/views/controls/button/checkbox.h +++ b/views/controls/button/checkbox.h @@ -42,6 +42,7 @@ class Checkbox : public NativeButton { // Overridden from View: virtual gfx::Size GetPreferredSize(); + virtual int GetHeightForWidth(int w); virtual void Layout(); virtual void SetEnabled(bool enabled); virtual void PaintFocusBorder(gfx::Canvas* canvas); |