show all available information in the dialog (somewhat modified patch 1592306)
[wxWidgets.git] / src / generic / aboutdlgg.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/generic/aboutdlgg.cpp
3 // Purpose: implements wxGenericAboutBox() function
4 // Author: Vadim Zeitlin
5 // Created: 2006-10-08
6 // RCS-ID: $Id$
7 // Copyright: (c) 2006 Vadim Zeitlin <vadim@wxwindows.org>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 // for compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #if wxUSE_ABOUTDLG
27
28 #ifndef WX_PRECOMP
29 #include "wx/sizer.h"
30 #include "wx/statbmp.h"
31 #include "wx/stattext.h"
32 #include "wx/button.h"
33 #endif //WX_PRECOMP
34
35 #include "wx/aboutdlg.h"
36 #include "wx/generic/aboutdlgg.h"
37
38 #include "wx/hyperlink.h"
39 #include "wx/collpane.h"
40
41 // ============================================================================
42 // implementation
43 // ============================================================================
44
45 // helper function: returns all array elements in a single comma-separated and
46 // newline-terminated string
47 static wxString AllAsString(const wxArrayString& a)
48 {
49 wxString s;
50 const size_t count = a.size();
51 s.reserve(20*count);
52 for ( size_t n = 0; n < count; n++ )
53 {
54 s << a[n] << (n == count - 1 ? _T("\n") : _T(", "));
55 }
56
57 return s;
58 }
59
60 // ----------------------------------------------------------------------------
61 // wxAboutDialogInfo
62 // ----------------------------------------------------------------------------
63
64 wxString wxAboutDialogInfo::GetDescriptionAndCredits() const
65 {
66 wxString s = GetDescription();
67 if ( !s.empty() )
68 s << _T('\n');
69
70 if ( HasDevelopers() )
71 s << _T('\n') << _("Developed by ") << AllAsString(GetDevelopers());
72
73 if ( HasDocWriters() )
74 s << _T('\n') << _("Documentation by ") << AllAsString(GetDocWriters());
75
76 if ( HasArtists() )
77 s << _T('\n') << _("Graphics art by ") << AllAsString(GetArtists());
78
79 if ( HasTranslators() )
80 s << _T('\n') << _("Translations by ") << AllAsString(GetTranslators());
81
82 return s;
83 }
84
85 wxIcon wxAboutDialogInfo::GetIcon() const
86 {
87 wxIcon icon = m_icon;
88 if ( !icon.Ok() && wxTheApp )
89 {
90 const wxTopLevelWindow * const
91 tlw = wxDynamicCast(wxTheApp->GetTopWindow(), wxTopLevelWindow);
92 if ( tlw )
93 icon = tlw->GetIcon();
94 }
95
96 return icon;
97 }
98
99 // ----------------------------------------------------------------------------
100 // wxGenericAboutDialog
101 // ----------------------------------------------------------------------------
102
103 bool wxGenericAboutDialog::Create(const wxAboutDialogInfo& info)
104 {
105 // TODO: should we use main frame as parent by default here?
106 if ( !wxDialog::Create(NULL, wxID_ANY, _("About ") + info.GetName(),
107 wxDefaultPosition, wxDefaultSize, wxRESIZE_BORDER|wxDEFAULT_DIALOG_STYLE) )
108 return false;
109
110 m_sizerText = new wxBoxSizer(wxVERTICAL);
111 wxString nameAndVersion = info.GetName();
112 if ( info.HasVersion() )
113 nameAndVersion << _T(' ') << info.GetVersion();
114 wxStaticText *label = new wxStaticText(this, wxID_ANY, nameAndVersion);
115 wxFont fontBig(*wxNORMAL_FONT);
116 fontBig.SetPointSize(fontBig.GetPointSize() + 2);
117 fontBig.SetWeight(wxFONTWEIGHT_BOLD);
118 label->SetFont(fontBig);
119
120 m_sizerText->Add(label, wxSizerFlags().Centre().Border());
121 m_sizerText->AddSpacer(5);
122
123 AddText(info.GetCopyright());
124 AddText(info.GetDescription());
125
126 if ( info.HasWebSite() )
127 {
128 #if wxUSE_HYPERLINKCTRL
129 AddControl(new wxHyperlinkCtrl(this, wxID_ANY,
130 info.GetWebSiteDescription(),
131 info.GetWebSiteURL()));
132 #else
133 AddText(info.GetWebSiteURL());
134 #endif // wxUSE_HYPERLINKCTRL/!wxUSE_HYPERLINKCTRL
135 }
136
137 #if wxUSE_COLLPANE
138 if ( info.HasLicence() )
139 AddCollapsiblePane(wxT("License"), info.GetLicence());
140
141 if ( info.HasDevelopers() )
142 AddCollapsiblePane(wxT("Developers"),
143 AllAsString(info.GetDevelopers()));
144
145 if ( info.HasDocWriters() )
146 AddCollapsiblePane(wxT("Documentation writers"),
147 AllAsString(info.GetDocWriters()));
148
149 if ( info.HasArtists() )
150 AddCollapsiblePane(wxT("Artists"),
151 AllAsString(info.GetArtists()));
152
153 if ( info.HasTranslators() )
154 AddCollapsiblePane(wxT("Translators"),
155 AllAsString(info.GetTranslators()));
156 #endif // wxUSE_COLLPANE
157
158 DoAddCustomControls();
159
160
161 wxSizer *sizerIconAndText = new wxBoxSizer(wxHORIZONTAL);
162 #if wxUSE_STATBMP
163 wxIcon icon = info.GetIcon();
164 if ( icon.Ok() )
165 {
166 sizerIconAndText->Add(new wxStaticBitmap(this, wxID_ANY, icon),
167 wxSizerFlags().Border(wxRIGHT));
168 }
169 #endif // wxUSE_STATBMP
170 sizerIconAndText->Add(m_sizerText, wxSizerFlags(1).Expand());
171
172 wxSizer *sizerTop = new wxBoxSizer(wxVERTICAL);
173 sizerTop->Add(sizerIconAndText, wxSizerFlags(1).Expand().Border());
174
175 wxSizer *sizerBtns = CreateButtonSizer(wxOK);
176 if ( sizerBtns )
177 {
178 sizerTop->Add(sizerBtns, wxSizerFlags().Expand().Border());
179 }
180
181 SetSizerAndFit(sizerTop);
182
183 CentreOnScreen();
184
185 return true;
186 }
187
188 void wxGenericAboutDialog::AddControl(wxWindow *win, const wxSizerFlags& flags)
189 {
190 wxCHECK_RET( m_sizerText, _T("can only be called after Create()") );
191 wxASSERT_MSG( win, _T("can't add NULL window to about dialog") );
192
193 m_sizerText->Add(win, flags);
194 }
195
196 void wxGenericAboutDialog::AddControl(wxWindow *win)
197 {
198 AddControl(win, wxSizerFlags().Border(wxDOWN).Centre());
199 }
200
201 void wxGenericAboutDialog::AddText(const wxString& text)
202 {
203 if ( !text.empty() )
204 AddControl(new wxStaticText(this, wxID_ANY, text));
205 }
206
207 void wxGenericAboutDialog::AddCollapsiblePane(const wxString& title,
208 const wxString& text)
209 {
210 wxCollapsiblePane *pane = new wxCollapsiblePane(this, wxID_ANY, title);
211 wxStaticText *txt = new wxStaticText(pane->GetPane(), wxID_ANY, text,
212 wxDefaultPosition, wxDefaultSize,
213 wxALIGN_CENTRE);
214
215 // don't make the text unreasonably wide
216 static const int maxWidth = wxGetDisplaySize().x/3;
217 txt->Wrap(maxWidth);
218
219 // NB: all the wxCollapsiblePanes must be added with a null proportion value
220 m_sizerText->Add(pane, wxSizerFlags(0).Expand().Border(wxBOTTOM));
221 }
222
223 // ----------------------------------------------------------------------------
224 // public functions
225 // ----------------------------------------------------------------------------
226
227 void wxGenericAboutBox(const wxAboutDialogInfo& info)
228 {
229 wxGenericAboutDialog dlg(info);
230 dlg.ShowModal();
231 }
232
233 // currently wxAboutBox is implemented natively only under these platforms, for
234 // the others we provide a generic fallback here
235 #if !defined(__WXMSW__) && !defined(__WXMAC__) && !defined(__WXGTK26__)
236
237 void wxAboutBox(const wxAboutDialogInfo& info)
238 {
239 wxGenericAboutBox(info);
240 }
241
242 #endif // platforms without native about dialog
243
244
245 #endif // wxUSE_ABOUTDLG