1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/generic/aboutdlgg.cpp
3 // Purpose: implements wxGenericAboutBox() function
4 // Author: Vadim Zeitlin
5 // Created: 2006-10-08
6 // Copyright: (c) 2006 Vadim Zeitlin <vadim@wxwidgets.org>
7 // Licence: wxWindows licence
8 ///////////////////////////////////////////////////////////////////////////////
9
10 // ============================================================================
11 // declarations
12 // ============================================================================
13
14 // ----------------------------------------------------------------------------
15 // headers
16 // ----------------------------------------------------------------------------
17
18 // for compilers that support precompilation, includes "wx.h".
19 #include "wx/wxprec.h"
20
21
22 #if wxUSE_ABOUTDLG
23
24 #ifndef WX_PRECOMP
25 #include "wx/sizer.h"
26 #include "wx/statbmp.h"
27 #include "wx/stattext.h"
28 #include "wx/button.h"
29 #endif //WX_PRECOMP
30
31 #include "wx/aboutdlg.h"
32 #include "wx/generic/aboutdlgg.h"
33
34 #include "wx/hyperlink.h"
35 #include "wx/collpane.h"
36
37 // ============================================================================
38 // implementation
39 // ============================================================================
40
41 // helper function: returns all array elements in a single comma-separated and
42 // newline-terminated string
AllAsString(const wxArrayString & a)43 static wxString AllAsString(const wxArrayString& a)
44 {
45 wxString s;
46 const size_t count = a.size();
47 s.reserve(20*count);
48 for ( size_t n = 0; n < count; n++ )
49 {
50 s << a[n] << (n == count - 1 ? wxT("\n") : wxT(", "));
51 }
52
53 return s;
54 }
55
56 // ----------------------------------------------------------------------------
57 // wxAboutDialogInfo
58 // ----------------------------------------------------------------------------
59
GetDescriptionAndCredits() const60 wxString wxAboutDialogInfo::GetDescriptionAndCredits() const
61 {
62 wxString s = GetDescription();
63 if ( !s.empty() )
64 s << wxT('\n');
65
66 if ( HasDevelopers() )
67 s << wxT('\n') << _("Developed by ") << AllAsString(GetDevelopers());
68
69 if ( HasDocWriters() )
70 s << wxT('\n') << _("Documentation by ") << AllAsString(GetDocWriters());
71
72 if ( HasArtists() )
73 s << wxT('\n') << _("Graphics art by ") << AllAsString(GetArtists());
74
75 if ( HasTranslators() )
76 s << wxT('\n') << _("Translations by ") << AllAsString(GetTranslators());
77
78 return s;
79 }
80
GetIcon() const81 wxIcon wxAboutDialogInfo::GetIcon() const
82 {
83 wxIcon icon = m_icon;
84 if ( !icon.IsOk() )
85 {
86 const wxTopLevelWindow * const
87 tlw = wxDynamicCast(wxApp::GetMainTopWindow(), wxTopLevelWindow);
88 if ( tlw )
89 icon = tlw->GetIcon();
90 }
91
92 return icon;
93 }
94
GetCopyrightToDisplay() const95 wxString wxAboutDialogInfo::GetCopyrightToDisplay() const
96 {
97 wxString ret = m_copyright;
98
99 #if wxUSE_UNICODE
100 const wxString copyrightSign = wxString::FromUTF8("\xc2\xa9");
101 ret.Replace("(c)", copyrightSign);
102 ret.Replace("(C)", copyrightSign);
103 #endif // wxUSE_UNICODE
104
105 return ret;
106 }
107
SetVersion(const wxString & version,const wxString & longVersion)108 void wxAboutDialogInfo::SetVersion(const wxString& version,
109 const wxString& longVersion)
110 {
111 if ( version.empty() )
112 {
113 m_version.clear();
114
115 wxASSERT_MSG( longVersion.empty(),
116 "long version should be empty if version is");
117
118 m_longVersion.clear();
119 }
120 else // setting valid version
121 {
122 m_version = version;
123
124 if ( longVersion.empty() )
125 m_longVersion = _("Version ") + m_version;
126 else
127 m_longVersion = longVersion;
128 }
129 }
130
131 // ----------------------------------------------------------------------------
132 // wxGenericAboutDialog
133 // ----------------------------------------------------------------------------
134
Create(const wxAboutDialogInfo & info,wxWindow * parent)135 bool wxGenericAboutDialog::Create(const wxAboutDialogInfo& info, wxWindow* parent)
136 {
137 if ( !wxDialog::Create(parent, wxID_ANY, wxString::Format(_("About %s"), info.GetName()),
138 wxDefaultPosition, wxDefaultSize, wxRESIZE_BORDER|wxDEFAULT_DIALOG_STYLE) )
139 return false;
140
141 m_sizerText = new wxBoxSizer(wxVERTICAL);
142 wxString nameAndVersion = info.GetName();
143 if ( info.HasVersion() )
144 nameAndVersion << wxT(' ') << info.GetVersion();
145 wxStaticText *label = new wxStaticText(this, wxID_ANY, nameAndVersion);
146 wxFont fontBig(*wxNORMAL_FONT);
147 fontBig.SetFractionalPointSize(fontBig.GetFractionalPointSize() + 2.0);
148 fontBig.SetWeight(wxFONTWEIGHT_BOLD);
149 label->SetFont(fontBig);
150
151 m_sizerText->Add(label, wxSizerFlags().Centre().Border());
152 m_sizerText->AddSpacer(5);
153
154 AddText(info.GetCopyrightToDisplay());
155 AddText(info.GetDescription());
156
157 if ( info.HasWebSite() )
158 {
159 #if wxUSE_HYPERLINKCTRL
160 AddControl(new wxHyperlinkCtrl(this, wxID_ANY,
161 info.GetWebSiteDescription(),
162 info.GetWebSiteURL()));
163 #else
164 AddText(info.GetWebSiteURL());
165 #endif // wxUSE_HYPERLINKCTRL/!wxUSE_HYPERLINKCTRL
166 }
167
168 #if wxUSE_COLLPANE
169 if ( info.HasLicence() )
170 AddCollapsiblePane(_("License"), info.GetLicence());
171
172 if ( info.HasDevelopers() )
173 AddCollapsiblePane(_("Developers"),
174 AllAsString(info.GetDevelopers()));
175
176 if ( info.HasDocWriters() )
177 AddCollapsiblePane(_("Documentation writers"),
178 AllAsString(info.GetDocWriters()));
179
180 if ( info.HasArtists() )
181 AddCollapsiblePane(_("Artists"),
182 AllAsString(info.GetArtists()));
183
184 if ( info.HasTranslators() )
185 AddCollapsiblePane(_("Translators"),
186 AllAsString(info.GetTranslators()));
187 #endif // wxUSE_COLLPANE
188
189 DoAddCustomControls();
190
191
192 wxSizer *sizerIconAndText = new wxBoxSizer(wxHORIZONTAL);
193 #if wxUSE_STATBMP
194 wxIcon icon = info.GetIcon();
195 if ( icon.IsOk() )
196 {
197 sizerIconAndText->Add(new wxStaticBitmap(this, wxID_ANY, icon),
198 wxSizerFlags().Border(wxRIGHT));
199 }
200 #endif // wxUSE_STATBMP
201 sizerIconAndText->Add(m_sizerText, wxSizerFlags(1).Expand());
202
203 wxSizer *sizerTop = new wxBoxSizer(wxVERTICAL);
204 sizerTop->Add(sizerIconAndText, wxSizerFlags(1).Expand().Border());
205
206 // Mac typically doesn't use OK buttons just for dismissing dialogs.
207 #if !defined(__WXMAC__)
208 wxSizer *sizerBtns = CreateButtonSizer(wxOK);
209 if ( sizerBtns )
210 {
211 sizerTop->Add(sizerBtns, wxSizerFlags().Expand().Border());
212 }
213 #endif
214
215 SetSizerAndFit(sizerTop);
216
217 CentreOnParent();
218
219 #if !wxUSE_MODAL_ABOUT_DIALOG
220 Bind(wxEVT_CLOSE_WINDOW, &wxGenericAboutDialog::OnCloseWindow, this);
221 Bind(wxEVT_BUTTON, &wxGenericAboutDialog::OnOK, this, wxID_OK);
222 #endif // !wxUSE_MODAL_ABOUT_DIALOG
223
224 return true;
225 }
226
AddControl(wxWindow * win,const wxSizerFlags & flags)227 void wxGenericAboutDialog::AddControl(wxWindow *win, const wxSizerFlags& flags)
228 {
229 wxCHECK_RET( m_sizerText, wxT("can only be called after Create()") );
230 wxASSERT_MSG( win, wxT("can't add NULL window to about dialog") );
231
232 m_sizerText->Add(win, flags);
233 }
234
AddControl(wxWindow * win)235 void wxGenericAboutDialog::AddControl(wxWindow *win)
236 {
237 AddControl(win, wxSizerFlags().Border(wxDOWN).Centre());
238 }
239
AddText(const wxString & text)240 void wxGenericAboutDialog::AddText(const wxString& text)
241 {
242 if ( !text.empty() )
243 AddControl(new wxStaticText(this, wxID_ANY, text));
244 }
245
246 #if wxUSE_COLLPANE
AddCollapsiblePane(const wxString & title,const wxString & text)247 void wxGenericAboutDialog::AddCollapsiblePane(const wxString& title,
248 const wxString& text)
249 {
250 wxCollapsiblePane *pane = new wxCollapsiblePane(this, wxID_ANY, title);
251 wxWindow * const paneContents = pane->GetPane();
252 wxStaticText *txt = new wxStaticText(paneContents, wxID_ANY, text,
253 wxDefaultPosition, wxDefaultSize,
254 wxALIGN_CENTRE);
255
256 // don't make the text unreasonably wide
257 static const int maxWidth = wxGetDisplaySize().x/3;
258 txt->Wrap(maxWidth);
259
260
261 // we need a sizer to make this text expand to fill the entire pane area
262 wxSizer * const sizerPane = new wxBoxSizer(wxHORIZONTAL);
263 sizerPane->Add(txt, wxSizerFlags(1).Expand());
264 paneContents->SetSizer(sizerPane);
265
266 // NB: all the wxCollapsiblePanes must be added with a null proportion value
267 m_sizerText->Add(pane, wxSizerFlags(0).Expand().Border(wxBOTTOM));
268 }
269 #endif
270
271 #if !wxUSE_MODAL_ABOUT_DIALOG
272
OnCloseWindow(wxCloseEvent & event)273 void wxGenericAboutDialog::OnCloseWindow(wxCloseEvent& event)
274 {
275 // safeguards in case the window is still shown using ShowModal
276 if ( !IsModal() )
277 Destroy();
278
279 event.Skip();
280 }
281
OnOK(wxCommandEvent & event)282 void wxGenericAboutDialog::OnOK(wxCommandEvent& event)
283 {
284 // safeguards in case the window is still shown using ShowModal
285 if ( !IsModal() )
286 {
287 // By default a modeless dialog would be just hidden, destroy this one
288 // instead.
289 Destroy();
290 }
291 else
292 event.Skip();
293 }
294
295 #endif // !wxUSE_MODAL_ABOUT_DIALOG
296
297 // ----------------------------------------------------------------------------
298 // public functions
299 // ----------------------------------------------------------------------------
300
wxGenericAboutBox(const wxAboutDialogInfo & info,wxWindow * parent)301 void wxGenericAboutBox(const wxAboutDialogInfo& info, wxWindow* parent)
302 {
303 #if wxUSE_MODAL_ABOUT_DIALOG
304 wxGenericAboutDialog dlg(info, parent);
305 dlg.ShowModal();
306 #else
307 wxGenericAboutDialog* dlg = new wxGenericAboutDialog(info, parent);
308 dlg->Show();
309 #endif
310 }
311
312 // currently wxAboutBox is implemented natively only under these platforms, for
313 // the others we provide a generic fallback here
314 #if !defined(__WXMSW__) && !defined(__WXMAC__) && \
315 (!defined(__WXGTK20__) || defined(__WXUNIVERSAL__))
316
wxAboutBox(const wxAboutDialogInfo & info,wxWindow * parent)317 void wxAboutBox(const wxAboutDialogInfo& info, wxWindow* parent)
318 {
319 wxGenericAboutBox(info, parent);
320 }
321
322 #endif // platforms without native about dialog
323
324
325 #endif // wxUSE_ABOUTDLG
326