diff options
Diffstat (limited to 'pcbnew/dialogs/wizard_add_fplib.cpp')
-rw-r--r-- | pcbnew/dialogs/wizard_add_fplib.cpp | 863 |
1 files changed, 863 insertions, 0 deletions
diff --git a/pcbnew/dialogs/wizard_add_fplib.cpp b/pcbnew/dialogs/wizard_add_fplib.cpp new file mode 100644 index 0000000..254cec3 --- /dev/null +++ b/pcbnew/dialogs/wizard_add_fplib.cpp @@ -0,0 +1,863 @@ +/* + * This program source code file is part of KiCad, a free EDA CAD application. + * + * Copyright (C) 2015 CERN + * @author Maciej Suminski <maciej.suminski@cern.ch> + * 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 footprint libraries consisting of 4 steps: + * - select source (Github/local files) + * - pick libraries + * - present a review of libraries (including validation) + * - select scope (global/project) + */ + +#include <wx/wx.h> +#include <wx/uri.h> +#include <wx/dir.h> +#include <wx/progdlg.h> + +#include <pgm_base.h> +#include <project.h> +#include <wizard_add_fplib.h> +#include <fp_lib_table.h> +#include <confirm.h> + +#include <class_module.h> + +#ifdef BUILD_GITHUB_PLUGIN +#include <../github/github_getliblist.h> +#endif + +// a key to store the default Kicad Github libs URL +#define KICAD_FPLIBS_URL_KEY wxT( "kicad_fplib_url" ) +#define KICAD_FPLIBS_LAST_DOWNLOAD_DIR wxT( "kicad_fplib_last_download_dir" ) + +// Filters for the file picker +static const int FILTER_COUNT = 4; +static const struct +{ + wxString m_Description; ///< Description shown in the file picker dialog + wxString m_Extension; ///< In case of folders it stands for extensions of files stored inside + bool m_IsFile; ///< Whether it is a folder or a file + IO_MGR::PCB_FILE_T m_Plugin; +} fileFilters[FILTER_COUNT] = +{ + { "KiCad (folder with .kicad_mod files)", "kicad_mod", false, IO_MGR::KICAD }, + { "Eagle 6.x (*.lbr)", "lbr", true, IO_MGR::EAGLE }, + { "KiCad legacy (*.mod)", "mod", true, IO_MGR::LEGACY }, + { "Geda (folder with *.fp files)", "fp", false, IO_MGR::GEDA_PCB }, +}; + + +// Returns the filter string for the file picker +static wxString getFilterString() +{ + wxString filterInit = _( "All supported library formats|" ); + wxString filter; + + for( int i = 0; i < FILTER_COUNT; ++i ) + { + // Init part + if( i != 0 ) + filterInit += ";"; + + filterInit += "*." + fileFilters[i].m_Extension; + + // Rest of the filter string + filter += "|" + fileFilters[i].m_Description + + "|" + ( fileFilters[i].m_IsFile ? "*." + fileFilters[i].m_Extension : "" ); + } + + return filterInit + filter; +} + + +// Tries to guess the plugin type basing on the path +static boost::optional<IO_MGR::PCB_FILE_T> getPluginType( const wxString& aPath ) +{ + if( ( aPath.StartsWith( "http://" ) || aPath.StartsWith( "https://" ) ) ) + return boost::optional<IO_MGR::PCB_FILE_T>( IO_MGR::GITHUB ); + + wxFileName path( aPath ); + + for( int i = 0; i < FILTER_COUNT; ++i ) + { + bool ok = false; + + if( fileFilters[i].m_IsFile ) + { + ok = path.IsFileReadable() && path.GetExt() == fileFilters[i].m_Extension; + } + else if( path.IsDirReadable() ) + { + // Plugin expects a directory containing files with a specific extension + wxDir dir( aPath ); + + if( dir.IsOpened() ) + { + wxString filename; + + dir.GetFirst( &filename, "*." + fileFilters[i].m_Extension, wxDIR_FILES ); + + ok = !filename.IsEmpty(); + } + } + + if( ok ) + return boost::optional<IO_MGR::PCB_FILE_T>( fileFilters[i].m_Plugin ); + } + + return boost::none; +} + + +// Checks if a filename fits specific filter +static bool passesFilter( const wxString& aFileName, int aFilterIndex ) +{ + wxASSERT( aFilterIndex <= FILTER_COUNT ); + wxFileName file( aFileName ); + boost::optional<IO_MGR::PCB_FILE_T> result = getPluginType( aFileName ); + + if( !result ) // does not match any supported plugin + return false; + + if( aFilterIndex == 0 ) // any plugin will do + return true; + + return ( fileFilters[aFilterIndex - 1].m_Plugin == *result ); +} + + +WIZARD_FPLIB_TABLE::LIBRARY::LIBRARY( const wxString& aPath, const wxString& aDescription ) : + m_path( aPath ), m_description( aDescription ), m_status( NOT_CHECKED ) +{ + m_plugin = getPluginType( aPath ); +} + + +bool WIZARD_FPLIB_TABLE::LIBRARY::Test() +{ + if( !m_plugin ) + { + m_status = LIBRARY::INVALID; + return false; + } + + PLUGIN* p = IO_MGR::PluginFind( *m_plugin ); + wxArrayString footprints; + + if( !p ) + { + m_status = LIBRARY::INVALID; + return false; + } + + try + { + footprints = p->FootprintEnumerate( m_path ); + } + catch( IO_ERROR& e ) + { + m_status = LIBRARY::INVALID; + return false; + } + + if( footprints.GetCount() == 0 ) + { + m_status = LIBRARY::INVALID; + return false; + } + + m_status = LIBRARY::OK; + return true; +} + + +wxString WIZARD_FPLIB_TABLE::LIBRARY::GetPluginName() const +{ + if( !m_plugin ) + return _( "UNKNOWN" ); + + switch( *m_plugin ) + { + case IO_MGR::LEGACY: + return wxT( "Legacy" ); + + case IO_MGR::KICAD: + return wxT( "KiCad" ); + + case IO_MGR::EAGLE: + return wxT( "Eagle" ); + + case IO_MGR::GEDA_PCB: + return wxT( "Geda-PCB" ); + + case IO_MGR::GITHUB: + return wxT( "Github" ); + + default: + return _( "UNKNOWN" ); + } + + /*PLUGIN* p = IO_MGR::PluginFind( *m_plugin ); + + if( !p ) + return _( "UNKNOWN" ); + + return p->PluginName();*/ +} + + +wxString WIZARD_FPLIB_TABLE::LIBRARY::GetRelativePath( const wxString& aBase, const wxString& aSubstitution ) const +{ + wxFileName libPath( m_path ); + + // Check if the library path belongs to the project folder + if( libPath.MakeRelativeTo( aBase ) && !libPath.GetFullPath().StartsWith( ".." ) ) + { + return wxString( aSubstitution + "/" + libPath.GetFullPath() ); + } + + // Probably on another drive, so the relative path will not work + return wxEmptyString; +} + + +wxString WIZARD_FPLIB_TABLE::LIBRARY::GetAutoPath( LIB_SCOPE aScope ) const +{ + const wxString& global_env = FP_LIB_TABLE::GlobalPathEnvVariableName(); + const wxString& project_env = PROJECT_VAR_NAME; + const wxString& github_env( "KIGITHUB" ); + + wxString rel_path; + + // KISYSMOD check + rel_path = replaceEnv( global_env ); + + if( !rel_path.IsEmpty() ) + return rel_path; + + // KIGITHUB check + rel_path = replaceEnv( github_env, false ); + + if( !rel_path.IsEmpty() ) + return rel_path; + + // KIPRJMOD check + if( aScope == PROJECT ) + { + rel_path = replaceEnv( project_env ); + + if( !rel_path.IsEmpty() ) + return rel_path; + } + + // Return the full path + return m_path; +} + + +wxString WIZARD_FPLIB_TABLE::LIBRARY::GetDescription() const +{ + if( !m_description.IsEmpty() ) + return m_description; + + wxFileName filename( m_path ); + return filename.GetName(); +} + + +wxString WIZARD_FPLIB_TABLE::LIBRARY::replaceEnv( const wxString& aEnvVar, bool aFilePath ) const +{ + wxString env_path; + + if( !wxGetEnv( aEnvVar, &env_path ) ) + return wxEmptyString; + + //return GetRelativePath( m_path, wxString( "$(" + aEnvVar + ")" ) ); + + wxString result( m_path ); + + if( result.Replace( env_path, wxString( "$(" + aEnvVar + ")" ) ) ) + return result; + + return wxEmptyString; +} + + +WIZARD_FPLIB_TABLE::WIZARD_FPLIB_TABLE( wxWindow* aParent ) : + WIZARD_FPLIB_TABLE_BASE( aParent ), m_welcomeDlg( m_pages[0] ), + m_fileSelectDlg( m_pages[1] ), m_githubListDlg( m_pages[2] ), + m_reviewDlg( m_pages[3] ), m_targetDlg( m_pages[4] ), m_selectedFilter( 0 ) +{ + m_filePicker->SetFilter( getFilterString() ); + + // Initialize default download dir + wxString default_path; + wxGetEnv( FP_LIB_TABLE::GlobalPathEnvVariableName(), &default_path ); + setDownloadDir( default_path ); + m_filePicker->SetPath( default_path ); + + // Restore the Github url + wxString githubUrl; + + wxConfigBase* cfg = Pgm().CommonSettings(); + cfg->Read( KICAD_FPLIBS_URL_KEY, &githubUrl ); + cfg->Read( KICAD_FPLIBS_LAST_DOWNLOAD_DIR, &m_lastGithubDownloadDirectory ); + + + if( !m_lastGithubDownloadDirectory.IsEmpty() ) + { + setDownloadDir( m_lastGithubDownloadDirectory ); + m_filePicker->SetPath( m_lastGithubDownloadDirectory ); + } else { + m_lastGithubDownloadDirectory = default_path; + } + + if( githubUrl.IsEmpty() ) + githubUrl = wxT( "https://github.com/KiCad" ); + + 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(); + + if( !m_radioAddGithub->GetValue() && !m_radioAddLocal->GetValue() ) + m_radioAddLocal->SetValue( true ); + + setupDialogOrder(); + updateGithubControls(); + + Connect( wxEVT_RADIOBUTTON, wxCommandEventHandler( WIZARD_FPLIB_TABLE::OnSourceCheck ), NULL, this ); + Connect( wxEVT_DIRCTRL_SELECTIONCHANGED, wxCommandEventHandler( WIZARD_FPLIB_TABLE::OnSelectFiles ), NULL, this ); + Connect( wxEVT_CHECKLISTBOX, wxCommandEventHandler( WIZARD_FPLIB_TABLE::OnCheckGithubList ), NULL, this ); +} + + +WIZARD_FPLIB_TABLE::~WIZARD_FPLIB_TABLE() +{ + // 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_FPLIBS_URL_KEY, GetGithubURL() ); +} + + +WIZARD_FPLIB_TABLE::LIB_SOURCE WIZARD_FPLIB_TABLE::GetLibSource() const +{ + if( m_radioAddGithub->GetValue() ) + return GITHUB; + + wxASSERT( m_radioAddLocal->GetValue() ); + + return LOCAL; +} + + +WIZARD_FPLIB_TABLE::LIB_SCOPE WIZARD_FPLIB_TABLE::GetLibScope() const +{ + if( m_radioGlobal->GetValue() ) + return GLOBAL; + + wxASSERT( m_radioProject->GetValue() ); + + return PROJECT; +} + + +void WIZARD_FPLIB_TABLE::OnPageChanged( wxWizardEvent& aEvent ) +{ + SetBitmap( KiBitmap( wizard_add_fplib_icon_xpm ) ); + enableNext( true ); + +#ifdef BUILD_GITHUB_PLUGIN + if( GetCurrentPage() == m_githubListDlg ) + setupGithubList(); + else +#endif + if( GetCurrentPage() == m_fileSelectDlg ) + setupFileSelect(); + else if( GetCurrentPage() == m_reviewDlg ) + setupReview(); +} + + +void WIZARD_FPLIB_TABLE::OnSelectFiles( wxCommandEvent& aEvent ) +{ + int filterIdx = m_filePicker->GetFilterIndex(); + + if( m_selectedFilter != filterIdx ) + { + m_selectedFilter = filterIdx; + + // Process the event again, as in the first iteration we cannot get the list of selected items + wxCommandEvent ev( wxEVT_DIRCTRL_SELECTIONCHANGED ); + AddPendingEvent( ev ); + return; + } + + enableNext( checkFiles() ); +} + + +void WIZARD_FPLIB_TABLE::OnCheckGithubList( wxCommandEvent& aEvent ) +{ + wxArrayInt dummy; + + enableNext( m_checkListGH->GetCheckedItems( dummy ) > 0 ); +} + + +void WIZARD_FPLIB_TABLE::OnSourceCheck( wxCommandEvent& aEvent ) +{ + updateGithubControls(); + setupDialogOrder(); +} + + +void WIZARD_FPLIB_TABLE::OnSelectAllGH( wxCommandEvent& aEvent ) +{ + for( unsigned int i = 0; i < m_checkListGH->GetCount(); ++i ) + m_checkListGH->Check( i, true ); + + // The list might be empty, e.g. in case of download error + wxArrayInt dummy; + enableNext( m_checkListGH->GetCheckedItems( dummy ) > 0 ); +} + + +void WIZARD_FPLIB_TABLE::OnUnselectAllGH( wxCommandEvent& aEvent ) +{ + for( unsigned int i = 0; i < m_checkListGH->GetCount(); ++i ) + m_checkListGH->Check( i, false ); + + enableNext( false ); +} + + +void WIZARD_FPLIB_TABLE::OnChangeSearch( wxCommandEvent& aEvent ) +{ + wxString searchPhrase = m_searchCtrlGH->GetValue().Lower(); + + // Store the current selection + wxArrayInt checkedIndices; + m_checkListGH->GetCheckedItems( checkedIndices ); + wxArrayString checkedStrings; + + for( unsigned int i = 0; i < checkedIndices.GetCount(); ++i ) + checkedStrings.Add( m_checkListGH->GetString( checkedIndices[i] ).AfterLast( '/' ) ); + + m_checkListGH->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_checkListGH->Insert( lib, matching++ ); + m_checkListGH->SetSelection( insertedIdx ); + } + else + insertedIdx = m_checkListGH->Append( lib ); + + if( wasChecked ) + m_checkListGH->Check( insertedIdx ); + } + + if( !m_checkListGH->IsEmpty() ) + m_checkListGH->EnsureVisible( 0 ); +} + + +void WIZARD_FPLIB_TABLE::OnWizardFinished( wxWizardEvent& aEvent ) +{ +#ifdef BUILD_GITHUB_PLUGIN + // Shall we download a localy copy of the libraries + if( GetLibSource() == GITHUB && m_downloadGithub->GetValue() ) + { + wxString error; + wxArrayString libs; + + // Prepare a list of libraries to download + for( std::vector<LIBRARY>::const_iterator it = m_libraries.begin(); + it != m_libraries.end(); ++it ) + { + wxASSERT( it->GetPluginType() == IO_MGR::GITHUB ); + + if( it->GetStatus() != LIBRARY::INVALID ) + libs.Add( it->GetAbsolutePath() ); + } + + if( !downloadGithubLibsFromList( libs, &error ) ) + { + DisplayError( this, error ); + m_libraries.clear(); + } + else + { + // Now libraries are stored locally, so update the paths to point to the download folder + for( std::vector<LIBRARY>::iterator it = m_libraries.begin(); + it != m_libraries.end(); ++it ) + { + wxString path = it->GetAbsolutePath(); + path.Replace( GetGithubURL(), getDownloadDir() ); + it->setPath( path ); + it->setPluginType( IO_MGR::KICAD ); + } + } + } +#endif +} + + +void WIZARD_FPLIB_TABLE::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 ); + + wxConfigBase* cfg = Pgm().CommonSettings(); + cfg->Write( KICAD_FPLIBS_LAST_DOWNLOAD_DIR, path ); + + updateGithubControls(); + } +} + + +void WIZARD_FPLIB_TABLE::OnCheckSaveCopy( wxCommandEvent& aEvent ) +{ + updateGithubControls(); +} + + +bool WIZARD_FPLIB_TABLE::checkFiles() const +{ + // Get current selection (files & directories) + wxArrayString candidates; + m_filePicker->GetPaths( candidates ); + + // Workaround, when you change filters "/" is automatically selected + int slash_index = candidates.Index( "/", true, true ); + if( slash_index != wxNOT_FOUND ) + candidates.RemoveAt( slash_index, 1 ); + + if( candidates.IsEmpty() ) + return false; + + // Verify all the files/folders comply to the selected library type filter + for( unsigned int i = 0; i < candidates.GetCount(); ++i ) + { + if( !passesFilter( candidates[i], m_filePicker->GetFilterIndex() ) ) + return false; + } + + return true; +} + + +#ifdef BUILD_GITHUB_PLUGIN +void WIZARD_FPLIB_TABLE::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.GetFootprintLibraryList( aList ); + + wxEndBusyCursor(); +} + + +// Download the .pretty libraries found in aUrlLis and store them on disk +// in a master folder +bool WIZARD_FPLIB_TABLE::downloadGithubLibsFromList( wxArrayString& aUrlList, + wxString* aErrorMessage ) +{ + // Display a progress bar to show the downlaod state + wxProgressDialog pdlg( _( "Downloading libraries" ), wxEmptyString, aUrlList.GetCount() ); + + // Download libs: + for( unsigned ii = 0; ii < aUrlList.GetCount(); ii++ ) + { + wxString& libsrc_name = aUrlList[ii]; + wxString libdst_name; + + // Extract the lib name from the full URL: + wxURI url( libsrc_name ); + wxFileName fn( url.GetPath() ); + // Set our local path + fn.SetPath( getDownloadDir() ); + libdst_name = fn.GetFullPath(); + + if( !wxDirExists( libdst_name ) ) + wxMkdir( libdst_name ); + + pdlg.Update( ii, libsrc_name ); + pdlg.Refresh(); + pdlg.Update(); + + try + { + PLUGIN::RELEASER src( IO_MGR::PluginFind( IO_MGR::GITHUB ) ); + PLUGIN::RELEASER dst( IO_MGR::PluginFind( IO_MGR::KICAD ) ); + + wxArrayString footprints = src->FootprintEnumerate( libsrc_name ); + + for( unsigned i = 0; i < footprints.size(); ++i ) + { + std::auto_ptr<MODULE> m( src->FootprintLoad( libsrc_name, footprints[i] ) ); + dst->FootprintSave( libdst_name, m.get() ); + // m is deleted here by auto_ptr. + } + } + catch( const IO_ERROR& ioe ) + { + if( aErrorMessage ) + aErrorMessage->Printf( _( "Error:\n'%s'\nwhile downloading library:\n'%s'" ), + GetChars( ioe.errorText ), GetChars( libsrc_name ) ); + return false; + } + } + + return true; +} + + +void WIZARD_FPLIB_TABLE::setupGithubList() +{ + // Enable 'Next' only if there is at least one library selected + wxArrayInt checkedIndices; + m_checkListGH->GetCheckedItems( checkedIndices ); + enableNext( checkedIndices.GetCount() > 0 ); + + // Update only if necessary + if( m_githubLibs.GetCount() == 0 ) + getLibsListGithub( m_githubLibs ); + + m_searchCtrlGH->Clear(); + + // Clear the review list so it will be reloaded + m_libraries.clear(); + m_listCtrlReview->DeleteAllItems(); +} +#endif /* BUILD_GITHUB_PLUGIN */ + + +void WIZARD_FPLIB_TABLE::updateGithubControls() +{ +#ifndef BUILD_GITHUB_PLUGIN + m_radioAddGithub->Enable( false ); +#endif + + // Disable inputs that have no meaning for the selected source + bool githubEnabled = ( GetLibSource() == GITHUB ); + m_textCtrlGithubURL->Enable( githubEnabled ); + m_downloadGithub->Enable( githubEnabled ); + m_downloadDir->Enable( githubEnabled && wantLocalCopy() ); + m_btnBrowse->Enable( githubEnabled && wantLocalCopy() ); + + bool valid = !( githubEnabled && wantLocalCopy() ) || wxFileName::IsDirWritable( getDownloadDir() ); + + // Do not allow to go further unless there is a valid directory selected + m_invalidDir->Show( !valid ); + enableNext( valid ); +} + + +void WIZARD_FPLIB_TABLE::updateLibraries() +{ + // No need to update, the review list is ready + if( m_listCtrlReview->GetItemCount() != 0 ) + return; + + switch( GetLibSource() ) + { + case LOCAL: + { + wxArrayString libs; + m_filePicker->GetPaths( libs ); + + // Workaround, when you change filters "/" is automatically selected + int slash_index = libs.Index( "/", true, true ); + if( slash_index != wxNOT_FOUND ) + libs.RemoveAt( slash_index, 1 ); + + m_libraries.reserve( libs.GetCount() ); + + for( unsigned int i = 0; i < libs.GetCount(); ++i ) + m_libraries.push_back( libs[i] ); + } + break; + + case GITHUB: + { + wxArrayInt checkedLibs; + m_checkListGH->GetCheckedItems( checkedLibs ); + + m_libraries.reserve( checkedLibs.GetCount() ); + + for( unsigned int i = 0; i < checkedLibs.GetCount(); ++i ) + m_libraries.push_back( GetGithubURL() + "/" + m_checkListGH->GetString( checkedLibs[i] ) ); + } + break; + + default: + wxASSERT( false ); + break; + } +} + + +void WIZARD_FPLIB_TABLE::setupDialogOrder() +{ + // Alternate the wizard pages flow depending on the selected option + switch( GetLibSource() ) + { + case LOCAL: + m_welcomeDlg->SetNext( m_fileSelectDlg ); + m_fileSelectDlg->SetPrev( m_welcomeDlg ); + + m_fileSelectDlg->SetNext( m_reviewDlg ); + m_reviewDlg->SetPrev( m_fileSelectDlg ); + break; + + case GITHUB: + m_welcomeDlg->SetNext( m_githubListDlg ); + m_githubListDlg->SetPrev( m_welcomeDlg ); + + m_githubListDlg->SetNext( m_reviewDlg ); + m_reviewDlg->SetPrev( m_githubListDlg ); + break; + + default: + wxASSERT( false ); + break; + } +} + + +void WIZARD_FPLIB_TABLE::setupFileSelect() +{ + // Disable the button until something is selected + enableNext( checkFiles() ); + + // Clear the review list so it will be reloaded + m_libraries.clear(); + m_listCtrlReview->DeleteAllItems(); +} + + +void WIZARD_FPLIB_TABLE::setupReview() +{ + wxBeginBusyCursor(); + updateLibraries(); + + int libTotalCount = m_libraries.size(); + int libCount = 0; + bool validate = true; + wxProgressDialog progressDlg( _( "Please wait..." ), _( "Validating libraries" ), + libTotalCount, this, + wxPD_APP_MODAL | wxPD_CAN_ABORT | wxPD_AUTO_HIDE ); + + m_dvLibName->SetWidth( 280 ); + + // Prepare the review list + m_listCtrlReview->DeleteAllItems(); + + for( std::vector<LIBRARY>::iterator it = m_libraries.begin(); it != m_libraries.end(); ++it ) + { + wxVector<wxVariant> row; + LIBRARY::STATUS status = it->GetStatus(); + + // Check if the library contents is valid + if( status == LIBRARY::NOT_CHECKED && validate ) + { + it->Test(); + status = it->GetStatus(); + } + + row.push_back( wxVariant( it->GetDescription() ) ); + + switch( it->GetStatus() ) + { + case LIBRARY::NOT_CHECKED: + row.push_back( wxVariant( _( "NOT CHECKED" ) ) ); + break; + + case LIBRARY::OK: + row.push_back( wxVariant( _( "OK" ) ) ); + break; + + case LIBRARY::INVALID: + row.push_back( wxVariant( _( "INVALID" ) ) ); + break; + } + + row.push_back( wxVariant( it->GetPluginName() ) ); + + m_listCtrlReview->AppendItem( row ); + + ++libCount; + if( !progressDlg.Update( libCount, wxString::Format( _( "Validating libraries %d/%d" ), + libCount, libTotalCount ) ) ) + validate = false; + } + + // The list should never be empty, but who knows? + enableNext( m_listCtrlReview->GetItemCount() > 0 ); + + wxEndBusyCursor(); +} |