Allow Net Inspector to create, rename and delete nets.

ADDED: create/edit/delete nets in PCBnew Net Inspector
ADDED: update from PCB now allows updating of changed nets

Fixes https://gitlab.com/kicad/code/kicad/issues/1996
This commit is contained in:
Jeff Young 2020-06-08 19:36:25 +01:00
parent 570cc61b3f
commit e325d2e18f
22 changed files with 1182 additions and 513 deletions

View File

@ -36,7 +36,7 @@
#include <wx/textctrl.h>
#include <wx/textentry.h>
#include <wx/log.h>
#include <wx/combo.h>
GRID_CELL_TEXT_EDITOR::GRID_CELL_TEXT_EDITOR() : wxGridCellTextEditor()
{
@ -316,6 +316,63 @@ bool LIB_ID_VALIDATOR::Validate( wxWindow *aParent )
}
NETNAME_VALIDATOR::NETNAME_VALIDATOR( wxString *aVal ) :
wxTextValidator(),
m_allowSpaces( false )
{
}
NETNAME_VALIDATOR::NETNAME_VALIDATOR( const NETNAME_VALIDATOR& aValidator ) :
wxTextValidator( aValidator ),
m_allowSpaces( aValidator.m_allowSpaces )
{
}
NETNAME_VALIDATOR::NETNAME_VALIDATOR( bool aAllowSpaces ) :
wxTextValidator(),
m_allowSpaces( aAllowSpaces )
{
}
bool NETNAME_VALIDATOR::Validate( wxWindow *aParent )
{
// If window is disabled, simply return
if ( !m_validatorWindow->IsEnabled() )
return true;
wxTextEntry * const text = GetTextEntry();
if ( !text )
return false;
const wxString& errormsg = IsValid( text->GetValue() );
if( !errormsg.empty() )
{
m_validatorWindow->SetFocus();
wxMessageBox( errormsg, _( "Invalid signal name" ), wxOK | wxICON_EXCLAMATION, aParent );
return false;
}
return true;
}
wxString NETNAME_VALIDATOR::IsValid( const wxString& str ) const
{
if( str.Contains( '\r' ) || str.Contains( '\n' ) )
return _( "Signal names cannot contain CR or LF characters" );
if( !m_allowSpaces && ( str.Contains( ' ' ) || str.Contains( '\t' ) ) )
return _( "Signal names cannot contain spaces" );
return wxString();
}
void KIUI::ValidatorTransferToWindowWithoutEvents( wxValidator& aValidator )
{
wxWindow* ctrl = aValidator.GetWindow();

View File

@ -1,12 +1,8 @@
/**
* @file eeschema/dialogs/dialog_update_from_pcb.cpp
*/
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 Alexander Shuklin <Jasuramme@gmail.com>
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.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
@ -27,20 +23,14 @@
*/
#include <backannotate.h>
#include <class_draw_panel_gal.h>
#include <common.h>
#include <confirm.h>
#include <dialog_update_from_pcb.h>
#include <functional>
#include <sch_edit_frame.h>
#include <sch_editor_control.h>
#include <tool/tool_manager.h>
#include <view/view.h>
#include <wx_html_report_panel.h>
// Saved dialog settings
DIALOG_UPDATE_FROM_PCB::DIALOG_UPDATE_FROM_PCB_SAVED_STATE
DIALOG_UPDATE_FROM_PCB::s_savedDialogState{ true, false, false, false };
DIALOG_UPDATE_FROM_PCB::s_savedDialogState{ true, true, true, true, false };
DIALOG_UPDATE_FROM_PCB::DIALOG_UPDATE_FROM_PCB( SCH_EDIT_FRAME* aParent )
: DIALOG_UPDATE_FROM_PCB_BASE( aParent ),
@ -55,6 +45,7 @@ DIALOG_UPDATE_FROM_PCB::DIALOG_UPDATE_FROM_PCB( SCH_EDIT_FRAME* aParent )
m_cbUpdateReferences->SetValue( s_savedDialogState.UpdateReferences );
m_cbUpdateFootprints->SetValue( s_savedDialogState.UpdateFootprints );
m_cbUpdateValues->SetValue( s_savedDialogState.UpdateValues );
m_cbUpdateNetNames->SetValue( s_savedDialogState.UpdateNetNames );
m_cbIgnoreOtherProjects->SetValue( s_savedDialogState.IgnoreOtherProjectsErrors );
// We use a sdbSizer to get platform-dependent ordering of the action buttons, but
@ -67,22 +58,23 @@ DIALOG_UPDATE_FROM_PCB::DIALOG_UPDATE_FROM_PCB( SCH_EDIT_FRAME* aParent )
FinishDialogSettings();
}
BACK_ANNOTATE::SETTINGS DIALOG_UPDATE_FROM_PCB::getSettings( bool aDryRun )
{
return BACK_ANNOTATE::SETTINGS{ m_messagePanel->Reporter(), m_cbUpdateFootprints->GetValue(),
m_cbUpdateValues->GetValue(), m_cbUpdateReferences->GetValue(),
m_cbIgnoreOtherProjects->GetValue(), aDryRun };
}
void DIALOG_UPDATE_FROM_PCB::updateData()
{
bool successfulRun = false;
m_messagePanel->Clear();
BACK_ANNOTATE backAnno( this->m_frame, getSettings( true ) );
BACK_ANNOTATE backAnno( this->m_frame,
m_messagePanel->Reporter(),
m_cbUpdateFootprints->GetValue(),
m_cbUpdateValues->GetValue(),
m_cbUpdateReferences->GetValue(),
m_cbUpdateNetNames->GetValue(),
m_cbIgnoreOtherProjects->GetValue(),
true );
std::string netlist;
if( backAnno.FetchNetlistFromPCB( netlist ) )
successfulRun = backAnno.BackAnnotateSymbols( netlist );
m_sdbSizerOK->Enable( successfulRun );
m_messagePanel->Flush( false );
}
@ -103,23 +95,22 @@ void DIALOG_UPDATE_FROM_PCB::OnOptionChanged( wxCommandEvent& event )
s_savedDialogState.UpdateReferences = m_cbUpdateReferences->GetValue();
s_savedDialogState.UpdateFootprints = m_cbUpdateFootprints->GetValue();
s_savedDialogState.UpdateValues = m_cbUpdateValues->GetValue();
s_savedDialogState.UpdateNetNames = m_cbUpdateNetNames->GetValue();
s_savedDialogState.IgnoreOtherProjectsErrors = m_cbIgnoreOtherProjects->GetValue();
}
void DIALOG_UPDATE_FROM_PCB::OnUpdateClick( wxCommandEvent& event )
{
KIDIALOG dlg( this,
_( "\n\nThis operation will change the existing annotation and cannot be undone." ),
_( "Confirmation" ), wxOK | wxCANCEL | wxICON_WARNING );
dlg.SetOKLabel( _( "Back annotate" ) );
dlg.DoNotShowCheckbox( __FILE__, __LINE__ );
if( dlg.ShowModal() == wxID_CANCEL )
return;
std::string netlist;
m_messagePanel->Clear();
BACK_ANNOTATE backAnno( this->m_frame, getSettings( false ) );
BACK_ANNOTATE backAnno( m_frame,
m_messagePanel->Reporter(),
m_cbUpdateFootprints->GetValue(),
m_cbUpdateValues->GetValue(),
m_cbUpdateReferences->GetValue(),
m_cbUpdateNetNames->GetValue(),
m_cbIgnoreOtherProjects->GetValue(),
false );
if( backAnno.FetchNetlistFromPCB( netlist ) && backAnno.BackAnnotateSymbols( netlist ) )
{

View File

@ -1,12 +1,8 @@
/**
* @file eeschema/dialogs/dialog_update_from_pcb.h
*/
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 Alexander Shuklin <Jasuramme@gmail.com>
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.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
@ -38,7 +34,6 @@ class SCH_EDITOR_CONTROL;
class DIALOG_UPDATE_FROM_PCB : public DIALOG_UPDATE_FROM_PCB_BASE
{
/**
* Struct containing the dialog last saved state
*/
@ -48,6 +43,7 @@ class DIALOG_UPDATE_FROM_PCB : public DIALOG_UPDATE_FROM_PCB_BASE
bool UpdateReferences;
bool UpdateFootprints;
bool UpdateValues;
bool UpdateNetNames;
bool IgnoreOtherProjectsErrors;
};
@ -64,13 +60,6 @@ public:
private:
void updateData();
/**
* @brief Creates back annotate settings from dialog ui
* @param aDryRun - is it dry run
* @return back annotation settings structure
*/
BACK_ANNOTATE::SETTINGS getSettings( bool aDryRun );
bool TransferDataToWindow() override;
void OnOptionChanged( wxCommandEvent& event ) override;
void OnUpdateClick( wxCommandEvent& event ) override;

View File

@ -54,6 +54,12 @@ DIALOG_UPDATE_FROM_PCB_BASE::DIALOG_UPDATE_FROM_PCB_BASE( wxWindow* parent, wxWi
fgSizer1->Add( m_cbUpdateFootprints, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
fgSizer1->Add( 0, 0, 1, wxEXPAND, 5 );
m_cbUpdateNetNames = new wxCheckBox( sbSizerOptions->GetStaticBox(), wxID_ANY, _("Update net names"), wxDefaultPosition, wxDefaultSize, 0 );
fgSizer1->Add( m_cbUpdateNetNames, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );
sbSizerOptions->Add( fgSizer1, 1, wxEXPAND, 5 );
@ -91,6 +97,7 @@ DIALOG_UPDATE_FROM_PCB_BASE::DIALOG_UPDATE_FROM_PCB_BASE( wxWindow* parent, wxWi
m_cbIgnoreOtherProjects->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this );
m_cbUpdateValues->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this );
m_cbUpdateFootprints->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this );
m_cbUpdateNetNames->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this );
m_sdbSizerOK->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnUpdateClick ), NULL, this );
}
@ -101,6 +108,7 @@ DIALOG_UPDATE_FROM_PCB_BASE::~DIALOG_UPDATE_FROM_PCB_BASE()
m_cbIgnoreOtherProjects->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this );
m_cbUpdateValues->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this );
m_cbUpdateFootprints->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this );
m_cbUpdateNetNames->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnOptionChanged ), NULL, this );
m_sdbSizerOK->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_UPDATE_FROM_PCB_BASE::OnUpdateClick ), NULL, this );
}

View File

@ -365,6 +365,81 @@
<event name="OnCheckBox">OnOptionChanged</event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="spacer" expanded="1">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Update net names</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_cbUpdateNetNames</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnCheckBox">OnOptionChanged</event>
</object>
</object>
</object>
</object>
</object>

View File

@ -39,6 +39,7 @@ class DIALOG_UPDATE_FROM_PCB_BASE : public DIALOG_SHIM
wxCheckBox* m_cbIgnoreOtherProjects;
wxCheckBox* m_cbUpdateValues;
wxCheckBox* m_cbUpdateFootprints;
wxCheckBox* m_cbUpdateNetNames;
WX_HTML_REPORT_PANEL* m_messagePanel;
wxStdDialogButtonSizer* m_sdbSizer;
wxButton* m_sdbSizerOK;

View File

@ -142,9 +142,9 @@ SCH_COMPONENT::SCH_COMPONENT( LIB_PART& aPart, LIB_ID aLibId, SCH_SHEET_PATH* sh
}
SCH_COMPONENT::SCH_COMPONENT(
LIB_PART& aPart, SCH_SHEET_PATH* aSheet, COMPONENT_SELECTION& aSel, const wxPoint& pos )
: SCH_COMPONENT( aPart, aSel.LibId, aSheet, aSel.Unit, aSel.Convert, pos )
SCH_COMPONENT::SCH_COMPONENT( LIB_PART& aPart, SCH_SHEET_PATH* aSheet, COMPONENT_SELECTION& aSel,
const wxPoint& pos ) :
SCH_COMPONENT( aPart, aSel.LibId, aSheet, aSel.Unit, aSel.Convert, pos )
{
// Set any fields that were modified as part of the component selection
for( auto const& i : aSel.Fields )
@ -262,9 +262,7 @@ void SCH_COMPONENT::SetLibSymbol( LIB_PART* aLibSymbol )
wxString SCH_COMPONENT::GetDescription() const
{
if( m_part )
{
return m_part->GetDescription();
}
return wxEmptyString;
}

View File

@ -27,6 +27,7 @@
* @brief Implementation of control validators for schematic dialogs.
*/
#include <sch_connection.h>
#include <wx/combo.h>
#include <sch_validators.h>
#include <project/net_settings.h>
@ -183,73 +184,6 @@ bool SCH_FIELD_VALIDATOR::Validate( wxWindow *aParent )
}
SCH_NETNAME_VALIDATOR::SCH_NETNAME_VALIDATOR( wxString *aVal )
: wxValidator(),
m_allowSpaces( false )
{
}
SCH_NETNAME_VALIDATOR::SCH_NETNAME_VALIDATOR( const SCH_NETNAME_VALIDATOR& aValidator )
: wxValidator(),
m_allowSpaces( aValidator.m_allowSpaces )
{
}
SCH_NETNAME_VALIDATOR::SCH_NETNAME_VALIDATOR( bool aAllowSpaces )
: wxValidator(),
m_allowSpaces( aAllowSpaces )
{
}
wxTextEntry *SCH_NETNAME_VALIDATOR::GetTextEntry()
{
#if wxUSE_TEXTCTRL
if( wxDynamicCast( m_validatorWindow, wxTextCtrl ) )
return static_cast<wxTextCtrl*>( m_validatorWindow );
#endif
#if wxUSE_COMBOBOX
if( wxDynamicCast( m_validatorWindow, wxComboBox ) )
return static_cast<wxComboBox*>( m_validatorWindow );
#endif
#if wxUSE_COMBOCTRL
if( wxDynamicCast( m_validatorWindow, wxComboCtrl ) )
return static_cast<wxComboCtrl*>( m_validatorWindow );
#endif
wxFAIL_MSG( "SCH_NETNAME_VALIDATOR can only be used with wxTextCtrl, wxComboBox, or wxComboCtrl" );
return nullptr;
}
bool SCH_NETNAME_VALIDATOR::Validate( wxWindow *aParent )
{
// If window is disabled, simply return
if ( !m_validatorWindow->IsEnabled() )
return true;
wxTextEntry * const text = GetTextEntry();
if ( !text )
return false;
const wxString& errormsg = IsValid( text->GetValue() );
if( !errormsg.empty() )
{
m_validatorWindow->SetFocus();
wxMessageBox( errormsg, _( "Invalid signal name" ), wxOK | wxICON_EXCLAMATION, aParent );
return false;
}
return true;
}
wxString SCH_NETNAME_VALIDATOR::IsValid( const wxString& str ) const
{
if( NET_SETTINGS::ParseBusGroup( str, nullptr, nullptr ) )
@ -259,11 +193,5 @@ wxString SCH_NETNAME_VALIDATOR::IsValid( const wxString& str ) const
!NET_SETTINGS::ParseBusVector( str, nullptr, nullptr ) )
return _( "Signal name contains '[' or ']' but is not a valid vector bus name" );
if( str.Contains( '\r' ) || str.Contains( '\n' ) )
return _( "Signal names cannot contain CR or LF characters" );
if( !m_allowSpaces && ( str.Contains( ' ' ) || str.Contains( '\t' ) ) )
return _( "Signal names cannot contain spaces" );
return wxString();
return NETNAME_VALIDATOR::IsValid( str );
}

View File

@ -31,7 +31,7 @@
#define _SCH_VALIDATORS_H_
#include <wx/valtext.h>
#include <validators.h>
#define FIELD_NAME -1
#define FIELD_VALUE -2
@ -71,38 +71,27 @@ public:
};
class SCH_NETNAME_VALIDATOR : public wxValidator
/*
* A refinement of the NETNAME_VALIDATOR which also allows (and checks) bus definitions.
*/
class SCH_NETNAME_VALIDATOR : public NETNAME_VALIDATOR
{
public:
SCH_NETNAME_VALIDATOR( wxString *aVal = nullptr );
SCH_NETNAME_VALIDATOR( wxString *aVal = nullptr ) :
NETNAME_VALIDATOR( aVal )
{ }
SCH_NETNAME_VALIDATOR( bool aAllowSpaces );
SCH_NETNAME_VALIDATOR( bool aAllowSpaces ) :
NETNAME_VALIDATOR( aAllowSpaces )
{ }
SCH_NETNAME_VALIDATOR( const SCH_NETNAME_VALIDATOR& aValidator );
void SetAllowSpaces( bool aAllowSpaces = true ) { m_allowSpaces = aAllowSpaces; }
bool GetAllowSpaces() const { return m_allowSpaces; }
bool Copy( const SCH_NETNAME_VALIDATOR& val );
virtual wxObject* Clone() const override { return new SCH_NETNAME_VALIDATOR( *this ); }
virtual bool TransferToWindow() override { return true; }
virtual bool TransferFromWindow() override { return true; }
wxTextEntry* GetTextEntry();
virtual bool Validate( wxWindow *aParent ) override;
SCH_NETNAME_VALIDATOR( const SCH_NETNAME_VALIDATOR& aValidator ) :
NETNAME_VALIDATOR( aValidator )
{ }
protected:
// returns the error message if the contents of 'val' are invalid
virtual wxString IsValid( const wxString& aVal ) const;
private:
bool m_allowSpaces;
wxString IsValid( const wxString& aVal ) const override;
};
#endif // _SCH_VALIDATORS_H_

View File

