From 5e2946ef900e171110523578b4cfc35a0302ba53 Mon Sep 17 00:00:00 2001 From: Jon Evans Date: Sun, 23 Aug 2020 21:46:01 -0400 Subject: [PATCH] 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 --- common/CMakeLists.txt | 1 + common/dialogs/panel_setup_netclasses.cpp | 24 ++++---- common/dialogs/panel_setup_netclasses.h | 4 +- common/widgets/grid_text_helpers.cpp | 52 +++++++++++++++++ eeschema/schematic.cpp | 70 +---------------------- include/widgets/grid_text_helpers.h | 44 ++++++++++++++ pcbnew/class_board.cpp | 10 +--- pcbnew/widgets/appearance_controls.cpp | 5 ++ 8 files changed, 120 insertions(+), 90 deletions(-) create mode 100644 common/widgets/grid_text_helpers.cpp create mode 100644 include/widgets/grid_text_helpers.h diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index cb80043d9d..dc60c113cb 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -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 diff --git a/common/dialogs/panel_setup_netclasses.cpp b/common/dialogs/panel_setup_netclasses.cpp index ed4f84d57e..a120d4e907 100644 --- a/common/dialogs/panel_setup_netclasses.cpp +++ b/common/dialogs/panel_setup_netclasses.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include @@ -68,12 +69,12 @@ wxArrayString g_lineStyleNames; PANEL_SETUP_NETCLASSES::PANEL_SETUP_NETCLASSES( PAGED_DIALOG* aParent, NETCLASSES* aNetclasses, - const std::vector& aCandidateNetNames, + const std::vector& 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 netToNetclassMap; std::map 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& ii : netToNetclassMap ) - addNet( UnescapeString( ii.first ), ii.second, false ); + addNet( ii.first, ii.second, false ); for( const std::pair& 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 ); } } diff --git a/common/dialogs/panel_setup_netclasses.h b/common/dialogs/panel_setup_netclasses.h index 19c9c7213e..5cf4468377 100644 --- a/common/dialogs/panel_setup_netclasses.h +++ b/common/dialogs/panel_setup_netclasses.h @@ -37,7 +37,7 @@ class PANEL_SETUP_NETCLASSES : public PANEL_SETUP_NETCLASSES_BASE private: PAGED_DIALOG* m_Parent; NETCLASSES* m_netclasses; - std::vector m_candidateNetNames; + std::vector 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& aCandidateNetNames, bool isEEschema ); + const std::vector& aNetNames, bool isEEschema ); ~PANEL_SETUP_NETCLASSES( ) override; bool TransferDataToWindow() override; diff --git a/common/widgets/grid_text_helpers.cpp b/common/widgets/grid_text_helpers.cpp new file mode 100644 index 0000000000..e37126d15f --- /dev/null +++ b/common/widgets/grid_text_helpers.cpp @@ -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 + * + * 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 . + */ + +#include +#include + + +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 ); +} diff --git a/eeschema/schematic.cpp b/eeschema/schematic.cpp index 63b4baf723..09799ff47f 100644 --- a/eeschema/schematic.cpp +++ b/eeschema/schematic.cpp @@ -168,73 +168,9 @@ std::vector SCHEMATIC::GetNetClassAssignmentCandidates() { std::vector 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( 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( item )->GetShownText(); - - wxString busPrefix; - std::vector 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& 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 + for( const NET_MAP::value_type& pair: m_connectionGraph->GetNetMap() ) + names.emplace_back( pair.first.first ); return names; } diff --git a/include/widgets/grid_text_helpers.h b/include/widgets/grid_text_helpers.h new file mode 100644 index 0000000000..746623f825 --- /dev/null +++ b/include/widgets/grid_text_helpers.h @@ -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 + * + * 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 . + */ + +#ifndef KICAD_GRID_TEXT_HELPERS_H +#define KICAD_GRID_TEXT_HELPERS_H + +#include + +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 diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index 0cfebf6d06..53d3df5655 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -1298,8 +1298,8 @@ std::vector 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 ); diff --git a/pcbnew/widgets/appearance_controls.cpp b/pcbnew/widgets/appearance_controls.cpp index 62c20b5f1c..3ed04d2fef 100644 --- a/pcbnew/widgets/appearance_controls.cpp +++ b/pcbnew/widgets/appearance_controls.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include @@ -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 );