diff --git a/eeschema/find.cpp b/eeschema/find.cpp index 59ce3783ad..9828e2c74c 100644 --- a/eeschema/find.cpp +++ b/eeschema/find.cpp @@ -321,6 +321,20 @@ void SCH_EDIT_FRAME::OnFindSchematicItem( wxFindDialogEvent& aEvent ) { if( m_foundItems.GetCount() == 0 ) return; + + // Refresh the search cache in case something has changed. This prevents any stale + // pointers from crashing Eeschema when the wxEVT_FIND_CLOSE event is handled. + if( IsSearchCacheObsolete( searchCriteria ) ) + { + if( aEvent.GetFlags() & FR_CURRENT_SHEET_ONLY && g_RootSheet->CountSheets() > 1 ) + { + m_foundItems.Collect( searchCriteria, m_CurrentSheet ); + } + else + { + m_foundItems.Collect( searchCriteria ); + } + } } else if( IsSearchCacheObsolete( searchCriteria ) ) { @@ -353,6 +367,23 @@ void SCH_EDIT_FRAME::OnFindReplace( wxFindDialogEvent& aEvent ) SCH_SHEET_PATH* sheet; SCH_SHEET_LIST schematic; SCH_FIND_COLLECTOR_DATA data; + SCH_FIND_REPLACE_DATA searchCriteria; + + searchCriteria.SetFlags( aEvent.GetFlags() ); + searchCriteria.SetFindString( aEvent.GetFindString() ); + searchCriteria.SetReplaceString( aEvent.GetReplaceString() ); + + if( IsSearchCacheObsolete( searchCriteria ) ) + { + if( aEvent.GetFlags() & FR_CURRENT_SHEET_ONLY && g_RootSheet->CountSheets() > 1 ) + { + m_foundItems.Collect( searchCriteria, m_CurrentSheet ); + } + else + { + m_foundItems.Collect( searchCriteria ); + } + } if( aEvent.GetEventType() == wxEVT_COMMAND_FIND_REPLACE_ALL ) { @@ -430,20 +461,6 @@ void SCH_EDIT_FRAME::updateFindReplaceView( wxFindDialogEvent& aEvent ) searchCriteria.SetFindString( aEvent.GetFindString() ); searchCriteria.SetReplaceString( aEvent.GetReplaceString() ); - // Refresh the search cache in case something has changed. This prevents any stale - // pointers. - if( IsSearchCacheObsolete( searchCriteria ) ) - { - if( aEvent.GetFlags() & FR_CURRENT_SHEET_ONLY && g_RootSheet->CountSheets() > 1 ) - { - m_foundItems.Collect( searchCriteria, m_CurrentSheet ); - } - else - { - m_foundItems.Collect( searchCriteria ); - } - } - if( m_foundItems.GetItem( data ) != NULL ) { wxLogTrace( traceFindReplace, wxT( "Found " ) + m_foundItems.GetText() ); diff --git a/pcbnew/drc.cpp b/pcbnew/drc.cpp index e337edcca4..8d72d0afca 100644 --- a/pcbnew/drc.cpp +++ b/pcbnew/drc.cpp @@ -873,10 +873,13 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, D_PAD** aStart, D_PAD** aEnd, int x_li if( pad->GetPosition().x > x_limit ) break; - // No problem if pads are on different copper layers, + // No problem if pads which are on copper layers are on different copper layers, + // (pads can be only on a technical layer, to build complex pads) // but their hole (if any ) can create DRC error because they are on all // copper layers, so we test them - if( ( pad->GetLayerSet() & layerMask ) == 0 ) + if( ( pad->GetLayerSet() & layerMask ) == 0 && + ( pad->GetLayerSet() & all_cu ) != 0 && + ( aRefPad->GetLayerSet() & all_cu ) != 0 ) { // if holes are in the same location and have the same size and shape, // this can be accepted diff --git a/pcbnew/scripting/plugins/FPC_(SMD_type)_footprintwizard.py b/pcbnew/scripting/plugins/FPC_(SMD_type)_footprintwizard.py index 359509288b..9d087434e3 100644 --- a/pcbnew/scripting/plugins/FPC_(SMD_type)_footprintwizard.py +++ b/pcbnew/scripting/plugins/FPC_(SMD_type)_footprintwizard.py @@ -1,93 +1,69 @@ +# 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 source code file is part of KiCad, a free EDA CAD application. +# 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. # -# Copyright (C) 2013-2014 KiCad Developers, see change_log.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 +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. # -# This python script wizard creates a FPC connector -# for Surface Mounted Technology +from __future__ import division +import pcbnew + +import HelpfulFootprintWizardPlugin as HFPW -from pcbnew import * +class FPC_FootprintWizard(HFPW.HelpfulFootprintWizardPlugin): -class FPCFootprintWizard(FootprintWizardPlugin): - def __init__(self): - FootprintWizardPlugin.__init__(self) - self.name = "FPC" - self.description = "FPC (SMT connector) Footprint Wizard" - self.parameters = { - "Pads": - {"*n":40, # not internal units preceded by "*" - "pitch": FromMM(0.5), - "width": FromMM(0.25), - "height": FromMM(1.6)}, - "Shield": - {"shield_to_pad": FromMM(1.6), - "from_top": FromMM(1.3), - "width": FromMM(1.5), - "height": FromMM(2)} - } + def GetName(self): + return "FPC (SMT connector)" + + def GetDescription(self): + return "FPC (SMT connector) Footprint Wizard" + + def GetReferencePrefix(self): + return "J" + + def GetValue(self): + pins = self.parameters["Pads"]["*n"] + return "FPC_%d" % pins + + def GenerateParameterList(self): + self.AddParam( "Pads", "n", self.uNatural, 40 ) + self.AddParam( "Pads", "pitch", self.uMM, 0.5 ) + self.AddParam( "Pads", "width", self.uMM, 0.25 ) + self.AddParam( "Pads", "height", self.uMM, 1.6) + self.AddParam( "Shield", "shield_to_pad", self.uMM, 1.6 ) + self.AddParam( "Shield", "from_top", self.uMM, 1.3 ) + self.AddParam( "Shield", "width", self.uMM, 1.5 ) + self.AddParam( "Shield", "height", self.uMM, 2 ) - self.ClearErrors() # build a rectangular pad def smdRectPad(self,module,size,pos,name): - pad = D_PAD(module) - pad.SetSize(size) - pad.SetShape(PAD_SHAPE_RECT) - pad.SetAttribute(PAD_ATTRIB_SMD) - pad.SetLayerSet( pad.SMDMask() ) - pad.SetPos0(pos) - pad.SetPosition(pos) - pad.SetPadName(name) - return pad + pad = pcbnew.D_PAD(module) + pad.SetSize(size) + pad.SetShape(pcbnew.PAD_SHAPE_RECT) + pad.SetAttribute(pcbnew.PAD_ATTRIB_SMD) + pad.SetLayerSet( pad.SMDMask() ) + pad.SetPos0(pos) + pad.SetPosition(pos) + pad.SetPadName(name) + return pad - # This method checks the parameters provided to wizard and set errors def CheckParameters(self): p = self.parameters - pad_count = p["Pads"]["*n"] - errors = "" - if( pad_count < 1 ): - self.parameter_errors["Pads"]["n"]="Must be positive" - errors +="Pads/n has wrong value, " - 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"] - pad_pitch = p["Pads"]["pitch"] - shl_width = p["Shield"]["width"] - shl_height = p["Shield"]["height"] - shl_to_pad = p["Shield"]["shield_to_pad"] - shl_from_top = p["Shield"]["from_top"] - - return errors + self.CheckParamInt( "Pads", "*n" ) # not internal units preceded by "*" - # build the footprint from parameters - def BuildFootprint(self): - self.ClearErrors() - self.CheckParameters() - - module = MODULE(None) # create a new module - self.module = module - + def BuildThisFootprint(self): p = self.parameters pad_count = int(p["Pads"]["*n"]) pad_width = p["Pads"]["width"] @@ -99,115 +75,102 @@ class FPCFootprintWizard(FootprintWizardPlugin): shl_from_top = p["Shield"]["from_top"] 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) + size_pad = pcbnew.wxSize( pad_width, pad_height ) + size_shld = pcbnew.wxSize(shl_width, shl_height) + size_text = pcbnew.FromMM( 0.8 ) - 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 ) + textposy = pad_height/2 + pcbnew.FromMM(1) + self.draw.Value( 0, textposy, size_text ) - textposy = textposy + FromMM(1) - module.SetValue("Val***") # give it a default value - module.Value().SetPos0( wxPoint(0, textposy) ) - module.Value().SetTextPosition(module.Value().GetPos0()) - module.Value().SetSize( size_text ) - - fpid = FPID(self.module.GetReference()) #the name in library - module.SetFPID( fpid ) + textposy = textposy + pcbnew.FromMM( 1.2 ) + self.draw.Reference( 0, textposy, size_text ) # create a pad array and add it to the module 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) + pad = self.smdRectPad(self.module,size_pad, pcbnew.wxPoint(xpos,0),str(n+1)) + self.module.Add(pad) # Mechanical shield pads: left pad and right pad xpos = -shl_to_pad-offsetX - pad_s0_pos = wxPoint(xpos,shl_from_top) - pad_s0 = self.smdRectPad(module, size_shld, pad_s0_pos, "0") + pad_s0_pos = pcbnew.wxPoint(xpos,shl_from_top) + pad_s0 = self.smdRectPad(self.module, size_shld, pad_s0_pos, "0") 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") + pad_s1_pos = pcbnew.wxPoint(xpos,shl_from_top) + pad_s1 = self.smdRectPad(self.module, size_shld, pad_s1_pos, "0") - module.Add(pad_s0) - module.Add(pad_s1) + self.module.Add(pad_s0) + self.module.Add(pad_s1) #add outline - outline = EDGE_MODULE(module) - linewidth = FromMM(0.2) + outline = pcbnew.EDGE_MODULE(self.module) + linewidth = pcbnew.FromMM(0.2) outline.SetWidth(linewidth) - margin = FromMM(0.2) + margin = pcbnew.FromMM(0.2) # upper line posy = -pad_height/2 - linewidth/2 - margin xstart = - pad_pitch*0.5-offsetX 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) - module.Add(outline) + outline.SetStartEnd( pcbnew.wxPoint(xstart, posy), pcbnew.wxPoint( xend, posy) ) + outline.SetLayer(pcbnew.F_SilkS) #default: not needed + outline.SetShape(pcbnew.S_SEGMENT) + self.module.Add(outline) # lower line outline1 = outline.Duplicate() #copy all settings from outline posy = pad_height/2 + linewidth/2 + margin - outline1.SetStartEnd(wxPoint(xstart, posy), wxPoint( xend, posy)) - module.Add(outline1) + outline1.SetStartEnd(pcbnew.wxPoint(xstart, posy), pcbnew.wxPoint( xend, posy)) + self.module.Add(outline1) # around left mechanical pad (the outline around right pad is mirrored/y axix) outline2 = outline.Duplicate() # vertical segment 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.SetStartEnd(pcbnew.wxPoint(xstart, posy), pcbnew.wxPoint( xstart, yend)) + self.module.Add(outline2) + outline2_d = pcbnew.EDGE_MODULE(self.module) # right pad side outline2_d.Copy(outline2) - outline2_d.SetStartEnd(wxPoint(-xstart, posy), wxPoint( -xstart, yend)) - module.Add(outline2_d) + outline2_d.SetStartEnd(pcbnew.wxPoint(-xstart, posy), pcbnew.wxPoint( -xstart, yend)) + self.module.Add(outline2_d) outline3 = outline.Duplicate() # horizontal segment below the pad 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.SetStartEnd(pcbnew.wxPoint(xstart, posy), pcbnew.wxPoint( xend, posy)) + self.module.Add(outline3) + outline3_d = pcbnew.EDGE_MODULE(self.module) # right pad side outline3_d.Copy(outline3) - outline3_d.SetStartEnd(wxPoint(-xstart, posy), wxPoint( -xend, yend)) - module.Add(outline3_d) + outline3_d.SetStartEnd(pcbnew.wxPoint(-xstart, posy), pcbnew.wxPoint( -xend, yend)) + self.module.Add(outline3_d) outline4 = outline.Duplicate() # vertical segment at left of the pad xstart = xend yend = posy - (shl_height + linewidth + margin*2) - outline4.SetStartEnd(wxPoint(xstart, posy), wxPoint( xend, yend)) - module.Add(outline4) + outline4.SetStartEnd(pcbnew.wxPoint(xstart, posy), pcbnew.wxPoint( xend, yend)) + self.module.Add(outline4) outline4_d = outline.Duplicate() # right pad side - outline4_d.SetStartEnd(wxPoint(-xstart, posy), wxPoint( -xend, yend)) - module.Add(outline4_d) + outline4_d.SetStartEnd(pcbnew.wxPoint(-xstart, posy), pcbnew.wxPoint( -xend, yend)) + self.module.Add(outline4_d) outline5 = outline.Duplicate() # horizontal segment above the pad xstart = xend xend = - pad_pitch*0.5-offsetX posy = yend - outline5.SetStartEnd(wxPoint(xstart, posy), wxPoint( xend, yend)) - module.Add(outline5) + outline5.SetStartEnd(pcbnew.wxPoint(xstart, posy), pcbnew.wxPoint( xend, yend)) + self.module.Add(outline5) outline5_d = outline.Duplicate() # right pad side - outline5_d.SetStartEnd(wxPoint(-xstart, posy), wxPoint( -xend, yend)) - module.Add(outline5_d) + outline5_d.SetStartEnd(pcbnew.wxPoint(-xstart, posy), pcbnew.wxPoint( -xend, yend)) + self.module.Add(outline5_d) outline6 = outline.Duplicate() # vertical segment above the pad xstart = xend yend = -pad_height/2 - linewidth/2 - margin - outline6.SetStartEnd(wxPoint(xstart, posy), wxPoint( xend, yend)) - module.Add(outline6) + outline6.SetStartEnd(pcbnew.wxPoint(xstart, posy), pcbnew.wxPoint( xend, yend)) + self.module.Add(outline6) outline6_d = outline.Duplicate() # right pad side - outline6_d.SetStartEnd(wxPoint(-xstart, posy), wxPoint( -xend, yend)) - module.Add(outline6_d) + outline6_d.SetStartEnd(pcbnew.wxPoint(-xstart, posy), pcbnew.wxPoint( -xend, yend)) + self.module.Add(outline6_d) -# create our footprint wizard -fpc_wizard = FPCFootprintWizard() - -# register it into pcbnew -fpc_wizard.register() +FPC_FootprintWizard().register() diff --git a/pcbnew/scripting/plugins/touch_slider_wizard.py b/pcbnew/scripting/plugins/touch_slider_wizard.py index 132ba3892e..e575f8beea 100644 --- a/pcbnew/scripting/plugins/touch_slider_wizard.py +++ b/pcbnew/scripting/plugins/touch_slider_wizard.py @@ -173,7 +173,7 @@ class TouchSliderWizard(FootprintWizardPlugin): self.AddFinalPad(pos,touch_width,step_length,touch_clearance,str(steps)) # build the footprint from parameters - def BuildFootprint(self): + def BuildThisFootprint(self): module = MODULE(None) # create a new module self.module = module diff --git a/pcbnew/tool_modview.cpp b/pcbnew/tool_modview.cpp index 65ca148437..5a56a35ae8 100644 --- a/pcbnew/tool_modview.cpp +++ b/pcbnew/tool_modview.cpp @@ -186,7 +186,7 @@ void FOOTPRINT_VIEWER_FRAME::ReCreateMenuBar( void ) // Contents AddMenuItem( helpMenu, wxID_HELP, - _( "P&cbnew Manual" ), + _( "Pcbnew &Manual" ), _( "Open the Pcbnew manual" ), KiBitmap( online_help_xpm ) );