962 lines
31 KiB
C++
962 lines
31 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( WIZARD_LAST_PLUGIN_KEY, &m_last_plugin_choice );
|
|
cfg->Read( WIZARD_LAST_PATHOPTION_KEY, &m_last_defaultpath_choice );
|
|
cfg->Read( KICAD_FPLIBS_URL_KEY, &msg );
|
|
|
|
if( msg.IsEmpty() ) // Give our current KiCad github URL
|
|
msg = wxT( "http://github.com/KiCad" );
|
|
|
|
// Be sure there is no trailing '/' at the end of the repo name
|
|
if( msg.EndsWith( wxT("/" ) ) )
|
|
msg.RemoveLast();
|
|
|
|
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 );
|
|
#else
|
|
// If the Web Viewer is not available, just add a template
|
|
// to the fp lib table.
|
|
// The user have to edit it
|
|
urls.Add( defaultURL + wxT("/newlibname.pretty") );
|
|
#endif
|
|
installGithubLibsFromList( urls );
|
|
}
|
|
|
|
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();
|
|
|
|
// 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 );
|
|
|
|
wxArrayString fullList;
|
|
getter.GetLibraryList( fullList );
|
|
|
|
wxEndBusyCursor();
|
|
|
|
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( _("Choose Folder to Copy Downloaded '.pretty' Libraries" ),
|
|
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
|
|
|