summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfinnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-24 16:03:23 +0000
committerfinnur@chromium.org <finnur@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-24 16:03:23 +0000
commitc0f9bf1d9efa6ce1e6442d5f5fb82ff637d6405c (patch)
tree4683feaf9970a558d064c5d19d108d24d279de21
parentaeaf2b2fa41307829e1a9ba4f51fa95ba2b54732 (diff)
downloadchromium_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.grd3
-rw-r--r--chrome/browser/extensions/extension_install_ui.cc11
-rw-r--r--chrome/browser/views/extensions/extension_installed_bubble.cc91
-rw-r--r--chrome/browser/views/extensions/extension_installed_bubble.h9
-rw-r--r--chrome/browser/views/tabs/tab_strip.cc2
-rw-r--r--views/controls/button/checkbox.cc15
-rw-r--r--views/controls/button/checkbox.h1
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);