Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(627)

Side by Side Diff: chrome/browser/ui/views/about_chrome_view.cc

Issue 10800096: views: Remove the implementation of about chrome dialog. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/ui/views/about_chrome_view.h ('k') | chrome/browser/ui/views/browser_dialogs.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/views/about_chrome_view.h"
6
7 #if defined(OS_WIN)
8 #include <commdlg.h>
9 #endif // defined(OS_WIN)
10
11 #include <algorithm>
12 #include <vector>
13
14 #include "base/callback.h"
15 #include "base/i18n/rtl.h"
16 #include "base/string_number_conversions.h"
17 #include "base/threading/thread_restrictions.h"
18 #include "base/utf_string_conversions.h"
19 #include "base/win/windows_version.h"
20 #include "chrome/browser/google/google_util.h"
21 #include "chrome/browser/lifetime/application_lifetime.h"
22 #include "chrome/browser/prefs/pref_service.h"
23 #include "chrome/browser/ui/browser.h"
24 #include "chrome/common/chrome_constants.h"
25 #include "chrome/common/chrome_version_info.h"
26 #include "chrome/common/url_constants.h"
27 #include "chrome/installer/util/browser_distribution.h"
28 #include "content/public/browser/user_metrics.h"
29 #include "grit/chromium_strings.h"
30 #include "grit/generated_resources.h"
31 #include "grit/locale_settings.h"
32 #include "grit/theme_resources.h"
33 #include "ui/base/l10n/l10n_util.h"
34 #include "ui/base/resource/resource_bundle.h"
35 #include "ui/gfx/canvas.h"
36 #include "ui/gfx/color_utils.h"
37 #include "ui/views/controls/button/text_button.h"
38 #include "ui/views/controls/link.h"
39 #include "ui/views/controls/textfield/textfield.h"
40 #include "ui/views/controls/throbber.h"
41 #include "ui/views/layout/layout_constants.h"
42 #include "ui/views/view_text_utils.h"
43 #include "ui/views/widget/widget.h"
44 #include "webkit/glue/webkit_glue.h"
45
46 #if defined(OS_WIN)
47 #include "base/win/win_util.h"
48 #include "chrome/browser/browser_process.h"
49 #include "chrome/installer/util/install_util.h"
50 #endif // defined(OS_WIN)
51
52 using content::OpenURLParams;
53 using content::Referrer;
54 using content::UserMetricsAction;
55
56 // The amount of vertical space separating the error label at the bottom from
57 // the rest of the text.
58 static const int kErrorLabelVerticalSpacing = 15; // Pixels.
59
60 namespace {
61 // These are used as placeholder text around the links in the text in the about
62 // dialog.
63 string16 kBeginLink() {
64 return ASCIIToUTF16("BEGIN_LINK");
65 }
66 string16 kEndLink() {
67 return ASCIIToUTF16("END_LINK");
68 }
69 string16 kBeginLinkChr() {
70 return ASCIIToUTF16("BEGIN_LINK_CHR");
71 }
72 string16 kBeginLinkOss() {
73 return ASCIIToUTF16("BEGIN_LINK_OSS");
74 }
75 string16 kEndLinkChr() {
76 return ASCIIToUTF16("END_LINK_CHR");
77 }
78 string16 kEndLinkOss() {
79 return ASCIIToUTF16("END_LINK_OSS");
80 }
81
82 // Returns a substring from |text| between start and end.
83 string16 StringSubRange(const string16& text, size_t start, size_t end) {
84 DCHECK(end > start);
85 return text.substr(start, end - start);
86 }
87
88 } // namespace
89
90 namespace chrome {
91
92 // Declared in browser_dialogs.h so that others don't
93 // need to depend on our .h.
94 void ShowAboutChromeView(gfx::NativeWindow parent, Browser* browser) {
95 views::Widget* window = views::Widget::CreateWindowWithParent(
96 new AboutChromeView(browser), parent);
97 window->Show();
98 }
99
100 } // namespace chrome
101
102 ////////////////////////////////////////////////////////////////////////////////
103 // AboutChromeView, public:
104
105 AboutChromeView::AboutChromeView(Browser* browser)
106 : browser_(browser),
107 about_dlg_background_logo_(NULL),
108 about_title_label_(NULL),
109 version_label_(NULL),
110 copyright_label_(NULL),
111 main_text_label_(NULL),
112 main_text_label_height_(0),
113 chromium_url_(NULL),
114 open_source_url_(NULL),
115 terms_of_service_url_(NULL),
116 error_label_(NULL),
117 restart_button_visible_(false),
118 chromium_url_appears_first_(true),
119 text_direction_is_rtl_(false) {
120 DCHECK(browser);
121
122 Init();
123
124 #if defined(OS_WIN) && !defined(USE_AURA)
125 google_updater_ = new GoogleUpdate();
126 google_updater_->set_status_listener(this);
127 #endif
128 }
129
130 AboutChromeView::~AboutChromeView() {
131 #if defined(OS_WIN) && !defined(USE_AURA)
132 // The Google Updater will hold a pointer to us until it reports status, so we
133 // need to let it know that we will no longer be listening.
134 if (google_updater_)
135 google_updater_->set_status_listener(NULL);
136 #endif
137 }
138
139 void AboutChromeView::Init() {
140 text_direction_is_rtl_ = base::i18n::IsRTL();
141 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
142
143 // Views we will add to the *parent* of this dialog, since it will display
144 // next to the buttons which we don't draw ourselves.
145 throbber_.reset(new views::Throbber(50, true));
146 throbber_->set_owned_by_client();
147 throbber_->SetVisible(false);
148
149 gfx::ImageSkia* success_image = rb.GetImageSkiaNamed(IDR_UPDATE_UPTODATE);
150 success_indicator_.SetImage(*success_image);
151 success_indicator_.set_owned_by_client();
152
153 gfx::ImageSkia* update_available_image = rb.GetImageSkiaNamed(
154 IDR_UPDATE_AVAILABLE);
155 update_available_indicator_.SetImage(*update_available_image);
156 update_available_indicator_.set_owned_by_client();
157
158 gfx::ImageSkia* timeout_image = rb.GetImageSkiaNamed(IDR_UPDATE_FAIL);
159 timeout_indicator_.SetImage(*timeout_image);
160 timeout_indicator_.set_owned_by_client();
161
162 update_label_.SetVisible(false);
163 update_label_.set_owned_by_client();
164
165 // Regular view controls we draw by ourself. First, we add the background
166 // image for the dialog. We have two different background images, one for
167 // LTR UIs and one for RTL UIs. We load the correct image based on the UI
168 // layout of the view.
169 about_dlg_background_logo_ = new views::ImageView();
170 gfx::ImageSkia* about_background_logo = rb.GetImageSkiaNamed(
171 base::i18n::IsRTL() ? IDR_ABOUT_BACKGROUND_RTL : IDR_ABOUT_BACKGROUND);
172
173 about_dlg_background_logo_->SetImage(*about_background_logo);
174 AddChildView(about_dlg_background_logo_);
175
176 // Add the dialog labels.
177 about_title_label_ = new views::Label(
178 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
179 about_title_label_->SetFont(ui::ResourceBundle::GetSharedInstance().GetFont(
180 ui::ResourceBundle::BaseFont).DeriveFont(18));
181 about_title_label_->SetBackgroundColor(SK_ColorWHITE);
182 about_title_label_->SetEnabledColor(SK_ColorBLACK);
183 AddChildView(about_title_label_);
184
185 // This is a text field so people can copy the version number from the dialog.
186 version_label_ = new views::Textfield();
187 chrome::VersionInfo version_info;
188 {
189 // TODO(finnur): Need to evaluate whether we should be doing IO here.
190 // See issue: http://crbug.com/101699.
191 base::ThreadRestrictions::ScopedAllowIO allow_io;
192 version_label_->SetText(UTF8ToUTF16(version_info.CreateVersionString()));
193 }
194 version_label_->SetReadOnly(true);
195 version_label_->RemoveBorder();
196 version_label_->SetTextColor(SK_ColorBLACK);
197 version_label_->SetBackgroundColor(SK_ColorWHITE);
198 version_label_->SetFont(ui::ResourceBundle::GetSharedInstance().GetFont(
199 ui::ResourceBundle::BaseFont));
200 AddChildView(version_label_);
201
202 // The copyright URL portion of the main label.
203 copyright_label_ = new views::Label(
204 l10n_util::GetStringUTF16(IDS_ABOUT_VERSION_COPYRIGHT));
205 copyright_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
206 AddChildView(copyright_label_);
207
208 main_text_label_ = new views::Label(string16());
209
210 // Figure out what to write in the main label of the About box.
211 string16 text = l10n_util::GetStringUTF16(IDS_ABOUT_OLD_VERSION_LICENSE);
212
213 chromium_url_appears_first_ =
214 text.find(kBeginLinkChr()) < text.find(kBeginLinkOss());
215
216 size_t link1 = text.find(kBeginLink());
217 DCHECK(link1 != string16::npos);
218 size_t link1_end = text.find(kEndLink(), link1);
219 DCHECK(link1_end != string16::npos);
220 size_t link2 = text.find(kBeginLink(), link1_end);
221 DCHECK(link2 != string16::npos);
222 size_t link2_end = text.find(kEndLink(), link2);
223 DCHECK(link1_end != string16::npos);
224
225 main_label_chunk1_ = text.substr(0, link1);
226 main_label_chunk2_ = StringSubRange(text, link1_end + kEndLinkOss().size(),
227 link2);
228 main_label_chunk3_ = text.substr(link2_end + kEndLinkOss().size());
229
230 // The Chromium link within the main text of the dialog.
231 chromium_url_ = new views::Link(
232 StringSubRange(text, text.find(kBeginLinkChr()) + kBeginLinkChr().size(),
233 text.find(kEndLinkChr())));
234 AddChildView(chromium_url_);
235 chromium_url_->set_listener(this);
236
237 // The Open Source link within the main text of the dialog.
238 open_source_url_ = new views::Link(
239 StringSubRange(text, text.find(kBeginLinkOss()) + kBeginLinkOss().size(),
240 text.find(kEndLinkOss())));
241 AddChildView(open_source_url_);
242 open_source_url_->set_listener(this);
243
244 #if defined(OS_WIN)
245 SkColor background_color = color_utils::GetSysSkColor(COLOR_3DFACE);
246 copyright_label_->SetBackgroundColor(background_color);
247 main_text_label_->SetBackgroundColor(background_color);
248 chromium_url_->SetBackgroundColor(background_color);
249 open_source_url_->SetBackgroundColor(background_color);
250 #endif
251
252 // Add together all the strings in the dialog for the purpose of calculating
253 // the height of the dialog. The space for the Terms of Service string is not
254 // included (it is added later, if needed).
255 string16 full_text = main_label_chunk1_ + chromium_url_->text() +
256 main_label_chunk2_ + open_source_url_->text() +
257 main_label_chunk3_;
258
259 dialog_dimensions_ = views::Widget::GetLocalizedContentsSize(
260 IDS_ABOUT_DIALOG_WIDTH_CHARS,
261 IDS_ABOUT_DIALOG_MINIMUM_HEIGHT_LINES);
262
263 // Create a label and add the full text so we can query it for the height.
264 views::Label dummy_text(full_text);
265 dummy_text.SetMultiLine(true);
266 gfx::Font font = ui::ResourceBundle::GetSharedInstance().GetFont(
267 ui::ResourceBundle::BaseFont);
268
269 // Add up the height of the various elements on the page.
270 int height = about_background_logo->height() +
271 views::kRelatedControlVerticalSpacing +
272 // Copyright line.
273 font.GetHeight() +
274 // Main label.
275 dummy_text.GetHeightForWidth(
276 dialog_dimensions_.width() - (2 * views::kPanelHorizMargin)) +
277 views::kRelatedControlVerticalSpacing;
278
279 #if defined(GOOGLE_CHROME_BUILD)
280 std::vector<size_t> url_offsets;
281 text = l10n_util::GetStringFUTF16(IDS_ABOUT_OLD_TERMS_OF_SERVICE,
282 string16(),
283 string16(),
284 &url_offsets);
285
286 main_label_chunk4_ = text.substr(0, url_offsets[0]);
287 main_label_chunk5_ = text.substr(url_offsets[0]);
288
289 // The Terms of Service URL at the bottom.
290 terms_of_service_url_ = new views::Link(
291 l10n_util::GetStringUTF16(IDS_TERMS_OF_SERVICE));
292 AddChildView(terms_of_service_url_);
293 terms_of_service_url_->set_listener(this);
294
295 error_label_ = new views::Label();
296 error_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
297 error_label_->SetMultiLine(true);
298 AddChildView(error_label_);
299
300 // Add the Terms of Service line and some whitespace.
301 height += font.GetHeight() + views::kRelatedControlVerticalSpacing;
302 #endif
303
304 // Use whichever is greater (the calculated height or the specified minimum
305 // height).
306 dialog_dimensions_.set_height(std::max(height, dialog_dimensions_.height()));
307 }
308
309 ////////////////////////////////////////////////////////////////////////////////
310 // AboutChromeView, views::View implementation:
311
312 gfx::Size AboutChromeView::GetPreferredSize() {
313 return dialog_dimensions_;
314 }
315
316 void AboutChromeView::Layout() {
317 gfx::Size panel_size = GetPreferredSize();
318
319 // Background image for the dialog.
320 gfx::Size sz = about_dlg_background_logo_->GetPreferredSize();
321 // Used to position main text below.
322 int background_image_height = sz.height();
323 about_dlg_background_logo_->SetBounds(panel_size.width() - sz.width(), 0,
324 sz.width(), sz.height());
325
326 // First label goes to the top left corner.
327 sz = about_title_label_->GetPreferredSize();
328 about_title_label_->SetBounds(
329 views::kPanelHorizMargin, views::kPanelVertMargin,
330 sz.width(), sz.height());
331
332 // Then we have the version number right below it.
333 sz = version_label_->GetPreferredSize();
334 version_label_->SetBounds(views::kPanelHorizMargin,
335 about_title_label_->y() +
336 about_title_label_->height() +
337 views::kRelatedControlVerticalSpacing,
338 panel_size.width() -
339 about_dlg_background_logo_->width(),
340 sz.height());
341
342 // For the width of the main text label we want to use up the whole panel
343 // width and remaining height, minus a little margin on each side.
344 int y_pos = background_image_height + views::kRelatedControlVerticalSpacing;
345 sz.set_width(panel_size.width() - 2 * views::kPanelHorizMargin);
346
347 // Draw the text right below the background image.
348 copyright_label_->SetBounds(views::kPanelHorizMargin,
349 y_pos,
350 sz.width(),
351 sz.height());
352
353 // Then the main_text_label.
354 main_text_label_->SetBounds(views::kPanelHorizMargin,
355 copyright_label_->y() +
356 copyright_label_->height(),
357 sz.width(),
358 main_text_label_height_);
359
360 // And the error label at the bottom of the main content. This does not fit on
361 // screen until EnlargeWindowSizeIfNeeded has been called (which happens when
362 // an error is returned from Google Update).
363 if (error_label_) {
364 sz.set_height(error_label_->GetHeightForWidth(sz.width()));
365 error_label_->SetBounds(main_text_label_->bounds().x(),
366 main_text_label_->bounds().y() +
367 main_text_label_->height() +
368 kErrorLabelVerticalSpacing,
369 sz.width(), sz.height());
370 }
371
372 // Get the y-coordinate of our parent so we can position the text left of the
373 // buttons at the bottom.
374 gfx::Rect parent_bounds = parent()->GetContentsBounds();
375
376 sz = throbber_->GetPreferredSize();
377 int throbber_topleft_x = views::kPanelHorizMargin;
378 int throbber_topleft_y =
379 parent_bounds.bottom() - sz.height() - views::kButtonVEdgeMargin - 3;
380 throbber_->SetBounds(throbber_topleft_x, throbber_topleft_y,
381 sz.width(), sz.height());
382
383 // This image is hidden (see ViewHierarchyChanged) and displayed on demand.
384 sz = success_indicator_.GetPreferredSize();
385 success_indicator_.SetBounds(throbber_topleft_x, throbber_topleft_y,
386 sz.width(), sz.height());
387
388 // This image is hidden (see ViewHierarchyChanged) and displayed on demand.
389 sz = update_available_indicator_.GetPreferredSize();
390 update_available_indicator_.SetBounds(throbber_topleft_x, throbber_topleft_y,
391 sz.width(), sz.height());
392
393 // This image is hidden (see ViewHierarchyChanged) and displayed on demand.
394 sz = timeout_indicator_.GetPreferredSize();
395 timeout_indicator_.SetBounds(throbber_topleft_x, throbber_topleft_y,
396 sz.width(), sz.height());
397
398 // The update label should be at the bottom of the screen, to the right of the
399 // throbber. It vertically lines up with the ok button, so we make sure it
400 // doesn't extend into the ok button.
401 sz = update_label_.GetPreferredSize();
402 int update_label_x = throbber_->x() + throbber_->width() +
403 views::kRelatedControlHorizontalSpacing;
404 views::DialogClientView* dialog_client_view = GetDialogClientView();
405 int max_x = parent_bounds.width();
406 if (dialog_client_view->ok_button() &&
407 dialog_client_view->ok_button()->visible()) {
408 max_x = std::min(dialog_client_view->ok_button()->x(), max_x);
409 }
410 if (dialog_client_view->cancel_button() &&
411 dialog_client_view->cancel_button()->visible()) {
412 max_x = std::min(dialog_client_view->cancel_button()->x(), max_x);
413 }
414 update_label_.SetHorizontalAlignment(views::Label::ALIGN_LEFT);
415 update_label_.SetBounds(update_label_x,
416 throbber_topleft_y + 1,
417 std::min(max_x - update_label_x, sz.width()),
418 sz.height());
419 }
420
421 void AboutChromeView::OnPaint(gfx::Canvas* canvas) {
422 views::View::OnPaint(canvas);
423
424 // Draw the background image color (and the separator) across the dialog.
425 // This will become the background for the logo image at the top of the
426 // dialog.
427 gfx::ImageSkia* background = ui::ResourceBundle::GetSharedInstance().
428 GetImageSkiaNamed(IDR_ABOUT_BACKGROUND_COLOR);
429 canvas->TileImageInt(*background, 0, 0, dialog_dimensions_.width(),
430 background->height());
431
432 gfx::Font font = ui::ResourceBundle::GetSharedInstance().GetFont(
433 ui::ResourceBundle::BaseFont);
434
435 const gfx::Rect label_bounds = main_text_label_->bounds();
436
437 views::Link* link1 =
438 chromium_url_appears_first_ ? chromium_url_ : open_source_url_;
439 views::Link* link2 =
440 chromium_url_appears_first_ ? open_source_url_ : chromium_url_;
441 gfx::Rect* rect1 = chromium_url_appears_first_ ?
442 &chromium_url_rect_ : &open_source_url_rect_;
443 gfx::Rect* rect2 = chromium_url_appears_first_ ?
444 &open_source_url_rect_ : &chromium_url_rect_;
445
446 // This struct keeps track of where to write the next word (which x,y
447 // pixel coordinate). This struct is updated after drawing text and checking
448 // if we need to wrap.
449 gfx::Size position;
450 // Draw the first text chunk and position the Chromium url.
451 view_text_utils::DrawTextAndPositionUrl(canvas, main_text_label_,
452 main_label_chunk1_, link1, rect1, &position,
453 text_direction_is_rtl_, label_bounds, font);
454 // Draw the second text chunk and position the Open Source url.
455 view_text_utils::DrawTextAndPositionUrl(canvas, main_text_label_,
456 main_label_chunk2_, link2, rect2, &position,
457 text_direction_is_rtl_, label_bounds, font);
458 // Draw the third text chunk (which has no URL associated with it).
459 view_text_utils::DrawTextAndPositionUrl(canvas, main_text_label_,
460 main_label_chunk3_, NULL, NULL, &position,
461 text_direction_is_rtl_, label_bounds, font);
462
463 #if defined(GOOGLE_CHROME_BUILD)
464 // Insert a line break and some whitespace.
465 position.set_width(0);
466 position.Enlarge(0, font.GetHeight() + views::kRelatedControlVerticalSpacing);
467
468 // And now the Terms of Service and position the TOS url.
469 view_text_utils::DrawTextAndPositionUrl(canvas, main_text_label_,
470 main_label_chunk4_, terms_of_service_url_,
471 &terms_of_service_url_rect_, &position, text_direction_is_rtl_,
472 label_bounds, font);
473 // The last text chunk doesn't have a URL associated with it.
474 view_text_utils::DrawTextAndPositionUrl(canvas, main_text_label_,
475 main_label_chunk5_, NULL, NULL, &position,
476 text_direction_is_rtl_, label_bounds, font);
477
478 // Position the TOS URL within the main label.
479 terms_of_service_url_->SetBounds(terms_of_service_url_rect_.x(),
480 terms_of_service_url_rect_.y(),
481 terms_of_service_url_rect_.width(),
482 terms_of_service_url_rect_.height());
483 #endif
484
485 // Position the URLs within the main label. First position the Chromium URL
486 // within the main label.
487 chromium_url_->SetBounds(chromium_url_rect_.x(),
488 chromium_url_rect_.y(),
489 chromium_url_rect_.width(),
490 chromium_url_rect_.height());
491 // Then position the Open Source URL within the main label.
492 open_source_url_->SetBounds(open_source_url_rect_.x(),
493 open_source_url_rect_.y(),
494 open_source_url_rect_.width(),
495 open_source_url_rect_.height());
496
497 // Save the height so we can set the bounds correctly.
498 main_text_label_height_ = position.height() + font.GetHeight();
499 }
500
501 void AboutChromeView::ViewHierarchyChanged(bool is_add,
502 views::View* parent,
503 views::View* child) {
504 // Since we want some of the controls to show up in the same visual row
505 // as the buttons, which are provided by the framework, we must add the
506 // buttons to the non-client view, which is the parent of this view.
507 // Similarly, when we're removed from the view hierarchy, we must take care
508 // to remove these items as well.
509 if (child == this) {
510 if (is_add) {
511 parent->AddChildView(&update_label_);
512 parent->AddChildView(throbber_.get());
513 parent->AddChildView(&success_indicator_);
514 success_indicator_.SetVisible(false);
515 parent->AddChildView(&update_available_indicator_);
516 update_available_indicator_.SetVisible(false);
517 parent->AddChildView(&timeout_indicator_);
518 timeout_indicator_.SetVisible(false);
519
520 #if defined(OS_WIN) && !defined(USE_AURA)
521 // On-demand updates for Chrome don't work in Vista RTM when UAC is turned
522 // off. So, in this case we just want the About box to not mention
523 // on-demand updates. Silent updates (in the background) should still
524 // work as before - enabling UAC or installing the latest service pack
525 // for Vista is another option.
526 if (!(base::win::GetVersion() == base::win::VERSION_VISTA &&
527 (base::win::OSInfo::GetInstance()->service_pack().major == 0) &&
528 !base::win::UserAccountControlIsEnabled())) {
529 UpdateStatus(UPGRADE_CHECK_STARTED, GOOGLE_UPDATE_NO_ERROR, string16());
530 // CheckForUpdate(false, ...) means don't upgrade yet.
531 google_updater_->CheckForUpdate(false, GetWidget()->GetNativeWindow());
532 }
533 #endif
534 } else {
535 parent->RemoveChildView(&update_label_);
536 parent->RemoveChildView(throbber_.get());
537 parent->RemoveChildView(&success_indicator_);
538 parent->RemoveChildView(&update_available_indicator_);
539 parent->RemoveChildView(&timeout_indicator_);
540 }
541 }
542 }
543
544 ////////////////////////////////////////////////////////////////////////////////
545 // AboutChromeView, views::DialogDelegate implementation:
546
547 string16 AboutChromeView::GetDialogButtonLabel(ui::DialogButton button) const {
548 if (button == ui::DIALOG_BUTTON_OK) {
549 return l10n_util::GetStringUTF16(IDS_RELAUNCH_AND_UPDATE);
550 } else if (button == ui::DIALOG_BUTTON_CANCEL) {
551 if (restart_button_visible_)
552 return l10n_util::GetStringUTF16(IDS_NOT_NOW);
553 // The OK button (which is the default button) has been re-purposed to be
554 // 'Restart Now' so we want the Cancel button should have the label
555 // OK but act like a Cancel button in all other ways.
556 return l10n_util::GetStringUTF16(IDS_OK);
557 }
558
559 NOTREACHED();
560 return string16();
561 }
562
563 string16 AboutChromeView::GetWindowTitle() const {
564 return l10n_util::GetStringUTF16(IDS_ABOUT_CHROME_TITLE);
565 }
566
567 bool AboutChromeView::IsDialogButtonEnabled(ui::DialogButton button) const {
568 if (button == ui::DIALOG_BUTTON_OK && !restart_button_visible_)
569 return false;
570
571 return true;
572 }
573
574 bool AboutChromeView::IsDialogButtonVisible(ui::DialogButton button) const {
575 if (button == ui::DIALOG_BUTTON_OK && !restart_button_visible_)
576 return false;
577
578 return true;
579 }
580
581 // (on ChromeOS) the default focus is ending up in the version field when
582 // the update button is hidden. This forces the focus to always be on the
583 // OK button (which is the dialog cancel button, see GetDialogButtonLabel
584 // above).
585 int AboutChromeView::GetDefaultDialogButton() const {
586 return ui::DIALOG_BUTTON_CANCEL;
587 }
588
589 bool AboutChromeView::CanResize() const {
590 return false;
591 }
592
593 bool AboutChromeView::CanMaximize() const {
594 return false;
595 }
596
597 ui::ModalType AboutChromeView::GetModalType() const {
598 return ui::MODAL_TYPE_WINDOW;
599 }
600
601 bool AboutChromeView::Accept() {
602 browser::AttemptRestart();
603 return true;
604 }
605
606 views::View* AboutChromeView::GetContentsView() {
607 return this;
608 }
609
610 ////////////////////////////////////////////////////////////////////////////////
611 // AboutChromeView, views::LinkListener implementation:
612 void AboutChromeView::LinkClicked(views::Link* source, int event_flags) {
613 GURL url;
614 if (source == terms_of_service_url_) {
615 url = GURL(chrome::kChromeUITermsURL);
616 } else if (source == chromium_url_) {
617 url = GURL(chrome::kChromiumProjectURL);
618 } else if (source == open_source_url_) {
619 url = GURL(chrome::kChromeUICreditsURL);
620 } else {
621 NOTREACHED() << "Unknown link source";
622 }
623
624 OpenURLParams params(
625 url, Referrer(), NEW_WINDOW, content::PAGE_TRANSITION_LINK, false);
626 browser_->OpenURL(params);
627 }
628
629 #if defined(OS_WIN) && !defined(USE_AURA)
630 ////////////////////////////////////////////////////////////////////////////////
631 // AboutChromeView, GoogleUpdateStatusListener implementation:
632
633 void AboutChromeView::OnReportResults(GoogleUpdateUpgradeResult result,
634 GoogleUpdateErrorCode error_code,
635 const string16& error_message,
636 const string16& version) {
637 // Drop the last reference to the object so that it gets cleaned up here.
638 google_updater_ = NULL;
639
640 // Make a note of which version Google Update is reporting is the latest
641 // version.
642 new_version_available_ = version;
643 UpdateStatus(result, error_code, error_message);
644 }
645
646 ////////////////////////////////////////////////////////////////////////////////
647 // AboutChromeView, private:
648
649 void AboutChromeView::UpdateStatus(GoogleUpdateUpgradeResult result,
650 GoogleUpdateErrorCode error_code,
651 const string16& error_message) {
652 #if !defined(GOOGLE_CHROME_BUILD)
653 // For Chromium builds it would show an error message.
654 // But it looks weird because in fact there is no error,
655 // just the update server is not available for non-official builds.
656 return;
657 #endif
658 bool show_success_indicator = false;
659 bool show_update_available_indicator = false;
660 bool show_timeout_indicator = false;
661 bool show_throbber = false;
662 bool show_update_label = true; // Always visible, except at start.
663
664 switch (result) {
665 case UPGRADE_STARTED:
666 content::RecordAction(UserMetricsAction("Upgrade_Started"));
667 show_throbber = true;
668 update_label_.SetText(l10n_util::GetStringUTF16(IDS_UPGRADE_STARTED));
669 break;
670 case UPGRADE_CHECK_STARTED:
671 content::RecordAction(UserMetricsAction("UpgradeCheck_Started"));
672 show_throbber = true;
673 update_label_.SetText(
674 l10n_util::GetStringUTF16(IDS_UPGRADE_CHECK_STARTED));
675 break;
676 case UPGRADE_IS_AVAILABLE:
677 content::RecordAction(
678 UserMetricsAction("UpgradeCheck_UpgradeIsAvailable"));
679 DCHECK(!google_updater_); // Should have been nulled out already.
680 google_updater_ = new GoogleUpdate();
681 google_updater_->set_status_listener(this);
682 UpdateStatus(UPGRADE_STARTED, GOOGLE_UPDATE_NO_ERROR, string16());
683 // CheckForUpdate(true,...) means perform upgrade if new version found.
684 google_updater_->CheckForUpdate(true, GetWidget()->GetNativeWindow());
685 // TODO(seanparent): Need to see if this code needs to change to
686 // force a machine restart.
687 return;
688 case UPGRADE_ALREADY_UP_TO_DATE: {
689 // The extra version check is necessary on Windows because the application
690 // may be already up to date on disk though the running app is still
691 // out of date. Chrome OS doesn't quite have this issue since the
692 // OS/App are updated together. If a newer version of the OS has been
693 // staged then UPGRADE_SUCESSFUL will be returned.
694 // Google Update reported that Chrome is up-to-date. Now make sure that we
695 // are running the latest version and if not, notify the user by falling
696 // into the next case of UPGRADE_SUCCESSFUL.
697 BrowserDistribution* dist = BrowserDistribution::GetDistribution();
698 base::ThreadRestrictions::ScopedAllowIO allow_io;
699 chrome::VersionInfo version_info;
700 Version installed_version;
701 InstallUtil::GetChromeVersion(dist, false, &installed_version);
702 if (!installed_version.IsValid()) {
703 // User-level Chrome is not installed, check system-level.
704 InstallUtil::GetChromeVersion(dist, true, &installed_version);
705 }
706 Version running_version(version_info.Version());
707 if (!installed_version.IsValid() ||
708 (installed_version.CompareTo(running_version) <= 0)) {
709 content::RecordAction(
710 UserMetricsAction("UpgradeCheck_AlreadyUpToDate"));
711 string16 update_label_text = l10n_util::GetStringFUTF16(
712 IDS_UPGRADE_ALREADY_UP_TO_DATE,
713 ASCIIToUTF16(version_info.Version()));
714 if (base::i18n::IsRTL()) {
715 update_label_text.push_back(
716 static_cast<wchar_t>(base::i18n::kLeftToRightMark));
717 }
718 update_label_.SetText(update_label_text);
719 show_success_indicator = true;
720 break;
721 }
722 // No break here as we want to notify user about upgrade if there is one.
723 }
724 case UPGRADE_SUCCESSFUL: {
725 if (result == UPGRADE_ALREADY_UP_TO_DATE)
726 content::RecordAction(
727 UserMetricsAction("UpgradeCheck_AlreadyUpgraded"));
728 else
729 content::RecordAction(UserMetricsAction("UpgradeCheck_Upgraded"));
730 restart_button_visible_ = true;
731 update_label_.SetText(
732 l10n_util::GetStringUTF16(IDS_OLD_UPGRADE_SUCCESSFUL_RELAUNCH));
733 show_success_indicator = true;
734 break;
735 }
736 case UPGRADE_ERROR: {
737 content::RecordAction(UserMetricsAction("UpgradeCheck_Error"));
738 if (!error_message.empty() && error_label_) {
739 error_label_->SetText(
740 l10n_util::GetStringFUTF16(IDS_ABOUT_BOX_ERROR_DURING_UPDATE_CHECK,
741 error_message));
742 int added_height = EnlargeWindowSizeIfNeeded();
743 dialog_dimensions_.set_height(dialog_dimensions_.height() +
744 added_height);
745 }
746 restart_button_visible_ = false;
747 if (error_code != GOOGLE_UPDATE_DISABLED_BY_POLICY) {
748 update_label_.SetText(
749 l10n_util::GetStringFUTF16Int(IDS_UPGRADE_ERROR, error_code));
750 } else {
751 update_label_.SetText(
752 l10n_util::GetStringUTF16(IDS_UPGRADE_DISABLED_BY_POLICY));
753 }
754 show_timeout_indicator = true;
755 break;
756 }
757 default:
758 NOTREACHED();
759 }
760
761 success_indicator_.SetVisible(show_success_indicator);
762 update_available_indicator_.SetVisible(show_update_available_indicator);
763 timeout_indicator_.SetVisible(show_timeout_indicator);
764 update_label_.SetVisible(show_update_label);
765 throbber_->SetVisible(show_throbber);
766 if (show_throbber)
767 throbber_->Start();
768 else
769 throbber_->Stop();
770
771 // We have updated controls on the parent, so we need to update its layout.
772 parent()->Layout();
773
774 // Check button may have appeared/disappeared. We cannot call this during
775 // ViewHierarchyChanged because the view hasn't been added to a Widget yet.
776 if (GetWidget())
777 GetDialogClientView()->UpdateDialogButtons();
778 }
779
780 int AboutChromeView::EnlargeWindowSizeIfNeeded() {
781 if (!error_label_ || error_label_->text().empty())
782 return 0;
783
784 // This will enlarge the window each time the function is called, which is
785 // fine since we only receive status once from Google Update.
786 gfx::Rect window_rect = GetWidget()->GetWindowBoundsInScreen();
787 int height = error_label_->GetHeightForWidth(
788 dialog_dimensions_.width() - (2 * views::kPanelHorizMargin)) +
789 views::kRelatedControlVerticalSpacing;
790 window_rect.set_height(window_rect.height() + height);
791 GetWidget()->SetBounds(window_rect);
792
793 return height;
794 }
795
796 #endif
OLDNEW
« no previous file with comments | « chrome/browser/ui/views/about_chrome_view.h ('k') | chrome/browser/ui/views/browser_dialogs.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698