Use full net names in netclasses

Short net names are not unique; full names with paths must be used.
Added a grid cell renderer that does the escaping, to make it easier
to display net names in grid cells.

Once you unescape a net name, you can't go back to the escaped form
because you can't assume which `/` should be {slash} and which `/`
Because of this, we cannot use Unescape/Escape on the data model in
the netclass setup panel, and instead do the Unescape in the view.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/5331
This commit is contained in:
Jon Evans 2020-08-23 21:46:01 -04:00
parent 1efd512847
commit 5e2946ef90
8 changed files with 120 additions and 90 deletions

View File

@ -213,6 +213,7 @@ set( COMMON_WIDGET_SRCS
widgets/grid_combobox.cpp
widgets/grid_icon_text_helpers.cpp
widgets/grid_text_button_helpers.cpp
widgets/grid_text_helpers.cpp
widgets/indicator_icon.cpp
widgets/infobar.cpp
widgets/layer_box_selector.cpp

View File

@ -35,6 +35,7 @@
#include <kicad_string.h>
#include <widgets/grid_color_swatch_helpers.h>
#include <widgets/grid_icon_text_helpers.h>
#include <widgets/grid_text_helpers.h>
#include <algorithm>
@ -68,12 +69,12 @@ wxArrayString g_lineStyleNames;
PANEL_SETUP_NETCLASSES::PANEL_SETUP_NETCLASSES( PAGED_DIALOG* aParent, NETCLASSES* aNetclasses,
const std::vector<wxString>& aCandidateNetNames,
const std::vector<wxString>& aNetNames,
bool aIsEEschema ) :
PANEL_SETUP_NETCLASSES_BASE( aParent->GetTreebook() ),
m_Parent( aParent ),
m_netclasses( aNetclasses ),
m_candidateNetNames( aCandidateNetNames )
m_netNames( aNetNames )
{
if( g_lineStyleIcons.empty() )
{
@ -166,6 +167,7 @@ PANEL_SETUP_NETCLASSES::PANEL_SETUP_NETCLASSES( PAGED_DIALOG* aParent, NETCLASSE
// Set up the net name column of the netclass membership grid to read-only
wxGridCellAttr* attr = new wxGridCellAttr;
attr->SetReadOnly( true );
attr->SetRenderer( new GRID_CELL_ESCAPED_TEXT_RENDERER );
m_membershipGrid->SetColAttr( 0, attr );
m_addButton->SetBitmap( KiBitmap( small_plus_xpm ) );
@ -222,7 +224,7 @@ bool PANEL_SETUP_NETCLASSES::TransferDataToWindow()
std::map<wxString, wxString> netToNetclassMap;
std::map<wxString, wxString> staleNetMap;
for( const wxString& candidate : m_candidateNetNames )
for( const wxString& candidate : m_netNames )
netToNetclassMap[ candidate ] = wxEmptyString;
if( m_netclassGrid->GetNumberRows() )
@ -249,14 +251,10 @@ bool PANEL_SETUP_NETCLASSES::TransferDataToWindow()
for( const wxString& net : *netclass )
{
// While we currently only store shortNames as members, legacy versions stored
// fully-qualified names so we don't know which kind we're going to find.
wxString shortName = net.AfterLast( '/' );
if( netToNetclassMap.count( shortName ) )
netToNetclassMap[ shortName ] = i->second->GetName();
if( netToNetclassMap.count( net ) )
netToNetclassMap[ net ] = i->second->GetName();
else
staleNetMap[ shortName ] = i->second->GetName();
staleNetMap[ net ] = i->second->GetName();
}
}
@ -265,10 +263,10 @@ bool PANEL_SETUP_NETCLASSES::TransferDataToWindow()
// add currently-assigned and candidate netnames to membership lists
for( const std::pair<const wxString, wxString>& ii : netToNetclassMap )
addNet( UnescapeString( ii.first ), ii.second, false );
addNet( ii.first, ii.second, false );
for( const std::pair<const wxString, wxString>& ii : staleNetMap )
addNet( UnescapeString( ii.first ), ii.second, true );
addNet( ii.first, ii.second, true );
return true;
}
@ -378,7 +376,7 @@ bool PANEL_SETUP_NETCLASSES::TransferDataFromWindow()
const NETCLASSPTR& nc = m_netclasses->Find( classname );
if( nc )
nc->Add( EscapeString( netname, CTX_NETNAME ) );
nc->Add( netname );
}
}

