Commit 9a8baa00 authored by Miguel Angel Ajo's avatar Miguel Angel Ajo

Allow plugins to be reloaded without closing/opening pcbnew, next step is...

Allow plugins to be reloaded without closing/opening pcbnew, next step is plugin editor, just a few lines away...
parent ecc6a69f
......@@ -31,11 +31,18 @@
#include "class_footprint_wizard.h"
#include <stdio.h>
FOOTPRINT_WIZARD::~FOOTPRINT_WIZARD()
{
}
void FOOTPRINT_WIZARD::register_wizard()
{
FOOTPRINT_WIZARDS::register_wizard( this );
}
std::vector<FOOTPRINT_WIZARD*> FOOTPRINT_WIZARDS::m_FootprintWizards;
FOOTPRINT_WIZARD* FOOTPRINT_WIZARDS::GetWizard( int aIndex )
......@@ -43,36 +50,54 @@ FOOTPRINT_WIZARD* FOOTPRINT_WIZARDS::GetWizard( int aIndex )
return m_FootprintWizards[aIndex];
}
FOOTPRINT_WIZARD* FOOTPRINT_WIZARDS::GetWizard( wxString aName )
{
int max = GetSize();
for( int i=0; i<max; i++ )
for( int i = 0; i<max; i++ )
{
FOOTPRINT_WIZARD *wizard = GetWizard( i );
FOOTPRINT_WIZARD* wizard = GetWizard( i );
wxString name = wizard->GetName();
if ( name.Cmp( aName ) )
if( name.Cmp( aName )==0 )
return wizard;
}
return NULL;
}
int FOOTPRINT_WIZARDS::GetSize()
{
return m_FootprintWizards.size();
}
void FOOTPRINT_WIZARDS::register_wizard(FOOTPRINT_WIZARD *aWizard)
{
void FOOTPRINT_WIZARDS::register_wizard( FOOTPRINT_WIZARD* aWizard )
{
wxString name = aWizard->GetName();
m_FootprintWizards.push_back( aWizard );
m_FootprintWizards.push_back( aWizard );
}
bool FOOTPRINT_WIZARDS::deregister_object( void* aObject )
{
int max = GetSize();
for( int i = 0; i<max; i++ )
{
FOOTPRINT_WIZARD* wizard = GetWizard( i );
if( wizard->GetObject() == aObject )
{
m_FootprintWizards.erase( m_FootprintWizards.begin() + i );
delete wizard;
return true;
}
}
return false;
}
......@@ -39,48 +39,47 @@
* derive */
class FOOTPRINT_WIZARD
{
public:
FOOTPRINT_WIZARD() {}
~FOOTPRINT_WIZARD() {}
virtual ~FOOTPRINT_WIZARD();
/**
* Function GetName
* @return the name of the wizard
*/
virtual wxString GetName()=0;
virtual wxString GetName() = 0;
/**
* Function GetImage
* @return an svg image of the wizard to be rendered
*/
virtual wxString GetImage()=0;
virtual wxString GetImage() = 0;
/**
* Function GetDescription
* @return a description of the footprint wizard
*/
virtual wxString GetDescription()=0;
virtual wxString GetDescription() = 0;
/**
* Function GetNumParameterPages
* @return the number of parameter pages that this wizard will show to the user
*/
virtual int GetNumParameterPages()=0;
virtual int GetNumParameterPages() = 0;
/**
* Function GetParameterPageName
* @param aPage is the page we want the name of
* @return a string with the page name
*/
virtual wxString GetParameterPageName(int aPage)=0;
virtual wxString GetParameterPageName( int aPage ) = 0;
/**
* Function GetParameterNames
* @param aPage is the page we want the parameter names of
* @return an array string with the parameter names on a certain page
*/
virtual wxArrayString GetParameterNames(int aPage)=0;
virtual wxArrayString GetParameterNames( int aPage ) = 0;
/**
* Function GetParameterTypes
......@@ -88,7 +87,7 @@ public:
* @return an array string with the parameter types on a certain page
* "IU" for internal units, "UNITS" for units (0,1,2,3...,N)
*/
virtual wxArrayString GetParameterTypes(int aPage)=0;
virtual wxArrayString GetParameterTypes( int aPage ) = 0;
/**
......@@ -96,14 +95,14 @@ public:
* @param aPage is the page we want the parameter values of
* @return an array of parameter values
*/
virtual wxArrayString GetParameterValues(int aPage)=0;
virtual wxArrayString GetParameterValues( int aPage ) = 0;
/**
* Function GetParameterErrors
* @param aPage is the page we want to know the errors of
* @return an array of errors (if any) for the parameters, empty strings for OK parameters
*/
virtual wxArrayString GetParameterErrors(int aPage)=0;
virtual wxArrayString GetParameterErrors( int aPage ) = 0;
/**
* Function SetParameterValues
......@@ -111,14 +110,21 @@ public:
* @param aValues are the values we want to set into the parameters
* @return an array of parameter values
*/
virtual wxString SetParameterValues(int aPage,wxArrayString& aValues)=0;
virtual wxString SetParameterValues( int aPage, wxArrayString& aValues ) = 0;
/**
* Function GetModule
* This method builds the module itself and returns it to the caller function
* @return PCB module built from the parameters given to the class
*/
virtual MODULE *GetModule()=0;
virtual MODULE* GetModule() = 0;
/**
* Function GetObject
* This method gets the pointer to the object from where this wizard constructs
* @return it's a void pointer, as it could be a PyObject or any other
*/
virtual void* GetObject() = 0;
/**
* Function register_wizard
......@@ -127,7 +133,6 @@ public:
*
*/
void register_wizard();
};
......@@ -138,7 +143,6 @@ private:
* FOOTPRINT_WIZARD system wide static list
*/
static std::vector<FOOTPRINT_WIZARD*> m_FootprintWizards;
public:
/**
......@@ -149,7 +153,18 @@ public:
* @param aWizard is the footprint wizard to be registered
*
*/
static void register_wizard(FOOTPRINT_WIZARD *aWizard);
static void register_wizard( FOOTPRINT_WIZARD* aWizard );
/**
* Function deregister_object
* Anyone calls this method to deregister an object which builds a wizard,
* it will lookup on the vector calling GetObject until find, then removed
* and deleted
*
* @param aObject is the footprint wizard object to be deregistered
*
*/
static bool deregister_object( void* aObject );
/**
* Function GetWizard
......@@ -157,7 +172,7 @@ public:
* @return a wizard object by it's name or NULL if it isn't available.
*
*/
static FOOTPRINT_WIZARD* GetWizard(wxString aName);
static FOOTPRINT_WIZARD* GetWizard( wxString aName );
/**
* Function GetWizard
......@@ -172,8 +187,6 @@ public:
* @return the number of wizards available into the system
*/
static int GetSize();
};
#endif /* PCBNEW_FOOTPRINT_WIZARDS_H */
......@@ -94,13 +94,15 @@ void FOOTPRINT_WIZARD_FRAME::DisplayWizardInfos()
void FOOTPRINT_WIZARD_FRAME::ReloadFootprint()
{
if( m_FootprintWizard == NULL )
FOOTPRINT_WIZARD* footprintWizard = GetMyWizard();
if( !footprintWizard )
return;
SetCurItem( NULL );
// Delete the current footprint
GetBoard()->m_Modules.DeleteAll();
MODULE* m = m_FootprintWizard->GetModule();
MODULE* m = footprintWizard->GetModule();
if( m )
{
......@@ -112,18 +114,37 @@ void FOOTPRINT_WIZARD_FRAME::ReloadFootprint()
}
else
{
printf( "m_FootprintWizard->GetModule() returns NULL\n" );
printf( "footprintWizard->GetModule() returns NULL\n" );
}
m_canvas->Refresh();
}
FOOTPRINT_WIZARD* FOOTPRINT_WIZARD_FRAME::GetMyWizard()
{
if( m_wizardName.Length()==0 )
return NULL;
FOOTPRINT_WIZARD* footprintWizard = FOOTPRINT_WIZARDS::GetWizard( m_wizardName );
if( !footprintWizard )
{
wxMessageBox( _( "Couldn't reload footprint wizard" ) );
return NULL;
}
return footprintWizard;
}
MODULE* FOOTPRINT_WIZARD_FRAME::GetBuiltFootprint()
{
if( m_FootprintWizard )
FOOTPRINT_WIZARD* footprintWizard = FOOTPRINT_WIZARDS::GetWizard( m_wizardName );
if( footprintWizard )
{
return m_FootprintWizard->GetModule();
return footprintWizard->GetModule();
}
else
{
......@@ -139,12 +160,17 @@ void FOOTPRINT_WIZARD_FRAME::SelectFootprintWizard()
selectWizard->ShowModal();
m_FootprintWizard = selectWizard->GetWizard();
FOOTPRINT_WIZARD* footprintWizard = selectWizard->GetWizard();
if( m_FootprintWizard )
if( footprintWizard )
{
m_wizardName = m_FootprintWizard->GetName();
m_wizardDescription = m_FootprintWizard->GetDescription();
m_wizardName = footprintWizard->GetName();
m_wizardDescription = footprintWizard->GetDescription();
}
else
{
m_wizardName = wxT( "" );
m_wizardDescription = wxT( "" );
}
ReloadFootprint();
......@@ -169,12 +195,17 @@ void FOOTPRINT_WIZARD_FRAME::ParametersUpdated( wxGridEvent& event )
{
int page = m_PageList->GetSelection();
FOOTPRINT_WIZARD* footprintWizard = GetMyWizard();
if( !footprintWizard )
return;
if( page<0 )
return;
int n = m_ParameterGrid->GetNumberRows();
wxArrayString arr;
wxArrayString ptList = m_FootprintWizard->GetParameterTypes( page );
wxArrayString ptList = footprintWizard->GetParameterTypes( page );
for( int i = 0; i<n; i++ )
{
......@@ -205,7 +236,7 @@ void FOOTPRINT_WIZARD_FRAME::ParametersUpdated( wxGridEvent& event )
arr.Add( value );
}
wxString res = m_FootprintWizard->SetParameterValues( page, arr );
wxString res = footprintWizard->SetParameterValues( page, arr );
ReloadFootprint();
DisplayWizardInfos();
......
......@@ -52,37 +52,39 @@
BEGIN_EVENT_TABLE( FOOTPRINT_WIZARD_FRAME, EDA_DRAW_FRAME )
/* Window events */
EVT_CLOSE( FOOTPRINT_WIZARD_FRAME::OnCloseWindow )
EVT_SIZE( FOOTPRINT_WIZARD_FRAME::OnSize )
EVT_ACTIVATE( FOOTPRINT_WIZARD_FRAME::OnActivate )
/* Window events */
EVT_CLOSE( FOOTPRINT_WIZARD_FRAME::OnCloseWindow )
EVT_SIZE( FOOTPRINT_WIZARD_FRAME::OnSize )
EVT_ACTIVATE( FOOTPRINT_WIZARD_FRAME::OnActivate )
/* Sash drag events */
EVT_SASH_DRAGGED( ID_FOOTPRINT_WIZARD_PAGES, FOOTPRINT_WIZARD_FRAME::OnSashDrag )
EVT_SASH_DRAGGED( ID_FOOTPRINT_WIZARD_PARAMETERS, FOOTPRINT_WIZARD_FRAME::OnSashDrag )
/* Sash drag events */
EVT_SASH_DRAGGED( ID_FOOTPRINT_WIZARD_PAGES, FOOTPRINT_WIZARD_FRAME::OnSashDrag )
EVT_SASH_DRAGGED( ID_FOOTPRINT_WIZARD_PARAMETERS, FOOTPRINT_WIZARD_FRAME::OnSashDrag )
/* Toolbar events */
EVT_TOOL( ID_FOOTPRINT_WIZARD_SELECT_WIZARD,
/* Toolbar events */
EVT_TOOL( ID_FOOTPRINT_WIZARD_SELECT_WIZARD,
FOOTPRINT_WIZARD_FRAME::SelectCurrentWizard )
EVT_TOOL( ID_FOOTPRINT_WIZARD_NEXT,
EVT_TOOL( ID_FOOTPRINT_WIZARD_NEXT,
FOOTPRINT_WIZARD_FRAME::Process_Special_Functions )
EVT_TOOL( ID_FOOTPRINT_WIZARD_PREVIOUS,
EVT_TOOL( ID_FOOTPRINT_WIZARD_PREVIOUS,
FOOTPRINT_WIZARD_FRAME::Process_Special_Functions )
EVT_TOOL( ID_FOOTPRINT_WIZARD_DONE,
EVT_TOOL( ID_FOOTPRINT_WIZARD_DONE,
FOOTPRINT_WIZARD_FRAME::ExportSelectedFootprint )
EVT_TOOL( ID_FOOTPRINT_WIZARD_SHOW_3D_VIEW,
EVT_TOOL( ID_FOOTPRINT_WIZARD_SHOW_3D_VIEW,
FOOTPRINT_WIZARD_FRAME::Show3D_Frame )
/* listbox events */
EVT_LISTBOX( ID_FOOTPRINT_WIZARD_PAGE_LIST, FOOTPRINT_WIZARD_FRAME::ClickOnPageList )
EVT_GRID_CMD_CELL_CHANGE( ID_FOOTPRINT_WIZARD_PARAMETER_LIST,
/* listbox events */
EVT_LISTBOX( ID_FOOTPRINT_WIZARD_PAGE_LIST, FOOTPRINT_WIZARD_FRAME::ClickOnPageList )
EVT_GRID_CMD_CELL_CHANGE( ID_FOOTPRINT_WIZARD_PARAMETER_LIST,
FOOTPRINT_WIZARD_FRAME::ParametersUpdated )
EVT_GRID_CMD_EDITOR_HIDDEN( ID_FOOTPRINT_WIZARD_PARAMETER_LIST,
FOOTPRINT_WIZARD_FRAME::ParametersUpdated )
EVT_MENU( ID_SET_RELATIVE_OFFSET, FOOTPRINT_WIZARD_FRAME::OnSetRelativeOffset )
EVT_MENU( ID_SET_RELATIVE_OFFSET, FOOTPRINT_WIZARD_FRAME::OnSetRelativeOffset )
END_EVENT_TABLE()
......@@ -131,7 +133,6 @@ FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( FOOTPRINT_EDIT_FRAME* parent,
// SetIcon( icon );
m_HotkeysZoomAndGridList = g_Module_Viewer_Hokeys_Descr;
m_FootprintWizard = NULL;
m_PageList = NULL;
m_ParameterGrid = NULL;
m_PageListWindow = NULL;
......@@ -386,15 +387,18 @@ void FOOTPRINT_WIZARD_FRAME::ReCreatePageList()
if( m_PageList == NULL )
return;
if( m_FootprintWizard == NULL )
FOOTPRINT_WIZARD* footprintWizard = GetMyWizard();
if( !footprintWizard )
return;
m_PageList->Clear();
int max_page = m_FootprintWizard->GetNumParameterPages();
int max_page = footprintWizard->GetNumParameterPages();
for( int i = 0; i<max_page; i++ )
{
wxString name = m_FootprintWizard->GetParameterPageName( i );
wxString name = footprintWizard->GetParameterPageName( i );
m_PageList->Append( name );
}
......@@ -417,7 +421,9 @@ void FOOTPRINT_WIZARD_FRAME::ReCreateParameterList()
if( m_ParameterGrid == NULL )
return;
if( m_FootprintWizard == NULL )
FOOTPRINT_WIZARD* footprintWizard = GetMyWizard();
if( footprintWizard == NULL )
return;
int page = m_PageList->GetSelection();
......@@ -435,9 +441,9 @@ void FOOTPRINT_WIZARD_FRAME::ReCreateParameterList()
m_ParameterGrid->SetRowLabelAlignment( wxALIGN_CENTRE, wxALIGN_CENTRE );
// Get the list of names, values, and types
wxArrayString fpList = m_FootprintWizard->GetParameterNames( page );
wxArrayString fvList = m_FootprintWizard->GetParameterValues( page );
wxArrayString ptList = m_FootprintWizard->GetParameterTypes( page );
wxArrayString fpList = footprintWizard->GetParameterNames( page );
wxArrayString fvList = footprintWizard->GetParameterValues( page );
wxArrayString ptList = footprintWizard->GetParameterTypes( page );
// Dimension the wxGrid
m_ParameterGrid->DeleteRows( 0, m_ParameterGrid->GetNumberRows() );
......
......@@ -60,8 +60,6 @@ private:
// Flags
wxSemaphore* m_Semaphore; // < != NULL if the frame must emulate a modal dialog
wxString m_configPath; // < subpath for configuration
FOOTPRINT_WIZARD* m_FootprintWizard;
protected:
wxString m_wizardName; // < name of the current wizard
wxString m_wizardDescription; // < description of the wizard
......@@ -118,6 +116,12 @@ private:
*/
void ReloadFootprint();
/**
* Function GetMyWizard
* Reloads the wizard by name
*/
FOOTPRINT_WIZARD* GetMyWizard();
void Process_Special_Functions( wxCommandEvent& event );
......
......@@ -53,6 +53,7 @@ PyObject* PYTHON_FOOTPRINT_WIZARD::CallMethod( const char* aMethod, PyObject* aA
{
PyLOCK lock;
PyErr_Clear();
// pFunc is a new reference to the desired method
PyObject* pFunc = PyObject_GetAttrString( this->m_PyWizard, aMethod );
......@@ -79,6 +80,8 @@ PyObject* PYTHON_FOOTPRINT_WIZARD::CallMethod( const char* aMethod, PyObject* aA
wxMessageBox( message,
wxT( "Exception on python footprint wizard code" ),
wxICON_ERROR | wxOK );
PyErr_Clear();
}
if( result )
......@@ -346,7 +349,10 @@ MODULE* PYTHON_FOOTPRINT_WIZARD::GetModule()
PyObject* obj = PyObject_GetAttrString( result, "this" );
if( PyErr_Occurred() )
{
PyErr_Print();
PyErr_Clear();
}
MODULE* mod = PyModule_to_MODULE( obj );
......@@ -354,9 +360,22 @@ MODULE* PYTHON_FOOTPRINT_WIZARD::GetModule()
}
void* PYTHON_FOOTPRINT_WIZARD::GetObject()
{
return (void*) m_PyWizard;
}
void PYTHON_FOOTPRINT_WIZARDS::register_wizard( PyObject* aPyWizard )
{
PYTHON_FOOTPRINT_WIZARD* fw = new PYTHON_FOOTPRINT_WIZARD( aPyWizard );
fw->register_wizard();
}
void PYTHON_FOOTPRINT_WIZARDS::deregister_wizard( PyObject* aPyWizard )
{
// deregister also destroyes the previously created "PYTHON_FOOTPRINT_WIZARD object"
FOOTPRINT_WIZARDS::deregister_object( (void*) aPyWizard );
}
......@@ -56,6 +56,7 @@ public:
wxArrayString GetParameterErrors( int aPage );
wxString SetParameterValues( int aPage, wxArrayString& aValues ); // < must return "OK" or error description
MODULE* GetModule();
void* GetObject();
};
......@@ -63,6 +64,7 @@ class PYTHON_FOOTPRINT_WIZARDS
{
public:
static void register_wizard( PyObject* aPyWizard );
static void deregister_wizard( PyObject* aPyWizard );
};
#endif /* PCBNEW_FOOTPRINT_WIZARDS_H */
......@@ -30,5 +30,6 @@ class PYTHON_FOOTPRINT_WIZARDS
{
public:
static void register_wizard(PyObject *wizard);
static void deregister_wizard(PyObject *wizard);
};
......@@ -41,37 +41,59 @@
%pythoncode
{
KICAD_PLUGINS={}
def ReloadPlugin(name):
if not KICAD_PLUGINS.has_key(name):
return False
KICAD_PLUGINS[name]["wizard"].deregister()
mod = reload(KICAD_PLUGINS[name]["module"])
KICAD_PLUGINS[name]["wizard"]= mod.register()
def LoadPlugins():
import os
import sys
# Use environment variable KICAD_PATH to derive path to plugins as a temporary solution
kicad_path = os.environ.get('KICAD_PATH')
plugin_directories=[]
if kicad_path and os.path.isdir(kicad_path):
plugin_directories.append(os.path.join(kicad_path, 'scripting', 'plugins'))
if sys.platform.startswith('linux'):
if sys.platform.startswith('linux') or sys.platform.startswith('darwin'):
plugin_directories.append(os.environ['HOME']+'/.kicad_plugins/')
plugin_directories.append(os.environ['HOME']+'/.kicad/scripting/plugins/')
# scan all possible directories for plugins, and load them
for plugins_dir in plugin_directories:
sys.path.append(plugins_dir)
if not os.path.isdir(plugins_dir):
continue
for module in os.listdir(plugins_dir):
if os.path.isdir(plugins_dir+module):
__import__(module, locals(), globals())
if module == '__init__.py' or module[-3:] != '.py':
continue
__import__(module[:-3], locals(), globals())
mod = __import__(module[:-3], locals(), globals())
if hasattr(mod,'register'):
KICAD_PLUGINS[module]={"filename":plugins_dir+"/"+module,
"wizard":mod.register(),
"module":mod}
# KiCadPlugin base class will register any plugin into the right place
class KiCadPlugin:
def __init__(self):
pass
......@@ -88,16 +110,27 @@ class KiCadPlugin:
return
def deregister(self):
if isinstance(self,FilePlugin):
pass # register to file plugins in C++
if isinstance(self,FootprintWizardPlugin):
PYTHON_FOOTPRINT_WIZARDS.deregister_wizard(self)
return
if isinstance(self,ActionPlugin):
pass # register to action plugins in C++
return
# This will be the file io scripting based plugins class
class FilePlugin(KiCadPlugin):
def __init__(self):
KiCadPlugin.__init__(self)
# Scriping footprint wizards
class FootprintWizardPlugin(KiCadPlugin):
def __init__(self):
KiCadPlugin.__init__(self)
......@@ -164,7 +197,7 @@ class FootprintWizardPlugin(KiCadPlugin):
print "[%s][%s]<="%(name,key),val
n+=1
# copies the parameter list on parameter_errors but empty
def ClearErrors(self):
errs={}
......@@ -203,6 +236,4 @@ class ActionPlugin(KiCadPlugin):
def __init__(self):
KiCadPlugin.__init__(self)
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment