From edbcf2d0cb5b6cd41f2c8f5da02eea83a87e23f5 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Thu, 20 Aug 2015 09:14:44 +0200 Subject: [PATCH] Add a wizard to Pcbnew to download 3d shapes libraries from Github --- pcbnew/CMakeLists.txt | 7 + .../wizard_3DShape_Libs_downloader.cpp | 522 +++++ .../dialogs/wizard_3DShape_Libs_downloader.h | 146 ++ .../wizard_3DShape_Libs_downloader_base.cpp | 235 ++ .../wizard_3DShape_Libs_downloader_base.fbp | 2050 +++++++++++++++++ .../wizard_3DShape_Libs_downloader_base.h | 86 + pcbnew/dialogs/wizard_add_fplib.cpp | 2 +- pcbnew/github/CMakeLists.txt | 2 +- pcbnew/github/github_getliblist.cpp | 52 +- pcbnew/github/github_getliblist.h | 61 +- pcbnew/github/github_plugin.cpp | 13 +- pcbnew/github/html_link_parser.cpp | 68 + pcbnew/github/html_link_parser.h | 109 + pcbnew/invoke_pcb_dialog.h | 10 + pcbnew/menubar_pcbframe.cpp | 7 + pcbnew/pcbframe.cpp | 1 + pcbnew/pcbnew_config.cpp | 6 + pcbnew/pcbnew_id.h | 1 + 18 files changed, 3353 insertions(+), 25 deletions(-) create mode 100644 pcbnew/dialogs/wizard_3DShape_Libs_downloader.cpp create mode 100644 pcbnew/dialogs/wizard_3DShape_Libs_downloader.h create mode 100644 pcbnew/dialogs/wizard_3DShape_Libs_downloader_base.cpp create mode 100644 pcbnew/dialogs/wizard_3DShape_Libs_downloader_base.fbp create mode 100644 pcbnew/dialogs/wizard_3DShape_Libs_downloader_base.h create mode 100644 pcbnew/github/html_link_parser.cpp create mode 100644 pcbnew/github/html_link_parser.h diff --git a/pcbnew/CMakeLists.txt b/pcbnew/CMakeLists.txt index 9135810401..8885c969d3 100644 --- a/pcbnew/CMakeLists.txt +++ b/pcbnew/CMakeLists.txt @@ -25,6 +25,12 @@ if( KICAD_SCRIPTING OR KICAD_SCRIPTING_MODULES ) endif() +if( BUILD_GITHUB_PLUGIN ) + set( GITHUB_3DLIBRARIES_WIZARD + dialogs/wizard_3DShape_Libs_downloader_base.cpp + dialogs/wizard_3DShape_Libs_downloader.cpp ) +endif() + include_directories( BEFORE ${INC_BEFORE} ) include_directories( ./dialogs @@ -143,6 +149,7 @@ set( PCBNEW_DIALOGS dialogs/dialog_footprint_wizard_list.cpp dialogs/wizard_add_fplib_base.cpp dialogs/wizard_add_fplib.cpp + ${GITHUB_3DLIBRARIES_WIZARD} ) set( PCBNEW_IMPORT_DXF diff --git a/pcbnew/dialogs/wizard_3DShape_Libs_downloader.cpp b/pcbnew/dialogs/wizard_3DShape_Libs_downloader.cpp new file mode 100644 index 0000000000..fd101d6ac1 --- /dev/null +++ b/pcbnew/dialogs/wizard_3DShape_Libs_downloader.cpp @@ -0,0 +1,522 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2015 CERN + * Code derived from "wizard_add_fplib.cpp" ( @author Maciej Suminski ) + * Copyright (C) 2014-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr + * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/** + * @brief Wizard for selecting and dowloading D shapes libraries of footprints + * consisting of 3 steps: + * - select source and destination (Github URL and local folder) + * - pick and select libraries + * - download files + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include <3d_viewer.h> + +#include <../github/github_getliblist.h> + +// a key to store the default Kicad Github 3D libs URL +#define KICAD_3DLIBS_URL_KEY wxT( "kicad_3Dlib_url" ) +#define KICAD_3DLIBS_LAST_DOWNLOAD_DIR wxT( "kicad_3Dlib_last_download_dir" ) + +#define DEFAULT_GITHUB_3DSHAPES_LIBS_URL \ + wxT( "https://github.com/KiCad/kicad-library/tree/master/modules/packages3d" ) + +void Invoke3DShapeLibsDownloaderWizard( wxTopLevelWindow* aParent ) +{ + WIZARD_3DSHAPE_LIBS_DOWNLOADER wizard( aParent ); + wizard.RunWizard( wizard.GetFirstPage() ); +} + + +WIZARD_3DSHAPE_LIBS_DOWNLOADER::WIZARD_3DSHAPE_LIBS_DOWNLOADER( wxWindow* aParent ) : + WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE( aParent ) +{ + m_welcomeDlg = m_pages[0]; + m_githubListDlg = m_pages[1]; + m_reviewDlg = m_pages[2]; + + // Initialize default download dir (local target folder of 3D shapes libs) + wxString default_path; + wxGetEnv( KISYS3DMOD, &default_path ); + + wxConfigBase* cfg = Pgm().CommonSettings(); + cfg->Read( KICAD_3DLIBS_LAST_DOWNLOAD_DIR, &m_lastGithubDownloadDirectory, default_path ); + setDownloadDir( m_lastGithubDownloadDirectory ); + + // Restore the Github 3D shapes libs url + wxString githubUrl; + cfg->Read( KICAD_3DLIBS_URL_KEY, &githubUrl ); + + if( githubUrl.IsEmpty() ) + githubUrl = DEFAULT_GITHUB_3DSHAPES_LIBS_URL; + + SetGithubURL( githubUrl ); + + + // Give the minimal size to the dialog, which allows displaying any page + wxSize minsize; + + for( unsigned ii = 0; ii < m_pages.size(); ii++ ) + { + wxSize size = m_pages[ii]->GetSizer()->CalcMin(); + minsize.x = std::max( minsize.x, size.x ); + minsize.y = std::max( minsize.y, size.y ); + } + + SetMinSize( minsize ); + SetPageSize( minsize ); + GetSizer()->SetSizeHints( this ); + Center(); + + setupDialogOrder(); + updateGithubControls(); + + // When starting m_textCtrlGithubURL has the focus, and the text is selected, + // and not fully visible. + // Forcing deselection does not work, at least on W7 with wxWidgets 3.0.2 + // So (and also because m_textCtrlGithubURL and m_downloadDir are rarely modified + // the focus is given to an other widget. + m_hyperlinkGithubKicad->SetFocus(); + + Connect( wxEVT_RADIOBUTTON, wxCommandEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER::OnSourceCheck ), NULL, this ); + Connect( wxEVT_CHECKLISTBOX, wxCommandEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER::OnCheckGithubList ), NULL, this ); +} + + +WIZARD_3DSHAPE_LIBS_DOWNLOADER::~WIZARD_3DSHAPE_LIBS_DOWNLOADER() +{ + // Use this if you want to store kicad lib URL in pcbnew/cvpcb section config: + // wxConfigBase* cfg = Kiface().KifaceSettings(); + + // Use this if you want to store kicad lib URL in common section config: + wxConfigBase* cfg = Pgm().CommonSettings(); + cfg->Write( KICAD_3DLIBS_URL_KEY, GetGithubURL() ); + cfg->Write( KICAD_3DLIBS_LAST_DOWNLOAD_DIR, getDownloadDir() ); +} + + + +void WIZARD_3DSHAPE_LIBS_DOWNLOADER::OnPageChanged( wxWizardEvent& aEvent ) +{ + SetBitmap( KiBitmap( wizard_add_fplib_icon_xpm ) ); + enableNext( true ); + + if( GetCurrentPage() == m_githubListDlg ) + setupGithubList(); + else if( GetCurrentPage() == m_reviewDlg ) + setupReview(); +} + + +void WIZARD_3DSHAPE_LIBS_DOWNLOADER::OnCheckGithubList( wxCommandEvent& aEvent ) +{ + wxArrayInt dummy; + + enableNext( m_checkList3Dlibnames->GetCheckedItems( dummy ) > 0 ); +} + + +void WIZARD_3DSHAPE_LIBS_DOWNLOADER::OnSourceCheck( wxCommandEvent& aEvent ) +{ + updateGithubControls(); + setupDialogOrder(); +} + +void WIZARD_3DSHAPE_LIBS_DOWNLOADER::OnGridLibReviewSize( wxSizeEvent& event ) +{ + // Adjust the width of the column 1 afo m_gridLibReview (library names) to the + // max available width. + int gridwidth = m_gridLibReview->GetClientSize().x; + gridwidth -= m_gridLibReview->GetColSize( 0 ) + m_gridLibReview->GetColLabelSize(); + + if( gridwidth < 200 ) + gridwidth = 200; + + m_gridLibReview->SetColSize( 1, gridwidth ); + + event.Skip(); +} + + +void WIZARD_3DSHAPE_LIBS_DOWNLOADER::setupReview() +{ + // Prepare the last page of the wizard. + + m_LocalFolderInfo->SetLabel( getDownloadDir() ); + + wxArrayInt checkedIndices; + m_checkList3Dlibnames->GetCheckedItems( checkedIndices ); + + m_libraries.Clear(); + + // populate m_libraries with the name of libraries, without the github path: + for( unsigned int ii = 0; ii < checkedIndices.GetCount(); ++ii ) + { + m_libraries.Add( m_checkList3Dlibnames->GetString( checkedIndices[ii] ).AfterLast( '/' ) ); + } + + // Adjust number of rows in m_gridLibReview: + int delta = m_libraries.GetCount() - m_gridLibReview->GetNumberRows(); + + if( delta < 0 ) + m_gridLibReview->DeleteRows( -delta ); + else if( delta > 0 ) + m_gridLibReview->AppendRows( delta ); + + // For user info, verify the existence of these libs in local folder + wxArrayString liblist; + wxFileName fn; + fn.AssignDir( getDownloadDir() ); + + for( unsigned int ii = 0; ii < m_libraries.GetCount(); ++ii ) + { + fn.SetName( m_libraries[ii] ); + + wxDir dirs; + bool isNew = ! dirs.Exists( fn.GetFullPath() ); + wxString info = isNew ? _( "New" ) : _( "Update" ); + + liblist.Add( info + wxT(" ") + m_libraries[ii] ); + + m_gridLibReview->SetCellValue( ii, 0, info ); + m_gridLibReview->SetCellValue( ii, 1, m_libraries[ii] ); + } + + m_gridLibReview->AutoSizeColumn( 0 ); +} + + +void WIZARD_3DSHAPE_LIBS_DOWNLOADER::OnSelectAll3Dlibs( wxCommandEvent& aEvent ) +{ + for( unsigned int i = 0; i < m_checkList3Dlibnames->GetCount(); ++i ) + m_checkList3Dlibnames->Check( i, true ); + + // The list might be empty, e.g. in case of download error + wxArrayInt dummy; + enableNext( m_checkList3Dlibnames->GetCheckedItems( dummy ) > 0 ); +} + + +void WIZARD_3DSHAPE_LIBS_DOWNLOADER::OnUnselectAll3Dlibs( wxCommandEvent& aEvent ) +{ + for( unsigned int i = 0; i < m_checkList3Dlibnames->GetCount(); ++i ) + m_checkList3Dlibnames->Check( i, false ); + + enableNext( false ); +} + + +void WIZARD_3DSHAPE_LIBS_DOWNLOADER::OnChangeSearch( wxCommandEvent& aEvent ) +{ + wxString searchPhrase = m_searchCtrl3Dlibs->GetValue().Lower(); + + // Store the current selection + wxArrayInt checkedIndices; + m_checkList3Dlibnames->GetCheckedItems( checkedIndices ); + wxArrayString checkedStrings; + + for( unsigned int i = 0; i < checkedIndices.GetCount(); ++i ) + checkedStrings.Add( m_checkList3Dlibnames->GetString( checkedIndices[i] ).AfterLast( '/' ) ); + + m_checkList3Dlibnames->Clear(); + + // Rebuild the list, putting the matching entries on the top + int matching = 0; // number of entries matching the search phrase + for( unsigned int i = 0; i < m_githubLibs.GetCount(); ++i ) + { + const wxString& lib = m_githubLibs[i].AfterLast( '/' ); + bool wasChecked = ( checkedStrings.Index( lib ) != wxNOT_FOUND ); + int insertedIdx = -1; + + if( !searchPhrase.IsEmpty() && lib.Lower().Contains( searchPhrase ) ) + { + insertedIdx = m_checkList3Dlibnames->Insert( lib, matching++ ); + m_checkList3Dlibnames->SetSelection( insertedIdx ); + } + else + insertedIdx = m_checkList3Dlibnames->Append( lib ); + + if( wasChecked ) + m_checkList3Dlibnames->Check( insertedIdx ); + } + + if( !m_checkList3Dlibnames->IsEmpty() ) + m_checkList3Dlibnames->EnsureVisible( 0 ); +} + + +void WIZARD_3DSHAPE_LIBS_DOWNLOADER::OnWizardFinished( wxWizardEvent& aEvent ) +{ + // we download a localy copy of the libraries + wxString error; + + if( !downloadGithubLibsFromList( m_libraries, &error ) ) + { + DisplayError( this, error ); + } +} + + +void WIZARD_3DSHAPE_LIBS_DOWNLOADER::OnBrowseButtonClick( wxCommandEvent& aEvent ) +{ + wxString path = getDownloadDir(); + + path = wxDirSelector( _("Choose a folder to save the downloaded libraries" ), + path, 0, wxDefaultPosition, this ); + + if( !path.IsEmpty() && wxDirExists( path ) ) + { + setDownloadDir( path ); + updateGithubControls(); + } +} + + +void WIZARD_3DSHAPE_LIBS_DOWNLOADER::OnDefault3DPathButtonClick( wxCommandEvent& event ) +{ + wxString default_path; + wxGetEnv( KISYS3DMOD, &default_path ); + + if( !default_path.IsEmpty() && wxDirExists( default_path ) ) + { + setDownloadDir( default_path ); + updateGithubControls(); + } + else + wxMessageBox( _( "KISYS3DMOD path not defined , or not existing" ) ); +} + + +void WIZARD_3DSHAPE_LIBS_DOWNLOADER::OnCheckSaveCopy( wxCommandEvent& aEvent ) +{ + updateGithubControls(); +} + + +void WIZARD_3DSHAPE_LIBS_DOWNLOADER::getLibsListGithub( wxArrayString& aList ) +{ + wxBeginBusyCursor(); + + // Be sure there is no trailing '/' at the end of the repo name + wxString git_url = m_textCtrlGithubURL->GetValue(); + + if( git_url.EndsWith( wxT( "/" ) ) ) + { + git_url.RemoveLast(); + m_textCtrlGithubURL->SetValue( git_url ); + } + + GITHUB_GETLIBLIST getter( git_url ); + getter.Get3DshapesLibsList( &aList, filter3dshapeslibraries ); + + wxEndBusyCursor(); +} + + +// Download the .pretty libraries folders found in aUrlList and store them on disk +// in a master folder +bool WIZARD_3DSHAPE_LIBS_DOWNLOADER::downloadGithubLibsFromList( wxArrayString& aUrlList, + wxString* aErrorMessage ) +{ + // Display a progress bar to show the download state + // The title is updated for each downloaded library. + // the state will be updated by downloadOneLib() for each file. + wxProgressDialog pdlg( _( "Downloading 3D libraries" ), wxEmptyString, + aUrlList.GetCount(), this, + wxPD_CAN_ABORT | wxPD_APP_MODAL | wxPD_AUTO_HIDE ); + + wxString url_base = GetGithubURL(); + + // Download libs: + for( unsigned ii = 0; ii < aUrlList.GetCount(); ii++ ) + { + wxString& libsrc_name = aUrlList[ii]; + + // Extract the lib name from the full URL: + wxString url = GetGithubURL() + wxT( "/" ) + libsrc_name; + wxFileName fn( libsrc_name ); + // Set our local path + fn.SetPath( getDownloadDir() ); + wxString libdst_name = fn.GetFullPath(); + + // Display the name of the library to download in the wxProgressDialog + pdlg.SetTitle( wxString::Format( wxT("%s [%d/%d]" ), + libsrc_name.AfterLast( '/' ).GetData(), + ii + 1, aUrlList.GetCount() ) ); + + if( !wxDirExists( libdst_name ) ) + wxMkdir( libdst_name ); + + if( !downloadOneLib( url, libdst_name, &pdlg, aErrorMessage ) ) + return false; + } + + return true; +} + + +bool WIZARD_3DSHAPE_LIBS_DOWNLOADER::downloadOneLib( const wxString& aLibURL, + const wxString& aLocalLibName, wxProgressDialog * aIndicator, + wxString* aErrorMessage ) +{ + wxArrayString fileslist; + + bool success; + + // Get the list of candidate files: with ext .wrl or .wings + do + { + GITHUB_GETLIBLIST getter( aLibURL ); + success = getter.Get3DshapesLibsList( &fileslist, filter3dshapesfiles ); + } while( 0 ); + + if( !success ) + return false; + + // Load each file in list: + wxURI repo( aLibURL ); + + wxString server = repo.GetServer(); + + // Github gives the current url of files inside .3dshapes folders like: + // "https://github.com/KiCad/kicad-library/blob/master/modules/packages3d/Capacitors_SMD.3dshapes/C_0402.wrl" + // which displays a html page showing the file in htmp form. + // + // the URL of the corresponding raw file is + // "https://github.com/KiCad/kicad-library/raw/master/modules/packages3d/Capacitors_SMD.3dshapes/C_0402.wrl" + // + // However Github redirects this current url to raw.githubusercontent.com/fullfilename + // when trying to download raw files. + // "https://github.com/KiCad/kicad-library/raw/master/modules/packages3d/Capacitors_SMD.3dshapes/C_0402.wrl" + // would be redirected to: + // "https://codeload.github.com/KiCad/kicad-library/master/modules/packages3d/Capacitors_SMD.3dshapes/C_0402.wrl" + // So use raw.githubusercontent.com instead of github.com + // (and removes the "/raw" in path) speed up the downloads (x2 faster). + // + // wxURI has no way to change the server name, so we need to use tricks to make the URL. + // + // Comment this next line to use the github.com URL +#define FORCE_GITHUB_RAW_URL + +#ifdef FORCE_GITHUB_RAW_URL + if( server.Cmp( wxT( "github.com" ) ) == 0 ) + server = wxT( "raw.githubusercontent.com" ); +#endif + + wxString full_url_base = repo.GetScheme() + wxT( "://" ) + server; + wxString target_full_url; + + for( unsigned ii = 0; ii < fileslist.GetCount(); ii++ ) + { + target_full_url = full_url_base + fileslist[ii]; + +#ifdef FORCE_GITHUB_RAW_URL + // Remove "blob/" in URL string to build the URL on "raw.githubusercontent.com" + // server from "github.com" URL string: + target_full_url.Replace( wxT( "blob/" ), wxT( "" ) ); +#else + // Replace "blob" by "raw" in URL to access the raw file itself, not the html page + // on "github.com" server + target_full_url.Replace( wxT( "blob" ), wxT( "raw" ) ); +#endif + aIndicator->SetRange( fileslist.GetCount() ); + bool abort = !aIndicator->Update( ii, target_full_url.AfterLast( '/' ) ); + + if( abort ) + { + if( aErrorMessage ) + *aErrorMessage << _( "Aborted by user" ); + return false; + } + + // Download the current file. + // Get3DshapesLibsList actually downloads and stores the target_full_url content. + GITHUB_GETLIBLIST getter( target_full_url ); + success = getter.Get3DshapesLibsList( NULL, NULL ); + + if( !success ) + break; + + wxFileName fn; + fn.AssignDir( aLocalLibName ); + fn.SetFullName( fileslist[ii].AfterLast( '/' ) ); + + // The entire downloaded file is stored in getter buffer + const std::string& buffer = getter.GetBuffer(); + + // Write is "as this". It can be a binary file. + wxFile file(fn.GetFullPath(), wxFile::write); + file.Write( &buffer[0], buffer.size() ); + } + + return success; +} + + +void WIZARD_3DSHAPE_LIBS_DOWNLOADER::setupGithubList() +{ + // Enable 'Next' only if there is at least one library selected + wxArrayInt checkedIndices; + m_checkList3Dlibnames->GetCheckedItems( checkedIndices ); + enableNext( checkedIndices.GetCount() > 0 ); + + // Update only if necessary + if( m_githubLibs.GetCount() == 0 ) + getLibsListGithub( m_githubLibs ); + + m_searchCtrl3Dlibs->Clear(); + + // Clear the review list so it will be reloaded + m_libraries.clear(); +} + + +void WIZARD_3DSHAPE_LIBS_DOWNLOADER::updateGithubControls() +{ + bool valid = wxFileName::IsDirWritable( getDownloadDir() ); + + // Do not allow to go further unless there is a valid directory selected + m_invalidDir->Show( !valid ); + enableNext( valid ); +} + + +void WIZARD_3DSHAPE_LIBS_DOWNLOADER::setupDialogOrder() +{ + m_welcomeDlg->SetNext( m_githubListDlg ); + m_githubListDlg->SetPrev( m_welcomeDlg ); + m_githubListDlg->SetNext( m_reviewDlg ); + m_reviewDlg->SetPrev( m_githubListDlg ); +} + diff --git a/pcbnew/dialogs/wizard_3DShape_Libs_downloader.h b/pcbnew/dialogs/wizard_3DShape_Libs_downloader.h new file mode 100644 index 0000000000..e3cf00ddce --- /dev/null +++ b/pcbnew/dialogs/wizard_3DShape_Libs_downloader.h @@ -0,0 +1,146 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2015 CERN + * Code derived from "wizard_add_fplib.h" (from Maciej Suminski ) + * Copyright (C) 2014-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr + * Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +class KIWAY_PLAYER; + +class WIZARD_3DSHAPE_LIBS_DOWNLOADER : public WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE +{ +public: + WIZARD_3DSHAPE_LIBS_DOWNLOADER( wxWindow* aParent ); + ~WIZARD_3DSHAPE_LIBS_DOWNLOADER(); + + /** + * Function GetFirstPage + * Returns the welcoming page for the wizard. + */ + inline wxWizardPage* GetFirstPage() const + { + return m_welcomeDlg; + } + + /** + * Function GetGithubURL + * Returns the current Github repository URL set in the wizard. + */ + inline wxString GetGithubURL() const + { + return m_textCtrlGithubURL->GetValue(); + } + + /** + * Function SetGithubURL + * Sets the current Github repository URL used by the wizard. + * @param aUrl is the new URL to be applied. + */ + inline void SetGithubURL( const wxString& aUrl ) + { + m_textCtrlGithubURL->SetValue( aUrl ); + } + + // Wizard event handlers + void OnSourceCheck( wxCommandEvent& aEvent ); + void OnCheckGithubList( wxCommandEvent& aEvent ); + void OnPageChanged( wxWizardEvent& aEvent ); + void OnSelectAll3Dlibs( wxCommandEvent& aEvent ); + void OnUnselectAll3Dlibs( wxCommandEvent& aEvent ); + void OnChangeSearch( wxCommandEvent& aEvent ); + void OnWizardFinished( wxWizardEvent& aEvent ); + void OnBrowseButtonClick( wxCommandEvent& aEvent ); + void OnCheckSaveCopy( wxCommandEvent& aEvent ); + void OnDefault3DPathButtonClick( wxCommandEvent& event ); + void OnGridLibReviewSize( wxSizeEvent& event ); + +protected: + // Initialization of wizard pages + void setupDialogOrder(); + void setupGithubList(); // Prepare the second page + // (list of available .3dshapes libraries on github) + void setupReview(); // Prepare the last page + + ///> Sets the target directory for libraries downloaded from Github + void setDownloadDir( const wxString& aDir ) + { + m_downloadDir->SetValue( aDir ); + } + + ///> Gets the current target for downloaded libraries + inline wxString getDownloadDir() + { + return m_downloadDir->GetValue(); + } + + ///> Downloads the list of Github libraries + void getLibsListGithub( wxArrayString& aList ); + + ///> Saves a list of Github libraries locally. + bool downloadGithubLibsFromList( wxArrayString& aUrlList, wxString* aErrorMessage ); + + ///> Saves a Github library aLibURL locally in aLocalLibName. + bool downloadOneLib( const wxString& aLibURL, + const wxString& aLocalLibName, + wxProgressDialog * aIndicator, + wxString* aErrorMessage ); + + ///> Enables Github widgets depending on the selected options. + void updateGithubControls(); + + ///> Enables/disable 'Next' button + inline void enableNext( bool aEnable ) + { + wxWindow* nextBtn = FindWindowById( wxID_FORWARD ); + + if( nextBtn ) + nextBtn->Enable( aEnable ); + } + + // A callback function to filter 3D filenames + static bool filter3dshapesfiles( const wxString& aData ) + { + return aData.Contains( wxT( ".wrl" ) ) || aData.Contains( wxT( ".wings" ) ); + } + + // A callback function to filter 3D folders names + static bool filter3dshapeslibraries( const wxString& aData ) + { + return aData.Contains( wxT( ".3dshapes" ) ); + } + + ///> Cache for the downloaded Github library list + wxArrayString m_githubLibs; + + ///> Libraries names selected in the wizard + wxArrayString m_libraries; + + // Aliases for wizard pages to make code more readable + wxWizardPageSimple* m_welcomeDlg; + wxWizardPageSimple* m_githubListDlg; + wxWizardPageSimple* m_reviewDlg; + + // path to the most recently used download directory from Github. + wxString m_lastGithubDownloadDirectory; +}; diff --git a/pcbnew/dialogs/wizard_3DShape_Libs_downloader_base.cpp b/pcbnew/dialogs/wizard_3DShape_Libs_downloader_base.cpp new file mode 100644 index 0000000000..efe08dc9ec --- /dev/null +++ b/pcbnew/dialogs/wizard_3DShape_Libs_downloader_base.cpp @@ -0,0 +1,235 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Jun 17 2015) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#include "wizard_3DShape_Libs_downloader_base.h" + +/////////////////////////////////////////////////////////////////////////// + +WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxBitmap& bitmap, const wxPoint& pos, long style ) +{ + this->Create( parent, id, title, bitmap, pos, style ); + this->SetSizeHints( wxSize( -1,-1 ), wxDefaultSize ); + + wxWizardPageSimple* m_wizPage1 = new wxWizardPageSimple( this, NULL, NULL, wxArtProvider::GetBitmap( wxART_HELP_BOOK, wxART_FRAME_ICON ) ); + m_pages.Add( m_wizPage1 ); + + m_wizPage1->SetMinSize( wxSize( 720,480 ) ); + + wxBoxSizer* bSizer1; + bSizer1 = new wxBoxSizer( wxVERTICAL ); + + m_staticText1 = new wxStaticText( m_wizPage1, wxID_ANY, _("Welcome to the 3D shape Libraries downloader Wizard!"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText1->Wrap( -1 ); + bSizer1->Add( m_staticText1, 0, wxALL|wxEXPAND, 5 ); + + + bSizer1->Add( 0, 20, 0, 0, 5 ); + + wxBoxSizer* bSizer19; + bSizer19 = new wxBoxSizer( wxVERTICAL ); + + m_staticText8 = new wxStaticText( m_wizPage1, wxID_ANY, _("Please select the URL for the 3D libraries to download"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText8->Wrap( -1 ); + bSizer19->Add( m_staticText8, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_textCtrlGithubURL = new wxTextCtrl( m_wizPage1, wxID_ANY, _("http://github.com/KiCad"), wxDefaultPosition, wxDefaultSize, 0 ); + m_textCtrlGithubURL->SetMinSize( wxSize( 300,-1 ) ); + + bSizer19->Add( m_textCtrlGithubURL, 0, wxALL|wxEXPAND, 5 ); + + + bSizer19->Add( 0, 10, 0, 0, 5 ); + + wxBoxSizer* bSizerLocalFolder; + bSizerLocalFolder = new wxBoxSizer( wxHORIZONTAL ); + + wxBoxSizer* bSizerDinname; + bSizerDinname = new wxBoxSizer( wxVERTICAL ); + + m_staticText9 = new wxStaticText( m_wizPage1, wxID_ANY, _("3D shape local folder:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText9->Wrap( -1 ); + bSizerDinname->Add( m_staticText9, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_downloadDir = new wxTextCtrl( m_wizPage1, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + bSizerDinname->Add( m_downloadDir, 0, wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND, 5 ); + + + bSizerLocalFolder->Add( bSizerDinname, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL, 5 ); + + wxBoxSizer* bSizerButts; + bSizerButts = new wxBoxSizer( wxVERTICAL ); + + m_btnBrowse = new wxButton( m_wizPage1, wxID_ANY, _("Browse"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizerButts->Add( m_btnBrowse, 0, wxEXPAND|wxALL, 5 ); + + m_buttonDefault3DPath = new wxButton( m_wizPage1, wxID_ANY, _("Default 3D Path"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizerButts->Add( m_buttonDefault3DPath, 0, wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + + bSizerLocalFolder->Add( bSizerButts, 0, wxEXPAND, 5 ); + + + bSizer19->Add( bSizerLocalFolder, 0, wxEXPAND, 5 ); + + + bSizer19->Add( 0, 10, 0, 0, 5 ); + + m_invalidDir = new wxStaticText( m_wizPage1, wxID_ANY, _("It is not possible to write in the selected directory.\nPlease choose another one."), wxDefaultPosition, wxDefaultSize, 0 ); + m_invalidDir->Wrap( -1 ); + m_invalidDir->SetForegroundColour( wxColour( 255, 0, 0 ) ); + + bSizer19->Add( m_invalidDir, 0, wxALL|wxALIGN_CENTER_HORIZONTAL, 5 ); + + + bSizer1->Add( bSizer19, 1, wxEXPAND, 5 ); + + wxBoxSizer* bSizerOfficialRepo; + bSizerOfficialRepo = new wxBoxSizer( wxHORIZONTAL ); + + m_bitmapRepo = new wxStaticBitmap( m_wizPage1, wxID_ANY, wxArtProvider::GetBitmap( wxART_INFORMATION, wxART_OTHER ), wxDefaultPosition, wxDefaultSize, 0 ); + bSizerOfficialRepo->Add( m_bitmapRepo, 0, wxALL, 5 ); + + + bSizerOfficialRepo->Add( 0, 0, 0, wxRIGHT|wxLEFT, 10 ); + + m_hyperlinkGithubKicad = new wxHyperlinkCtrl( m_wizPage1, wxID_ANY, _("Visit our official Kicad repository on Github and get more libraries"), wxT("https://github.com/KiCad"), wxDefaultPosition, wxDefaultSize, wxHL_DEFAULT_STYLE ); + bSizerOfficialRepo->Add( m_hyperlinkGithubKicad, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); + + + bSizer1->Add( bSizerOfficialRepo, 0, wxEXPAND, 5 ); + + + m_wizPage1->SetSizer( bSizer1 ); + m_wizPage1->Layout(); + wxWizardPageSimple* m_wizPage2_Github = new wxWizardPageSimple( this, NULL, NULL, wxArtProvider::GetBitmap( wxART_HELP_BOOK, wxART_FRAME_ICON ) ); + m_pages.Add( m_wizPage2_Github ); + + wxBoxSizer* bSizer111; + bSizer111 = new wxBoxSizer( wxVERTICAL ); + + m_staticText112 = new wxStaticText( m_wizPage2_Github, wxID_ANY, _("Select Github libraries to add:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText112->Wrap( -1 ); + bSizer111->Add( m_staticText112, 0, wxALL|wxEXPAND, 5 ); + + wxArrayString m_checkList3DlibnamesChoices; + m_checkList3Dlibnames = new wxCheckListBox( m_wizPage2_Github, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_checkList3DlibnamesChoices, wxLB_MULTIPLE|wxLB_NEEDED_SB ); + bSizer111->Add( m_checkList3Dlibnames, 1, wxALL|wxEXPAND, 5 ); + + wxBoxSizer* bSizer7; + bSizer7 = new wxBoxSizer( wxHORIZONTAL ); + + m_btnSelectAll3Dlibs = new wxButton( m_wizPage2_Github, wxID_ANY, _("Select all"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer7->Add( m_btnSelectAll3Dlibs, 1, wxALL, 5 ); + + m_btnUnselectAll3Dlibs = new wxButton( m_wizPage2_Github, wxID_ANY, _("Unselect all"), wxDefaultPosition, wxDefaultSize, 0 ); + bSizer7->Add( m_btnUnselectAll3Dlibs, 1, wxALL, 5 ); + + + bSizer7->Add( 0, 0, 1, wxEXPAND, 5 ); + + m_searchCtrl3Dlibs = new wxSearchCtrl( m_wizPage2_Github, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + #ifndef __WXMAC__ + m_searchCtrl3Dlibs->ShowSearchButton( true ); + #endif + m_searchCtrl3Dlibs->ShowCancelButton( false ); + bSizer7->Add( m_searchCtrl3Dlibs, 2, wxALL, 5 ); + + + bSizer111->Add( bSizer7, 0, wxEXPAND, 5 ); + + + m_wizPage2_Github->SetSizer( bSizer111 ); + m_wizPage2_Github->Layout(); + bSizer111->Fit( m_wizPage2_Github ); + wxWizardPageSimple* m_wizPage3_SelectTarget = new wxWizardPageSimple( this, NULL, NULL, wxArtProvider::GetBitmap( wxART_HELP_BOOK, wxART_FRAME_ICON ) ); + m_pages.Add( m_wizPage3_SelectTarget ); + + wxBoxSizer* bSizer12; + bSizer12 = new wxBoxSizer( wxVERTICAL ); + + m_staticTextlocalfolder = new wxStaticText( m_wizPage3_SelectTarget, wxID_ANY, _("Local library folder:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticTextlocalfolder->Wrap( -1 ); + bSizer12->Add( m_staticTextlocalfolder, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_LocalFolderInfo = new wxStaticText( m_wizPage3_SelectTarget, wxID_ANY, _("dummy"), wxDefaultPosition, wxDefaultSize, 0 ); + m_LocalFolderInfo->Wrap( -1 ); + bSizer12->Add( m_LocalFolderInfo, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 ); + + m_staticText12 = new wxStaticText( m_wizPage3_SelectTarget, wxID_ANY, _("3D shape libraries to be downloaded:"), wxDefaultPosition, wxDefaultSize, 0 ); + m_staticText12->Wrap( -1 ); + bSizer12->Add( m_staticText12, 0, wxTOP|wxRIGHT|wxLEFT, 5 ); + + m_gridLibReview = new wxGrid( m_wizPage3_SelectTarget, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 ); + + // Grid + m_gridLibReview->CreateGrid( 1, 2 ); + m_gridLibReview->EnableEditing( false ); + m_gridLibReview->EnableGridLines( true ); + m_gridLibReview->EnableDragGridSize( false ); + m_gridLibReview->SetMargins( 5, 0 ); + + // Columns + m_gridLibReview->EnableDragColMove( false ); + m_gridLibReview->EnableDragColSize( true ); + m_gridLibReview->SetColLabelSize( 30 ); + m_gridLibReview->SetColLabelValue( 0, _("Status") ); + m_gridLibReview->SetColLabelValue( 1, _("Libraries") ); + m_gridLibReview->SetColLabelValue( 2, wxEmptyString ); + m_gridLibReview->SetColLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE ); + + // Rows + m_gridLibReview->AutoSizeRows(); + m_gridLibReview->EnableDragRowSize( true ); + m_gridLibReview->SetRowLabelSize( 30 ); + m_gridLibReview->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE ); + + // Label Appearance + + // Cell Defaults + m_gridLibReview->SetDefaultCellAlignment( wxALIGN_LEFT, wxALIGN_TOP ); + bSizer12->Add( m_gridLibReview, 1, wxALL|wxEXPAND, 5 ); + + + m_wizPage3_SelectTarget->SetSizer( bSizer12 ); + m_wizPage3_SelectTarget->Layout(); + bSizer12->Fit( m_wizPage3_SelectTarget ); + + this->Centre( wxBOTH ); + + for ( unsigned int i = 1; i < m_pages.GetCount(); i++ ) + { + m_pages.Item( i )->SetPrev( m_pages.Item( i - 1 ) ); + m_pages.Item( i - 1 )->SetNext( m_pages.Item( i ) ); + } + + // Connect Events + this->Connect( wxID_ANY, wxEVT_WIZARD_FINISHED, wxWizardEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnWizardFinished ) ); + this->Connect( wxID_ANY, wxEVT_WIZARD_PAGE_CHANGED, wxWizardEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnPageChanged ) ); + this->Connect( wxID_ANY, wxEVT_WIZARD_PAGE_CHANGING, wxWizardEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnPageChanging ) ); + m_btnBrowse->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnBrowseButtonClick ), NULL, this ); + m_buttonDefault3DPath->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnDefault3DPathButtonClick ), NULL, this ); + m_btnSelectAll3Dlibs->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnSelectAll3Dlibs ), NULL, this ); + m_btnUnselectAll3Dlibs->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnUnselectAll3Dlibs ), NULL, this ); + m_searchCtrl3Dlibs->Connect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnChangeSearch ), NULL, this ); + m_gridLibReview->Connect( wxEVT_SIZE, wxSizeEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnGridLibReviewSize ), NULL, this ); +} + +WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::~WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE() +{ + // Disconnect Events + this->Disconnect( wxID_ANY, wxEVT_WIZARD_FINISHED, wxWizardEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnWizardFinished ) ); + this->Disconnect( wxID_ANY, wxEVT_WIZARD_PAGE_CHANGED, wxWizardEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnPageChanged ) ); + this->Disconnect( wxID_ANY, wxEVT_WIZARD_PAGE_CHANGING, wxWizardEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnPageChanging ) ); + m_btnBrowse->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnBrowseButtonClick ), NULL, this ); + m_buttonDefault3DPath->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnDefault3DPathButtonClick ), NULL, this ); + m_btnSelectAll3Dlibs->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnSelectAll3Dlibs ), NULL, this ); + m_btnUnselectAll3Dlibs->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnUnselectAll3Dlibs ), NULL, this ); + m_searchCtrl3Dlibs->Disconnect( wxEVT_COMMAND_TEXT_UPDATED, wxCommandEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnChangeSearch ), NULL, this ); + m_gridLibReview->Disconnect( wxEVT_SIZE, wxSizeEventHandler( WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE::OnGridLibReviewSize ), NULL, this ); + + m_pages.Clear(); +} diff --git a/pcbnew/dialogs/wizard_3DShape_Libs_downloader_base.fbp b/pcbnew/dialogs/wizard_3DShape_Libs_downloader_base.fbp new file mode 100644 index 0000000000..59273ad644 --- /dev/null +++ b/pcbnew/dialogs/wizard_3DShape_Libs_downloader_base.fbp @@ -0,0 +1,2050 @@ + + + + + + C++ + 1 + source_name + 0 + 0 + res + UTF-8 + connect + wizard_3DShape_Libs_downloader_base + 1000 + none + 1 + Wizard_3DShapes_Libs_Downloader + + . + + 1 + 1 + 1 + 1 + UI + 0 + 0 + + + Load From Art Provider; wxART_HELP_BOOK; wxART_FRAME_ICON + wxBOTH + + 1 + 1 + impl_virtual + + + + 0 + wxID_ANY + + -1,-1 + WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE + + 591,405 + wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxRESIZE_BORDER + ; + Add 3D Shape Libraries Wizard + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnWizardFinished + + OnPageChanged + OnPageChanging + + + Load From Art Provider; wxART_HELP_BOOK; wxART_FRAME_ICON + + 1 + 1 + + + 0 + wxID_ANY + + 720,480 + m_wizPage1 + protected + + 720,480 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer1 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Welcome to the 3D shape Libraries downloader Wizard! + + 0 + + + 0 + + 1 + m_staticText1 + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + + 0 + + 20 + protected + 0 + + + + 5 + wxEXPAND + 1 + + + bSizer19 + wxVERTICAL + none + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Please select the URL for the 3D libraries to download + + 0 + + + 0 + + 1 + m_staticText8 + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + 300,-1 + 1 + m_textCtrlGithubURL + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + http://github.com/KiCad + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + + 0 + + 10 + protected + 0 + + + + 5 + wxEXPAND + 0 + + + bSizerLocalFolder + wxHORIZONTAL + none + + 5 + wxEXPAND|wxALIGN_CENTER_VERTICAL + 1 + + + bSizerDinname + wxVERTICAL + none + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + 3D shape local folder: + + 0 + + + 0 + + 1 + m_staticText9 + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxALIGN_CENTER_VERTICAL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + + 0 + + 1 + m_downloadDir + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bSizerButts + wxVERTICAL + none + + 5 + wxEXPAND|wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Browse + + 0 + + + 0 + + 1 + m_btnBrowse + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnBrowseButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND|wxBOTTOM|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Default 3D Path + + 0 + + + 0 + + 1 + m_buttonDefault3DPath + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnDefault3DPathButtonClick + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + + 0 + + 10 + protected + 0 + + + + 5 + wxALL|wxALIGN_CENTER_HORIZONTAL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + 255,0,0 + 1 + + 0 + 0 + wxID_ANY + It is not possible to write in the selected directory. Please choose another one. + + 0 + + + 0 + + 1 + m_invalidDir + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bSizerOfficialRepo + wxHORIZONTAL + none + + 5 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + Load From Art Provider; wxART_INFORMATION; wxART_OTHER + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_bitmapRepo + 1 + + + protected + 1 + + Resizable + 1 + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 10 + wxRIGHT|wxLEFT + 0 + + 0 + protected + 0 + + + + 5 + wxALIGN_CENTER_VERTICAL|wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + + wxID_ANY + Visit our official Kicad repository on Github and get more libraries + + 0 + + + 0 + + 1 + m_hyperlinkGithubKicad + + 1 + + + protected + 1 + + Resizable + 1 + + wxHL_DEFAULT_STYLE + + 0 + + https://github.com/KiCad + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Load From Art Provider; wxART_HELP_BOOK; wxART_FRAME_ICON + + 1 + 1 + + + 0 + wxID_ANY + + + m_wizPage2_Github + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer111 + wxVERTICAL + none + + 5 + wxALL|wxEXPAND + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Select Github libraries to add: + + 0 + + + 0 + + 1 + m_staticText112 + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_checkList3Dlibnames + 1 + + + protected + 1 + + Resizable + 1 + + wxLB_MULTIPLE|wxLB_NEEDED_SB + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 0 + + + bSizer7 + wxHORIZONTAL + none + + 5 + wxALL + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Select all + + 0 + + + 0 + + 1 + m_btnSelectAll3Dlibs + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnSelectAll3Dlibs + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL + 1 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Unselect all + + 0 + + + 0 + + 1 + m_btnUnselectAll3Dlibs + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + OnUnselectAll3Dlibs + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxEXPAND + 1 + + 0 + protected + 0 + + + + 5 + wxALL + 2 + + 1 + 1 + 1 + 1 + + + + + + + 0 + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + + 0 + + + 0 + + 1 + m_searchCtrl3Dlibs + 1 + + + protected + 1 + + Resizable + 1 + 1 + + + + 0 + + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnChangeSearch + + + + + + + + + + + Load From Art Provider; wxART_HELP_BOOK; wxART_FRAME_ICON + + 1 + 1 + + + 0 + wxID_ANY + + + m_wizPage3_SelectTarget + protected + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + bSizer12 + wxVERTICAL + none + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Local library folder: + + 0 + + + 0 + + 1 + m_staticTextlocalfolder + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxBOTTOM|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + dummy + + 0 + + + 0 + + 1 + m_LocalFolderInfo + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxTOP|wxRIGHT|wxLEFT + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + 3D shape libraries to be downloaded: + + 0 + + + 0 + + 1 + m_staticText12 + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + + + + + -1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 5 + wxALL|wxEXPAND + 1 + + 1 + 1 + 1 + 1 + + + + + 0 + 1 + + + + 1 + + + wxALIGN_LEFT + + wxALIGN_TOP + 0 + 1 + wxALIGN_CENTRE + 30 + "Status" "Libraries" "" + wxALIGN_CENTRE + 2 + + + 1 + 0 + Dock + 0 + Left + 0 + 1 + 0 + 1 + 0 + 1 + + 1 + + + 1 + 0 + 0 + wxID_ANY + + + + 0 + 5 + + 0 + + + 0 + + 1 + m_gridLibReview + 1 + + + protected + 1 + + Resizable + wxALIGN_CENTRE + 30 + + wxALIGN_CENTRE + + 1 + 1 + + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OnGridLibReviewSize + + + + + + + + diff --git a/pcbnew/dialogs/wizard_3DShape_Libs_downloader_base.h b/pcbnew/dialogs/wizard_3DShape_Libs_downloader_base.h new file mode 100644 index 0000000000..eff150d291 --- /dev/null +++ b/pcbnew/dialogs/wizard_3DShape_Libs_downloader_base.h @@ -0,0 +1,86 @@ +/////////////////////////////////////////////////////////////////////////// +// C++ code generated with wxFormBuilder (version Jun 17 2015) +// http://www.wxformbuilder.org/ +// +// PLEASE DO "NOT" EDIT THIS FILE! +/////////////////////////////////////////////////////////////////////////// + +#ifndef __WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE_H__ +#define __WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +WX_DEFINE_ARRAY_PTR( wxWizardPageSimple*, WizardPages ); + +/////////////////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +/// Class WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE +/////////////////////////////////////////////////////////////////////////////// +class WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE : public wxWizard +{ + private: + + protected: + wxStaticText* m_staticText1; + wxStaticText* m_staticText8; + wxTextCtrl* m_textCtrlGithubURL; + wxStaticText* m_staticText9; + wxTextCtrl* m_downloadDir; + wxButton* m_btnBrowse; + wxButton* m_buttonDefault3DPath; + wxStaticText* m_invalidDir; + wxStaticBitmap* m_bitmapRepo; + wxHyperlinkCtrl* m_hyperlinkGithubKicad; + wxStaticText* m_staticText112; + wxCheckListBox* m_checkList3Dlibnames; + wxButton* m_btnSelectAll3Dlibs; + wxButton* m_btnUnselectAll3Dlibs; + wxSearchCtrl* m_searchCtrl3Dlibs; + wxStaticText* m_staticTextlocalfolder; + wxStaticText* m_LocalFolderInfo; + wxStaticText* m_staticText12; + wxGrid* m_gridLibReview; + + // Virtual event handlers, overide them in your derived class + virtual void OnWizardFinished( wxWizardEvent& event ) { event.Skip(); } + virtual void OnPageChanged( wxWizardEvent& event ) { event.Skip(); } + virtual void OnPageChanging( wxWizardEvent& event ) { event.Skip(); } + virtual void OnBrowseButtonClick( wxCommandEvent& event ) { event.Skip(); } + virtual void OnDefault3DPathButtonClick( wxCommandEvent& event ) { event.Skip(); } + virtual void OnSelectAll3Dlibs( wxCommandEvent& event ) { event.Skip(); } + virtual void OnUnselectAll3Dlibs( wxCommandEvent& event ) { event.Skip(); } + virtual void OnChangeSearch( wxCommandEvent& event ) { event.Skip(); } + virtual void OnGridLibReviewSize( wxSizeEvent& event ) { event.Skip(); } + + + public: + + WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Add 3D Shape Libraries Wizard"), const wxBitmap& bitmap = wxArtProvider::GetBitmap( wxART_HELP_BOOK, wxART_FRAME_ICON ), const wxPoint& pos = wxDefaultPosition, long style = wxCAPTION|wxCLOSE_BOX|wxDEFAULT_DIALOG_STYLE|wxMAXIMIZE_BOX|wxRESIZE_BORDER ); + WizardPages m_pages; + ~WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE(); + +}; + +#endif //__WIZARD_3DSHAPE_LIBS_DOWNLOADER_BASE_H__ diff --git a/pcbnew/dialogs/wizard_add_fplib.cpp b/pcbnew/dialogs/wizard_add_fplib.cpp index 882c8f2b01..254cec3531 100644 --- a/pcbnew/dialogs/wizard_add_fplib.cpp +++ b/pcbnew/dialogs/wizard_add_fplib.cpp @@ -615,7 +615,7 @@ void WIZARD_FPLIB_TABLE::getLibsListGithub( wxArrayString& aList ) } GITHUB_GETLIBLIST getter( git_url ); - getter.GetLibraryList( aList ); + getter.GetFootprintLibraryList( aList ); wxEndBusyCursor(); } diff --git a/pcbnew/github/CMakeLists.txt b/pcbnew/github/CMakeLists.txt index 8231c30e7e..d630c69a8d 100644 --- a/pcbnew/github/CMakeLists.txt +++ b/pcbnew/github/CMakeLists.txt @@ -51,7 +51,7 @@ set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-sign-compare -Wno-reorder -Wno-unused-variable -Wno-unused-function -Wno-strict-aliasing" ) set( GITHUB_PLUGIN_SRCS - github_plugin.cpp github_getliblist.cpp + github_plugin.cpp github_getliblist.cpp html_link_parser.cpp ) add_library( github_plugin STATIC ${GITHUB_PLUGIN_SRCS} ) diff --git a/pcbnew/github/github_getliblist.cpp b/pcbnew/github/github_getliblist.cpp index 3bec9479c6..7ef26553b2 100644 --- a/pcbnew/github/github_getliblist.cpp +++ b/pcbnew/github/github_getliblist.cpp @@ -75,19 +75,55 @@ #include #include #include +#include GITHUB_GETLIBLIST::GITHUB_GETLIBLIST( const wxString& aRepoURL ) { m_repoURL = aRepoURL; + m_libs_ext = wxT( ".pretty" ); + strcpy( m_option_string, "application/json" ); } -bool GITHUB_GETLIBLIST::GetLibraryList( wxArrayString& aList ) +bool GITHUB_GETLIBLIST::Get3DshapesLibsList( wxArrayString* aList, + bool (*aFilter)( const wxString& aData ) ) +{ + std::string fullURLCommand; + strcpy( m_option_string, "text/html" ); + + wxString repoURL = m_repoURL; + + wxString errorMsg; + + fullURLCommand = repoURL.utf8_str(); + bool success = remote_get_json( &fullURLCommand, &errorMsg ); + + if( !success ) + { + wxMessageBox( errorMsg ); + return false; + } + + if( aFilter && aList ) + { + //Convert m_image (std::string) to a wxString for HTML_LINK_PARSER + wxString buffer( GetBuffer() ); + + HTML_LINK_PARSER html_parser( buffer, *aList ); + html_parser.ParseLinks( aFilter ); + } + + return true; +} + + +bool GITHUB_GETLIBLIST::GetFootprintLibraryList( wxArrayString& aList ) { std::string fullURLCommand; int page = 1; int itemCountMax = 99; // Do not use a valu > 100, it does not work + strcpy( m_option_string, "application/json" ); // Github max items returned is 100 per page @@ -101,12 +137,13 @@ bool GITHUB_GETLIBLIST::GetLibraryList( wxArrayString& aList ) // The URL lib names are relative to the server name. // so add the server name to them. wxURI repo( m_repoURL ); - wxString urlPrefix = wxT( "https://" ) + repo.GetServer() + wxT( "/" ); + wxString urlPrefix = repo.GetScheme() + wxT( "://" ) + repo.GetServer() + wxT( "/" ); wxString errorMsg; const char sep = ','; // Separator fields, in json returned file wxString tmp; int items_count_per_page = 0; + std::string& json_image = GetBuffer(); while( 1 ) { @@ -118,9 +155,10 @@ bool GITHUB_GETLIBLIST::GetLibraryList( wxArrayString& aList ) return false; } - for( unsigned ii = 0; ii < m_json_image.size(); ii++ ) + + for( unsigned ii = 0; ii < json_image.size(); ii++ ) { - if( m_json_image[ii] == sep || ii == m_json_image.size() - 1 ) + if( json_image[ii] == sep || ii == json_image.size() - 1 ) { if( tmp.StartsWith( wxT( "\"full_name\"" ) ) ) { @@ -129,7 +167,7 @@ bool GITHUB_GETLIBLIST::GetLibraryList( wxArrayString& aList ) if( tmp[tmp.Length() - 1] == QUOTE ) tmp.RemoveLast(); - if( tmp.EndsWith( wxT( ".pretty" ) ) ) + if( tmp.EndsWith( m_libs_ext ) ) { aList.Add( tmp.AfterLast( ':' ) ); int idx = aList.GetCount() - 1; @@ -146,7 +184,7 @@ bool GITHUB_GETLIBLIST::GetLibraryList( wxArrayString& aList ) tmp.Clear(); } else - tmp << m_json_image[ii]; + tmp << json_image[ii]; } if( items_count_per_page >= itemCountMax ) @@ -154,7 +192,7 @@ bool GITHUB_GETLIBLIST::GetLibraryList( wxArrayString& aList ) page++; repoURL2listURL( m_repoURL, &fullURLCommand, itemCountMax, page ); items_count_per_page = 0; - m_json_image.clear(); + ClearBuffer(); } else break; diff --git a/pcbnew/github/github_getliblist.h b/pcbnew/github/github_getliblist.h index 17daa53396..6fd059800f 100644 --- a/pcbnew/github/github_getliblist.h +++ b/pcbnew/github/github_getliblist.h @@ -27,19 +27,58 @@ /** - * Class GITHUB_GETLIBLIST - * implements a portion of pcbnew's PLUGIN interface to provide read only access - * to a github repo to extract pretty footprints library list, in json format. + * Class GITHUB_GETLIBLIST + * implements a portion of pcbnew's PLUGIN interface to provide read only access + * to a github repo to extract pretty footprints library list, in json format, + * or extract 3D shapes libraries list (.3dshapes folders) and download the 3d shapes files * - * this plugin simply reads in a zip file of the repo and unzips it from RAM as - * needed. Therefore this "Github" plugin is read only for accessing remote - * at https://api.github.com/orgs/KiCad/repos + * To extract pretty footprints library list, this plugin simply reads in + * a zip file of the repo and unzips it from RAM as needed. + * Therefore this "Github" plugin is read only for accessing remote + * at https://api.github.com/orgs/KiCad/repos + * + * To extract 3D shapes libraries list (.3dshapes folders) we cannot use api.github.com + * to read this list, becuse it is in a subdirectory of https://github.com/KiCad. + * The corresponding html page of the server is read, and URLs of all .3dshapes folders + * are extracted. + * files are then read from https://raw.githubusercontent.com/, but not zipped + * because they are not accessible in zipped form. */ class GITHUB_GETLIBLIST { public: // --------------------------------------------------------------- - bool GetLibraryList( wxArrayString& aList ); + + /** + * Fills aList by the name of footprint libraries found on the github repo + */ + bool GetFootprintLibraryList( wxArrayString& aList ); + + /** + * Fills aList by the URL of libraries found on the github repo + * @param aList = a reference to a wxArrayString to fill with names + * @param aFilter( const wxString& aData ) = a callback funtion to + * to filter URLs to put in aList. + * If NULL, no URL will be stored in aList + */ + bool Get3DshapesLibsList( wxArrayString* aList, + bool (*aFilter)( const wxString& aData ) ); + + /** + * @return the buffer which stores all the downloaded raw data + */ + std::string& GetBuffer() { return m_image; } + + /** + * Clear the buffer which stores all the downloaded raw data + */ + void ClearBuffer() { m_image.clear(); } + + /** + * The library names are expecting ending by .pretty + * SetLibraryExt set the extension to aExt + */ + void SetLibraryExt( const wxString& aExt ) { m_libs_ext = aExt; } // -------------------------------------------------------------- @@ -55,7 +94,7 @@ protected: * * @param aRepoURL points to the base of the repo. * @param aFullURLCommand is URL the full URL command (URL+options). - * @param aItemCountMax is the max item count in apage, + * @param aItemCountMax is the max item count in a page, * and is 100 for github repo. * @param aPage is the page number, if there are more than one page in repo. * @return bool - true if @a aRepoULR was parseable, else false @@ -75,8 +114,10 @@ protected: bool remote_get_json( std::string* aFullURLCommand, wxString* aMsgError ); wxString m_github_path; ///< Something like https://api.github.com/orgs/KiCad - std::string m_json_image; ///< image of the text file in its entirety. - wxString m_repoURL; // the URL of the Github repo + std::string m_image; ///< image of the downloaded data in its entirety. + wxString m_repoURL; ///< the URL of the Github repo + wxString m_libs_ext; ///< the extension of the name of libraries (default = .pretty) + char m_option_string[64]; ///< option for transfert type, like "application/json" }; diff --git a/pcbnew/github/github_plugin.cpp b/pcbnew/github/github_plugin.cpp index 695365ccaa..c3c6b91d7a 100644 --- a/pcbnew/github/github_plugin.cpp +++ b/pcbnew/github/github_plugin.cpp @@ -592,8 +592,9 @@ bool GITHUB_GETLIBLIST::remote_get_json( std::string* aFullURLCommand, wxString* avhttp::http_stream h( io ); avhttp::request_opts options; - options.insert( "Accept", "application/json" ); - options.insert( "User-Agent", "http://kicad-pcb.org" ); // THAT WOULD BE ME. + + options.insert( "Accept", m_option_string ); + options.insert( "User-Agent", "http://kicad-pcb.org" ); // THAT WOULD BE ME. h.request_options( options ); try @@ -603,8 +604,8 @@ bool GITHUB_GETLIBLIST::remote_get_json( std::string* aFullURLCommand, wxString* h.open( *aFullURLCommand ); // only one file, therefore do it synchronously. os << &h; - // Keep json text file image in RAM. - m_json_image = os.str(); + // Keep downloaded text file image in RAM. + m_image = os.str(); // 4 lines, using SSL, top that. } @@ -613,7 +614,7 @@ bool GITHUB_GETLIBLIST::remote_get_json( std::string* aFullURLCommand, wxString* // https "GET" has faild, report this to API caller. static const char errorcmd[] = "https GET command failed"; // Do not translate this message - UTF8 fmt( _( "%s\nCannot get/download json data from: '%s'\nReason: '%s'" ) ); + UTF8 fmt( _( "%s\nCannot get/download data from: '%s'\nReason: '%s'" ) ); std::string msg = StrPrintf( fmt.c_str(), errorcmd, @@ -625,7 +626,7 @@ bool GITHUB_GETLIBLIST::remote_get_json( std::string* aFullURLCommand, wxString* if( aMsgError ) { - *aMsgError = msg; + *aMsgError = FROM_UTF8( msg.c_str() ); return false; } } diff --git a/pcbnew/github/html_link_parser.cpp b/pcbnew/github/html_link_parser.cpp new file mode 100644 index 0000000000..5d6b751d87 --- /dev/null +++ b/pcbnew/github/html_link_parser.cpp @@ -0,0 +1,68 @@ +/** + * @file html_link_parse.cpp + */ + +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* + * wxWidgets gives very few info about wxwebkit. For more info and more comments: + * see https://forums.wxwidgets.org/viewtopic.php?f=1&t=1119# + */ + +#include + +bool LINK_TAGHANDLER::HandleTag(const wxHtmlTag& tag) +{ + if( tag.HasParam( wxT("HREF") ) ) + { + wxString href( tag.GetParam( wxT("HREF") ) ); + // Add the first parameter (the link) + m_Parser->AddString( href ); + // Parse other params, but do nothing, because the AddText() callback + // do nothing + ParseInner(tag); + return true; + } + else + return false; +} + +HTML_LINK_PARSER::HTML_LINK_PARSER( const wxString& aSrc, wxArrayString& aUrls ) + : m_src( aSrc ), stringUrls( aUrls ) +{ + AddTagHandler( new LINK_TAGHANDLER(this) ); +} + + +void HTML_LINK_PARSER::AddString( const wxString& aText ) +{ + wxString text = aText; + text.Trim( true ); + text.Trim( false ); + + if( ! m_filter || m_filter( text ) ) + { + stringUrls.Add( text ); + } +} diff --git a/pcbnew/github/html_link_parser.h b/pcbnew/github/html_link_parser.h new file mode 100644 index 0000000000..c18c27e743 --- /dev/null +++ b/pcbnew/github/html_link_parser.h @@ -0,0 +1,109 @@ +/** + * @file html_link_parse.h + */ + +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 1992-2014 KiCad Developers, see AUTHORS.txt for contributors. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, you may find one here: + * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html + * or you may search the http://www.gnu.org website for the version 2 license, + * or you may write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* + * wxWidgets gives very few info about wxwebkit. For more info and more comments: + * see https://forums.wxwidgets.org/viewtopic.php?f=1&t=1119# + */ + +#ifndef HTML_LINK_PARSE_H +#define HTML_LINK_PARSE_H + + +#include +#include + +class HTML_LINK_PARSER ; + +/** + * a Tag parser, to extract tagged data in html text. + * this tag handler extract a url link, givent by tag "A" + * like: + * " Valves.pretty" + * the tag is "a" + * and the link is the parameter given by "href" + */ +class LINK_TAGHANDLER : public wxHtmlTagHandler +{ + HTML_LINK_PARSER* m_Parser; + +public: + LINK_TAGHANDLER() : m_Parser( NULL ) + { + } + + LINK_TAGHANDLER( HTML_LINK_PARSER* aParser ) : m_Parser( aParser ) + { + } + + wxString GetSupportedTags() + { + return "A"; + } + + bool HandleTag(const wxHtmlTag& tag); +}; + +/** + * The engine to parse a html text and extract useful data + * Here, the useful data are url links + */ +class HTML_LINK_PARSER : public wxHtmlParser +{ + const wxString& m_src; // the html text to parse + wxArrayString& stringUrls; // the strings extracted from html text + bool (*m_filter)( const wxString& aData ); // a callback function to filter strings + +public: + + HTML_LINK_PARSER( const wxString& aSrc, wxArrayString& aUrls ); + + /** + * Parse the html text and store links in stringUrls + * Stored links can be filtered if aFilter is non NULL + * @param aFilter a filtering function ( bool aFilter( const wxString& aData ) ) + * which return true if the text aData must be stored. + */ + void ParseLinks( bool (*aFilter)( const wxString& aData ) ) + { + m_filter = aFilter; + Parse(m_src); + } + + // virtual pure from wxHtmlParser, do nothing here, but needed. + void AddText( const wxString& aText ){} + + // Our "AddText" used to store selected text (the url link) + void AddString( const wxString& aText ); + + wxObject* GetProduct() + { + return NULL; + } +}; + +#endif // ifndef HTML_LINK_PARSE_H diff --git a/pcbnew/invoke_pcb_dialog.h b/pcbnew/invoke_pcb_dialog.h index 549b9c5716..aa5ad14e6b 100644 --- a/pcbnew/invoke_pcb_dialog.h +++ b/pcbnew/invoke_pcb_dialog.h @@ -90,6 +90,16 @@ int InvokePcbLibTableEditor( wxTopLevelWindow* aCaller, FP_LIB_TABLE* aGlobal, F */ int InvokeFootprintWizard( wxTopLevelWindow* aParent, FP_LIB_TABLE* aGlobal, FP_LIB_TABLE* aProject ); +/** + * Function Invoke3DShapeLibsDownloaderWizard + * Runs the downloader wizard for easy 3D shape libraries download from + * the official Kicad Github repository of *.3Dshape libraries. + * + * @param aCaller is the wxTopLevelWindow which is invoking the dialog. + */ +void Invoke3DShapeLibsDownloaderWizard( wxTopLevelWindow* aParent ); + + /** * Function InvokePluginOptionsEditor * calls DIALOG_FP_PLUGIN_OPTIONS dialog so that plugin options set can be edited. diff --git a/pcbnew/menubar_pcbframe.cpp b/pcbnew/menubar_pcbframe.cpp index 9527d6d17f..0fc493cdb3 100644 --- a/pcbnew/menubar_pcbframe.cpp +++ b/pcbnew/menubar_pcbframe.cpp @@ -494,6 +494,13 @@ void PCB_EDIT_FRAME::ReCreateMenuBar() _( "Edit path configuration environment variables" ), KiBitmap( editor_xpm ) ); +#ifdef BUILD_GITHUB_PLUGIN + AddMenuItem( configmenu, ID_PCB_3DSHAPELIB_WIZARD, + _( "&3D Shapes Libraries Downloader" ), + _( "Download from Github the 3D shape libraries with wizard" ), + KiBitmap( wizard_add_fplib_small_xpm ) ); +#endif + // Colors and Visibility are also handled by the layers manager toolbar AddMenuItem( configmenu, ID_MENU_PCB_SHOW_HIDE_LAYERS_MANAGER_DIALOG, m_show_layer_manager_tools ? diff --git a/pcbnew/pcbframe.cpp b/pcbnew/pcbframe.cpp index 940a5192d7..50755b0536 100644 --- a/pcbnew/pcbframe.cpp +++ b/pcbnew/pcbframe.cpp @@ -136,6 +136,7 @@ BEGIN_EVENT_TABLE( PCB_EDIT_FRAME, PCB_BASE_FRAME ) EVT_MENU( ID_PCB_DRAWINGS_WIDTHS_SETUP, PCB_EDIT_FRAME::OnConfigurePcbOptions ) EVT_MENU( ID_PCB_LIB_TABLE_EDIT, PCB_EDIT_FRAME::Process_Config ) EVT_MENU( ID_PCB_LIB_WIZARD, PCB_EDIT_FRAME::Process_Config ) + EVT_MENU( ID_PCB_3DSHAPELIB_WIZARD, PCB_EDIT_FRAME::Process_Config ) EVT_MENU( ID_PREFERENCES_CONFIGURE_PATHS, PCB_EDIT_FRAME::OnConfigurePaths ) EVT_MENU( ID_CONFIG_SAVE, PCB_EDIT_FRAME::Process_Config ) EVT_MENU( ID_CONFIG_READ, PCB_EDIT_FRAME::Process_Config ) diff --git a/pcbnew/pcbnew_config.cpp b/pcbnew/pcbnew_config.cpp index 1419efdd9a..2937fae15f 100644 --- a/pcbnew/pcbnew_config.cpp +++ b/pcbnew/pcbnew_config.cpp @@ -174,6 +174,12 @@ void PCB_EDIT_FRAME::Process_Config( wxCommandEvent& event ) } break; + case ID_PCB_3DSHAPELIB_WIZARD: +#ifdef BUILD_GITHUB_PLUGIN + Invoke3DShapeLibsDownloaderWizard( this ); +#endif + break; + case ID_PCB_MASK_CLEARANCE: { DIALOG_PADS_MASK_CLEARANCE dlg( this ); diff --git a/pcbnew/pcbnew_id.h b/pcbnew/pcbnew_id.h index c15d7969f2..6fd8bb6709 100644 --- a/pcbnew/pcbnew_id.h +++ b/pcbnew/pcbnew_id.h @@ -295,6 +295,7 @@ enum pcbnew_ids ID_PCB_USER_GRID_SETUP, ID_PCB_GEN_BOM_FILE_FROM_BOARD, ID_PCB_LIB_WIZARD, + ID_PCB_3DSHAPELIB_WIZARD, ID_PCB_LIB_TABLE_EDIT, ID_MENU_PCB_SHOW_DESIGN_RULES_DIALOG, ID_MENU_PCB_SHOW_HIDE_LAYERS_MANAGER_DIALOG,