global_error_bubble_view.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
183e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org// Copyright (c) 2012 The Chromium Authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 5304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org#include "chrome/browser/ui/views/global_error_bubble_view.h" 6304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "base/strings/utf_string_conversions.h" 871affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org#include "chrome/browser/ui/global_error/global_error.h" 971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.org#include "chrome/browser/ui/global_error/global_error_service.h" 1043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "chrome/browser/ui/global_error/global_error_service_factory.h" 1143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "chrome/browser/ui/views/frame/browser_view.h" 12304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org#include "chrome/browser/ui/views/toolbar/toolbar_view.h" 13304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org#include "ui/base/resource/resource_bundle.h" 1443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "ui/gfx/image/image.h" 1555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org#include "ui/views/controls/button/label_button.h" 16afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org#include "ui/views/controls/image_view.h" 1743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#include "ui/views/controls/label.h" 1855ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org#include "ui/views/layout/grid_layout.h" 19afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org#include "ui/views/layout/layout_constants.h" 2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 2143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansennamespace { 2243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 23afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.orgenum { 24304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org TAG_ACCEPT_BUTTON = 1, 25304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org TAG_CANCEL_BUTTON, 2643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen}; 2743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 28afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.orgconst int kMaxBubbleViewWidth = 262; 29b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 30afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org// The horizontal padding between the title and the icon. 31b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.orgconst int kTitleHorizontalPadding = 5; 32afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org 3343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// The vertical inset of the wrench bubble anchor from the wrench menu button. 34a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgconst int kAnchorVerticalInset = 5; 35afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org 3655ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.orgconst int kBubblePadding = 6; 37b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org 3843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} // namespace 39a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 40afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org// GlobalErrorBubbleViewBase --------------------------------------------------- 41a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org 42a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org// static 43a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgGlobalErrorBubbleViewBase* GlobalErrorBubbleViewBase::ShowStandardBubbleView( 4443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen Browser* browser, 4543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen const base::WeakPtr<GlobalErrorWithStandardBubble>& error) { 4683e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser); 4743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen views::View* wrench_button = browser_view->toolbar()->app_menu(); 4843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen GlobalErrorBubbleView* bubble_view = 4943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen new GlobalErrorBubbleView(wrench_button, 5043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen views::BubbleBorder::TOP_RIGHT, 5143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen browser, 52afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org error); 5355ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org views::BubbleDelegateView::CreateBubble(bubble_view); 5455ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org bubble_view->GetWidget()->Show(); 5543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen return bubble_view; 5643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} 5743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen 58afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org// GlobalErrorBubbleView ------------------------------------------------------- 59e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org 60a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgGlobalErrorBubbleView::GlobalErrorBubbleView( 61a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org views::View* anchor_view, 62a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org views::BubbleBorder::Arrow arrow, 63a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org Browser* browser, 6483e168294456ca2f02db421a635f7d5f5d023966kmillikin@chromium.org const base::WeakPtr<GlobalErrorWithStandardBubble>& error) 6543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen : BubbleDelegateView(anchor_view, arrow), 6643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen browser_(browser), 67afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org error_(error) { 68304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org // Compensate for built-in vertical padding in the anchor view's image. 69e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org set_anchor_view_insets( 7055ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org gfx::Insets(kAnchorVerticalInset, 0, kAnchorVerticalInset, 0)); 71304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 7255ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 7343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen gfx::Image image = error_->GetBubbleViewIcon(); 7443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen CHECK(!image.IsEmpty()); 7543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen scoped_ptr<views::ImageView> image_view(new views::ImageView()); 76afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org image_view->SetImage(image.ToImageSkia()); 77afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org 78afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org base::string16 title_string(error_->GetBubbleViewTitle()); 79afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org scoped_ptr<views::Label> title_label(new views::Label(title_string)); 80afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org title_label->SetMultiLine(true); 81afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org title_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); 82afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org title_label->SetFontList(rb.GetFontList(ui::ResourceBundle::MediumFont)); 835a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org 8443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen std::vector<base::string16> message_strings(error_->GetBubbleViewMessages()); 8555ee80713569ab0324fc8dcedcb5518501daa6a6ricow@chromium.org std::vector<views::Label*> message_labels; 8643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen for (size_t i = 0; i < message_strings.size(); ++i) { 8743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen views::Label* message_label = new views::Label(message_strings[i]); 88304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org message_label->SetMultiLine(true); 89304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org message_label->SizeToFit(kMaxBubbleViewWidth); 90304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org message_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); 91304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org message_labels.push_back(message_label); 92304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } 93304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 94304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org base::string16 accept_string(error_->GetBubbleViewAcceptButtonLabel()); 95304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org scoped_ptr<views::LabelButton> accept_button( 96304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org new views::LabelButton(this, accept_string)); 97304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org accept_button->SetStyle(views::Button::STYLE_BUTTON); 98304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org accept_button->SetIsDefault(true); 99304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org accept_button->set_tag(TAG_ACCEPT_BUTTON); 100304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 101304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org base::string16 cancel_string(error_->GetBubbleViewCancelButtonLabel()); 102afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org scoped_ptr<views::LabelButton> cancel_button; 103afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org if (!cancel_string.empty()) { 104304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org cancel_button.reset(new views::LabelButton(this, cancel_string)); 105afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org cancel_button->SetStyle(views::Button::STYLE_BUTTON); 106304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org cancel_button->set_tag(TAG_CANCEL_BUTTON); 107304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org } 108304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 109304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org views::GridLayout* layout = new views::GridLayout(this); 110304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org SetLayoutManager(layout); 111304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org layout->SetInsets(kBubblePadding, kBubblePadding, 112750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org kBubblePadding, kBubblePadding); 113750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 114304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org // Top row, icon and title. 115304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org views::ColumnSet* cs = layout->AddColumnSet(0); 116304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org cs->AddColumn(views::GridLayout::LEADING, views::GridLayout::LEADING, 117750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org 0, views::GridLayout::USE_PREF, 0, 0); 118304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org cs->AddPaddingColumn(0, kTitleHorizontalPadding); 119304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org cs->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 120304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 1, views::GridLayout::USE_PREF, 0, 0); 121afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org 122afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org // Middle rows, message labels. 123304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org cs = layout->AddColumnSet(1); 124afbdadc5f06365a7889e7c1c1fdb7dbf596cce68machenbach@chromium.org cs->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 125304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 1, views::GridLayout::USE_PREF, 0, 0); 126304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org 127304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org // Bottom row, accept and cancel button. 12843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen cs = layout->AddColumnSet(2); 12943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen cs->AddPaddingColumn(1, views::kRelatedControlHorizontalSpacing); 130304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org cs->AddColumn(views::GridLayout::TRAILING, views::GridLayout::LEADING, 131 0, views::GridLayout::USE_PREF, 0, 0); 132 if (cancel_button.get()) { 133 cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing); 134 cs->AddColumn(views::GridLayout::TRAILING, views::GridLayout::LEADING, 135 0, views::GridLayout::USE_PREF, 0, 0); 136 } 137 138 layout->StartRow(1, 0); 139 layout->AddView(image_view.release()); 140 layout->AddView(title_label.release()); 141 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); 142 143 for (size_t i = 0; i < message_labels.size(); ++i) { 144 layout->StartRow(1, 1); 145 layout->AddView(message_labels[i]); 146 if (i < message_labels.size() - 1) 147 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing); 148 } 149 layout->AddPaddingRow(0, views::kLabelToControlVerticalSpacing); 150 151 layout->StartRow(0, 2); 152 layout->AddView(accept_button.release()); 153 if (cancel_button.get()) 154 layout->AddView(cancel_button.release()); 155 156 // Adjust the message label size in case buttons are too long. 157 for (size_t i = 0; i < message_labels.size(); ++i) 158 message_labels[i]->SizeToFit(layout->GetPreferredSize(this).width()); 159} 160 161GlobalErrorBubbleView::~GlobalErrorBubbleView() { 162} 163 164void GlobalErrorBubbleView::ButtonPressed(views::Button* sender, 165 const ui::Event& event) { 166 if (error_) { 167 if (sender->tag() == TAG_ACCEPT_BUTTON) 168 error_->BubbleViewAcceptButtonPressed(browser_); 169 else if (sender->tag() == TAG_CANCEL_BUTTON) 170 error_->BubbleViewCancelButtonPressed(browser_); 171 else 172 NOTREACHED(); 173 } 174 GetWidget()->Close(); 175} 176 177void GlobalErrorBubbleView::WindowClosing() { 178 if (error_) 179 error_->BubbleViewDidClose(browser_); 180} 181 182void GlobalErrorBubbleView::CloseBubbleView() { 183 GetWidget()->Close(); 184} 185