@ -1,12 +1,8 @@
/**
* @file eeschema/tools/backannotate.cpp
*/
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 Alexander Shuklin <Jasuramme@gmail.com>
* Copyright (C) 2004-2019 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2004-2020 KiCad Developers, see AUTHORS.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
@ -31,18 +27,25 @@
#include <boost/property_tree/ptree.hpp>
#include <confirm.h>
#include <dsnlexer.h>
#include <kiface_i.h>
#include <macros.h>
#include <ptree.h>
#include <reporter.h>
#include <sch_edit_frame.h>
#include <sch_sheet_path.h>
#include <schematic.h>
#include <utf8.h>
#include <kiface_i.h>
BACK_ANNOTATE::BACK_ANNOTATE( SCH_EDIT_FRAME* aFrame, SETTINGS aSettings ) :
m_settings( aSettings ),
BACK_ANNOTATE::BACK_ANNOTATE( SCH_EDIT_FRAME* aFrame, REPORTER& aReporter,
bool aProcessFootprints, bool aProcessValues,
bool aProcessReferences, bool aProcessNetNames,
bool aIgnoreOtherProjects, bool aDryRun ) :
m_reporter( aReporter ),
m_processFootprints( aProcessFootprints ),
m_processValues( aProcessValues ),
m_processReferences( aProcessReferences ),
m_processNetNames( aProcessNetNames ),
m_ignoreOtherProjects( aIgnoreOtherProjects ),
m_dryRun( aDryRun ),
m_frame( aFrame ),
m_changesCount( 0 )
{
@ -59,103 +62,100 @@ bool BACK_ANNOTATE::BackAnnotateSymbols( const std::string& aNetlist )
m_changesCount = 0;
wxString msg;
if( !m_settings.processValues && !m_settings.processFootprints
&& !m_settings.processReferences )
if( !m_processValues && !m_processFootprints && !m_processReferences && !m_processNetNames )
{
m_settings.reporter.ReportTail(
_( "Select at least one property to back annotate" ), RPT_SEVERITY_ERROR );
m_reporter.ReportTail( _( "Select at least one property to back annotate." ),
RPT_SEVERITY_ERROR );
return false;
}
int errors = getPcbModulesFromString( aNetlist );
getPcbModulesFromString( aNetlist );
SCH_SHEET_LIST sheets = m_frame->Schematic().GetSheets();
sheets.GetComponents( m_refs, false );
sheets.GetMultiUnitComponents( m_multiUnitsRefs );
errors += getChangeList();
errors += checkForUnusedSymbols();
errors += checkSharedSchematicErrors();
getChangeList();
checkForUnusedSymbols();
checkSharedSchematicErrors();
if( errors > 0 )
m_settings.dryRun = true;
SCH_SHEET_PATH current = m_frame->GetCurrentSheet();
applyChangelist();
m_frame->SetCurrentSheet( current );
if( !errors )
{
if( !m_settings.dryRun )
{
msg.Printf( _( "Schematic is back-annotated. %d changes applied." ), m_changesCount );
m_settings.reporter.ReportTail( msg, RPT_SEVERITY_ACTION );
}
else
m_settings.reporter.ReportTail(
_( "No errors during dry run. Ready to go." ), RPT_SEVERITY_ACTION );
}
else
{
msg.Printf( _( "Found %d errors. Fix them and run back annotation." ), errors );
m_settings.reporter.ReportTail( msg, RPT_SEVERITY_ERROR );
}
return !errors;
return true;
}
bool BACK_ANNOTATE::FetchNetlistFromPCB( std::string& aNetlist )
{
if( Kiface().IsSingle() )
{
DisplayErrorMessage(
m_frame, _( "Cannot fetch PCB netlist because eeschema is opened in "
"stand-alone mode.\n"
"You must launch the KiCad project manager "
"and create a project." ) );
return false;
}
KIWAY_PLAYER* player = m_frame->Kiway().Player( FRAME_PCB_EDITOR, false );
if( !player )
{
DisplayErrorMessage(
this->m_frame, _( "Please open Pcbnew and run back annotation again" ) );
DisplayErrorMessage( m_frame, _( "Cannot fetch PCB netlist because eeschema is opened "
"in stand-alone mode.\n"
"You must launch the KiCad project manager and create "
"a project." ) );
return false;
}
m_frame->Kiway().Player( FRAME_PCB_EDITOR, true );
m_frame->Kiway().ExpressMail( FRAME_PCB_EDITOR, MAIL_PCB_GET_NETLIST, aNetlist );
return true;
}
int BACK_ANNOTATE::getPcbModulesFromString( const std::string& aPayload )
void BACK_ANNOTATE::getPcbModulesFromString( const std::string& aPayload )
{
auto getStr = []( const PTREE& pt ) -> wxString
{
return UTF8( pt.front().first );
};
DSNLEXER lexer( aPayload, FROM_UTF8( __func__ ) );
PTREE doc;
Scan( &doc, &lexer );
CPTREE& tree = doc.get_child( "pcb_netlist" );
wxString msg;
int errors = 0;
// NOTE: KiCad's PTREE scanner constructs a property *name* tree, not a property tree.
// Every token in the s-expr is stored as a property name; the property's value is then
// either the nested s-exprs or an empty PTREE; there are *no* literal property values.
Scan( &doc, &lexer );
PTREE& tree = doc.get_child( "pcb_netlist" );
wxString msg;
m_pcbModules.clear();
for( auto& item : tree )
for( const std::pair<const std::string, PTREE>& item : tree )
{
wxString path, value, footprint;
std::map<wxString, wxString> pinNetMap;
wxASSERT( item.first == "ref" );
wxString ref = UTF8( item.second.front().first );
wxString ref = getStr( item.second );
try
{
path = UTF8( item.second.get_child( "timestamp" ).front().first );
path = getStr( item.second.get_child( "timestamp" ) );
if( path == "" )
{
msg.Printf( _( "Footprint \"%s\" has no symbol associated." ), ref );
m_settings.reporter.ReportHead( msg, RPT_SEVERITY_WARNING );
m_reporter.ReportHead( msg, RPT_SEVERITY_WARNING );
continue;
}
footprint = UTF8( item.second.get_child( "fpid" ).front().first );
value = UTF8( item.second.get_child( "value" ).front().first );
footprint = getStr( item.second.get_child( "fpid" ) );
value = getStr( item.second.get_child( "value" ) );
boost::optional<const PTREE&> nets = item.second.get_child_optional( "nets" );
if( nets )
{
for( const std::pair<const std::string, PTREE>& pin_net : nets.get() )
{
wxASSERT( pin_net.first == "pin_net" );
wxString pinNumber = UTF8( pin_net.second.front().first );
wxString netName = UTF8( pin_net.second.back().first );
pinNetMap[ pinNumber ] = netName;
}
}
}
catch( ... )
{
@ -169,34 +169,30 @@ int BACK_ANNOTATE::getPcbModulesFromString( const std::string& aPayload )
{
// Module with this path already exists - generate error
msg.Printf( _( "Pcb footprints \"%s\" and \"%s\" linked to same symbol" ),
nearestItem->second->ref, ref );
m_settings.reporter.ReportHead( msg, RPT_SEVERITY_ERROR );
++errors;
nearestItem->second->m_ref, ref );
m_reporter.ReportHead( msg, RPT_SEVERITY_ERROR );
}
else
{
// Add module to the map
PCB_MODULE_DATA data( ref, footprint, value );
m_pcbModules.insert( nearestItem,
std::make_pair( path, std::make_shared<PCB_MODULE_DATA>( data ) ) );
auto data = std::make_shared<PCB_MODULE_DATA>( ref, footprint, value, pinNetMap );
m_pcbModules.insert( nearestItem, std::make_pair( path, data ) );
}
}
return errors;
}
int BACK_ANNOTATE::getChangeList()
{
int errors = 0;
for( auto& module : m_pcbModules )
void BACK_ANNOTATE::getChangeList()
{
for( std::pair<const wxString, std::shared_ptr<PCB_MODULE_DATA>>& module : m_pcbModules )
{
auto& pcbPath = module.first;
auto& pcbData = module.second;
bool foundInMultiunit = false;
const wxString& pcbPath = module.first;
auto& pcbData = module.second;
bool foundInMultiunit = false;
for( auto& item : m_multiUnitsRefs )
{
auto& refList = item.second;
SCH_REFERENCE_LIST& refList = item.second;
if( refList.FindRefByPath( pcbPath ) >= 0 )
{
@ -206,8 +202,10 @@ int BACK_ANNOTATE::getChangeList()
foundInMultiunit = true;
for( size_t i = 0; i < refList.GetCount(); ++i )
{
m_changelist.push_back( CHANGELIST_ITEM( refList[i], pcbData ) );
refList[i].GetComp()->ClearFlags( SKIP_STRUCT );
m_changelist.emplace_back( CHANGELIST_ITEM( refList[i], pcbData ) );
}
break;
}
}
@ -218,23 +216,22 @@ int BACK_ANNOTATE::getChangeList()
int refIndex = m_refs.FindRefByPath( pcbPath );
if( refIndex >= 0 )
m_changelist.push_back( CHANGELIST_ITEM( m_refs[refIndex], pcbData ) );
{
m_refs[refIndex].GetComp()->ClearFlags( SKIP_STRUCT );
m_changelist.emplace_back( CHANGELIST_ITEM( m_refs[refIndex], pcbData ) );
}
else
{
// Haven't found linked symbol in multiunits or common refs. Generate error
wxString msg;
msg.Printf( _( "Cannot find symbol for \"%s\" footprint" ), pcbData->ref );
++errors;
m_settings.reporter.ReportTail( msg, RPT_SEVERITY_ERROR );
msg.Printf( _( "Cannot find symbol for \"%s\" footprint" ), pcbData->m_ref );
m_reporter.ReportTail( msg, RPT_SEVERITY_ERROR );
}
}
return errors;
}
int BACK_ANNOTATE::checkForUnusedSymbols()
void BACK_ANNOTATE::checkForUnusedSymbols()
{
int errors = 0;
m_refs.SortByTimeStamp();
std::sort( m_changelist.begin(), m_changelist.end(),
@ -244,32 +241,31 @@ int BACK_ANNOTATE::checkForUnusedSymbols()
} );
size_t i = 0;
for( auto& item : m_changelist )
{
// Refs and changelist are both sorted by paths, so we just go over m_refs and
// generate errors before we will find m_refs member to which item linked
while( i < m_refs.GetCount() && m_refs[i].GetPath() != item.first.GetPath() )
{
++errors;
wxString msg;
msg.Printf( _( "Cannot find footprint for \"%s\" symbol" ), m_refs[i++].GetFullRef() );
m_settings.reporter.ReportTail( msg, RPT_SEVERITY_ERROR );
m_reporter.ReportTail( msg, RPT_SEVERITY_ERROR );
}
++i;
}
return errors;
}
bool BACK_ANNOTATE::checkReuseViolation( PCB_MODULE_DATA& aFirst, PCB_MODULE_DATA& aSecond )
{
if( m_settings.processFootprints && aFirst.footprint != aSecond.footprint )
if( m_processFootprints && aFirst.m_footprint != aSecond.m_footprint )
return false;
if( m_settings.processValues && aFirst.value != aSecond.value )
if( m_processValues && aFirst.m_value != aSecond.m_value )
return false;
return true;
}
@ -279,18 +275,17 @@ wxString BACK_ANNOTATE::getTextFromField( const SCH_REFERENCE& aRef, const NumFi
}
int BACK_ANNOTATE::checkSharedSchematicErrors()
void BACK_ANNOTATE::checkSharedSchematicErrors()
{
std::sort( m_changelist.begin(), m_changelist.end(),
[]( CHANGELIST_ITEM& a, CHANGELIST_ITEM& b ) {
return a.first.GetComp() > b.first.GetComp();
} );
[]( CHANGELIST_ITEM& a, CHANGELIST_ITEM& b )
{
return a.first.GetComp() > b.first.GetComp();
} );
// We don't check that if no footprints or values updating
if( !m_settings.processFootprints && !m_settings.processValues )
return 0;
int errors = 0;
if( !m_processFootprints && !m_processValues )
return;
// We will count how many times every component used in our changelist
// Component in this case is SCH_COMPONENT which can be used by more than one symbol
@ -307,90 +302,302 @@ int BACK_ANNOTATE::checkSharedSchematicErrors()
if( ( it + 1 ) != m_changelist.end() && it->first.GetComp() == ( it + 1 )->first.GetComp() )
{
++usageCount;
if( !checkReuseViolation( *it->second, *( it + 1 )->second ) )
{
// Refs share same component but have different values or footprints
++errors;
it->first.GetComp()->SetFlags( SKIP_STRUCT );
wxString msg;
msg.Printf( _( "\"%s\" and \"%s\" use the same schematic symbol.\n"
"They cannot have different footprints or values." ),
( it + 1 )->second->ref, it->second->ref );
m_settings.reporter.ReportTail( msg, RPT_SEVERITY_ERROR );
( it + 1 )->second->m_ref,
it->second->m_ref );
m_reporter.ReportTail( msg, RPT_SEVERITY_ERROR );
}
}
else
{
/* Next ref uses different component, so we count all components number for current
one. We compare that number to stored in the component itself. If that differs, it
means that this particular component is reused in some another project. */
if( !m_settings.ignoreOtherProjects && compUsage > usageCount )
means that this particular component is reused in some other project. */
if( !m_ignoreOtherProjects && compUsage > usageCount )
{
PCB_MODULE_DATA tmp{ "", getTextFromField( it->first, FOOTPRINT ),
getTextFromField( it->first, VALUE ) };
PCB_MODULE_DATA tmp{ "",
getTextFromField( it->first, FOOTPRINT ),
getTextFromField( it->first, VALUE ),
{} };
if( !checkReuseViolation( tmp, *it->second ) )
{
it->first.GetComp()->SetFlags( SKIP_STRUCT );
wxString msg;
msg.Printf( _( "Unable to change \"%s\" footprint or value because associated"
" symbol is reused in the another project" ),
it->second->ref );
m_settings.reporter.ReportTail( msg, RPT_SEVERITY_ERROR );
++errors;
it->second->m_ref );
m_reporter.ReportTail( msg, RPT_SEVERITY_ERROR );
}
}
usageCount = 1;
}
}
return errors;
}
void BACK_ANNOTATE::applyChangelist()
{
wxString msg;
int leftUnchanged = 0;
std::set<wxString> handledNetChanges;
wxString msg;
int leftUnchanged = 0;
// Apply changes from change list
for( auto& item : m_changelist )
for( CHANGELIST_ITEM& item : m_changelist )
{
SCH_REFERENCE& ref = item.first;
PCB_MODULE_DATA& module = *item.second;
wxString oldFootprint = getTextFromField( ref, FOOTPRINT );
wxString oldValue = getTextFromField( ref, VALUE );
int changesCountBefore = m_changesCount;
bool skip = ( ref.GetComp()->GetFlags() & SKIP_STRUCT ) > 0;
if( m_settings.processReferences && ref.GetRef() != module.ref )
if( m_processReferences && ref.GetRef() != module.m_ref && !skip )
{
++m_changesCount;
msg.Printf( _( "Change \"%s\" reference designator to \"%s\"." ), ref.GetFullRef(), module.ref );
if( !m_settings.dryRun )
ref.GetComp()->SetRef( &ref.GetSheetPath(), module.ref );
m_settings.reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
msg.Printf( _( "Change \"%s\" reference designator to \"%s\"." ),
ref.GetFullRef(),
module.m_ref );
if( !m_dryRun )
ref.GetComp()->SetRef( &ref.GetSheetPath(), module.m_ref );
m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
}
if( m_settings.processFootprints && oldFootprint != module.footprint )
if( m_processFootprints && oldFootprint != module.m_footprint && !skip )
{
++m_changesCount;
msg.Printf( _( "Change %s footprint from \"%s\" to \"%s\"." ), ref.GetFullRef(),
getTextFromField( ref, FOOTPRINT ), module.footprint );
msg.Printf( _( "Change %s footprint from \"%s\" to \"%s\"." ),
ref.GetFullRef(),
getTextFromField( ref, FOOTPRINT ),
module.m_footprint );
if( !m_settings.dryRun )
ref.GetComp()->GetField( FOOTPRINT )->SetText( module.footprint );
m_settings.reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
if( !m_dryRun )
ref.GetComp()->GetField( FOOTPRINT )->SetText( module.m_footprint );
m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
}
if( m_settings.processValues && oldValue != module.value )
if( m_processValues && oldValue != module.m_value && !skip )
{
++m_changesCount;
msg.Printf( _( "Change \"%s\" value from \"%s\" to \"\"%s\"." ), ref.GetFullRef(),
getTextFromField( ref, VALUE ), module.value );
if( !m_settings.dryRun )
item.first.GetComp()->GetField( VALUE )->SetText( module.value );
m_settings.reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
msg.Printf( _( "Change %s value from \"%s\" to \"%s\"." ),
ref.GetFullRef(),
getTextFromField( ref, VALUE ),
module.m_value );
if( !m_dryRun )
item.first.GetComp()->GetField( VALUE )->SetText( module.m_value );
m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
}
if( m_processNetNames )
{
for( const std::pair<const wxString, wxString>& entry : module.m_pinMap )
{
const wxString& pinNumber = entry.first;
const wxString& shortNetName = entry.second;
SCH_COMPONENT* comp = ref.GetComp();
LIB_PIN* pin = comp->GetPin( pinNumber );
SCH_CONNECTION* conn = comp->GetConnectionForPin( pin, ref.GetSheetPath() );
wxString key = shortNetName + ref.GetSheetPath().PathAsString();
if( handledNetChanges.count( key ) )
continue;
else
handledNetChanges.insert( key );
if( conn && conn->Name( true ) != shortNetName )
processNetNameChange( conn, conn->Name( true ), shortNetName );
}
}
if( changesCountBefore == m_changesCount )
++leftUnchanged;
}
msg.Printf( _( "%d symbols left unchanged" ), leftUnchanged );
m_settings.reporter.ReportHead( msg, RPT_SEVERITY_INFO );
m_reporter.ReportHead( msg, RPT_SEVERITY_INFO );
}
void BACK_ANNOTATE::processNetNameChange( SCH_CONNECTION* aConn, const wxString& aOldName,
const wxString& aNewName )
{
wxString msg;
SCH_ITEM* driver = aConn->Driver();
auto editMatchingLabels =
[this]( SCH_SCREEN* aScreen, KICAD_T aType, const wxString& oldName,
const wxString& newName )
{
for( SCH_ITEM* schItem : aScreen->Items().OfType( aType ) )
{
SCH_TEXT* label = static_cast<SCH_TEXT*>( schItem );
if( EscapeString( label->GetShownText(), CTX_NETNAME ) == oldName )
{
m_frame->SaveCopyInUndoList( label, UR_CHANGED );
static_cast<SCH_TEXT*>( label )->SetText( newName );
}
}
};
switch( driver->Type() )
{
case SCH_LABEL_T:
++m_changesCount;
msg.Printf( _( "Change \"%s\" labels to \"%s\"." ),
aOldName,
aNewName );
if( !m_dryRun )
{
m_frame->Schematic().SetCurrentSheet( aConn->Sheet() );
for( SCH_ITEM* label : m_frame->GetScreen()->Items().OfType( SCH_LABEL_T ) )
{
SCH_CONNECTION* conn = label->Connection( aConn->Sheet() );
if( conn && conn->Driver() == driver )
{
m_frame->SaveCopyInUndoList( label, UR_CHANGED );
static_cast<SCH_TEXT*>( label )->SetText( aNewName );
}
}
}
m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
break;
case SCH_GLOBAL_LABEL_T:
++m_changesCount;
msg.Printf( _( "Change \"%s\" global labels to \"%s\"." ),
aConn->Name( true ),
aNewName );
if( !m_dryRun )
{
SCH_SHEET_LIST all_sheets = m_frame->Schematic().GetSheets();
for( const SCH_SHEET_PATH& sheet : all_sheets )
{
m_frame->Schematic().SetCurrentSheet( sheet );
editMatchingLabels( m_frame->GetScreen(), SCH_GLOBAL_LABEL_T, aOldName, aNewName );
}
}
m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
break;
case SCH_HIER_LABEL_T:
++m_changesCount;
msg.Printf( _( "Change \"%s\" hierarchical label to \"%s\"." ),
aConn->Name( true ),
aNewName );
if( !m_dryRun )
{
m_frame->Schematic().SetCurrentSheet( aConn->Sheet() );
editMatchingLabels( m_frame->GetScreen(), SCH_HIER_LABEL_T, aOldName, aNewName );
SCH_SHEET* sheet = dynamic_cast<SCH_SHEET*>( driver->GetParent() );
m_frame->SetScreen( sheet->GetScreen() );
for( SCH_SHEET_PIN* pin : sheet->GetPins() )
{
if( EscapeString( pin->GetShownText(), CTX_NETNAME ) == aOldName )
{
m_frame->SaveCopyInUndoList( pin, UR_CHANGED );
static_cast<SCH_TEXT*>( pin )->SetText( aNewName );
}
}
}
m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
break;
case SCH_SHEET_PIN_T:
++m_changesCount;
msg.Printf( _( "Change \"%s\" hierarchical label to \"%s\"." ),
aConn->Name( true ),
aNewName );
if( !m_dryRun )
{
m_frame->Schematic().SetCurrentSheet( aConn->Sheet() );
m_frame->SaveCopyInUndoList( driver, UR_CHANGED );
static_cast<SCH_TEXT*>( driver )->SetText( aNewName );
SCH_SHEET* sheet = static_cast<SCH_SHEET_PIN*>( driver )->GetParent();
m_frame->SetScreen( sheet->GetScreen() );
editMatchingLabels( sheet->GetScreen(), SCH_HIER_LABEL_T, aOldName, aNewName );
}
m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
break;
case LIB_PIN_T:
{
LIB_PIN* pin = dynamic_cast<LIB_PIN*>( driver );
LABEL_SPIN_STYLE spin = LABEL_SPIN_STYLE::RIGHT;
if( pin->IsPowerConnection() )
{
msg.Printf( _( "Net \"%s\" cannot be changed to \"%s\" because it "
"is driven by a power pin." ),
aOldName,
aNewName );
m_reporter.ReportHead( msg, RPT_SEVERITY_ERROR );
break;
}
switch( pin->GetOrientation() )
{
case PIN_UP: spin = LABEL_SPIN_STYLE::UP; break;
case PIN_DOWN: spin = LABEL_SPIN_STYLE::BOTTOM; break;
case PIN_LEFT: spin = LABEL_SPIN_STYLE::LEFT; break;
case PIN_RIGHT: spin = LABEL_SPIN_STYLE::RIGHT; break;
}
++m_changesCount;
msg.Printf( _( "Add label \"%s\" to net \"%s\"." ),
aNewName,
aConn->Name( true ) );
if( !m_dryRun )
{
SCHEMATIC_SETTINGS& settings = m_frame->Schematic().Settings();
SCH_LABEL* label = new SCH_LABEL( driver->GetPosition(), aNewName );
label->SetParent( &m_frame->Schematic() );
label->SetTextSize( wxSize( settings.m_DefaultTextSize,
settings.m_DefaultTextSize ) );
label->SetLabelSpinStyle( spin );
label->SetFlags( IS_NEW );
m_frame->Schematic().SetCurrentSheet( aConn->Sheet() );
m_frame->AddItemToScreenAndUndoList( label );
}
m_reporter.ReportHead( msg, RPT_SEVERITY_ACTION );
}
break;
default:
break;
}
m_frame->Schematic().SetCurrentSheet( SCH_SHEET_PATH() );
}

