aboutdlg.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Name: src/gtk/aboutdlg.cpp
  3. // Purpose: native GTK+ wxAboutBox() implementation
  4. // Author: Vadim Zeitlin
  5. // Created: 2006-10-08
  6. // Copyright: (c) 2006 Vadim Zeitlin <vadim@wxwindows.org>
  7. // Licence: wxWindows licence
  8. ///////////////////////////////////////////////////////////////////////////////
  9. // ============================================================================
  10. // declarations
  11. // ============================================================================
  12. // ----------------------------------------------------------------------------
  13. // headers
  14. // ----------------------------------------------------------------------------
  15. // for compilers that support precompilation, includes "wx.h".
  16. #include "wx/wxprec.h"
  17. #if wxUSE_ABOUTDLG
  18. #include "wx/aboutdlg.h"
  19. #ifndef WX_PRECOMP
  20. #include "wx/utils.h" // for wxLaunchDefaultBrowser()
  21. #endif //WX_PRECOMP
  22. #include <gtk/gtk.h>
  23. #include "wx/gtk/private.h"
  24. #include "wx/gtk/private/gtk2-compat.h"
  25. // ----------------------------------------------------------------------------
  26. // GtkArray: temporary array of GTK strings
  27. // ----------------------------------------------------------------------------
  28. namespace
  29. {
  30. class GtkArray
  31. {
  32. public:
  33. // Create empty GtkArray
  34. GtkArray() : m_strings(0), m_count(0)
  35. {
  36. }
  37. // Create GtkArray from wxArrayString. Note that the created object is
  38. // only valid as long as 'a' is!
  39. GtkArray(const wxArrayString& a)
  40. {
  41. m_count = a.size();
  42. m_strings = new const gchar *[m_count + 1];
  43. for ( size_t n = 0; n < m_count; n++ )
  44. {
  45. #if wxUSE_UNICODE
  46. // notice that there is no need to copy the string pointer here
  47. // because this class is used only as a temporary and during its
  48. // existence the pointer persists in wxString which uses it either
  49. // for internal representation (in wxUSE_UNICODE_UTF8 case) or as
  50. // cached m_convertedToChar (in wxUSE_UNICODE_WCHAR case)
  51. m_strings[n] = wxGTK_CONV_SYS(a[n]);
  52. #else // !wxUSE_UNICODE
  53. // and in ANSI build we can simply borrow the pointer from
  54. // wxCharBuffer (which owns it in this case) instead of copying it
  55. // but we then become responsible for freeing it
  56. m_strings[n] = wxGTK_CONV_SYS(a[n]).release();
  57. #endif // wxUSE_UNICODE/!wxUSE_UNICODE
  58. }
  59. // array must be NULL-terminated
  60. m_strings[m_count] = NULL;
  61. }
  62. operator const gchar **() const { return m_strings; }
  63. ~GtkArray()
  64. {
  65. #if !wxUSE_UNICODE
  66. for ( size_t n = 0; n < m_count; n++ )
  67. free(const_cast<gchar *>(m_strings[n]));
  68. #endif
  69. delete [] m_strings;
  70. }
  71. private:
  72. const gchar **m_strings;
  73. size_t m_count;
  74. wxDECLARE_NO_COPY_CLASS(GtkArray);
  75. };
  76. } // anonymous namespace
  77. // ============================================================================
  78. // implementation
  79. // ============================================================================
  80. // GTK+ about dialog is modeless, keep track of it in this variable
  81. static GtkAboutDialog *gs_aboutDialog = NULL;
  82. extern "C" {
  83. static void wxGtkAboutDialogOnClose(GtkAboutDialog *about)
  84. {
  85. gtk_widget_destroy(GTK_WIDGET(about));
  86. if ( about == gs_aboutDialog )
  87. gs_aboutDialog = NULL;
  88. }
  89. }
  90. #ifdef __WXGTK3__
  91. extern "C" {
  92. static gboolean activate_link(GtkAboutDialog*, const char* link, void* dontIgnore)
  93. {
  94. if (dontIgnore)
  95. {
  96. wxLaunchDefaultBrowser(wxGTK_CONV_BACK_SYS(link));
  97. return true;
  98. }
  99. return false;
  100. }
  101. }
  102. #else
  103. extern "C" {
  104. static void wxGtkAboutDialogOnLink(GtkAboutDialog*, const char* link, void*)
  105. {
  106. wxLaunchDefaultBrowser(wxGTK_CONV_BACK_SYS(link));
  107. }
  108. }
  109. #endif
  110. void wxAboutBox(const wxAboutDialogInfo& info, wxWindow* WXUNUSED(parent))
  111. {
  112. // don't create another dialog if one is already present
  113. if ( !gs_aboutDialog )
  114. gs_aboutDialog = GTK_ABOUT_DIALOG(gtk_about_dialog_new());
  115. GtkAboutDialog * const dlg = gs_aboutDialog;
  116. gtk_about_dialog_set_program_name(dlg, wxGTK_CONV_SYS(info.GetName()));
  117. if ( info.HasVersion() )
  118. gtk_about_dialog_set_version(dlg, wxGTK_CONV_SYS(info.GetVersion()));
  119. else
  120. gtk_about_dialog_set_version(dlg, NULL);
  121. if ( info.HasCopyright() )
  122. gtk_about_dialog_set_copyright(dlg, wxGTK_CONV_SYS(info.GetCopyrightToDisplay()));
  123. else
  124. gtk_about_dialog_set_copyright(dlg, NULL);
  125. if ( info.HasDescription() )
  126. gtk_about_dialog_set_comments(dlg, wxGTK_CONV_SYS(info.GetDescription()));
  127. else
  128. gtk_about_dialog_set_comments(dlg, NULL);
  129. if ( info.HasLicence() )
  130. gtk_about_dialog_set_license(dlg, wxGTK_CONV_SYS(info.GetLicence()));
  131. else
  132. gtk_about_dialog_set_license(dlg, NULL);
  133. wxIcon icon = info.GetIcon();
  134. if ( icon.IsOk() )
  135. gtk_about_dialog_set_logo(dlg, info.GetIcon().GetPixbuf());
  136. if ( info.HasWebSite() )
  137. {
  138. #ifdef __WXGTK3__
  139. g_signal_connect(dlg, "activate-link", G_CALLBACK(activate_link), dlg);
  140. #else
  141. // NB: must be called before gtk_about_dialog_set_website() as
  142. // otherwise it has no effect (although GTK+ docs don't mention
  143. // this...)
  144. gtk_about_dialog_set_url_hook(wxGtkAboutDialogOnLink, NULL, NULL);
  145. #endif
  146. gtk_about_dialog_set_website(dlg, wxGTK_CONV_SYS(info.GetWebSiteURL()));
  147. gtk_about_dialog_set_website_label
  148. (
  149. dlg,
  150. wxGTK_CONV_SYS(info.GetWebSiteDescription())
  151. );
  152. }
  153. else
  154. {
  155. gtk_about_dialog_set_website(dlg, NULL);
  156. gtk_about_dialog_set_website_label(dlg, NULL);
  157. #ifdef __WXGTK3__
  158. g_signal_connect(dlg, "activate-link", G_CALLBACK(activate_link), NULL);
  159. #else
  160. gtk_about_dialog_set_url_hook(NULL, NULL, NULL);
  161. #endif
  162. }
  163. if ( info.HasDevelopers() )
  164. gtk_about_dialog_set_authors(dlg, GtkArray(info.GetDevelopers()));
  165. else
  166. gtk_about_dialog_set_authors(dlg, GtkArray());
  167. if ( info.HasDocWriters() )
  168. gtk_about_dialog_set_documenters(dlg, GtkArray(info.GetDocWriters()));
  169. else
  170. gtk_about_dialog_set_documenters(dlg, GtkArray());
  171. if ( info.HasArtists() )
  172. gtk_about_dialog_set_artists(dlg, GtkArray(info.GetArtists()));
  173. else
  174. gtk_about_dialog_set_artists(dlg, GtkArray());
  175. wxString transCredits;
  176. if ( info.HasTranslators() )
  177. {
  178. const wxArrayString& translators = info.GetTranslators();
  179. const size_t count = translators.size();
  180. for ( size_t n = 0; n < count; n++ )
  181. {
  182. transCredits << translators[n] << wxT('\n');
  183. }
  184. }
  185. else // no translators explicitly specified
  186. {
  187. // maybe we have translator credits in the message catalog?
  188. wxString translator = _("translator-credits");
  189. // gtk_about_dialog_set_translator_credits() is smart enough to
  190. // detect if "translator-credits" is untranslated and hide the
  191. // translators tab in that case, however it will still show the
  192. // "credits" button, (at least GTK 2.10.6) even if there are no
  193. // credits informations at all, so we still need to do the check
  194. // ourselves
  195. if ( translator != wxT("translator-credits") ) // untranslated!
  196. transCredits = translator;
  197. }
  198. if ( !transCredits.empty() )
  199. gtk_about_dialog_set_translator_credits(dlg, wxGTK_CONV_SYS(transCredits));
  200. else
  201. gtk_about_dialog_set_translator_credits(dlg, NULL);
  202. g_signal_connect(dlg, "response",
  203. G_CALLBACK(wxGtkAboutDialogOnClose), NULL);
  204. gtk_window_present(GTK_WINDOW(dlg));
  205. }
  206. #endif // wxUSE_ABOUTDLG