diff --git a/CMakeLists.txt b/CMakeLists.txt index 12695523b4..6e449944b7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -115,6 +115,8 @@ if( NOT DEFAULT_INSTALL_PATH ) "Location of KiCad data files." ) endif() +message( STATUS "Kicad install dir: <${DEFAULT_INSTALL_PATH}>" ) + # Generate build system specific header file. include( PerformFeatureChecks ) perform_feature_checks() @@ -334,10 +336,17 @@ set( KIFACE_PREFIX "_" ) #================================================ if( NOT APPLE ) # 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." ) - set( KICAD_PLUGINS lib/kicad/plugins - CACHE PATH "Location of KiCad plugins." ) + + if( WIN32 ) + set( KICAD_PLUGINS ${KICAD_BIN}/scripting/plugins + CACHE PATH "Location of KiCad plugins." ) + else() + set( KICAD_PLUGINS lib/kicad/plugins + CACHE PATH "Location of KiCad plugins." ) + endif() + set( KICAD_DATA share/kicad CACHE PATH "Location of KiCad data files." ) set( KICAD_DOCS share/doc/kicad diff --git a/common/kiway_player.cpp b/common/kiway_player.cpp index 7eb8ae2fd9..295855cda6 100644 --- a/common/kiway_player.cpp +++ b/common/kiway_player.cpp @@ -106,14 +106,32 @@ bool KIWAY_PLAYER::ShowModal( wxString* aResult, wxWindow* aResultantFocusWindow 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 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 wxWindowDisabler toggle( this ); - WX_EVENT_LOOP event_loop; + // 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; m_modal_loop = &event_loop; - event_loop.Run(); } // End of scop for some variables. diff --git a/pcb_calculator/dialogs/pcb_calculator_frame_base.cpp b/pcb_calculator/dialogs/pcb_calculator_frame_base.cpp index aeab7acf93..5ba848f949 100644 --- a/pcb_calculator/dialogs/pcb_calculator_frame_base.cpp +++ b/pcb_calculator/dialogs/pcb_calculator_frame_base.cpp @@ -248,7 +248,7 @@ PCB_CALCULATOR_FRAME_BASE::PCB_CALCULATOR_FRAME_BASE( wxWindow* parent, wxWindow m_panelRegulators->SetSizer( bSizerMainReg ); m_panelRegulators->Layout(); 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 ); wxBoxSizer* bSizerTrackWidth; 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 ); - 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->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->Layout(); 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 ); wxBoxSizer* bSizerElectricalClearance; bSizerElectricalClearance = new wxBoxSizer( wxHORIZONTAL ); diff --git a/pcb_calculator/dialogs/pcb_calculator_frame_base.fbp b/pcb_calculator/dialogs/pcb_calculator_frame_base.fbp index 4a8e96f67f..3cf27fd505 100644 --- a/pcb_calculator/dialogs/pcb_calculator_frame_base.fbp +++ b/pcb_calculator/dialogs/pcb_calculator_frame_base.fbp @@ -270,7 +270,7 @@ Regulators - 1 + 0 1 1 @@ -3267,7 +3267,7 @@ Track Width - 0 + 1 1 1 @@ -3359,7 +3359,7 @@ 5 wxALL|wxEXPAND - 1 + 0 wxID_ANY Parameters diff --git a/pcbnew/class_footprint_wizard.h b/pcbnew/class_footprint_wizard.h index 88f7e3285d..20fc1d443f 100644 --- a/pcbnew/class_footprint_wizard.h +++ b/pcbnew/class_footprint_wizard.h @@ -116,8 +116,10 @@ public: * 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 + * @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 diff --git a/pcbnew/footprint_wizard.cpp b/pcbnew/footprint_wizard.cpp index c334fd7593..4174a8dd85 100644 --- a/pcbnew/footprint_wizard.cpp +++ b/pcbnew/footprint_wizard.cpp @@ -101,7 +101,9 @@ void FOOTPRINT_WIZARD_FRAME::ReloadFootprint() GetBoard()->m_Modules.DeleteAll(); // Creates the module - MODULE* module = footprintWizard->GetModule(); + wxString msg; + MODULE* module = footprintWizard->GetFootprint( &msg ); + DisplayBuildMessage( msg ); if( module ) { @@ -111,13 +113,22 @@ void FOOTPRINT_WIZARD_FRAME::ReloadFootprint() } else { - DBG(printf( "footprintWizard->GetModule() returns NULL\n" );) + DBG(printf( "footprintWizard->GetFootprint() returns NULL\n" );) } 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() { if( m_wizardName.Length() == 0 ) @@ -141,7 +152,11 @@ MODULE* FOOTPRINT_WIZARD_FRAME::GetBuiltFootprint() if( footprintWizard && m_modal_ret_val ) { - return footprintWizard->GetModule(); + wxString msg; + MODULE * footprint = footprintWizard->GetFootprint( &msg ); + DisplayBuildMessage( msg ); + + return footprint; } return NULL; diff --git a/pcbnew/footprint_wizard_frame.cpp b/pcbnew/footprint_wizard_frame.cpp index fdbd6ea324..a840dd63ac 100644 --- a/pcbnew/footprint_wizard_frame.cpp +++ b/pcbnew/footprint_wizard_frame.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2012-2015 Miguel Angel Ajo Pelayo - * 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 * 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 ); #endif + // Prepare the window to display the message generated by the footprint script builder + m_messagesFrame = new FOOTPRINT_WIZARD_MESSAGES( this, config() ); + Show( true ); + m_messagesFrame->Show( true ); SelectFootprintWizard(); } @@ -222,6 +226,9 @@ FOOTPRINT_WIZARD_FRAME::~FOOTPRINT_WIZARD_FRAME() void FOOTPRINT_WIZARD_FRAME::OnCloseWindow( wxCloseEvent& Event ) { + if( m_messagesFrame ) + m_messagesFrame->CloseMessagesWindow(); + if( IsModal() ) { // 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 PARAMLIST_WIDTH_KEY wxT( "Paramlist_width" ) +#define PARTLIST_WIDTH_KEY wxT( "Fpwizard_Partlist_width" ) +#define PARAMLIST_WIDTH_KEY wxT( "Fpwizard_Paramlist_width" ) void FOOTPRINT_WIZARD_FRAME::LoadSettings( wxConfigBase* aCfg ) @@ -407,7 +414,7 @@ void FOOTPRINT_WIZARD_FRAME::SaveSettings( wxConfigBase* aCfg ) EDA_DRAW_FRAME::SaveSettings( aCfg ); 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 } + + +// 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 ); +} diff --git a/pcbnew/footprint_wizard_frame.h b/pcbnew/footprint_wizard_frame.h index b54b82a14b..87ee427d68 100644 --- a/pcbnew/footprint_wizard_frame.h +++ b/pcbnew/footprint_wizard_frame.h @@ -39,6 +39,8 @@ class wxGrid; class wxGridEvent; class FOOTPRINT_EDIT_FRAME; +// A helper class to display messages when building a footprin +class FOOTPRINT_WIZARD_MESSAGES; /** * Class FOOTPRINT_WIZARD_FRAME @@ -50,6 +52,7 @@ private: int m_pageListWidth; ///< width of the window wxGrid* m_parameterGrid; ///< The list of parameters int m_parameterGridWidth; ///< size of the grid + FOOTPRINT_WIZARD_MESSAGES* m_messagesFrame; // Column index to display parameters in m_parameterGrid static int m_columnPrmName; @@ -112,6 +115,12 @@ private: */ void ReloadFootprint(); + /** + * Function DisplayBuildMessages + * Display the message generated by the python build footprint script + */ + void DisplayBuildMessage( wxString& aMessage ); + /** * Function GetMyWizard * Reloads the wizard by name @@ -188,4 +197,24 @@ private: 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_ diff --git a/pcbnew/scripting/pcbnew_footprint_wizards.cpp b/pcbnew/scripting/pcbnew_footprint_wizards.cpp index 28b73d5b20..e0f3854788 100644 --- a/pcbnew/scripting/pcbnew_footprint_wizards.cpp +++ b/pcbnew/scripting/pcbnew_footprint_wizards.cpp @@ -314,11 +314,14 @@ wxString PYTHON_FOOTPRINT_WIZARD::SetParameterValues( int aPage, wxArrayString& MODULE* PyModule_to_MODULE( PyObject* obj0 ); -MODULE* PYTHON_FOOTPRINT_WIZARD::GetModule() +MODULE* PYTHON_FOOTPRINT_WIZARD::GetFootprint( wxString * aMessages ) { PyLOCK lock; - PyObject* result = CallMethod( "GetModule", NULL ); + PyObject* result = CallMethod( "GetFootprint", NULL ); + + if( aMessages ) + *aMessages = CallRetStrMethod( "GetBuildMessages", NULL ); if( !result ) return NULL; diff --git a/pcbnew/scripting/pcbnew_footprint_wizards.h b/pcbnew/scripting/pcbnew_footprint_wizards.h index bb1045853d..ada111f4b7 100644 --- a/pcbnew/scripting/pcbnew_footprint_wizards.h +++ b/pcbnew/scripting/pcbnew_footprint_wizards.h @@ -56,7 +56,7 @@ public: wxArrayString GetParameterErrors( int aPage ); // must return an empty string or an error description wxString SetParameterValues( int aPage, wxArrayString& aValues ); - MODULE* GetModule(); + MODULE* GetFootprint( wxString * aMessages ); void* GetObject(); }; diff --git a/pcbnew/scripting/plugins/FPC_(SMD_type)_footprintwizard.py b/pcbnew/scripting/plugins/FPC_(SMD_type)_footprintwizard.py index 8cbea5fe32..359509288b 100644 --- a/pcbnew/scripting/plugins/FPC_(SMD_type)_footprintwizard.py +++ b/pcbnew/scripting/plugins/FPC_(SMD_type)_footprintwizard.py @@ -62,12 +62,12 @@ class FPCFootprintWizard(FootprintWizardPlugin): # This method checks the parameters provided to wizard and set errors def CheckParameters(self): p = self.parameters - pads = p["Pads"]["*n"] + pad_count = p["Pads"]["*n"] errors = "" - if (pads<1): + if( pad_count < 1 ): self.parameter_errors["Pads"]["n"]="Must be positive" 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_height = p["Pads"]["height"] @@ -82,16 +82,14 @@ class FPCFootprintWizard(FootprintWizardPlugin): # build the footprint from parameters def BuildFootprint(self): - - print "parameters:",self.parameters - #self.ClearErrors() - #print "errors:",self.parameter_errors + self.ClearErrors() + self.CheckParameters() module = MODULE(None) # create a new module self.module = module p = self.parameters - pads = int(p["Pads"]["*n"]) + pad_count = int(p["Pads"]["*n"]) pad_width = p["Pads"]["width"] pad_height = p["Pads"]["height"] pad_pitch = p["Pads"]["pitch"] @@ -100,13 +98,13 @@ class FPCFootprintWizard(FootprintWizardPlugin): shl_to_pad = p["Shield"]["shield_to_pad"] 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_shld = wxSize(shl_width,shl_height) size_text = wxSize( FromMM( 0.8), FromMM( 0.7) ) 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().SetTextPosition(module.Reference().GetPos0()) module.Reference().SetSize( size_text ) @@ -121,7 +119,7 @@ class FPCFootprintWizard(FootprintWizardPlugin): module.SetFPID( fpid ) # 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 pad = self.smdRectPad(module,size_pad,wxPoint(xpos,0),str(n+1)) module.Add(pad) @@ -131,7 +129,7 @@ class FPCFootprintWizard(FootprintWizardPlugin): xpos = -shl_to_pad-offsetX pad_s0_pos = wxPoint(xpos,shl_from_top) 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 = self.smdRectPad(module, size_shld, pad_s1_pos, "0") @@ -147,7 +145,7 @@ class FPCFootprintWizard(FootprintWizardPlugin): # upper line posy = -pad_height/2 - linewidth/2 - margin 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.SetLayer(F_SilkS) #default: not needed outline.SetShape(S_SEGMENT) diff --git a/pcbnew/scripting/plugins/HelpfulFootprintWizardPlugin.py b/pcbnew/scripting/plugins/HelpfulFootprintWizardPlugin.py index 2bc7544d05..00a057fa92 100644 --- a/pcbnew/scripting/plugins/HelpfulFootprintWizardPlugin.py +++ b/pcbnew/scripting/plugins/HelpfulFootprintWizardPlugin.py @@ -61,7 +61,7 @@ class FootprintWizardParameterManager: TODO: Hints are not supported, as there is as yet nowhere to put them in the KiCAD interface """ - + error = "" val = None if unit == self.uMM: val = pcbnew.FromMM(default) @@ -74,8 +74,8 @@ class FootprintWizardParameterManager: elif unit == self.uBool: val = "True" if default else "False" # ugly stringing else: - print "Warning: Unknown unit type: %s" % unit - return + error = "Warning: Unknown unit type: %s" % unit + return error if unit in [self.uNatural, self.uBool, self.uString]: param = "*%s" % param # star prefix for natural @@ -85,12 +85,17 @@ class FootprintWizardParameterManager: self.parameters[section][param] = val + return error + + def _PrintParameterTable(self): """ Pretty-print the parameters we have """ + message = "" + for name, section in self.parameters.iteritems(): - print " %s:" % name + message += " %s:" % name for key, value in section.iteritems(): unit = "" @@ -103,7 +108,10 @@ class FootprintWizardParameterManager: else: value = pcbnew.ToMM(value) - print " %s: %s%s" % (key, value, unit) + message += " %s: %s%s\n" % (key, value, unit) + + return message + def _ParametersHaveErrors(self): """ @@ -121,6 +129,7 @@ class FootprintWizardParameterManager: """ Pretty-print parameters with errors """ + errors = "" for name, section in self.parameter_errors.iteritems(): printed_section = False @@ -128,11 +137,13 @@ class FootprintWizardParameterManager: for key, value in section.iteritems(): if value: 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]) + return errors + def ProcessParameters(self): """ Make sure the parameters we have meet whatever expectations the @@ -143,22 +154,8 @@ class FootprintWizardParameterManager: self.CheckParameters() if self._ParametersHaveErrors(): - print "Cannot build footprint: Parameters have errors:" - self._PrintParameterErrors() 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 ################################################################# @@ -283,18 +280,27 @@ class HelpfulFootprintWizardPlugin(pcbnew.FootprintWizardPlugin, """ raise NotImplementedError - def BuildFootprint(self): + def BuildFootprint( self ): """ 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 # do it first, so if we return early, we don't segfault KiCad if not self.ProcessParameters(): + self.buildmessages = "Cannot build footprint: Parameters have errors:\n" + self.buildmessages += self._PrintParameterErrors() return + self.buildmessages = ("Building new %s footprint with the following parameters:\n" + % self.name) + + self.buildmessages += self._PrintParameterTable() + self.draw = FootprintWizardDrawingAids.FootprintWizardDrawingAids( self.module) @@ -312,3 +318,5 @@ class HelpfulFootprintWizardPlugin(pcbnew.FootprintWizardPlugin, self.module.Value().SetThickness(thick) self.BuildThisFootprint() # implementer's build function + + return diff --git a/pcbnew/scripting/plugins/qfp_wizard.py b/pcbnew/scripting/plugins/qfp_wizard.py index e4ebf2ea35..83cdf459ab 100644 --- a/pcbnew/scripting/plugins/qfp_wizard.py +++ b/pcbnew/scripting/plugins/qfp_wizard.py @@ -42,7 +42,6 @@ class QFPWizard(HelpfulFootprintWizardPlugin.HelpfulFootprintWizardPlugin): self.AddParam("Pads", "package height", self.uMM, 14) def CheckParameters(self): - self.CheckParamInt("Pads", "*n", is_multiple_of=4) self.CheckParamBool("Pads", "*oval") @@ -50,7 +49,6 @@ class QFPWizard(HelpfulFootprintWizardPlugin.HelpfulFootprintWizardPlugin): return "QFP_%d" % self.parameters["Pads"]["*n"] def BuildThisFootprint(self): - pads = self.parameters["Pads"] 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 - h_pad = PA.PadMaker(self.module).SMDPad( - pad_width, pad_length, shape=pad_shape) - v_pad = PA.PadMaker(self.module).SMDPad( - pad_length, pad_width, shape=pad_shape) + h_pad = PA.PadMaker(self.module).SMDPad( pad_width, pad_length, shape=pad_shape) + v_pad = PA.PadMaker(self.module).SMDPad( pad_length, pad_width, shape=pad_shape) #left row pin1Pos = pcbnew.wxPoint(-h_pitch / 2, 0) - array = PA.PadLineArray(h_pad, pads_per_row, pad_pitch, True, - pin1Pos) + array = PA.PadLineArray(h_pad, pads_per_row, pad_pitch, True, pin1Pos) array.SetFirstPadInArray(1) array.AddPadsToModule(self.draw) diff --git a/scripting/kicadplugins.i b/scripting/kicadplugins.i index de1b3f257c..2596a7f38b 100644 --- a/scripting/kicadplugins.i +++ b/scripting/kicadplugins.i @@ -174,6 +174,7 @@ class FootprintWizardPlugin(KiCadPlugin): self.name = "Undefined Footprint Wizard plugin" self.description = "" self.image = "" + self.buildmessages = "" def GetName(self): return self.name @@ -242,13 +243,16 @@ class FootprintWizardPlugin(KiCadPlugin): self.parameter_errors = errs - def GetModule(self): + def GetFootprint( self ): self.BuildFootprint() return self.module def BuildFootprint(self): return + def GetBuildMessages( self ): + return self.buildmessages + def Show(self): print "Footprint Wizard Name: ",self.GetName() print "Footprint Wizard Description: ",self.GetDescription()