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

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

Issue 3310002: Gtk page info bubble. (Closed) Base URL: git://codf21.jail/chromium.git
Patch Set: remove comment Created 10 years, 3 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
« no previous file with comments | « chrome/browser/gtk/location_bar_view_gtk.h ('k') | chrome/browser/gtk/page_info_window_gtk.cc » ('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) 2009 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 <gtk/gtk.h>
6
7 #include "build/build_config.h"
8
9 #include "app/l10n_util.h"
10 #include "app/resource_bundle.h"
11 #include "base/i18n/rtl.h"
12 #include "base/utf_string_conversions.h"
13 #include "chrome/browser/browser_list.h"
14 #include "chrome/browser/certificate_viewer.h"
15 #include "chrome/browser/gtk/browser_toolbar_gtk.h"
16 #include "chrome/browser/gtk/browser_window_gtk.h"
17 #include "chrome/browser/gtk/gtk_chrome_link_button.h"
18 #include "chrome/browser/gtk/gtk_theme_provider.h"
19 #include "chrome/browser/gtk/gtk_util.h"
20 #include "chrome/browser/gtk/info_bubble_gtk.h"
21 #include "chrome/browser/gtk/location_bar_view_gtk.h"
22 #include "chrome/browser/page_info_model.h"
23 #include "chrome/browser/page_info_window.h"
24 #include "chrome/common/notification_observer.h"
25 #include "chrome/common/notification_registrar.h"
26 #include "chrome/common/notification_service.h"
27 #include "gfx/gtk_util.h"
28 #include "googleurl/src/gurl.h"
29 #include "grit/generated_resources.h"
30 #include "grit/locale_settings.h"
31 #include "grit/theme_resources.h"
32
33 class Profile;
34
35 namespace {
36
37 class PageInfoBubbleGtk : public PageInfoModel::PageInfoModelObserver,
38 public InfoBubbleGtkDelegate,
39 public NotificationObserver {
40 public:
41 PageInfoBubbleGtk(gfx::NativeWindow parent,
42 Profile* profile,
43 const GURL& url,
44 const NavigationEntry::SSLStatus& ssl,
45 bool show_history);
46 virtual ~PageInfoBubbleGtk();
47
48 // PageInfoModelObserver implementation:
49 virtual void ModelChanged();
50
51 // NotificationObserver implementation:
52 virtual void Observe(NotificationType type,
53 const NotificationSource& source,
54 const NotificationDetails& details);
55
56 // InfoBubbleGtkDelegate implementation:
57 virtual void InfoBubbleClosing(InfoBubbleGtk* info_bubble,
58 bool closed_by_escape);
59
60 private:
61 // Layouts the different sections retrieved from the model.
62 void InitContents();
63
64 // Returns a widget that contains the UI for the passed |section|.
65 GtkWidget* CreateSection(const PageInfoModel::SectionInfo& section);
66
67 // Link button callbacks.
68 CHROMEGTK_CALLBACK_0(PageInfoBubbleGtk, void, OnViewCertLinkClicked);
69 CHROMEGTK_CALLBACK_0(PageInfoBubbleGtk, void, OnHelpLinkClicked);
70
71 // The model containing the different sections to display.
72 PageInfoModel model_;
73
74 // The url for this dialog. Should be unique among active dialogs.
75 GURL url_;
76
77 // The id of the certificate for this page.
78 int cert_id_;
79
80 // Parent window.
81 GtkWindow* parent_;
82
83 // The virtual box containing the sections.
84 GtkWidget* contents_;
85
86 // The widget relative to which we are positioned.
87 GtkWidget* anchor_;
88
89 // Provides colors and stuff.
90 GtkThemeProvider* theme_provider_;
91
92 // The various elements in the interface we keep track of for theme changes.
93 std::vector<GtkWidget*> labels_;
94 std::vector<GtkWidget*> links_;
95
96 InfoBubbleGtk* bubble_;
97
98 NotificationRegistrar registrar_;
99
100 DISALLOW_COPY_AND_ASSIGN(PageInfoBubbleGtk);
101 };
102
103 PageInfoBubbleGtk::PageInfoBubbleGtk(gfx::NativeWindow parent,
104 Profile* profile,
105 const GURL& url,
106 const NavigationEntry::SSLStatus& ssl,
107 bool show_history)
108 : ALLOW_THIS_IN_INITIALIZER_LIST(model_(profile, url, ssl,
109 show_history, this)),
110 url_(url),
111 cert_id_(ssl.cert_id()),
112 parent_(parent),
113 contents_(NULL),
114 theme_provider_(GtkThemeProvider::GetFrom(profile)) {
115 BrowserWindowGtk* browser_window =
116 BrowserWindowGtk::GetBrowserWindowForNativeWindow(parent);
117
118 anchor_ = browser_window->
119 GetToolbar()->GetLocationBarView()->location_icon_widget();
120
121 registrar_.Add(this, NotificationType::BROWSER_THEME_CHANGED,
122 NotificationService::AllSources());
123
124 InitContents();
125
126 InfoBubbleGtk::ArrowLocationGtk arrow_location = base::i18n::IsRTL() ?
127 InfoBubbleGtk::ARROW_LOCATION_TOP_RIGHT :
128 InfoBubbleGtk::ARROW_LOCATION_TOP_LEFT;
129 bubble_ = InfoBubbleGtk::Show(anchor_,
130 NULL, // |rect|
131 contents_,
132 arrow_location,
133 true, // |match_system_theme|
134 true, // |grab_input|
135 theme_provider_,
136 this); // |delegate|
137 if (!bubble_) {
138 NOTREACHED();
139 return;
140 }
141 }
142
143 PageInfoBubbleGtk::~PageInfoBubbleGtk() {
144 }
145
146 void PageInfoBubbleGtk::ModelChanged() {
147 InitContents();
148 }
149
150 void PageInfoBubbleGtk::Observe(NotificationType type,
151 const NotificationSource& source,
152 const NotificationDetails& details) {
153 DCHECK(type == NotificationType::BROWSER_THEME_CHANGED);
154
155 for (std::vector<GtkWidget*>::iterator it = links_.begin();
156 it != links_.end(); ++it) {
157 gtk_chrome_link_button_set_use_gtk_theme(
158 GTK_CHROME_LINK_BUTTON(*it),
159 theme_provider_->UseGtkTheme());
160 }
161
162 if (theme_provider_->UseGtkTheme()) {
163 for (std::vector<GtkWidget*>::iterator it = labels_.begin();
164 it != labels_.end(); ++it) {
165 gtk_widget_modify_fg(*it, GTK_STATE_NORMAL, NULL);
166 }
167 } else {
168 for (std::vector<GtkWidget*>::iterator it = labels_.begin();
169 it != labels_.end(); ++it) {
170 gtk_widget_modify_fg(*it, GTK_STATE_NORMAL, &gfx::kGdkBlack);
171 }
172 }
173 }
174
175 void PageInfoBubbleGtk::InfoBubbleClosing(InfoBubbleGtk* info_bubble,
176 bool closed_by_escape) {
177 delete this;
178 }
179
180 void PageInfoBubbleGtk::InitContents() {
181 if (!contents_) {
182 contents_ = gtk_vbox_new(FALSE, gtk_util::kContentAreaSpacing);
183 gtk_container_set_border_width(GTK_CONTAINER(contents_),
184 gtk_util::kContentAreaBorder);
185 } else {
186 labels_.clear();
187 links_.clear();
188 gtk_util::RemoveAllChildren(contents_);
189 }
190
191 for (int i = 0; i < model_.GetSectionCount(); i++) {
192 gtk_box_pack_start(GTK_BOX(contents_),
193 CreateSection(model_.GetSectionInfo(i)),
194 FALSE, FALSE, 0);
195 gtk_box_pack_start(GTK_BOX(contents_),
196 gtk_hseparator_new(),
197 FALSE, FALSE, 0);
198 }
199
200 GtkWidget* help_link = gtk_chrome_link_button_new(
201 l10n_util::GetStringUTF8(IDS_PAGE_INFO_HELP_CENTER_LINK).c_str());
202 links_.push_back(help_link);
203 GtkWidget* help_link_hbox = gtk_hbox_new(FALSE, 0);
204 // Stick it in an hbox so it doesn't expand to the whole width.
205 gtk_box_pack_start(GTK_BOX(help_link_hbox), help_link, TRUE, FALSE, 0);
206 gtk_box_pack_start(GTK_BOX(contents_), help_link_hbox, FALSE, FALSE, 0);
207 g_signal_connect(help_link, "clicked",
208 G_CALLBACK(OnHelpLinkClickedThunk), this);
209
210 theme_provider_->InitThemesFor(this);
211 gtk_widget_show_all(contents_);
212 }
213
214 GtkWidget* PageInfoBubbleGtk::CreateSection(
215 const PageInfoModel::SectionInfo& section) {
216 GtkWidget* section_box = gtk_hbox_new(FALSE, 0);
217
218 if (section.type == PageInfoModel::SECTION_INFO_IDENTITY ||
219 section.type == PageInfoModel::SECTION_INFO_CONNECTION) {
220 ResourceBundle& rb = ResourceBundle::GetSharedInstance();
221 GdkPixbuf* pixbuf = NULL;
222 switch (section.state) {
223 case PageInfoModel::SECTION_STATE_OK:
224 pixbuf = rb.GetPixbufNamed(IDR_PAGEINFO_GOOD);
225 break;
226 case PageInfoModel::SECTION_STATE_WARNING:
227 DCHECK(section.type == PageInfoModel::SECTION_INFO_CONNECTION);
228 pixbuf = rb.GetPixbufNamed(IDR_PAGEINFO_MIXED);
229 break;
230 case PageInfoModel::SECTION_STATE_ERROR:
231 pixbuf = rb.GetPixbufNamed(IDR_PAGEINFO_BAD);
232 break;
233 default:
234 NOTREACHED();
235 }
236 GtkWidget* image = gtk_image_new_from_pixbuf(pixbuf);
237 gtk_box_pack_start(GTK_BOX(section_box), image, FALSE, FALSE,
238 gtk_util::kControlSpacing);
239 gtk_misc_set_alignment(GTK_MISC(image), 0, 0);
240 }
241
242 GtkWidget* vbox = gtk_vbox_new(FALSE, gtk_util::kControlSpacing);
243 gtk_box_pack_start(GTK_BOX(section_box), vbox, TRUE, TRUE, 0);
244
245 if (!section.headline.empty()) {
246 GtkWidget* label = gtk_label_new(UTF16ToUTF8(section.headline).c_str());
247 labels_.push_back(label);
248 PangoAttrList* attributes = pango_attr_list_new();
249 pango_attr_list_insert(attributes,
250 pango_attr_weight_new(PANGO_WEIGHT_BOLD));
251 gtk_label_set_attributes(GTK_LABEL(label), attributes);
252 pango_attr_list_unref(attributes);
253 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
254 // Allow linebreaking in the middle of words if necessary, so that extremely
255 // long hostnames (longer than one line) will still be completely shown.
256 gtk_label_set_line_wrap_mode(GTK_LABEL(label), PANGO_WRAP_WORD_CHAR);
257 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
258 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
259 gtk_widget_set_size_request(label, 400, -1);
260 }
261 GtkWidget* label = gtk_label_new(UTF16ToUTF8(section.description).c_str());
262 labels_.push_back(label);
263 gtk_misc_set_alignment(GTK_MISC(label), 0, 0);
264 gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
265 // Allow linebreaking in the middle of words if necessary, so that extremely
266 // long hostnames (longer than one line) will still be completely shown.
267 gtk_label_set_line_wrap_mode(GTK_LABEL(label), PANGO_WRAP_WORD_CHAR);
268 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
269 gtk_widget_set_size_request(label, 400, -1);
270
271 if (section.type == PageInfoModel::SECTION_INFO_IDENTITY && cert_id_ > 0) {
272 GtkWidget* view_cert_link = gtk_chrome_link_button_new(
273 l10n_util::GetStringUTF8(IDS_PAGEINFO_CERT_INFO_BUTTON).c_str());
274 links_.push_back(view_cert_link);
275 GtkWidget* cert_link_hbox = gtk_hbox_new(FALSE, 0);
276 // Stick it in an hbox so it doesn't expand to the whole width.
277 gtk_box_pack_start(GTK_BOX(cert_link_hbox), view_cert_link,
278 FALSE, FALSE, 0);
279 gtk_box_pack_start(GTK_BOX(vbox), cert_link_hbox, FALSE, FALSE, 0);
280 g_signal_connect(view_cert_link, "clicked",
281 G_CALLBACK(OnViewCertLinkClickedThunk), this);
282 }
283
284 return section_box;
285 }
286
287 void PageInfoBubbleGtk::OnViewCertLinkClicked(GtkWidget* widget) {
288 ShowCertificateViewerByID(GTK_WINDOW(parent_), cert_id_);
289 bubble_->Close();
290 }
291
292 void PageInfoBubbleGtk::OnHelpLinkClicked(GtkWidget* widget) {
293 GURL url = GURL(l10n_util::GetStringUTF16(IDS_PAGE_INFO_HELP_CENTER));
294 Browser* browser = BrowserList::GetLastActive();
295 browser->OpenURL(url, GURL(), NEW_FOREGROUND_TAB, PageTransition::LINK);
296 bubble_->Close();
297 }
298
299 } // namespace
300
301 namespace browser {
302
303 void ShowPageInfoBubble(gfx::NativeWindow parent,
304 Profile* profile,
305 const GURL& url,
306 const NavigationEntry::SSLStatus& ssl,
307 bool show_history) {
308 new PageInfoBubbleGtk(parent, profile, url, ssl, show_history);
309 }
310
311 } // namespace browser
OLDNEW
« no previous file with comments | « chrome/browser/gtk/location_bar_view_gtk.h ('k') | chrome/browser/gtk/page_info_window_gtk.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698