• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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/gtk/sad_tab_gtk.h"
6 
7 #include <string>
8 
9 #include "chrome/browser/google/google_util.h"
10 #include "chrome/browser/ui/gtk/gtk_chrome_link_button.h"
11 #include "chrome/browser/ui/gtk/gtk_util.h"
12 #include "chrome/common/url_constants.h"
13 #include "content/browser/tab_contents/tab_contents.h"
14 #include "grit/generated_resources.h"
15 #include "grit/locale_settings.h"
16 #include "grit/theme_resources.h"
17 #include "ui/base/l10n/l10n_util.h"
18 #include "ui/base/resource/resource_bundle.h"
19 
20 namespace {
21 
22 // Background color of the content (a grayish blue) for a crashed tab.
23 const GdkColor kCrashedBackgroundColor = GDK_COLOR_RGB(35, 48, 64);
24 
25 // Background color of the content (a grayish purple) for a killed
26 // tab.  TODO(gspencer): update this for the "real" color when the UI
27 // team provides one.  See http://crosbug.com/10711
28 const GdkColor kKilledBackgroundColor = GDK_COLOR_RGB(57, 48, 88);
29 
30 // Construct a centered GtkLabel with a white foreground.
31 // |format| is a printf-style format containing a %s;
32 // |str| is substituted into the format.
MakeWhiteMarkupLabel(const char * format,const std::string & str)33 GtkWidget* MakeWhiteMarkupLabel(const char* format, const std::string& str) {
34   GtkWidget* label = gtk_label_new(NULL);
35   char* markup = g_markup_printf_escaped(format, str.c_str());
36   gtk_label_set_markup(GTK_LABEL(label), markup);
37   g_free(markup);
38 
39   // Center align and justify it.
40   gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);
41   gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_CENTER);
42 
43   // Set text to white.
44   GdkColor white = gtk_util::kGdkWhite;
45   gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &white);
46 
47   return label;
48 }
49 
50 }  // namespace
51 
SadTabGtk(TabContents * tab_contents,Kind kind)52 SadTabGtk::SadTabGtk(TabContents* tab_contents, Kind kind)
53     : tab_contents_(tab_contents),
54       kind_(kind) {
55   DCHECK(tab_contents_);
56 
57   // Use an event box to get the background painting correctly.
58   event_box_.Own(gtk_event_box_new());
59   gtk_widget_modify_bg(event_box_.get(), GTK_STATE_NORMAL,
60                        kind == CRASHED ?
61                        &kCrashedBackgroundColor :
62                        &kKilledBackgroundColor);
63   // Allow ourselves to be resized arbitrarily small.
64   gtk_widget_set_size_request(event_box_.get(), 0, 0);
65 
66   GtkWidget* centering = gtk_alignment_new(0.5, 0.5, 0.0, 0.0);
67   gtk_container_add(GTK_CONTAINER(event_box_.get()), centering);
68 
69   // Use a vertical box to contain icon, title, message and link.
70   GtkWidget* vbox = gtk_vbox_new(FALSE, 0);
71   gtk_container_add(GTK_CONTAINER(centering), vbox);
72 
73   // Add center-aligned image.
74   GtkWidget* image = gtk_image_new_from_pixbuf(
75       ResourceBundle::GetSharedInstance().GetPixbufNamed(kind == CRASHED ?
76                                                          IDR_SAD_TAB :
77                                                          IDR_KILLED_TAB));
78   gtk_misc_set_alignment(GTK_MISC(image), 0.5, 0.5);
79   gtk_box_pack_start(GTK_BOX(vbox), image, FALSE, FALSE, 0);
80 
81   // Add spacer between image and title.
82   GtkWidget* spacer = gtk_label_new(NULL);
83   gtk_label_set_markup(GTK_LABEL(spacer), "<span size=\"larger\"> </span>");
84   gtk_box_pack_start(GTK_BOX(vbox), spacer, FALSE, FALSE, 0);
85 
86   // Add center-aligned title.
87   GtkWidget* title = MakeWhiteMarkupLabel(
88       "<span size=\"larger\" style=\"normal\"><b>%s</b></span>",
89       l10n_util::GetStringUTF8(kind == CRASHED ?
90                                IDS_SAD_TAB_TITLE :
91                                IDS_KILLED_TAB_TITLE));
92   gtk_box_pack_start(GTK_BOX(vbox), title, FALSE, FALSE, 0);
93 
94   // Add spacer between title and message.
95   spacer = gtk_label_new(" ");
96   gtk_box_pack_start(GTK_BOX(vbox), spacer, FALSE, FALSE, 0);
97 
98   // Add center-aligned message.
99   GtkWidget* message = MakeWhiteMarkupLabel(
100       "<span style=\"normal\">%s</span>",
101       l10n_util::GetStringUTF8(kind == CRASHED ?
102                                IDS_SAD_TAB_MESSAGE :
103                                IDS_KILLED_TAB_MESSAGE));
104   gtk_label_set_line_wrap(GTK_LABEL(message), TRUE);
105   gtk_box_pack_start(GTK_BOX(vbox), message, FALSE, FALSE, 0);
106 
107   // Add spacer between message and link.
108   spacer = gtk_label_new(" ");
109   gtk_box_pack_start(GTK_BOX(vbox), spacer, FALSE, FALSE, 0);
110 
111   if (tab_contents_ != NULL) {
112     // Add the learn-more link and center-align it in an alignment.
113     GtkWidget* link = gtk_chrome_link_button_new(
114         l10n_util::GetStringUTF8(IDS_LEARN_MORE).c_str());
115     gtk_chrome_link_button_set_normal_color(GTK_CHROME_LINK_BUTTON(link),
116                                             &gtk_util::kGdkWhite);
117     g_signal_connect(link, "clicked", G_CALLBACK(OnLinkButtonClickThunk), this);
118     GtkWidget* link_alignment = gtk_alignment_new(0.5, 0.5, 0.0, 0.0);
119     gtk_container_add(GTK_CONTAINER(link_alignment), link);
120     gtk_box_pack_start(GTK_BOX(vbox), link_alignment, FALSE, FALSE, 0);
121   }
122 
123   gtk_widget_show_all(event_box_.get());
124 }
125 
~SadTabGtk()126 SadTabGtk::~SadTabGtk() {
127   event_box_.Destroy();
128 }
129 
OnLinkButtonClick(GtkWidget * sender)130 void SadTabGtk::OnLinkButtonClick(GtkWidget* sender) {
131   if (tab_contents_ != NULL) {
132     GURL help_url =
133         google_util::AppendGoogleLocaleParam(GURL(
134             kind_ == CRASHED ?
135             chrome::kCrashReasonURL :
136             chrome::kKillReasonURL));
137     tab_contents_->OpenURL(help_url, GURL(), CURRENT_TAB, PageTransition::LINK);
138   }
139 }
140