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