Home | History | Annotate | Download | only in gtk
      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.
     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 
     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 
    126 SadTabGtk::~SadTabGtk() {
    127   event_box_.Destroy();
    128 }
    129 
    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