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