1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/aboutdlg.cpp
3 // Purpose: native GTK+ wxAboutBox() implementation
4 // Author: Vadim Zeitlin
6 // Copyright: (c) 2006 Vadim Zeitlin <vadim@wxwindows.org>
7 // Licence: wxWindows licence
8 ///////////////////////////////////////////////////////////////////////////////
10 // ============================================================================
12 // ============================================================================
14 // ----------------------------------------------------------------------------
16 // ----------------------------------------------------------------------------
18 // for compilers that support precompilation, includes "wx.h".
19 #include "wx/wxprec.h"
23 #include "wx/aboutdlg.h"
26 #include "wx/utils.h" // for wxLaunchDefaultBrowser()
30 #include "wx/gtk/private.h"
31 #include "wx/gtk/private/gtk2-compat.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 static void wxGtkAboutDialogOnClose(GtkAboutDialog
*about
)
107 gtk_widget_destroy(GTK_WIDGET(about
));
108 if ( about
== gs_aboutDialog
)
109 gs_aboutDialog
= NULL
;
115 static gboolean
activate_link(GtkAboutDialog
*, const char* link
, void* dontIgnore
)
119 wxLaunchDefaultBrowser(wxGTK_CONV_BACK_SYS(link
));
127 static void wxGtkAboutDialogOnLink(GtkAboutDialog
*, const char* link
, void*)
129 wxLaunchDefaultBrowser(wxGTK_CONV_BACK_SYS(link
));
134 void wxAboutBox(const wxAboutDialogInfo
& info
, wxWindow
* WXUNUSED(parent
))
136 // don't create another dialog if one is already present
137 if ( !gs_aboutDialog
)
138 gs_aboutDialog
= GTK_ABOUT_DIALOG(gtk_about_dialog_new());
140 GtkAboutDialog
* const dlg
= gs_aboutDialog
;
141 gtk_about_dialog_set_program_name(dlg
, wxGTK_CONV_SYS(info
.GetName()));
142 if ( info
.HasVersion() )
143 gtk_about_dialog_set_version(dlg
, wxGTK_CONV_SYS(info
.GetVersion()));
145 gtk_about_dialog_set_version(dlg
, NULL
);
146 if ( info
.HasCopyright() )
147 gtk_about_dialog_set_copyright(dlg
, wxGTK_CONV_SYS(info
.GetCopyrightToDisplay()));
149 gtk_about_dialog_set_copyright(dlg
, NULL
);
150 if ( info
.HasDescription() )
151 gtk_about_dialog_set_comments(dlg
, wxGTK_CONV_SYS(info
.GetDescription()));
153 gtk_about_dialog_set_comments(dlg
, NULL
);
154 if ( info
.HasLicence() )
155 gtk_about_dialog_set_license(dlg
, wxGTK_CONV_SYS(info
.GetLicence()));
157 gtk_about_dialog_set_license(dlg
, NULL
);
159 wxIcon icon
= info
.GetIcon();
161 gtk_about_dialog_set_logo(dlg
, info
.GetIcon().GetPixbuf());
163 if ( info
.HasWebSite() )
166 g_signal_connect(dlg
, "activate-link", G_CALLBACK(activate_link
), dlg
);
168 // NB: must be called before gtk_about_dialog_set_website() as
169 // otherwise it has no effect (although GTK+ docs don't mention
171 gtk_about_dialog_set_url_hook(wxGtkAboutDialogOnLink
, NULL
, NULL
);
174 gtk_about_dialog_set_website(dlg
, wxGTK_CONV_SYS(info
.GetWebSiteURL()));
175 gtk_about_dialog_set_website_label
178 wxGTK_CONV_SYS(info
.GetWebSiteDescription())
183 gtk_about_dialog_set_website(dlg
, NULL
);
184 gtk_about_dialog_set_website_label(dlg
, NULL
);
186 g_signal_connect(dlg
, "activate-link", G_CALLBACK(activate_link
), NULL
);
188 gtk_about_dialog_set_url_hook(NULL
, NULL
, NULL
);
192 if ( info
.HasDevelopers() )
193 gtk_about_dialog_set_authors(dlg
, GtkArray(info
.GetDevelopers()));
195 gtk_about_dialog_set_authors(dlg
, GtkArray());
196 if ( info
.HasDocWriters() )
197 gtk_about_dialog_set_documenters(dlg
, GtkArray(info
.GetDocWriters()));
199 gtk_about_dialog_set_documenters(dlg
, GtkArray());
200 if ( info
.HasArtists() )
201 gtk_about_dialog_set_artists(dlg
, GtkArray(info
.GetArtists()));
203 gtk_about_dialog_set_artists(dlg
, GtkArray());
205 wxString transCredits
;
206 if ( info
.HasTranslators() )
208 const wxArrayString
& translators
= info
.GetTranslators();
209 const size_t count
= translators
.size();
210 for ( size_t n
= 0; n
< count
; n
++ )
212 transCredits
<< translators
[n
] << wxT('\n');
215 else // no translators explicitly specified
217 // maybe we have translator credits in the message catalog?
218 wxString translator
= _("translator-credits");
220 // gtk_about_dialog_set_translator_credits() is smart enough to
221 // detect if "translator-credits" is untranslated and hide the
222 // translators tab in that case, however it will still show the
223 // "credits" button, (at least GTK 2.10.6) even if there are no
224 // credits informations at all, so we still need to do the check
226 if ( translator
!= wxT("translator-credits") ) // untranslated!
227 transCredits
= translator
;
230 if ( !transCredits
.empty() )
231 gtk_about_dialog_set_translator_credits(dlg
, wxGTK_CONV_SYS(transCredits
));
233 gtk_about_dialog_set_translator_credits(dlg
, NULL
);
235 g_signal_connect(dlg
, "response",
236 G_CALLBACK(wxGtkAboutDialogOnClose
), NULL
);
238 gtk_window_present(GTK_WINDOW(dlg
));
241 #endif // wxUSE_ABOUTDLG