| 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 | // this is a modal dialog thus we'll use GetParentForModalDialog: |
| 106 | if ( !wxDialog::Create(GetParentForModalDialog(), 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(_("License"), info.GetLicence()); |
| 140 | |
| 141 | if ( info.HasDevelopers() ) |
| 142 | AddCollapsiblePane(_("Developers"), |
| 143 | AllAsString(info.GetDevelopers())); |
| 144 | |
| 145 | if ( info.HasDocWriters() ) |
| 146 | AddCollapsiblePane(_("Documentation writers"), |
| 147 | AllAsString(info.GetDocWriters())); |
| 148 | |
| 149 | if ( info.HasArtists() ) |
| 150 | AddCollapsiblePane(_("Artists"), |
| 151 | AllAsString(info.GetArtists())); |
| 152 | |
| 153 | if ( info.HasTranslators() ) |
| 154 | AddCollapsiblePane(_("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 |