View File

@ -1,12 +1,8 @@
/**
* @file eeschema/tools/backannotate.h
*/
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 Alexander Shuklin <Jasuramme@gmail.com>
* Copyright (C) 2004-2019 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2004-2020 KiCad Developers, see AUTHORS.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
@ -44,8 +40,9 @@ class SCH_EDIT_FRAME;
/**
* @brief Back annotation algorithm class. It used to recieve, check and apply \ref NETLIST
* from PCBNEW. Class check for following collisions:
* @brief Back annotation algorithm class used to recieve, check, and apply a \ref NETLIST from
* PCBNEW.
* The following checks are made:
* - Schematic symbol exists, but linked PCBnew module missing
* - PCBnew module exists but no schematic symbol connected to
* - PCBnew module is standalone
@ -58,31 +55,23 @@ class SCH_EDIT_FRAME;
class BACK_ANNOTATE
{
public:
/**
* @brief settings struct to set up back annotation
*/
struct SETTINGS
{
REPORTER& reporter;
bool processFootprints;
bool processValues;
bool processReferences;
bool ignoreOtherProjects;
bool dryRun;
};
/**
* @brief Struct to hold PCBnew module data
*/
struct PCB_MODULE_DATA
{
PCB_MODULE_DATA(wxString aRef, wxString aFootprint, wxString aValue) :
ref(aRef),
footprint(aFootprint),
value(aValue){};
wxString ref;
wxString footprint;
wxString value;
PCB_MODULE_DATA( const wxString& aRef, const wxString& aFootprint,
const wxString& aValue, const std::map<wxString, wxString> aPinMap ) :
m_ref( aRef ),
m_footprint( aFootprint ),
m_value( aValue ),
m_pinMap( aPinMap )
{};
wxString m_ref;
wxString m_footprint;
wxString m_value;
std::map<wxString, wxString> m_pinMap;
};
///> Map to hold NETLIST modules data
@ -90,11 +79,9 @@ public:
using CHANGELIST_ITEM = std::pair<SCH_REFERENCE, std::shared_ptr<PCB_MODULE_DATA>>;
///> To hold match between reference and PCBnew module
using CHANGELIST = std::deque<CHANGELIST_ITEM>;
BACK_ANNOTATE( SCH_EDIT_FRAME* aFrame, SETTINGS aSettings );
BACK_ANNOTATE( SCH_EDIT_FRAME* aFrame, REPORTER& aReporter, bool aProcessFootprints,
bool aProcessValues, bool aProcessReferences, bool aProcessNetNames,
bool aIgnoreOtherProjects, bool aDryRun );
~BACK_ANNOTATE();
/**
@ -113,11 +100,19 @@ public:
bool BackAnnotateSymbols( const std::string& aNetlist );
private:
SETTINGS m_settings;
REPORTER& m_reporter;
bool m_processFootprints;
bool m_processValues;
bool m_processReferences;
bool m_processNetNames;
bool m_ignoreOtherProjects;
bool m_dryRun;
PCB_MODULES_MAP m_pcbModules;
SCH_REFERENCE_LIST m_refs;
SCH_MULTI_UNIT_REFERENCE_MAP m_multiUnitsRefs;
CHANGELIST m_changelist;
std::deque<CHANGELIST_ITEM> m_changelist;
SCH_EDIT_FRAME* m_frame;
///> To count number of changes applied to the schematic
@ -140,28 +135,29 @@ private:
* @param aPayload - netlist from PCBnew
* @return number of errors during parsing
*/
int getPcbModulesFromString( const std::string& aPayload );
void getPcbModulesFromString( const std::string& aPayload );
///> Create changelist
int getChangeList();
void getChangeList();
/**
* @brief Check if some symbols are not represented in PCB modules and vice versa.
* \ref m_refs must be sorted by path
* @return number of errors
*/
int checkForUnusedSymbols();
void checkForUnusedSymbols();
/**
* @brief Check for errors connected to reusing schematic in project or between projects
* @return number of errors
*/
int checkSharedSchematicErrors();
void checkSharedSchematicErrors();
/**
* @brief Apply changelist to the schematic
*/
void applyChangelist();
void processNetNameChange( SCH_CONNECTION* aConn, const wxString& aOldName,
const wxString& aNewName );
};
#endif