View File

@ -37,7 +37,7 @@ class PANEL_SETUP_NETCLASSES : public PANEL_SETUP_NETCLASSES_BASE
private:
PAGED_DIALOG* m_Parent;
NETCLASSES* m_netclasses;
std::vector<wxString> m_candidateNetNames;
std::vector<wxString> m_netNames;
int* m_originalColWidths;
bool m_netclassesDirty; // The netclass drop-down menus need rebuilding
@ -69,7 +69,7 @@ private:
public:
PANEL_SETUP_NETCLASSES( PAGED_DIALOG* aParent, NETCLASSES* aNetclasses,
const std::vector<wxString>& aCandidateNetNames, bool isEEschema );
const std::vector<wxString>& aNetNames, bool isEEschema );
~PANEL_SETUP_NETCLASSES( ) override;
bool TransferDataToWindow() override;

View File

@ -0,0 +1,52 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* @author Jon Evans <jon@craftyjon.com>
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <kicad_string.h>
#include <widgets/grid_text_helpers.h>
GRID_CELL_ESCAPED_TEXT_RENDERER::GRID_CELL_ESCAPED_TEXT_RENDERER() :
wxGridCellStringRenderer()
{
}
void GRID_CELL_ESCAPED_TEXT_RENDERER::Draw( wxGrid& aGrid, wxGridCellAttr& aAttr, wxDC& aDC,
const wxRect& aRect, int aRow, int aCol,
bool isSelected )
{
wxString unescaped = UnescapeString( aGrid.GetCellValue( aRow, aCol ) );
wxRect rect = aRect;
rect.Inflate( -1 );
// erase background
wxGridCellRenderer::Draw( aGrid, aAttr, aDC, aRect, aRow, aCol, isSelected );
SetTextColoursAndFont( aGrid, aAttr, aDC, isSelected );
aGrid.DrawTextRectangle( aDC, unescaped, rect, wxALIGN_LEFT, wxALIGN_CENTRE );
}
wxSize GRID_CELL_ESCAPED_TEXT_RENDERER::GetBestSize( wxGrid & aGrid, wxGridCellAttr & aAttr,
wxDC & aDC, int aRow, int aCol )
{
wxString unescaped = UnescapeString( aGrid.GetCellValue( aRow, aCol ) );
return wxGridCellStringRenderer::DoGetBestSize( aAttr, aDC, unescaped );
}

View File

@ -168,73 +168,9 @@ std::vector<wxString> SCHEMATIC::GetNetClassAssignmentCandidates()
{
std::vector<wxString> names;
SCH_SCREENS allScreens( Root() );
for( SCH_SCREEN* screen = allScreens.GetFirst(); screen; screen = allScreens.GetNext() )
{
for( SCH_ITEM* item : screen->Items() )
{
switch( item->Type() )
{
case SCH_PIN_T:
{
SCH_PIN* pin = static_cast<SCH_PIN*>( item );
if( pin->IsPowerConnection() )
names.emplace_back( pin->GetName() );
}
break;
case SCH_LABEL_T:
case SCH_GLOBAL_LABEL_T:
case SCH_HIER_LABEL_T:
case SCH_SHEET_PIN_T:
{
wxString unescaped = static_cast<SCH_TEXT*>( item )->GetShownText();
wxString busPrefix;
std::vector<wxString> busMembers;
if( NET_SETTINGS::ParseBusVector( unescaped, nullptr, nullptr ) )
{
// Allow netclass assignment to an entire vector.
names.emplace_back( EscapeString( unescaped, CTX_NETNAME ) );
}
else if( NET_SETTINGS::ParseBusGroup( unescaped, &busPrefix, &busMembers ) )
{
// Allow netclass assignment to an entire group.
names.emplace_back( EscapeString( unescaped, CTX_NETNAME ) );
// Named bus groups generate a net prefix, unnamed ones don't
if( !busPrefix.IsEmpty() )
busPrefix += wxT( "." );
for( const wxString& member : busMembers )
{
// Handle alias inside bus group member list
if( const std::shared_ptr<BUS_ALIAS>& alias = GetBusAlias( member ) )
{
for( const wxString& alias_member : alias->Members() )
names.emplace_back( busPrefix + alias_member );
}
else
{
names.emplace_back( busPrefix + member );
}
}
}
else
{
names.emplace_back( EscapeString( unescaped, CTX_NETNAME ) );
}
}
break;
default:
break;
}
}
}
// Key is a NET_NAME_CODE aka std::pair<name, code>
for( const NET_MAP::value_type& pair: m_connectionGraph->GetNetMap() )
names.emplace_back( pair.first.first );
return names;
}

