1 /////////////////////////////////////////////////////////////////////////////// 
   2 // Name:        src/gtk/aboutdlg.cpp 
   3 // Purpose:     native GTK+ wxAboutBox() implementation 
   4 // Author:      Vadim Zeitlin 
   7 // Copyright:   (c) 2006 Vadim Zeitlin <vadim@wxwindows.org> 
   8 // Licence:     wxWindows licence 
   9 /////////////////////////////////////////////////////////////////////////////// 
  11 // ============================================================================ 
  13 // ============================================================================ 
  15 // ---------------------------------------------------------------------------- 
  17 // ---------------------------------------------------------------------------- 
  19 // for compilers that support precompilation, includes "wx.h". 
  20 #include "wx/wxprec.h" 
  22 #if wxUSE_ABOUTDLG && defined(__WXGTK26__) 
  25     #include "wx/utils.h"       // for wxLaunchDefaultBrowser() 
  28 #include "wx/aboutdlg.h" 
  29 #include "wx/generic/aboutdlgg.h" 
  31 #include "wx/gtk/private.h" 
  33 // ---------------------------------------------------------------------------- 
  34 // GtkArray: temporary array of GTK strings 
  35 // ---------------------------------------------------------------------------- 
  43     // Create empty GtkArray 
  44     GtkArray() : m_strings(0), m_count(0) 
  48     // Create GtkArray from wxArrayString. Note that the created object is 
  49     // only valid as long as 'a' is! 
  50     GtkArray(const wxArrayString
& a
) 
  53         m_strings 
= new const gchar 
*[m_count 
+ 1]; 
  55         for ( size_t n 
= 0; n 
< m_count
; n
++ ) 
  58             // notice that there is no need to copy the string pointer here 
  59             // because this class is used only as a temporary and during its 
  60             // existence the pointer persists in wxString which uses it either 
  61             // for internal representation (in wxUSE_UNICODE_UTF8 case) or as 
  62             // cached m_convertedToChar (in wxUSE_UNICODE_WCHAR case) 
  63             m_strings
[n
] = wxGTK_CONV_SYS(a
[n
]); 
  64 #else // !wxUSE_UNICODE 
  65             // and in ANSI build we can simply borrow the pointer from 
  66             // wxCharBuffer (which owns it in this case) instead of copying it 
  67             // but we then become responsible for freeing it 
  68             m_strings
[n
] = wxGTK_CONV_SYS(a
[n
]).release(); 
  69 #endif // wxUSE_UNICODE/!wxUSE_UNICODE 
  72         // array must be NULL-terminated 
  73         m_strings
[m_count
] = NULL
; 
  76     operator const gchar 
**() const { return m_strings
; } 
  81         for ( size_t n 
= 0; n 
< m_count
; n
++ ) 
  82             free(const_cast<gchar 
*>(m_strings
[n
])); 
  89     const gchar 
**m_strings
; 
  92     wxDECLARE_NO_COPY_CLASS(GtkArray
); 
  95 } // anonymous namespace 
  97 // ============================================================================ 
  99 // ============================================================================ 
 101 // GTK+ about dialog is modeless, keep track of it in this variable 
 102 static GtkAboutDialog 
*gs_aboutDialog 
= NULL
; 
 105 wxGtkAboutDialogOnClose(GtkAboutDialog 
*about
) 
 107     gtk_widget_destroy(GTK_WIDGET(about
)); 
 108     if ( about 
== gs_aboutDialog 
) 
 109         gs_aboutDialog 
= NULL
; 
 113 wxGtkAboutDialogOnLink(GtkAboutDialog 
* WXUNUSED(about
), 
 115                        gpointer 
WXUNUSED(data
)) 
 117     wxLaunchDefaultBrowser(wxGTK_CONV_BACK_SYS(link
)); 
 120 void wxAboutBox(const wxAboutDialogInfo
& info
, wxWindow
* WXUNUSED(parent
)) 
 122     if ( !gtk_check_version(2,6,0) ) 
 124         // don't create another dialog if one is already present 
 125         if ( !gs_aboutDialog 
) 
 126             gs_aboutDialog 
= GTK_ABOUT_DIALOG(gtk_about_dialog_new()); 
 128         GtkAboutDialog 
