mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-14 10:13:19 +02:00
* if the current select plugin is the github plugin, one can select some of these libraries and add them to the table * if the current select plugin is the kicad plugin, one can select some of these libraries and download them to make alocal copy. They can added to the table after they are downloaded.
946 lines
30 KiB
C++
946 lines
30 KiB
C++
/**
|
|
* @file wizard_add_fplib.cpp
|
|
*/
|
|
|
|
/*
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
*
|
|
* Copyright (C) 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 this code creates a wizard to add entries in the footprint library table.
|
|
* The wizard contains 3 pages:
|
|
* The first is the selection of the type of libraries (plugin type):
|
|
* * Kicad .pretty library (actually a folder containing .kicad_mod footprint files)
|
|
* * Gihtub .pretty on line library, accessible via a internet connection
|
|
* * Legacy library (old .mod format file containing footprints desc)
|
|
* * Eagle xml V6 library (.lbr files)
|
|
* * Geda-PCB library (actually a folder containing .fp footprint files
|
|
* The second is the selection of path management:
|
|
* use environment variable or absolute path.
|
|
* When using an environment variable, selec it
|
|
* The third is the library list selection
|
|
* It allows entering entries by running a tool to select a set of libraries
|
|
* The tool depend on the type of lib (files/folder/urls):
|
|
* * multi files selector
|
|
* * multi folder selector
|
|
* * multi URL selector (via a web viewer)
|
|
* The path and the plugin type comes from the selection, and a library nickname
|
|
* is built from the path.
|
|
*/
|
|
|
|
#include <wx/wx.h>
|
|
#include <wx/url.h>
|
|
#include <wx/progdlg.h>
|
|
|
|
#include <pgm_base.h>
|
|
#include <kiface_i.h>
|
|
#include <dialog_helpers.h>
|
|
#include <project.h> // For PROJECT_VAR_NAME definition
|
|
#include <fp_lib_table.h> // For KISYSMOD definition
|
|
#include <io_mgr.h>
|
|
#include <wizard_add_fplib.h>
|
|
#include <dialog_select_dirlist_base.h>
|
|
|
|
// a key to store the default Kicad Github libs URL
|
|
#define KICAD_FPLIBS_URL_KEY wxT( "kicad_fplib_url" )
|
|
|
|
// key to store last options of th wizard
|
|
#define WIZARD_LAST_PLUGIN_KEY wxT( "wizard_plugin" )
|
|
#define WIZARD_LAST_PATHOPTION_KEY wxT( "wizard_path_option" )
|
|
|
|
// static members to store last choices during a session
|
|
int WIZARD_FPLIB_TABLE::m_last_plugin_choice = 0;
|
|
int WIZARD_FPLIB_TABLE::m_last_defaultpath_choice = 2;
|
|
|
|
WIZARD_FPLIB_TABLE::WIZARD_FPLIB_TABLE( wxWindow* aParent, wxArrayString& aEnvVariableList )
|
|
: WIZARD_FPLIB_TABLE_BASE( aParent )
|
|
{
|
|
initDlg( aEnvVariableList );
|
|
|
|
// Allows github plugin selection only when the plugin is compiled:
|
|
#ifndef BUILD_GITHUB_PLUGIN
|
|
m_rbFpLibFormat->Enable( GITHUB_PLUGIN, false );
|
|
|
|
if( m_rbFpLibFormat->GetSelection() == GITHUB_PLUGIN )
|
|
m_rbFpLibFormat->SetSelection( KICAD_PLUGIN );
|
|
#endif
|
|
|
|
// Currently, I (JPC) do not know the best way to add/store
|
|
// what is currently called env variables
|
|
// So do not show tools to change them,
|
|
// but do not remove the code, just in case
|
|
m_buttonAddEV->Show( false );
|
|
m_buttonRemoveEV->Show( false );
|
|
|
|
#ifndef BUILD_GITHUB_PLUGIN
|
|
m_buttonGithubLibList->Show( false );
|
|
#endif
|
|
|
|
// Gives a 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();
|
|
}
|
|
|
|
|
|
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, m_textCtrlGithubURL->GetValue() );
|
|
|
|
m_last_plugin_choice = m_rbFpLibFormat->GetSelection();
|
|
m_last_defaultpath_choice = m_rbPathManagement->GetSelection();
|
|
|
|
cfg->Write( WIZARD_LAST_PLUGIN_KEY, m_last_plugin_choice );
|
|
cfg->Write( WIZARD_LAST_PATHOPTION_KEY, m_last_defaultpath_choice );
|
|
}
|
|
|
|
|
|
void WIZARD_FPLIB_TABLE::initDlg( wxArrayString& aEnvVariableList )
|
|
{
|
|
m_currLibDescr = NULL;
|
|
|
|
SetBitmap( KiBitmap( wizard_add_fplib_icon_xpm ) );
|
|
|
|
wxString msg;
|
|
wxConfigBase* cfg = Pgm().CommonSettings();
|
|
cfg->Read( KICAD_FPLIBS_URL_KEY, &msg );
|
|
cfg->Read( WIZARD_LAST_PLUGIN_KEY, &m_last_plugin_choice );
|
|
cfg->Read( WIZARD_LAST_PATHOPTION_KEY, &m_last_defaultpath_choice );
|
|
|
|
if( msg.IsEmpty() )
|
|
m_textCtrlGithubURL->SetValue( wxT( "http://github.com/KiCad/" ) );
|
|
else
|
|
m_textCtrlGithubURL->SetValue( msg );
|
|
|
|
// KIGITHUB is frequently used (examples in docs, and other place)
|
|
// So add it if it not yet in list, but if it is defined as env var
|
|
// (note this env var is not hardcoded or existing in kicad sources)
|
|
if( aEnvVariableList.Index( wxT("KIGITHUB"), false ) == wxNOT_FOUND )
|
|
{
|
|
// Not yet in use in lib table, see in env. vars
|
|
wxString evValue;
|
|
wxGetEnv( wxT("KIGITHUB"), &evValue );
|
|
|
|
// Not yet in use in lib table, but it is defined in environment,
|
|
// so add it, just in case
|
|
if( ! evValue.IsEmpty() )
|
|
aEnvVariableList.Add( wxT("KIGITHUB") );
|
|
}
|
|
|
|
m_rowPrjEnvVarPosition = 0;
|
|
m_predefinedEnvVarCnt = aEnvVariableList.GetCount();
|
|
|
|
for( int row = 0; row < m_predefinedEnvVarCnt; row++ )
|
|
{
|
|
if( GetEnvVarCount() <= row )
|
|
m_gridEnvironmentVariablesList->AppendRows(1);
|
|
|
|
m_gridEnvironmentVariablesList->SetCellValue( row, 0, aEnvVariableList[row] );
|
|
|
|
if( aEnvVariableList[row] == PROJECT_VAR_NAME )
|
|
m_rowPrjEnvVarPosition = row;
|
|
|
|
wxString evValue;
|
|
|
|
if( wxGetEnv( aEnvVariableList[row], &evValue ) )
|
|
m_gridEnvironmentVariablesList->SetCellValue( row, 1, evValue );
|
|
|
|
// All these env var are defined outside the wizard,
|
|
// and cannot be modified in this dialog
|
|
m_gridEnvironmentVariablesList->SetReadOnly( row, 0, true );
|
|
m_gridEnvironmentVariablesList->SetReadOnly( row, 1, true );
|
|
}
|
|
|
|
m_gridEnvironmentVariablesList->Fit();
|
|
|
|
m_buttonRemoveEV->Enable( GetEnvVarCount() > m_predefinedEnvVarCnt );
|
|
m_gridEnvironmentVariablesList->AutoSizeColumns();
|
|
|
|
m_rbFpLibFormat->SetSelection( m_last_plugin_choice );
|
|
m_rbPathManagement->SetSelection( m_last_defaultpath_choice );
|
|
|
|
wxCommandEvent event;
|
|
updateFromPlugingChoice();
|
|
OnPathManagementSelection( event );
|
|
}
|
|
|
|
int WIZARD_FPLIB_TABLE::HasGithubEnvVarCompatible()
|
|
{
|
|
// Return true if at least one env var defines a url relative to github
|
|
for( int row = 0; row < GetEnvVarCount(); row++ )
|
|
{
|
|
if( m_gridEnvironmentVariablesList->GetCellValue(
|
|
wxGridCellCoords( row, 1 ) ).Lower().StartsWith( "http" ) )
|
|
return row;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
|
|
bool WIZARD_FPLIB_TABLE::ValidateOptions()
|
|
{
|
|
// Some choices can be conficting or do not work.
|
|
// Warn the user when this is the case
|
|
wxString msg;
|
|
|
|
if( getSelectedEnvVarValue().IsEmpty() )
|
|
{
|
|
// PROJECT_PATH option cannot be used with empty local path
|
|
if( m_rbPathManagement->GetSelection() == PROJECT_PATH )
|
|
{
|
|
msg = _("The project path is empty and this option is not valid.\n"
|
|
"Looks like you are running the wizard outside a project.");
|
|
wxMessageBox( msg );
|
|
return false;
|
|
}
|
|
else if( m_rbPathManagement->GetSelection() != ABSOLUTE_PATH )
|
|
{
|
|
wxMessageBox( wxString::Format(
|
|
_("The default path defined by env var \"%s\" is empty.\nCannot use it"),
|
|
GetChars( getSelectedEnvVar() ) ) );
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( IsGithubPlugin() )
|
|
{
|
|
// Github plugin cannot be used with local path; Need absolute path or valid URL
|
|
if( !getSelectedEnvVarValue().Lower().StartsWith( "http" ) )
|
|
{
|
|
msg = _("Github Plugin uses a valid Internet URL starting by http.\n"
|
|
"Cannot be used as URL");
|
|
wxMessageBox( msg );
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( getSelectedEnvVarValue().Lower().StartsWith( "http" ) )
|
|
{
|
|
msg = _("This default path looks strange.\n"
|
|
"Cannot be used for a file path");
|
|
wxMessageBox( msg );
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Other conficts: TODO
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
void WIZARD_FPLIB_TABLE::OnPluginSelection( wxCommandEvent& event )
|
|
{
|
|
updateFromPlugingChoice();
|
|
}
|
|
|
|
void WIZARD_FPLIB_TABLE::updateFromPlugingChoice()
|
|
{
|
|
#ifdef BUILD_GITHUB_PLUGIN
|
|
m_buttonGithubLibList->Show( IsGithubPlugin() || IsKicadPlugin() );
|
|
#endif
|
|
|
|
// update dialog options and widgets depending on a plugin choice
|
|
// Project path has no sense for GITHUB_PLUGIN
|
|
bool enablePrjPathOpt = not IsGithubPlugin();
|
|
|
|
// Project path cannot be used if unknown
|
|
if( m_gridEnvironmentVariablesList->GetCellValue(
|
|
wxGridCellCoords( m_rowPrjEnvVarPosition, 1 ) ).IsEmpty() )
|
|
enablePrjPathOpt = false;
|
|
|
|
m_rbPathManagement->Enable( PROJECT_PATH, enablePrjPathOpt );
|
|
|
|
// Sometimes only the choice "absolute path" is allowed;
|
|
// Force this choice, at least make it the default choice
|
|
bool force_absolute_path = false;
|
|
|
|
// For github plugin, the project path is not allowed
|
|
if( ( m_rbPathManagement->GetSelection() == PROJECT_PATH ) && !enablePrjPathOpt )
|
|
force_absolute_path = true;
|
|
|
|
// For github plugin, at least one github compatible path must exist
|
|
// If no github path, force absolute path
|
|
int first_github_envvar = HasGithubEnvVarCompatible();
|
|
if( IsGithubPlugin() )
|
|
{
|
|
if( first_github_envvar < 0 )
|
|
force_absolute_path = true;
|
|
else if( !getSelectedEnvVarValue().StartsWith( "http" ) )
|
|
m_gridEnvironmentVariablesList->SelectRow( first_github_envvar );
|
|
|
|
}
|
|
|
|
if( force_absolute_path )
|
|
m_rbPathManagement->SetSelection( ABSOLUTE_PATH );
|
|
}
|
|
|
|
|
|
void WIZARD_FPLIB_TABLE::OnPathManagementSelection( wxCommandEvent& event )
|
|
{
|
|
// Disable irrevant options, and enable others.
|
|
int row_count = GetEnvVarCount();
|
|
|
|
switch( m_rbPathManagement->GetSelection() )
|
|
{
|
|
case PROJECT_PATH: // Choice = path relative to the project
|
|
m_gridEnvironmentVariablesList->Enable( true );
|
|
m_buttonAddEV->Enable( false );
|
|
m_gridEnvironmentVariablesList->ShowRow( PROJECT_PATH );
|
|
|
|
for( int row = 0; row < row_count; row++ )
|
|
{
|
|
if( row == PROJECT_PATH )
|
|
continue;
|
|
|
|
m_gridEnvironmentVariablesList->HideRow( row );
|
|
}
|
|
break;
|
|
|
|
case ENV_VAR_PATH: // Choice = path relative to env var
|
|
m_gridEnvironmentVariablesList->Enable( true );
|
|
m_buttonAddEV->Enable( true );
|
|
|
|
for( int row = 0; row < row_count; row++ )
|
|
m_gridEnvironmentVariablesList->ShowRow( row );
|
|
|
|
break;
|
|
|
|
case ABSOLUTE_PATH: // Choice = path relative to the project
|
|
m_gridEnvironmentVariablesList->Enable( false );
|
|
m_buttonAddEV->Enable( false );
|
|
break;
|
|
}
|
|
}
|
|
|
|
void WIZARD_FPLIB_TABLE::OnAddEVariable( wxCommandEvent& event )
|
|
{
|
|
m_gridEnvironmentVariablesList->AppendRows( 1 );
|
|
m_gridEnvironmentVariablesList->AutoSizeColumns();
|
|
m_buttonRemoveEV->Enable( GetEnvVarCount() > m_predefinedEnvVarCnt );
|
|
m_gridEnvironmentVariablesList->SetGridCursor( GetEnvVarCount()-1, 0 );
|
|
}
|
|
|
|
void WIZARD_FPLIB_TABLE::OnRemoveEVariable( wxCommandEvent& event )
|
|
{
|
|
wxArrayInt selectedRows = m_gridEnvironmentVariablesList->GetSelectedRows();
|
|
int row_cursor = m_gridEnvironmentVariablesList->GetGridCursorRow();
|
|
|
|
if( selectedRows.size() == 0 && row_cursor >= 0 )
|
|
selectedRows.Add( row_cursor );
|
|
|
|
std::sort( selectedRows.begin(), selectedRows.end() );
|
|
|
|
for( int ii = selectedRows.GetCount()-1; ii >= 0; ii-- )
|
|
{
|
|
int row = selectedRows[ii];
|
|
|
|
// don't remove them env var. which are already existing in lib table
|
|
if( row > m_predefinedEnvVarCnt-1 )
|
|
m_gridEnvironmentVariablesList->DeleteRows( row, 1 );
|
|
}
|
|
|
|
m_gridEnvironmentVariablesList->SelectRow( m_gridEnvironmentVariablesList->GetGridCursorRow() );
|
|
m_buttonRemoveEV->Enable( GetEnvVarCount() > m_predefinedEnvVarCnt );
|
|
}
|
|
|
|
void WIZARD_FPLIB_TABLE::OnSelectEnvVarCell( wxGridEvent& event )
|
|
{
|
|
// Ensure the selected row is also the row which have the focus.
|
|
// useful when the user want to delete a row, and select it by the mouse
|
|
m_gridEnvironmentVariablesList->SelectRow( event.GetRow() );
|
|
}
|
|
|
|
wxString WIZARD_FPLIB_TABLE::getSelectedEnvVar()
|
|
{
|
|
wxString envVar;
|
|
wxArrayInt selectedRows = m_gridEnvironmentVariablesList->GetSelectedRows();
|
|
int row = selectedRows.GetCount() ? selectedRows[0] :
|
|
m_gridEnvironmentVariablesList->GetGridCursorRow();
|
|
|
|
switch( m_rbPathManagement->GetSelection() )
|
|
{
|
|
case ENV_VAR_PATH: // Choice = path relative to env var
|
|
envVar = m_gridEnvironmentVariablesList->GetCellValue(
|
|
wxGridCellCoords( row, 0 ) );
|
|
break;
|
|
|
|
case PROJECT_PATH: // Choice = path relative to the project
|
|
envVar = PROJECT_VAR_NAME;
|
|
break;
|
|
|
|
case ABSOLUTE_PATH: // Choice = absolute path
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return envVar;
|
|
}
|
|
|
|
|
|
wxString WIZARD_FPLIB_TABLE::getSelectedEnvVarValue()
|
|
{
|
|
wxString envVarValue;
|
|
wxArrayInt selectedRows = m_gridEnvironmentVariablesList->GetSelectedRows();
|
|
int row = selectedRows.GetCount() ? selectedRows[0] :
|
|
m_gridEnvironmentVariablesList->GetGridCursorRow();
|
|
|
|
switch( m_rbPathManagement->GetSelection() )
|
|
{
|
|
case ENV_VAR_PATH: // Choice = path relative tp env var
|
|
envVarValue = m_gridEnvironmentVariablesList->GetCellValue(
|
|
wxGridCellCoords( row, 1 ) );
|
|
break;
|
|
|
|
case PROJECT_PATH: // Choice = path relative to the project
|
|
envVarValue = m_gridEnvironmentVariablesList->GetCellValue(
|
|
wxGridCellCoords( m_rowPrjEnvVarPosition, 1 ) );
|
|
break;
|
|
|
|
case ABSOLUTE_PATH: // Choice = absolute path
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return envVarValue;
|
|
}
|
|
|
|
void WIZARD_FPLIB_TABLE::OnPageChanged( wxWizardEvent& event )
|
|
{
|
|
if( GetCurrentPage() == m_pages[2] )
|
|
setLastPage();
|
|
else if( GetCurrentPage() == m_pages[1] )
|
|
setSecondPage();
|
|
}
|
|
|
|
void WIZARD_FPLIB_TABLE::OnPageChanging( wxWizardEvent& event )
|
|
{
|
|
if( !( GetCurrentPage() == m_pages[1] && event.GetDirection() ) )
|
|
return;
|
|
|
|
if( ! ValidateOptions() )
|
|
{
|
|
event.Veto();
|
|
return;
|
|
}
|
|
|
|
if( ( m_rbPathManagement->GetSelection() != ABSOLUTE_PATH ) &&
|
|
( IsGithubPlugin() ) )
|
|
{
|
|
wxURI uri( getSelectedEnvVarValue() );
|
|
|
|
// We cannot use wxURL to test the validity of the url, because
|
|
// wxURL does not know https protocol we are using, and aways returns
|
|
// error for url starting by https
|
|
bool badurl = !uri.HasPath();
|
|
|
|
if( badurl )
|
|
{
|
|
wxMessageBox( wxString::Format(
|
|
_("The URL defined by env var \"%s\" is an incorrect URL.\nCannot use it"),
|
|
GetChars( getSelectedEnvVar() ) ) );
|
|
event.Veto();
|
|
}
|
|
}
|
|
}
|
|
|
|
bool WIZARD_FPLIB_TABLE::setSecondPage()
|
|
{
|
|
// Init parameters for the second wizard page: this is only
|
|
// the current library description.
|
|
updateFromPlugingChoice();
|
|
|
|
delete m_currLibDescr;
|
|
m_currLibDescr = NULL;
|
|
|
|
switch( m_rbFpLibFormat->GetSelection() )
|
|
{
|
|
case 0: // Kicad lib type
|
|
m_currLibDescr = new LIB_DESCR_KICAD;
|
|
m_buttonGithubLibList->SetLabel( _("Download Github Libs") );
|
|
break;
|
|
|
|
case 1: // Github lib type
|
|
m_currLibDescr = new LIB_DESCR_GITHUB;
|
|
m_buttonGithubLibList->SetLabel( _("Github Libs List") );
|
|
break;
|
|
|
|
case 2: // Legacy lib type
|
|
m_currLibDescr = new LIB_DESCR_LEGACY;
|
|
break;
|
|
|
|
case 3: // Eagle V6 lib type
|
|
m_currLibDescr = new LIB_DESCR_EAGLE;
|
|
break;
|
|
|
|
case 4: // Geda lib type
|
|
m_currLibDescr = new LIB_DESCR_GEDA;
|
|
break;
|
|
}
|
|
|
|
if( IsGithubPlugin() )
|
|
{
|
|
#ifdef KICAD_USE_WEBKIT
|
|
m_buttonAddLib->SetLabel( _("Add Libs with WebViewer") );
|
|
#else
|
|
m_buttonAddLib->SetLabel( _("Add FP Library entry") );
|
|
#endif
|
|
}
|
|
else
|
|
m_buttonAddLib->SetLabel( _("Add FP Libraries") );
|
|
|
|
return m_currLibDescr!= NULL;
|
|
}
|
|
|
|
bool WIZARD_FPLIB_TABLE::setLastPage() // Init prms for the last wizard page
|
|
{
|
|
// Update texts in last wizard page
|
|
m_textPluginType->SetLabel( m_rbFpLibFormat->GetStringSelection() );
|
|
|
|
switch( m_rbPathManagement->GetSelection() )
|
|
{
|
|
case ENV_VAR_PATH: // Choice = path relative env var
|
|
case PROJECT_PATH: // Choice = path relative to the project
|
|
m_currLibDescr->m_EnvVarName = getSelectedEnvVar();
|
|
m_currLibDescr->m_DefaultPath = getSelectedEnvVarValue();
|
|
m_currLibDescr->m_IsAbsolutePath = false;
|
|
|
|
m_textOption->SetLabel( wxString::Format( wxT("%s (%s)"),
|
|
m_rbPathManagement->GetStringSelection().GetData(),
|
|
getSelectedEnvVar().GetData() ) );
|
|
|
|
m_textPath->SetLabel( getSelectedEnvVarValue() );
|
|
break;
|
|
|
|
case ABSOLUTE_PATH: // Choice = absolute path
|
|
m_currLibDescr->m_IsAbsolutePath = true;
|
|
|
|
m_textOption->SetLabel( m_rbPathManagement->GetStringSelection() );
|
|
|
|
if( IsGithubPlugin() )
|
|
m_textPath->SetLabel( _("Full URL") );
|
|
else
|
|
m_textPath->SetLabel( _("Full filename") );
|
|
break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
void WIZARD_FPLIB_TABLE::OnAddFpLibs( wxCommandEvent& event )
|
|
{
|
|
if( m_currLibDescr->m_IsFile )
|
|
selectLibsFiles();
|
|
else if( m_currLibDescr->m_IsGitHub )
|
|
selectLibsGithubWithWebViewer();
|
|
else
|
|
selectLibsFolders();
|
|
|
|
m_gridFpListLibs->SetGridCursor( GetLibsCount()-1, 0 );
|
|
m_gridFpListLibs->SelectRow( GetLibsCount()-1 );
|
|
}
|
|
|
|
void WIZARD_FPLIB_TABLE::selectLibsFiles() // select a set of library files
|
|
{
|
|
wxString msk = wxT("*.") + m_currLibDescr->m_Ext;
|
|
|
|
wxFileDialog dlg( this, _("Select Library Files"), m_currLibDescr->m_DefaultPath,
|
|
wxEmptyString, msk,
|
|
wxFD_DEFAULT_STYLE|wxFD_FILE_MUST_EXIST|wxFD_MULTIPLE );
|
|
|
|
dlg.ShowModal();
|
|
|
|
wxArrayString filepaths;
|
|
dlg.GetPaths( filepaths );
|
|
|
|
// Create the nickname: currently make it from the filename
|
|
wxArrayString nicknames;
|
|
wxFileName fn;
|
|
|
|
for( unsigned ii = 0; ii < filepaths.GetCount(); ii++ )
|
|
{
|
|
fn = filepaths[ii];
|
|
nicknames.Add( fn.GetName() );
|
|
|
|
if( m_currLibDescr->m_IsAbsolutePath || m_currLibDescr->m_DefaultPath.IsEmpty() )
|
|
{
|
|
filepaths[ii] = fn.GetPathWithSep();
|
|
}
|
|
else
|
|
{
|
|
if( ! fn.MakeRelativeTo( m_currLibDescr->m_DefaultPath ) )
|
|
filepaths[ii] = fn.GetFullPath();
|
|
else
|
|
filepaths[ii].Printf( wxT("${%s}%c%s"),
|
|
GetChars( m_currLibDescr->m_EnvVarName ),
|
|
fn.GetPathSeparator(),
|
|
GetChars( fn.GetFullPath() ) );
|
|
}
|
|
#ifdef __WINDOWS__
|
|
// We store paths using Unix notation, which also works fine on Windows
|
|
filepaths[ii].Replace( wxT("\\"), wxT("/") );
|
|
#endif
|
|
}
|
|
|
|
populateLibList( nicknames, filepaths, m_currLibDescr->m_PluginName );
|
|
m_gridFpListLibs->AutoSizeColumns();
|
|
}
|
|
|
|
|
|
void WIZARD_FPLIB_TABLE::populateLibList( const wxArrayString& aNickNames,
|
|
const wxArrayString& aPaths,
|
|
const wxString& aPluginName )
|
|
{
|
|
if( aPaths.GetCount() <= 0 )
|
|
return;
|
|
|
|
// Ensure there is room for selected libs
|
|
int first_row = m_gridFpListLibs->GetTable()->GetRowsCount();
|
|
m_gridFpListLibs->AppendRows( aPaths.GetCount() );
|
|
|
|
// Populates the library list
|
|
for( unsigned ii = 0; ii < aPaths.GetCount(); ii++ )
|
|
{
|
|
int jj = first_row + ii;
|
|
// Add the nickname: currently make it from filename
|
|
m_gridFpListLibs->SetCellValue( jj, 0, aNickNames[ii] );
|
|
// Add the full path:
|
|
m_gridFpListLibs->SetCellValue( jj, 1, aPaths[ii] );
|
|
// Add the plugin name:
|
|
m_gridFpListLibs->SetCellValue( jj, 2, aPluginName );
|
|
m_gridFpListLibs->SetReadOnly( jj, 2, true );
|
|
}
|
|
|
|
m_gridFpListLibs->Fit();
|
|
}
|
|
|
|
|
|
// A helper dialog to show and select a set of directories
|
|
class DIALOG_SELECT_DIRLIST : public DIALOG_SELECT_DIRLIST_BASE
|
|
{
|
|
public:
|
|
DIALOG_SELECT_DIRLIST( wxWindow* parent,
|
|
const wxString& aDefaultPath ):
|
|
DIALOG_SELECT_DIRLIST_BASE( parent, wxID_ANY )
|
|
{
|
|
if( !aDefaultPath.IsEmpty() )
|
|
m_dirCtrl->SetPath( aDefaultPath );
|
|
|
|
Layout();
|
|
GetSizer()->Fit( this );
|
|
GetSizer()->SetSizeHints(this);
|
|
Centre();
|
|
}
|
|
|
|
~DIALOG_SELECT_DIRLIST() {};
|
|
|
|
void GetPaths( wxArrayString& aPaths ) { m_dirCtrl->GetPaths( aPaths ); }
|
|
};
|
|
|
|
void WIZARD_FPLIB_TABLE::selectLibsFolders() // select a set of library folders
|
|
{
|
|
DIALOG_SELECT_DIRLIST dlg( this, m_currLibDescr->m_DefaultPath );
|
|
|
|
if( dlg.ShowModal() != wxID_OK )
|
|
return;
|
|
|
|
wxArrayString filepaths;
|
|
|
|
dlg.GetPaths( filepaths );
|
|
|
|
// Create the nickname: currently make it from the filename
|
|
wxArrayString nicknames;
|
|
wxFileName fn;
|
|
|
|
for( unsigned ii = 0; ii < filepaths.GetCount(); ii++ )
|
|
{
|
|
fn = filepaths[ii];
|
|
nicknames.Add( fn.GetName() );
|
|
|
|
fn.AssignDir( filepaths[ii] );
|
|
|
|
if( m_currLibDescr->m_IsAbsolutePath || m_currLibDescr->m_DefaultPath.IsEmpty() )
|
|
{
|
|
filepaths[ii] = fn.GetFullPath();
|
|
}
|
|
else
|
|
{
|
|
if( ! fn.MakeRelativeTo( m_currLibDescr->m_DefaultPath ) )
|
|
filepaths[ii] = fn.GetFullPath();
|
|
else
|
|
filepaths[ii].Printf( wxT("${%s}%c%s"),
|
|
GetChars( m_currLibDescr->m_EnvVarName ),
|
|
fn.GetPathSeparator(),
|
|
GetChars( fn.GetFullPath() ) );
|
|
}
|
|
#ifdef __WINDOWS__
|
|
// We store paths using Unix notation, which also works fine on Windows
|
|
filepaths[ii].Replace( wxT("\\"), wxT("/") );
|
|
#endif
|
|
// Remove trailing path separator, if any.
|
|
if( filepaths[ii].EndsWith( wxT("/") ) )
|
|
filepaths[ii].RemoveLast();
|
|
}
|
|
|
|
populateLibList( nicknames, filepaths, m_currLibDescr->m_PluginName );
|
|
}
|
|
|
|
#ifdef KICAD_USE_WEBKIT
|
|
|
|
// A helper function to run the wen viewer (see webviewer.cpp)
|
|
extern int RunWebViewer( wxWindow * aParent, const wxString& aUrlOnStart,
|
|
wxArrayString* aUrlListSelection = NULL );
|
|
#endif
|
|
|
|
void WIZARD_FPLIB_TABLE::selectLibsGithubWithWebViewer() // select a set of library on Github
|
|
{
|
|
// A string array to store the URLs selected from the web viewer:
|
|
wxArrayString urls;
|
|
|
|
// Run the web viewer and open the default URL: the default path
|
|
// or our github library repos
|
|
wxString defaultURL = m_currLibDescr->m_DefaultPath;
|
|
|
|
if( defaultURL.IsEmpty() )
|
|
defaultURL = wxT( "https://github.com/KiCad" );
|
|
#ifdef KICAD_USE_WEBKIT
|
|
RunWebViewer( this, defaultURL, &urls );
|
|
installGithubLibsFromList( urls );
|
|
#else
|
|
urls.Add( defaultURL + wxT("newlibname.pretty") );
|
|
#endif
|
|
|
|
}
|
|
|
|
void WIZARD_FPLIB_TABLE::installGithubLibsFromList( wxArrayString& aUrlList )
|
|
{
|
|
// add the libs found in aUrlList, after calculating a nickname and
|
|
// replacing the path by an env variable, if needed
|
|
// Create the nickname: currently make it from the url
|
|
wxArrayString filepaths;
|
|
wxArrayString nicknames;
|
|
|
|
for( unsigned ii = 0; ii < aUrlList.GetCount(); ii++ )
|
|
{
|
|
wxString urlstring( aUrlList[ii] );
|
|
|
|
wxURI uri( urlstring );
|
|
|
|
// We cannot use wxURL to test the validity of the url, because
|
|
// wxURL does not know https protocol we are using, and aways returns
|
|
// error for URLs starting by https. Hope this test is enough
|
|
if( uri.HasPath() )
|
|
nicknames.Add( uri.GetPath().AfterLast( '/').BeforeLast( '.' ) );
|
|
else
|
|
continue; // Should not happen: bad URL
|
|
|
|
if( m_currLibDescr->m_IsAbsolutePath ||
|
|
m_currLibDescr->m_DefaultPath.IsEmpty() )
|
|
{
|
|
filepaths.Add( aUrlList[ii] ); // use the full URL
|
|
}
|
|
else
|
|
{
|
|
wxString shortURI;
|
|
if( aUrlList[ii].Lower().StartsWith(
|
|
m_currLibDescr->m_DefaultPath.Lower(), &shortURI ) )
|
|
{
|
|
shortURI.Prepend( wxT("${") + m_currLibDescr->m_EnvVarName + wxT("}") );
|
|
filepaths.Add( shortURI );
|
|
}
|
|
else // keep the full URL
|
|
filepaths.Add( aUrlList[ii] ); // use the full URL
|
|
}
|
|
}
|
|
|
|
populateLibList( nicknames, filepaths, m_currLibDescr->m_PluginName );
|
|
}
|
|
|
|
|
|
void WIZARD_FPLIB_TABLE::OnRemoveFpLibs( wxCommandEvent& event )
|
|
{
|
|
wxArrayInt selectedRows = m_gridFpListLibs->GetSelectedRows();
|
|
int row_cursor = m_gridFpListLibs->GetGridCursorRow();
|
|
|
|
if( selectedRows.size() == 0 && row_cursor >= 0 )
|
|
selectedRows.Add( row_cursor );
|
|
|
|
std::sort( selectedRows.begin(), selectedRows.end() );
|
|
|
|
for( int ii = selectedRows.GetCount()-1; ii >= 0; ii-- )
|
|
{
|
|
int row = selectedRows[ii];
|
|
m_gridFpListLibs->DeleteRows( row, 1 );
|
|
}
|
|
|
|
m_gridFpListLibs->SelectRow( m_gridFpListLibs->GetGridCursorRow() );
|
|
}
|
|
|
|
#ifdef BUILD_GITHUB_PLUGIN
|
|
#include <../github/github_getliblist.h>
|
|
|
|
void WIZARD_FPLIB_TABLE::OnGithubLibsList( wxCommandEvent& event )
|
|
{
|
|
wxArrayString liblist;
|
|
getLibsListGithub( liblist );
|
|
|
|
if( liblist.GetCount() == 0 ) // No lib selected
|
|
return;
|
|
|
|
if( IsKicadPlugin() )
|
|
{
|
|
wxString msg;
|
|
|
|
if( !downloadGithubLibsFromList( liblist, &msg ) )
|
|
{
|
|
wxMessageBox( msg );
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
installGithubLibsFromList( liblist );
|
|
}
|
|
|
|
void WIZARD_FPLIB_TABLE::getLibsListGithub( wxArrayString& aList )
|
|
{
|
|
wxBeginBusyCursor();
|
|
GITHUB_GETLIBLIST getter( m_textCtrlGithubURL->GetValue() );
|
|
wxEndBusyCursor();
|
|
|
|
wxArrayString fullList;
|
|
getter.GetLibraryList( fullList );
|
|
|
|
wxArrayInt choices;
|
|
wxString msg( _( "Urls detected as footprint .pretty libraries.\n"
|
|
"Selected urls will be added to the current footprint library list" ) );
|
|
|
|
if( wxGetSelectedChoices( choices, msg,
|
|
_( "Footprint libraries" ), fullList, this ) <= 0 )
|
|
return;
|
|
|
|
// Add selected url in list
|
|
for( unsigned ii = 0; ii < choices.GetCount(); ii++ )
|
|
{
|
|
wxString& url = fullList[choices[ii]];
|
|
aList.Add( url );
|
|
}
|
|
}
|
|
|
|
|
|
// 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 )
|
|
{
|
|
wxString masterFolder;
|
|
wxString default_path;
|
|
wxGetEnv( FP_LIB_TABLE::GlobalPathEnvVariableName(), &default_path );
|
|
|
|
masterFolder = wxDirSelector( _("Output Folder" ),
|
|
default_path, 0, wxDefaultPosition, this );
|
|
|
|
if( masterFolder.IsEmpty() ) // Aborted by user
|
|
{
|
|
if( aErrorMessage )
|
|
*aErrorMessage = _( "Aborted" );
|
|
|
|
return false;
|
|
}
|
|
|
|
if( !wxDirExists( masterFolder ) )
|
|
{
|
|
if( aErrorMessage )
|
|
aErrorMessage->Printf( _( "Folder '%s' does not exists" ),
|
|
GetChars( masterFolder ) );
|
|
|
|
return false;
|
|
}
|
|
|
|
// Display a progress bar to show the downlaod state
|
|
wxProgressDialog pdlg( _("Download 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( masterFolder );
|
|
libdst_name = fn.GetFullPath();
|
|
|
|
if( !wxDirExists( libdst_name ) )
|
|
wxMkdir( libdst_name );
|
|
|
|
pdlg.Update( ii, libsrc_name);
|
|
|
|
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;
|
|
}
|
|
#endif
|
|
|