View File

@ -0,0 +1,44 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2020 KiCad Developers, see AUTHORS.txt for contributors.
* @author Jon Evans <jon@craftyjon.com>
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KICAD_GRID_TEXT_HELPERS_H
#define KICAD_GRID_TEXT_HELPERS_H
#include <wx/generic/gridctrl.h>
class wxGrid;
/**
* A text renderer that can unescape text for display
* This is useful where it's desired to keep the underlying storage escaped.
*/
class GRID_CELL_ESCAPED_TEXT_RENDERER : public wxGridCellStringRenderer
{
public:
GRID_CELL_ESCAPED_TEXT_RENDERER();
void Draw( wxGrid& aGrid, wxGridCellAttr& aAttr, wxDC& aDC,
const wxRect& aRect, int aRow, int aCol, bool isSelected ) override;
wxSize GetBestSize( wxGrid & grid, wxGridCellAttr & attr, wxDC & dc,
int row, int col ) override;
};
#endif // KICAD_GRID_TEXT_HELPERS_H

View File

@ -1298,8 +1298,8 @@ std::vector<wxString> BOARD::GetNetClassAssignmentCandidates()
for( NETINFO_ITEM* net : m_NetInfo )
{
if( !net->GetShortNetname().IsEmpty() )
names.emplace_back( net->GetShortNetname() );
if( !net->GetNetname().IsEmpty() )
names.emplace_back( net->GetNetname() );
}
return names;
@ -1324,18 +1324,12 @@ void BOARD::SynchronizeNetsAndNetClasses()
for( NETINFO_ITEM* net : m_NetInfo )
{
const wxString& netname = net->GetNetname();
const wxString& shortname = net->GetShortNetname();
if( netSettings->m_NetClassAssignments.count( netname ) )
{
const wxString& classname = netSettings->m_NetClassAssignments[ netname ];
net->SetClass( netClasses.Find( classname ) );
}
else if( netSettings->m_NetClassAssignments.count( shortname ) )
{
const wxString& classname = netSettings->m_NetClassAssignments[ shortname ];
net->SetClass( netClasses.Find( classname ) );
}
else
{
net->SetClass( defaultNetClass );

View File

@ -35,6 +35,7 @@
#include <widgets/color_swatch.h>
#include <widgets/grid_bitmap_toggle.h>
#include <widgets/grid_color_swatch_helpers.h>
#include <widgets/grid_text_helpers.h>
#include <widgets/indicator_icon.h>
@ -438,6 +439,10 @@ APPEARANCE_CONTROLS::APPEARANCE_CONTROLS( PCB_BASE_FRAME* aParent, wxWindow* aFo
new GRID_CELL_COLOR_RENDERER( m_frame, SWATCH_SMALL ),
new GRID_CELL_COLOR_SELECTOR( m_frame, m_netsGrid ) );
wxGridCellAttr* attr = new wxGridCellAttr;
attr->SetRenderer( new GRID_CELL_ESCAPED_TEXT_RENDERER );
m_netsGrid->SetColAttr( NET_GRID_TABLE::COL_LABEL, attr );
m_netsTable = new NET_GRID_TABLE( m_frame );
m_netsGrid->SetTable( m_netsTable, true, wxGrid::wxGridSelectRows );