172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Use of this source code is governed by a BSD-style license that can be
3bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// found in the LICENSE file.
4bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/views/page_info_bubble_view.h"
6bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
7bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/utf_string_conversions.h"
84a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/google/google_util.h"
9ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/browser_list.h"
1072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/views/frame/browser_view.h"
11ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/views/bubble/bubble.h"
1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/views/toolbar_view.h"
134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/common/url_constants.h"
14dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/cert_store.h"
15ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/browser/certificate_viewer.h"
16bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "grit/generated_resources.h"
17bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "grit/locale_settings.h"
1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h"
19dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "ui/gfx/image.h"
20bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "views/controls/image_view.h"
21bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "views/controls/label.h"
22bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "views/controls/separator.h"
2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "views/layout/grid_layout.h"
24bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "views/widget/widget.h"
25bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "views/window/window.h"
26bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
27bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsennamespace {
28bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
29bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Layout constants.
30bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst int kHGapToBorder = 11;
31bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst int kVGapToImage = 10;
32bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst int kVGapToHeadline = 7;
33bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst int kHGapImageToDescription = 6;
34bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst int kTextPaddingRight = 10;
35bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst int kPaddingBelowSeparator = 4;
36bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenconst int kPaddingAboveSeparator = 13;
37731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst int kIconHorizontalOffset = 27;
38731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst int kIconVerticalOffset = -7;
39731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
40731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// The duration of the animation that resizes the bubble once the async
41731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// information is provided through the ModelChanged event.
42731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickconst int kPageInfoSlideDuration = 300;
43bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
44bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// A section contains an image that shows a status (good or bad), a title, an
45bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// optional head-line (in bold) and a description.
46bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenclass Section : public views::View,
47bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                public views::LinkController {
48bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen public:
49bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  Section(PageInfoBubbleView* owner,
50bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          const PageInfoModel::SectionInfo& section_info,
51731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick          const SkBitmap* status_icon,
52bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen          bool show_cert);
53bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  virtual ~Section();
54bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
55bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // views::View methods:
56bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  virtual int GetHeightForWidth(int w);
57bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  virtual void Layout();
58bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
59bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // views::LinkController methods:
60bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  virtual void LinkActivated(views::Link* source, int event_flags);
61bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
62bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen private:
63bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Calculate the layout if |compute_bounds_only|, otherwise does Layout also.
64bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  gfx::Size LayoutItems(bool compute_bounds_only, int width);
65bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
66bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // The view that owns this Section object.
67bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  PageInfoBubbleView* owner_;
68bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
69bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // The information this view represents.
70bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  PageInfoModel::SectionInfo info_;
71bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
72bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  views::ImageView* status_image_;
73bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  views::Label* headline_label_;
74bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  views::Label* description_label_;
75bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  views::Link* link_;
76bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
77bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  DISALLOW_COPY_AND_ASSIGN(Section);
78bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen};
79bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
80bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}  // namespace
81bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
82bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen////////////////////////////////////////////////////////////////////////////////
83bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// PageInfoBubbleView
84bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenBubble* PageInfoBubbleView::bubble_ = NULL;
86ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
87bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenPageInfoBubbleView::PageInfoBubbleView(gfx::NativeWindow parent_window,
88bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                       Profile* profile,
89bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                       const GURL& url,
90bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                       const NavigationEntry::SSLStatus& ssl,
91bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                       bool show_history)
92bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    : ALLOW_THIS_IN_INITIALIZER_LIST(model_(profile, url, ssl,
93bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                            show_history, this)),
94bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      parent_window_(parent_window),
95bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      cert_id_(ssl.cert_id()),
96731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      help_center_link_(NULL),
97731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      ALLOW_THIS_IN_INITIALIZER_LIST(resize_animation_(this)),
98731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      animation_start_height_(0) {
99ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (bubble_)
100ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    bubble_->Close();
101731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (cert_id_ > 0) {
102731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    scoped_refptr<net::X509Certificate> cert;
10321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    CertStore::GetInstance()->RetrieveCert(cert_id_, &cert);
104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // When running with fake certificate (Chrome Frame), we have no os
105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // certificate, so there is no cert to show. Don't bother showing the cert
106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // info link in that case.
107731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (!cert.get() || !cert->os_cert_handle())
108731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      cert_id_ = 0;
109731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
110bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  LayoutSections();
111bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
112bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
113bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenPageInfoBubbleView::~PageInfoBubbleView() {
114bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
115bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
116bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid PageInfoBubbleView::ShowCertDialog() {
117bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  ShowCertificateViewerByID(parent_window_, cert_id_);
118bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
119bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
120bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid PageInfoBubbleView::LayoutSections() {
121bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Remove all the existing sections.
122bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  RemoveAllChildViews(true);
123bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
124bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  views::GridLayout* layout = new views::GridLayout(this);
125bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  SetLayoutManager(layout);
126bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  views::ColumnSet* columns = layout->AddColumnSet(0);
127bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  columns->AddColumn(views::GridLayout::FILL,  // Horizontal resize.
128bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                     views::GridLayout::FILL,  // Vertical resize.
129bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                     1,   // Resize weight.
130bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                     views::GridLayout::USE_PREF,  // Size type.
131bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                     0,   // Ignored for USE_PREF.
132bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                     0);  // Minimum size.
133731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // Add a column set for aligning the text when it has no icons (such as the
134731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // help center link).
135731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  columns = layout->AddColumnSet(1);
136731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  columns->AddPaddingColumn(
137731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      0, kHGapToBorder + kIconHorizontalOffset + kHGapImageToDescription);
138731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  columns->AddColumn(views::GridLayout::LEADING,  // Horizontal resize.
139731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                     views::GridLayout::FILL,     // Vertical resize.
140731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                     1,   // Resize weight.
141731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                     views::GridLayout::USE_PREF,  // Size type.
142731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                     0,   // Ignored for USE_PREF.
143731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                     0);  // Minimum size.
144bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
145bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  int count = model_.GetSectionCount();
146bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  for (int i = 0; i < count; ++i) {
147bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    PageInfoModel::SectionInfo info = model_.GetSectionInfo(i);
148bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    layout->StartRow(0, 0);
149dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const SkBitmap* icon = *model_.GetIconImage(info.icon_id);
150731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    layout->AddView(new Section(this, info, icon, cert_id_ > 0));
151bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
152bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    // Add separator after all sections.
153bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    layout->AddPaddingRow(0, kPaddingAboveSeparator);
154bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    layout->StartRow(0, 0);
155bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    layout->AddView(new views::Separator());
156bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    layout->AddPaddingRow(0, kPaddingBelowSeparator);
157bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
158bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
159bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Then add the help center link at the bottom.
160731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  layout->StartRow(0, 1);
1613f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen  help_center_link_ = new views::Link(
1623f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen      UTF16ToWide(l10n_util::GetStringUTF16(IDS_PAGE_INFO_HELP_CENTER_LINK)));
163bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  help_center_link_->SetController(this);
164bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  layout->AddView(help_center_link_);
165bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
166bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
167bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsengfx::Size PageInfoBubbleView::GetPreferredSize() {
168bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  gfx::Size size(views::Window::GetLocalizedContentsSize(
169bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      IDS_PAGEINFOBUBBLE_WIDTH_CHARS, IDS_PAGEINFOBUBBLE_HEIGHT_LINES));
170bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  size.set_height(0);
171bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
172bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  int count = model_.GetSectionCount();
173bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  for (int i = 0; i < count; ++i) {
174bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    PageInfoModel::SectionInfo info = model_.GetSectionInfo(i);
175dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    const SkBitmap* icon = *model_.GetIconImage(info.icon_id);
176731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    Section section(this, info, icon, cert_id_ > 0);
177bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    size.Enlarge(0, section.GetHeightForWidth(size.width()));
178bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
179bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
180bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Calculate how much space the separators take up (with padding).
181bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  views::Separator separator;
182bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  gfx::Size separator_size = separator.GetPreferredSize();
183bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  gfx::Size separator_plus_padding(0, separator_size.height() +
184bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                      kPaddingAboveSeparator +
185bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                      kPaddingBelowSeparator);
186bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
187bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Account for the separators and padding within sections.
188bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  size.Enlarge(0, (count - 1) * separator_plus_padding.height());
189bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
190bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Account for the Help Center link and the separator above it.
191bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  gfx::Size link_size = help_center_link_->GetPreferredSize();
192bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  size.Enlarge(0, separator_plus_padding.height() +
193bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                  link_size.height());
194bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
195731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (!resize_animation_.is_animating())
196731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return size;
197731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
198731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // We are animating from animation_start_height_ to size.
199731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  int target_height = animation_start_height_ + static_cast<int>(
200731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      (size.height() - animation_start_height_) *
201731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      resize_animation_.GetCurrentValue());
202731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  size.set_height(target_height);
203bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return size;
204bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
205bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
206bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid PageInfoBubbleView::ModelChanged() {
207731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  animation_start_height_ = bounds().height();
208bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  LayoutSections();
209731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  resize_animation_.SetSlideDuration(kPageInfoSlideDuration);
210731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  resize_animation_.Show();
211bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
212bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid PageInfoBubbleView::BubbleClosing(Bubble* bubble, bool closed_by_escape) {
214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  resize_animation_.Reset();
215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bubble_ = NULL;
216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
218dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool PageInfoBubbleView::CloseOnEscape() {
219dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return true;
220dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
221dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
222dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool PageInfoBubbleView::FadeInOnShow() {
223dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return false;
224dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
225dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
226dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstd::wstring PageInfoBubbleView::accessible_name() {
227dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  return L"PageInfoBubble";
228dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen}
229dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen
230bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid PageInfoBubbleView::LinkActivated(views::Link* source, int event_flags) {
23172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // We want to make sure the info bubble closes once the link is activated.  So
23272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // we close it explicitly rather than relying on a side-effect of opening a
23372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // new tab (see http://crosbug.com/10186).
234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bubble_->Close();
23572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
2364a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  GURL url = google_util::AppendGoogleLocaleParam(
2374a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      GURL(chrome::kPageInfoHelpCenterURL));
238bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  Browser* browser = BrowserList::GetLastActive();
239bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  browser->OpenURL(url, GURL(), NEW_FOREGROUND_TAB, PageTransition::LINK);
240bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
241bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
2423f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid PageInfoBubbleView::AnimationEnded(const ui::Animation* animation) {
243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bubble_->SizeToContents();
244731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
245731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2463f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsenvoid PageInfoBubbleView::AnimationProgressed(const ui::Animation* animation) {
247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bubble_->SizeToContents();
248731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
249731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
250bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen////////////////////////////////////////////////////////////////////////////////
251bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Section
252bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
253bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenSection::Section(PageInfoBubbleView* owner,
254bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                 const PageInfoModel::SectionInfo& section_info,
255731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                 const SkBitmap* state_icon,
256bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                 bool show_cert)
257bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    : owner_(owner),
258bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      info_(section_info),
259bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      status_image_(NULL),
260bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      link_(NULL) {
261731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (state_icon) {
262bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    status_image_ = new views::ImageView();
263731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    status_image_->SetImage(*state_icon);
264bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    AddChildView(status_image_);
265bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
266bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
267bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  headline_label_ = new views::Label(UTF16ToWideHack(info_.headline));
268bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  headline_label_->SetFont(
269bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      headline_label_->font().DeriveFont(0, gfx::Font::BOLD));
270bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  headline_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
271bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  AddChildView(headline_label_);
272bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
273bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  description_label_ = new views::Label(UTF16ToWideHack(info_.description));
274bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  description_label_->SetMultiLine(true);
275bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  description_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
276bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Allow linebreaking in the middle of words if necessary, so that extremely
277bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // long hostnames (longer than one line) will still be completely shown.
278bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  description_label_->SetAllowCharacterBreak(true);
279bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  AddChildView(description_label_);
280bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
281bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (info_.type == PageInfoModel::SECTION_INFO_IDENTITY && show_cert) {
282bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    link_ = new views::Link(
2833f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen        UTF16ToWide(l10n_util::GetStringUTF16(IDS_PAGEINFO_CERT_INFO_BUTTON)));
284bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    link_->SetController(this);
285bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    AddChildView(link_);
286bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
287bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
288bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
289bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenSection::~Section() {
290bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
291bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
292bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenint Section::GetHeightForWidth(int width) {
293bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return LayoutItems(true, width).height();
294bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
295bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
296bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid Section::Layout() {
297bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  LayoutItems(false, width());
298bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
299bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
300bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid Section::LinkActivated(views::Link* source, int event_flags) {
301bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  owner_->ShowCertDialog();
302bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
303bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
304bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsengfx::Size Section::LayoutItems(bool compute_bounds_only, int width) {
305bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  int x = kHGapToBorder;
306bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  int y = kVGapToImage;
307bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
308bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Layout the image, head-line and description.
309bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  gfx::Size size;
310bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (status_image_) {
311bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      size = status_image_->GetPreferredSize();
312bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    if (!compute_bounds_only)
313bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      status_image_->SetBounds(x, y, size.width(), size.height());
314bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
315bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  int image_height = y + size.height();
316bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  x += size.width() + kHGapImageToDescription;
317bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  int w = width - x - kTextPaddingRight;
318bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  y = kVGapToHeadline;
319bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (!headline_label_->GetText().empty()) {
320bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    size = headline_label_->GetPreferredSize();
321bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    if (!compute_bounds_only)
322bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      headline_label_->SetBounds(x, y, w > 0 ? w : 0, size.height());
323bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    y += size.height();
324bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  } else {
325bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    if (!compute_bounds_only)
326bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      headline_label_->SetBounds(x, y, 0, 0);
327bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
328bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (w > 0) {
329bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    int height = description_label_->GetHeightForWidth(w);
330bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    if (!compute_bounds_only)
331bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      description_label_->SetBounds(x, y, w, height);
332bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    y += height;
333bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  } else {
334bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    if (!compute_bounds_only)
335bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      description_label_->SetBounds(x, y, 0, 0);
336bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
337bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (info_.type == PageInfoModel::SECTION_INFO_IDENTITY && link_) {
338bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    size = link_->GetPreferredSize();
339bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    if (!compute_bounds_only)
340bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      link_->SetBounds(x, y, size.width(), size.height());
341bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    y += size.height();
342bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
343bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
344bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Make sure the image is not truncated if the text doesn't contain much.
345bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  y = std::max(y, image_height);
346bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  return gfx::Size(width, y);
347bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
348bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
349bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsennamespace browser {
350bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
351bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid ShowPageInfoBubble(gfx::NativeWindow parent,
352bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                        Profile* profile,
353bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                        const GURL& url,
354bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                        const NavigationEntry::SSLStatus& ssl,
355bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                        bool show_history) {
356bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  // Find where to point the bubble at.
357bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  BrowserView* browser_view =
358bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      BrowserView::GetBrowserViewForNativeWindow(parent);
359bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  gfx::Point point;
360bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  if (base::i18n::IsRTL()) {
361bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen    int width = browser_view->toolbar()->location_bar()->width();
362731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    point = gfx::Point(width - kIconHorizontalOffset, 0);
363bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  }
364731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  point.Offset(0, kIconVerticalOffset);
365bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  views::View::ConvertPointToScreen(browser_view->toolbar()->location_bar(),
366bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen                                    &point);
367bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  gfx::Rect bounds = browser_view->toolbar()->location_bar()->bounds();
368bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  bounds.set_origin(point);
369731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  bounds.set_width(kIconHorizontalOffset);
370bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
371ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Show the bubble. If the bubble already exist - it will be closed first.
372bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen  PageInfoBubbleView* page_info_bubble =
373bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen      new PageInfoBubbleView(parent, profile, url, ssl, show_history);
374ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Bubble* bubble =
375ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      Bubble::Show(browser_view->GetWidget(), bounds,
376ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                   BubbleBorder::TOP_LEFT,
377ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                   page_info_bubble, page_info_bubble);
378ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  page_info_bubble->set_bubble(bubble);
379bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
380bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen
381bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen}
382