summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-10 22:04:28 +0000
committeraa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-10 22:04:28 +0000
commit121cd7b957d4ed22f861a22783de788703bcaf7c (patch)
treec8a391f2c463a0321b7cb2efd61f9760fca51249
parenta850ba49a28734c8660e04c52449a3b770a04d1b (diff)
downloadchromium_src-121cd7b957d4ed22f861a22783de788703bcaf7c.zip
chromium_src-121cd7b957d4ed22f861a22783de788703bcaf7c.tar.gz
chromium_src-121cd7b957d4ed22f861a22783de788703bcaf7c.tar.bz2
Add a confirmation prompt to app uninstallation on the ntp.
The uninstall dialog used to say: [===============================x] |Confirm Uninstallation | |--------------------------------| |<b>Uninstall Foo Extension?</b> | | | |Are you sure you want to | |uninstall this extension? | | | |================================| We don't have the bottom string with the word 'app', and I realized it is somewhat extraneous anyway. So just removed it in all cases and de-bolded the text above. Looks much better. Also, fixed a bug where the icon we display in the GTK dialogs is too big by doing image resizing in ExtensionInstallUI. BUG=54874 TEST=Uninstall app and extension. Both should have a prompt, and UI layout should be the same. Review URL: http://codereview.chromium.org/3332016 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@59157 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/app/generated_resources.grd3
-rw-r--r--chrome/browser/cocoa/extension_install_prompt.mm3
-rw-r--r--chrome/browser/dom_ui/app_launcher_handler.cc40
-rw-r--r--chrome/browser/dom_ui/app_launcher_handler.h19
-rw-r--r--chrome/browser/extensions/extension_install_ui.cc14
-rw-r--r--chrome/browser/extensions/extension_install_ui.h2
-rw-r--r--chrome/browser/gtk/extension_install_prompt_gtk.cc26
-rw-r--r--chrome/browser/resources/ntp/apps.js1
-rw-r--r--chrome/browser/views/extensions/extension_install_prompt.cc119
9 files changed, 102 insertions, 125 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index af446c4..79f019d 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -3410,9 +3410,6 @@ each locale. -->
<message name="IDS_EXTENSION_UNINSTALL_PROMPT_HEADING" desc="First bold line in the content area of the extension uninstallation prompt. Asks the user if they want to uninstall a particular extension.">
Uninstall "<ph name="EXTENSION_NAME">$1<ex>Gmail Checker</ex></ph>"?
</message>
- <message name="IDS_EXTENSION_UNINSTALL_CONFIRMATION" desc="The warning you get when you are about to uninstall an extension.">
- Are you sure you want to uninstall this extension?
- </message>
<message name="IDS_EXTENSION_PROMPT_WARNING_BROWSER" desc="Warning displayed in body of extension dialog when the extension requires access to browser APIs.">
This extension will have access to your browsing history.
</message>
diff --git a/chrome/browser/cocoa/extension_install_prompt.mm b/chrome/browser/cocoa/extension_install_prompt.mm
index b73ebc2..3519319 100644
--- a/chrome/browser/cocoa/extension_install_prompt.mm
+++ b/chrome/browser/cocoa/extension_install_prompt.mm
@@ -21,7 +21,7 @@ class Profile;
void ExtensionInstallUI::ShowExtensionInstallUIPromptImpl(
Profile* profile, Delegate* delegate, Extension* extension, SkBitmap* icon,
- const string16& warning_text, ExtensionInstallUI::PromptType type) {
+ ExtensionInstallUI::PromptType type) {
NSAlert* alert = [[[NSAlert alloc] init] autorelease];
NSButton* continueButton = [alert addButtonWithTitle:l10n_util::GetNSString(
@@ -37,7 +37,6 @@ void ExtensionInstallUI::ShowExtensionInstallUIPromptImpl(
[alert setMessageText:l10n_util::GetNSStringF(
ExtensionInstallUI::kHeadingIds[type],
UTF8ToUTF16(extension->name()))];
- [alert setInformativeText:base::SysUTF16ToNSString(warning_text)];
[alert setAlertStyle:NSWarningAlertStyle];
[alert setIcon:gfx::SkBitmapToNSImage(*icon)];
diff --git a/chrome/browser/dom_ui/app_launcher_handler.cc b/chrome/browser/dom_ui/app_launcher_handler.cc
index 46cf478..7049d05 100644
--- a/chrome/browser/dom_ui/app_launcher_handler.cc
+++ b/chrome/browser/dom_ui/app_launcher_handler.cc
@@ -6,6 +6,7 @@
#include "app/animation.h"
#include "base/string_number_conversions.h"
+#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/app_launched_animation.h"
@@ -197,11 +198,42 @@ void AppLauncherHandler::AnimateAppIcon(Extension* extension,
void AppLauncherHandler::HandleUninstallApp(const ListValue* args) {
std::string extension_id = WideToUTF8(ExtractStringValue(args));
+ Extension* extension = extensions_service_->GetExtensionById(
+ extension_id, false);
+ if (!extension)
+ return;
+
+ if (!extension_id_prompting_.empty())
+ return; // Only one prompt at a time.
+
+ extension_id_prompting_ = extension_id;
+ GetExtensionInstallUI()->ConfirmUninstall(this, extension);
+}
+
+ExtensionInstallUI* AppLauncherHandler::GetExtensionInstallUI() {
+ if (!install_ui_.get())
+ install_ui_.reset(new ExtensionInstallUI(dom_ui_->GetProfile()));
+ return install_ui_.get();
+}
- // Make sure that the extension exists.
+void AppLauncherHandler::InstallUIProceed(bool create_app_shortcut) {
+ // We only ever use ExtensionInstallUI for uninstalling, which should never
+ // result in it telling us to create a shortcut.
+ DCHECK(!create_app_shortcut);
+ DCHECK(!extension_id_prompting_.empty());
+
+ // The extension can be uninstalled in another window while the UI was
+ // showing. Do nothing in that case.
Extension* extension =
- extensions_service_->GetExtensionById(extension_id, false);
- DCHECK(extension);
+ extensions_service_->GetExtensionById(extension_id_prompting_, true);
+ if (!extension)
+ return;
+
+ extensions_service_->UninstallExtension(extension_id_prompting_,
+ false /* external_uninstall */);
+ extension_id_prompting_ = "";
+}
- extensions_service_->UninstallExtension(extension_id, false);
+void AppLauncherHandler::InstallUIAbort() {
+ extension_id_prompting_ = "";
}
diff --git a/chrome/browser/dom_ui/app_launcher_handler.h b/chrome/browser/dom_ui/app_launcher_handler.h
index 7e89bb7..6a2954a 100644
--- a/chrome/browser/dom_ui/app_launcher_handler.h
+++ b/chrome/browser/dom_ui/app_launcher_handler.h
@@ -6,7 +6,9 @@
#define CHROME_BROWSER_DOM_UI_APP_LAUNCHER_HANDLER_H_
#pragma once
+#include "base/scoped_ptr.h"
#include "chrome/browser/dom_ui/dom_ui.h"
+#include "chrome/browser/extensions/extension_install_ui.h"
#include "chrome/common/notification_observer.h"
#include "chrome/common/notification_registrar.h"
@@ -20,6 +22,7 @@ namespace gfx {
// The handler for Javascript messages related to the "apps" view.
class AppLauncherHandler
: public DOMMessageHandler,
+ public ExtensionInstallUI::Delegate,
public NotificationObserver {
public:
explicit AppLauncherHandler(ExtensionsService* extension_service);
@@ -47,6 +50,15 @@ class AppLauncherHandler
void HandleUninstallApp(const ListValue* args);
private:
+ // ExtensionInstallUI::Delegate implementation, used for receiving
+ // notification about uninstall confirmation dialog selections.
+ virtual void InstallUIProceed(bool create_app_shortcut);
+ virtual void InstallUIAbort();
+
+ // Returns the ExtensionInstallUI object for this class, creating it if
+ // needed.
+ ExtensionInstallUI* GetExtensionInstallUI();
+
// Starts the animation of the app icon.
void AnimateAppIcon(Extension* extension, const gfx::Rect& rect);
@@ -57,6 +69,13 @@ class AppLauncherHandler
// when necessary.
NotificationRegistrar registrar_;
+ // Used to show confirmation UI for uninstalling/enabling extensions in
+ // incognito mode.
+ scoped_ptr<ExtensionInstallUI> install_ui_;
+
+ // The id of the extension we are prompting the user about.
+ std::string extension_id_prompting_;
+
DISALLOW_COPY_AND_ASSIGN(AppLauncherHandler);
};
diff --git a/chrome/browser/extensions/extension_install_ui.cc b/chrome/browser/extensions/extension_install_ui.cc
index e2a8c8e..5e39366 100644
--- a/chrome/browser/extensions/extension_install_ui.cc
+++ b/chrome/browser/extensions/extension_install_ui.cc
@@ -63,6 +63,9 @@ const int ExtensionInstallUI::kButtonIds[NUM_PROMPT_TYPES] = {
namespace {
+// Size of extension icon in top left of dialog.
+const int kIconSize = 69;
+
static void GetV2Warnings(Extension* extension,
std::vector<string16>* warnings) {
if (!extension->plugins().empty()) {
@@ -291,15 +294,13 @@ void ExtensionInstallUI::OnImageLoaded(
std::vector<string16> warnings;
GetV2Warnings(extension_, &warnings);
- ShowExtensionInstallUIPrompt2Impl(
- profile_, delegate_, extension_, &icon_, warnings);
+ ShowExtensionInstallUIPrompt2Impl(profile_, delegate_, extension_, &icon_,
+ warnings);
break;
}
case UNINSTALL_PROMPT: {
- string16 message =
- l10n_util::GetStringUTF16(IDS_EXTENSION_UNINSTALL_CONFIRMATION);
ShowExtensionInstallUIPromptImpl(profile_, delegate_, extension_, &icon_,
- message, UNINSTALL_PROMPT);
+ UNINSTALL_PROMPT);
break;
}
default:
@@ -360,8 +361,7 @@ void ExtensionInstallUI::ShowConfirmation(PromptType prompt_type) {
ExtensionResource image =
extension_->GetIconResource(Extension::EXTENSION_ICON_LARGE);
tracker_.LoadImage(extension_, image,
- gfx::Size(Extension::EXTENSION_ICON_LARGE,
- Extension::EXTENSION_ICON_LARGE),
+ gfx::Size(kIconSize, kIconSize),
ImageLoadingTracker::DONT_CACHE);
}
diff --git a/chrome/browser/extensions/extension_install_ui.h b/chrome/browser/extensions/extension_install_ui.h
index 238da54..ae07363 100644
--- a/chrome/browser/extensions/extension_install_ui.h
+++ b/chrome/browser/extensions/extension_install_ui.h
@@ -116,7 +116,7 @@ class ExtensionInstallUI : public ImageLoadingTracker::Observer {
// NOTE: The implementations of this function is platform-specific.
static void ShowExtensionInstallUIPromptImpl(
Profile* profile, Delegate* delegate, Extension* extension,
- SkBitmap* icon, const string16& warning, PromptType type);
+ SkBitmap* icon, PromptType type);
// Implements the showing of the new install dialog. The implementations of
// this function are platform-specific.
diff --git a/chrome/browser/gtk/extension_install_prompt_gtk.cc b/chrome/browser/gtk/extension_install_prompt_gtk.cc
index 12566173..45efdc7 100644
--- a/chrome/browser/gtk/extension_install_prompt_gtk.cc
+++ b/chrome/browser/gtk/extension_install_prompt_gtk.cc
@@ -26,18 +26,6 @@ namespace {
// Left or right margin.
const int kPanelHorizMargin = 13;
-GtkWidget* MakeMarkupLabel(const char* format, const std::string& str) {
- GtkWidget* label = gtk_label_new(NULL);
- char* markup = g_markup_printf_escaped(format, str.c_str());
- gtk_label_set_markup(GTK_LABEL(label), markup);
- g_free(markup);
-
- // Left align it.
- gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
-
- return label;
-}
-
void OnDialogResponse(GtkDialog* dialog, int response_id,
ExtensionInstallUI::Delegate* delegate) {
if (response_id == GTK_RESPONSE_ACCEPT) {
@@ -52,7 +40,6 @@ void OnDialogResponse(GtkDialog* dialog, int response_id,
void ShowInstallPromptDialog(GtkWindow* parent, SkBitmap* skia_icon,
Extension *extension,
ExtensionInstallUI::Delegate *delegate,
- const string16& warning_text,
ExtensionInstallUI::PromptType type) {
// Build the dialog.
int title_id = ExtensionInstallUI::kTitleIds[type];
@@ -88,15 +75,10 @@ void ShowInstallPromptDialog(GtkWindow* parent, SkBitmap* skia_icon,
int heading_id = ExtensionInstallUI::kHeadingIds[type];
std::string heading_text = l10n_util::GetStringFUTF8(
heading_id, UTF8ToUTF16(extension->name()));
- GtkWidget* heading_label = MakeMarkupLabel("<span weight=\"bold\">%s</span>",
- heading_text);
+ GtkWidget* heading_label = gtk_label_new(heading_text.c_str());
gtk_misc_set_alignment(GTK_MISC(heading_label), 0.0, 0.5);
gtk_box_pack_start(GTK_BOX(right_column_area), heading_label, TRUE, TRUE, 0);
- GtkWidget* warning_label = gtk_label_new(UTF16ToUTF8(warning_text).c_str());
- gtk_misc_set_alignment(GTK_MISC(warning_label), 0.0, 0.5);
- gtk_box_pack_start(GTK_BOX(right_column_area), warning_label, TRUE, TRUE, 0);
-
g_signal_connect(dialog, "response", G_CALLBACK(OnDialogResponse), delegate);
gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
gtk_widget_show_all(dialog);
@@ -106,7 +88,7 @@ void ShowInstallPromptDialog(GtkWindow* parent, SkBitmap* skia_icon,
void ExtensionInstallUI::ShowExtensionInstallUIPromptImpl(
Profile* profile, Delegate* delegate, Extension* extension, SkBitmap* icon,
- const string16& warning_text, ExtensionInstallUI::PromptType type) {
+ ExtensionInstallUI::PromptType type) {
Browser* browser = BrowserList::GetLastActiveWithProfile(profile);
if (!browser) {
delegate->InstallUIAbort();
@@ -120,6 +102,6 @@ void ExtensionInstallUI::ShowExtensionInstallUIPromptImpl(
return;
}
- ShowInstallPromptDialog(browser_window->window(), icon, extension,
- delegate, warning_text, type);
+ ShowInstallPromptDialog(browser_window->window(), icon, extension, delegate,
+ type);
}
diff --git a/chrome/browser/resources/ntp/apps.js b/chrome/browser/resources/ntp/apps.js
index 4c717b3..0ae457a 100644
--- a/chrome/browser/resources/ntp/apps.js
+++ b/chrome/browser/resources/ntp/apps.js
@@ -12,6 +12,7 @@ function getAppsCallback(data) {
if (data.apps.length == 0) {
appsSection.classList.add('disabled');
+ layoutSections();
return;
}
diff --git a/chrome/browser/views/extensions/extension_install_prompt.cc b/chrome/browser/views/extensions/extension_install_prompt.cc
index 3de19a3..af9c540 100644
--- a/chrome/browser/views/extensions/extension_install_prompt.cc
+++ b/chrome/browser/views/extensions/extension_install_prompt.cc
@@ -28,34 +28,19 @@ class Profile;
namespace {
-// Since apps don't (currently) have any privilege disclosure text, the dialog
-// looks a bit empty if it is sized the same as extensions. So we scale
-// everything down a bit for apps for the time being.
-const int kRightColumnWidthApp = 210;
-const int kRightColumnWidthExtension = 270;
-const int kIconSizeApp = 69;
-const int kIconSizeExtension = 85;
+const int kRightColumnWidth = 210;
+const int kIconSize = 69;
// Implements the extension installation prompt for Windows.
class InstallDialogContent : public views::View, public views::DialogDelegate {
public:
InstallDialogContent(ExtensionInstallUI::Delegate* delegate,
- Extension* extension, SkBitmap* icon, const std::wstring& warning_text,
- ExtensionInstallUI::PromptType type)
- : delegate_(delegate), icon_(NULL), warning_(NULL),
- create_shortcut_(NULL), type_(type) {
- if (extension->GetFullLaunchURL().is_valid()) {
- icon_size_ = kIconSizeApp;
- right_column_width_ = kRightColumnWidthApp;
- } else {
- icon_size_ = kIconSizeExtension;
- right_column_width_ = kRightColumnWidthExtension;
- }
-
+ Extension* extension, SkBitmap* icon, ExtensionInstallUI::PromptType type)
+ : delegate_(delegate), icon_(NULL), type_(type) {
// Scale down to icon size, but allow smaller icons (don't scale up).
gfx::Size size(icon->width(), icon->height());
- if (size.width() > icon_size_ || size.height() > icon_size_)
- size = gfx::Size(icon_size_, icon_size_);
+ if (size.width() > kIconSize || size.height() > kIconSize)
+ size = gfx::Size(kIconSize, kIconSize);
icon_ = new views::ImageView();
icon_->SetImageSize(size);
icon_->SetImage(*icon);
@@ -64,24 +49,9 @@ class InstallDialogContent : public views::View, public views::DialogDelegate {
heading_ = new views::Label(
l10n_util::GetStringF(ExtensionInstallUI::kHeadingIds[type_],
UTF8ToWide(extension->name())));
- heading_->SetFont(heading_->font().DeriveFont(1, gfx::Font::BOLD));
heading_->SetMultiLine(true);
heading_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
AddChildView(heading_);
-
- if (type_ == ExtensionInstallUI::INSTALL_PROMPT &&
- extension->GetFullLaunchURL().is_valid()) {
- create_shortcut_ = new views::Checkbox(
- l10n_util::GetString(IDS_EXTENSION_PROMPT_CREATE_SHORTCUT));
- create_shortcut_->SetChecked(true);
- create_shortcut_->SetMultiLine(true);
- AddChildView(create_shortcut_);
- } else {
- warning_ = new views::Label(warning_text);
- warning_->SetMultiLine(true);
- warning_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
- AddChildView(warning_);
- }
}
private:
@@ -104,8 +74,9 @@ class InstallDialogContent : public views::View, public views::DialogDelegate {
}
virtual bool Accept() {
- delegate_->InstallUIProceed(
- create_shortcut_ && create_shortcut_->checked());
+ // We don't support shortcut creation from this dialog anymore.
+ // TODO(aa): Remove this param from ExtensionInstallUI::Delegate.
+ delegate_->InstallUIProceed(false);
return true;
}
@@ -124,70 +95,47 @@ class InstallDialogContent : public views::View, public views::DialogDelegate {
// View
virtual gfx::Size GetPreferredSize() {
- int width = right_column_width_ + kPanelHorizMargin + kPanelHorizMargin;
- width += icon_size_;
- width += kPanelHorizMargin;
+ int width = kRightColumnWidth;
+ width += kIconSize;
+ width += kPanelHorizMargin * 3;
int height = kPanelVertMargin * 2;
- height += heading_->GetHeightForWidth(right_column_width_);
- height += kPanelVertMargin;
-
- if (warning_)
- height += warning_->GetHeightForWidth(right_column_width_);
- else
- height += create_shortcut_->GetPreferredSize().height();
-
- height += kPanelVertMargin;
+ height += heading_->GetHeightForWidth(kRightColumnWidth);
return gfx::Size(width,
- std::max(height, icon_size_ + kPanelVertMargin * 2));
+ std::max(height, kIconSize + kPanelVertMargin * 2));
}
virtual void Layout() {
int x = kPanelHorizMargin;
int y = kPanelVertMargin;
- icon_->SetBounds(x, y, icon_size_, icon_size_);
- x += icon_size_;
- x += kPanelHorizMargin;
-
- heading_->SizeToFit(right_column_width_);
- heading_->SetX(x);
- heading_->SetY(y);
- y += heading_->height();
-
- y += kPanelVertMargin;
-
- if (create_shortcut_) {
- create_shortcut_->SetBounds(x, y, right_column_width_, 0);
- create_shortcut_->SetBounds(x, y, right_column_width_,
- create_shortcut_->GetPreferredSize().height());
-
- int bottom_aligned = icon_->y() + icon_->height() -
- create_shortcut_->height();
- if (bottom_aligned > y) {
- create_shortcut_->SetY(bottom_aligned);
- y = bottom_aligned;
- }
- y += create_shortcut_->height();
+ heading_->SizeToFit(kRightColumnWidth);
+
+ if (heading_->height() <= kIconSize) {
+ icon_->SetBounds(x, y, kIconSize, kIconSize);
+ x += kIconSize;
+ x += kPanelHorizMargin;
+
+ heading_->SetX(x);
+ heading_->SetY(y + (kIconSize - heading_->height()) / 2);
} else {
- warning_->SizeToFit(right_column_width_);
- warning_->SetX(x);
- warning_->SetY(y);
- y += warning_->height();
+ icon_->SetBounds(x,
+ y + (heading_->height() - kIconSize) / 2,
+ kIconSize,
+ kIconSize);
+ x += kIconSize;
+ x += kPanelHorizMargin;
+
+ heading_->SetX(x);
+ heading_->SetY(y);
}
-
- y += kPanelVertMargin;
}
ExtensionInstallUI::Delegate* delegate_;
views::ImageView* icon_;
views::Label* heading_;
- views::Label* warning_;
- views::Checkbox* create_shortcut_;
ExtensionInstallUI::PromptType type_;
- int right_column_width_;
- int icon_size_;
DISALLOW_COPY_AND_ASSIGN(InstallDialogContent);
};
@@ -197,7 +145,7 @@ class InstallDialogContent : public views::View, public views::DialogDelegate {
// static
void ExtensionInstallUI::ShowExtensionInstallUIPromptImpl(
Profile* profile, Delegate* delegate, Extension* extension, SkBitmap* icon,
- const string16& warning_text, PromptType type) {
+ PromptType type) {
Browser* browser = BrowserList::GetLastActiveWithProfile(profile);
if (!browser) {
delegate->InstallUIAbort();
@@ -212,6 +160,5 @@ void ExtensionInstallUI::ShowExtensionInstallUIPromptImpl(
views::Window::CreateChromeWindow(window->GetNativeHandle(), gfx::Rect(),
new InstallDialogContent(delegate, extension, icon,
- UTF16ToWideHack(warning_text),
type))->Show();
}