View File

@ -194,6 +194,33 @@ protected:
LIB_ID::LIB_ID_TYPE m_idType;
};
class NETNAME_VALIDATOR : public wxTextValidator
{
public:
NETNAME_VALIDATOR( wxString *aVal = nullptr );
NETNAME_VALIDATOR( bool aAllowSpaces );
NETNAME_VALIDATOR( const NETNAME_VALIDATOR& aValidator );
virtual wxObject* Clone() const override { return new NETNAME_VALIDATOR( *this ); }
virtual bool TransferToWindow() override { return true; }
virtual bool TransferFromWindow() override { return true; }
virtual bool Validate( wxWindow *aParent ) override;
protected:
// returns the error message if the contents of 'val' are invalid
wxString IsValid( const wxString& aVal ) const override;
private:
bool m_allowSpaces;
};
namespace KIUI
{
/**

View File

@ -34,7 +34,6 @@
#include <class_board.h>
#include <class_module.h>
#include <class_track.h>
#include <class_zone.h>
#include <collectors.h>
#include <eda_dde.h>
#include <fctsys.h>
@ -43,14 +42,10 @@
#include <macros.h>
#include <netlist_reader/pcb_netlist.h>
#include <pcb_edit_frame.h>
#include <pcb_painter.h>
#include <pcbnew.h>
#include <pcbnew_settings.h>
#include <pgm_base.h>
#include <tool/tool_manager.h>
#include <tools/pcb_actions.h>
#include <tools/selection_tool.h>
#include <wx/tokenzr.h>
/* Execute a remote command send by Eeschema via a socket,
* port KICAD_PCB_PORT_SERVICE_NUMBER
@ -402,13 +397,24 @@ void PCB_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
{
NETLIST netlist;
STRING_FORMATTER sf;
for( auto& module : this->GetBoard()->Modules() )
for( MODULE* module : this->GetBoard()->Modules() )
{
netlist.AddComponent( new COMPONENT( module->GetFPID(), module->GetReference(),
module->GetValue(), module->GetPath() ) );
COMPONENT* component = new COMPONENT( module->GetFPID(), module->GetReference(),
module->GetValue(), module->GetPath() );
for( D_PAD* pad : module->Pads() )
{
const wxString& netname = pad->GetShortNetname();
if( !netname.IsEmpty() )
component->AddNet( pad->GetName(), netname, wxEmptyString );
}
netlist.AddComponent( component );
}
netlist.Format(
"pcb_netlist", &sf, 0, CTL_OMIT_FILTERS | CTL_OMIT_NETS | CTL_OMIT_FILTERS );
netlist.Format( "pcb_netlist", &sf, 0, CTL_OMIT_FILTERS );
payload = sf.GetString();
break;
}

View File

@ -3,7 +3,7 @@
*
* Copyright (C) 2020 Oleg Endo <olegendo@gcc.gnu.org>
* Copyright (C) 2019 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.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
@ -24,19 +24,18 @@
*/
#include <fctsys.h>
#include <kicad_string.h>
#include <pcbnew.h>
#include <tools/pcb_inspection_tool.h>
#include <class_board.h>
#include <class_track.h>
#include <dialog_select_net_from_list.h>
#include <eda_pattern_match.h>
#include <wildcards_and_files_ext.h>
#include <view/view.h>
#include <view/view_controls.h>
#include <pcb_painter.h>
#include <connectivity/connectivity_data.h>
#include <connectivity/connectivity_algo.h>
#include <dialogs/dialog_text_entry.h>
#include <validators.h>
#include <bitmaps.h>
struct DIALOG_SELECT_NET_FROM_LIST::COLUMN_ID
{
@ -122,27 +121,23 @@ struct DIALOG_SELECT_NET_FROM_LIST::ROW_DESC
};
DIALOG_SELECT_NET_FROM_LIST::DIALOG_SELECT_NET_FROM_LIST(
PCB_EDIT_FRAME* aParent, const SETTINGS& aSettings )
: DIALOG_SELECT_NET_FROM_LIST_BASE( aParent ), m_frame( aParent )
DIALOG_SELECT_NET_FROM_LIST::DIALOG_SELECT_NET_FROM_LIST( PCB_EDIT_FRAME* aParent,
const SETTINGS& aSettings ) :
DIALOG_SELECT_NET_FROM_LIST_BASE( aParent ),
m_frame( aParent )
{
m_brd = aParent->GetBoard();
m_wasSelected = false;
m_netsList->AppendTextColumn(
COLUMN_NET.display_name, wxDATAVIEW_CELL_INERT, 0, wxALIGN_LEFT, 0 );
m_netsList->AppendTextColumn(
COLUMN_NAME.display_name, wxDATAVIEW_CELL_INERT, 0, wxALIGN_LEFT, 0 );
m_netsList->AppendTextColumn(
COLUMN_PAD_COUNT.display_name, wxDATAVIEW_CELL_INERT, 0, wxALIGN_CENTER, 0 );
m_netsList->AppendTextColumn(
COLUMN_VIA_COUNT.display_name, wxDATAVIEW_CELL_INERT, 0, wxALIGN_CENTER, 0 );
m_netsList->AppendTextColumn(
COLUMN_BOARD_LENGTH.display_name, wxDATAVIEW_CELL_INERT, 0, wxALIGN_CENTER, 0 );
m_netsList->AppendTextColumn(
COLUMN_CHIP_LENGTH.display_name, wxDATAVIEW_CELL_INERT, 0, wxALIGN_CENTER, 0 );
m_netsList->AppendTextColumn(
COLUMN_TOTAL_LENGTH.display_name, wxDATAVIEW_CELL_INERT, 0, wxALIGN_CENTER, 0 );
#define ADD_COL( name, flag, align ) m_netsList->AppendTextColumn( name, flag, 0, align, 0 );
ADD_COL( COLUMN_NET.display_name, wxDATAVIEW_CELL_INERT, wxALIGN_LEFT );
ADD_COL( COLUMN_NAME.display_name, wxDATAVIEW_CELL_INERT, wxALIGN_LEFT );
ADD_COL( COLUMN_PAD_COUNT.display_name, wxDATAVIEW_CELL_INERT, wxALIGN_CENTER );
ADD_COL( COLUMN_VIA_COUNT.display_name, wxDATAVIEW_CELL_INERT, wxALIGN_CENTER );
ADD_COL( COLUMN_BOARD_LENGTH.display_name, wxDATAVIEW_CELL_INERT, wxALIGN_CENTER );
ADD_COL( COLUMN_CHIP_LENGTH.display_name, wxDATAVIEW_CELL_INERT, wxALIGN_CENTER );
ADD_COL( COLUMN_TOTAL_LENGTH.display_name, wxDATAVIEW_CELL_INERT, wxALIGN_CENTER );
// The fact that we're a list should keep the control from reserving space for the
// expander buttons... but it doesn't. Fix by forcing the indent to 0.
@ -155,6 +150,10 @@ DIALOG_SELECT_NET_FROM_LIST::DIALOG_SELECT_NET_FROM_LIST(
adjustListColumns();
m_addNet->SetBitmap( KiBitmap( small_plus_xpm ) );
m_renameNet->SetBitmap( KiBitmap( small_edit_xpm ) );
m_deleteNet->SetBitmap( KiBitmap( trash_xpm ) );
m_sdbSizerOK->SetDefault();
FinishDialogSettings();
@ -277,7 +276,7 @@ std::vector<CN_ITEM*> DIALOG_SELECT_NET_FROM_LIST::relevantConnectivityItems() c
std::vector<CN_ITEM*> cn_items;
cn_items.reserve( 1024 );
for( auto& cn_item : m_brd->GetConnectivity()->GetConnectivityAlgo()->ItemList() )
for( CN_ITEM* cn_item : m_brd->GetConnectivity()->GetConnectivityAlgo()->ItemList() )
{
if( cn_item->Valid() && type_bits[cn_item->Parent()->Type()] )
cn_items.push_back( cn_item );
@ -323,8 +322,8 @@ void DIALOG_SELECT_NET_FROM_LIST::deleteRow( const ROW_DESC& aRow )
}
void DIALOG_SELECT_NET_FROM_LIST::setValue(
const ROW_DESC& aRow, const COLUMN_ID& aCol, wxString aVal )
void DIALOG_SELECT_NET_FROM_LIST::setValue( const ROW_DESC& aRow, const COLUMN_ID& aCol,
wxString aVal )
{
if( aRow )
m_netsList->SetValue( aVal, aRow.row_num, aCol.col_num );
@ -369,7 +368,7 @@ void DIALOG_SELECT_NET_FROM_LIST::OnBoardItemAdded( BOARD& aBoard, BOARD_ITEM* a
std::sort( m_list_items_by_net.begin(), m_list_items_by_net.end(),
LIST_ITEM_NET_CMP_LESS( m_list_items ) );
auto& new_i = m_list_items.back();
LIST_ITEM& new_i = m_list_items.back();
new_i.m_pad_count = m_brd->GetNodesCount( net->GetNet() );
wxVector<wxVariant> new_row( 7 );
@ -386,14 +385,14 @@ void DIALOG_SELECT_NET_FROM_LIST::OnBoardItemAdded( BOARD& aBoard, BOARD_ITEM* a
return;
}
else if( auto* i = dynamic_cast<BOARD_CONNECTED_ITEM*>( aBoardItem ) )
else if( BOARD_CONNECTED_ITEM* i = dynamic_cast<BOARD_CONNECTED_ITEM*>( aBoardItem ) )
{
auto r = findRow( i->GetNet() );
const ROW_DESC& r = findRow( i->GetNet() );
if( r )
{
// try to handle frequent operations quickly.
if( auto* track = dynamic_cast<TRACK*>( i ) )
if( TRACK* track = dynamic_cast<TRACK*>( i ) )
{
int len = track->GetLength();
r.by_row->m_board_wire_length += len;
@ -420,16 +419,16 @@ void DIALOG_SELECT_NET_FROM_LIST::OnBoardItemAdded( BOARD& aBoard, BOARD_ITEM* a
void DIALOG_SELECT_NET_FROM_LIST::OnBoardItemRemoved( BOARD& aBoard, BOARD_ITEM* aBoardItem )
{
if( auto* net = dynamic_cast<NETINFO_ITEM*>( aBoardItem ) )
if( NETINFO_ITEM* net = dynamic_cast<NETINFO_ITEM*>( aBoardItem ) )
{
deleteRow( findRow( net ) );
return;
}
else if( auto* mod = dynamic_cast<MODULE*>( aBoardItem ) )
else if( MODULE* mod = dynamic_cast<MODULE*>( aBoardItem ) )
{
for( const D_PAD* pad : mod->Pads() )
{
auto r = findRow( pad->GetNet() );
const ROW_DESC& r = findRow( pad->GetNet() );
if( r )
{
@ -442,14 +441,14 @@ void DIALOG_SELECT_NET_FROM_LIST::OnBoardItemRemoved( BOARD& aBoard, BOARD_ITEM*
}
}
}
else if( auto* i = dynamic_cast<BOARD_CONNECTED_ITEM*>( aBoardItem ) )
else if( BOARD_CONNECTED_ITEM* i = dynamic_cast<BOARD_CONNECTED_ITEM*>( aBoardItem ) )
{
auto r = findRow( i->GetNet() );
const ROW_DESC& r = findRow( i->GetNet() );
if( r )
{
// try to handle frequent operations quickly.
if( auto* track = dynamic_cast<TRACK*>( i ) )
if( TRACK* track = dynamic_cast<TRACK*>( i ) )
{
int len = track->GetLength();
r.by_row->m_board_wire_length -= len;
@ -520,22 +519,22 @@ void DIALOG_SELECT_NET_FROM_LIST::updateNet( NETINFO_ITEM* aNet )
return;
}
auto all_cn_items = relevantConnectivityItems();
std::vector<CN_ITEM*> all_cn_items = relevantConnectivityItems();
LIST_ITEM list_item( aNet );
list_item.m_pad_count = node_count;
const auto cn_items = std::equal_range(
all_cn_items.begin(), all_cn_items.end(), aNet->GetNet(), NETCODE_CMP_LESS() );
const auto cn_items = std::equal_range( all_cn_items.begin(), all_cn_items.end(),
aNet->GetNet(), NETCODE_CMP_LESS() );
for( auto i = cn_items.first; i != cn_items.second; ++i )
{
auto item = ( *i )->Parent();
BOARD_CONNECTED_ITEM* item = ( *i )->Parent();
if( item->Type() == PCB_PAD_T )
list_item.m_chip_wire_length += static_cast<D_PAD*>( item )->GetPadToDieLength();
else if( auto* track = dynamic_cast<TRACK*>( item ) )
else if( TRACK* track = dynamic_cast<TRACK*>( item ) )
{
list_item.m_board_wire_length += track->GetLength();
@ -589,7 +588,6 @@ void DIALOG_SELECT_NET_FROM_LIST::buildNetsList()
std::vector<CN_ITEM*> prefiltered_cn_items = relevantConnectivityItems();
// collect all nets which pass the filter string.
struct NET_INFO
@ -618,7 +616,7 @@ void DIALOG_SELECT_NET_FROM_LIST::buildNetsList()
std::vector<NET_INFO> nets;
nets.reserve( m_brd->GetNetInfo().NetsByNetcode().size() );
for( auto&& ni : m_brd->GetNetInfo().NetsByNetcode() )
for( const std::pair<const int, NETINFO_ITEM*>& ni : m_brd->GetNetInfo().NetsByNetcode() )
{
if( netFilterMatches( ni.second ) )
nets.emplace_back( NET_INFO{ ni.first, ni.second, 0 } );
@ -627,37 +625,37 @@ void DIALOG_SELECT_NET_FROM_LIST::buildNetsList()
// count the pads for each net. since the nets are sorted by netcode
// this way around is faster than using counting pads for each net.
for( auto&& mod : m_brd->Modules() )
for( MODULE* mod : m_brd->Modules() )
{
for( auto&& pad : mod->Pads() )
for( D_PAD* pad : mod->Pads() )
{
auto i = std::lower_bound(
nets.begin(), nets.end(), pad->GetNetCode(), NET_INFO_CMP_LESS() );
auto i = std::lower_bound( nets.begin(), nets.end(), pad->GetNetCode(),
NET_INFO_CMP_LESS() );
if( i != nets.end() && i->netcode == pad->GetNetCode() )
i->pad_count += 1;
}
}
for( auto&& ni : nets )
for( NET_INFO& ni : nets )
{
if( !m_cbShowZeroPad->IsChecked() && ni.pad_count == 0 )
continue;
m_list_items.emplace_back( ni.net );
auto& list_item = m_list_items.back();
LIST_ITEM& list_item = m_list_items.back();
const auto cn_items = std::equal_range( prefiltered_cn_items.begin(),
prefiltered_cn_items.end(), ni.netcode, NETCODE_CMP_LESS() );
for( auto i = cn_items.first; i != cn_items.second; ++i )
{
auto item = ( *i )->Parent();
BOARD_CONNECTED_ITEM* item = ( *i )->Parent();
if( item->Type() == PCB_PAD_T )
list_item.m_chip_wire_length += static_cast<D_PAD*>( item )->GetPadToDieLength();
else if( auto* track = dynamic_cast<TRACK*>( item ) )
else if( TRACK* track = dynamic_cast<TRACK*>( item ) )
{
list_item.m_board_wire_length += track->GetLength();
@ -673,7 +671,7 @@ void DIALOG_SELECT_NET_FROM_LIST::buildNetsList()
wxVector<wxVariant> dataLine;
dataLine.resize( 7 );
for( auto& i : m_list_items )
for( LIST_ITEM& i : m_list_items )
{
dataLine[COLUMN_NET] = formatNetCode( i.m_net );
dataLine[COLUMN_NAME] = formatNetName( i.m_net );
@ -699,14 +697,14 @@ void DIALOG_SELECT_NET_FROM_LIST::buildNetsList()
m_wasSelected = false;
else
{
auto r = findRow( prev_selected_netcode );
const ROW_DESC& r = findRow( prev_selected_netcode );
if( r )
{
m_selection = r.by_row->m_net->GetNetname();
m_wasSelected = true;
auto i = m_netsList->RowToItem( r.row_num );
wxDataViewItem i = m_netsList->RowToItem( r.row_num );
m_netsList->Select( i );
m_netsList->EnsureVisible( i );
}
@ -716,11 +714,11 @@ void DIALOG_SELECT_NET_FROM_LIST::buildNetsList()
void DIALOG_SELECT_NET_FROM_LIST::HighlightNet( NETINFO_ITEM* aNet )
{
const auto r = findRow( aNet );
const ROW_DESC& r = findRow( aNet );
if( r )
{
auto i = m_netsList->RowToItem( r.row_num );
wxDataViewItem i = m_netsList->RowToItem( r.row_num );
m_netsList->Select( i );
m_netsList->EnsureVisible( i );
}
@ -754,7 +752,7 @@ void DIALOG_SELECT_NET_FROM_LIST::onSelChanged( wxDataViewEvent& )
if( selected_row >= 0 && selected_row < static_cast<int>( m_list_items.size() ) )
{
auto* net = m_list_items[selected_row].m_net;
NETINFO_ITEM* net = m_list_items[selected_row].m_net;
m_selection = net->GetNetname();
m_wasSelected = true;
@ -772,10 +770,9 @@ void DIALOG_SELECT_NET_FROM_LIST::adjustListColumns()
int w0, w1, w2, w3, w4, w5, w6;
/**
* Calculating optimal width of the first (Net) and
* the last (Pad Count) columns. That width must be
* enough to fit column header label and be not less
* than width of four chars (0000).
* Calculating optimal width of the first (Net) and the last (Pad Count) columns.
* That width must be enough to fit column header label and be not less than width of
* four chars (0000).
*/
wxClientDC dc( GetParent() );
@ -792,26 +789,19 @@ void DIALOG_SELECT_NET_FROM_LIST::adjustListColumns()
// Considering left and right margins.
// For wxRenderGeneric it is 5px.
w0 = std::max( w0+10, minw_col0);
w2 = std::max( w2+10, minw);
w3 = std::max( w3+10, minw);
w4 = std::max( w4+10, minw);
w5 = std::max( w5+10, minw);
w6 = std::max( w6+10, minw);
m_netsList->GetColumn( 0 )->SetWidth( w0 );
m_netsList->GetColumn( 2 )->SetWidth( w2 );
m_netsList->GetColumn( 3 )->SetWidth( w3 );
m_netsList->GetColumn( 4 )->SetWidth( w4 );
m_netsList->GetColumn( 5 )->SetWidth( w5 );
m_netsList->GetColumn( 6 )->SetWidth( w6 );
m_netsList->GetColumn( 0 )->SetWidth( std::max( w0 + 10, minw_col0 ) );
m_netsList->GetColumn( 2 )->SetWidth( w2 + 10 );
m_netsList->GetColumn( 3 )->SetWidth( w3 + 10 );
m_netsList->GetColumn( 4 )->SetWidth( std::max( w4 + 10, minw ) );
m_netsList->GetColumn( 5 )->SetWidth( std::max( w5 + 10, minw ) );
m_netsList->GetColumn( 6 )->SetWidth( std::max( w6 + 10, minw ) );
// At resizing of the list the width of middle column (Net Names) changes only.
int width = m_netsList->GetClientSize().x;
w1 = width - w0 - w2 - w3 - w4 - w5 - w6;
// Column 1 (net names) need a minimal width to display net names
dc.GetTextExtent( "MMMMMMMMMMMMMMMMMMMM", &minw, &h );
dc.GetTextExtent( "MMMMMMMMMMMMMMMMMM", &minw, &h );
w1 = std::max( w1, minw );
m_netsList->GetColumn( 1 )->SetWidth( w1 );
@ -834,6 +824,129 @@ bool DIALOG_SELECT_NET_FROM_LIST::GetNetName( wxString& aName ) const
}
void DIALOG_SELECT_NET_FROM_LIST::onAddNet( wxCommandEvent& aEvent )
{
wxString newNetName;
NETNAME_VALIDATOR validator( &newNetName );
WX_TEXT_ENTRY_DIALOG dlg( this, _( "Net name:" ), _( "New Net" ), newNetName );
dlg.SetTextValidator( validator );
while( true )
{
if( dlg.ShowModal() != wxID_OK || dlg.GetValue().IsEmpty() )
return; //Aborted by user
newNetName = dlg.GetValue();
if( m_brd->FindNet( newNetName ) )
{
DisplayError( this, wxString::Format( _( "Net name '%s' is already in use." ),
newNetName ) );
newNetName = wxEmptyString;
}
else
{
break;
}
}
NETINFO_ITEM *newnet = new NETINFO_ITEM( m_brd, dlg.GetValue(), 0 );
m_brd->Add( newnet );
m_frame->OnModify();
// We'll get an OnBoardItemChanged callback from this to update our listbox
}
void DIALOG_SELECT_NET_FROM_LIST::onRenameNet( wxCommandEvent& aEvent )
{
int selected_row = m_netsList->GetSelectedRow();
if( selected_row >= 0 && selected_row < static_cast<int>( m_list_items.size() ) )
{
NETINFO_ITEM* net = m_list_items[selected_row].m_net;
wxString fullNetName = net->GetNetname();
wxString netPath;
wxString shortNetName;
if( fullNetName.Contains( "/" ) )
{
netPath = fullNetName.BeforeLast( '/' ) + '/';
shortNetName = fullNetName.AfterLast( '/' );
}
else
{
shortNetName = fullNetName;
}
wxString unescapedShortName = UnescapeString( shortNetName );
WX_TEXT_ENTRY_DIALOG dlg( this, _( "Net name:" ), _( "Rename Net" ), unescapedShortName );
NETNAME_VALIDATOR validator( &unescapedShortName );
dlg.SetTextValidator( validator );
while( true )
{
if( dlg.ShowModal() != wxID_OK )
return; //Aborted by user
unescapedShortName = dlg.GetValue();
if( unescapedShortName.IsEmpty() )
{
DisplayError( this, wxString::Format( _( "Net name cannot be empty." ),
unescapedShortName ) );
continue;
}
shortNetName = EscapeString( unescapedShortName, CTX_NETNAME );
fullNetName = netPath + shortNetName;
if( m_brd->FindNet( shortNetName ) || m_brd->FindNet( fullNetName ) )
{
DisplayError( this, wxString::Format( _( "Net name '%s' is already in use." ),
unescapedShortName ) );
unescapedShortName = wxEmptyString;
}
else
{
break;
}
}
net->SetNetname( fullNetName );
m_frame->OnModify();
buildNetsList();
m_netsList->Refresh();
}
}
void DIALOG_SELECT_NET_FROM_LIST::onDeleteNet( wxCommandEvent& aEvent )
{
int selected_row = m_netsList->GetSelectedRow();
if( selected_row >= 0 && selected_row < static_cast<int>( m_list_items.size() ) )
{
NETINFO_ITEM* net = m_list_items[selected_row].m_net;
if( m_list_items[selected_row].m_pad_count > 0 )
{
if( !IsOK( this, _( "Net is in use. Delete anyway?" ) ) )
return;
}
m_brd->Remove( net );
m_frame->OnModify();
// We'll get an OnBoardItemChanged callback from this to update our listbox
}
}
void DIALOG_SELECT_NET_FROM_LIST::onReport( wxCommandEvent& aEvent )
{
wxFileDialog dlg( this, _( "Report file" ), "", "",
@ -860,13 +973,14 @@ void DIALOG_SELECT_NET_FROM_LIST::onReport( wxCommandEvent& aEvent )
// Print list of nets:
for( int row = 1; row < rows; row++ )
{
txt.Printf( "%s;\"%s\";%s;%s;%s;%s;%s;", m_netsList->GetTextValue( row, COLUMN_NET ),
m_netsList->GetTextValue( row, COLUMN_NAME ),
m_netsList->GetTextValue( row, COLUMN_PAD_COUNT ),
m_netsList->GetTextValue( row, COLUMN_VIA_COUNT ),
m_netsList->GetTextValue( row, COLUMN_BOARD_LENGTH ),
m_netsList->GetTextValue( row, COLUMN_CHIP_LENGTH ),
m_netsList->GetTextValue( row, COLUMN_TOTAL_LENGTH ) );
txt.Printf( "%s;\"%s\";%s;%s;%s;%s;%s;",
m_netsList->GetTextValue( row, COLUMN_NET ),
m_netsList->GetTextValue( row, COLUMN_NAME ),
m_netsList->GetTextValue( row, COLUMN_PAD_COUNT ),
m_netsList->GetTextValue( row, COLUMN_VIA_COUNT ),
m_netsList->GetTextValue( row, COLUMN_BOARD_LENGTH ),
m_netsList->GetTextValue( row, COLUMN_CHIP_LENGTH ),
m_netsList->GetTextValue( row, COLUMN_TOTAL_LENGTH ) );
f.AddLine( txt );
}

View File

@ -94,6 +94,9 @@ private:
void onSelChanged( wxDataViewEvent& event ) override;
void onFilterChange( wxCommandEvent& event ) override;
void onListSize( wxSizeEvent& event ) override;
void onAddNet( wxCommandEvent& event ) override;
void onRenameNet( wxCommandEvent& event ) override;
void onDeleteNet( wxCommandEvent& event ) override;
void onReport( wxCommandEvent& event ) override;
void buildNetsList();

View File

@ -41,14 +41,35 @@ DIALOG_SELECT_NET_FROM_LIST_BASE::DIALOG_SELECT_NET_FROM_LIST_BASE( wxWindow* pa
bSizerMain->Add( m_netsList, 1, wxEXPAND|wxRIGHT|wxLEFT, 10 );
wxBoxSizer* bSizerBottom;
bSizerBottom = new wxBoxSizer( wxHORIZONTAL );
wxBoxSizer* bSizerListButtons;
bSizerListButtons = new wxBoxSizer( wxHORIZONTAL );
m_addNet = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
bSizerListButtons->Add( m_addNet, 0, wxTOP|wxBOTTOM|wxLEFT, 5 );
m_renameNet = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
bSizerListButtons->Add( m_renameNet, 0, wxALL, 5 );
bSizerListButtons->Add( 15, 0, 0, wxEXPAND, 5 );
m_deleteNet = new wxBitmapButton( this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxDefaultSize, wxBU_AUTODRAW|0 );
bSizerListButtons->Add( m_deleteNet, 0, wxALL, 5 );
bSizerListButtons->Add( 0, 0, 1, wxEXPAND, 5 );
m_ReportButt = new wxButton( this, wxID_ANY, _("Create Report..."), wxDefaultPosition, wxDefaultSize, 0 );
bSizerBottom->Add( m_ReportButt, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
bSizerListButtons->Add( m_ReportButt, 0, wxALL|wxALIGN_CENTER_VERTICAL, 5 );
bSizerBottom->Add( 0, 0, 1, wxEXPAND, 5 );
bSizerMain->Add( bSizerListButtons, 0, wxEXPAND|wxALL, 5 );
m_staticline1 = new wxStaticLine( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL );
bSizerMain->Add( m_staticline1, 0, wxEXPAND | wxALL, 5 );
wxBoxSizer* bSizerBottom;
bSizerBottom = new wxBoxSizer( wxHORIZONTAL );
m_sdbSizer = new wxStdDialogButtonSizer();
m_sdbSizerOK = new wxButton( this, wxID_OK );
@ -57,7 +78,7 @@ DIALOG_SELECT_NET_FROM_LIST_BASE::DIALOG_SELECT_NET_FROM_LIST_BASE( wxWindow* pa
m_sdbSizer->AddButton( m_sdbSizerCancel );
m_sdbSizer->Realize();
bSizerBottom->Add( m_sdbSizer, 0, wxALL|wxEXPAND, 5 );
bSizerBottom->Add( m_sdbSizer, 1, wxALL|wxEXPAND, 5 );
bSizerMain->Add( bSizerBottom, 0, wxEXPAND|wxLEFT, 5 );
@ -65,6 +86,7 @@ DIALOG_SELECT_NET_FROM_LIST_BASE::DIALOG_SELECT_NET_FROM_LIST_BASE( wxWindow* pa
this->SetSizer( bSizerMain );
this->Layout();
bSizerMain->Fit( this );
this->Centre( wxBOTH );
@ -73,6 +95,9 @@ DIALOG_SELECT_NET_FROM_LIST_BASE::DIALOG_SELECT_NET_FROM_LIST_BASE( wxWindow* pa
m_cbShowZeroPad->Connect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SELECT_NET_FROM_LIST_BASE::onFilterChange ), NULL, this );
m_netsList->Connect( wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, wxDataViewEventHandler( DIALOG_SELECT_NET_FROM_LIST_BASE::onSelChanged ), NULL, this );
m_netsList->Connect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_SELECT_NET_FROM_LIST_BASE::onListSize ), NULL, this );
m_addNet->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SELECT_NET_FROM_LIST_BASE::onAddNet ), NULL, this );
m_renameNet->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SELECT_NET_FROM_LIST_BASE::onRenameNet ), NULL, this );
m_deleteNet->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SELECT_NET_FROM_LIST_BASE::onDeleteNet ), NULL, this );
m_ReportButt->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SELECT_NET_FROM_LIST_BASE::onReport ), NULL, this );
}
@ -83,6 +108,9 @@ DIALOG_SELECT_NET_FROM_LIST_BASE::~DIALOG_SELECT_NET_FROM_LIST_BASE()
m_cbShowZeroPad->Disconnect( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEventHandler( DIALOG_SELECT_NET_FROM_LIST_BASE::onFilterChange ), NULL, this );
m_netsList->Disconnect( wxEVT_COMMAND_DATAVIEW_SELECTION_CHANGED, wxDataViewEventHandler( DIALOG_SELECT_NET_FROM_LIST_BASE::onSelChanged ), NULL, this );
m_netsList->Disconnect( wxEVT_SIZE, wxSizeEventHandler( DIALOG_SELECT_NET_FROM_LIST_BASE::onListSize ), NULL, this );
m_addNet->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SELECT_NET_FROM_LIST_BASE::onAddNet ), NULL, this );
m_renameNet->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SELECT_NET_FROM_LIST_BASE::onRenameNet ), NULL, this );
m_deleteNet->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SELECT_NET_FROM_LIST_BASE::onDeleteNet ), NULL, this );
m_ReportButt->Disconnect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( DIALOG_SELECT_NET_FROM_LIST_BASE::onReport ), NULL, this );
}

View File

@ -45,7 +45,7 @@
<property name="minimum_size">-1,-1</property>
<property name="name">DIALOG_SELECT_NET_FROM_LIST_BASE</property>
<property name="pos"></property>
<property name="size">720,397</property>
<property name="size">-1,-1</property>
<property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
<property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
<property name="title">Net Inspector</property>
@ -301,13 +301,252 @@
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxLEFT</property>
<property name="flag">wxEXPAND|wxALL</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizerBottom</property>
<property name="name">bSizerListButtons</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxTOP|wxBOTTOM|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxBitmapButton" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Add Net</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_addNet</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">onAddNet</event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxBitmapButton" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Rename Net</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_renameNet</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">onRenameNet</event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="spacer" expanded="1">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">15</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxBitmapButton" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="bitmap"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="current"></property>
<property name="default">0</property>
<property name="default_pane">0</property>
<property name="disabled"></property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="focus"></property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Delete Net</property>
<property name="margins"></property>
<property name="markup">0</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_deleteNet</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="position"></property>
<property name="pressed"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnButtonClick">onDeleteNet</event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="spacer" expanded="1">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL|wxALIGN_CENTER_VERTICAL</property>
@ -381,20 +620,79 @@
<event name="OnButtonClick">onReport</event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="spacer" expanded="1">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">0</property>
</object>
</object>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND | wxALL</property>
<property name="proportion">0</property>
<object class="wxStaticLine" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_staticline1</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style">wxLI_HORIZONTAL</property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">bSizerBottom</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">0</property>
<property name="proportion">1</property>
<object class="wxStdDialogButtonSizer" expanded="0">
<property name="Apply">0</property>
<property name="Cancel">1</property>

View File

@ -21,10 +21,12 @@
#include <wx/checkbox.h>
#include <wx/sizer.h>
#include <wx/dataview.h>
#include <wx/bmpbuttn.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
#include <wx/button.h>
#include <wx/statline.h>
#include <wx/dialog.h>
///////////////////////////////////////////////////////////////////////////
@ -42,7 +44,11 @@ class DIALOG_SELECT_NET_FROM_LIST_BASE : public DIALOG_SHIM
wxTextCtrl* m_textCtrlFilter;
wxCheckBox* m_cbShowZeroPad;
wxDataViewListCtrl* m_netsList;
wxBitmapButton* m_addNet;
wxBitmapButton* m_renameNet;
wxBitmapButton* m_deleteNet;
wxButton* m_ReportButt;
wxStaticLine* m_staticline1;
wxStdDialogButtonSizer* m_sdbSizer;
wxButton* m_sdbSizerOK;
wxButton* m_sdbSizerCancel;
@ -51,12 +57,15 @@ class DIALOG_SELECT_NET_FROM_LIST_BASE : public DIALOG_SHIM
virtual void onFilterChange( wxCommandEvent& event ) { event.Skip(); }
virtual void onSelChanged( wxDataViewEvent& event ) { event.Skip(); }
virtual void onListSize( wxSizeEvent& event ) { event.Skip(); }
virtual void onAddNet( wxCommandEvent& event ) { event.Skip(); }
virtual void onRenameNet( wxCommandEvent& event ) { event.Skip(); }
virtual void onDeleteNet( wxCommandEvent& event ) { event.Skip(); }
virtual void onReport( wxCommandEvent& event ) { event.Skip(); }
public:
DIALOG_SELECT_NET_FROM_LIST_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Net Inspector"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 720,397 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
DIALOG_SELECT_NET_FROM_LIST_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Net Inspector"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_SELECT_NET_FROM_LIST_BASE();
};

View File

@ -236,6 +236,21 @@ public:
*/
const wxString& GetShortNetname() const { return m_ShortNetname; }
/**
* Function SetNetname
* Sets the long netname to \a aNetName, and the short netname to the last token in
* the long netname's path.
*/
void SetNetname( const wxString& aNewName )
{
m_Netname = aNewName;
if( aNewName.Contains( "/" ) )
m_ShortNetname = aNewName.AfterLast( '/' );
else
m_ShortNetname = aNewName;
}
bool IsCurrent() const { return m_isCurrent; }
void SetIsCurrent( bool isCurrent ) { m_isCurrent = isCurrent; }

View File

@ -864,6 +864,5 @@ bool BOARD_NETLIST_UPDATER::UpdateNetlist( NETLIST& aNetlist )
return false;
}
m_reporter->ReportTail( _( "Netlist update successful!" ), RPT_SEVERITY_ACTION );
return true;
}

View File

@ -1,12 +1,9 @@
/**
* @file pcb_netlist.cpp
*/
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2011 Jean-Pierre Charras.
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>.
* Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.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
@ -27,13 +24,9 @@
*/
#include <macros.h>
#include <refdes_utils.h>
#include <reporter.h>
#include "pcb_netlist.h"
#include <class_module.h>
#include <eda_pattern_match.h>
int COMPONENT_NET::Format( OUTPUTFORMATTER* aOut, int aNestLevel, int aCtl )
@ -220,14 +213,3 @@ bool NETLIST::AnyFootprintsLinked() const
}
bool NETLIST::AllFootprintsLinked() const
{
for( unsigned i = 0; i < m_components.size(); i++ )
{
if( m_components[i].GetFPID().empty() )
return false;
}
return true;
}

View File

@ -97,7 +97,6 @@ class COMPONENT
/// The #LIB_ID of the footprint assigned to the component.
LIB_ID m_fpid;
/// The alt LIB_ID of the footprint, when there are 2 different assigned footprints,
/// One from the netlist, the other from the .cmp file.
/// this one is a copy of the netlist footprint assignment
@ -106,15 +105,12 @@ class COMPONENT
/// The #MODULE loaded for #m_fpid.
std::unique_ptr< MODULE > m_footprint;
/// Set to true if #m_fpid was changed when the footprint link file was read.
bool m_footprintChanged;
static COMPONENT_NET m_emptyNet;
public:
COMPONENT( const LIB_ID& aFPID,
const wxString& aReference,
const wxString& aValue,
COMPONENT( const LIB_ID& aFPID,
const wxString& aReference,
const wxString& aValue,
const KIID_PATH& aPath )
{
m_fpid = aFPID;
@ -122,7 +118,6 @@ public:
m_value = aValue;
m_pinCount = 0;
m_path = aPath;
m_footprintChanged = false;
}
virtual ~COMPONENT() { };
@ -150,35 +145,18 @@ public:
const wxString& GetValue() const { return m_value; }
void SetFPID( const LIB_ID& aFPID )
{
m_footprintChanged = !m_fpid.empty() && (m_fpid != aFPID);
m_fpid = aFPID;
}
void SetAltFPID( const LIB_ID& aFPID )
{
m_altFpid = aFPID;
}
void SetFPID( const LIB_ID& aFPID ) { m_fpid = aFPID; }
const LIB_ID& GetFPID() const { return m_fpid; }
void SetAltFPID( const LIB_ID& aFPID ) { m_altFpid = aFPID; }
const LIB_ID& GetAltFPID() const { return m_altFpid; }
const KIID_PATH& GetPath() const { return m_path; }
void SetFootprintFilters( const wxArrayString& aFilterList )
{
m_footprintFilters = aFilterList;
}
void SetFootprintFilters( const wxArrayString& aFilters ) { m_footprintFilters = aFilters; }
const wxArrayString& GetFootprintFilters() const { return m_footprintFilters; }
void SetPinCount( int aPinCount )
{
m_pinCount = aPinCount;
}
void SetPinCount( int aPinCount ) { m_pinCount = aPinCount; }
int GetPinCount() const { return m_pinCount; }
MODULE* GetModule( bool aRelease = false )
@ -193,15 +171,11 @@ public:
return aLibrary == m_library && aName == m_name;
}
bool FootprintChanged() const { return m_footprintChanged; }
void Format( OUTPUTFORMATTER* aOut, int aNestLevel, int aCtl );
};
typedef boost::ptr_vector< COMPONENT > COMPONENTS;
typedef COMPONENTS::iterator COMPONENTS_ITER;
typedef COMPONENTS::const_iterator COMPONENTS_CITER;
/**
@ -300,12 +274,6 @@ public:
m_deleteExtraFootprints = aDeleteExtraFootprints;
}
bool GetDeleteExtraFootprints() const { return m_deleteExtraFootprints; }
void SetIsDryRun( bool aIsDryRun ) { m_isDryRun = aIsDryRun; }
bool IsDryRun() const { return m_isDryRun; }
void SetFindByTimeStamp( bool aFindByTimeStamp ) { m_findByTimeStamp = aFindByTimeStamp; }
bool IsFindByTimeStamp() const { return m_findByTimeStamp; }
@ -323,25 +291,6 @@ public:
*/
bool AnyFootprintsLinked() const;
/**
* Function AllFootprintsLinked
* @return true if all components have a footprint link.
*/
bool AllFootprintsLinked() const;
/**
* Function NoFootprintsLinked
* @return true if none of the components have a footprint link.
*/
bool NoFootprintsLinked() const { return !AnyFootprintsLinked(); }
/**
* Function AnyFootprintsChanged
* @return true if any components footprints were changed when the footprint link file
* (*.cmp) was loaded.
*/
bool AnyFootprintsChanged() const;
void Format( const char* aDocName, OUTPUTFORMATTER* aOut, int aNestLevel, int aCtl = 0 );
#define CTL_OMIT_EXTRA (1<<0)