7
mirror of https://gitlab.com/kicad/code/kicad.git synced 2025-04-14 15:59:36 +00:00

Cross-probing/selection for multiple items (SCH->PCB)

This commit is contained in:
dsa-t 2022-01-16 20:29:03 +00:00 committed by Jon Evans
parent 51adf1ace4
commit bc1ff6756f
31 changed files with 974 additions and 389 deletions

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 Jon Evans <jon@craftyjon.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2020-2022 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 as published by the
@ -129,6 +129,9 @@ APP_SETTINGS_BASE::APP_SETTINGS_BASE( const std::string& aFilename, int aSchemaV
addParamsForWindow( &m_Window, "window" );
m_params.emplace_back( new PARAM<bool>( "cross_probing.on_selection",
&m_CrossProbing.on_selection, true ) );
m_params.emplace_back( new PARAM<bool>( "cross_probing.center_on_items",
&m_CrossProbing.center_on_items, true ) );

View File

@ -174,6 +174,17 @@ wxString EscapeString( const wxString& aSource, ESCAPE_CONTEXT aContext )
else
converted += c;
}
else if( aContext == CTX_IPC )
{
if( c == '/' )
converted += "{slash}";
else if( c == ',' )
converted += "{comma}";
else if( c == '\"' )
converted += "{dblquote}";
else
converted += c;
}
else if( aContext == CTX_QUOTED_STR )
{
if( c == '\"' )
@ -276,6 +287,7 @@ wxString UnescapeString( const wxString& aSource )
else if( token == wxS( "backslash" ) ) newbuf.append( wxS( "\\" ) );
else if( token == wxS( "slash" ) ) newbuf.append( wxS( "/" ) );
else if( token == wxS( "bar" ) ) newbuf.append( wxS( "|" ) );
else if( token == wxS( "comma" ) ) newbuf.append( wxS( "," ) );
else if( token == wxS( "colon" ) ) newbuf.append( wxS( ":" ) );
else if( token == wxS( "space" ) ) newbuf.append( wxS( " " ) );
else if( token == wxS( "dollar" ) ) newbuf.append( wxS( "$" ) );

View File

@ -62,6 +62,12 @@ SELECTION_CONDITION SELECTION_CONDITIONS::HasType( KICAD_T aType )
}
SELECTION_CONDITION SELECTION_CONDITIONS::HasTypes( const KICAD_T aTypes[] )
{
return std::bind( &SELECTION_CONDITIONS::hasTypesFunc, _1, aTypes );
}
SELECTION_CONDITION SELECTION_CONDITIONS::OnlyType( KICAD_T aType )
{
return std::bind( &SELECTION_CONDITIONS::onlyTypeFunc, _1, aType );
@ -94,7 +100,10 @@ SELECTION_CONDITION SELECTION_CONDITIONS::LessThan( int aNumber )
bool SELECTION_CONDITIONS::hasTypeFunc( const SELECTION& aSelection, KICAD_T aType )
{
for( const auto& item : aSelection )
if( aSelection.Empty() )
return false;
for( const EDA_ITEM* item : aSelection )
{
if( item->Type() == aType )
return true;
@ -104,6 +113,21 @@ bool SELECTION_CONDITIONS::hasTypeFunc( const SELECTION& aSelection, KICAD_T aTy
}
bool SELECTION_CONDITIONS::hasTypesFunc( const SELECTION& aSelection, const KICAD_T aTypes[] )
{
if( aSelection.Empty() )
return false;
for( const EDA_ITEM* item : aSelection )
{
if( item->IsType( aTypes ) )
return true;
}
return false;
}
bool SELECTION_CONDITIONS::onlyTypeFunc( const SELECTION& aSelection, KICAD_T aType )
{
if( aSelection.Empty() )
@ -111,7 +135,7 @@ bool SELECTION_CONDITIONS::onlyTypeFunc( const SELECTION& aSelection, KICAD_T aT
KICAD_T types[] = { aType, EOT };
for( const auto& item : aSelection )
for( const EDA_ITEM* item : aSelection )
{
if( !item->IsType( types ) )
return false;
@ -126,7 +150,7 @@ bool SELECTION_CONDITIONS::onlyTypesFunc( const SELECTION& aSelection, const KIC
if( aSelection.Empty() )
return false;
for( const auto& item : aSelection )
for( const EDA_ITEM* item : aSelection )
{
if( !item->IsType( aTypes ) )
return false;

View File

@ -3,7 +3,7 @@
*
* Copyright (C) 2019 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 2004-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2004-2022 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
@ -473,6 +473,116 @@ void SCH_EDIT_FRAME::SendMessageToPCBNEW( EDA_ITEM* aObjectToSync, SCH_SYMBOL* a
}
std::string FormatProbeItems( bool aSelectConnections, const std::deque<EDA_ITEM*>& aItems )
{
std::string command = "";
std::set<wxString> parts;
for( EDA_ITEM* item : aItems )
{
switch( item->Type() )
{
case SCH_SYMBOL_T:
{
SCH_SYMBOL* symbol = (SCH_SYMBOL*) item;
wxString ref = symbol->GetField( REFERENCE_FIELD )->GetText();
parts.insert( "F" + EscapeString( ref, CTX_IPC ) );
break;
}
case SCH_SHEET_T:
{
// For cross probing, we need the full path of the sheet, because
// in complex hierarchies the sheet uuid of not unique
SCH_SHEET* sheet = (SCH_SHEET*) item;
wxString full_path;
SCH_SHEET* parent = sheet;
while( ( parent = dynamic_cast<SCH_SHEET*>( parent->GetParent() ) ) )
{
if( parent->GetParent() && parent->GetParent()->Type() == SCH_SHEET_T )
{
// The root sheet has no parent sheet and path is just "/"
full_path.Prepend( parent->m_Uuid.AsString() );
full_path.Prepend( "/" );
}
}
full_path += "/" + sheet->m_Uuid.AsString();
parts.insert( "S" + full_path );
break;
}
case SCH_PIN_T:
{
SCH_PIN* pin = (SCH_PIN*) item;
SCH_SYMBOL* symbol = pin->GetParentSymbol();
wxString ref = symbol->GetField( REFERENCE_FIELD )->GetText();
parts.insert( "P" + EscapeString( ref, CTX_IPC ) + "/"
+ EscapeString( pin->GetShownNumber(), CTX_IPC ) );
break;
}
default: break;
}
}
if( !parts.empty() )
{
command = "$SELECT: ";
if( aSelectConnections )
command += "1";
else
command += "0";
command += ",";
for( wxString part : parts )
{
command += part;
command += ",";
}
command.pop_back();
}
return command;
}
void SCH_EDIT_FRAME::SendSelectItems( bool aSelectConnections, const std::deque<EDA_ITEM*>& aItems )
{
std::string packet = FormatProbeItems( aSelectConnections, aItems );
if( !packet.empty() )
{
if( Kiface().IsSingle() )
{
SendCommand( MSG_TO_PCB, packet );
}
else
{
// Typically ExpressMail is going to be s-expression packets, but since
// we have existing interpreter of the selection packet on the other
// side in place, we use that here.
Kiway().ExpressMail( FRAME_PCB_EDITOR, MAIL_SELECTION, packet, this );
}
}
}
void SCH_EDIT_FRAME::SendCrossProbeNetName( const wxString& aNetName )
{
// The command is a keyword followed by a quoted string.

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2009 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2022 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
@ -66,6 +66,7 @@ void PANEL_EESCHEMA_DISPLAY_OPTIONS::loadEEschemaSettings( EESCHEMA_SETTINGS* cf
m_selWidthCtrl->SetValue( cfg->m_Selection.selection_thickness );
m_highlightWidthCtrl->SetValue( cfg->m_Selection.highlight_thickness );
m_checkCrossProbeOnSelection->SetValue( cfg->m_CrossProbing.on_selection );
m_checkCrossProbeCenter->SetValue( cfg->m_CrossProbing.center_on_items );
m_checkCrossProbeZoom->SetValue( cfg->m_CrossProbing.zoom_to_fit );
m_checkCrossProbeAutoHighlight->SetValue( cfg->m_CrossProbing.auto_highlight );
@ -106,9 +107,10 @@ bool PANEL_EESCHEMA_DISPLAY_OPTIONS::TransferDataFromWindow()
cfg->m_Selection.selection_thickness = KiROUND( m_selWidthCtrl->GetValue() );
cfg->m_Selection.highlight_thickness = KiROUND( m_highlightWidthCtrl->GetValue() );
cfg->m_CrossProbing.on_selection = m_checkCrossProbeOnSelection->GetValue();
cfg->m_CrossProbing.center_on_items = m_checkCrossProbeCenter->GetValue();
cfg->m_CrossProbing.zoom_to_fit = m_checkCrossProbeZoom->GetValue();
cfg->m_CrossProbing.auto_highlight = m_checkCrossProbeAutoHighlight->GetValue();
cfg->m_CrossProbing.zoom_to_fit = m_checkCrossProbeZoom->GetValue();
cfg->m_CrossProbing.auto_highlight = m_checkCrossProbeAutoHighlight->GetValue();
m_galOptsPanel->TransferDataFromWindow();

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Oct 26 2018)
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -112,6 +112,10 @@ PANEL_EESCHEMA_DISPLAY_OPTIONS_BASE::PANEL_EESCHEMA_DISPLAY_OPTIONS_BASE( wxWind
wxStaticBoxSizer* sbSizer31;
sbSizer31 = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Cross-probing") ), wxVERTICAL );
m_checkCrossProbeOnSelection = new wxCheckBox( sbSizer31->GetStaticBox(), wxID_ANY, _("Cross-probe on selection"), wxDefaultPosition, wxDefaultSize, 0 );
m_checkCrossProbeOnSelection->SetValue(true);
sbSizer31->Add( m_checkCrossProbeOnSelection, 0, wxALL, 5 );
m_checkCrossProbeCenter = new wxCheckBox( sbSizer31->GetStaticBox(), wxID_ANY, _("Center view on cross-probed items"), wxDefaultPosition, wxDefaultSize, 0 );
m_checkCrossProbeCenter->SetValue(true);
sbSizer31->Add( m_checkCrossProbeCenter, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<wxFormBuilder_Project>
<FileVersion major="1" minor="15" />
<FileVersion major="1" minor="16" />
<object class="Project" expanded="1">
<property name="class_decoration"></property>
<property name="code_generation">C++</property>
@ -14,6 +14,7 @@
<property name="file">panel_eeschema_display_options_base</property>
<property name="first_id">1000</property>
<property name="help_provider">none</property>
<property name="image_path_wrapper_function_name"></property>
<property name="indent_with_spaces"></property>
<property name="internationalize">1</property>
<property name="name">PanelEeschemaDisplayOptions</property>
@ -25,6 +26,7 @@
<property name="skip_php_events">1</property>
<property name="skip_python_events">1</property>
<property name="ui_table">UI</property>
<property name="use_array_enum">0</property>
<property name="use_enum">1</property>
<property name="use_microsoft_bom">0</property>
<object class="Panel" expanded="1">
@ -46,6 +48,7 @@
<property name="size">-1,-1</property>
<property name="subclass">RESETTABLE_PANEL; widgets/resettable_panel.h; Not forward_declare</property>
<property name="tooltip"></property>
<property name="two_step_creation">0</property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style">wxTAB_TRAVERSAL</property>
@ -1169,6 +1172,70 @@
<property name="orient">wxVERTICAL</property>
<property name="parent">1</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</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">1</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">Cross-probe on selection</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_checkCrossProbeOnSelection</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>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Oct 26 2018)
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -54,6 +54,7 @@ class PANEL_EESCHEMA_DISPLAY_OPTIONS_BASE : public RESETTABLE_PANEL
wxStaticText* m_highlightColorNote;
wxStaticText* m_highlightWidthLabel;
wxSpinCtrlDouble* m_highlightWidthCtrl;
wxCheckBox* m_checkCrossProbeOnSelection;
wxCheckBox* m_checkCrossProbeCenter;
wxCheckBox* m_checkCrossProbeZoom;
wxCheckBox* m_checkCrossProbeAutoHighlight;
@ -61,6 +62,7 @@ class PANEL_EESCHEMA_DISPLAY_OPTIONS_BASE : public RESETTABLE_PANEL
public:
PANEL_EESCHEMA_DISPLAY_OPTIONS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString );
~PANEL_EESCHEMA_DISPLAY_OPTIONS_BASE();
};

View File

@ -307,6 +307,14 @@ public:
*/
void SendMessageToPCBNEW( EDA_ITEM* aObjectToSync, SCH_SYMBOL* aPart );
/**
* Sends items to Pcbnew for selection
*
* @param aSelectConnections - set to select connected tracks/vias too
* @param aElements are the items to select
*/
void SendSelectItems( bool aSelectConnections, const std::deque<EDA_ITEM*>& aElements );
/**
* Sends a net name to Pcbnew for highlighting
*

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 CERN
* Copyright (C) 2019-2020 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2019-2022 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
@ -641,9 +641,10 @@ TOOL_ACTION EE_ACTIONS::generateBOM( "eeschema.EditorControl.generateBOM",
_( "Generate BOM..." ), _( "Generate a bill of materials for the current schematic" ),
BITMAPS::post_bom );
TOOL_ACTION EE_ACTIONS::explicitCrossProbe( "eeschema.EditorControl.explicitCrossProbe",
TOOL_ACTION EE_ACTIONS::selectOnPCB( "eeschema.EditorControl.selectOnPCB",
AS_GLOBAL, 0, "",
_( "Highlight on PCB" ), _( "Highlight corresponding items in PCB editor" ),
_( "Select on PCB" ),
_( "Select corresponding items in PCB editor" ),
BITMAPS::select_same_sheet );
TOOL_ACTION EE_ACTIONS::toggleHiddenPins( "eeschema.EditorControl.showHiddenPins",

View File

@ -201,7 +201,7 @@ public:
static TOOL_ACTION toggleERCExclusions;
static TOOL_ACTION toggleSyncedPinsMode;
static TOOL_ACTION restartMove;
static TOOL_ACTION explicitCrossProbe;
static TOOL_ACTION selectOnPCB;
static TOOL_ACTION pushPinLength;
static TOOL_ACTION pushPinNameSize;
static TOOL_ACTION pushPinNumSize;

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 CERN
* Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2019-2022 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
@ -171,11 +171,14 @@ bool EE_SELECTION_TOOL::Init()
SCH_PIN_T,
EOT };
static KICAD_T crossProbingTypes[] = { SCH_SYMBOL_T, SCH_PIN_T, SCH_SHEET_T, EOT };
auto wireSelection = E_C::MoreThan( 0 ) && E_C::OnlyType( SCH_ITEM_LOCATE_WIRE_T );
auto busSelection = E_C::MoreThan( 0 ) && E_C::OnlyType( SCH_ITEM_LOCATE_BUS_T );
auto wireOrBusSelection = E_C::MoreThan( 0 ) && E_C::OnlyTypes( wireOrBusTypes );
auto connectedSelection = E_C::MoreThan( 0 ) && E_C::OnlyTypes( connectedTypes );
auto sheetSelection = E_C::Count( 1 ) && E_C::OnlyType( SCH_SHEET_T );
auto sheetSelection = E_C::Count( 1 ) && E_C::OnlyType( SCH_SHEET_T );
auto crossProbingSelection = E_C::MoreThan( 0 ) && E_C::HasTypes( crossProbingTypes );
auto schEditSheetPageNumberCondition =
[&] ( const SELECTION& aSel )
@ -211,7 +214,7 @@ bool EE_SELECTION_TOOL::Init()
auto& menu = m_menu.GetMenu();
menu.AddItem( EE_ACTIONS::enterSheet, sheetSelection && EE_CONDITIONS::Idle, 1 );
menu.AddItem( EE_ACTIONS::explicitCrossProbe, sheetSelection && EE_CONDITIONS::Idle, 1 );
menu.AddItem( EE_ACTIONS::selectOnPCB, crossProbingSelection && EE_CONDITIONS::Idle, 1 );
menu.AddItem( EE_ACTIONS::leaveSheet, belowRootSheetCondition, 1 );
menu.AddSeparator( 100 );

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019 CERN
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2022 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
@ -672,63 +672,14 @@ void SCH_EDITOR_CONTROL::doCrossProbeSchToPcb( const TOOL_EVENT& aEvent, bool aF
if( m_probingPcbToSch )
return;
EE_SELECTION_TOOL* selTool = m_toolMgr->GetTool<EE_SELECTION_TOOL>();
SCH_ITEM* item = nullptr;
SCH_SYMBOL* symbol = nullptr;
if( aForce )
{
EE_SELECTION& selection = selTool->RequestSelection();
if( selection.GetSize() >= 1 )
item = (SCH_ITEM*) selection.Front();
}
else
{
EE_SELECTION& selection = selTool->GetSelection();
if( selection.GetSize() >= 1 )
item = (SCH_ITEM*) selection.Front();
}
if( !item )
{
if( aForce )
m_frame->SendMessageToPCBNEW( nullptr, nullptr );
if( !aForce && !m_frame->eeconfig()->m_CrossProbing.on_selection )
return;
}
EE_SELECTION_TOOL* selTool = m_toolMgr->GetTool<EE_SELECTION_TOOL>();
switch( item->Type() )
{
case SCH_FIELD_T:
case LIB_FIELD_T:
if( item->GetParent() && item->GetParent()->Type() == SCH_SYMBOL_T )
{
symbol = (SCH_SYMBOL*) item->GetParent();
m_frame->SendMessageToPCBNEW( item, symbol );
}
break;
EE_SELECTION& selection = aForce ? selTool->RequestSelection() : selTool->GetSelection();
case SCH_SYMBOL_T:
symbol = (SCH_SYMBOL*) item;
m_frame->SendMessageToPCBNEW( item, symbol );
break;
case SCH_PIN_T:
symbol = (SCH_SYMBOL*) item->GetParent();
m_frame->SendMessageToPCBNEW( static_cast<SCH_PIN*>( item ), symbol );
break;
case SCH_SHEET_T:
if( aForce )
m_frame->SendMessageToPCBNEW( item, nullptr );
break;
default:
break;
}
m_frame->SendSelectItems( false, selection.GetItems() );
}
@ -2318,7 +2269,7 @@ void SCH_EDITOR_CONTROL::setTransitions()
Go( &SCH_EDITOR_CONTROL::CrossProbeToPcb, EVENTS::SelectedEvent );
Go( &SCH_EDITOR_CONTROL::CrossProbeToPcb, EVENTS::UnselectedEvent );
Go( &SCH_EDITOR_CONTROL::CrossProbeToPcb, EVENTS::ClearedEvent );
Go( &SCH_EDITOR_CONTROL::ExplicitCrossProbeToPcb, EE_ACTIONS::explicitCrossProbe.MakeEvent() );
Go( &SCH_EDITOR_CONTROL::ExplicitCrossProbeToPcb, EE_ACTIONS::selectOnPCB.MakeEvent() );
#ifdef KICAD_SPICE
Go( &SCH_EDITOR_CONTROL::SimProbe, EE_ACTIONS::simProbe.MakeEvent() );

View File

@ -84,8 +84,7 @@ public:
///< Notifies pcbnew about the selected item.
int CrossProbeToPcb( const TOOL_EVENT& aEvent );
///< Equivalent to the above, but initiated by the user. We also do SCH_SHEETs on this
///< one (they're too slow on big projects for the auto version above).
///< Equivalent to the above, but initiated by the user.
int ExplicitCrossProbeToPcb( const TOOL_EVENT& aEvent );
#ifdef KICAD_SPICE
@ -151,7 +150,7 @@ public:
* Find a symbol in the schematic and an item in this symbol.
*
* @param aPath The symbol path to find. Pass nullptr to search by aReference.
* @param aReference The symbol reference designator to find, or to display in
* @param aReference The symbol reference designator to find, or to display in
* status bar if aPath is specified
* @param aSearchHierarchy If false, search the current sheet only. Otherwise,
* the entire hierarchy

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2014 CERN
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.TXT for contributors.
* Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.TXT for contributors.
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
@ -37,6 +37,7 @@
enum MAIL_T
{
MAIL_CROSS_PROBE, // PCB<->SCH, CVPCB->SCH cross-probing.
MAIL_SELECTION, // SCH->PCB selection synchronization.
MAIL_ASSIGN_FOOTPRINTS, // CVPCB->SCH footprint stuffing
MAIL_SCH_SAVE, // CVPCB->SCH save the schematic
MAIL_EESCHEMA_NETLIST, // SCH->CVPCB netlist immediately after launching CVPCB

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 Jon Evans <jon@craftyjon.com>
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2020-2022 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 as published by the
@ -29,6 +29,7 @@
*/
struct CROSS_PROBING_SETTINGS
{
bool on_selection; ///< Synchronize the selection for multiple items too
bool center_on_items; ///< Automatically pan to cross-probed items
bool zoom_to_fit; ///< Zoom to fit items (ignored if center_on_items is off)
bool auto_highlight; ///< Automatically turn on highlight mode in the target frame

View File

@ -53,6 +53,7 @@ enum ESCAPE_CONTEXT
{
CTX_NETNAME,
CTX_LIBID,
CTX_IPC,
CTX_QUOTED_STR,
CTX_LINE,
CTX_FILENAME,

View File

@ -131,6 +131,16 @@ public:
*/
static SELECTION_CONDITION HasType( KICAD_T aType );
/**
* Create a functor that tests if among the selected items there is at least one of a
* given types.
*
* @param aTypes is an array containing types that are searched. It has to be ended with
* #KICAD_T::EOT as end marker.
* @return Functor testing for presence of items of a given types.
*/
static SELECTION_CONDITION HasTypes( const KICAD_T aTypes[] );
/**
* Create a functor that tests if the selected items are *only* of given type.
*
@ -179,6 +189,9 @@ private:
///< Helper function used by HasType()
static bool hasTypeFunc( const SELECTION& aSelection, KICAD_T aType );
///< Helper function used by HasTypes()
static bool hasTypesFunc( const SELECTION& aSelection, const KICAD_T aTypes[] );
///< Helper function used by OnlyType()
static bool onlyTypeFunc( const SELECTION& aSelection, KICAD_T aType );

View File

@ -1,7 +1,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2019-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2019-2022 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
@ -41,6 +41,7 @@
#include <eda_dde.h>
#include <kiface_base.h>
#include <kiway_express.h>
#include <string_utils.h>
#include <netlist_reader/pcb_netlist.h>
#include <netlist_reader/board_netlist_updater.h>
#include <painter.h>
@ -277,133 +278,7 @@ void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
{
if( crossProbingSettings.zoom_to_fit )
{
//#define DEFAULT_PCBNEW_CODE // Un-comment for normal full zoom KiCad algorithm
#ifdef DEFAULT_PCBNEW_CODE
auto bbSize = bbox.Inflate( bbox.GetWidth() * 0.2f ).GetSize();
auto screenSize = view->ToWorld( GetCanvas()->GetClientSize(), false );
// The "fabs" on x ensures the right answer when the view is flipped
screenSize.x = std::max( 10.0, fabs( screenSize.x ) );
screenSize.y = std::max( 10.0, screenSize.y );
double ratio = std::max( fabs( bbSize.x / screenSize.x ),
fabs( bbSize.y / screenSize.y ) );
// Try not to zoom on every cross-probe; it gets very noisy
if( crossProbingSettings.zoom_to_fit && ( ratio < 0.5 || ratio > 1.0 ) )
view->SetScale( view->GetScale() / ratio );
#endif // DEFAULT_PCBNEW_CODE
#ifndef DEFAULT_PCBNEW_CODE // Do the scaled zoom
auto bbSize = bbox.Inflate( bbox.GetWidth() * 0.2f ).GetSize();
auto screenSize = view->ToWorld( GetCanvas()->GetClientSize(), false );
// This code tries to come up with a zoom factor that doesn't simply zoom in
// to the cross probed component, but instead shows a reasonable amount of the
// circuit around it to provide context. This reduces or eliminates the need
// to manually change the zoom because it's too close.
// Using the default text height as a constant to compare against, use the
// height of the bounding box of visible items for a footprint to figure out
// if this is a big footprint (like a processor) or a small footprint (like a resistor).
// This ratio is not useful by itself as a scaling factor. It must be "bent" to
// provide good scaling at varying component sizes. Bigger components need less
// scaling than small ones.
double currTextHeight = Millimeter2iu( DEFAULT_TEXT_SIZE );
double compRatio = bbSize.y / currTextHeight; // Ratio of component to text height
// This will end up as the scaling factor we apply to "ratio".
double compRatioBent = 1.0;
// This is similar to the original KiCad code that scaled the zoom to make sure
// components were visible on screen. It's simply a ratio of screen size to
// component size, and its job is to zoom in to make the component fullscreen.
// Earlier in the code the component BBox is given a 20% margin to add some
// breathing room. We compare the height of this enlarged component bbox to the
// default text height. If a component will end up with the sides clipped, we
// adjust later to make sure it fits on screen.
//
// The "fabs" on x ensures the right answer when the view is flipped
screenSize.x = std::max( 10.0, fabs( screenSize.x ) );
screenSize.y = std::max( 10.0, screenSize.y );
double ratio = std::max( -1.0, fabs( bbSize.y / screenSize.y ) );
// Original KiCad code for how much to scale the zoom
double kicadRatio = std::max( fabs( bbSize.x / screenSize.x ),
fabs( bbSize.y / screenSize.y ) );
// LUT to scale zoom ratio to provide reasonable schematic context. Must work
// with footprints of varying sizes (e.g. 0402 package and 200 pin BGA).
// "first" is used as the input and "second" as the output
//
// "first" = compRatio (footprint height / default text height)
// "second" = Amount to scale ratio by
std::vector<std::pair<double, double>> lut{
{ 1, 8 },
{ 1.5, 5 },
{ 3, 3 },
{ 4.5, 2.5 },
{ 8, 2.0 },
{ 12, 1.7 },
{ 16, 1.5 },
{ 24, 1.3 },
{ 32, 1.0 },
};
std::vector<std::pair<double, double>>::iterator it;
compRatioBent = lut.back().second; // Large component default
if( compRatio >= lut.front().first )
{
// Use LUT to do linear interpolation of "compRatio" within "first", then
// use that result to linearly interpolate "second" which gives the scaling
// factor needed.
for( it = lut.begin(); it < lut.end() - 1; it++ )
{
if( it->first <= compRatio && next( it )->first >= compRatio )
{
double diffx = compRatio - it->first;
double diffn = next( it )->first - it->first;
compRatioBent =
it->second + ( next( it )->second - it->second ) * diffx / diffn;
break; // We have our interpolated value
}
}
}
else
{
compRatioBent = lut.front().second; // Small component default
}
// If the width of the part we're probing is bigger than what the screen width will be
// after the zoom, then punt and use the KiCad zoom algorithm since it guarantees the
// part's width will be encompassed within the screen. This will apply to parts that
// are much wider than they are tall.
if( bbSize.x > screenSize.x * ratio * compRatioBent )
{
// Use standard KiCad zoom algorithm for parts too wide to fit screen/
ratio = kicadRatio;
compRatioBent = 1.0; // Reset so we don't modify the "KiCad" ratio
wxLogTrace( "CROSS_PROBE_SCALE",
"Part TOO WIDE for screen. Using normal KiCad zoom ratio: %1.5f",
ratio );
}
// Now that "compRatioBent" holds our final scaling factor we apply it to the original
// fullscreen zoom ratio to arrive at the final ratio itself.
ratio *= compRatioBent;
bool alwaysZoom = false; // DEBUG - allows us to minimize zooming or not
// Try not to zoom on every cross-probe; it gets very noisy
if( ( ratio < 0.5 || ratio > 1.0 ) || alwaysZoom )
view->SetScale( view->GetScale() / ratio );
#endif // ifndef DEFAULT_PCBNEW_CODE
GetToolManager()->GetTool<PCB_SELECTION_TOOL>()->zoomFitCrossProbeBBox( bbox );
}
FocusOnLocation( (wxPoint) bbox.Centre() );
@ -510,6 +385,77 @@ void PCB_EDIT_FRAME::SendCrossProbeNetName( const wxString& aNetName )
}
std::vector<BOARD_ITEM*> PCB_EDIT_FRAME::FindItemsFromSyncSelection( std::string syncStr )
{
wxArrayString syncArray = wxStringTokenize( syncStr, "," );
std::vector<BOARD_ITEM*> items;
for( FOOTPRINT* footprint : GetBoard()->Footprints() )
{
if( footprint == nullptr )
continue;
wxString fpSheetPath = footprint->GetPath().AsString().BeforeLast( '/' );
wxString fpUUID = footprint->m_Uuid.AsString();
if( fpSheetPath.IsEmpty() )
fpSheetPath += '/';
if( fpUUID.empty() )
continue;
wxString fpRefEscaped = EscapeString( footprint->GetReference(), CTX_IPC );
for( wxString syncEntry : syncArray )
{
if( syncEntry.empty() )
continue;
wxString syncData = syncEntry.substr( 1 );
switch( syncEntry.GetChar( 0 ).GetValue() )
{
case 'S': // Select sheet with subsheets: S<Sheet path>
if( fpSheetPath.StartsWith( syncData ) )
{
items.push_back( footprint );
}
break;
case 'F': // Select footprint: F<Reference>
if( syncData == fpRefEscaped )
{
items.push_back( footprint );
}
break;
case 'P': // Select pad: P<Footprint reference>/<Pad number>
{
if( syncData.StartsWith( fpRefEscaped ) )
{
wxString selectPadNumberEscaped =
syncData.substr( fpRefEscaped.size() + 1 ); // Skips the slash
wxString selectPadNumber = UnescapeString( selectPadNumberEscaped );
for( PAD* pad : footprint->Pads() )
{
if( selectPadNumber == pad->GetNumber() )
{
items.push_back( pad );
}
}
}
break;
}
default: break;
}
}
}
return items;
}
void PCB_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
{
std::string& payload = mail.GetPayload();
@ -575,6 +521,50 @@ void PCB_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
ExecuteRemoteCommand( payload.c_str() );
break;
case MAIL_SELECTION:
{
// $SELECT: <mode 0 - only footprints, 1 - with connections>,<spec1>,<spec2>,<spec3>
std::string prefix = "$SELECT: ";
if( !payload.compare( 0, prefix.size(), prefix ) )
{
std::string del = ",";
std::string paramStr = payload.substr( prefix.size() );
int modeEnd = paramStr.find( del );
bool selectConnections = false;
try
{
if( std::stoi( paramStr.substr( 0, modeEnd ) ) == 1 )
selectConnections = true;
}
catch( std::invalid_argument& )
{
wxFAIL;
}
std::vector<BOARD_ITEM*> items =
FindItemsFromSyncSelection( paramStr.substr( modeEnd + 1 ) );
m_syncingSchToPcbSelection = true; // recursion guard
if( selectConnections )
{
GetToolManager()->RunAction( PCB_ACTIONS::syncSelectionWithNets, true,
static_cast<void*>( &items ) );
}
else
{
GetToolManager()->RunAction( PCB_ACTIONS::syncSelection, true,
static_cast<void*>( &items ) );
}
m_syncingSchToPcbSelection = false;
}
break;
}
case MAIL_PCB_UPDATE:
m_toolManager->RunAction( ACTIONS::updatePcbFromSchematic, true );
break;

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 Jean-Pierre Charras, jean-pierre.charras at wanadoo.fr
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2022 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 as published by the
@ -57,6 +57,7 @@ void PANEL_DISPLAY_OPTIONS::loadPCBSettings( PCBNEW_SETTINGS* aCfg )
m_OptDisplayPadNoConn->SetValue( aCfg->m_Display.m_DisplayPadNoConnects );
m_ShowNetNamesOption->SetSelection( aCfg->m_Display.m_DisplayNetNamesMode );
m_live3Drefresh->SetValue( aCfg->m_Display.m_Live3DRefresh );
m_checkCrossProbeOnSelection->SetValue( aCfg->m_CrossProbing.on_selection );
m_checkCrossProbeCenter->SetValue( aCfg->m_CrossProbing.center_on_items );
m_checkCrossProbeZoom->SetValue( aCfg->m_CrossProbing.zoom_to_fit );
m_checkCrossProbeAutoHighlight->SetValue( aCfg->m_CrossProbing.auto_highlight );
@ -99,7 +100,7 @@ bool PANEL_DISPLAY_OPTIONS::TransferDataFromWindow()
cfg->m_Display.m_DisplayPadNoConnects = m_OptDisplayPadNoConn->GetValue();
cfg->m_Display.m_DisplayNetNamesMode = m_ShowNetNamesOption->GetSelection();
cfg->m_Display.m_Live3DRefresh = m_live3Drefresh->GetValue();
cfg->m_CrossProbing.center_on_items = m_checkCrossProbeCenter->GetValue();
cfg->m_CrossProbing.on_selection = m_checkCrossProbeOnSelection->GetValue();
cfg->m_CrossProbing.zoom_to_fit = m_checkCrossProbeZoom->GetValue();
cfg->m_CrossProbing.auto_highlight = m_checkCrossProbeAutoHighlight->GetValue();
}

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Oct 26 2018)
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -73,6 +73,10 @@ PANEL_DISPLAY_OPTIONS_BASE::PANEL_DISPLAY_OPTIONS_BASE( wxWindow* parent, wxWind
wxStaticBoxSizer* sbSizer3;
sbSizer3 = new wxStaticBoxSizer( new wxStaticBox( pcbPage, wxID_ANY, _("Cross-probing") ), wxVERTICAL );
m_checkCrossProbeOnSelection = new wxCheckBox( sbSizer3->GetStaticBox(), wxID_ANY, _("Cross-probe on selection"), wxDefaultPosition, wxDefaultSize, 0 );
m_checkCrossProbeOnSelection->SetValue(true);
sbSizer3->Add( m_checkCrossProbeOnSelection, 0, wxALL, 5 );
m_checkCrossProbeCenter = new wxCheckBox( sbSizer3->GetStaticBox(), wxID_ANY, _("Scroll cross-probed items into view"), wxDefaultPosition, wxDefaultSize, 0 );
m_checkCrossProbeCenter->SetValue(true);
sbSizer3->Add( m_checkCrossProbeCenter, 0, wxBOTTOM|wxRIGHT|wxLEFT, 5 );

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<wxFormBuilder_Project>
<FileVersion major="1" minor="15" />
<FileVersion major="1" minor="16" />
<object class="Project" expanded="1">
<property name="class_decoration"></property>
<property name="code_generation">C++</property>
@ -14,6 +14,7 @@
<property name="file">panel_display_options_base</property>
<property name="first_id">1000</property>
<property name="help_provider">none</property>
<property name="image_path_wrapper_function_name"></property>
<property name="indent_with_spaces"></property>
<property name="internationalize">1</property>
<property name="name">PanelDisplayOptions</property>
@ -25,6 +26,7 @@
<property name="skip_php_events">1</property>
<property name="skip_python_events">1</property>
<property name="ui_table">UI</property>
<property name="use_array_enum">0</property>
<property name="use_enum">1</property>
<property name="use_microsoft_bom">0</property>
<object class="Panel" expanded="1">
@ -46,6 +48,7 @@
<property name="size">-1,-1</property>
<property name="subclass">RESETTABLE_PANEL; widgets/resettable_panel.h; Not forward_declare</property>
<property name="tooltip"></property>
<property name="two_step_creation">0</property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style">wxTAB_TRAVERSAL</property>
@ -608,6 +611,70 @@
<property name="orient">wxVERTICAL</property>
<property name="parent">1</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxALL</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">1</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">Cross-probe on selection</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_checkCrossProbeOnSelection</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>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">5</property>
<property name="flag">wxBOTTOM|wxRIGHT|wxLEFT</property>

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Oct 26 2018)
// C++ code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -45,6 +45,7 @@ class PANEL_DISPLAY_OPTIONS_BASE : public RESETTABLE_PANEL
wxCheckBox* m_OptDisplayPadNoConn;
wxRadioBox* m_OptDisplayTracksClearance;
wxCheckBox* m_OptDisplayPadClearence;
wxCheckBox* m_checkCrossProbeOnSelection;
wxCheckBox* m_checkCrossProbeCenter;
wxCheckBox* m_checkCrossProbeZoom;
wxCheckBox* m_checkCrossProbeAutoHighlight;
@ -53,6 +54,7 @@ class PANEL_DISPLAY_OPTIONS_BASE : public RESETTABLE_PANEL
public:
PANEL_DISPLAY_OPTIONS_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxTAB_TRAVERSAL, const wxString& name = wxEmptyString );
~PANEL_DISPLAY_OPTIONS_BASE();
};

View File

@ -4,7 +4,7 @@
* Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2013 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 2013-2021 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2013-2022 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 as published by the
@ -175,10 +175,10 @@ END_EVENT_TABLE()
PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
PCB_BASE_EDIT_FRAME( aKiway, aParent, FRAME_PCB_EDITOR, _( "PCB Editor" ), wxDefaultPosition,
wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, PCB_EDIT_FRAME_NAME ),
m_exportNetlistAction( nullptr ),
m_findDialog( nullptr )
PCB_BASE_EDIT_FRAME( aKiway, aParent, FRAME_PCB_EDITOR, _( "PCB Editor" ),
wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE,
PCB_EDIT_FRAME_NAME ),
m_exportNetlistAction( nullptr ), m_findDialog( nullptr )
{
m_maximizeByDefault = true;
m_showBorderAndTitleBlock = true; // true to display sheet references
@ -187,6 +187,7 @@ PCB_EDIT_FRAME::PCB_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ) :
m_SelLayerBox = nullptr;
m_show_layer_manager_tools = true;
m_supportsAutoSave = true;
m_syncingSchToPcbSelection = false;
// We don't know what state board was in when it was last saved, so we have to
// assume dirty

View File

@ -121,6 +121,11 @@ public:
void KiwayMailIn( KIWAY_EXPRESS& aEvent ) override;
/**
* Used to find items by selection synchronization spec string.
*/
std::vector<BOARD_ITEM*> FindItemsFromSyncSelection( std::string syncStr );
/**
* Show the Find dialog.
*/
@ -782,6 +787,8 @@ public:
bool m_ZoneFillsDirty; // Board has been modified since last zone fill.
bool m_syncingSchToPcbSelection; // Recursion guard when synchronizing selection from schematic
private:
friend struct PCB::IFACE;
friend class APPEARANCE_CONTROLS;

Some files were not shown because too many files have changed in this diff Show More