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

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

Issue 1081007: Implement ConfirmInfoBar link support on GTK... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years, 9 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/gtk/infobar_gtk.h ('k') | no next file » | 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/infobar_gtk.h" 5 #include "chrome/browser/gtk/infobar_gtk.h"
6 6
7 #include <gtk/gtk.h> 7 #include <gtk/gtk.h>
8 8
9 #include "base/utf_string_conversions.h" 9 #include "base/utf_string_conversions.h"
10 #include "chrome/browser/gtk/custom_button.h" 10 #include "chrome/browser/gtk/custom_button.h"
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 NotificationService::AllSources()); 160 NotificationService::AllSources());
161 UpdateBorderColor(); 161 UpdateBorderColor();
162 } 162 }
163 163
164 void InfoBar::Observe(NotificationType type, 164 void InfoBar::Observe(NotificationType type,
165 const NotificationSource& source, 165 const NotificationSource& source,
166 const NotificationDetails& details) { 166 const NotificationDetails& details) {
167 UpdateBorderColor(); 167 UpdateBorderColor();
168 } 168 }
169 169
170 // TODO(joth): This method factors out some common functionality between the
171 // various derived infobar classes, however the class hierarchy itself could
172 // use refactoring to reduce this duplication. http://crbug.com/38924
173 void InfoBar::AddLabelAndLink(const std::wstring& display_text,
174 const std::wstring& link_text,
175 size_t link_offset,
176 guint link_padding,
177 GCallback callback) {
178 GtkWidget* link_button = NULL;
179 if (link_text.empty()) {
180 // No link text, so skip creating the link and splitting display_text.
181 link_offset = std::wstring::npos;
182 } else {
183 // If we have some link text, create the link button.
184 link_button = gtk_chrome_link_button_new(WideToUTF8(link_text).c_str());
185 gtk_chrome_link_button_set_use_gtk_theme(
186 GTK_CHROME_LINK_BUTTON(link_button), FALSE);
187 DCHECK(callback);
188 g_signal_connect(link_button, "clicked", callback, this);
189 gtk_util::SetButtonTriggersNavigation(link_button);
190 }
191
192 GtkWidget* hbox = gtk_hbox_new(FALSE, 0);
193 // We want the link to be horizontally shrinkable, so that the Chrome
194 // window can be resized freely even with a very long link.
195 gtk_widget_set_size_request(hbox, 0, -1);
196 gtk_box_pack_start(GTK_BOX(hbox_), hbox, TRUE, TRUE, 0);
197
198 // If link_offset is npos, we right-align the link instead of embedding it
199 // in the text.
200 if (link_offset == std::wstring::npos) {
201 if (link_button)
202 gtk_box_pack_end(GTK_BOX(hbox), link_button, FALSE, FALSE, 0);
203 GtkWidget* label = gtk_label_new(WideToUTF8(display_text).c_str());
204 // In order to avoid the link_button and the label overlapping with each
205 // other, we make the label shrinkable.
206 gtk_widget_set_size_request(label, 0, -1);
207 gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_END);
208 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
209 gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &gfx::kGdkBlack);
210 gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
211 } else {
212 DCHECK(link_button);
213 // Need to insert the link inside the display text.
214 GtkWidget* initial_label = gtk_label_new(
215 WideToUTF8(display_text.substr(0, link_offset)).c_str());
216 GtkWidget* trailing_label = gtk_label_new(
217 WideToUTF8(display_text.substr(link_offset)).c_str());
218
219 // TODO(joth): Unlike the right-align case above, none of the label widgets
220 // are set as shrinkable here, meaning the text will run under the close
221 // button etc. when the width is restricted, rather than eliding.
222 gtk_widget_modify_fg(initial_label, GTK_STATE_NORMAL, &gfx::kGdkBlack);
223 gtk_widget_modify_fg(trailing_label, GTK_STATE_NORMAL, &gfx::kGdkBlack);
224
225 // We don't want any spacing between the elements, so we pack them into
226 // this hbox that doesn't use kElementPadding.
227 gtk_box_pack_start(GTK_BOX(hbox), initial_label, FALSE, FALSE, 0);
228 gtk_util::CenterWidgetInHBox(hbox, link_button, false, link_padding);
229 gtk_box_pack_start(GTK_BOX(hbox), trailing_label, FALSE, FALSE, 0);
230 }
231 }
232
170 void InfoBar::UpdateBorderColor() { 233 void InfoBar::UpdateBorderColor() {
171 GdkColor border_color = theme_provider_->GetBorderColor(); 234 GdkColor border_color = theme_provider_->GetBorderColor();
172 gtk_widget_modify_bg(border_bin_.get(), GTK_STATE_NORMAL, &border_color); 235 gtk_widget_modify_bg(border_bin_.get(), GTK_STATE_NORMAL, &border_color);
173 } 236 }
174 237
175 // static 238 // static
176 void InfoBar::OnCloseButton(GtkWidget* button, InfoBar* info_bar) { 239 void InfoBar::OnCloseButton(GtkWidget* button, InfoBar* info_bar) {
177 if (info_bar->delegate_) 240 if (info_bar->delegate_)
178 info_bar->delegate_->InfoBarDismissed(); 241 info_bar->delegate_->InfoBarDismissed();
179 info_bar->RemoveInfoBar(); 242 info_bar->RemoveInfoBar();
180 } 243 }
181 244
182 // AlertInfoBar ---------------------------------------------------------------- 245 // AlertInfoBar ----------------------------------------------------------------
183 246
184 class AlertInfoBar : public InfoBar { 247 class AlertInfoBar : public InfoBar {
185 public: 248 public:
186 explicit AlertInfoBar(AlertInfoBarDelegate* delegate) 249 explicit AlertInfoBar(AlertInfoBarDelegate* delegate)
187 : InfoBar(delegate) { 250 : InfoBar(delegate) {
188 std::wstring text = delegate->GetMessageText(); 251 AddLabelAndLink(delegate->GetMessageText(), std::wstring(), 0, 0, NULL);
189 GtkWidget* label = gtk_label_new(WideToUTF8(text).c_str());
190 // We want the label to be horizontally shrinkable, so that the Chrome
191 // window can be resized freely even with a very long message.
192 gtk_widget_set_size_request(label, 0, -1);
193 gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_END);
194 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
195 gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &gfx::kGdkBlack);
196 gtk_box_pack_start(GTK_BOX(hbox_), label, TRUE, TRUE, 0);
197
198 gtk_widget_show_all(border_bin_.get()); 252 gtk_widget_show_all(border_bin_.get());
199 } 253 }
200 }; 254 };
201 255
202 // LinkInfoBar ----------------------------------------------------------------- 256 // LinkInfoBar -----------------------------------------------------------------
203 257
204 class LinkInfoBar : public InfoBar { 258 class LinkInfoBar : public InfoBar {
205 public: 259 public:
206 explicit LinkInfoBar(LinkInfoBarDelegate* delegate) 260 explicit LinkInfoBar(LinkInfoBarDelegate* delegate)
207 : InfoBar(delegate) { 261 : InfoBar(delegate) {
208 size_t link_offset; 262 size_t link_offset;
209 std::wstring display_text = 263 std::wstring display_text =
210 delegate->GetMessageTextWithOffset(&link_offset); 264 delegate->GetMessageTextWithOffset(&link_offset);
211 std::wstring link_text = delegate->GetLinkText(); 265 std::wstring link_text = delegate->GetLinkText();
212 266 AddLabelAndLink(display_text, link_text, link_offset, 0,
213 // Create the link button. 267 G_CALLBACK(OnLinkClick));
214 GtkWidget* link_button =
215 gtk_chrome_link_button_new(WideToUTF8(link_text).c_str());
216 gtk_chrome_link_button_set_use_gtk_theme(
217 GTK_CHROME_LINK_BUTTON(link_button), FALSE);
218 g_signal_connect(link_button, "clicked",
219 G_CALLBACK(OnLinkClick), this);
220 gtk_util::SetButtonTriggersNavigation(link_button);
221
222 GtkWidget* hbox = gtk_hbox_new(FALSE, 0);
223 // We want the link to be horizontally shrinkable, so that the Chrome
224 // window can be resized freely even with a very long link.
225 gtk_widget_set_size_request(hbox, 0, -1);
226 gtk_box_pack_start(GTK_BOX(hbox_), hbox, TRUE, TRUE, 0);
227 // If link_offset is npos, we right-align the link instead of embedding it
228 // in the text.
229 if (link_offset == std::wstring::npos) {
230 gtk_box_pack_end(GTK_BOX(hbox), link_button, FALSE, FALSE, 0);
231 GtkWidget* label = gtk_label_new(WideToUTF8(display_text).c_str());
232 // In order to avoid the link_button and the label overlapping with each
233 // other, we make the label shrinkable.
234 gtk_widget_set_size_request(label, 0, -1);
235 gtk_label_set_ellipsize(GTK_LABEL(label), PANGO_ELLIPSIZE_END);
236 gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5);
237 gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &gfx::kGdkBlack);
238 gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
239 } else {
240 GtkWidget* initial_label = gtk_label_new(
241 WideToUTF8(display_text.substr(0, link_offset)).c_str());
242 GtkWidget* trailing_label = gtk_label_new(
243 WideToUTF8(display_text.substr(link_offset)).c_str());
244
245 gtk_widget_modify_fg(initial_label, GTK_STATE_NORMAL, &gfx::kGdkBlack);
246 gtk_widget_modify_fg(trailing_label, GTK_STATE_NORMAL, &gfx::kGdkBlack);
247
248 // We don't want any spacing between the elements, so we pack them into
249 // this hbox that doesn't use kElementPadding.
250 gtk_box_pack_start(GTK_BOX(hbox), initial_label, FALSE, FALSE, 0);
251 gtk_util::CenterWidgetInHBox(hbox, link_button, false, 0);
252 gtk_box_pack_start(GTK_BOX(hbox), trailing_label, FALSE, FALSE, 0);
253 }
254
255 gtk_widget_show_all(border_bin_.get()); 268 gtk_widget_show_all(border_bin_.get());
256 } 269 }
257 270
258 private: 271 private:
259 static void OnLinkClick(GtkWidget* button, LinkInfoBar* link_info_bar) { 272 static void OnLinkClick(GtkWidget* button, LinkInfoBar* link_info_bar) {
260 if (link_info_bar->delegate_->AsLinkInfoBarDelegate()-> 273 if (link_info_bar->delegate_->AsLinkInfoBarDelegate()->
261 LinkClicked(gtk_util::DispositionForCurrentButtonPressEvent())) { 274 LinkClicked(gtk_util::DispositionForCurrentButtonPressEvent())) {
262 link_info_bar->RemoveInfoBar(); 275 link_info_bar->RemoveInfoBar();
263 } 276 }
264 } 277 }
265 }; 278 };
266 279
267 // ConfirmInfoBar -------------------------------------------------------------- 280 // ConfirmInfoBar --------------------------------------------------------------
268 281
269 class ConfirmInfoBar : public AlertInfoBar { 282 class ConfirmInfoBar : public InfoBar {
270 public: 283 public:
271 explicit ConfirmInfoBar(ConfirmInfoBarDelegate* delegate) 284 explicit ConfirmInfoBar(ConfirmInfoBarDelegate* delegate)
272 : AlertInfoBar(delegate) { 285 : InfoBar(delegate) {
273 AddConfirmButton(ConfirmInfoBarDelegate::BUTTON_CANCEL); 286 AddConfirmButton(ConfirmInfoBarDelegate::BUTTON_CANCEL);
274 AddConfirmButton(ConfirmInfoBarDelegate::BUTTON_OK); 287 AddConfirmButton(ConfirmInfoBarDelegate::BUTTON_OK);
275 288 std::wstring display_text = delegate->GetMessageText();
289 std::wstring link_text = delegate->GetLinkText();
290 AddLabelAndLink(display_text, link_text, display_text.size(),
291 kElementPadding, G_CALLBACK(OnLinkClick));
276 gtk_widget_show_all(border_bin_.get()); 292 gtk_widget_show_all(border_bin_.get());
277 } 293 }
278 294
279 private: 295 private:
280 // Adds a button to the info bar by type. It will do nothing if the delegate 296 // Adds a button to the info bar by type. It will do nothing if the delegate
281 // doesn't specify a button of the given type. 297 // doesn't specify a button of the given type.
282 void AddConfirmButton(ConfirmInfoBarDelegate::InfoBarButton type) { 298 void AddConfirmButton(ConfirmInfoBarDelegate::InfoBarButton type) {
283 if (delegate_->AsConfirmInfoBarDelegate()->GetButtons() & type) { 299 if (delegate_->AsConfirmInfoBarDelegate()->GetButtons() & type) {
284 GtkWidget* button = gtk_button_new_with_label(WideToUTF8( 300 GtkWidget* button = gtk_button_new_with_label(WideToUTF8(
285 delegate_->AsConfirmInfoBarDelegate()->GetButtonLabel(type)).c_str()); 301 delegate_->AsConfirmInfoBarDelegate()->GetButtonLabel(type)).c_str());
286 gtk_util::CenterWidgetInHBox(hbox_, button, true, 0); 302 gtk_util::CenterWidgetInHBox(hbox_, button, true, 0);
287 g_signal_connect(button, "clicked", 303 g_signal_connect(button, "clicked",
288 G_CALLBACK(type == ConfirmInfoBarDelegate::BUTTON_OK ? 304 G_CALLBACK(type == ConfirmInfoBarDelegate::BUTTON_OK ?
289 OnOkButton : OnCancelButton), 305 OnOkButton : OnCancelButton),
290 this); 306 this);
291 } 307 }
292 } 308 }
293 309
294 static void OnCancelButton(GtkWidget* button, ConfirmInfoBar* info_bar) { 310 static void OnCancelButton(GtkWidget* button, ConfirmInfoBar* info_bar) {
295 if (info_bar->delegate_->AsConfirmInfoBarDelegate()->Cancel()) 311 if (info_bar->delegate_->AsConfirmInfoBarDelegate()->Cancel())
296 info_bar->RemoveInfoBar(); 312 info_bar->RemoveInfoBar();
297 } 313 }
298 314
299 static void OnOkButton(GtkWidget* button, ConfirmInfoBar* info_bar) { 315 static void OnOkButton(GtkWidget* button, ConfirmInfoBar* info_bar) {
300 if (info_bar->delegate_->AsConfirmInfoBarDelegate()->Accept()) 316 if (info_bar->delegate_->AsConfirmInfoBarDelegate()->Accept())
301 info_bar->RemoveInfoBar(); 317 info_bar->RemoveInfoBar();
302 } 318 }
319
320 static void OnLinkClick(GtkWidget* button, ConfirmInfoBar* link_info_bar) {
321 if (link_info_bar->delegate_->AsConfirmInfoBarDelegate()->
322 LinkClicked(gtk_util::DispositionForCurrentButtonPressEvent())) {
323 link_info_bar->RemoveInfoBar();
324 }
325 }
303 }; 326 };
304 327
305 // AlertInfoBarDelegate, InfoBarDelegate overrides: ---------------------------- 328 // AlertInfoBarDelegate, InfoBarDelegate overrides: ----------------------------
306 329
307 InfoBar* AlertInfoBarDelegate::CreateInfoBar() { 330 InfoBar* AlertInfoBarDelegate::CreateInfoBar() {
308 return new AlertInfoBar(this); 331 return new AlertInfoBar(this);
309 } 332 }
310 333
311 // LinkInfoBarDelegate, InfoBarDelegate overrides: ----------------------------- 334 // LinkInfoBarDelegate, InfoBarDelegate overrides: -----------------------------
312 335
313 InfoBar* LinkInfoBarDelegate::CreateInfoBar() { 336 InfoBar* LinkInfoBarDelegate::CreateInfoBar() {
314 return new LinkInfoBar(this); 337 return new LinkInfoBar(this);
315 } 338 }
316 339
317 // ConfirmInfoBarDelegate, InfoBarDelegate overrides: -------------------------- 340 // ConfirmInfoBarDelegate, InfoBarDelegate overrides: --------------------------
318 341
319 InfoBar* ConfirmInfoBarDelegate::CreateInfoBar() { 342 InfoBar* ConfirmInfoBarDelegate::CreateInfoBar() {
320 return new ConfirmInfoBar(this); 343 return new ConfirmInfoBar(this);
321 } 344 }
OLDNEW
« no previous file with comments | « chrome/browser/gtk/infobar_gtk.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698