1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Use of this source code is governed by a BSD-style license that can be 3ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// found in the LICENSE file. 4ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/first_run/try_chrome_dialog_view.h" 6ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 7ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include <shellapi.h> 8ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/logging.h" 10ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/message_loop.h" 11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/string16.h" 12ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/process_singleton.h" 13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/installer/util/browser_distribution.h" 14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "grit/chromium_strings.h" 15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "grit/generated_resources.h" 16ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "grit/theme_resources.h" 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "ui/base/resource/resource_bundle.h" 18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "views/controls/button/image_button.h" 19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "views/controls/button/radio_button.h" 20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "views/controls/image_view.h" 21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "views/layout/grid_layout.h" 22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "views/layout/layout_constants.h" 23ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "views/widget/root_view.h" 24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "views/widget/widget.h" 25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "ui/base/l10n/l10n_util.h" 26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace { 28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 29ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenconst wchar_t kHelpCenterUrl[] = 30ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen L"https://www.google.com/support/chrome/bin/answer.py?answer=150752"; 31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 32ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} // namespace 33ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 34ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// static 35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTryChromeDialogView::Result TryChromeDialogView::Show( 36ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen size_t version, 37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ProcessSingleton* process_singleton) { 38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (version > 10000) { 39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // This is a test value. We want to make sure we exercise 40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // returning this early. See EarlyReturnTest test harness. 41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return NOT_NOW; 42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen TryChromeDialogView dialog(version); 44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return dialog.ShowModal(process_singleton); 45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTryChromeDialogView::TryChromeDialogView(size_t version) 48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen : version_(version), 49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen popup_(NULL), 50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen try_chrome_(NULL), 51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen kill_chrome_(NULL), 52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen result_(COUNT) { 53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTryChromeDialogView::~TryChromeDialogView() { 56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTryChromeDialogView::Result TryChromeDialogView::ShowModal( 59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ProcessSingleton* process_singleton) { 60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen views::ImageView* icon = new views::ImageView(); 63ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen icon->SetImage(*rb.GetBitmapNamed(IDR_PRODUCT_ICON_32)); 64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gfx::Size icon_size = icon->GetPreferredSize(); 65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // An approximate window size. After Layout() we'll get better bounds. 67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen views::Widget::CreateParams params(views::Widget::CreateParams::TYPE_POPUP); 68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen params.can_activate = true; 69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen popup_ = views::Widget::CreateWidget(params); 70ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!popup_) { 71ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NOTREACHED(); 72ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return DIALOG_ERROR; 73ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 74ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 75ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gfx::Rect pos(310, 160); 76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen popup_->Init(NULL, pos); 77ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 78ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen views::RootView* root_view = popup_->GetRootView(); 79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // The window color is a tiny bit off-white. 80ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen root_view->set_background( 81ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen views::Background::CreateSolidBackground(0xfc, 0xfc, 0xfc)); 82ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 83ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen views::GridLayout* layout = views::GridLayout::CreatePanel(root_view); 84ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!layout) { 85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NOTREACHED(); 86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return DIALOG_ERROR; 87ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 88ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen root_view->SetLayoutManager(layout); 89ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen views::ColumnSet* columns; 91ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // First row: [icon][pad][text][button]. 92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen columns = layout->AddColumnSet(0); 93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::LEADING, 0, 94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen views::GridLayout::FIXED, icon_size.width(), 95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen icon_size.height()); 96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen columns->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing); 97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1, 98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen views::GridLayout::USE_PREF, 0, 0); 99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::FILL, 1, 100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen views::GridLayout::USE_PREF, 0, 0); 101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Second row: [pad][pad][radio 1]. 102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen columns = layout->AddColumnSet(1); 103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen columns->AddPaddingColumn(0, icon_size.width()); 104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen columns->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing); 105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 1, 106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen views::GridLayout::USE_PREF, 0, 0); 107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Third row: [pad][pad][radio 2]. 108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen columns = layout->AddColumnSet(2); 109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen columns->AddPaddingColumn(0, icon_size.width()); 110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen columns->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing); 111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 1, 112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen views::GridLayout::USE_PREF, 0, 0); 113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Fourth row: [pad][pad][button][pad][button]. 114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen columns = layout->AddColumnSet(3); 115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen columns->AddPaddingColumn(0, icon_size.width()); 116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen columns->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing); 117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 0, 118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen views::GridLayout::USE_PREF, 0, 0); 119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen columns->AddPaddingColumn(0, views::kRelatedButtonHSpacing); 120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 0, 121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen views::GridLayout::USE_PREF, 0, 0); 122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Fifth row: [pad][pad][link]. 123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen columns = layout->AddColumnSet(4); 124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen columns->AddPaddingColumn(0, icon_size.width()); 125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen columns->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing); 126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 1, 127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen views::GridLayout::USE_PREF, 0, 0); 128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // First row views. 129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen layout->StartRow(0, 0); 130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen layout->AddView(icon); 131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Find out what experiment we are conducting. 133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserDistribution* dist = BrowserDistribution::GetDistribution(); 134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!dist) { 135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NOTREACHED() << "Cannot determine browser distribution"; 136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return DIALOG_ERROR; 137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BrowserDistribution::UserExperiment experiment; 139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!dist->GetExperimentDetails(&experiment, version_) || 140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen !experiment.heading) { 141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen NOTREACHED() << "Cannot determine which headline to show."; 142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return DIALOG_ERROR; 143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 144ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen string16 heading = l10n_util::GetStringUTF16(experiment.heading); 145ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen views::Label* label = new views::Label(heading); 146ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen label->SetFont(rb.GetFont(ResourceBundle::MediumBoldFont)); 147ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen label->SetMultiLine(true); 148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen label->SizeToFit(200); 149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen label->SetHorizontalAlignment(views::Label::ALIGN_LEFT); 150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen layout->AddView(label); 151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // The close button is custom. 152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen views::ImageButton* close_button = new views::ImageButton(this); 153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen close_button->SetImage(views::CustomButton::BS_NORMAL, 154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen rb.GetBitmapNamed(IDR_CLOSE_BAR)); 155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen close_button->SetImage(views::CustomButton::BS_HOT, 156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen rb.GetBitmapNamed(IDR_CLOSE_BAR_H)); 157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen close_button->SetImage(views::CustomButton::BS_PUSHED, 158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen rb.GetBitmapNamed(IDR_CLOSE_BAR_P)); 159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen close_button->set_tag(BT_CLOSE_BUTTON); 160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen layout->AddView(close_button); 161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Second row views. 163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const string16 try_it(l10n_util::GetStringUTF16(IDS_TRY_TOAST_TRY_OPT)); 164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen layout->StartRowWithPadding(0, 1, 0, 10); 165ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen try_chrome_ = new views::RadioButton(try_it, 1); 166ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen layout->AddView(try_chrome_); 167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen try_chrome_->SetChecked(true); 168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Third row views. 170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const string16 kill_it(l10n_util::GetStringUTF16(IDS_UNINSTALL_CHROME)); 171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen layout->StartRow(0, 2); 172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen kill_chrome_ = new views::RadioButton(kill_it, 1); 173ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen layout->AddView(kill_chrome_); 174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Fourth row views. 176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const string16 ok_it(l10n_util::GetStringUTF16(IDS_OK)); 177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const string16 cancel_it(l10n_util::GetStringUTF16(IDS_TRY_TOAST_CANCEL)); 178ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const string16 why_this(l10n_util::GetStringUTF16(IDS_TRY_TOAST_WHY)); 179ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen layout->StartRowWithPadding(0, 3, 0, 10); 180ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen views::Button* accept_button = new views::NativeButton(this, ok_it); 181ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen accept_button->set_tag(BT_OK_BUTTON); 182ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen layout->AddView(accept_button); 183ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen views::Button* cancel_button = new views::NativeButton(this, cancel_it); 184ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen cancel_button->set_tag(BT_CLOSE_BUTTON); 185ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen layout->AddView(cancel_button); 186ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Fifth row views. 187ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen layout->StartRowWithPadding(0, 4, 0, 10); 188ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen views::Link* link = new views::Link(why_this); 189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen link->SetController(this); 190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen layout->AddView(link); 191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // We resize the window according to the layout manager. This takes into 193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // account the differences between XP and Vista fonts and buttons. 194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen layout->Layout(root_view); 195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen gfx::Size preferred = layout->GetPreferredSize(root_view); 196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen pos = ComputeWindowPosition(preferred.width(), preferred.height(), 197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen base::i18n::IsRTL()); 198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen popup_->SetBounds(pos); 199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Carve the toast shape into the window. 201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen SetToastRegion(popup_->GetNativeView(), 202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen preferred.width(), preferred.height()); 203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Time to show the window in a modal loop. We don't want this chrome 205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // instance trying to serve WM_COPYDATA requests, as we'll surely crash. 206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen process_singleton->Lock(popup_->GetNativeView()); 207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen popup_->Show(); 208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MessageLoop::current()->Run(); 209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen process_singleton->Unlock(); 210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return result_; 211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsengfx::Rect TryChromeDialogView::ComputeWindowPosition(int width, 214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int height, 215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool is_RTL) { 216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // The 'Shell_TrayWnd' is the taskbar. We like to show our window in that 217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // monitor if we can. This code works even if such window is not found. 218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen HWND taskbar = ::FindWindowW(L"Shell_TrayWnd", NULL); 219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen HMONITOR monitor = ::MonitorFromWindow(taskbar, MONITOR_DEFAULTTOPRIMARY); 220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MONITORINFO info = {sizeof(info)}; 221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (!GetMonitorInfoW(monitor, &info)) { 222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Quite unexpected. Do a best guess at a visible rectangle. 223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return gfx::Rect(20, 20, width + 20, height + 20); 224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // The |rcWork| is the work area. It should account for the taskbars that 226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // are in the screen when we called the function. 227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int left = is_RTL ? info.rcWork.left : info.rcWork.right - width; 228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int top = info.rcWork.bottom - height; 229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return gfx::Rect(left, top, width, height); 230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TryChromeDialogView::SetToastRegion(HWND window, int w, int h) { 233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen static const POINT polygon[] = { 234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen {0, 4}, {1, 2}, {2, 1}, {4, 0}, // Left side. 235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen {w-4, 0}, {w-2, 1}, {w-1, 2}, {w, 4}, // Right side. 236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen {w, h}, {0, h} 237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen }; 238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen HRGN region = ::CreatePolygonRgn(polygon, arraysize(polygon), WINDING); 239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ::SetWindowRgn(window, region, FALSE); 240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TryChromeDialogView::ButtonPressed(views::Button* sender, 243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const views::Event& event) { 244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (sender->tag() == BT_CLOSE_BUTTON) { 245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // The user pressed cancel or the [x] button. 246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen result_ = NOT_NOW; 247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else if (!try_chrome_) { 248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // We don't have radio buttons, the user pressed ok. 249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen result_ = TRY_CHROME; 250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // The outcome is according to the selected ratio button. 252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen result_ = try_chrome_->checked() ? TRY_CHROME : UNINSTALL_CHROME; 253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen popup_->Close(); 255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen MessageLoop::current()->Quit(); 256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 257ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 258ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid TryChromeDialogView::LinkActivated(views::Link* source, int event_flags) { 259ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ::ShellExecuteW(NULL, L"open", kHelpCenterUrl, NULL, NULL, SW_SHOW); 260ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 261