15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/first_run/try_chrome_dialog_view.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <shellapi.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 109ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/process_singleton.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/installer/util/browser_distribution.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/installer/util/user_experiment.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/chromium_strings.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/ui_resources.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/image/image.h" 22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/views/background.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/button/checkbox.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/button/image_button.h" 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/views/controls/button/label_button.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/button/radio_button.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/image_view.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/link.h" 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/views/controls/separator.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/grid_layout.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/layout_constants.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_AURA) 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/root_window.h" 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/aura/window.h" 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t kHelpCenterUrl[] = 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L"https://www.google.com/support/chrome/bin/answer.py?answer=150752"; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum ButtonTags { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BT_NONE, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BT_CLOSE_BUTTON, 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BT_OK_BUTTON, 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BT_TRY_IT_RADIO, 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BT_DONT_BUG_RADIO 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kRadioGroupID = 1; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TryChromeDialogView::Result TryChromeDialogView::Show( 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t flavor, 59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ActiveModalDialogListener& listener) { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (flavor > 10000) { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is a test value. We want to make sure we exercise 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // returning this early. See TryChromeDialogBrowserTest test. 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NOT_NOW; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TryChromeDialogView dialog(flavor); 66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return dialog.ShowModal(listener); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TryChromeDialogView::TryChromeDialogView(size_t flavor) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : flavor_(flavor), 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) popup_(NULL), 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try_chrome_(NULL), 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kill_chrome_(NULL), 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dont_try_chrome_(NULL), 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) make_default_(NULL), 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result_(COUNT) { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TryChromeDialogView::~TryChromeDialogView() { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TryChromeDialogView::Result TryChromeDialogView::ShowModal( 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ActiveModalDialogListener& listener) { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::ImageView* icon = new views::ImageView(); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon->SetImage(rb.GetNativeImageNamed(IDR_PRODUCT_LOGO_32).ToImageSkia()); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size icon_size = icon->GetPreferredSize(); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // An approximate window size. After Layout() we'll get better bounds. 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params.can_activate = true; 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.bounds = gfx::Rect(310, 200); 943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) popup_ = new views::Widget; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) popup_->Init(params); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::View* root_view = popup_->GetRootView(); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The window color is a tiny bit off-white. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_view->set_background( 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::Background::CreateSolidBackground(0xfc, 0xfc, 0xfc)); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GridLayout* layout = views::GridLayout::CreatePanel(root_view); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) root_view->SetLayoutManager(layout); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::ColumnSet* columns; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // First row: [icon][pad][text][pad][button]. 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) columns = layout->AddColumnSet(0); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::LEADING, 0, 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GridLayout::FIXED, icon_size.width(), 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) icon_size.height()); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) columns->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) columns->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1, 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GridLayout::USE_PREF, 0, 0); 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) columns->AddPaddingColumn(0, views::kUnrelatedControlHorizontalSpacing); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::FILL, 1, 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GridLayout::USE_PREF, 0, 0); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Optional second row: [pad][pad][radio 1]. 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) columns = layout->AddColumnSet(1); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) columns->AddPaddingColumn(0, icon_size.width()); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) columns->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 1, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GridLayout::USE_PREF, 0, 0); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Third row: [pad][pad][radio 2]. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) columns = layout->AddColumnSet(2); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) columns->AddPaddingColumn(0, icon_size.width()); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) columns->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 1, 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GridLayout::USE_PREF, 0, 0); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fourth row: [pad][pad][button][pad][button]. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) columns = layout->AddColumnSet(3); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) columns->AddPaddingColumn(0, icon_size.width()); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 0, 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GridLayout::USE_PREF, 0, 0); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) columns->AddPaddingColumn(0, views::kRelatedButtonHSpacing); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 0, 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GridLayout::USE_PREF, 0, 0); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fifth row: [pad][pad][link]. 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) columns = layout->AddColumnSet(4); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) columns->AddPaddingColumn(0, icon_size.width()); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) columns->AddPaddingColumn(0, views::kRelatedControlHorizontalSpacing); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 1, 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GridLayout::USE_PREF, 0, 0); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Optional fourth row: [button]. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) columns = layout->AddColumnSet(5); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) columns->AddColumn(views::GridLayout::CENTER, views::GridLayout::FILL, 1, 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GridLayout::USE_PREF, 0, 0); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Optional fourth row: [divider] 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) columns = layout->AddColumnSet(6); 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) columns->AddColumn(views::GridLayout::CENTER, views::GridLayout::FILL, 1, 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::GridLayout::USE_PREF, 0, 0); 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Optional fifth row [checkbox][pad][button] 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) columns = layout->AddColumnSet(7); 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) columns->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 0, 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::GridLayout::USE_PREF, 0, 0); 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) columns->AddPaddingColumn(0, views::kUnrelatedControlHorizontalSpacing); 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::FILL, 1, 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::GridLayout::USE_PREF, 0, 0); 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First row. 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->StartRow(0, 0); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->AddView(icon); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Find out what experiment we are conducting. 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) installer::ExperimentDetails experiment; 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!BrowserDistribution::GetDistribution()->HasUserExperiments() || 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !installer::CreateExperimentDetails(flavor_, &experiment) || 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !experiment.heading) { 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Cannot determine which headline to show."; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DIALOG_ERROR; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::Label* label = new views::Label( 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringUTF16(experiment.heading)); 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) label->SetFont(rb.GetFont(ui::ResourceBundle::MediumFont)); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label->SetMultiLine(true); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label->SizeToFit(200); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) label->SetHorizontalAlignment(gfx::ALIGN_LEFT); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->AddView(label); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The close button is custom. 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::ImageButton* close_button = new views::ImageButton(this); 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) close_button->SetImage(views::CustomButton::STATE_NORMAL, 188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rb.GetNativeImageNamed(IDR_CLOSE_2).ToImageSkia()); 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) close_button->SetImage(views::CustomButton::STATE_HOVERED, 190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rb.GetNativeImageNamed(IDR_CLOSE_2_H).ToImageSkia()); 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) close_button->SetImage(views::CustomButton::STATE_PRESSED, 192c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) rb.GetNativeImageNamed(IDR_CLOSE_2_P).ToImageSkia()); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close_button->set_tag(BT_CLOSE_BUTTON); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->AddView(close_button); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Second row. 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->StartRowWithPadding(0, 1, 0, 10); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try_chrome_ = new views::RadioButton( 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringUTF16(IDS_TRY_TOAST_TRY_OPT), kRadioGroupID); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try_chrome_->SetChecked(true); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try_chrome_->set_tag(BT_TRY_IT_RADIO); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) try_chrome_->set_listener(this); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->AddView(try_chrome_); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Decide if the don't bug me is a button or a radio button. 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool dont_bug_me_button = 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !!(experiment.flags & installer::kToastUiDontBugMeAsButton); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Optional third and fourth row. 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!dont_bug_me_button) { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->StartRow(0, 1); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dont_try_chrome_ = new views::RadioButton( 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringUTF16(IDS_TRY_TOAST_CANCEL), kRadioGroupID); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dont_try_chrome_->set_tag(BT_DONT_BUG_RADIO); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dont_try_chrome_->set_listener(this); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->AddView(dont_try_chrome_); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (experiment.flags & installer::kToastUiUninstall) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->StartRow(0, 2); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kill_chrome_ = new views::RadioButton( 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringUTF16(IDS_UNINSTALL_CHROME), kRadioGroupID); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->AddView(kill_chrome_); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 225c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) views::LabelButton* accept_button = new views::LabelButton( 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, l10n_util::GetStringUTF16(IDS_OK)); 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) accept_button->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON); 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) accept_button->set_tag(BT_OK_BUTTON); 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) views::Separator* separator = NULL; 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (experiment.flags & installer::kToastUiMakeDefault) { 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // In this flavor we have some veritical space, then a separator line 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // and the 'make default' checkbox and the OK button on the same row. 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->StartRow(0, 6); 236a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) separator = new views::Separator(views::Separator::HORIZONTAL); 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) layout->AddView(separator); 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing); 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) layout->StartRow(0, 7); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) make_default_ = new views::Checkbox( 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringUTF16(IDS_TRY_TOAST_SET_DEFAULT)); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) make_default_->SetChecked(true); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->AddView(make_default_); 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) layout->AddView(accept_button); 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // On this other flavor there is no checkbox, the OK button and possibly 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the cancel button are in the same row. 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) layout->StartRowWithPadding(0, dont_bug_me_button ? 3 : 5, 0, 10); 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) layout->AddView(accept_button); 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (dont_bug_me_button) { 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The dialog needs a "Don't bug me" as a button or as a radio button, 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // this the button case. 254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) views::LabelButton* cancel_button = new views::LabelButton( 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, l10n_util::GetStringUTF16(IDS_TRY_TOAST_CANCEL)); 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cancel_button->SetStyle(views::Button::STYLE_NATIVE_TEXTBUTTON); 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) cancel_button->set_tag(BT_CLOSE_BUTTON); 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) layout->AddView(cancel_button); 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (experiment.flags & installer::kToastUiWhyLink) { 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->StartRowWithPadding(0, 4, 0, 10); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) views::Link* link = new views::Link( 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) l10n_util::GetStringUTF16(IDS_TRY_TOAST_WHY)); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) link->set_listener(this); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->AddView(link); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We resize the window according to the layout manager. This takes into 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // account the differences between XP and Vista fonts and buttons. 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) layout->Layout(root_view); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Size preferred = layout->GetPreferredSize(root_view); 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (separator) { 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int separator_height = separator->GetPreferredSize().height(); 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) separator->SetSize(gfx::Size(preferred.width(), separator_height)); 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect pos = ComputeWindowPosition(preferred.width(), preferred.height(), 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::i18n::IsRTL()); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) popup_->SetBounds(pos); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Carve the toast shape into the window. 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) HWND toast_window; 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_AURA) 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) toast_window = 287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) popup_->GetNativeView()->GetDispatcher()->host()->GetAcceleratedWidget(); 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) toast_window = popup_->GetNativeView(); 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SetToastRegion(toast_window, preferred.width(), preferred.height()); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Time to show the window in a modal loop. 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) popup_->Show(); 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!listener.is_null()) 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) listener.Run(popup_->GetNativeView()); 29790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Run(); 298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!listener.is_null()) 299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) listener.Run(NULL); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result_; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect TryChromeDialogView::ComputeWindowPosition(int width, 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int height, 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_RTL) { 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The 'Shell_TrayWnd' is the taskbar. We like to show our window in that 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // monitor if we can. This code works even if such window is not found. 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HWND taskbar = ::FindWindowW(L"Shell_TrayWnd", NULL); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMONITOR monitor = ::MonitorFromWindow(taskbar, MONITOR_DEFAULTTOPRIMARY); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MONITORINFO info = {sizeof(info)}; 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetMonitorInfoW(monitor, &info)) { 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Quite unexpected. Do a best guess at a visible rectangle. 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gfx::Rect(20, 20, width + 20, height + 20); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The |rcWork| is the work area. It should account for the taskbars that 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // are in the screen when we called the function. 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int left = is_RTL ? info.rcWork.left : info.rcWork.right - width; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int top = info.rcWork.bottom - height; 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gfx::Rect(left, top, width, height); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TryChromeDialogView::SetToastRegion(HWND window, int w, int h) { 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const POINT polygon[] = { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {0, 4}, {1, 2}, {2, 1}, {4, 0}, // Left side. 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {w-4, 0}, {w-2, 1}, {w-1, 2}, {w, 4}, // Right side. 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {w, h}, {0, h} 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HRGN region = ::CreatePolygonRgn(polygon, arraysize(polygon), WINDING); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::SetWindowRgn(window, region, FALSE); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TryChromeDialogView::ButtonPressed(views::Button* sender, 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ui::Event& event) { 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sender->tag() == BT_DONT_BUG_RADIO) { 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (make_default_) { 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) make_default_->SetChecked(false); 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) make_default_->SetVisible(false); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (sender->tag() == BT_TRY_IT_RADIO) { 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (make_default_) { 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) make_default_->SetVisible(true); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) make_default_->SetChecked(true); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (sender->tag() == BT_CLOSE_BUTTON) { 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The user pressed cancel or the [x] button. 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result_ = NOT_NOW; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (!try_chrome_) { 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't have radio buttons, the user pressed ok. 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result_ = TRY_CHROME; 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The outcome is according to the selected radio button. 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (try_chrome_->checked()) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result_ = TRY_CHROME; 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (dont_try_chrome_ && dont_try_chrome_->checked()) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result_ = NOT_NOW; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (kill_chrome_ && kill_chrome_->checked()) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result_ = UNINSTALL_CHROME; 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unknown radio button selected"; 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (make_default_) { 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((result_ == TRY_CHROME) && make_default_->checked()) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result_ = TRY_CHROME_AS_DEFAULT; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) popup_->Close(); 37090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->Quit(); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TryChromeDialogView::LinkClicked(views::Link* source, int event_flags) { 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::ShellExecuteW(NULL, L"open", kHelpCenterUrl, NULL, NULL, SW_SHOW); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 376