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  wxBoxSizer* bSizer = new wxBoxSizer( wxHORIZONTAL );
201 
202  wxScrolledWindow* m_scrolledWindow1 = new wxScrolledWindow( aParent, wxID_ANY,
203  wxDefaultPosition,
204  wxDefaultSize,
205  wxHSCROLL|wxVSCROLL );
206  m_scrolledWindow1->SetScrollRate( 5, 5 );
207 
208  /* Panel for additional space at the left,
209  * but can also be used to show an additional bitmap.
210  */
211  wxPanel* panel1 = new wxPanel( m_scrolledWindow1 );
212 
213  wxFlexGridSizer* fgSizer1 = createFlexGridSizer();
214 
215  for( size_t i=0; i < aContributors.GetCount(); ++i )
216  {
217  CONTRIBUTOR* contributor = &aContributors.Item( i );
218 
219  wxBitmap* icon = contributor->GetIcon();
220  wxString category = contributor->GetCategory();
221 
222  /* to construct the next row we expect to have
223  * a category and a contributor that was not considered up to now
224  */
225  if( ( category != wxEmptyString ) && !( contributor->IsChecked() ) )
226  {
227  // Icon at first column
228  wxStaticBitmap* m_bitmap1 = createStaticBitmap( m_scrolledWindow1, icon );
229  fgSizer1->Add( m_bitmap1, 0, wxALIGN_CENTER|wxLEFT|wxRIGHT, 5 );
230 
231  // Category name at second column
232  wxStaticText* m_staticText1 = new wxStaticText( m_scrolledWindow1, wxID_ANY,
233  contributor->GetCategory() + wxT( ":" ),
234  wxDefaultPosition, wxDefaultSize, 0 );
235  m_staticText1->SetFont( wxFont( -1, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL,
236  wxFONTWEIGHT_BOLD, false,
237  wxEmptyString ) ); // bold font
238  m_staticText1->Wrap( -1 );
239  fgSizer1->Add( m_staticText1, 0, wxALIGN_LEFT|wxBOTTOM, 2 );
240 
241  // Nothing at third column
242  fgSizer1->AddSpacer( 5 );
243 
244  // Now, all contributors of the same category will follow
245  for( size_t j=0; j < aContributors.GetCount(); ++j )
246  {
247  CONTRIBUTOR* sub_contributor = &aContributors.Item( j );
248 
249  if ( sub_contributor->GetCategory() == category )
250  {
251  // First column is empty
252  fgSizer1->AddSpacer(5);
253 
254  wxControl* ctrl;
255 
256  // No URL supplied, display normal text control
257  if( sub_contributor->GetUrl().IsEmpty() )
258  {
259  ctrl = new wxStaticText( m_scrolledWindow1, wxID_ANY,
260  wxT( " • " ) + sub_contributor->GetName(),
261  wxDefaultPosition,
262  wxDefaultSize, 0 );
263  }
264  else
265  {
266  // Display a hyperlink control instead
267  ctrl = new wxHyperlinkCtrl( m_scrolledWindow1, wxID_ANY,
268  wxT( "• " ) + sub_contributor->GetName(),
269  sub_contributor->GetUrl(),
270  wxDefaultPosition,
271  wxDefaultSize, wxHL_ALIGN_LEFT );
272  }
273 
274  m_staticText1->Wrap( -1 );
275 
276  fgSizer1->Add( ctrl, 0, wxALIGN_LEFT|wxBOTTOM, 2 );
277 
278  // Email address of contributor at third column
279  if( sub_contributor->GetEMail() != wxEmptyString )
280  {
281  wxStaticText* mail = wxStaticTextMail( m_scrolledWindow1,
282  sub_contributor->GetEMail() );
283  fgSizer1->Add( mail, 0, wxALIGN_LEFT|wxBOTTOM, 2 );
284  }
285  else
286  {
287  fgSizer1->AddSpacer( 5 );
288  }
289 
290  /* this contributor was added to the GUI,
291  * thus can be ignored next time
292  */
293  sub_contributor->SetChecked( true );
294  }
295  }
296  }
297  else
298  {
299  continue;
300  }
301  }
302 
303  /* Now, lets list the remaining contributors that have not been considered
304  * because they were not assigned to any category.
305  */
306  for ( size_t k=0; k < aContributors.GetCount(); ++k )
307  {
308  CONTRIBUTOR* contributor = &aContributors.Item( k );
309 
310  if ( contributor->IsChecked() )
311  continue;
312 
313  // Icon at first column
314  wxStaticBitmap* m_bitmap1 = createStaticBitmap( m_scrolledWindow1, contributor->GetIcon() );
315  fgSizer1->Add( m_bitmap1, 0, wxALIGN_CENTER|wxLEFT|wxRIGHT, 5 );
316 
317  // Name of contributor at second column
318  if( contributor->GetName() != wxEmptyString )
319  {
320  wxStaticText* m_staticText1 = new wxStaticText( m_scrolledWindow1, wxID_ANY,
321  contributor->GetName(),
322  wxDefaultPosition, wxDefaultSize, 0 );
323  m_staticText1->Wrap( -1 );
324  fgSizer1->Add( m_staticText1, 0, wxALIGN_LEFT|wxBOTTOM, 2 );
325  }
326  else
327  {
328  fgSizer1->AddSpacer( 5 );
329  }
330 
331  // Email address of contributor at third column
332  if ( contributor->GetEMail() != wxEmptyString )
333  {
334  wxStaticText* mail = wxStaticTextMail( m_scrolledWindow1,
335  contributor->GetEMail() );
336  fgSizer1->Add( mail, 0, wxALIGN_LEFT|wxBOTTOM, 2 );
337  }
338  else
339  {
340  fgSizer1->AddSpacer( 5 );
341  }
342  }
343 
344  bSizer->Add( panel1, 1, wxEXPAND|wxALL, 10 );
345  bSizer->Add( fgSizer1, 7, wxEXPAND|wxALL, 10 ); // adjust width of panel with first int value
346  m_scrolledWindow1->SetSizer( bSizer );
347  m_scrolledWindow1->Layout();
348  bSizer->Fit( m_scrolledWindow1 );
349  aParent->AddPage( m_scrolledWindow1, aCaption, false, aIcon );
350 }
351 
352 
353 void DIALOG_ABOUT::createNotebookHtmlPage( wxAuiNotebook* aParent, const wxString& aCaption,
354  const wxBitmap& aIcon, const wxString& html,
355  bool aSelection )
356 {
357  wxPanel* panel = new wxPanel( aParent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
358  wxTAB_TRAVERSAL );
359 
360  wxBoxSizer* bSizer = new wxBoxSizer( wxVERTICAL );
361 
362  wxString htmlPage = wxEmptyString, htmlContent = html;
363 
364  // to have a unique look background color for HTML pages is set to the default as it is
365  // used for all the other widgets
366  wxString htmlColor = ( this->GetBackgroundColour() ).GetAsString( wxC2S_HTML_SYNTAX );
367 
368  // beginning of HTML structure
369  htmlPage.Append( wxT( "<html><body bgcolor='" ) + htmlColor + wxT( "'>" ) );
370 
371  htmlPage.Append( htmlContent );
372 
373  // end of HTML structure indicated by closing tags
374  htmlPage.Append( wxT( "</body></html>" ) );
375 
376  int flags = aSelection ? wxHW_SCROLLBAR_AUTO : ( wxHW_SCROLLBAR_AUTO | wxHW_NO_SELECTION );
377 
378  // the HTML page is going to be created with previously created HTML content
379  auto htmlWindow = new wxHtmlWindow( panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, flags );
380 
381  // HTML font set to font properties as they are used for widgets to have an unique look
382  // under different platforms with HTML
383  wxFont font = this->GetFont();
384  htmlWindow->SetStandardFonts( font.GetPointSize(), font.GetFaceName(), font.GetFaceName() );
385  htmlWindow->SetPage( htmlPage );
386 
387  // the HTML window shall not be used to open external links, thus this task is delegated
388  // to users default browser
389  htmlWindow->Connect( wxEVT_COMMAND_HTML_LINK_CLICKED,
390  wxHtmlLinkEventHandler( DIALOG_ABOUT::onHtmlLinkClicked ), NULL, this );
391 
392  // no additional space around the HTML window as it is also the case by the other notebook pages
393  bSizer->Add( htmlWindow, 1, wxALL|wxEXPAND, 0 );
394  panel->SetSizer( bSizer );
395  panel->Layout();
396  bSizer->Fit( panel );
397  aParent->AddPage( panel, aCaption, false, aIcon );
398 }
399 
400 
401 wxStaticText* DIALOG_ABOUT::wxStaticTextMail(wxScrolledWindow* aParent, const wxString& aEmail)
402 {
403  wxStaticText* text = new wxStaticText( aParent, wxID_ANY,
404  wxT( "<" ) + aEmail + wxT( ">" ) );
405 
406  return text;
407 }
408 
409 
410 wxStaticBitmap* DIALOG_ABOUT::createStaticBitmap(wxScrolledWindow* aParent, wxBitmap* aIcon)
411 {
412  wxStaticBitmap* bitmap = new wxStaticBitmap( aParent, wxID_ANY, wxNullBitmap,
413  wxDefaultPosition, wxDefaultSize, 0 );
414 
415  if( aIcon )
416  {
417  bitmap->SetBitmap( *aIcon );
418  }
419  else
420  {
421  bitmap->SetBitmap( KiBitmap( right_xpm ) );
422  }
423 
424  return bitmap;
425 }
426 
427 
428 void DIALOG_ABOUT::onHtmlLinkClicked( wxHtmlLinkEvent& event )
429 {
430  ::wxLaunchDefaultBrowser( event.GetLinkInfo().GetHref() );
431 }
432 
433 
434 void DIALOG_ABOUT::onCopyVersionInfo( wxCommandEvent& event )
435 {
436  if( !wxTheClipboard->Open() )
437  {
438  wxMessageBox( _( "Could not open clipboard to write version information." ),
439  _( "Clipboard Error" ), wxOK | wxICON_EXCLAMATION, this );
440  return;
441  }
442 
443  wxString msg_version = GetVersionInfoData( m_titleName );
444 
445  wxTheClipboard->SetData( new wxTextDataObject( msg_version ) );
446  wxTheClipboard->Close();
447  m_btCopyVersionInfo->SetLabel( _( "Copied..." ) );
448 }
449 
450 
451 void DIALOG_ABOUT::onReportBug( wxCommandEvent& event )
452 {
453  if( TOOL_MANAGER* mgr = static_cast<EDA_BASE_FRAME*>( GetParent() )->GetToolManager() )
454  mgr->RunAction( "common.SuiteControl.reportBug", true );
455 }
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
Subclass of DIALOG_DISPLAY_HTML_TEXT_BASE, which is generated by wxFormBuilder.
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:205
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)