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

Side by Side Diff: chrome/browser/gtk/about_chrome_dialog.cc

Issue 155040: GTK: Give the aboot dialog a facelift.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 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 | « no previous file | chrome/browser/gtk/gtk_chrome_link_button.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/gtk/about_chrome_dialog.h" 5 #include "chrome/browser/gtk/about_chrome_dialog.h"
6 6
7 #include <gtk/gtk.h> 7 #include <gtk/gtk.h>
8 #include <wchar.h>
9 8
10 #include "app/l10n_util.h" 9 #include "app/l10n_util.h"
11 #include "app/resource_bundle.h" 10 #include "app/resource_bundle.h"
12 #include "base/file_version_info.h" 11 #include "base/file_version_info.h"
13 #include "base/gfx/gtk_util.h" 12 #include "base/gfx/gtk_util.h"
13 #include "chrome/browser/browser_list.h"
14 #include "chrome/browser/gtk/gtk_chrome_link_button.h"
15 #include "chrome/browser/profile.h"
14 #include "chrome/common/chrome_constants.h" 16 #include "chrome/common/chrome_constants.h"
15 #include "chrome/browser/profile.h"
16 #include "chrome/common/gtk_util.h" 17 #include "chrome/common/gtk_util.h"
17 #include "grit/chromium_strings.h" 18 #include "grit/chromium_strings.h"
18 #include "grit/generated_resources.h" 19 #include "grit/generated_resources.h"
19 #include "grit/locale_settings.h" 20 #include "grit/locale_settings.h"
20 #include "grit/theme_resources.h" 21 #include "grit/theme_resources.h"
21 #include "webkit/glue/webkit_glue.h" 22 #include "webkit/glue/webkit_glue.h"
22 23
23 namespace { 24 namespace {
24 // The pixel width of the version text field. Ideally, we'd like to have the
25 // bounds set to the edge of the icon. However, the icon is not a view but a
26 // part of the background, so we have to hard code the width to make sure
27 // the version field doesn't overlap it.
28 const int kVersionFieldWidth = 195;
29 25
30 // The URLs that you navigate to when clicking the links in the About dialog. 26 // The URLs that you navigate to when clicking the links in the About dialog.
31 const wchar_t* const kChromiumUrl = L"http://www.chromium.org/"; 27 const char* const kAcknowledgements = "about:credits";
32 const wchar_t* const kAcknowledgements = L"about:credits"; 28 const char* const kTOS = "about:terms";
33 const wchar_t* const kTOS = L"about:terms";
34 29
35 // Left or right margin. 30 // Left or right margin.
36 const int kPanelHorizMargin = 13; 31 const int kPanelHorizMargin = 13;
37 32
38 // Top or bottom margin. 33 // Top or bottom margin.
39 const int kPanelVertMargin = 13; 34 const int kPanelVertMargin = 20;
35
36 // Extra spacing between product name and version number.
37 const int kExtraLineSpacing = 5;
40 38
41 // These are used as placeholder text around the links in the text in the about 39 // These are used as placeholder text around the links in the text in the about
42 // dialog. 40 // dialog.
43 const wchar_t* kBeginLinkChr = L"BEGIN_LINK_CHR"; 41 const char* kBeginLinkChr = "BEGIN_LINK_CHR";
44 const wchar_t* kBeginLinkOss = L"BEGIN_LINK_OSS"; 42 const char* kBeginLinkOss = "BEGIN_LINK_OSS";
45 const wchar_t* kEndLinkChr = L"END_LINK_CHR"; 43 // We don't actually use this one.
46 const wchar_t* kEndLinkOss = L"END_LINK_OSS"; 44 // const char* kEndLinkChr = "END_LINK_CHR";
47 const wchar_t* kBeginLink = L"BEGIN_LINK"; 45 const char* kEndLinkOss = "END_LINK_OSS";
48 const wchar_t* kEndLink = L"END_LINK"; 46 const char* kBeginLink = "BEGIN_LINK";
49 47 const char* kEndLink = "END_LINK";
50 void RemoveText(std::wstring* text, const wchar_t* to_remove) {
51 size_t start = text->find(to_remove, 0);
52 if (start != std::string::npos) {
53 size_t length = wcslen(to_remove);
54 *text = text->substr(0, start) + text->substr(start + length);
55 }
56 }
57 48
58 void OnDialogResponse(GtkDialog* dialog, int response_id) { 49 void OnDialogResponse(GtkDialog* dialog, int response_id) {
59 // We're done. 50 // We're done.
60 gtk_widget_destroy(GTK_WIDGET(dialog)); 51 gtk_widget_destroy(GTK_WIDGET(dialog));
61 } 52 }
62 53
63 void FixLabelWrappingCallback(GtkWidget *label, 54 void FixLabelWrappingCallback(GtkWidget *label,
64 GtkAllocation *allocation, 55 GtkAllocation *allocation,
65 gpointer data) { 56 gpointer data) {
66 gtk_widget_set_size_request(label, allocation->width, -1); 57 gtk_widget_set_size_request(label, allocation->width, -1);
67 } 58 }
68 59
69 GtkWidget* MakeMarkupLabel(const char* format, const std::wstring& str) { 60 GtkWidget* MakeMarkupLabel(const char* format, const std::string& str) {
70 GtkWidget* label = gtk_label_new(NULL); 61 GtkWidget* label = gtk_label_new(NULL);
71 char* markup = g_markup_printf_escaped( 62 char* markup = g_markup_printf_escaped(format, str.c_str());
72 format, WideToUTF8(str).c_str());
73 gtk_label_set_markup(GTK_LABEL(label), markup); 63 gtk_label_set_markup(GTK_LABEL(label), markup);
74 g_free(markup); 64 g_free(markup);
75 65
66 // Left align it.
67 gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5);
68
76 return label; 69 return label;
77 } 70 }
78 71
72 void OnLinkButtonClick(GtkWidget* button, const char* url) {
73 BrowserList::GetLastActive()->
74 OpenURL(GURL(url), GURL(), NEW_WINDOW, PageTransition::LINK);
75 }
76
77 const char* GetChromiumUrl() {
78 static std::string url(l10n_util::GetStringUTF8(IDS_CHROMIUM_PROJECT_URL));
79 return url.c_str();
80 }
81
79 } // namespace 82 } // namespace
80 83
81 void ShowAboutDialogForProfile(GtkWindow* parent, Profile* profile) { 84 void ShowAboutDialogForProfile(GtkWindow* parent, Profile* profile) {
82 ResourceBundle& rb = ResourceBundle::GetSharedInstance(); 85 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
83 static GdkPixbuf* background = rb.GetPixbufNamed(IDR_ABOUT_BACKGROUND); 86 static GdkPixbuf* background = rb.GetPixbufNamed(IDR_ABOUT_BACKGROUND);
84 scoped_ptr<FileVersionInfo> version_info( 87 scoped_ptr<FileVersionInfo> version_info(
85 FileVersionInfo::CreateFileVersionInfoForCurrentModule()); 88 FileVersionInfo::CreateFileVersionInfoForCurrentModule());
86 std::wstring current_version = version_info->file_version(); 89 std::wstring current_version = version_info->file_version();
87 #if !defined(GOOGLE_CHROME_BUILD) 90 #if !defined(GOOGLE_CHROME_BUILD)
88 current_version += L" ("; 91 current_version += L" (";
(...skipping 20 matching lines...) Expand all
109 GtkWidget* ebox = gtk_event_box_new(); 112 GtkWidget* ebox = gtk_event_box_new();
110 gtk_widget_modify_bg(ebox, GTK_STATE_NORMAL, &gfx::kGdkWhite); 113 gtk_widget_modify_bg(ebox, GTK_STATE_NORMAL, &gfx::kGdkWhite);
111 114
112 GtkWidget* hbox = gtk_hbox_new(FALSE, 0); 115 GtkWidget* hbox = gtk_hbox_new(FALSE, 0);
113 116
114 GtkWidget* text_alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); 117 GtkWidget* text_alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
115 gtk_alignment_set_padding(GTK_ALIGNMENT(text_alignment), 118 gtk_alignment_set_padding(GTK_ALIGNMENT(text_alignment),
116 kPanelVertMargin, kPanelVertMargin, 119 kPanelVertMargin, kPanelVertMargin,
117 kPanelHorizMargin, kPanelHorizMargin); 120 kPanelHorizMargin, kPanelHorizMargin);
118 121
119 GtkWidget* text_vbox = gtk_vbox_new(FALSE, 0); 122 GtkWidget* text_vbox = gtk_vbox_new(FALSE, kExtraLineSpacing);
120 123
121 GtkWidget* product_label = MakeMarkupLabel( 124 GtkWidget* product_label = MakeMarkupLabel(
122 "<span font_desc=\"18\" weight=\"bold\" style=\"normal\">%s</span>", 125 "<span font_desc=\"18\" weight=\"bold\" style=\"normal\">%s</span>",
123 l10n_util::GetString(IDS_PRODUCT_NAME)); 126 l10n_util::GetStringUTF8(IDS_PRODUCT_NAME));
124 gtk_box_pack_start(GTK_BOX(text_vbox), product_label, FALSE, FALSE, 0); 127 gtk_box_pack_start(GTK_BOX(text_vbox), product_label, FALSE, FALSE, 0);
125 128
126 GtkWidget* version_label = MakeMarkupLabel( 129 GtkWidget* version_label = gtk_label_new(WideToUTF8(current_version).c_str());
127 "<span style=\"italic\">%s</span>", 130 gtk_misc_set_alignment(GTK_MISC(version_label), 0.0, 0.5);
128 current_version);
129 gtk_label_set_selectable(GTK_LABEL(version_label), TRUE); 131 gtk_label_set_selectable(GTK_LABEL(version_label), TRUE);
130 gtk_box_pack_start(GTK_BOX(text_vbox), version_label, FALSE, FALSE, 0); 132 gtk_box_pack_start(GTK_BOX(text_vbox), version_label, FALSE, FALSE, 0);
131 133
132 gtk_container_add(GTK_CONTAINER(text_alignment), text_vbox); 134 gtk_container_add(GTK_CONTAINER(text_alignment), text_vbox);
133 gtk_box_pack_start(GTK_BOX(hbox), text_alignment, TRUE, FALSE, 0); 135 gtk_box_pack_start(GTK_BOX(hbox), text_alignment, TRUE, TRUE, 0);
134 136
135 GtkWidget* image_vbox = gtk_vbox_new(FALSE, 0); 137 GtkWidget* image_vbox = gtk_vbox_new(FALSE, 0);
136 gtk_box_pack_end(GTK_BOX(image_vbox), 138 gtk_box_pack_end(GTK_BOX(image_vbox),
137 gtk_image_new_from_pixbuf(background), 139 gtk_image_new_from_pixbuf(background),
138 FALSE, FALSE, 0); 140 FALSE, FALSE, 0);
139 141
140 gtk_box_pack_start(GTK_BOX(hbox), image_vbox, FALSE, FALSE, 0); 142 gtk_box_pack_start(GTK_BOX(hbox), image_vbox, FALSE, FALSE, 0);
141 gtk_container_add(GTK_CONTAINER(ebox), hbox); 143 gtk_container_add(GTK_CONTAINER(ebox), hbox);
142 gtk_box_pack_start(GTK_BOX(content_area), ebox, TRUE, TRUE, 0); 144 gtk_box_pack_start(GTK_BOX(content_area), ebox, TRUE, TRUE, 0);
143 145
144 // We use a separate box for the licensing etc. text. See the comment near 146 // We use a separate box for the licensing etc. text. See the comment near
145 // the top of this function about using a special layout for this dialog. 147 // the top of this function about using a special layout for this dialog.
146 GtkWidget* vbox = gtk_vbox_new(FALSE, gtk_util::kControlSpacing); 148 GtkWidget* vbox = gtk_vbox_new(FALSE, gtk_util::kControlSpacing);
147 gtk_container_set_border_width(GTK_CONTAINER(vbox), 149 gtk_container_set_border_width(GTK_CONTAINER(vbox),
148 gtk_util::kContentAreaBorder); 150 gtk_util::kContentAreaBorder);
149 151
150 GtkWidget* copyright_label = MakeMarkupLabel( 152 GtkWidget* copyright_label = MakeMarkupLabel(
151 "<span size=\"smaller\">%s</span>", 153 "<span size=\"smaller\">%s</span>",
152 l10n_util::GetString(IDS_ABOUT_VERSION_COPYRIGHT)); 154 l10n_util::GetStringUTF8(IDS_ABOUT_VERSION_COPYRIGHT));
153 gtk_box_pack_start(GTK_BOX(vbox), copyright_label, TRUE, TRUE, 5); 155 gtk_box_pack_start(GTK_BOX(vbox), copyright_label, TRUE, TRUE, 5);
154 156
155 // TODO(erg): Figure out how to really insert links. We could just depend on 157 std::string license = l10n_util::GetStringUTF8(IDS_ABOUT_VERSION_LICENSE);
156 // (or include the source of) libsexy's SexyUrlLabel gtk widget... 158 bool chromium_url_appears_first =
157 std::wstring license = l10n_util::GetString(IDS_ABOUT_VERSION_LICENSE); 159 license.find(kBeginLinkChr) < license.find(kBeginLinkOss);
158 RemoveText(&license, kBeginLinkChr); 160 size_t link1 = license.find(kBeginLink);
159 RemoveText(&license, kBeginLinkOss); 161 DCHECK(link1 != std::string::npos);
160 RemoveText(&license, kBeginLink); 162 size_t link1_end = license.find(kEndLink, link1);
161 RemoveText(&license, kEndLinkChr); 163 DCHECK(link1_end != std::string::npos);
162 RemoveText(&license, kEndLinkOss); 164 size_t link2 = license.find(kBeginLink, link1_end);
163 RemoveText(&license, kEndLink); 165 DCHECK(link2 != std::string::npos);
166 size_t link2_end = license.find(kEndLink, link2);
167 DCHECK(link1_end != std::string::npos);
164 168
165 GtkWidget* license_label = MakeMarkupLabel( 169 GtkWidget* license_chunk1 = MakeMarkupLabel(
166 "<span size=\"smaller\">%s</span>", license); 170 "<span size=\"smaller\">%s</span>",
171 license.substr(0, link1));
172 GtkWidget* license_chunk2 = MakeMarkupLabel(
173 "<span size=\"smaller\">%s</span>",
174 license.substr(link1_end + strlen(kEndLinkOss),
175 link2 - link1_end - strlen(kEndLinkOss)));
176 GtkWidget* license_chunk3 = MakeMarkupLabel(
177 "<span size=\"smaller\">%s</span>",
178 license.substr(link2_end + strlen(kEndLinkOss)));
167 179
168 gtk_label_set_line_wrap(GTK_LABEL(license_label), TRUE); 180 std::string first_link_text =
169 gtk_misc_set_alignment(GTK_MISC(license_label), 0, 0); 181 std::string("<span size=\"smaller\">") +
170 gtk_box_pack_start(GTK_BOX(vbox), license_label, TRUE, TRUE, 0); 182 license.substr(link1 + strlen(kBeginLinkOss),
183 link1_end - link1 - strlen(kBeginLinkOss)) +
184 std::string("</span>");
185 std::string second_link_text =
186 std::string("<span size=\"smaller\">") +
187 license.substr(link2 + strlen(kBeginLinkOss),
188 link2_end - link2 - strlen(kBeginLinkOss)) +
189 std::string("</span>");
171 190
172 // Hack around Gtk's not-so-good label wrapping, as described here: 191 GtkWidget* first_link =
173 // http://blog.16software.com/dynamic-label-wrapping-in-gtk 192 gtk_chrome_link_button_new_with_markup(first_link_text.c_str());
174 g_signal_connect(G_OBJECT(license_label), "size-allocate", 193 GtkWidget* second_link =
175 G_CALLBACK(FixLabelWrappingCallback), NULL); 194 gtk_chrome_link_button_new_with_markup(second_link_text.c_str());
195 if (!chromium_url_appears_first) {
196 GtkWidget* swap = second_link;
197 second_link = first_link;
198 first_link = swap;
199 }
176 200
201 g_signal_connect(chromium_url_appears_first ? first_link : second_link,
202 "clicked", G_CALLBACK(OnLinkButtonClick),
203 const_cast<char*>(GetChromiumUrl()));
204 g_signal_connect(chromium_url_appears_first ? second_link : first_link,
205 "clicked", G_CALLBACK(OnLinkButtonClick),
206 const_cast<char*>(kAcknowledgements));
207
208 GtkWidget* license_hbox = gtk_hbox_new(FALSE, 0);
209 gtk_box_pack_start(GTK_BOX(license_hbox), license_chunk1,
210 FALSE, FALSE, 0);
211 gtk_box_pack_start(GTK_BOX(license_hbox), first_link,
212 FALSE, FALSE, 0);
213 gtk_box_pack_start(GTK_BOX(license_hbox), license_chunk2,
214 FALSE, FALSE, 0);
215
216 // Since there's no good way to dynamically wrap the license block, force
217 // a line break right before the second link (which matches en-US Windows
218 // chromium).
219 GtkWidget* license_hbox2 = gtk_hbox_new(FALSE, 0);
220 gtk_box_pack_start(GTK_BOX(license_hbox2), second_link,
221 FALSE, FALSE, 0);
222 gtk_box_pack_start(GTK_BOX(license_hbox2), license_chunk3,
223 FALSE, FALSE, 0);
224
225 GtkWidget* license_vbox = gtk_vbox_new(FALSE, 0);
226 gtk_box_pack_start(GTK_BOX(license_vbox), license_hbox, FALSE, FALSE, 0);
227 gtk_box_pack_start(GTK_BOX(license_vbox), license_hbox2, FALSE, FALSE, 0);
228
229 gtk_box_pack_start(GTK_BOX(vbox), license_vbox, TRUE, TRUE, 0);
177 gtk_box_pack_start(GTK_BOX(content_area), vbox, TRUE, TRUE, 0); 230 gtk_box_pack_start(GTK_BOX(content_area), vbox, TRUE, TRUE, 0);
178 231
179 g_signal_connect(dialog, "response", G_CALLBACK(OnDialogResponse), NULL); 232 g_signal_connect(dialog, "response", G_CALLBACK(OnDialogResponse), NULL);
180 gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE); 233 gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
181 gtk_widget_show_all(dialog); 234 gtk_widget_show_all(dialog);
182 } 235 }
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/gtk/gtk_chrome_link_button.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698