* const dlg 
= gs_aboutDialog
; 
 129         gtk_about_dialog_set_name(dlg
, wxGTK_CONV_SYS(info
.GetName())); 
 130         if ( info
.HasVersion() ) 
 131             gtk_about_dialog_set_version(dlg
, wxGTK_CONV_SYS(info
.GetVersion())); 
 133             gtk_about_dialog_set_version(dlg
, NULL
); 
 134         if ( info
.HasCopyright() ) 
 135             gtk_about_dialog_set_copyright(dlg
, wxGTK_CONV_SYS(info
.GetCopyrightToDisplay())); 
 137             gtk_about_dialog_set_copyright(dlg
, NULL
); 
 138         if ( info
.HasDescription() ) 
 139             gtk_about_dialog_set_comments(dlg
, wxGTK_CONV_SYS(info
.GetDescription())); 
 141             gtk_about_dialog_set_comments(dlg
, NULL
); 
 142         if ( info
.HasLicence() ) 
 143             gtk_about_dialog_set_license(dlg
, wxGTK_CONV_SYS(info
.GetLicence())); 
 145             gtk_about_dialog_set_license(dlg
, NULL
); 
 147         wxIcon icon 
= info
.GetIcon(); 
 149             gtk_about_dialog_set_logo(dlg
, info
.GetIcon().GetPixbuf()); 
 151         if ( info
.HasWebSite() ) 
 153             // NB: must be called before gtk_about_dialog_set_website() as 
 154             //     otherwise it has no effect (although GTK+ docs don't mention 
 156             gtk_about_dialog_set_url_hook(wxGtkAboutDialogOnLink
, NULL
, NULL
); 
 158             gtk_about_dialog_set_website(dlg
, wxGTK_CONV_SYS(info
.GetWebSiteURL())); 
 159             gtk_about_dialog_set_website_label
 
 162                 wxGTK_CONV_SYS(info
.GetWebSiteDescription()) 
 167             gtk_about_dialog_set_website(dlg
, NULL
); 
 168             gtk_about_dialog_set_website_label(dlg
, NULL
); 
 169             gtk_about_dialog_set_url_hook(NULL
, NULL
, NULL
); 
 172         if ( info
.HasDevelopers() ) 
 173             gtk_about_dialog_set_authors(dlg
, GtkArray(info
.GetDevelopers())); 
 175             gtk_about_dialog_set_authors(dlg
, GtkArray()); 
 176         if ( info
.HasDocWriters() ) 
 177             gtk_about_dialog_set_documenters(dlg
, GtkArray(info
.GetDocWriters())); 
 179             gtk_about_dialog_set_documenters(dlg
, GtkArray()); 
 180         if ( info
.HasArtists() ) 
 181             gtk_about_dialog_set_artists(dlg
, GtkArray(info
.GetArtists())); 
 183             gtk_about_dialog_set_artists(dlg
, GtkArray()); 
 185         wxString transCredits
; 
 186         if ( info
.HasTranslators() ) 
 188             const wxArrayString
& translators 
= info
.GetTranslators(); 
 189             const size_t count 
= translators
.size(); 
 190             for ( size_t n 
= 0; n 
< count
; n
++ ) 
 192                 transCredits 
<< translators
[n
] << wxT('\n'); 
 195         else // no translators explicitely specified 
 197             // maybe we have translator credits in the message catalog? 
 198             wxString translator 
= _("translator-credits"); 
 200             // gtk_about_dialog_set_translator_credits() is smart enough to 
 201             // detect if "translator-credits" is untranslated and hide the 
 202             // translators tab in that case, however it will still show the 
 203             // "credits" button, (at least GTK 2.10.6) even if there are no 
 204             // credits informations at all, so we still need to do the check 
 206             if ( translator 
!= wxT("translator-credits") ) // untranslated! 
 207                 transCredits 
= translator
; 
 210         if ( !transCredits
.empty() ) 
 211             gtk_about_dialog_set_translator_credits(dlg
, wxGTK_CONV_SYS(transCredits
)); 
 213             gtk_about_dialog_set_translator_credits(dlg
, NULL
); 
 215         g_signal_connect(dlg
, "response", 
 216                             G_CALLBACK(wxGtkAboutDialogOnClose
), NULL
); 
 218         gtk_window_present(GTK_WINDOW(dlg
)); 
 222     // native about dialog not available, fall back to the generic one 
 223     wxGenericAboutBox(info
); 
 226 #endif // wxUSE_ABOUTDLG && GTK+ 2.6+