KiCad PCB EDA Suite
dialog_about.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2010 Rafael Sokolowski <Rafael.Sokolowski@web.de>
5  * Copyright (C) 2017-2020 KiCad Developers, see CHANGELOG.TXT for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
25 
26 #include <config.h>
27 #include <string>
28 
29 #include <wx/clipbrd.h>
30 #include <wx/msgdlg.h>
31 #include <wx/hyperlink.h>
32 
33 /* All KiCad icons are linked into shared library 'libbitmaps.a'.
34  * Icons:
35  * preference_xpm; // Icon for 'Developers' tab
36  * editor_xpm; // Icon for 'Doc Writers' tab
37  * palette_xpm; // Icon for 'Artists' tab
38  * language_xpm; // Icon for 'Translators' tab
39  * right_xpm; // Right arrow icon for list items
40  * info_xpm; // Bulb for description tab
41  * tools_xpm; // Sheet of paper icon for license info tab
42  */
43 #include <bitmaps.h>
44 #include <build_version.h>
45 #include <html_messagebox.h>
46 #include <tool/tool_manager.h>
47 
48 #include "dialog_about.h"
49 
50 
52  : DIALOG_ABOUT_BASE( aParent ), m_info( aAppInfo )
53 {
54  wxASSERT( aParent != nullptr );
55 
64 
65  if( m_info.GetAppIcon().IsOk() )
66  {
67  SetIcon( m_info.GetAppIcon() );
68  m_bitmapApp->SetBitmap( m_info.GetAppIcon() );
69  }
70  else
71  {
72  wxIcon icon;
73  icon.CopyFromBitmap( KiBitmap( icon_kicad_xpm ) );
74  SetIcon( icon );
75  m_bitmapApp->SetBitmap( icon );
76  }
77 
78  m_titleName = aParent->GetAboutTitle();
79  m_staticTextAppTitle->SetLabel( m_titleName );
81  m_staticTextBuildVersion->SetLabel( "Version: " + m_info.GetBuildVersion() );
83 
84  SetTitle( wxString::Format( _( "About %s" ), m_titleName ) );
86 
87  GetSizer()->SetSizeHints( this );
88  m_auiNotebook->Update();
89  SetFocus();
90  Centre();
91 }
92 
93 
95 {
96 }
97 
98 
100 {
101  // three columns with vertical and horizontal extra space of two pixels
102  wxFlexGridSizer* fgSizer = new wxFlexGridSizer( 3, 2, 2 );
103  fgSizer->SetFlexibleDirection( wxHORIZONTAL );
104  fgSizer->SetNonFlexibleGrowMode( wxFLEX_GROWMODE_SPECIFIED );
105 
106  return fgSizer;
107 }
108 
109 
111 {
114 
115  wxString version = GetVersionInfoData( m_titleName, true );
116 
117  createNotebookHtmlPage( m_auiNotebook, _( "Version" ), m_picVersion, version, true );
118 
120  m_info.GetDevelopers() );
122  m_info.GetDocWriters() );
123 
125  m_info.GetArtists() );
129  m_info.GetPackagers() );
130 
132 }
133 
134 void DIALOG_ABOUT::createNotebookPage( wxAuiNotebook* aParent, const wxString& aCaption,
135  const wxBitmap& aIcon, const CONTRIBUTORS& aContributors )
136 {
137  wxBoxSizer* bSizer = new wxBoxSizer( wxHORIZONTAL );
138 
139  wxScrolledWindow* m_scrolledWindow1 = new wxScrolledWindow( aParent, wxID_ANY,
140  wxDefaultPosition,
141  wxDefaultSize,
142  wxHSCROLL|wxVSCROLL );
143  m_scrolledWindow1->SetScrollRate( 5, 5 );
144 
145  /* Panel for additional space at the left,
146  * but can also be used to show an additional bitmap.
147  */
148  wxPanel* panel1 = new wxPanel( m_scrolledWindow1 );
149 
150  wxFlexGridSizer* fgSizer1 = createFlexGridSizer();
151 
152  for( size_t i=0; i<aContributors.GetCount(); ++i )
153  {
154  CONTRIBUTOR* contributor = &aContributors.Item( i );
155 
156  // Icon at first column
157  wxStaticBitmap* m_bitmap1 = createStaticBitmap( m_scrolledWindow1, contributor->GetIcon() );
158  fgSizer1->Add( m_bitmap1, 0, wxALIGN_CENTER|wxLEFT|wxRIGHT, 5 );
159 
160  // Name of contributor at second column
161  if ( contributor->GetName() != wxEmptyString )
162  {
163  wxStaticText* m_staticText1 = new wxStaticText( m_scrolledWindow1, wxID_ANY,
164  contributor->GetName(),
165  wxDefaultPosition, wxDefaultSize, 0 );
166  m_staticText1->Wrap( -1 );
167  fgSizer1->Add( m_staticText1, 0, wxALIGN_LEFT|wxBOTTOM, 2 );
168  }
169  else
170  {
171  fgSizer1->AddSpacer( 5 );
172  }
173 
174  // Email address of contributor at third column
175  if ( contributor->GetEMail() != wxEmptyString )
176  {
177  wxStaticText* hyperlink = wxStaticTextMail( m_scrolledWindow1,
178  contributor->GetEMail() );
179  fgSizer1->Add( hyperlink, 0, wxALIGN_LEFT|wxBOTTOM, 2 );
180  }
181  else
182  {
183  fgSizer1->AddSpacer( 5 );
184  }
185  }
186 
187  bSizer->Add( panel1, 1, wxEXPAND|wxALL, 10 );
188  bSizer->Add( fgSizer1, 7, wxEXPAND|wxALL, 10 ); // adjust width of panel with first int value
189  m_scrolledWindow1->SetSizer( bSizer );
190  m_scrolledWindow1->Layout();
191  bSizer->Fit( m_scrolledWindow1 );
192  aParent->AddPage( m_scrolledWindow1, aCaption, false, aIcon );
193 }
194 
195 
196 void DIALOG_ABOUT::createNotebookPageByCategory( wxAuiNotebook* aParent, const wxString& aCaption,
197  const wxBitmap& aIcon,
198  const CONTRIBUTORS& aContributors)
199 {
200  // The left justification between wxStaticText and wxHyperlinkCtrl is different so
201  // we must pad to make the alignment look decent.
202  //
203  // @todo Just make all of the contributor lists HTML so the alignment is consistent.
204  wxString padding;
205 
206  // Of course the padding is different depending on the platform so we adjust the
207  // padding accordingly.
208 #if defined( __WXGTK__ )
209  padding += " ";
210 #endif
211 
212  wxBoxSizer* bSizer = new wxBoxSizer( wxHORIZONTAL );
213 
214  wxScrolledWindow* m_scrolledWindow1 = new wxScrolledWindow( aParent, wxID_ANY,
215  wxDefaultPosition,
216  wxDefaultSize,
217  wxHSCROLL|wxVSCROLL );
218  m_scrolledWindow1->SetScrollRate( 5, 5 );
219 
220  /* Panel for additional space at the left,
221  * but can also be used to show an additional bitmap.
222  */
223  wxPanel* panel1 = new wxPanel( m_scrolledWindow1 );
224 
225  wxFlexGridSizer* fgSizer1 = createFlexGridSizer();
226 
227  for( size_t i=0; i < aContributors.GetCount(); ++i )
228  {
229  CONTRIBUTOR* contributor = &aContributors.Item( i );
230 
231  wxBitmap* icon = contributor->GetIcon();
232  wxString category = contributor->GetCategory();
233 
234  /* to construct the next row we expect to have
235  * a category and a contributor that was not considered up to now
236  */
237  if( ( category != wxEmptyString ) && !( contributor->IsChecked() ) )
238  {
239  // Icon at first column
240  wxStaticBitmap* m_bitmap1 = createStaticBitmap( m_scrolledWindow1, icon );
241  fgSizer1->Add( m_bitmap1, 0, wxALIGN_CENTER|wxLEFT|wxRIGHT, 5 );
242 
243  // Category name at second column
244  wxStaticText* m_staticText1 = new wxStaticText( m_scrolledWindow1, wxID_ANY,
245  contributor->GetCategory() + wxT( ":" ),
246  wxDefaultPosition, wxDefaultSize, 0 );
247  m_staticText1->SetFont( wxFont( -1, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL,
248  wxFONTWEIGHT_BOLD, false,
249  wxEmptyString ) ); // bold font
250  m_staticText1->Wrap( -1 );
251  fgSizer1->Add( m_staticText1, 0, wxALIGN_LEFT|wxBOTTOM, 2 );
252 
253  // Nothing at third column
254  fgSizer1->AddSpacer( 5 );
255 
256  // Now, all contributors of the same category will follow
257  for( size_t j=0; j < aContributors.GetCount(); ++j )
258  {
259  CONTRIBUTOR* sub_contributor = &aContributors.Item( j );
260 
261  if ( sub_contributor->GetCategory() == category )
262  {
263  // First column is empty
264  fgSizer1->AddSpacer( 5 );
265 
266  wxControl* ctrl;
267 
268  // No URL supplied, display normal text control
269  if( sub_contributor->GetUrl().IsEmpty() )
270  {
271  ctrl = new wxStaticText( m_scrolledWindow1, wxID_ANY,
272  padding + wxT( "• " ) + sub_contributor->GetName(),
273  wxDefaultPosition,
274  wxDefaultSize, 0 );
275  }
276  else
277  {
278  // Display a hyperlink control instead
279  ctrl = new wxHyperlinkCtrl( m_scrolledWindow1, wxID_ANY,
280  wxT( "• " ) + sub_contributor->GetName(),
281  sub_contributor->GetUrl(),
282  wxDefaultPosition,
283  wxDefaultSize,
284  wxBORDER_NONE | wxHL_CONTEXTMENU | wxHL_ALIGN_LEFT );
285  }
286 
287  m_staticText1->Wrap( -1 );
288 
289  fgSizer1->Add( ctrl, 0, wxALIGN_LEFT|wxBOTTOM, 2 );
290 
291  // Email address of contributor at third column
292  if( sub_contributor->GetEMail() != wxEmptyString )
293  {
294  wxStaticText* mail = wxStaticTextMail( m_scrolledWindow1,
295  sub_contributor->GetEMail() );
296  fgSizer1->Add( mail, 0, wxALIGN_LEFT|wxBOTTOM, 2 );
297  }
298  else
299  {
300  fgSizer1->AddSpacer( 5 );
301  }
302 
303  /* this contributor was added to the GUI,
304  * thus can be ignored next time
305  */
306  sub_contributor->SetChecked( true );
307  }
308  }
309  }
310  else
311  {
312  continue;
313  }
314  }
315 
316  /* Now, lets list the remaining contributors that have not been considered
317  * because they were not assigned to any category.
318  */
319  for ( size_t k=0; k < aContributors.GetCount(); ++k )
320  {
321  CONTRIBUTOR* contributor = &aContributors.Item( k );
322 
323  if ( contributor->IsChecked() )
324  continue;
325 
326  // Icon at first column
327  wxStaticBitmap* m_bitmap1 = createStaticBitmap( m_scrolledWindow1, contributor->GetIcon() );
328  fgSizer1->Add( m_bitmap1, 0, wxALIGN_CENTER|wxLEFT|wxRIGHT, 5 );
329 
330  // Name of contributor at second column
331  if( contributor->GetName() != wxEmptyString )
332  {
333  wxStaticText* m_staticText1 = new wxStaticText( m_scrolledWindow1, wxID_ANY,
334  contributor->GetName(),
335  wxDefaultPosition, wxDefaultSize, 0 );
336  m_staticText1->Wrap( -1 );
337  fgSizer1->Add( m_staticText1, 0, wxALIGN_LEFT|wxBOTTOM, 2 );
338  }
339  else
340  {
341  fgSizer1->AddSpacer( 5 );
342  }
343 
344  // Email address of contributor at third column
345  if ( contributor->GetEMail() != wxEmptyString )
346  {
347  wxStaticText* mail = wxStaticTextMail( m_scrolledWindow1,
348  contributor->GetEMail() );
349  fgSizer1->Add( mail, 0, wxALIGN_LEFT|wxBOTTOM, 2 );
350  }
351  else
352  {
353  fgSizer1->AddSpacer( 5 );
354  }
355  }
356 
357  bSizer->Add( panel1, 1, wxEXPAND|wxALL, 10 );
358  bSizer->Add( fgSizer1, 7, wxEXPAND|wxALL, 10 ); // adjust width of panel with first int value
359  m_scrolledWindow1->SetSizer( bSizer );
360  m_scrolledWindow1->Layout();
361  bSizer->Fit( m_scrolledWindow1 );
362  aParent->AddPage( m_scrolledWindow1, aCaption, false, aIcon );
363 }
364 
365 
366 void DIALOG_ABOUT::createNotebookHtmlPage( wxAuiNotebook* aParent, const wxString& aCaption,
367  const wxBitmap& aIcon, const wxString& html,
368  bool aSelection )
369 {
370  wxPanel* panel = new wxPanel( aParent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
371  wxTAB_TRAVERSAL );
372 
373  wxBoxSizer* bSizer = new wxBoxSizer( wxVERTICAL );
374 
375  wxString htmlPage = wxEmptyString, htmlContent = html;
376 
377  // to have a unique look background color for HTML pages is set to the default as it is
378  // used for all the other widgets
379  wxString htmlColor = ( this->GetBackgroundColour() ).GetAsString( wxC2S_HTML_SYNTAX );
380 
381  // beginning of HTML structure
382  htmlPage.Append( wxT( "<html><body bgcolor='" ) + htmlColor + wxT( "'>" ) );
383 
384  htmlPage.Append( htmlContent );
385 
386  // end of HTML structure indicated by closing tags
387  htmlPage.Append( wxT( "</body></html>" ) );
388 
389  int flags = aSelection ? wxHW_SCROLLBAR_AUTO : ( wxHW_SCROLLBAR_AUTO | wxHW_NO_SELECTION );
390 
391  // the HTML page is going to be created with previously created HTML content
392  auto htmlWindow = new wxHtmlWindow( panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, flags );
393 
394  // HTML font set to font properties as they are used for widgets to have an unique look
395  // under different platforms with HTML
396  wxFont font = this->GetFont();
397  htmlWindow->SetStandardFonts( font.GetPointSize(), font.GetFaceName(), font.GetFaceName() );
398  htmlWindow->SetPage( htmlPage );
399 
400  // the HTML window shall not be used to open external links, thus this task is delegated
401  // to users default browser
402  htmlWindow->Connect( wxEVT_COMMAND_HTML_LINK_CLICKED,
403  wxHtmlLinkEventHandler( DIALOG_ABOUT::onHtmlLinkClicked ), NULL, this );
404 
405  // no additional space around the HTML window as it is also the case by the other notebook pages
406  bSizer->Add( htmlWindow, 1, wxALL|wxEXPAND, 0 );
407  panel->SetSizer( bSizer );
408  panel->Layout();
409  bSizer->Fit( panel );
410  aParent->AddPage( panel, aCaption, false, aIcon );
411 }
412 
413 
414 wxStaticText* DIALOG_ABOUT::wxStaticTextMail( wxScrolledWindow* aParent, const wxString& aEmail )
415 {
416  wxStaticText* text = new wxStaticText( aParent, wxID_ANY,
417  wxT( "<" ) + aEmail + wxT( ">" ) );
418 
419  return text;
420 }
421 
422 
423 wxStaticBitmap* DIALOG_ABOUT::createStaticBitmap( wxScrolledWindow* aParent, wxBitmap* aIcon )
424 {
425  wxStaticBitmap* bitmap = new wxStaticBitmap( aParent, wxID_ANY, wxNullBitmap,
426  wxDefaultPosition, wxDefaultSize, 0 );
427 
428  if( aIcon )
429  {
430  bitmap->SetBitmap( *aIcon );
431  }
432  else
433  {
434  bitmap->SetBitmap( KiBitmap( right_xpm ) );
435  }
436 
437  return bitmap;
438 }
439 
440 
441 void DIALOG_ABOUT::onHtmlLinkClicked( wxHtmlLinkEvent& event )
442 {
443  ::wxLaunchDefaultBrowser( event.GetLinkInfo().GetHref() );
444 }
445 
446 
447 void DIALOG_ABOUT::onCopyVersionInfo( wxCommandEvent& event )
448 {
449  if( !wxTheClipboard->Open() )
450  {
451  wxMessageBox( _( "Could not open clipboard to write version information." ),
452  _( "Clipboard Error" ), wxOK | wxICON_EXCLAMATION, this );
453  return;
454  }
455 
456  wxString msg_version = GetVersionInfoData( m_titleName );
457 
458  wxTheClipboard->SetData( new wxTextDataObject( msg_version ) );
459  wxTheClipboard->Close();
460  m_btCopyVersionInfo->SetLabel( _( "Copied..." ) );
461 }
462 
463 
464 void DIALOG_ABOUT::onReportBug( wxCommandEvent& event )
465 {
466  if( TOOL_MANAGER* mgr = static_cast<EDA_BASE_FRAME*>( GetParent() )->GetToolManager() )
467  mgr->RunAction( "common.SuiteControl.reportBug", true );
468 }
wxFlexGridSizer * createFlexGridSizer()
wxAuiNotebook * m_auiNotebook
const BITMAP_OPAQUE right_xpm[1]
Definition: right.cpp:49
wxBitmap m_picDevelopers
Definition: dialog_about.h:47
wxString & GetUrl()
Definition: aboutinfo.h:173
CONTRIBUTORS GetTranslators()
Definition: aboutinfo.h:83
wxString & GetLibVersion()
Definition: aboutinfo.h:105
void createNotebookHtmlPage(wxAuiNotebook *aParent, const wxString &aCaption, const wxBitmap &aIcon, const wxString &aHtmlMessage, bool aSelection=false)
const BITMAP_OPAQUE editor_xpm[1]
Definition: editor.cpp:83
wxString GetVersionInfoData(const wxString &aTitle, bool aHtml, bool aBrief)
Create a version info string for bug reports and the about dialog.
const BITMAP_OPAQUE palette_xpm[1]
Definition: palette.cpp:89
const BITMAP_OPAQUE icon_kicad_xpm[1]
Definition: icon_kicad.cpp:153
DIALOG_ABOUT(EDA_BASE_FRAME *aParent, ABOUT_APP_INFO &aAppInfo)
wxStaticText * m_staticTextAppTitle
void SetChecked(bool status)
Definition: aboutinfo.h:176
wxString & GetCategory()
Definition: aboutinfo.h:174
wxString & GetName()
Definition: aboutinfo.h:171
const BITMAP_OPAQUE zip_xpm[1]
Definition: zip.cpp:60
void createNotebookPageByCategory(wxAuiNotebook *aParent, const wxString &aCaption, const wxBitmap &aIcon, const CONTRIBUTORS &aContributors)
wxBitmap m_picPackagers
Definition: dialog_about.h:51
void createNotebooks()
wxString & GetBuildVersion()
Definition: aboutinfo.h:99
wxStaticText * m_staticTextLibVersion
wxIcon & GetAppIcon()
Definition: aboutinfo.h:108
An object of this class is meant to be used to store application specific information like who has co...
Definition: aboutinfo.h:44
wxStaticBitmap * m_bitmapApp
wxString & GetLicense()
Definition: aboutinfo.h:90
const BITMAP_OPAQUE recent_xpm[1]
Definition: recent.cpp:68
wxStaticText * wxStaticTextMail(wxScrolledWindow *aParent, const wxString &email)
wxBitmap m_picDocWriters
Definition: dialog_about.h:48
TOOL_MANAGER.
Definition: tool_manager.h:51
wxBitmap KiBitmap(BITMAP_DEF aBitmap)
Construct a wxBitmap from a memory record, held in a BITMAP_DEF.
Definition: bitmap.cpp:80
wxBitmap m_picArtists
Definition: dialog_about.h:49
#define NULL
CONTRIBUTORS GetDocWriters()
Definition: aboutinfo.h:81
wxStaticText * m_staticTextBuildVersion
void onCopyVersionInfo(wxCommandEvent &event) override
void onHtmlLinkClicked(wxHtmlLinkEvent &event)
CONTRIBUTORS GetArtists()
Definition: aboutinfo.h:82
wxBitmap m_picTranslators
Definition: dialog_about.h:50
wxString GetCopyright()
Definition: aboutinfo.h:93
wxStaticText * m_staticTextCopyright
wxBitmap m_picInformation
Definition: dialog_about.h:45
wxBitmap m_picLicense
Definition: dialog_about.h:52
const BITMAP_OPAQUE info_xpm[1]
Definition: info.cpp:75
const BITMAP_OPAQUE language_xpm[1]
Definition: language.cpp:104
const BITMAP_OPAQUE tools_xpm[1]
Definition: tools.cpp:113
wxString & GetEMail()
Definition: aboutinfo.h:172
wxStaticBitmap * createStaticBitmap(wxScrolledWindow *aParent, wxBitmap *icon)
CONTRIBUTORS GetPackagers()
Definition: aboutinfo.h:84
wxBitmap * GetIcon()
Definition: aboutinfo.h:175
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, CPTREE &aTree)
Function Format outputs a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:201
CONTRIBUTORS GetDevelopers()
Definition: aboutinfo.h:80
Class DIALOG_ABOUT_BASE.
#define _(s)
Definition: 3d_actions.cpp:33
const wxString & GetAboutTitle() const
A contributor, a person which was involved in the development of the application or which has contrib...
Definition: aboutinfo.h:152
The base frame for deriving all KiCad main window classes.
wxString m_titleName
Definition: dialog_about.h:53
wxString & GetDescription()
Definition: aboutinfo.h:87
wxButton * m_btCopyVersionInfo
wxBitmap m_picVersion
Definition: dialog_about.h:46
const BITMAP_OPAQUE preference_xpm[1]
Definition: preference.cpp:66
bool IsChecked()
Definition: aboutinfo.h:177
ABOUT_APP_INFO & m_info
Definition: dialog_about.h:55
void onReportBug(wxCommandEvent &event) override
void createNotebookPage(wxAuiNotebook *aParent, const wxString &aCaption, const wxBitmap &aIcon, const CONTRIBUTORS &aContributors)