diff --git a/include/wxPcbStruct.h b/include/wxPcbStruct.h index df6116ccfb..6498d7f0f3 100644 --- a/include/wxPcbStruct.h +++ b/include/wxPcbStruct.h @@ -972,12 +972,20 @@ public: /** * Function ExporttoSPECCTRA - * will export the current BOARD to a specctra dsn file. See - * See http://www.autotraxeda.com/docs/SPECCTRA/SPECCTRA.pdf for the - * specification. + * Ask for a filename and call ExportSpecctraFile to export the current BOARD + * to a specctra dsn file. */ void ExportToSpecctra( wxCommandEvent& event ); + /** + * Function ExportSpecctraFile + * will export the current BOARD to a specctra dsn file. + * See http://www.autotraxeda.com/docs/SPECCTRA/SPECCTRA.pdf for the + * specification. + * @return true if OK + */ + bool ExportSpecctraFile( const wxString& aFullFilename ); + /** * Function ImportSpecctraSession * will import a specctra *.ses file and use it to relocate MODULEs and diff --git a/pcbnew/class_module.cpp b/pcbnew/class_module.cpp index b8b4853b46..26527c095a 100644 --- a/pcbnew/class_module.cpp +++ b/pcbnew/class_module.cpp @@ -892,7 +892,7 @@ void MODULE::Flip( const wxPoint& aCentre ) case PCB_MODULE_TEXT_T: text = (TEXTE_MODULE*) item; text->m_Pos.y -= m_Pos.y; - NEGATE( text->m_Pos0.y ); + NEGATE( text->m_Pos.y ); text->m_Pos.y += m_Pos.y; NEGATE( text->m_Pos0.y ); NEGATE_AND_NORMALIZE_ANGLE_POS( text->m_Orient ); diff --git a/pcbnew/dialogs/dialog_freeroute_exchange.cpp b/pcbnew/dialogs/dialog_freeroute_exchange.cpp index 81608d3276..fa765b7dcd 100644 --- a/pcbnew/dialogs/dialog_freeroute_exchange.cpp +++ b/pcbnew/dialogs/dialog_freeroute_exchange.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include <../common/dialogs/dialog_display_info_HTML_base.h> @@ -76,6 +77,7 @@ void DIALOG_FREEROUTE::MyInit() { SetFocus(); m_FreeRouteSetupChanged = false; + m_freeRouterIsLocal = false; wxString msg; @@ -87,6 +89,14 @@ void DIALOG_FREEROUTE::MyInit() m_FreerouteURLName->SetValue( wxT( "http://www.freerouting.net/" ) ); else m_FreerouteURLName->SetValue( msg ); + + wxFileName fileName( FindKicadFile( wxT( "freeroute.jar" ) ), wxPATH_UNIX ); + + if( fileName.FileExists() ) + { + m_freeRouterIsLocal = true; + m_buttonLaunchFreeroute->SetLabel( _("Create .dsn File and Launch FreeRouter") ); + } } const char * s_FreeRouteHelpInfo = @@ -116,7 +126,7 @@ void DIALOG_FREEROUTE::OnImportButtonClick( wxCommandEvent& event ) { m_Parent->ImportSpecctraSession( event ); - /* Connectivity inf must be rebuild. + /* Connectivity must be rebuild. * because for large board it can take some time, this is made only on demand */ if( IsOK( this, _("Do you want to rebuild connectivity data ?" ) ) ) @@ -128,13 +138,23 @@ void DIALOG_FREEROUTE::OnImportButtonClick( wxCommandEvent& event ) */ void DIALOG_FREEROUTE::OnLaunchButtonClick( wxCommandEvent& event ) { + wxString javaCommand; + + if( m_freeRouterIsLocal ) + { + javaCommand = CmdRunFreeRouterLocal(); + + if( javaCommand.IsEmpty() ) // Something is wrong + return; + } + else + javaCommand = wxT( "javaws" ); + wxString url; - wxString command; wxFileName fileName( FindKicadFile( wxT( "freeroute.jnlp" ) ), wxPATH_UNIX ); - if( fileName.FileExists() ) + if( m_freeRouterIsLocal || fileName.FileExists() ) { - wxString javaWebStartCommand = wxT( "javaws" ); // Find the Java web start application on Windows. #ifdef __WINDOWS__ @@ -145,13 +165,20 @@ void DIALOG_FREEROUTE::OnLaunchButtonClick( wxCommandEvent& event ) // Windows and the build version of KiCad. // This key works for 32 bit Java on 32 bit Windows and 64 bit Java on 64 bit Windows. - wxRegKey key( wxRegKey::HKLM, wxT( "SOFTWARE\\JavaSoft\\Java Web Start" ), + wxString keyName = m_freeRouterIsLocal ? wxT( "SOFTWARE\\JavaSoft\\Java Runtime Environment" ) + : wxT( "SOFTWARE\\JavaSoft\\Java Web Start" ); + wxRegKey key( wxRegKey::HKLM, keyName, wxIsPlatform64Bit() ? wxRegKey::WOW64ViewMode_64 : wxRegKey::WOW64ViewMode_Default ); // It's possible that 32 bit Java is installed on 64 bit Windows. if( !key.Exists() && wxIsPlatform64Bit() ) - key.SetName( wxRegKey::HKLM, wxT( "SOFTWARE\\Wow6432Node\\JavaSoft\\Java Web Start" ) ); + { + keyName = m_freeRouterIsLocal ? + wxT( "SOFTWARE\\Wow6432Node\\JavaSoft\\Java Runtime Environment" ) + : wxT( "SOFTWARE\\Wow6432Node\\JavaSoft\\Java Web Start" ); + key.SetName( wxRegKey::HKLM, keyName ); + } if( !key.Exists() ) { @@ -168,17 +195,24 @@ void DIALOG_FREEROUTE::OnLaunchButtonClick( wxCommandEvent& event ) wxString value; key.QueryValue( wxT( "CurrentVersion" ), value ); key.SetName( key.GetName() + wxT( "\\" ) + value ); - key.QueryValue( wxT( "Home" ), value ); - javaWebStartCommand = value + wxFileName::GetPathSeparator() + javaWebStartCommand; + + key.QueryValue( m_freeRouterIsLocal ? wxT( "JavaHome" ) : wxT( "Home" ), value ); + wxString javaCommandPath = value + wxFileName::GetPathSeparator(); #else #warning Kicad needs wxWidgets >= 2.9.4. version 2.8 is only supported for testing purposes #endif // wxCHECK_VERSION( 2, 9, 0 ) #endif // __WINDOWS__ - // Wrap FullFileName in double quotes in case it has C:\Program Files in it. - // The space is interpreted as an argument separator. - command << javaWebStartCommand << wxChar( ' ' ) << wxChar( '"' ) - << fileName.GetFullPath() << wxChar( '"' ); + wxString command = javaCommandPath; + + if( m_freeRouterIsLocal ) + command << wxT("bin\\") << javaCommand; + else + // Wrap FullFileName in double quotes in case it has C:\Program Files in it. + // The space is interpreted as an argument separator. + command << javaCommand << wxChar( ' ' ) << wxChar( '"' ) + << fileName.GetFullPath() << wxChar( '"' ); + ProcessExecute( command ); return; } @@ -188,6 +222,43 @@ void DIALOG_FREEROUTE::OnLaunchButtonClick( wxCommandEvent& event ) wxLaunchDefaultBrowser( url ); } +wxString DIALOG_FREEROUTE::CmdRunFreeRouterLocal() +{ + wxString fullFileName = m_Parent->GetBoard()->GetFileName(); + wxString path; + wxString name; + wxString ext; + wxString dsn_ext = wxT( ".dsn" ); + wxString mask = wxT( "*" ) + dsn_ext; + + wxFileName::SplitPath( fullFileName, &path, &name, &ext ); + + name += dsn_ext; + + fullFileName = EDA_FileSelector( _( "Specctra DSN file:" ), + path, + name, // name.ext without path! + dsn_ext, + mask, + this, + wxFD_SAVE, + false + ); + + if( fullFileName == wxEmptyString ) + return fullFileName; + + if( ! m_Parent->ExportSpecctraFile( fullFileName ) ) // the file was not created + return fullFileName; + + wxFileName jarfileName( FindKicadFile( wxT( "freeroute.jar" ) ), wxPATH_UNIX ); + + wxString command = wxT("java -jar "); + command << wxChar( '"' ) << jarfileName.GetFullPath() << wxT( "\" -de " ); + command << wxChar( '"' ) << fullFileName << wxChar( '"' ); + + return command; +} /* wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_BUTTON */ diff --git a/pcbnew/dialogs/dialog_freeroute_exchange.h b/pcbnew/dialogs/dialog_freeroute_exchange.h index 0f1e6f97ff..e9646060f0 100644 --- a/pcbnew/dialogs/dialog_freeroute_exchange.h +++ b/pcbnew/dialogs/dialog_freeroute_exchange.h @@ -16,6 +16,7 @@ class DIALOG_FREEROUTE : public DIALOG_FREEROUTE_BASE private: PCB_EDIT_FRAME* m_Parent; bool m_FreeRouteSetupChanged; + bool m_freeRouterIsLocal; private: // Virtual event handlers @@ -28,7 +29,7 @@ private: void OnCancelButtonClick( wxCommandEvent& event ); void OnTextEditFrUrlUpdated( wxCommandEvent& event ); void MyInit ( ); - + wxString CmdRunFreeRouterLocal(); public: DIALOG_FREEROUTE( PCB_EDIT_FRAME* parent ); diff --git a/pcbnew/scripting/pcbnew_footprint_wizards.cpp b/pcbnew/scripting/pcbnew_footprint_wizards.cpp index 8b74d4ac70..70e2238d34 100644 --- a/pcbnew/scripting/pcbnew_footprint_wizards.cpp +++ b/pcbnew/scripting/pcbnew_footprint_wizards.cpp @@ -81,7 +81,9 @@ PyObject* PYTHON_FOOTPRINT_WIZARD::CallMethod( const char* aMethod, PyObject* aA } if( pFunc ) + { Py_XDECREF( pFunc ); + } return NULL; } diff --git a/pcbnew/scripting/plugins/FPC_(SMD_type)_footprintwizard.py b/pcbnew/scripting/plugins/FPC_(SMD_type)_footprintwizard.py index 0cace0dfb1..f751c47f38 100644 --- a/pcbnew/scripting/plugins/FPC_(SMD_type)_footprintwizard.py +++ b/pcbnew/scripting/plugins/FPC_(SMD_type)_footprintwizard.py @@ -104,10 +104,13 @@ class FPCFootprintWizard(FootprintWizardPlugin): module.Add(pad) + # Mechanical shield pads: left pad and right pad xpos = -shl_to_pad-offsetX - pad_s0 = self.smdRectPad(module, size_shld, wxPoint(xpos,shl_from_top), "0") + 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 - pad_s1 = self.smdRectPad(module, size_shld, wxPoint(xpos,shl_from_top), "0") + pad_s1_pos = wxPoint(xpos,shl_from_top) + pad_s1 = self.smdRectPad(module, size_shld, pad_s1_pos, "0") module.Add(pad_s0) module.Add(pad_s1) @@ -115,21 +118,81 @@ class FPCFootprintWizard(FootprintWizardPlugin): #add outline outline = EDGE_MODULE(module) linewidth = FromMM(0.2) - posy = -pad_height/2 - linewidth/2 -FromMM(0.2) - outline.SetStartEnd(wxPoint(pad_pitch * pads - pad_pitch*0.5-offsetX, posy), - wxPoint( - pad_pitch*0.5-offsetX, posy)) outline.SetWidth(linewidth) + margin = FromMM(0.2) + + # upper line + posy = -pad_height/2 - linewidth/2 - margin + xstart = - pad_pitch*0.5-offsetX + xend = pad_pitch * pads + xstart; + outline.SetStartEnd( wxPoint(xstart, posy), wxPoint( xend, posy) ) outline.SetLayer(SILKSCREEN_N_FRONT) #default: not needed outline.SetShape(S_SEGMENT) module.Add(outline) + # lower line outline1 = EDGE_MODULE(module) outline1.Copy(outline) #copy all settings from outline - posy = pad_height/2 + linewidth/2 +FromMM(0.2) - outline1.SetStartEnd(wxPoint(pad_pitch * pads - pad_pitch*0.5-offsetX, posy), - wxPoint( - pad_pitch*0.5-offsetX, posy)) + posy = pad_height/2 + linewidth/2 + margin + outline1.SetStartEnd(wxPoint(xstart, posy), wxPoint( xend, posy)) module.Add(outline1) + # around left mechanical pad (the outline around right pad is mirrored/y axix) + outline2 = EDGE_MODULE(module) # vertical segment + outline2.Copy(outline) + yend = pad_s0_pos.y + shl_height/2 + margin + outline2.SetStartEnd(wxPoint(xstart, posy), wxPoint( xstart, yend)) + module.Add(outline2) + outline2_d = EDGE_MODULE(module) # right pad side + outline2_d.Copy(outline2) + outline2_d.SetStartEnd(wxPoint(-xstart, posy), wxPoint( -xstart, yend)) + module.Add(outline2_d) + + outline3 = EDGE_MODULE(module) # horizontal segment below the pad + outline3.Copy(outline) + posy = yend + xend = pad_s0_pos.x - (shl_width/2 + linewidth + margin*2) + outline3.SetStartEnd(wxPoint(xstart, posy), wxPoint( xend, posy)) + module.Add(outline3) + outline3_d = EDGE_MODULE(module) # right pad side + outline3_d.Copy(outline3) + outline3_d.SetStartEnd(wxPoint(-xstart, posy), wxPoint( -xend, yend)) + module.Add(outline3_d) + + outline4 = EDGE_MODULE(module) # vertical segment at left of the pad + outline4.Copy(outline) + xstart = xend + yend = posy - (shl_height + linewidth + margin*2) + outline4.SetStartEnd(wxPoint(xstart, posy), wxPoint( xend, yend)) + module.Add(outline4) + outline4_d = EDGE_MODULE(module) # right pad side + outline4_d.Copy(outline4) + outline4_d.SetStartEnd(wxPoint(-xstart, posy), wxPoint( -xend, yend)) + module.Add(outline4_d) + + outline5 = EDGE_MODULE(module) # horizontal segment above the pad + outline5.Copy(outline) + xstart = xend + xend = - pad_pitch*0.5-offsetX + posy = yend + outline5.SetStartEnd(wxPoint(xstart, posy), wxPoint( xend, yend)) + module.Add(outline5) + outline5_d = EDGE_MODULE(module) # right pad side + outline5_d.Copy(outline5) + outline5_d.SetStartEnd(wxPoint(-xstart, posy), wxPoint( -xend, yend)) + module.Add(outline5_d) + + outline6 = EDGE_MODULE(module) # vertical segment above the pad + outline6.Copy(outline) + xstart = xend + yend = -pad_height/2 - linewidth/2 - margin + outline6.SetStartEnd(wxPoint(xstart, posy), wxPoint( xend, yend)) + module.Add(outline6) + outline6_d = EDGE_MODULE(module) # right pad side + outline6_d.Copy(outline6) + outline6_d.SetStartEnd(wxPoint(-xstart, posy), wxPoint( -xend, yend)) + module.Add(outline6_d) + # create our footprint wizard fpc_wizard = FPCFootprintWizard() diff --git a/pcbnew/specctra_export.cpp b/pcbnew/specctra_export.cpp index e348c45c82..c9a85591d6 100644 --- a/pcbnew/specctra_export.cpp +++ b/pcbnew/specctra_export.cpp @@ -132,6 +132,11 @@ void PCB_EDIT_FRAME::ExportToSpecctra( wxCommandEvent& event ) if( fullFileName == wxEmptyString ) return; + ExportSpecctraFile( fullFileName ); +} + +bool PCB_EDIT_FRAME::ExportSpecctraFile( const wxString& aFullFilename ) +{ SPECCTRA_DB db; bool ok = true; wxString errorText; @@ -152,7 +157,7 @@ void PCB_EDIT_FRAME::ExportToSpecctra( wxCommandEvent& event ) { GetBoard()->SynchronizeNetsAndNetClasses(); db.FromBOARD( GetBoard() ); - db.ExportPCB( fullFileName, true ); + db.ExportPCB( aFullFilename, true ); // if an exception is thrown by FromBOARD or ExportPCB(), then // ~SPECCTRA_DB() will close the file. @@ -184,6 +189,8 @@ void PCB_EDIT_FRAME::ExportToSpecctra( wxCommandEvent& event ) errorText += _( "Unable to export, please fix and try again." ); DisplayError( this, errorText ); } + + return ok; } diff --git a/scripting/wx_python_helpers.cpp b/scripting/wx_python_helpers.cpp index a97314b355..8ee7bba28b 100644 --- a/scripting/wx_python_helpers.cpp +++ b/scripting/wx_python_helpers.cpp @@ -102,10 +102,14 @@ wxString* newWxStringFromPy( PyObject* src ) } if( must_unref_str ) + { Py_DECREF( uni_str ); + } if( must_unref_obj ) + { Py_DECREF( obj ); + } #else // normal string (or object) to normal python string @@ -136,7 +140,9 @@ wxString* newWxStringFromPy( PyObject* src ) result = new wxString( str_ptr, str_size ); if( must_unref_str ) + { Py_DECREF( str ); + } #endif