Fix KIWAY_PLAYER::ShowModal: the top level windows children of the KIWAY_PLAYER Modal frame are now enabled (previously were disabled). It fix some issues for instance with the aui toolbar when moved, and the dialog open when starting the footprint wizard frame. Perhaps also explains a few other bugs in modal mode.

footprint wizard frame: now shows messages from footprints python scripts. Especially usefull when a parameter is incorrect. Fix also an other issue (IO exception error) with some python scripts when they are usin a  print command to output messages (now they use the new message window.
This commit is contained in:
jean-pierre charras 2015-09-05 16:47:16 +02:00
commit 7995f0e7de
14 changed files with 236 additions and 68 deletions

View File

@ -115,6 +115,8 @@ if( NOT DEFAULT_INSTALL_PATH )
"Location of KiCad data files." ) "Location of KiCad data files." )
endif() endif()
message( STATUS "Kicad install dir: <${DEFAULT_INSTALL_PATH}>" )
# Generate build system specific header file. # Generate build system specific header file.
include( PerformFeatureChecks ) include( PerformFeatureChecks )
perform_feature_checks() perform_feature_checks()
@ -334,10 +336,17 @@ set( KIFACE_PREFIX "_" )
#================================================ #================================================
if( NOT APPLE ) if( NOT APPLE )
# Everything without leading / is relative to CMAKE_INSTALL_PREFIX. # Everything without leading / is relative to CMAKE_INSTALL_PREFIX.
set( KICAD_BIN bin set( KICAD_BIN ${CMAKE_INSTALL_PREFIX}/bin
CACHE PATH "Location of KiCad binaries." ) CACHE PATH "Location of KiCad binaries." )
if( WIN32 )
set( KICAD_PLUGINS ${KICAD_BIN}/scripting/plugins
CACHE PATH "Location of KiCad plugins." )
else()
set( KICAD_PLUGINS lib/kicad/plugins set( KICAD_PLUGINS lib/kicad/plugins
CACHE PATH "Location of KiCad plugins." ) CACHE PATH "Location of KiCad plugins." )
endif()
set( KICAD_DATA share/kicad set( KICAD_DATA share/kicad
CACHE PATH "Location of KiCad data files." ) CACHE PATH "Location of KiCad data files." )
set( KICAD_DOCS share/doc/kicad set( KICAD_DOCS share/doc/kicad

View File

@ -106,14 +106,32 @@ bool KIWAY_PLAYER::ShowModal( wxString* aResult, wxWindow* aResultantFocusWindow
SetFocus(); SetFocus();
{ {
// exception safe way to disable all frames except the modal one, // We have to disable all frames but the the modal one.
// wxWindowDisabler does that, but remember it disables all top level windows
// We do not want to disable top level windows which are child off the modal one,
// if they are enabled.
// An example is an aui toolbar which was moved
// or a dialog or an other frame or miniframe opened by the modal one.
wxWindowList wlist = GetChildren();
std::vector<wxWindow*> enabledTopLevelWindows;
for( unsigned ii = 0; ii < wlist.size(); ii++ )
if( wlist[ii]->IsTopLevel() && wlist[ii]->IsEnabled() )
enabledTopLevelWindows.push_back( wlist[ii] );
// exception safe way to disable all top level windows except the modal one,
// re-enables only those that were disabled on exit // re-enables only those that were disabled on exit
wxWindowDisabler toggle( this ); wxWindowDisabler toggle( this );
// Reenable top level windows which are child of the modal one:
for( unsigned ii = 0; ii < wlist.size(); ii++ )
for( unsigned ii = 0; ii < enabledTopLevelWindows.size(); ii++ )
enabledTopLevelWindows[ii]->Enable( true );
WX_EVENT_LOOP event_loop; WX_EVENT_LOOP event_loop;
m_modal_loop = &event_loop; m_modal_loop = &event_loop;
event_loop.Run(); event_loop.Run();
} // End of scop for some variables. } // End of scop for some variables.

View File

@ -248,7 +248,7 @@ PCB_CALCULATOR_FRAME_BASE::PCB_CALCULATOR_FRAME_BASE( wxWindow* parent, wxWindow
m_panelRegulators->SetSizer( bSizerMainReg ); m_panelRegulators->SetSizer( bSizerMainReg );
m_panelRegulators->Layout(); m_panelRegulators->Layout();
bSizerMainReg->Fit( m_panelRegulators ); bSizerMainReg->Fit( m_panelRegulators );
m_Notebook->AddPage( m_panelRegulators, _("Regulators"), true ); m_Notebook->AddPage( m_panelRegulators, _("Regulators"), false );
m_panelTrackWidth = new wxPanel( m_Notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); m_panelTrackWidth = new wxPanel( m_Notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizerTrackWidth; wxBoxSizer* bSizerTrackWidth;
bSizerTrackWidth = new wxBoxSizer( wxHORIZONTAL ); bSizerTrackWidth = new wxBoxSizer( wxHORIZONTAL );
@ -317,7 +317,7 @@ PCB_CALCULATOR_FRAME_BASE::PCB_CALCULATOR_FRAME_BASE( wxWindow* parent, wxWindow
sbSizerTW_Prms->Add( fgSizerTWprms, 0, wxEXPAND, 5 ); sbSizerTW_Prms->Add( fgSizerTWprms, 0, wxEXPAND, 5 );
bSizeLeft->Add( sbSizerTW_Prms, 1, wxALL|wxEXPAND, 5 ); bSizeLeft->Add( sbSizerTW_Prms, 0, wxALL|wxEXPAND, 5 );
m_htmlWinFormulas = new wxHtmlWindow( m_panelTrackWidth, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_NO_SELECTION|wxHW_SCROLLBAR_AUTO|wxSIMPLE_BORDER ); m_htmlWinFormulas = new wxHtmlWindow( m_panelTrackWidth, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_NO_SELECTION|wxHW_SCROLLBAR_AUTO|wxSIMPLE_BORDER );
m_htmlWinFormulas->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) ); m_htmlWinFormulas->SetForegroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_WINDOW ) );
@ -516,7 +516,7 @@ PCB_CALCULATOR_FRAME_BASE::PCB_CALCULATOR_FRAME_BASE( wxWindow* parent, wxWindow
m_panelTrackWidth->SetSizer( bSizerTrackWidth ); m_panelTrackWidth->SetSizer( bSizerTrackWidth );
m_panelTrackWidth->Layout(); m_panelTrackWidth->Layout();
bSizerTrackWidth->Fit( m_panelTrackWidth ); bSizerTrackWidth->Fit( m_panelTrackWidth );
m_Notebook->AddPage( m_panelTrackWidth, _("Track Width"), false ); m_Notebook->AddPage( m_panelTrackWidth, _("Track Width"), true );
m_panelElectricalSpacing = new wxPanel( m_Notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL ); m_panelElectricalSpacing = new wxPanel( m_Notebook, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
wxBoxSizer* bSizerElectricalClearance; wxBoxSizer* bSizerElectricalClearance;
bSizerElectricalClearance = new wxBoxSizer( wxHORIZONTAL ); bSizerElectricalClearance = new wxBoxSizer( wxHORIZONTAL );

View File

@ -270,7 +270,7 @@
<object class="notebookpage" expanded="1"> <object class="notebookpage" expanded="1">
<property name="bitmap"></property> <property name="bitmap"></property>
<property name="label">Regulators</property> <property name="label">Regulators</property>
<property name="select">1</property> <property name="select">0</property>
<object class="wxPanel" expanded="1"> <object class="wxPanel" expanded="1">
<property name="BottomDockable">1</property> <property name="BottomDockable">1</property>
<property name="LeftDockable">1</property> <property name="LeftDockable">1</property>
@ -3267,7 +3267,7 @@
<object class="notebookpage" expanded="1"> <object class="notebookpage" expanded="1">
<property name="bitmap"></property> <property name="bitmap"></property>
<property name="label">Track Width</property> <property name="label">Track Width</property>
<property name="select">0</property> <property name="select">1</property>
<object class="wxPanel" expanded="1"> <object class="wxPanel" expanded="1">
<property name="BottomDockable">1</property> <property name="BottomDockable">1</property>
<property name="LeftDockable">1</property> <property name="LeftDockable">1</property>
@ -3359,7 +3359,7 @@
<object class="sizeritem" expanded="0"> <object class="sizeritem" expanded="0">
<property name="border">5</property> <property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property> <property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">1</property> <property name="proportion">0</property>
<object class="wxStaticBoxSizer" expanded="1"> <object class="wxStaticBoxSizer" expanded="1">
<property name="id">wxID_ANY</property> <property name="id">wxID_ANY</property>
<property name="label">Parameters</property> <property name="label">Parameters</property>

View File

@ -116,8 +116,10 @@ public:
* Function GetModule * Function GetModule
* This method builds the module itself and returns it to the caller function * This method builds the module itself and returns it to the caller function
* @return PCB module built from the parameters given to the class * @return PCB module built from the parameters given to the class
* @param aMessage a wxString to store messages (if any) generated by the
* footprint generator
*/ */
virtual MODULE* GetModule() = 0; virtual MODULE* GetFootprint( wxString* aMessage ) = 0;
/** /**
* Function GetObject * Function GetObject

View File

@ -101,7 +101,9 @@ void FOOTPRINT_WIZARD_FRAME::ReloadFootprint()
GetBoard()->m_Modules.DeleteAll(); GetBoard()->m_Modules.DeleteAll();
// Creates the module // Creates the module
MODULE* module = footprintWizard->GetModule(); wxString msg;
MODULE* module = footprintWizard->GetFootprint( &msg );
DisplayBuildMessage( msg );
if( module ) if( module )
{ {
@ -111,13 +113,22 @@ void FOOTPRINT_WIZARD_FRAME::ReloadFootprint()
} }
else else
{ {
DBG(printf( "footprintWizard->GetModule() returns NULL\n" );) DBG(printf( "footprintWizard->GetFootprint() returns NULL\n" );)
} }
m_canvas->Refresh(); m_canvas->Refresh();
} }
void FOOTPRINT_WIZARD_FRAME::DisplayBuildMessage( wxString& aMessage )
{
m_messagesFrame->ClearScreen();
if( !aMessage.IsEmpty() )
m_messagesFrame->PrintMessage( aMessage );
}
FOOTPRINT_WIZARD* FOOTPRINT_WIZARD_FRAME::GetMyWizard() FOOTPRINT_WIZARD* FOOTPRINT_WIZARD_FRAME::GetMyWizard()
{ {
if( m_wizardName.Length() == 0 ) if( m_wizardName.Length() == 0 )
@ -141,7 +152,11 @@ MODULE* FOOTPRINT_WIZARD_FRAME::GetBuiltFootprint()
if( footprintWizard && m_modal_ret_val ) if( footprintWizard && m_modal_ret_val )
{ {
return footprintWizard->GetModule(); wxString msg;
MODULE * footprint = footprintWizard->GetFootprint( &msg );
DisplayBuildMessage( msg );
return footprint;
} }
return NULL; return NULL;

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application. * This program source code file is part of KiCad, a free EDA CAD application.
* *
* Copyright (C) 2012-2015 Miguel Angel Ajo Pelayo <miguelangel@nbee.es> * Copyright (C) 2012-2015 Miguel Angel Ajo Pelayo <miguelangel@nbee.es>
* Copyright (C) 2012-2015 Jean-Pierre Charras, jaen-pierre.charras * Copyright (C) 2012-2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2008-2015 Wayne Stambaugh <stambaughw@verizon.net> * Copyright (C) 2008-2015 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors. * Copyright (C) 2004-2015 KiCad Developers, see change_log.txt for contributors.
* *
@ -207,7 +207,11 @@ FOOTPRINT_WIZARD_FRAME::FOOTPRINT_WIZARD_FRAME( KIWAY* aKiway,
Zoom_Automatique( false ); Zoom_Automatique( false );
#endif #endif
// Prepare the window to display the message generated by the footprint script builder
m_messagesFrame = new FOOTPRINT_WIZARD_MESSAGES( this, config() );
Show( true ); Show( true );
m_messagesFrame->Show( true );
SelectFootprintWizard(); SelectFootprintWizard();
} }
@ -222,6 +226,9 @@ FOOTPRINT_WIZARD_FRAME::~FOOTPRINT_WIZARD_FRAME()
void FOOTPRINT_WIZARD_FRAME::OnCloseWindow( wxCloseEvent& Event ) void FOOTPRINT_WIZARD_FRAME::OnCloseWindow( wxCloseEvent& Event )
{ {
if( m_messagesFrame )
m_messagesFrame->CloseMessagesWindow();
if( IsModal() ) if( IsModal() )
{ {
// Only dismiss a modal frame once, so that the return values set by // Only dismiss a modal frame once, so that the return values set by
@ -382,8 +389,8 @@ void FOOTPRINT_WIZARD_FRAME::ClickOnPageList( wxCommandEvent& event )
} }
#define PARTLIST_WIDTH_KEY wxT( "Partlist_width" ) #define PARTLIST_WIDTH_KEY wxT( "Fpwizard_Partlist_width" )
#define PARAMLIST_WIDTH_KEY wxT( "Paramlist_width" ) #define PARAMLIST_WIDTH_KEY wxT( "Fpwizard_Paramlist_width" )
void FOOTPRINT_WIZARD_FRAME::LoadSettings( wxConfigBase* aCfg ) void FOOTPRINT_WIZARD_FRAME::LoadSettings( wxConfigBase* aCfg )
@ -407,7 +414,7 @@ void FOOTPRINT_WIZARD_FRAME::SaveSettings( wxConfigBase* aCfg )
EDA_DRAW_FRAME::SaveSettings( aCfg ); EDA_DRAW_FRAME::SaveSettings( aCfg );
aCfg->Write( PARTLIST_WIDTH_KEY, m_pageList->GetSize().x ); aCfg->Write( PARTLIST_WIDTH_KEY, m_pageList->GetSize().x );
aCfg->Write( PARAMLIST_WIDTH_KEY, m_parameterGrid->GetSize().x ); aCfg->Write( PARAMLIST_WIDTH_KEY, m_parameterGridWidth );
} }
@ -614,3 +621,83 @@ void FOOTPRINT_WIZARD_FRAME::ReCreateVToolbar()
{ {
// Currently, there is no vertical toolbar // Currently, there is no vertical toolbar
} }
// frame to display messages from footprint builder scripts
FOOTPRINT_WIZARD_MESSAGES::FOOTPRINT_WIZARD_MESSAGES( FOOTPRINT_WIZARD_FRAME* aParent, wxConfigBase* aCfg ) :
wxMiniFrame( aParent, wxID_ANY, _( "Footprint Builder Messages" ),
wxDefaultPosition, wxDefaultSize,
wxCAPTION | wxRESIZE_BORDER | wxFRAME_FLOAT_ON_PARENT )
{
wxBoxSizer* bSizer = new wxBoxSizer( wxVERTICAL );
SetSizer( bSizer );
m_messageWindow = new wxTextCtrl( this, wxID_ANY, wxEmptyString,
wxDefaultPosition, wxDefaultSize,
wxTE_MULTILINE|wxTE_READONLY );
bSizer->Add( m_messageWindow, 1, wxEXPAND, 0 );
m_config = aCfg;
LoadSettings();
SetSize( m_position.x, m_position.y, m_size.x, m_size.y );
m_messageWindow->SetMinSize( wxSize( 350, 250 ) );
Layout();
bSizer->SetSizeHints( this );
}
void FOOTPRINT_WIZARD_MESSAGES::CloseMessagesWindow()
{
if( !IsIconized() )
{
m_position = GetPosition();
m_size = GetSize();
}
SaveSettings();
Close();
}
FOOTPRINT_WIZARD_MESSAGES::~FOOTPRINT_WIZARD_MESSAGES()
{
}
void FOOTPRINT_WIZARD_MESSAGES::PrintMessage( const wxString& aMessage )
{
m_messageWindow->SetValue( aMessage );
}
void FOOTPRINT_WIZARD_MESSAGES::ClearScreen()
{
m_messageWindow->Clear();
}
#define MESSAGE_BOX_POSX_KEY wxT( "Fpwizard_Msg_PosX" )
#define MESSAGE_BOX_POSY_KEY wxT( "Fpwizard_Msg_PosY" )
#define MESSAGE_BOX_SIZEX_KEY wxT( "Fpwizard_Msg_SIZEX" )
#define MESSAGE_BOX_SIZEY_KEY wxT( "Fpwizard_Msg_SIZEY" )
void FOOTPRINT_WIZARD_MESSAGES::SaveSettings()
{
m_config->Write( MESSAGE_BOX_POSX_KEY, m_position.x );
m_config->Write( MESSAGE_BOX_POSY_KEY, m_position.y );
m_config->Write( MESSAGE_BOX_SIZEX_KEY, m_size.x );
m_config->Write( MESSAGE_BOX_SIZEY_KEY, m_size.y );
}
void FOOTPRINT_WIZARD_MESSAGES::LoadSettings()
{
m_config->Read( MESSAGE_BOX_POSX_KEY, &m_position.x, -1 );
m_config->Read( MESSAGE_BOX_POSY_KEY, &m_position.y, -1 );
m_config->Read( MESSAGE_BOX_SIZEX_KEY, &m_size.x, 350 );
m_config->Read( MESSAGE_BOX_SIZEY_KEY, &m_size.y, 250 );
}

View File

@ -39,6 +39,8 @@ class wxGrid;
class wxGridEvent; class wxGridEvent;
class FOOTPRINT_EDIT_FRAME; class FOOTPRINT_EDIT_FRAME;
// A helper class to display messages when building a footprin
class FOOTPRINT_WIZARD_MESSAGES;
/** /**
* Class FOOTPRINT_WIZARD_FRAME * Class FOOTPRINT_WIZARD_FRAME
@ -50,6 +52,7 @@ private:
int m_pageListWidth; ///< width of the window int m_pageListWidth; ///< width of the window
wxGrid* m_parameterGrid; ///< The list of parameters wxGrid* m_parameterGrid; ///< The list of parameters
int m_parameterGridWidth; ///< size of the grid int m_parameterGridWidth; ///< size of the grid
FOOTPRINT_WIZARD_MESSAGES* m_messagesFrame;
// Column index to display parameters in m_parameterGrid // Column index to display parameters in m_parameterGrid
static int m_columnPrmName; static int m_columnPrmName;
@ -112,6 +115,12 @@ private:
*/ */
void ReloadFootprint(); void ReloadFootprint();
/**
* Function DisplayBuildMessages
* Display the message generated by the python build footprint script
*/
void DisplayBuildMessage( wxString& aMessage );
/** /**
* Function GetMyWizard * Function GetMyWizard
* Reloads the wizard by name * Reloads the wizard by name
@ -188,4 +197,24 @@ private:
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
}; };
// A miniframe to display messages from the builder
class FOOTPRINT_WIZARD_MESSAGES: public wxMiniFrame
{
public:
FOOTPRINT_WIZARD_MESSAGES( FOOTPRINT_WIZARD_FRAME* aParent, wxConfigBase* aCfg );
~FOOTPRINT_WIZARD_MESSAGES();
void PrintMessage( const wxString& aMessage );
void ClearScreen();
void CloseMessagesWindow();
void SaveSettings();
void LoadSettings();
private:
wxTextCtrl* m_messageWindow;
wxPoint m_position;
wxSize m_size;
wxConfigBase* m_config;
};
#endif // FOOTPRINT_WIZARD_FRM_H_ #endif // FOOTPRINT_WIZARD_FRM_H_

View File

@ -314,11 +314,14 @@ wxString PYTHON_FOOTPRINT_WIZARD::SetParameterValues( int aPage, wxArrayString&
MODULE* PyModule_to_MODULE( PyObject* obj0 ); MODULE* PyModule_to_MODULE( PyObject* obj0 );
MODULE* PYTHON_FOOTPRINT_WIZARD::GetModule() MODULE* PYTHON_FOOTPRINT_WIZARD::GetFootprint( wxString * aMessages )
{ {
PyLOCK lock; PyLOCK lock;
PyObject* result = CallMethod( "GetModule", NULL ); PyObject* result = CallMethod( "GetFootprint", NULL );
if( aMessages )
*aMessages = CallRetStrMethod( "GetBuildMessages", NULL );
if( !result ) if( !result )
return NULL; return NULL;

View File

@ -56,7 +56,7 @@ public:
wxArrayString GetParameterErrors( int aPage ); wxArrayString GetParameterErrors( int aPage );
// must return an empty string or an error description // must return an empty string or an error description
wxString SetParameterValues( int aPage, wxArrayString& aValues ); wxString SetParameterValues( int aPage, wxArrayString& aValues );
MODULE* GetModule(); MODULE* GetFootprint( wxString * aMessages );
void* GetObject(); void* GetObject();
}; };

View File

@ -62,12 +62,12 @@ class FPCFootprintWizard(FootprintWizardPlugin):
# This method checks the parameters provided to wizard and set errors # This method checks the parameters provided to wizard and set errors
def CheckParameters(self): def CheckParameters(self):
p = self.parameters p = self.parameters
pads = p["Pads"]["*n"] pad_count = p["Pads"]["*n"]
errors = "" errors = ""
if (pads<1): if( pad_count < 1 ):
self.parameter_errors["Pads"]["n"]="Must be positive" self.parameter_errors["Pads"]["n"]="Must be positive"
errors +="Pads/n has wrong value, " errors +="Pads/n has wrong value, "
p["Pads"]["n"] = int(pads) # make sure it stays as int (default is float) p["Pads"]["n"] = int( pad_count ) # make sure it stays as int (default is float)
pad_width = p["Pads"]["width"] pad_width = p["Pads"]["width"]
pad_height = p["Pads"]["height"] pad_height = p["Pads"]["height"]
@ -82,16 +82,14 @@ class FPCFootprintWizard(FootprintWizardPlugin):
# build the footprint from parameters # build the footprint from parameters
def BuildFootprint(self): def BuildFootprint(self):
self.ClearErrors()
print "parameters:",self.parameters self.CheckParameters()
#self.ClearErrors()
#print "errors:",self.parameter_errors
module = MODULE(None) # create a new module module = MODULE(None) # create a new module
self.module = module self.module = module
p = self.parameters p = self.parameters
pads = int(p["Pads"]["*n"]) pad_count = int(p["Pads"]["*n"])
pad_width = p["Pads"]["width"] pad_width = p["Pads"]["width"]
pad_height = p["Pads"]["height"] pad_height = p["Pads"]["height"]
pad_pitch = p["Pads"]["pitch"] pad_pitch = p["Pads"]["pitch"]
@ -100,13 +98,13 @@ class FPCFootprintWizard(FootprintWizardPlugin):
shl_to_pad = p["Shield"]["shield_to_pad"] shl_to_pad = p["Shield"]["shield_to_pad"]
shl_from_top = p["Shield"]["from_top"] shl_from_top = p["Shield"]["from_top"]
offsetX = pad_pitch*(pads-1)/2 offsetX = pad_pitch * ( pad_count-1 ) / 2
size_pad = wxSize(pad_width,pad_height) size_pad = wxSize(pad_width,pad_height)
size_shld = wxSize(shl_width,shl_height) size_shld = wxSize(shl_width,shl_height)
size_text = wxSize( FromMM( 0.8), FromMM( 0.7) ) size_text = wxSize( FromMM( 0.8), FromMM( 0.7) )
textposy = pad_height/2 + FromMM(1) textposy = pad_height/2 + FromMM(1)
module.SetReference("FPC"+str(pads)) # give it a reference name module.SetReference( "FPC"+str( pad_count ) ) # give it a reference name
module.Reference().SetPos0(wxPoint(0, textposy)) module.Reference().SetPos0(wxPoint(0, textposy))
module.Reference().SetTextPosition(module.Reference().GetPos0()) module.Reference().SetTextPosition(module.Reference().GetPos0())
module.Reference().SetSize( size_text ) module.Reference().SetSize( size_text )
@ -121,7 +119,7 @@ class FPCFootprintWizard(FootprintWizardPlugin):
module.SetFPID( fpid ) module.SetFPID( fpid )
# create a pad array and add it to the module # create a pad array and add it to the module
for n in range (0,pads): for n in range ( 0, pad_count ):
xpos = pad_pitch*n - offsetX xpos = pad_pitch*n - offsetX
pad = self.smdRectPad(module,size_pad,wxPoint(xpos,0),str(n+1)) pad = self.smdRectPad(module,size_pad,wxPoint(xpos,0),str(n+1))
module.Add(pad) module.Add(pad)
@ -131,7 +129,7 @@ class FPCFootprintWizard(FootprintWizardPlugin):
xpos = -shl_to_pad-offsetX xpos = -shl_to_pad-offsetX
pad_s0_pos = wxPoint(xpos,shl_from_top) pad_s0_pos = wxPoint(xpos,shl_from_top)
pad_s0 = self.smdRectPad(module, size_shld, pad_s0_pos, "0") pad_s0 = self.smdRectPad(module, size_shld, pad_s0_pos, "0")
xpos = (pads-1)*pad_pitch+shl_to_pad-offsetX xpos = (pad_count-1) * pad_pitch+shl_to_pad - offsetX
pad_s1_pos = wxPoint(xpos,shl_from_top) pad_s1_pos = wxPoint(xpos,shl_from_top)
pad_s1 = self.smdRectPad(module, size_shld, pad_s1_pos, "0") pad_s1 = self.smdRectPad(module, size_shld, pad_s1_pos, "0")
@ -147,7 +145,7 @@ class FPCFootprintWizard(FootprintWizardPlugin):
# upper line # upper line
posy = -pad_height/2 - linewidth/2 - margin posy = -pad_height/2 - linewidth/2 - margin
xstart = - pad_pitch*0.5-offsetX xstart = - pad_pitch*0.5-offsetX
xend = pad_pitch * pads + xstart; xend = pad_pitch * pad_count + xstart;
outline.SetStartEnd( wxPoint(xstart, posy), wxPoint( xend, posy) ) outline.SetStartEnd( wxPoint(xstart, posy), wxPoint( xend, posy) )
outline.SetLayer(F_SilkS) #default: not needed outline.SetLayer(F_SilkS) #default: not needed
outline.SetShape(S_SEGMENT) outline.SetShape(S_SEGMENT)

View File

@ -61,7 +61,7 @@ class FootprintWizardParameterManager:
TODO: Hints are not supported, as there is as yet nowhere to TODO: Hints are not supported, as there is as yet nowhere to
put them in the KiCAD interface put them in the KiCAD interface
""" """
error = ""
val = None val = None
if unit == self.uMM: if unit == self.uMM:
val = pcbnew.FromMM(default) val = pcbnew.FromMM(default)
@ -74,8 +74,8 @@ class FootprintWizardParameterManager:
elif unit == self.uBool: elif unit == self.uBool:
val = "True" if default else "False" # ugly stringing val = "True" if default else "False" # ugly stringing
else: else:
print "Warning: Unknown unit type: %s" % unit error = "Warning: Unknown unit type: %s" % unit
return return error
if unit in [self.uNatural, self.uBool, self.uString]: if unit in [self.uNatural, self.uBool, self.uString]:
param = "*%s" % param # star prefix for natural param = "*%s" % param # star prefix for natural
@ -85,12 +85,17 @@ class FootprintWizardParameterManager:
self.parameters[section][param] = val self.parameters[section][param] = val
return error
def _PrintParameterTable(self): def _PrintParameterTable(self):
""" """
Pretty-print the parameters we have Pretty-print the parameters we have
""" """
message = ""
for name, section in self.parameters.iteritems(): for name, section in self.parameters.iteritems():
print " %s:" % name message += " %s:" % name
for key, value in section.iteritems(): for key, value in section.iteritems():
unit = "" unit = ""
@ -103,7 +108,10 @@ class FootprintWizardParameterManager:
else: else:
value = pcbnew.ToMM(value) value = pcbnew.ToMM(value)
print " %s: %s%s" % (key, value, unit) message += " %s: %s%s\n" % (key, value, unit)
return message
def _ParametersHaveErrors(self): def _ParametersHaveErrors(self):
""" """
@ -121,6 +129,7 @@ class FootprintWizardParameterManager:
""" """
Pretty-print parameters with errors Pretty-print parameters with errors
""" """
errors = ""
for name, section in self.parameter_errors.iteritems(): for name, section in self.parameter_errors.iteritems():
printed_section = False printed_section = False
@ -128,11 +137,13 @@ class FootprintWizardParameterManager:
for key, value in section.iteritems(): for key, value in section.iteritems():
if value: if value:
if not printed_section: if not printed_section:
print " %s:" % name errors += " %s:" % name
print " %s: %s (have %s)" % ( errors += " %s: %s (have %s)\n" % (
key, value, self.parameters[name][key]) key, value, self.parameters[name][key])
return errors
def ProcessParameters(self): def ProcessParameters(self):
""" """
Make sure the parameters we have meet whatever expectations the Make sure the parameters we have meet whatever expectations the
@ -143,22 +154,8 @@ class FootprintWizardParameterManager:
self.CheckParameters() self.CheckParameters()
if self._ParametersHaveErrors(): if self._ParametersHaveErrors():
print "Cannot build footprint: Parameters have errors:"
self._PrintParameterErrors()
return False return False
"""
Be aware print messages create IO exceptions, because the wizard
is run from Pcbnew. And if pcbnew is not run from a console, there is
no io channel to read the output of print function.
When the buffer is full, a IO exception is thrown.
"""
"""
print ("Building new %s footprint with the following parameters:"
% self.name)
self._PrintParameterTable()
"""
return True return True
################################################################# #################################################################
@ -286,15 +283,24 @@ class HelpfulFootprintWizardPlugin(pcbnew.FootprintWizardPlugin,
def BuildFootprint( self ): def BuildFootprint( self ):
""" """
Actually make the footprint. We defer all but the setup to Actually make the footprint. We defer all but the setup to
the implmenting class the implementing class
""" """
self.buildmessages = ""
self.module = pcbnew.MODULE(None) # create a new module self.module = pcbnew.MODULE(None) # create a new module
# do it first, so if we return early, we don't segfault KiCad # do it first, so if we return early, we don't segfault KiCad
if not self.ProcessParameters(): if not self.ProcessParameters():
self.buildmessages = "Cannot build footprint: Parameters have errors:\n"
self.buildmessages += self._PrintParameterErrors()
return return
self.buildmessages = ("Building new %s footprint with the following parameters:\n"
% self.name)
self.buildmessages += self._PrintParameterTable()
self.draw = FootprintWizardDrawingAids.FootprintWizardDrawingAids( self.draw = FootprintWizardDrawingAids.FootprintWizardDrawingAids(
self.module) self.module)
@ -312,3 +318,5 @@ class HelpfulFootprintWizardPlugin(pcbnew.FootprintWizardPlugin,
self.module.Value().SetThickness(thick) self.module.Value().SetThickness(thick)
self.BuildThisFootprint() # implementer's build function self.BuildThisFootprint() # implementer's build function
return

View File

@ -42,7 +42,6 @@ class QFPWizard(HelpfulFootprintWizardPlugin.HelpfulFootprintWizardPlugin):
self.AddParam("Pads", "package height", self.uMM, 14) self.AddParam("Pads", "package height", self.uMM, 14)
def CheckParameters(self): def CheckParameters(self):
self.CheckParamInt("Pads", "*n", is_multiple_of=4) self.CheckParamInt("Pads", "*n", is_multiple_of=4)
self.CheckParamBool("Pads", "*oval") self.CheckParamBool("Pads", "*oval")
@ -50,7 +49,6 @@ class QFPWizard(HelpfulFootprintWizardPlugin.HelpfulFootprintWizardPlugin):
return "QFP_%d" % self.parameters["Pads"]["*n"] return "QFP_%d" % self.parameters["Pads"]["*n"]
def BuildThisFootprint(self): def BuildThisFootprint(self):
pads = self.parameters["Pads"] pads = self.parameters["Pads"]
pad_pitch = pads["pad pitch"] pad_pitch = pads["pad pitch"]
@ -66,15 +64,12 @@ class QFPWizard(HelpfulFootprintWizardPlugin.HelpfulFootprintWizardPlugin):
pad_shape = pcbnew.PAD_SHAPE_OVAL if pads["*oval"] else pcbnew.PAD_SHAPE_RECT pad_shape = pcbnew.PAD_SHAPE_OVAL if pads["*oval"] else pcbnew.PAD_SHAPE_RECT
h_pad = PA.PadMaker(self.module).SMDPad( h_pad = PA.PadMaker(self.module).SMDPad( pad_width, pad_length, shape=pad_shape)
pad_width, pad_length, shape=pad_shape) v_pad = PA.PadMaker(self.module).SMDPad( pad_length, pad_width, shape=pad_shape)
v_pad = PA.PadMaker(self.module).SMDPad(
pad_length, pad_width, shape=pad_shape)
#left row #left row
pin1Pos = pcbnew.wxPoint(-h_pitch / 2, 0) pin1Pos = pcbnew.wxPoint(-h_pitch / 2, 0)
array = PA.PadLineArray(h_pad, pads_per_row, pad_pitch, True, array = PA.PadLineArray(h_pad, pads_per_row, pad_pitch, True, pin1Pos)
pin1Pos)
array.SetFirstPadInArray(1) array.SetFirstPadInArray(1)
array.AddPadsToModule(self.draw) array.AddPadsToModule(self.draw)

View File

@ -174,6 +174,7 @@ class FootprintWizardPlugin(KiCadPlugin):
self.name = "Undefined Footprint Wizard plugin" self.name = "Undefined Footprint Wizard plugin"
self.description = "" self.description = ""
self.image = "" self.image = ""
self.buildmessages = ""
def GetName(self): def GetName(self):
return self.name return self.name
@ -242,13 +243,16 @@ class FootprintWizardPlugin(KiCadPlugin):
self.parameter_errors = errs self.parameter_errors = errs
def GetModule(self): def GetFootprint( self ):
self.BuildFootprint() self.BuildFootprint()
return self.module return self.module
def BuildFootprint(self): def BuildFootprint(self):
return return
def GetBuildMessages( self ):
return self.buildmessages
def Show(self): def Show(self):
print "Footprint Wizard Name: ",self.GetName() print "Footprint Wizard Name: ",self.GetName()
print "Footprint Wizard Description: ",self.GetDescription() print "Footprint Wizard Description: ",self.GetDescription()