Browse Source
New connectivity algorithm and bus upgrades
New connectivity algorithm and bus upgrades
Bus upgrades: core new connectivity code Bus upgrades: eeschema integration and modifications Bus upgrades: eeschema dialogs Bus upgrades: netlist export Bus upgrades: file format changespull/13/head
committed by
Wayne Stambaugh
89 changed files with 7138 additions and 405 deletions
-
2CMakeLists.txt
-
55common/validators.cpp
-
7eeschema/CMakeLists.txt
-
12eeschema/annotate.cpp
-
2eeschema/block.cpp
-
155eeschema/bus-wire-junction.cpp
-
41eeschema/bus_alias.cpp
-
100eeschema/bus_alias.h
-
1644eeschema/connection_graph.cpp
-
327eeschema/connection_graph.h
-
3eeschema/controle.cpp
-
517eeschema/dialogs/dialog_bus_manager.cpp
-
90eeschema/dialogs/dialog_bus_manager.h
-
11eeschema/dialogs/dialog_edit_label.cpp
-
4eeschema/dialogs/dialog_edit_label_base.cpp
-
11eeschema/dialogs/dialog_edit_label_base.fbp
-
5eeschema/dialogs/dialog_edit_label_base.h
-
103eeschema/dialogs/dialog_erc.cpp
-
9eeschema/dialogs/dialog_erc.h
-
20eeschema/dialogs/dialog_erc_base.cpp
-
367eeschema/dialogs/dialog_erc_base.fbp
-
6eeschema/dialogs/dialog_erc_base.h
-
229eeschema/dialogs/dialog_migrate_buses.cpp
-
71eeschema/dialogs/dialog_migrate_buses.h
-
70eeschema/dialogs/dialog_migrate_buses_base.cpp
-
669eeschema/dialogs/dialog_migrate_buses_base.fbp
-
57eeschema/dialogs/dialog_migrate_buses_base.h
-
1eeschema/dialogs/dialog_sch_edit_sheet_pin.cpp
-
1eeschema/dialogs/dialog_sch_sheet_props.cpp
-
17eeschema/drc_erc_item.cpp
-
3eeschema/edit_component_in_schematic.cpp
-
21eeschema/eeschema_config.cpp
-
6eeschema/eeschema_id.h
-
70eeschema/erc.cpp
-
49eeschema/erc.h
-
82eeschema/erc_settings.h
-
31eeschema/files-io.cpp
-
26eeschema/find.cpp
-
14eeschema/general.h
-
5eeschema/getpart.cpp
-
1eeschema/help_common_strings.h
-
13eeschema/hierarch.cpp
-
76eeschema/highlight_connection.cpp
-
5eeschema/hotkeys.cpp
-
1eeschema/hotkeys.h
-
3eeschema/invoke_sch_dialog.h
-
1eeschema/lib_draw_item.h
-
14eeschema/lib_pin.cpp
-
6eeschema/menubar.cpp
-
111eeschema/netlist_exporters/netlist_exporter_generic.cpp
-
15eeschema/netlist_exporters/netlist_exporter_generic.h
-
131eeschema/netlist_exporters/netlist_exporter_kicad.cpp
-
6eeschema/netlist_exporters/netlist_exporter_kicad.h
-
6eeschema/netlist_generator.cpp
-
159eeschema/netlist_object.cpp
-
15eeschema/netlist_object.h
-
2eeschema/onleftclick.cpp
-
58eeschema/onrightclick.cpp
-
54eeschema/sch_base_frame.cpp
-
9eeschema/sch_base_frame.h
-
31eeschema/sch_bus_entry.cpp
-
16eeschema/sch_bus_entry.h
-
60eeschema/sch_component.cpp
-
33eeschema/sch_component.h
-
469eeschema/sch_connection.cpp
-
347eeschema/sch_connection.h
-
79eeschema/sch_edit_frame.cpp
-
94eeschema/sch_edit_frame.h
-
44eeschema/sch_item_struct.cpp
-
49eeschema/sch_item_struct.h
-
6eeschema/sch_junction.cpp
-
47eeschema/sch_legacy_plugin.cpp
-
4eeschema/sch_legacy_plugin.h
-
35eeschema/sch_line.cpp
-
2eeschema/sch_line.h
-
37eeschema/sch_painter.cpp
-
87eeschema/sch_pin_connection.cpp
-
77eeschema/sch_pin_connection.h
-
77eeschema/sch_screen.cpp
-
39eeschema/sch_screen.h
-
3eeschema/sch_sheet.cpp
-
2eeschema/sch_sheet.h
-
16eeschema/sch_sheet_path.cpp
-
13eeschema/sch_sheet_path.h
-
50eeschema/sch_text.cpp
-
3eeschema/sch_text.h
-
161eeschema/schedit.cpp
-
1include/core/typeinfo.h
-
62include/validators.h
@ -0,0 +1,41 @@ |
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2018 CERN |
|||
* @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 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License along |
|||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
|
|||
#include <algorithm>
|
|||
|
|||
#include "bus_alias.h"
|
|||
|
|||
|
|||
BUS_ALIAS::BUS_ALIAS( SCH_SCREEN* aParent ) : |
|||
m_parent( aParent ) |
|||
{ |
|||
} |
|||
|
|||
|
|||
BUS_ALIAS::~BUS_ALIAS() |
|||
{ |
|||
} |
|||
|
|||
|
|||
bool BUS_ALIAS::Contains( const wxString& aName ) |
|||
{ |
|||
return ( std::find( m_members.begin(), m_members.end(), aName ) |
|||
!= m_members.end() ); |
|||
} |
@ -0,0 +1,100 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2018 CERN |
|||
* @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 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License along |
|||
* with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
#ifndef _BUS_ALIAS_H |
|||
#define _BUS_ALIAS_H |
|||
|
|||
#include <memory> |
|||
#include <vector> |
|||
#include <wx/string.h> |
|||
|
|||
|
|||
class SCH_SCREEN; |
|||
|
|||
|
|||
class BUS_ALIAS |
|||
{ |
|||
public: |
|||
BUS_ALIAS( SCH_SCREEN* aParent = NULL ); |
|||
|
|||
~BUS_ALIAS(); |
|||
|
|||
std::shared_ptr< BUS_ALIAS > Clone() const |
|||
{ |
|||
return std::make_shared< BUS_ALIAS >( *this ); |
|||
} |
|||
|
|||
wxString GetName() |
|||
{ |
|||
return m_name; |
|||
} |
|||
|
|||
void SetName( const wxString& aName ) |
|||
{ |
|||
m_name = aName; |
|||
} |
|||
|
|||
void ClearMembers() |
|||
{ |
|||
m_members.clear(); |
|||
} |
|||
|
|||
void AddMember( const wxString& aName ) |
|||
{ |
|||
m_members.push_back( aName ); |
|||
} |
|||
|
|||
int GetMemberCount() |
|||
{ |
|||
return m_members.size(); |
|||
} |
|||
|
|||
std::vector< wxString >& Members() |
|||
{ |
|||
return m_members; |
|||
} |
|||
|
|||
bool Contains( const wxString& aName ); |
|||
|
|||
SCH_SCREEN* GetParent() |
|||
{ |
|||
return m_parent; |
|||
} |
|||
|
|||
void SetParent( SCH_SCREEN* aParent ) |
|||
{ |
|||
m_parent = aParent; |
|||
} |
|||
|
|||
protected: |
|||
|
|||
wxString m_name; |
|||
|
|||
std::vector< wxString > m_members; |
|||
|
|||
/** |
|||
* The bus alias editor dialog can edit aliases from all open sheets. |
|||
* This means we have to store a reference back to our parent so that |
|||
* the dialog can update the parent if aliases are changed or removed. |
|||
*/ |
|||
SCH_SCREEN* m_parent; |
|||
}; |
|||
|
|||
#endif |
1644
eeschema/connection_graph.cpp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,327 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2018 CERN |
|||
* @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 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License along |
|||
* with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
#ifndef _CONNECTION_GRAPH_H |
|||
#define _CONNECTION_GRAPH_H |
|||
|
|||
#include <mutex> |
|||
#include <vector> |
|||
|
|||
#include <common.h> |
|||
#include <erc_settings.h> |
|||
#include <sch_connection.h> |
|||
#include <sch_item_struct.h> |
|||
|
|||
|
|||
#ifdef DEBUG |
|||
// Uncomment this line to enable connectivity debugging features |
|||
// #define CONNECTIVITY_DEBUG |
|||
#endif |
|||
|
|||
class SCH_PIN_CONNECTION; |
|||
|
|||
class SCH_EDIT_FRAME; |
|||
|
|||
|
|||
/** |
|||
* A subgraph is a set of items that are "physically" connected in the schematic. |
|||
* |
|||
* For example, a label connected to a wire and so on. |
|||
* A net is composed of one or more subgraphs. |
|||
* |
|||
* A set of items that appears to be physically connected may actually be more |
|||
* than one subgraph, because some items don't connect electrically. |
|||
* |
|||
* For example, multiple bus wires can come together at a junction but have |
|||
* different labels on each branch. Each label+wire branch is its own subgraph. |
|||
* |
|||
*/ |
|||
class CONNECTION_SUBGRAPH |
|||
{ |
|||
public: |
|||
CONNECTION_SUBGRAPH( SCH_EDIT_FRAME* aFrame ) : |
|||
m_dirty( false ), m_code( -1 ), m_multiple_power_ports( false ), |
|||
m_no_connect( nullptr ), m_driver( nullptr ), m_frame( aFrame ) |
|||
{} |
|||
/** |
|||
* Determines which potential driver should drive the subgraph. |
|||
* |
|||
* If multiple possible drivers exist, picks one according to the priority. |
|||
* If multiple "winners" exist, returns false and sets m_driver to nullptr. |
|||
* |
|||
* @param aCreateMarkers controls whether ERC markers should be added for conflicts |
|||
* @return true if m_driver was set, or false if a conflict occurred |
|||
*/ |
|||
bool ResolveDrivers( bool aCreateMarkers = false ); |
|||
|
|||
/** |
|||
* Returns the fully-qualified net name for this subgraph (if one exists) |
|||
*/ |
|||
wxString GetNetName(); |
|||
|
|||
/// Returns all the bus labels attached to this subgraph (if any) |
|||
std::vector<SCH_ITEM*> GetBusLabels(); |
|||
|
|||
bool m_dirty; |
|||
|
|||
long m_code; |
|||
|
|||
/// True if this subgraph contains multiple power ports to join in one net |
|||
bool m_multiple_power_ports; |
|||
|
|||
/// No-connect item in graph, if any |
|||
SCH_ITEM* m_no_connect; |
|||
|
|||
std::vector<SCH_ITEM*> m_items; |
|||
|
|||
std::vector<SCH_ITEM*> m_drivers; |
|||
|
|||
SCH_ITEM* m_driver; |
|||
|
|||
SCH_SHEET_PATH m_sheet; |
|||
|
|||
// Needed for m_UserUnits for now; maybe refactor later |
|||
SCH_EDIT_FRAME* m_frame; |
|||
|
|||
/** |
|||
* This map stores pointers to other subgraphs on the same sheet as this one |
|||
* which should be connected to this one. |
|||
* |
|||
* For example, if this subgraph is part of the bus D[7..0] and there is |
|||
* another subgraph on this sheet with connection D7, this map will include |
|||
* a pointer to that subgraph under the key D7 (where the key comes from |
|||
* the m_members list of the SCH_CONNECTION that drives this subgraph) |
|||
*/ |
|||
std::unordered_map< std::shared_ptr<SCH_CONNECTION>, |
|||
std::vector<CONNECTION_SUBGRAPH*> > m_neighbor_map; |
|||
}; |
|||
|
|||
|
|||
/** |
|||
* Calculates the connectivity of a schematic and generates netlists |
|||
*/ |
|||
class CONNECTION_GRAPH |
|||
{ |
|||
public: |
|||
CONNECTION_GRAPH( SCH_EDIT_FRAME* aFrame) : |
|||
m_frame( aFrame ) |
|||
{} |
|||
|
|||
void Reset(); |
|||
|
|||
/** |
|||
* Updates the connection graph for the given list of sheets. |
|||
* |
|||
* @param aSheetList should be the whole schematic for now |
|||
*/ |
|||
void Recalculate( SCH_SHEET_LIST aSheetList ); |
|||
|
|||
/** |
|||
* Updates the connectivity graph based on a single item |
|||
*/ |
|||
void RebuildGraphForItem( SCH_ITEM* aItem ); |
|||
|
|||
/** |
|||
* Returns a bus alias pointer for the given name if it exists (from cache) |
|||
* |
|||
* CONNECTION_GRAPH caches these, they are owned by the SCH_SCREEN that |
|||
* the alias was defined on. The cache is only used to update the graph. |
|||
*/ |
|||
std::shared_ptr<BUS_ALIAS> GetBusAlias( wxString aName ); |
|||
|
|||
/** |
|||
* Determines which subgraphs have more than one conflicting bus label. |
|||
* |
|||
* @see DIALOG_MIGRATE_BUSES |
|||
* @return a list of subgraphs that need migration |
|||
*/ |
|||
|
|||
std::vector<CONNECTION_SUBGRAPH*> GetBusesNeedingMigration(); |
|||
|
|||
/** |
|||
* Returns true if the graph makes use of any of the new bus features |
|||
* |
|||
* For quality control during rollout of new bus features: |
|||
* - Aliases |
|||
* - Bus groups |
|||
*/ |
|||
bool UsesNewBusFeatures() const; |
|||
|
|||
/** |
|||
* Runs electrical rule checks on the connectivity graph. |
|||
* |
|||
* Precondition: graph is up-to-date |
|||
* |
|||
* @param aSettings is used to control which tests to run |
|||
* @param aCreateMarkers controls whether error markers are created |
|||
* @return the number of errors found |
|||
*/ |
|||
int RunERC( const ERC_SETTINGS& aSettings, bool aCreateMarkers = true ); |
|||
|
|||
// TODO(JE) firm up API and move to private |
|||
std::map<int, std::vector<CONNECTION_SUBGRAPH*> > m_net_code_to_subgraphs_map; |
|||
|
|||
private: |
|||
|
|||
std::vector<SCH_ITEM*> m_items; |
|||
|
|||
std::vector<CONNECTION_SUBGRAPH*> m_subgraphs; |
|||
|
|||
std::vector<SCH_PIN_CONNECTION*> m_invisible_power_pins; |
|||
|
|||
std::map<wxString, std::shared_ptr<BUS_ALIAS>> m_bus_alias_cache; |
|||
|
|||
std::map<wxString, int> m_net_name_to_code_map; |
|||
|
|||
std::map<wxString, int> m_bus_name_to_code_map; |
|||
|
|||
std::unordered_map<int, CONNECTION_SUBGRAPH*> m_subgraph_code_map; |
|||
|
|||
int m_last_net_code; |
|||
|
|||
int m_last_bus_code; |
|||
|
|||
int m_last_subgraph_code; |
|||
|
|||
std::mutex m_item_mutex; |
|||
|
|||
// Needed for m_UserUnits for now; maybe refactor later |
|||
SCH_EDIT_FRAME* m_frame; |
|||
|
|||
/** |
|||
* Updates the graphical connectivity between items (i.e. where they touch) |
|||
* The items passed in must be on the same sheet. |
|||
* |
|||
* In the first phase, all items in aItemList have their connections |
|||
* initialized for the given sheet (since they may have connections on more |
|||
* than one sheet, and each needs to be calculated individually). The |
|||
* graphical connection points for the item are added to a map that stores |
|||
* (x, y) -> [list of items]. |
|||
* |
|||
* Any item that is stored in the list of items that have a connection point |
|||
* at a given (x, y) location will eventually be electrically connected. |
|||
* This means that we can't store SCH_COMPONENTs in this map -- we must store |
|||
* a structure that links a specific pin on a component back to that |
|||
* component: a SCH_PIN_CONNECTION. This wrapper class is a convenience for |
|||
* linking a pin and component to a specific (x, y) point. |
|||
* |
|||
* In the second phase, we iterate over each value in the map, which is a |
|||
* vector of items that have overlapping connection points. After some |
|||
* checks to ensure that the items should actually connect, the items are |
|||
* linked together using ConnectedItems(). |
|||
* |
|||
* As a side effect, items are loaded into m_items for BuildConnectionGraph() |
|||
* |
|||
* @param aSheet is the path to the sheet of all items in the list |
|||
* @param aItemList is a list of items to consider |
|||
*/ |
|||
void updateItemConnectivity( SCH_SHEET_PATH aSheet, |
|||
std::vector<SCH_ITEM*> aItemList ); |
|||
|
|||
/** |
|||
* Generates the connection graph (after all item connectivity has been updated) |
|||
* |
|||
* In the first phase, the algorithm iterates over all items, and then over |
|||
* all items that are connected (graphically) to each item, placing them into |
|||
* CONNECTION_SUBGRAPHs. Items that can potentially drive connectivity (i.e. |
|||
* labels, pins, etc.) are added to the m_drivers vector of the subgraph. |
|||
* |
|||
* In the second phase, each subgraph is resolved. To resolve a subgraph, |
|||
* the driver is first selected by CONNECTION_SUBGRAPH::ResolveDrivers(), |
|||
* and then the connection for the chosen driver is propagated to all the |
|||
* other items in the subgraph. |
|||
*/ |
|||
void buildConnectionGraph(); |
|||
|
|||
/** |
|||
* Helper to assign a new net code to a connection |
|||
* |
|||
* @return the assigned code |
|||
*/ |
|||
int assignNewNetCode( SCH_CONNECTION& aConnection ); |
|||
|
|||
/** |
|||
* Checks one subgraph for conflicting connections between net and bus labels |
|||
* |
|||
* For example, a net wire connected to a bus port/pin, or vice versa |
|||
* |
|||
* @param aSubgraph is the subgraph to examine |
|||
* @param aCreateMarkers controls whether error markers are created |
|||
* @return true for no errors, false for errors |
|||
*/ |
|||
bool ercCheckBusToNetConflicts( CONNECTION_SUBGRAPH* aSubgraph, |
|||
bool aCreateMarkers ); |
|||
|
|||
/** |
|||
* Checks one subgraph for conflicting connections between two bus items |
|||
* |
|||
* For example, a labeled bus wire connected to a hierarchical sheet pin |
|||
* where the labeled bus doesn't contain any of the same bus members as the |
|||
* sheet pin |
|||
* |
|||
* @param aSubgraph is the subgraph to examine |
|||
* @param aCreateMarkers controls whether error markers are created |
|||
* @return true for no errors, false for errors |
|||
*/ |
|||
bool ercCheckBusToBusConflicts( CONNECTION_SUBGRAPH* aSubgraph, |
|||
bool aCreateMarkers ); |
|||
|
|||
/** |
|||
* Checks one subgraph for conflicting bus entry to bus connections |
|||
* |
|||
* For example, a wire with label "A0" is connected to a bus labeled "D[8..0]" |
|||
* |
|||
* Will also check for mistakes related to bus group names, for example: |
|||
* A bus group named "USB{DP DM}" should have bus entry connections like |
|||
* "USB.DP" but someone might accidentally just enter "DP" |
|||
* |
|||
* @param aSubgraph is the subgraph to examine |
|||
* @param aCreateMarkers controls whether error markers are created |
|||
* @return true for no errors, false for errors |
|||
*/ |
|||
bool ercCheckBusToBusEntryConflicts( CONNECTION_SUBGRAPH* aSubgraph, |
|||
bool aCreateMarkers ); |
|||
|
|||
/** |
|||
* Checks one subgraph for proper presence or absence of no-connect symbols |
|||
* |
|||
* A pin with a no-connect symbol should not have any connections |
|||
* A pin without a no-connect symbol should have at least one connection |
|||
* |
|||
* @param aSubgraph is the subgraph to examine |
|||
* @param aCreateMarkers controls whether error markers are created |
|||
* @return true for no errors, false for errors |
|||
*/ |
|||
bool ercCheckNoConnects( CONNECTION_SUBGRAPH* aSubgraph, |
|||
bool aCreateMarkers ); |
|||
|
|||
/** |
|||
* Checks one subgraph for proper connection of labels |
|||
* |
|||
* Labels should be connected to something |
|||
* |
|||
* @param aSubgraph is the subgraph to examine |
|||
* @param aCreateMarkers controls whether error markers are created |
|||
* @return true for no errors, false for errors |
|||
*/ |
|||
bool ercCheckLabels( CONNECTION_SUBGRAPH* aSubgraph, bool aCreateMarkers ); |
|||
}; |
|||
|
|||
#endif |
@ -0,0 +1,517 @@ |
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2018 CERN |
|||
* @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 <wx/tokenzr.h>
|
|||
|
|||
#include <invoke_sch_dialog.h>
|
|||
#include <sch_sheet_path.h>
|
|||
|
|||
#include "dialog_bus_manager.h"
|
|||
|
|||
|
|||
BEGIN_EVENT_TABLE( DIALOG_BUS_MANAGER, DIALOG_SHIM ) |
|||
EVT_BUTTON( wxID_OK, DIALOG_BUS_MANAGER::OnOkClick ) |
|||
EVT_BUTTON( wxID_CANCEL, DIALOG_BUS_MANAGER::OnCancelClick ) |
|||
END_EVENT_TABLE() |
|||
|
|||
|
|||
DIALOG_BUS_MANAGER::DIALOG_BUS_MANAGER( SCH_EDIT_FRAME* aParent ) |
|||
: DIALOG_SHIM( aParent, wxID_ANY, _( "Bus Definitions" ), |
|||
wxDefaultPosition, wxSize( 640, 480 ), |
|||
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER ), |
|||
m_parent( aParent ) |
|||
{ |
|||
auto sizer = new wxBoxSizer( wxVERTICAL ); |
|||
auto buttons = new wxStdDialogButtonSizer(); |
|||
|
|||
buttons->AddButton( new wxButton( this, wxID_OK ) ); |
|||
buttons->AddButton( new wxButton( this, wxID_CANCEL ) ); |
|||
buttons->Realize(); |
|||
|
|||
auto top_container = new wxBoxSizer( wxHORIZONTAL ); |
|||
auto left_pane = new wxBoxSizer( wxVERTICAL ); |
|||
auto right_pane = new wxBoxSizer( wxVERTICAL ); |
|||
|
|||
// Left pane: alias list
|
|||
auto lbl_aliases = new wxStaticText( this, wxID_ANY, _( "Bus Aliases" ), |
|||
wxDefaultPosition, wxDefaultSize, |
|||
wxALIGN_LEFT ); |
|||
|
|||
m_bus_list_view = new wxListView( this, wxID_ANY, wxDefaultPosition, |
|||
wxSize( 300, 300 ), wxLC_ALIGN_LEFT | |
|||
wxLC_NO_HEADER | wxLC_REPORT | |
|||
wxLC_SINGLE_SEL ); |
|||
m_bus_list_view->InsertColumn( 0, "" ); |
|||
|
|||
auto lbl_alias_edit = new wxStaticText( this, wxID_ANY, _( "Alias Name" ), |
|||
wxDefaultPosition, wxDefaultSize, |
|||
wxALIGN_LEFT ); |
|||
|
|||
m_bus_edit = new wxTextCtrl( this, wxID_ANY, wxEmptyString, |
|||
wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER ); |
|||
|
|||
auto left_button_sizer = new wxBoxSizer( wxHORIZONTAL ); |
|||
|
|||
m_btn_add_bus = new wxButton( this, wxID_ANY, _( "Add" ) ); |
|||
m_btn_rename_bus = new wxButton( this, wxID_ANY, _( "Rename" ) ); |
|||
m_btn_remove_bus = new wxButton( this, wxID_ANY, _( "Remove" ) ); |
|||
|
|||
left_button_sizer->Add( m_btn_add_bus ); |
|||
left_button_sizer->Add( m_btn_rename_bus ); |
|||
left_button_sizer->Add( m_btn_remove_bus ); |
|||
|
|||
left_pane->Add( lbl_aliases, 0, wxEXPAND | wxALL, 5 ); |
|||
left_pane->Add( m_bus_list_view, 1, wxEXPAND | wxALL, 5 ); |
|||
left_pane->Add( lbl_alias_edit, 0, wxEXPAND | wxALL, 5 ); |
|||
left_pane->Add( m_bus_edit, 0, wxEXPAND | wxALL, 5 ); |
|||
left_pane->Add( left_button_sizer, 0, wxEXPAND | wxALL, 5 ); |
|||
|
|||
// Right pane: signal list
|
|||
auto lbl_signals = new wxStaticText( this, wxID_ANY, _( "Alias Members" ), |
|||
wxDefaultPosition, wxDefaultSize, |
|||
wxALIGN_LEFT ); |
|||
|
|||
m_signal_list_view = new wxListView( this, wxID_ANY, wxDefaultPosition, |
|||
wxSize( 300, 300 ), wxLC_ALIGN_LEFT | |
|||
wxLC_NO_HEADER | wxLC_REPORT | |
|||
wxLC_SINGLE_SEL ); |
|||
m_signal_list_view->InsertColumn( 0, "" ); |
|||
|
|||
auto lbl_signal_edit = new wxStaticText( this, wxID_ANY, _( "Member Name" ), |
|||
wxDefaultPosition, wxDefaultSize, |
|||
wxALIGN_LEFT ); |
|||
|
|||
m_signal_edit = new wxTextCtrl( this, wxID_ANY, wxEmptyString, |
|||
wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER ); |
|||
|
|||
auto right_button_sizer = new wxBoxSizer( wxHORIZONTAL ); |
|||
|
|||
m_btn_add_signal = new wxButton( this, wxID_ANY, _( "Add" ) ); |
|||
m_btn_rename_signal = new wxButton( this, wxID_ANY, _( "Rename" ) ); |
|||
m_btn_remove_signal = new wxButton( this, wxID_ANY, _( "Remove" ) ); |
|||
|
|||
right_button_sizer->Add( m_btn_add_signal ); |
|||
right_button_sizer->Add( m_btn_rename_signal ); |
|||
right_button_sizer->Add( m_btn_remove_signal ); |
|||
|
|||
right_pane->Add( lbl_signals, 0, wxEXPAND | wxALL, 5 ); |
|||
right_pane->Add( m_signal_list_view, 1, wxEXPAND | wxALL, 5 ); |
|||
right_pane->Add( lbl_signal_edit, 0, wxEXPAND | wxALL, 5 ); |
|||
right_pane->Add( m_signal_edit, 0, wxEXPAND | wxALL, 5 ); |
|||
right_pane->Add( right_button_sizer, 0, wxEXPAND | wxALL, 5 ); |
|||
|
|||
top_container->Add( left_pane, 1, wxEXPAND ); |
|||
top_container->Add( right_pane, 1, wxEXPAND ); |
|||
|
|||
sizer->Add( top_container, 1, wxEXPAND | wxALL, 5 ); |
|||
sizer->Add( buttons, 0, wxEXPAND | wxBOTTOM, 10 ); |
|||
SetSizer( sizer ); |
|||
|
|||
// Setup validators
|
|||
|
|||
wxTextValidator validator; |
|||
validator.SetStyle( wxFILTER_EXCLUDE_CHAR_LIST ); |
|||
validator.SetCharExcludes( "\r\n\t " ); |
|||
m_bus_edit->SetValidator( validator ); |
|||
|
|||
// Allow spaces in the signal edit, so that you can type in a list of
|
|||
// signals in the box and it can automatically split them when you add.
|
|||
validator.SetCharExcludes( "\r\n\t" ); |
|||
m_signal_edit->SetValidator( validator ); |
|||
|
|||
// Setup events
|
|||
|
|||
Bind( wxEVT_INIT_DIALOG, &DIALOG_BUS_MANAGER::OnInitDialog, this ); |
|||
m_bus_list_view->Connect( wxEVT_COMMAND_LIST_ITEM_DESELECTED, |
|||
wxListEventHandler( DIALOG_BUS_MANAGER::OnSelectBus ), NULL, this ); |
|||
m_bus_list_view->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, |
|||
wxListEventHandler( DIALOG_BUS_MANAGER::OnSelectBus ), NULL, this ); |
|||
m_signal_list_view->Connect( wxEVT_COMMAND_LIST_ITEM_DESELECTED, |
|||
wxListEventHandler( DIALOG_BUS_MANAGER::OnSelectSignal ), NULL, this ); |
|||
m_signal_list_view->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED, |
|||
wxListEventHandler( DIALOG_BUS_MANAGER::OnSelectSignal ), NULL, this ); |
|||
|
|||
m_btn_add_bus->Connect( wxEVT_COMMAND_BUTTON_CLICKED, |
|||
wxCommandEventHandler( DIALOG_BUS_MANAGER::OnAddBus ), NULL, this ); |
|||
m_btn_rename_bus->Connect( wxEVT_COMMAND_BUTTON_CLICKED, |
|||
wxCommandEventHandler( DIALOG_BUS_MANAGER::OnRenameBus ), NULL, this ); |
|||
m_btn_remove_bus->Connect( wxEVT_COMMAND_BUTTON_CLICKED, |
|||
wxCommandEventHandler( DIALOG_BUS_MANAGER::OnRemoveBus ), NULL, this ); |
|||
m_signal_edit->Connect( wxEVT_TEXT_ENTER, |
|||
wxCommandEventHandler( DIALOG_BUS_MANAGER::OnAddSignal ), NULL, this ); |
|||
|
|||
m_btn_add_signal->Connect( wxEVT_COMMAND_BUTTON_CLICKED, |
|||
wxCommandEventHandler( DIALOG_BUS_MANAGER::OnAddSignal ), NULL, this ); |
|||
m_btn_rename_signal->Connect( wxEVT_COMMAND_BUTTON_CLICKED, |
|||
wxCommandEventHandler( DIALOG_BUS_MANAGER::OnRenameSignal ), NULL, this ); |
|||
m_btn_remove_signal->Connect( wxEVT_COMMAND_BUTTON_CLICKED, |
|||
wxCommandEventHandler( DIALOG_BUS_MANAGER::OnRemoveSignal ), NULL, this ); |
|||
m_bus_edit->Connect( wxEVT_TEXT_ENTER, |
|||
wxCommandEventHandler( DIALOG_BUS_MANAGER::OnAddBus ), NULL, this ); |
|||
|
|||
// Set initial UI state
|
|||
|
|||
m_btn_rename_bus->Disable(); |
|||
m_btn_remove_bus->Disable(); |
|||
|
|||
m_btn_add_signal->Disable(); |
|||
m_btn_rename_signal->Disable(); |
|||
m_btn_remove_signal->Disable(); |
|||
|
|||
m_bus_edit->SetHint( _T( "Bus Alias Name" ) ); |
|||
m_signal_edit->SetHint( _T( "Net or Bus Name" ) ); |
|||
|
|||
FinishDialogSettings(); |
|||
} |
|||
|
|||
|
|||
void DIALOG_BUS_MANAGER::OnInitDialog( wxInitDialogEvent& aEvent ) |
|||
{ |
|||
TransferDataToWindow(); |
|||
} |
|||
|
|||
|
|||
bool DIALOG_BUS_MANAGER::TransferDataToWindow() |
|||
{ |
|||
m_aliases.clear(); |
|||
|
|||
SCH_SHEET_LIST aSheets( g_RootSheet ); |
|||
std::vector< std::shared_ptr< BUS_ALIAS > > original_aliases; |
|||
|
|||
// collect aliases from each open sheet
|
|||
for( unsigned i = 0; i < aSheets.size(); i++ ) |
|||
{ |
|||
auto sheet_aliases = aSheets[i].LastScreen()->GetBusAliases(); |
|||
original_aliases.insert( original_aliases.end(), sheet_aliases.begin(), |
|||
sheet_aliases.end() ); |
|||
} |
|||
|
|||
original_aliases.erase( std::unique( original_aliases.begin(), |
|||
original_aliases.end() ), |
|||
original_aliases.end() ); |
|||
|
|||
// clone into a temporary working set
|
|||
int idx = 0; |
|||
for( auto alias : original_aliases ) |
|||
{ |
|||
m_aliases.push_back( alias->Clone() ); |
|||
auto text = getAliasDisplayText( alias ); |
|||
m_bus_list_view->InsertItem( idx, text ); |
|||
m_bus_list_view->SetItemPtrData( idx, wxUIntPtr( m_aliases[idx].get() ) ); |
|||
idx++; |
|||
} |
|||
|
|||
m_bus_list_view->SetColumnWidth( 0, -1 ); |
|||
|
|||
return true; |
|||
} |
|||
|
|||
|
|||
void DIALOG_BUS_MANAGER::OnOkClick( wxCommandEvent& aEvent ) |
|||
{ |
|||
if( TransferDataFromWindow() ) |
|||
{ |
|||
( ( SCH_EDIT_FRAME* )GetParent() )->OnModify(); |
|||
EndModal( wxID_OK ); |
|||
} |
|||
} |
|||
|
|||
|
|||
void DIALOG_BUS_MANAGER::OnCancelClick( wxCommandEvent& aEvent ) |
|||
{ |
|||
EndModal( wxID_CANCEL ); |
|||
} |
|||
|
|||
|
|||
bool DIALOG_BUS_MANAGER::TransferDataFromWindow() |
|||
{ |
|||
// Since we have a clone of all the data, and it is from potentially
|
|||
// multiple screens, the way this works is to rebuild each screen's aliases.
|
|||
// A list of screens is stored here so that the screen's alias list is only
|
|||
// cleared once.
|
|||
|
|||
std::unordered_set< SCH_SCREEN* > cleared_list; |
|||
|
|||
for( auto alias : m_aliases ) |
|||
{ |
|||
auto screen = alias->GetParent(); |
|||
|
|||
if( cleared_list.count( screen ) == 0 ) |
|||
{ |
|||
screen->ClearBusAliases(); |
|||
cleared_list.insert( screen ); |
|||
} |
|||
|
|||
screen->AddBusAlias( alias ); |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
|
|||
|
|||
void DIALOG_BUS_MANAGER::OnSelectBus( wxListEvent& event ) |
|||
{ |
|||
if( event.GetEventType() == wxEVT_COMMAND_LIST_ITEM_SELECTED ) |
|||
{ |
|||
auto alias = m_aliases[ event.GetIndex() ]; |
|||
|
|||
if( m_active_alias != alias ) |
|||
{ |
|||
m_active_alias = alias; |
|||
|
|||
m_bus_edit->ChangeValue( alias->GetName() ); |
|||
|
|||
m_btn_add_bus->Disable(); |
|||
m_btn_rename_bus->Enable(); |
|||
m_btn_remove_bus->Enable(); |
|||
|
|||
auto members = alias->Members(); |
|||
|
|||
// TODO(JE) Clear() seems to be clearing the hint, contrary to
|
|||
// the wx documentation.
|
|||
m_signal_edit->Clear(); |
|||
m_signal_list_view->DeleteAllItems(); |
|||
|
|||
for( unsigned i = 0; i < members.size(); i++ ) |
|||
{ |
|||
m_signal_list_view->InsertItem( i, members[i] ); |
|||
} |
|||
|
|||
m_signal_list_view->SetColumnWidth( 0, -1 ); |
|||
|
|||
m_btn_add_signal->Enable(); |
|||
m_btn_rename_signal->Disable(); |
|||
m_btn_remove_signal->Disable(); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
m_active_alias = NULL; |
|||
m_bus_edit->Clear(); |
|||
m_signal_edit->Clear(); |
|||
m_signal_list_view->DeleteAllItems(); |
|||
|
|||
m_btn_add_bus->Enable(); |
|||
m_btn_rename_bus->Disable(); |
|||
m_btn_remove_bus->Disable(); |
|||
|
|||
m_btn_add_signal->Disable(); |
|||
m_btn_rename_signal->Disable(); |
|||
m_btn_remove_signal->Disable(); |
|||
} |
|||
} |
|||
|
|||
|
|||
void DIALOG_BUS_MANAGER::OnSelectSignal( wxListEvent& event ) |
|||
{ |
|||
if( event.GetEventType() == wxEVT_COMMAND_LIST_ITEM_SELECTED ) |
|||
{ |
|||
m_signal_edit->ChangeValue( event.GetText() ); |
|||
m_btn_rename_signal->Enable(); |
|||
m_btn_remove_signal->Enable(); |
|||
} |
|||
else |
|||
{ |
|||
m_signal_edit->Clear(); |
|||
m_btn_rename_signal->Disable(); |
|||
m_btn_remove_signal->Disable(); |
|||
} |
|||
} |
|||
|
|||
|
|||
void DIALOG_BUS_MANAGER::OnAddBus( wxCommandEvent& aEvent ) |
|||
{ |
|||
// If there is an active alias, then check that the user actually
|
|||
// changed the text in the edit box (we can't have duplicate aliases)
|
|||
|
|||
auto new_name = m_bus_edit->GetValue(); |
|||
|
|||
if( new_name.Length() == 0 ) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
for( auto alias : m_aliases ) |
|||
{ |
|||
if( alias->GetName() == new_name ) |
|||
{ |
|||
// TODO(JE) display error?
|
|||
return; |
|||
} |
|||
} |
|||
|
|||
if( !m_active_alias || |
|||
( m_active_alias && m_active_alias->GetName().Cmp( new_name ) ) ) |
|||
{ |
|||
// The values are different; create a new alias
|
|||
auto alias = std::make_shared<BUS_ALIAS>(); |
|||
alias->SetName( new_name ); |
|||
|
|||
// New aliases get stored on the currently visible sheet
|
|||
alias->SetParent( static_cast<SCH_EDIT_FRAME*>( GetParent() )->GetScreen() ); |
|||
auto text = getAliasDisplayText( alias ); |
|||
|
|||
m_aliases.push_back( alias ); |
|||
long idx = m_bus_list_view->InsertItem( m_aliases.size() - 1, text ); |
|||
m_bus_list_view->SetColumnWidth( 0, -1 ); |
|||
m_bus_list_view->Select( idx ); |
|||
m_bus_edit->Clear(); |
|||
} |
|||
else |
|||
{ |
|||
// TODO(JE) Check about desired result here.
|
|||
// Maybe warn the user? Or just do nothing
|
|||
} |
|||
} |
|||
|
|||
|
|||
void DIALOG_BUS_MANAGER::OnRenameBus( wxCommandEvent& aEvent ) |
|||
{ |
|||
// We should only get here if there is an active alias
|
|||
wxASSERT( m_active_alias ); |
|||
|
|||
m_active_alias->SetName( m_bus_edit->GetValue() ); |
|||
long idx = m_bus_list_view->FindItem( -1, wxUIntPtr( m_active_alias.get() ) ); |
|||
|
|||
wxASSERT( idx >= 0 ); |
|||
|
|||
m_bus_list_view->SetItemText( idx, getAliasDisplayText( m_active_alias ) ); |
|||
} |
|||
|
|||
|
|||
void DIALOG_BUS_MANAGER::OnRemoveBus( wxCommandEvent& aEvent ) |
|||
{ |
|||
// We should only get here if there is an active alias
|
|||
wxASSERT( m_active_alias ); |
|||
long i = m_bus_list_view->GetFirstSelected(); |
|||
wxASSERT( m_active_alias == m_aliases[ i ] ); |
|||
|
|||
m_bus_list_view->DeleteItem( i ); |
|||
m_aliases.erase( m_aliases.begin() + i ); |
|||
m_bus_edit->Clear(); |
|||
|
|||
m_active_alias = NULL; |
|||
|
|||
auto evt = wxListEvent( wxEVT_COMMAND_LIST_ITEM_DESELECTED ); |
|||
OnSelectBus( evt ); |
|||
} |
|||
|
|||
|
|||
void DIALOG_BUS_MANAGER::OnAddSignal( wxCommandEvent& aEvent ) |
|||
{ |
|||
auto name_list = m_signal_edit->GetValue(); |
|||
|
|||
if( !m_active_alias || name_list.Length() == 0 ) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
// String collecting net names that were not added to the bus
|
|||
wxString notAdded; |
|||
|
|||
// Parse a space-separated list and add each one
|
|||
wxStringTokenizer tok( name_list, " " ); |
|||
while( tok.HasMoreTokens() ) |
|||
{ |
|||
auto name = tok.GetNextToken(); |
|||
|
|||
if( !m_active_alias->Contains( name ) ) |
|||
{ |
|||
m_active_alias->AddMember( name ); |
|||
|
|||
long idx = m_signal_list_view->InsertItem( |
|||
m_active_alias->GetMemberCount() - 1, name ); |
|||
|
|||
m_signal_list_view->SetColumnWidth( 0, -1 ); |
|||
m_signal_list_view->Select( idx ); |
|||
} |
|||
else |
|||
{ |
|||
// Some of the requested net names were not added to the list, so keep them for editing
|
|||
notAdded = notAdded.IsEmpty() ? name : notAdded + " " + name; |
|||
} |
|||
} |
|||
|
|||
m_signal_edit->SetValue( notAdded ); |
|||
m_signal_edit->SetInsertionPointEnd(); |
|||
} |
|||
|
|||
|
|||
void DIALOG_BUS_MANAGER::OnRenameSignal( wxCommandEvent& aEvent ) |
|||
{ |
|||
// We should only get here if there is an active alias
|
|||
wxASSERT( m_active_alias ); |
|||
|
|||
auto new_name = m_signal_edit->GetValue(); |
|||
long idx = m_signal_list_view->GetFirstSelected(); |
|||
|
|||
wxASSERT( idx >= 0 ); |
|||
|
|||
auto old_name = m_active_alias->Members()[ idx ]; |
|||
|
|||
// User could have typed a space here, so check first
|
|||
if( new_name.Find( " " ) != wxNOT_FOUND ) |
|||
{ |
|||
// TODO(JE) error feedback
|
|||
m_signal_edit->ChangeValue( old_name ); |
|||
return; |
|||
} |
|||
|
|||
m_active_alias->Members()[ idx ] = new_name; |
|||
m_signal_list_view->SetItemText( idx, new_name ); |
|||
m_signal_list_view->SetColumnWidth( 0, -1 ); |
|||
} |
|||
|
|||
|
|||
void DIALOG_BUS_MANAGER::OnRemoveSignal( wxCommandEvent& aEvent ) |
|||
{ |
|||
// We should only get here if there is an active alias
|
|||
wxASSERT( m_active_alias ); |
|||
|
|||
long idx = m_signal_list_view->GetFirstSelected(); |
|||
|
|||
wxASSERT( idx >= 0 ); |
|||
|
|||
m_active_alias->Members().erase( m_active_alias->Members().begin() + idx ); |
|||
|
|||
m_signal_list_view->DeleteItem( idx ); |
|||
m_signal_edit->Clear(); |
|||
m_btn_rename_signal->Disable(); |
|||
m_btn_remove_signal->Disable(); |
|||
} |
|||
|
|||
|
|||
wxString DIALOG_BUS_MANAGER::getAliasDisplayText( std::shared_ptr< BUS_ALIAS > aAlias ) |
|||
{ |
|||
wxString name = aAlias->GetName(); |
|||
wxFileName sheet_name( aAlias->GetParent()->GetFileName() ); |
|||
|
|||
name += _T( " (" ) + sheet_name.GetFullName() + _T( ")" ); |
|||
|
|||
return name; |
|||
} |
|||
|
|||
|
|||
// see invoke_sch_dialog.h
|
|||
void InvokeDialogBusManager( SCH_EDIT_FRAME* aCaller ) |
|||
{ |
|||
DIALOG_BUS_MANAGER dlg( aCaller ); |
|||
dlg.ShowModal(); |
|||
} |
@ -0,0 +1,90 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2018 CERN |
|||
* @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 _DIALOG_BUS_MANAGER_H_ |
|||
#define _DIALOG_BUS_MANAGER_H_ |
|||
|
|||
#include "dialog_shim.h" |
|||
|
|||
#include <sch_edit_frame.h> |
|||
#include <wx/listctrl.h> |
|||
|
|||
#include <bus_alias.h> |
|||
|
|||
class DIALOG_BUS_MANAGER : public DIALOG_SHIM |
|||
{ |
|||
public: |
|||
DIALOG_BUS_MANAGER( SCH_EDIT_FRAME* aParent ); |
|||
|
|||
~DIALOG_BUS_MANAGER() {} |
|||
|
|||
bool TransferDataFromWindow() override; |
|||
|
|||
bool TransferDataToWindow() override; |
|||
|
|||
void OnAddBus( wxCommandEvent& aEvent ); |
|||
void OnRenameBus( wxCommandEvent& aEvent ); |
|||
void OnRemoveBus( wxCommandEvent& aEvent ); |
|||
|
|||
void OnAddSignal( wxCommandEvent& aEvent ); |
|||
void OnRenameSignal( wxCommandEvent& aEvent ); |
|||
void OnRemoveSignal( wxCommandEvent& aEvent ); |
|||
|
|||
protected: |
|||
|
|||
void OnInitDialog( wxInitDialogEvent& aEvent ); |
|||
|
|||
void OnSelectBus( wxListEvent& event ); |
|||
|
|||
void OnSelectSignal( wxListEvent& event ); |
|||
|
|||
SCH_EDIT_FRAME* m_parent; |
|||
|
|||
wxListView* m_bus_list_view; |
|||
wxListView* m_signal_list_view; |
|||
wxTextCtrl* m_bus_edit; |
|||
wxTextCtrl* m_signal_edit; |
|||
|
|||
wxButton* m_btn_add_bus; |
|||
wxButton* m_btn_rename_bus; |
|||
wxButton* m_btn_remove_bus; |
|||
|
|||
wxButton* m_btn_add_signal; |
|||
wxButton* m_btn_rename_signal; |
|||
wxButton* m_btn_remove_signal; |
|||
|
|||
private: |
|||
virtual void OnOkClick( wxCommandEvent& aEvent ); |
|||
|
|||
virtual void OnCancelClick( wxCommandEvent& aEvent ); |
|||
|
|||
wxString getAliasDisplayText( std::shared_ptr< BUS_ALIAS > aAlias ); |
|||
|
|||
std::vector< std::shared_ptr< BUS_ALIAS > > m_aliases; |
|||
|
|||
std::shared_ptr< BUS_ALIAS > m_active_alias; |
|||
|
|||
DECLARE_EVENT_TABLE() |
|||
}; |
|||
|
|||
|
|||
#endif |
|||
|
|||
// _DIALOG_BUS_MANAGER_H_ |
@ -0,0 +1,229 @@ |
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2018 CERN |
|||
* @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 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License along |
|||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
|
|||
#include <sch_connection.h>
|
|||
#include <connection_graph.h>
|
|||
|
|||
#include <dialog_migrate_buses.h>
|
|||
|
|||
/**
|
|||
* Migrates buses using legacy multi-label joining behavior. |
|||
* |
|||
* In KiCad verions before 6.0, you were allowed to place multiple labels |
|||
* on a given bus subgraph, and that would have the effect of making those |
|||
* bus descriptions equivalent according to the bus vector number. |
|||
* |
|||
* For example, if the labels PCA[0..15], ADR[0.7], and BUS[5..10] are all |
|||
* attached to the same subgraph, the intention is that there is connectivity |
|||
* between PCA0 and ADR0, between PCA10 and BUS10, and between PCA5, ADR5, |
|||
* and BUS5 (basically connect all the prefix names where the vector numbers |
|||
* line up). |
|||
* |
|||
* This is no longer allowed, because it doesn't map well onto the new |
|||
* bus groups feature and because it is confusing (the netlist will take on |
|||
* one of the possible names and it's impossible to control which one is |
|||
* used). |
|||
* |
|||
* This dialog identifies all of the subgraphs that have this behavior, |
|||
* and corrects them by determining a new name for the subgraph and removing |
|||
* all but one label. The name is determined by choosing a prefix and bus |
|||
* vector notation that can capture all the attached buses. In the above |
|||
* example, the result would need to have the vector notation [0..15] to |
|||
* capture all of the attached buses, and the name could be any of PCA, ADR, |
|||
* or BUS. We present a dialog to the user for them to select which name |
|||
* they want to use. |
|||
*/ |
|||
|
|||
|
|||
DIALOG_MIGRATE_BUSES::DIALOG_MIGRATE_BUSES( SCH_EDIT_FRAME* aParent ) : |
|||
DIALOG_MIGRATE_BUSES_BASE( aParent ), |
|||
m_frame( aParent ) |
|||
{ |
|||
m_migration_list->Bind( wxEVT_LIST_ITEM_SELECTED, |
|||
&DIALOG_MIGRATE_BUSES::onItemSelected, this ); |
|||
|
|||
m_btn_accept->Bind( wxEVT_COMMAND_BUTTON_CLICKED, |
|||
&DIALOG_MIGRATE_BUSES::onAcceptClicked, this ); |
|||
|
|||
loadGraphData(); |
|||
updateUi(); |
|||
|
|||
m_frame->Zoom_Automatique( false ); |
|||
} |
|||
|
|||
|
|||
void DIALOG_MIGRATE_BUSES::loadGraphData() |
|||
{ |
|||
m_items.clear(); |
|||
auto subgraphs = g_ConnectionGraph->GetBusesNeedingMigration(); |
|||
|
|||
for( auto subgraph : subgraphs ) |
|||
{ |
|||
BUS_MIGRATION_STATUS status; |
|||
|
|||
status.subgraph = subgraph; |
|||
status.approved = false; |
|||
|
|||
auto labels = subgraph->GetBusLabels(); |
|||
wxASSERT( labels.size() > 1 ); |
|||
|
|||
for( auto label : labels ) |
|||
status.labels.push_back( static_cast<SCH_TEXT*>( label )->GetText() ); |
|||
|
|||
status.possible_labels = getProposedLabels( status.labels ); |
|||
m_items.push_back( status ); |
|||
} |
|||
} |
|||
|
|||
|
|||
void DIALOG_MIGRATE_BUSES::updateUi() |
|||
{ |
|||
m_migration_list->DeleteAllItems(); |
|||
|
|||
m_migration_list->InsertColumn( 0, _( "Sheet" ) ); |
|||
m_migration_list->InsertColumn( 1, _( "Conflicting Labels" ) ); |
|||
m_migration_list->InsertColumn( 2, _( "New Label" ) ); |
|||
m_migration_list->InsertColumn( 3, _( "Status" ) ); |
|||
|
|||
for( auto item : m_items ) |
|||
{ |
|||
wxString old = item.labels[0]; |
|||
for( unsigned j = 1; j < item.labels.size(); j++ ) |
|||
old << ", " << item.labels[j]; |
|||
|
|||
auto i = m_migration_list->InsertItem( m_migration_list->GetItemCount(), |
|||
wxEmptyString ); |
|||
|
|||
m_migration_list->SetItem( i, 0, item.subgraph->m_sheet.PathHumanReadable() ); |
|||
m_migration_list->SetItem( i, 1, old ); |
|||
m_migration_list->SetItem( i, 2, item.possible_labels[0] ); |
|||
m_migration_list->SetItem( i, 3, "" ); |
|||
} |
|||
|
|||
m_migration_list->Select( 0 ); |
|||
m_migration_list->SetColumnWidth( 1, -1 ); |
|||
} |
|||
|
|||
|
|||
std::vector<wxString> DIALOG_MIGRATE_BUSES::getProposedLabels( std::vector<wxString> aLabelList ) |
|||
{ |
|||
int lowest_start = INT_MAX; |
|||
int highest_end = -1; |
|||
int widest_bus = -1; |
|||
|
|||
for( auto label : aLabelList ) |
|||
{ |
|||
SCH_CONNECTION conn; |
|||
conn.ConfigureFromLabel( label ); |
|||
|
|||
int start = conn.VectorStart(); |
|||
int end = conn.VectorEnd(); |
|||
|
|||
if( start < lowest_start ) |
|||
lowest_start = start; |
|||
|
|||
if( end > highest_end ) |
|||
highest_end = end; |
|||
|
|||
if( end - start + 1 > widest_bus ) |
|||
widest_bus = end - start + 1; |
|||
} |
|||
|
|||
SCH_CONNECTION conn; |
|||
std::vector<wxString> proposals; |
|||
|
|||
for( auto label : aLabelList ) |
|||
{ |
|||
conn.ConfigureFromLabel( label ); |
|||
wxString proposal = conn.VectorPrefix(); |
|||
proposal << "[" << highest_end << ".." << lowest_start << "]"; |
|||
proposals.push_back( proposal ); |
|||
} |
|||
|
|||
return proposals; |
|||
} |
|||
|
|||
|
|||
void DIALOG_MIGRATE_BUSES::onItemSelected( wxListEvent& aEvent ) |
|||
{ |
|||
unsigned sel = aEvent.GetIndex(); |
|||
wxASSERT( sel < m_items.size() ); |
|||
|
|||
m_selected_index = sel; |
|||
|
|||
auto subgraph = m_items[sel].subgraph; |
|||
|
|||
auto sheet = subgraph->m_sheet; |
|||
auto driver = subgraph->m_driver; |
|||
|
|||
if( sheet != *g_CurrentSheet ) |
|||
{ |
|||
sheet.LastScreen()->SetZoom( m_frame->GetScreen()->GetZoom() ); |
|||
*g_CurrentSheet = sheet; |
|||
g_CurrentSheet->UpdateAllScreenReferences(); |
|||
sheet.LastScreen()->TestDanglingEnds(); |
|||
} |
|||
|
|||
auto pos = driver->GetPosition(); |
|||
|
|||
m_frame->SetCrossHairPosition( pos ); |
|||
m_frame->RedrawScreen( pos, false ); |
|||
|
|||
m_cb_new_name->Clear(); |
|||
|
|||
for( auto option : m_items[sel].possible_labels ) |
|||
m_cb_new_name->Append( option ); |
|||
|
|||
m_cb_new_name->Select( 0 ); |
|||
} |
|||
|
|||
|
|||
void DIALOG_MIGRATE_BUSES::onAcceptClicked( wxCommandEvent& aEvent ) |
|||
{ |
|||
wxASSERT( m_selected_index < m_items.size() ); |
|||
|
|||
auto sel = m_selected_index; |
|||
|
|||
m_items[sel].approved_label = m_cb_new_name->GetStringSelection(); |
|||
m_items[sel].approved = true; |
|||
|
|||
auto sheet = m_items[sel].subgraph->m_sheet; |
|||
auto screen = sheet.LastScreen(); |
|||
|
|||
auto labels = m_items[sel].subgraph->GetBusLabels(); |
|||
|
|||
static_cast<SCH_TEXT*>( labels[0] )->SetText( m_items[sel].approved_label ); |
|||
|
|||
labels.erase( labels.begin() ); |
|||
|
|||
for( auto label : labels ) |
|||
{ |
|||
label->SetFlags( STRUCT_DELETED ); |
|||
screen->Remove( label ); |
|||
} |
|||
|
|||
m_migration_list->SetItem( sel, 2, m_items[sel].approved_label ); |
|||
m_migration_list->SetItem( sel, 3, _( "Updated" ) ); |
|||
|
|||
if( sel < m_items.size() - 1 ) |
|||
{ |
|||
m_migration_list->Select( sel + 1 ); |
|||
} |
|||
} |
@ -0,0 +1,71 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2018 CERN |
|||
* @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 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License along |
|||
* with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
#ifndef _DIALOG_MIGRATE_BUSES_H |
|||
#define _DIALOG_MIGRATE_BUSES_H |
|||
|
|||
#include <vector> |
|||
|
|||
#include <sch_edit_frame.h> |
|||
|
|||
#include <dialog_migrate_buses_base.h> |
|||
|
|||
class CONNECTION_SUBGRAPH; |
|||
|
|||
|
|||
struct BUS_MIGRATION_STATUS |
|||
{ |
|||
CONNECTION_SUBGRAPH* subgraph; |
|||
|
|||
std::vector<wxString> labels; |
|||
|
|||
std::vector<wxString> possible_labels; |
|||
|
|||
wxString approved_label; |
|||
|
|||
bool approved; |
|||
}; |
|||
|
|||
class DIALOG_MIGRATE_BUSES : public DIALOG_MIGRATE_BUSES_BASE |
|||
{ |
|||
public: |
|||
|
|||
DIALOG_MIGRATE_BUSES( SCH_EDIT_FRAME* aParent ); |
|||
|
|||
private: |
|||
|
|||
SCH_EDIT_FRAME* m_frame; |
|||
|
|||
unsigned m_selected_index; |
|||
|
|||
void loadGraphData(); |
|||
|
|||
void updateUi(); |
|||
|
|||
std::vector<wxString> getProposedLabels( std::vector<wxString> aLabelList ); |
|||
|
|||
void onItemSelected( wxListEvent& aEvent ); |
|||
|
|||
void onAcceptClicked( wxCommandEvent& aEvent ); |
|||
|
|||
std::vector<BUS_MIGRATION_STATUS> m_items; |
|||
}; |
|||
|
|||
#endif |
@ -0,0 +1,70 @@ |
|||
///////////////////////////////////////////////////////////////////////////
|
|||
// C++ code generated with wxFormBuilder (version Oct 17 2016)
|
|||
// http://www.wxformbuilder.org/
|
|||
//
|
|||
// PLEASE DO "NOT" EDIT THIS FILE!
|
|||
///////////////////////////////////////////////////////////////////////////
|
|||
|
|||
#include "dialog_migrate_buses_base.h"
|
|||
|
|||
///////////////////////////////////////////////////////////////////////////
|
|||
|
|||
DIALOG_MIGRATE_BUSES_BASE::DIALOG_MIGRATE_BUSES_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style ) |
|||
{ |
|||
this->SetSizeHints( wxDefaultSize, wxDefaultSize ); |
|||
|
|||
wxBoxSizer* main_sizer; |
|||
main_sizer = new wxBoxSizer( wxVERTICAL ); |
|||
|
|||
m_staticText5 = new wxStaticText( this, wxID_ANY, _("This schematic has one or more buses with more than one label. This was allowed in previous KiCad versions but is no longer permitted."), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_staticText5->Wrap( 480 ); |
|||
main_sizer->Add( m_staticText5, 0, wxALL|wxEXPAND, 5 ); |
|||
|
|||
m_staticText7 = new wxStaticText( this, wxID_ANY, _("Please select a new name for each of the buses below.\nA name has been suggested for you based on the labels attached to the bus."), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_staticText7->Wrap( 480 ); |
|||
m_staticText7->SetMinSize( wxSize( -1,60 ) ); |
|||
|
|||
main_sizer->Add( m_staticText7, 0, wxALL|wxEXPAND, 5 ); |
|||
|
|||
m_migration_list = new wxListView( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_HRULES|wxLC_REPORT|wxLC_SINGLE_SEL|wxLC_VRULES ); |
|||
m_migration_list->SetMinSize( wxSize( 460,100 ) ); |
|||
|
|||
main_sizer->Add( m_migration_list, 1, wxALL|wxEXPAND, 5 ); |
|||
|
|||
m_staticText6 = new wxStaticText( this, wxID_ANY, _("Proposed new name:"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
m_staticText6->Wrap( -1 ); |
|||
main_sizer->Add( m_staticText6, 0, wxALL, 5 ); |
|||
|
|||
wxBoxSizer* bSizer7; |
|||
bSizer7 = new wxBoxSizer( wxHORIZONTAL ); |
|||
|
|||
m_cb_new_name = new wxComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); |
|||
m_cb_new_name->SetMinSize( wxSize( 300,-1 ) ); |
|||
m_cb_new_name->SetMaxSize( wxSize( 460,-1 ) ); |
|||
|
|||
bSizer7->Add( m_cb_new_name, 1, wxALL|wxEXPAND, 5 ); |
|||
|
|||
m_btn_accept = new wxButton( this, wxID_ANY, _("Accept Name"), wxDefaultPosition, wxDefaultSize, 0 ); |
|||
bSizer7->Add( m_btn_accept, 0, wxALL, 5 ); |
|||
|
|||
|
|||
main_sizer->Add( bSizer7, 0, wxEXPAND, 5 ); |
|||
|
|||
m_sdbSizer1 = new wxStdDialogButtonSizer(); |
|||
m_sdbSizer1OK = new wxButton( this, wxID_OK ); |
|||
m_sdbSizer1->AddButton( m_sdbSizer1OK ); |
|||
m_sdbSizer1->Realize(); |
|||
|
|||
main_sizer->Add( m_sdbSizer1, 0, wxEXPAND, 5 ); |
|||
|
|||
|
|||
this->SetSizer( main_sizer ); |
|||
this->Layout(); |
|||
main_sizer->Fit( this ); |
|||
|
|||
this->Centre( wxBOTH ); |
|||
} |
|||
|
|||
DIALOG_MIGRATE_BUSES_BASE::~DIALOG_MIGRATE_BUSES_BASE() |
|||
{ |
|||
} |
@ -0,0 +1,669 @@ |
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> |
|||
<wxFormBuilder_Project> |
|||
<FileVersion major="1" minor="13" /> |
|||
<object class="Project" expanded="1"> |
|||
<property name="class_decoration"></property> |
|||
<property name="code_generation">C++</property> |
|||
<property name="disconnect_events">1</property> |
|||
<property name="disconnect_mode">source_name</property> |
|||
<property name="disconnect_php_events">0</property> |
|||
<property name="disconnect_python_events">0</property> |
|||
<property name="embedded_files_path">res</property> |
|||
<property name="encoding">UTF-8</property> |
|||
<property name="event_generation">connect</property> |
|||
<property name="file">dialog_migrate_buses_base</property> |
|||
<property name="first_id">1000</property> |
|||
<property name="help_provider">none</property> |
|||
<property name="internationalize">1</property> |
|||
<property name="name">DIALOG_MIGRATE_BUSES_BASE</property> |
|||
<property name="namespace"></property> |
|||
<property name="path">.</property> |
|||
<property name="precompiled_header"></property> |
|||
<property name="relative_path">1</property> |
|||
<property name="skip_lua_events">1</property> |
|||
<property name="skip_php_events">1</property> |
|||
<property name="skip_python_events">1</property> |
|||
<property name="ui_table">UI</property> |
|||
<property name="use_enum">0</property> |
|||
<property name="use_microsoft_bom">0</property> |
|||
<object class="Dialog" expanded="1"> |
|||
<property name="aui_managed">0</property> |
|||
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property> |
|||
<property name="bg"></property> |
|||
<property name="center">wxBOTH</property> |
|||
<property name="context_help"></property> |
|||
<property name="context_menu">1</property> |
|||
<property name="enabled">1</property> |
|||
<property name="event_handler">impl_virtual</property> |
|||
<property name="extra_style"></property> |
|||
<property name="fg"></property> |
|||
<property name="font"></property> |
|||
<property name="hidden">0</property> |
|||
<property name="id">wxID_ANY</property> |
|||
<property name="maximum_size"></property> |
|||
<property name="minimum_size"></property> |
|||
<property name="name">DIALOG_MIGRATE_BUSES_BASE</property> |
|||
<property name="pos"></property> |
|||
<property name="size"></property> |
|||
<property name="style">wxDEFAULT_DIALOG_STYLE</property> |
|||
<property name="subclass">DIALOG_SHIM; dialog_shim.h</property> |
|||
<property name="title">Migrate Buses</property> |
|||
<property name="tooltip"></property> |
|||
<property name="window_extra_style"></property> |
|||
<property name="window_name"></property> |
|||
<property name="window_style"></property> |
|||
<event name="OnActivate"></event> |
|||
<event name="OnActivateApp"></event> |
|||
<event name="OnAuiFindManager"></event> |
|||
<event name="OnAuiPaneButton"></event> |
|||
<event name="OnAuiPaneClose"></event> |
|||
<event name="OnAuiPaneMaximize"></event> |
|||
<event name="OnAuiPaneRestore"></event> |
|||
<event name="OnAuiRender"></event> |
|||
<event name="OnChar"></event> |
|||
<event name="OnClose"></event> |
|||
<event name="OnEnterWindow"></event> |
|||
<event name="OnEraseBackground"></event> |
|||
<event name="OnHibernate"></event> |
|||
<event name="OnIconize"></event> |
|||
<event name="OnIdle"></event> |
|||
<event name="OnInitDialog"></event> |
|||
<event name="OnKeyDown"></event> |
|||
<event name="OnKeyUp"></event> |
|||
<event name="OnKillFocus"></event> |
|||
<event name="OnLeaveWindow"></event> |
|||
<event name="OnLeftDClick"></event> |
|||
<event name="OnLeftDown"></event> |
|||
<event name="OnLeftUp"></event> |
|||
<event name="OnMiddleDClick"></event> |
|||
<event name="OnMiddleDown"></event> |
|||
<event name="OnMiddleUp"></event> |
|||
<event name="OnMotion"></event> |
|||
<event name="OnMouseEvents"></event> |
|||
<event name="OnMouseWheel"></event> |
|||
<event name="OnPaint"></event> |
|||
<event name="OnRightDClick"></event> |
|||
<event name="OnRightDown"></event> |
|||
<event name="OnRightUp"></event> |
|||
<event name="OnSetFocus"></event> |
|||
<event name="OnSize"></event> |
|||
<event name="OnUpdateUI"></event> |
|||
<object class="wxBoxSizer" expanded="1"> |
|||
<property name="minimum_size"></property> |
|||
<property name="name">main_sizer</property> |
|||
<property name="orient">wxVERTICAL</property> |
|||
<property name="permission">none</property> |
|||
<object class="sizeritem" expanded="1"> |
|||
<property name="border">5</property> |
|||
<property name="flag">wxALL|wxEXPAND</property> |
|||
<property name="proportion">0</property> |
|||
<object class="wxStaticText" 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="label">This schematic has one or more buses with more than one label. This was allowed in previous KiCad versions but is no longer permitted.</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_staticText5</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"></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> |
|||
<property name="wrap">480</property> |
|||
<event name="OnChar"></event> |
|||
<event name="OnEnterWindow"></event> |
|||
<event name="OnEraseBackground"></event> |
|||
<event name="OnKeyDown"></event> |
|||
<event name="OnKeyUp"></event> |
|||
<event name="OnKillFocus"></event> |
|||
<event name="OnLeaveWindow"></event> |
|||
<event name="OnLeftDClick"></event> |
|||
<event name="OnLeftDown"></event> |
|||
<event name="OnLeftUp"></event> |
|||
<event name="OnMiddleDClick"></event> |
|||
<event name="OnMiddleDown"></event> |
|||
<event name="OnMiddleUp"></event> |
|||
<event name="OnMotion"></event> |
|||
<event name="OnMouseEvents"></event> |
|||
<event name="OnMouseWheel"></event> |
|||
<event name="OnPaint"></event> |
|||
<event name="OnRightDClick"></event> |
|||
<event name="OnRightDown"></event> |
|||
<event name="OnRightUp"></event> |
|||
<event name="OnSetFocus"></event> |
|||
<event name="OnSize"></event> |
|||
<event name="OnUpdateUI"></event> |
|||
</object> |
|||
</object> |
|||
<object class="sizeritem" expanded="1"> |
|||
<property name="border">5</property> |
|||
<property name="flag">wxALL|wxEXPAND</property> |
|||
<property name="proportion">0</property> |
|||
<object class="wxStaticText" 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="label">Please select a new name for each of the buses below.
A name has been suggested for you based on the labels attached to the bus.</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">-1,60</property> |
|||
<property name="moveable">1</property> |
|||
<property name="name">m_staticText7</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"></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> |
|||
<property name="wrap">480</property> |
|||
<event name="OnChar"></event> |
|||
<event name="OnEnterWindow"></event> |
|||
<event name="OnEraseBackground"></event> |
|||
<event name="OnKeyDown"></event> |
|||
<event name="OnKeyUp"></event> |
|||
<event name="OnKillFocus"></event> |
|||
<event name="OnLeaveWindow"></event> |
|||
<event name="OnLeftDClick"></event> |
|||
<event name="OnLeftDown"></event> |
|||
<event name="OnLeftUp"></event> |
|||
<event name="OnMiddleDClick"></event> |
|||
<event name="OnMiddleDown"></event> |
|||
<event name="OnMiddleUp"></event> |
|||
<event name="OnMotion"></event> |
|||
<event name="OnMouseEvents"></event> |
|||
<event name="OnMouseWheel"></event> |
|||
<event name="OnPaint"></event> |
|||
<event name="OnRightDClick"></event> |
|||
<event name="OnRightDown"></event> |
|||
<event name="OnRightUp"></event> |
|||
<event name="OnSetFocus"></event> |
|||
<event name="OnSize"></event> |
|||
<event name="OnUpdateUI"></event> |
|||
</object> |
|||
</object> |
|||
<object class="sizeritem" expanded="1"> |
|||
<property name="border">5</property> |
|||
<property name="flag">wxALL|wxEXPAND</property> |
|||
<property name="proportion">1</property> |
|||
<object class="wxListCtrl" 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">460,100</property> |
|||
<property name="moveable">1</property> |
|||
<property name="name">m_migration_list</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">wxLC_HRULES|wxLC_REPORT|wxLC_SINGLE_SEL|wxLC_VRULES</property> |
|||
<property name="subclass">wxListView; </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="OnChar"></event> |
|||
<event name="OnEnterWindow"></event> |
|||
<event name="OnEraseBackground"></event> |
|||
<event name="OnKeyDown"></event> |
|||
<event name="OnKeyUp"></event> |
|||
<event name="OnKillFocus"></event> |
|||
<event name="OnLeaveWindow"></event> |
|||
<event name="OnLeftDClick"></event> |
|||
<event name="OnLeftDown"></event> |
|||
<event name="OnLeftUp"></event> |
|||
<event name="OnListBeginDrag"></event> |
|||
<event name="OnListBeginLabelEdit"></event> |
|||
<event name="OnListBeginRDrag"></event> |
|||
<event name="OnListCacheHint"></event> |
|||
<event name="OnListColBeginDrag"></event> |
|||
<event name="OnListColClick"></event> |
|||
<event name="OnListColDragging"></event> |
|||
<event name="OnListColEndDrag"></event> |
|||
<event name="OnListColRightClick"></event> |
|||
<event name="OnListDeleteAllItems"></event> |
|||
<event name="OnListDeleteItem"></event> |
|||
<event name="OnListEndLabelEdit"></event> |
|||
<event name="OnListInsertItem"></event> |
|||
<event name="OnListItemActivated"></event> |
|||
<event name="OnListItemDeselected"></event> |
|||
<event name="OnListItemFocused"></event> |
|||
<event name="OnListItemMiddleClick"></event> |
|||
<event name="OnListItemRightClick"></event> |
|||
<event name="OnListItemSelected"></event> |
|||
<event name="OnListKeyDown"></event> |
|||
<event name="OnMiddleDClick"></event> |
|||
<event name="OnMiddleDown"></event> |
|||
<event name="OnMiddleUp"></event> |
|||
<event name="OnMotion"></event> |
|||
<event name="OnMouseEvents"></event> |
|||
<event name="OnMouseWheel"></event> |
|||
<event name="OnPaint"></event> |
|||
<event name="OnRightDClick"></event> |
|||
<event name="OnRightDown"></event> |
|||
<event name="OnRightUp"></event> |
|||
<event name="OnSetFocus"></event> |
|||
<event name="OnSize"></event> |
|||
<event name="OnUpdateUI"></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="wxStaticText" 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="label">Proposed new name:</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_staticText6</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"></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> |
|||
<property name="wrap">-1</property> |
|||
<event name="OnChar"></event> |
|||
<event name="OnEnterWindow"></event> |
|||
<event name="OnEraseBackground"></event> |
|||
<event name="OnKeyDown"></event> |
|||
<event name="OnKeyUp"></event> |
|||
<event name="OnKillFocus"></event> |
|||
<event name="OnLeaveWindow"></event> |
|||
<event name="OnLeftDClick"></event> |
|||
<event name="OnLeftDown"></event> |
|||
<event name="OnLeftUp"></event> |
|||
<event name="OnMiddleDClick"></event> |
|||
<event name="OnMiddleDown"></event> |
|||
<event name="OnMiddleUp"></event> |
|||
<event name="OnMotion"></event> |
|||
<event name="OnMouseEvents"></event> |
|||
<event name="OnMouseWheel"></event> |
|||
<event name="OnPaint"></event> |
|||
<event name="OnRightDClick"></event> |
|||
<event name="OnRightDown"></event> |
|||
<event name="OnRightUp"></event> |
|||
<event name="OnSetFocus"></event> |
|||
<event name="OnSize"></event> |
|||
<event name="OnUpdateUI"></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="wxBoxSizer" expanded="1"> |
|||
<property name="minimum_size"></property> |
|||
<property name="name">bSizer7</property> |
|||
<property name="orient">wxHORIZONTAL</property> |
|||
<property name="permission">none</property> |
|||
<object class="sizeritem" expanded="1"> |
|||
<property name="border">5</property> |
|||
<property name="flag">wxALL|wxEXPAND</property> |
|||
<property name="proportion">1</property> |
|||
<object class="wxComboBox" 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="choices"></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">460,-1</property> |
|||
<property name="min_size"></property> |
|||
<property name="minimize_button">0</property> |
|||
<property name="minimum_size">300,-1</property> |
|||
<property name="moveable">1</property> |
|||
<property name="name">m_cb_new_name</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="selection">-1</property> |
|||
<property name="show">1</property> |
|||
<property name="size"></property> |
|||
<property name="style"></property> |
|||
<property name="subclass"></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="value"></property> |
|||
<property name="window_extra_style"></property> |
|||
<property name="window_name"></property> |
|||
<property name="window_style"></property> |
|||
<event name="OnChar"></event> |
|||
<event name="OnCombobox"></event> |
|||
<event name="OnEnterWindow"></event> |
|||
<event name="OnEraseBackground"></event> |
|||
<event name="OnKeyDown"></event> |
|||
<event name="OnKeyUp"></event> |
|||
<event name="OnKillFocus"></event> |
|||
<event name="OnLeaveWindow"></event> |
|||
<event name="OnLeftDClick"></event> |
|||
<event name="OnLeftDown"></event> |
|||
<event name="OnLeftUp"></event> |
|||
<event name="OnMiddleDClick"></event> |
|||
<event name="OnMiddleDown"></event> |
|||
<event name="OnMiddleUp"></event> |
|||
<event name="OnMotion"></event> |
|||
<event name="OnMouseEvents"></event> |
|||
<event name="OnMouseWheel"></event> |
|||
<event name="OnPaint"></event> |
|||
<event name="OnRightDClick"></event> |
|||
<event name="OnRightDown"></event> |
|||
<event name="OnRightUp"></event> |
|||
<event name="OnSetFocus"></event> |
|||
<event name="OnSize"></event> |
|||
<event name="OnText"></event> |
|||
<event name="OnTextEnter"></event> |
|||
<event name="OnUpdateUI"></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="wxButton" 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">0</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">Accept Name</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_btn_accept</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"></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"></event> |
|||
<event name="OnChar"></event> |
|||
<event name="OnEnterWindow"></event> |
|||
<event name="OnEraseBackground"></event> |
|||
<event name="OnKeyDown"></event> |
|||
<event name="OnKeyUp"></event> |
|||
<event name="OnKillFocus"></event> |
|||
<event name="OnLeaveWindow"></event> |
|||
<event name="OnLeftDClick"></event> |
|||
<event name="OnLeftDown"></event> |
|||
<event name="OnLeftUp"></event> |
|||
<event name="OnMiddleDClick"></event> |
|||
<event name="OnMiddleDown"></event> |
|||
<event name="OnMiddleUp"></event> |
|||
<event name="OnMotion"></event> |
|||
<event name="OnMouseEvents"></event> |
|||
<event name="OnMouseWheel"></event> |
|||
<event name="OnPaint"></event> |
|||
<event name="OnRightDClick"></event> |
|||
<event name="OnRightDown"></event> |
|||
<event name="OnRightUp"></event> |
|||
<event name="OnSetFocus"></event> |
|||
<event name="OnSize"></event> |
|||
<event name="OnUpdateUI"></event> |
|||
</object> |
|||
</object> |
|||
</object> |
|||
</object> |
|||
<object class="sizeritem" expanded="1"> |
|||
<property name="border">5</property> |
|||
<property name="flag">wxEXPAND</property> |
|||
<property name="proportion">0</property> |
|||
<object class="wxStdDialogButtonSizer" expanded="1"> |
|||
<property name="Apply">0</property> |
|||
<property name="Cancel">0</property> |
|||
<property name="ContextHelp">0</property> |
|||
<property name="Help">0</property> |
|||
<property name="No">0</property> |
|||
<property name="OK">1</property> |
|||
<property name="Save">0</property> |
|||
<property name="Yes">0</property> |
|||
<property name="minimum_size"></property> |
|||
<property name="name">m_sdbSizer1</property> |
|||
<property name="permission">protected</property> |
|||
<event name="OnApplyButtonClick"></event> |
|||
<event name="OnCancelButtonClick"></event> |
|||
<event name="OnContextHelpButtonClick"></event> |
|||
<event name="OnHelpButtonClick"></event> |
|||
<event name="OnNoButtonClick"></event> |
|||
<event name="OnOKButtonClick"></event> |
|||
<event name="OnSaveButtonClick"></event> |
|||
<event name="OnYesButtonClick"></event> |
|||
</object> |
|||
</object> |
|||
</object> |
|||
</object> |
|||
</object> |
|||
</wxFormBuilder_Project> |
@ -0,0 +1,57 @@ |
|||
/////////////////////////////////////////////////////////////////////////// |
|||
// C++ code generated with wxFormBuilder (version Oct 17 2016) |
|||
// http://www.wxformbuilder.org/ |
|||
// |
|||
// PLEASE DO "NOT" EDIT THIS FILE! |
|||
/////////////////////////////////////////////////////////////////////////// |
|||
|
|||
#ifndef __DIALOG_MIGRATE_BUSES_BASE_H__ |
|||
#define __DIALOG_MIGRATE_BUSES_BASE_H__ |
|||
|
|||
#include <wx/artprov.h> |
|||
#include <wx/xrc/xmlres.h> |
|||
#include <wx/intl.h> |
|||
class DIALOG_SHIM; |
|||
class wxListView; |
|||
|
|||
#include "dialog_shim.h" |
|||
#include <wx/string.h> |
|||
#include <wx/stattext.h> |
|||
#include <wx/gdicmn.h> |
|||
#include <wx/font.h> |
|||
#include <wx/colour.h> |
|||
#include <wx/settings.h> |
|||
#include <wx/listctrl.h> |
|||
#include <wx/combobox.h> |
|||
#include <wx/button.h> |
|||
#include <wx/sizer.h> |
|||
#include <wx/dialog.h> |
|||
|
|||
/////////////////////////////////////////////////////////////////////////// |
|||
|
|||
|
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
/// Class DIALOG_MIGRATE_BUSES_BASE |
|||
/////////////////////////////////////////////////////////////////////////////// |
|||
class DIALOG_MIGRATE_BUSES_BASE : public DIALOG_SHIM |
|||
{ |
|||
private: |
|||
|
|||
protected: |
|||
wxStaticText* m_staticText5; |
|||
wxStaticText* m_staticText7; |
|||
wxListView* m_migration_list; |
|||
wxStaticText* m_staticText6; |
|||
wxComboBox* m_cb_new_name; |
|||
wxButton* m_btn_accept; |
|||
wxStdDialogButtonSizer* m_sdbSizer1; |
|||
wxButton* m_sdbSizer1OK; |
|||
|
|||
public: |
|||
|
|||
DIALOG_MIGRATE_BUSES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Migrate Buses"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE ); |
|||
~DIALOG_MIGRATE_BUSES_BASE(); |
|||
|
|||
}; |
|||
|
|||
#endif //__DIALOG_MIGRATE_BUSES_BASE_H__ |
@ -0,0 +1,82 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2018 CERN |
|||
* @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 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License along |
|||
* with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
#ifndef _ERC_SETTINGS_H |
|||
#define _ERC_SETTINGS_H |
|||
|
|||
/** |
|||
* Container for ERC settings |
|||
* |
|||
* Currently only stores flags about checks to run, but could later be expanded |
|||
* to contain the matrix of electrical pin types. |
|||
*/ |
|||
class ERC_SETTINGS |
|||
{ |
|||
public: |
|||
void LoadDefaults() |
|||
{ |
|||
write_erc_file = false; |
|||
check_similar_labels = true; |
|||
check_unique_global_labels = true; |
|||
check_bus_driver_conflicts = true; |
|||
check_bus_entry_conflicts = true; |
|||
check_bus_to_bus_conflicts = true; |
|||
check_bus_to_net_conflicts = true; |
|||
} |
|||
|
|||
bool operator==( const ERC_SETTINGS& other ) const |
|||
{ |
|||
return ( other.write_erc_file == write_erc_file && |
|||
other.check_similar_labels == check_similar_labels && |
|||
other.check_unique_global_labels == check_unique_global_labels && |
|||
other.check_bus_driver_conflicts == check_bus_driver_conflicts && |
|||
other.check_bus_entry_conflicts == check_bus_entry_conflicts && |
|||
other.check_bus_to_bus_conflicts == check_bus_to_bus_conflicts && |
|||
other.check_bus_to_net_conflicts == check_bus_to_net_conflicts ); |
|||
} |
|||
|
|||
bool operator!=( const ERC_SETTINGS& other ) const |
|||
{ |
|||
return !( other == *this ); |
|||
} |
|||
|
|||
/// If true, write ERC results to a file |
|||
bool write_erc_file; |
|||
|
|||
/// If true, check each sheet for labels that differ only by letter case |
|||
bool check_similar_labels; |
|||
|
|||
/// If true, check to ensure that each global label apperas more than once |
|||
bool check_unique_global_labels; |
|||
|
|||
/// If true, check that buses don't have conflicting drivers |
|||
bool check_bus_driver_conflicts; |
|||
|
|||
/// If true, check that wires connecting to buses actually exist in the bus |
|||
bool check_bus_entry_conflicts; |
|||
|
|||
/// If true, check that bus-to-bus connections share at least one member |
|||
bool check_bus_to_bus_conflicts; |
|||
|
|||
/// If true, check that bus wires don't graphically connect to net objects (or vice versa) |
|||
bool check_bus_to_net_conflicts; |
|||
}; |
|||
|
|||
#endif |
@ -0,0 +1,469 @@ |
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2018 CERN |
|||
* @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 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License along |
|||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
|
|||
#include <boost/regex.hpp>
|
|||
#include <wx/tokenzr.h>
|
|||
|
|||
#include <connection_graph.h>
|
|||
#include <sch_pin_connection.h>
|
|||
#include <sch_screen.h>
|
|||
|
|||
#include <sch_connection.h>
|
|||
|
|||
|
|||
/**
|
|||
* |
|||
* Buses can be defined in multiple ways. A bus vector consists of a prefix and |
|||
* a numeric range of suffixes: |
|||
* |
|||
* BUS_NAME[M..N] |
|||
* |
|||
* For example, the bus A[3..0] will contain nets A3, A2, A1, and A0. |
|||
* The BUS_NAME is required. M and N must be integers but do not need to be in |
|||
* any particular order -- A[0..3] produces the same result. |
|||
* |
|||
* Like net names, bus names cannot contain whitespace. |
|||
* |
|||
* A bus group is just a grouping of signals, separated by spaces, some |
|||
* of which may be bus vectors. Bus groups can have names, but do not need to. |
|||
* |
|||
* MEMORY{A[15..0] D[7..0] RW CE OE} |
|||
* |
|||
* In named bus groups, the net names are expanded as <BUS_NAME>.<NET_NAME> |
|||
* In the above example, the nets would be named like MEMORY.A15, MEMORY.D0, etc. |
|||
* |
|||
* {USB_DP USB_DN} |
|||
* |
|||
* In the above example, the bus is unnamed and so the underlying net names are |
|||
* just USB_DP and USB_DN. |
|||
* |
|||
*/ |
|||
static boost::regex bus_label_re( "^([^[:space:]]+)(\\[[\\d]+\\.+[\\d]+\\])$" ); |
|||
|
|||
static boost::regex bus_group_label_re( "^([^[:space:]]+)?\\{((?:[^[:space:]]+(?:\\[[\\d]+\\.+[\\d]+\\])? ?)+)\\}$" ); |
|||
|
|||
|
|||
SCH_CONNECTION::SCH_CONNECTION( SCH_ITEM* aParent, SCH_SHEET_PATH aPath ) : |
|||
m_sheet( aPath ), |
|||
m_parent( aParent ) |
|||
{ |
|||
Reset(); |
|||
} |
|||
|
|||
|
|||
bool SCH_CONNECTION::operator==( const SCH_CONNECTION& aOther ) const |
|||
{ |
|||
// NOTE: Not comparing m_dirty or net/bus/subgraph codes
|
|||
if( ( aOther.m_driver == m_driver ) && |
|||
( aOther.m_type == m_type ) && |
|||
( aOther.m_name == m_name ) && |
|||
( aOther.m_sheet == m_sheet ) ) |
|||
{ |
|||
return true; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
|
|||
void SCH_CONNECTION::SetDriver( SCH_ITEM* aItem ) |
|||
{ |
|||
m_driver = aItem; |
|||
|
|||
for( auto member : m_members ) |
|||
member->SetDriver( aItem ); |
|||
} |
|||
|
|||
|
|||
void SCH_CONNECTION::SetSheet( SCH_SHEET_PATH aSheet ) |
|||
{ |
|||
m_sheet = aSheet; |
|||
|
|||
for( auto member : m_members ) |
|||
member->SetSheet( aSheet ); |
|||
} |
|||
|
|||
|
|||
bool SCH_CONNECTION::operator!=( const SCH_CONNECTION& aOther ) const |
|||
{ |
|||
return !( aOther == *this ); |
|||
} |
|||
|
|||
|
|||
void SCH_CONNECTION::ConfigureFromLabel( wxString aLabel ) |
|||
{ |
|||
if( IsBusVectorLabel( aLabel ) ) |
|||
{ |
|||
m_name = aLabel; |
|||
m_type = CONNECTION_BUS; |
|||
|
|||
ParseBusVector( aLabel, &m_vector_prefix, &m_vector_start, &m_vector_end ); |
|||
|
|||
for( long i = m_vector_start; i <= m_vector_end; ++i ) |
|||
{ |
|||
auto member = std::make_shared< SCH_CONNECTION >( m_parent, m_sheet ); |
|||
wxString name = m_vector_prefix; |
|||
name << i; |
|||
member->m_type = CONNECTION_NET; |
|||
member->m_name = m_prefix + name; |
|||
member->m_vector_index = i; |
|||
m_members.push_back( member ); |
|||
} |
|||
} |
|||
else if( IsBusGroupLabel( aLabel ) ) |
|||
{ |
|||
m_type = CONNECTION_BUS_GROUP; |
|||
m_name = aLabel; |
|||
|
|||
std::vector<wxString> members; |
|||
wxString group_name; |
|||
|
|||
if( ParseBusGroup( aLabel, &group_name, members ) ) |
|||
{ |
|||
// Named bus groups generate a net prefix, unnamed ones don't
|
|||
auto prefix = ( group_name != "" ) ? ( group_name + "." ) : ""; |
|||
|
|||
for( auto group_member : members ) |
|||
{ |
|||
// Handle alias inside bus group member list
|
|||
if( auto alias = g_ConnectionGraph->GetBusAlias( group_member ) ) |
|||
{ |
|||
for( auto alias_member : alias->Members() ) |
|||
{ |
|||
auto member = std::make_shared< SCH_CONNECTION >( m_parent, m_sheet ); |
|||
member->SetPrefix( prefix ); |
|||
member->ConfigureFromLabel( alias_member ); |
|||
m_members.push_back( member ); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
auto member = std::make_shared< SCH_CONNECTION >( m_parent, m_sheet ); |
|||
member->SetPrefix( prefix ); |
|||
member->ConfigureFromLabel( group_member ); |
|||
m_members.push_back( member ); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
else if( auto alias = g_ConnectionGraph->GetBusAlias( aLabel ) ) |
|||
{ |
|||
m_type = CONNECTION_BUS_GROUP; |
|||
m_name = aLabel; |
|||
|
|||
for( auto alias_member : alias->Members() ) |
|||
{ |
|||
auto member = std::make_shared< SCH_CONNECTION >( m_parent ); |
|||
member->ConfigureFromLabel( alias_member ); |
|||
m_members.push_back( member ); |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
m_name = m_prefix + aLabel; |
|||
m_type = CONNECTION_NET; |
|||
} |
|||
} |
|||
|
|||
|
|||
void SCH_CONNECTION::Reset() |
|||
{ |
|||
m_type = CONNECTION_NONE; |
|||
m_name = "<NO NET>"; |
|||
m_prefix = ""; |
|||
m_driver = nullptr; |
|||
m_members.clear(); |
|||
m_dirty = true; |
|||
m_net_code = 0; |
|||
m_bus_code = 0; |
|||
m_subgraph_code = 0; |
|||
m_vector_start = 0; |
|||
m_vector_end = 0; |
|||
m_vector_index = 0; |
|||
m_vector_prefix = ""; |
|||
} |
|||
|
|||
|
|||
void SCH_CONNECTION::Clone( SCH_CONNECTION& aOther ) |
|||
{ |
|||
m_type = aOther.Type(); |
|||
m_driver = aOther.Driver(); |
|||
m_sheet = aOther.Sheet(); |
|||
m_name = aOther.Name( true ); |
|||
m_prefix = aOther.Prefix(); |
|||
m_members = aOther.Members(); |
|||
m_net_code = aOther.NetCode(); |
|||
m_bus_code = aOther.BusCode(); |
|||
//m_subgraph_code = aOther.SubgraphCode();
|
|||
m_vector_start = aOther.VectorStart(); |
|||
m_vector_end = aOther.VectorEnd(); |
|||
m_vector_index = aOther.VectorIndex(); |
|||
m_vector_prefix = aOther.VectorPrefix(); |
|||
} |
|||
|
|||
|
|||
bool SCH_CONNECTION::IsDriver() const |
|||
{ |
|||
wxASSERT( Parent() ); |
|||
|
|||
switch( Parent()->Type() ) |
|||
{ |
|||
case SCH_LABEL_T: |
|||
case SCH_GLOBAL_LABEL_T: |
|||
case SCH_HIERARCHICAL_LABEL_T: |
|||
case SCH_PIN_CONNECTION_T: |
|||
case SCH_SHEET_PIN_T: |
|||
case SCH_SHEET_T: |
|||
case LIB_PIN_T: |
|||
return true; |
|||
|
|||
default: |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
|
|||
wxString SCH_CONNECTION::Name( bool aIgnoreSheet ) const |
|||
{ |
|||
wxString ret = m_name; |
|||
|
|||
if( !Parent() || m_type == CONNECTION_NONE ) |
|||
return ret; |
|||
|
|||
bool prepend_path = true; |
|||
|
|||
switch( Parent()->Type() ) |
|||
{ |
|||
case SCH_PIN_CONNECTION_T: |
|||
// Pins are either power connections or belong to a uniquely-annotated
|
|||
// component, so they don't need a path
|
|||
prepend_path = false; |
|||
break; |
|||
|
|||
case SCH_GLOBAL_LABEL_T: |
|||
prepend_path = false; |
|||
break; |
|||
|
|||
default: |
|||
break; |
|||
} |
|||
|
|||
if( prepend_path && !aIgnoreSheet ) |
|||
ret = m_sheet.PathHumanReadable() + ret; |
|||
|
|||
return ret; |
|||
} |
|||
|
|||
|
|||
void SCH_CONNECTION::AppendInfoToMsgPanel( MSG_PANEL_ITEMS& aList ) const |
|||
{ |
|||
wxString msg, group_name; |
|||
std::vector<wxString> group_members; |
|||
|
|||
aList.push_back( MSG_PANEL_ITEM( _( "Connection Name" ), m_name, BROWN ) ); |
|||
|
|||
msg.Printf( "%d", m_net_code ); |
|||
aList.push_back( MSG_PANEL_ITEM( _( "Net Code" ), msg, BROWN ) ); |
|||
|
|||
if( auto alias = g_ConnectionGraph->GetBusAlias( m_name ) ) |
|||
{ |
|||
msg.Printf( _( "Bus Alias %s Members" ), m_name ); |
|||
|
|||
wxString members; |
|||
|
|||
for( auto member : alias->Members() ) |
|||
members << member << " "; |
|||
|
|||
aList.push_back( MSG_PANEL_ITEM( msg, members, RED ) ); |
|||
} |
|||
else if( ParseBusGroup( m_name, &group_name, group_members ) ) |
|||
{ |
|||
for( auto group_member : group_members ) |
|||
{ |
|||
if( auto group_alias = g_ConnectionGraph->GetBusAlias( group_member ) ) |
|||
{ |
|||
msg.Printf( _( "Bus Alias %s Members" ), group_alias->GetName() ); |
|||
|
|||
wxString members; |
|||
|
|||
for( auto member : group_alias->Members() ) |
|||
members << member << " "; |
|||
|
|||
aList.push_back( MSG_PANEL_ITEM( msg, members, RED ) ); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
void SCH_CONNECTION::AppendDebugInfoToMsgPanel( MSG_PANEL_ITEMS& aList ) const |
|||
{ |
|||
wxString msg; |
|||
|
|||
AppendInfoToMsgPanel( aList ); |
|||
|
|||
msg.Printf( "%d", m_bus_code ); |
|||
aList.push_back( MSG_PANEL_ITEM( _( "Bus Code" ), msg, BROWN ) ); |
|||
|
|||
msg.Printf( "%d", m_subgraph_code ); |
|||
aList.push_back( MSG_PANEL_ITEM( _( "Subgraph Code" ), msg, BROWN ) ); |
|||
|
|||
if( auto driver = Driver() ) |
|||
{ |
|||
msg.Printf( "%s at %p", driver->GetSelectMenuText( MILLIMETRES ), driver ); |
|||
aList.push_back( MSG_PANEL_ITEM( _( "Connection Source" ), msg, RED ) ); |
|||
} |
|||
|
|||
msg.Printf( "%s at %p", Parent()->GetSelectMenuText( MILLIMETRES ), Parent() ); |
|||
aList.push_back( MSG_PANEL_ITEM( _( "Attached To" ), msg, RED ) ); |
|||
} |
|||
|
|||
|
|||
bool SCH_CONNECTION::IsBusLabel( const wxString& aLabel ) |
|||
{ |
|||
return IsBusVectorLabel( aLabel ) || IsBusGroupLabel( aLabel ); |
|||
} |
|||
|
|||
|
|||
bool SCH_CONNECTION::IsBusVectorLabel( const wxString& aLabel ) |
|||
{ |
|||
return boost::regex_match( std::string( aLabel.mb_str() ), bus_label_re ); |
|||
} |
|||
|
|||
|
|||
bool SCH_CONNECTION::IsBusGroupLabel( const wxString& aLabel ) |
|||
{ |
|||
return boost::regex_match( std::string( aLabel.mb_str() ), bus_group_label_re ); |
|||
} |
|||
|
|||
|
|||
void SCH_CONNECTION::ParseBusVector( wxString aVector, wxString* aName, |
|||
long* begin, long* end ) const |
|||
{ |
|||
auto ss_vector = std::string( aVector.mb_str() ); |
|||
boost::smatch matches; |
|||
|
|||
if( !boost::regex_match( ss_vector, matches, bus_label_re ) ) |
|||
{ |
|||
wxFAIL_MSG( wxT( "<" ) + aVector + wxT( "> is not a valid bus vector." ) ); |
|||
return; |
|||
} |
|||
|
|||
*aName = wxString( matches[1] ); |
|||
wxString numberString( matches[2] ); |
|||
|
|||
// numberString will include the brackets, e.g. [5..0] so skip the first one
|
|||
size_t i = 1, len = numberString.Len(); |
|||
wxString tmp; |
|||
|
|||
while( i < len && numberString[i] != '.' ) |
|||
{ |
|||
tmp.Append( numberString[i] ); |
|||
i++; |
|||
} |
|||
|
|||
tmp.ToLong( begin ); |
|||
|
|||
while( i < len && numberString[i] == '.' ) |
|||
i++; |
|||
|
|||
tmp.Empty(); |
|||
|
|||
while( i < len && numberString[i] != ']' ) |
|||
{ |
|||
tmp.Append( numberString[i] ); |
|||
i++; |
|||
} |
|||
|
|||
tmp.ToLong( end ); |
|||
|
|||
if( *begin < 0 ) |
|||
*begin = 0; |
|||
|
|||
if( *end < 0 ) |
|||
*end = 0; |
|||
|
|||
if( *begin > *end ) |
|||
std::swap( *begin, *end ); |
|||
} |
|||
|
|||
|
|||
bool SCH_CONNECTION::ParseBusGroup( wxString aGroup, wxString* aName, |
|||
std::vector<wxString>& aMemberList ) const |
|||
{ |
|||
auto ss_group = std::string( aGroup.mb_str() ); |
|||
boost::smatch matches; |
|||
|
|||
if( !boost::regex_match( ss_group, matches, bus_group_label_re ) ) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
*aName = wxString( matches[1] ); |
|||
|
|||
wxStringTokenizer tokenizer( wxString( matches[2] ), " " ); |
|||
while( tokenizer.HasMoreTokens() ) |
|||
{ |
|||
aMemberList.push_back( tokenizer.GetNextToken() ); |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
|
|||
|
|||
bool SCH_CONNECTION::IsSubsetOf( SCH_CONNECTION* aOther ) const |
|||
{ |
|||
if( aOther->IsNet() ) |
|||
return IsNet() ? ( aOther->Name( true ) == Name( true ) ) : false; |
|||
|
|||
if( !IsBus() ) |
|||
return false; |
|||
|
|||
std::vector<wxString> mine, theirs; |
|||
|
|||
for( auto m : Members() ) |
|||
mine.push_back( m->Name( true ) ); |
|||
|
|||
for( auto m : aOther->Members() ) |
|||
theirs.push_back( m->Name( true ) ); |
|||
|
|||
std::set<wxString> subset; |
|||
|
|||
std::set_intersection( mine.begin(), mine.end(), |
|||
theirs.begin(), theirs.end(), |
|||
std::inserter(subset, subset.begin() ) ); |
|||
|
|||
return ( !subset.empty() ); |
|||
} |
|||
|
|||
|
|||
bool SCH_CONNECTION::IsMemberOfBus( SCH_CONNECTION* aOther ) const |
|||
{ |
|||
if( !aOther->IsBus() ) |
|||
return false; |
|||
|
|||
auto me = Name( true ); |
|||
|
|||
for( auto m : aOther->Members() ) |
|||
if( m->Name( true ) == me ) |
|||
return true; |
|||
|
|||
return false; |
|||
} |
@ -0,0 +1,347 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2018 CERN |
|||
* @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 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License along |
|||
* with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
#ifndef _SCH_CONNECTION_H |
|||
#define _SCH_CONNECTION_H |
|||
|
|||
#include <memory> |
|||
#include <unordered_set> |
|||
|
|||
#include <boost/optional.hpp> |
|||
#include <wx/regex.h> |
|||
|
|||
#include <bus_alias.h> |
|||
#include <msgpanel.h> |
|||
#include <sch_sheet_path.h> |
|||
|
|||
|
|||
class SCH_ITEM; |
|||
class SCH_SHEET_PATH; |
|||
|
|||
|
|||
enum CONNECTION_TYPE |
|||
{ |
|||
CONNECTION_NONE, ///< No connection to this item |
|||
CONNECTION_NET, ///< This item represents a net |
|||
CONNECTION_BUS, ///< This item represents a bus vector |
|||
CONNECTION_BUS_GROUP, ///< This item represents a bus group |
|||
}; |
|||
|
|||
/** |
|||
* Each graphical item can have a SCH_CONNECTION describing its logical |
|||
* connection (to a bus or net). These are generated when netlisting, or when |
|||
* editing operations that can change the netlist are performed. |
|||
* |
|||
* In hierarchical schematics, a single SCH_ITEM object can refer to multiple |
|||
* distinct parts of a design (in the case of a sub-sheet that is instanced |
|||
* more than once in a higher level sheet). Because of this, a single item may |
|||
* contain more than one SCH_CONNECTION -- each is specific to a sheet. |
|||
* |
|||
* Components contain connections for each of their pins (and for each sheet |
|||
* they exist on) but don't use their own connection object. |
|||
*/ |
|||
class SCH_CONNECTION |
|||
{ |
|||
public: |
|||
SCH_CONNECTION( SCH_ITEM* aParent = nullptr, SCH_SHEET_PATH aPath = SCH_SHEET_PATH() ); |
|||
|
|||
~SCH_CONNECTION() |
|||
{} |
|||
|
|||
/** |
|||
* Note: the equality operator for SCH_CONNECTION only tests the net |
|||
* properties, not the ownership / sheet location! |
|||
*/ |
|||
bool operator==( const SCH_CONNECTION& aOther ) const; |
|||
|
|||
bool operator!=( const SCH_CONNECTION& aOther ) const; |
|||
|
|||
/** |
|||
* Configures the connection given a label. |
|||
* For CONNECTION_NET, this just sets the name. |
|||
* For CONNECTION_BUS, this will deduce the correct BUS_TYPE and also |
|||
* generate a correct list of members. |
|||
*/ |
|||
void ConfigureFromLabel( wxString aLabel ); |
|||
|
|||
/** |
|||
* Clears connectivity information |
|||
*/ |
|||
void Reset(); |
|||
|
|||
/** |
|||
* Copies connectivity information (but not parent) from another connection |
|||
* |
|||
* @param aOther is the connection to clone |
|||
*/ |
|||
void Clone( SCH_CONNECTION& aOther ); |
|||
|
|||
SCH_ITEM* Parent() const |
|||
{ |
|||
return m_parent; |
|||
} |
|||
|
|||
SCH_ITEM* Driver() const |
|||
{ |
|||
return m_driver; |
|||
} |
|||
|
|||
SCH_SHEET_PATH Sheet() const |
|||
{ |
|||
return m_sheet; |
|||
} |
|||
|
|||
void SetDriver( SCH_ITEM* aItem ); |
|||
|
|||
void SetSheet( SCH_SHEET_PATH aSheet ); |
|||
|
|||
/** |
|||
* Checks if the SCH_ITEM this connection is attached to can drive connections |
|||
* Drivers can be labels, sheet pins, or component pins. |
|||
* |
|||
* @return true if the attached items is a driver |
|||
*/ |
|||
bool IsDriver() const; |
|||
|
|||
bool IsBus() const |
|||
{ |
|||
return ( m_type == CONNECTION_BUS || m_type == CONNECTION_BUS_GROUP ); |
|||
} |
|||
|
|||
bool IsNet() const |
|||
{ |
|||
return ( m_type == CONNECTION_NET ); |
|||
} |
|||
|
|||
bool IsDirty() const |
|||
{ |
|||
return m_dirty; |
|||
} |
|||
|
|||
void SetDirty() |
|||
{ |
|||
m_dirty = true; |
|||
} |
|||
|
|||
void ClearDirty() |
|||
{ |
|||
m_dirty = false; |
|||
} |
|||
|
|||
wxString Name( bool aIgnoreSheet = false ) const; |
|||
|
|||
wxString Prefix() const |
|||
{ |
|||
return m_prefix; |
|||
} |
|||
|
|||
void SetPrefix( wxString aPrefix ) |
|||
{ |
|||
m_prefix = aPrefix; |
|||
} |
|||
|
|||
CONNECTION_TYPE Type() const |
|||
{ |
|||
return m_type; |
|||
} |
|||
|
|||
void SetType( CONNECTION_TYPE aType ) |
|||
{ |
|||
m_type = aType; |
|||
} |
|||
|
|||
int NetCode() const |
|||
{ |
|||
return m_net_code; |
|||
} |
|||
|
|||
void SetNetCode( int aCode ) |
|||
{ |
|||
m_net_code = aCode; |
|||
} |
|||
|
|||
int BusCode() const |
|||
{ |
|||
return m_bus_code; |
|||
} |
|||
|
|||
void SetBusCode( int aCode ) |
|||
{ |
|||
m_bus_code = aCode; |
|||
} |
|||
|
|||
int SubgraphCode() const |
|||
{ |
|||
return m_subgraph_code; |
|||
} |
|||
|
|||
void SetSubgraphCode( int aCode ) |
|||
{ |
|||
m_subgraph_code = aCode; |
|||
} |
|||
|
|||
long VectorStart() const |
|||
{ |
|||
return m_vector_start; |
|||
} |
|||
|
|||
long VectorEnd() const |
|||
{ |
|||
return m_vector_end; |
|||
} |
|||
|
|||
long VectorIndex() const |
|||
{ |
|||
return m_vector_index; |
|||
} |
|||
|
|||
wxString VectorPrefix() const |
|||
{ |
|||
return m_vector_prefix; |
|||
} |
|||
|
|||
std::vector< std::shared_ptr< SCH_CONNECTION > >& Members() |
|||
{ |
|||
return m_members; |
|||
} |
|||
|
|||
const std::vector< std::shared_ptr< SCH_CONNECTION > >& Members() const |
|||
{ |
|||
return m_members; |
|||
} |
|||
|
|||
/** |
|||
* Returns true if aOther is a subset of this connection or vice versa. |
|||
* |
|||
* For plain nets, this just tests whether or not the connectio names are |
|||
* the same. For buses, this tests whether the two have any shared members. |
|||
* |
|||
* Will always return false if one connection is a bus and the other a net. |
|||
*/ |
|||
bool IsSubsetOf( SCH_CONNECTION* aOther ) const; |
|||
|
|||
/** |
|||
* Returns true if this connection is a member of bus connection aOther |
|||
* |
|||
* Will always return false if aOther is not a bus connection |
|||
*/ |
|||
bool IsMemberOfBus( SCH_CONNECTION* aOther ) const; |
|||
|
|||
/** |
|||
* Parses a bus vector (e.g. A[7..0]) into name, begin, and end. |
|||
* Ensures that begin and end are positive and that end > begin. |
|||
* |
|||
* @param vector is a bus vector label string |
|||
* @param name output of the name portion of the label |
|||
* @param begin is the first entry in the vector |
|||
* @param end is the last entry in the vector |
|||
*/ |
|||
void ParseBusVector( wxString vector, wxString* name, |
|||
long* begin, long* end ) const; |
|||
|
|||
/** |
|||
* Parses a bus group label into the name and a list of components |
|||
* |
|||
* @param aGroup is the input label, e.g. "USB{DP DM}" |
|||
* @param name is the output group name, e.g. "USB" |
|||
* @param aMemberList is a list of member strings, e.g. "DP", "DM" |
|||
* @return true if aGroup was successfully parsed |
|||
*/ |
|||
bool ParseBusGroup( wxString aGroup, wxString* name, |
|||
std::vector<wxString>& aMemberList ) const; |
|||
|
|||
/** |
|||
* Adds information about the connection object to aList |
|||
*/ |
|||
void AppendInfoToMsgPanel( MSG_PANEL_ITEMS& aList ) const; |
|||
|
|||
/** |
|||
* Adds extended debug information about the connection object to aList |
|||
*/ |
|||
void AppendDebugInfoToMsgPanel( MSG_PANEL_ITEMS& aList ) const; |
|||
|
|||
/** |
|||
* Test if \a aLabel has a bus notation. |
|||
* |
|||
* @param aLabel A wxString object containing the label to test. |
|||
* @return true if text is a bus notation format otherwise false is returned. |
|||
*/ |
|||
bool IsBusLabel( const wxString& aLabel ); |
|||
|
|||
/** |
|||
* Test if \a aLabel has a bus vector notation (simple bus, e.g. A[7..0]) |
|||
* |
|||
* @param aLabel A wxString object containing the label to test. |
|||
* @return true if text is a bus notation format otherwise false is returned. |
|||
*/ |
|||
bool IsBusVectorLabel( const wxString& aLabel ); |
|||
|
|||
/** |
|||
* Test if \a aLabel has a bus group notation. |
|||
* |
|||
* @param aLabel A wxString object containing the label to test. |
|||
* @return true if text is a bus group notation format |
|||
*/ |
|||
bool IsBusGroupLabel( const wxString& aLabel ); |
|||
|
|||
private: |
|||
|
|||
bool m_dirty; |
|||
|
|||
SCH_SHEET_PATH m_sheet; ///< The hierarchical sheet this connection is on |
|||
|
|||
SCH_ITEM* m_parent; ///< The SCH_ITEM this connection is owned by |
|||
|
|||
SCH_ITEM* m_driver; ///< The SCH_ITEM that drives this connection's net |
|||
|
|||
CONNECTION_TYPE m_type; ///< @see enum CONNECTION_TYPE |
|||
|
|||
wxString m_name; ///< Name of the bus. |
|||
|
|||
///< Prefix if connection is member of a labeled bus group (or "" if not) |
|||
wxString m_prefix; |
|||
|
|||
int m_net_code; // TODO(JE) remove if unused |
|||
|
|||
int m_bus_code; // TODO(JE) remove if unused |
|||
|
|||
int m_subgraph_code; ///< Groups directly-connected items |
|||
|
|||
long m_vector_index; ///< Index of bus vector member nets |
|||
|
|||
long m_vector_start; ///< Highest member of a vector bus |
|||
|
|||
long m_vector_end; ///< Lowest member of a vector bus |
|||
|
|||
///< Prefix name of the vector, if m_type == CONNECTION_BUS (or "" if not) |
|||
wxString m_vector_prefix; |
|||
|
|||
/** |
|||
* For bus connections, store a list of member connections |
|||
* |
|||
* NOTE: All connections that Clone() others share the list of member |
|||
* pointers. This seems fine at the moment. |
|||
*/ |
|||
std::vector< std::shared_ptr< SCH_CONNECTION > > m_members; |
|||
|
|||
}; |
|||
|
|||
#endif |
|||
|
@ -0,0 +1,87 @@ |
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2018 CERN |
|||
* @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 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License along |
|||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
|
|||
#include <lib_pin.h>
|
|||
#include <sch_component.h>
|
|||
#include <sch_pin_connection.h>
|
|||
#include <sch_sheet_path.h>
|
|||
|
|||
|
|||
SCH_PIN_CONNECTION::SCH_PIN_CONNECTION( EDA_ITEM* aParent ) : |
|||
SCH_ITEM( aParent, SCH_PIN_CONNECTION_T ) |
|||
{ |
|||
} |
|||
|
|||
|
|||
wxString SCH_PIN_CONNECTION::GetSelectMenuText( EDA_UNITS_T aUnits ) const |
|||
{ |
|||
wxString tmp; |
|||
|
|||
#ifdef DEBUG
|
|||
tmp.Printf( _( "SCH_PIN_CONNECTION for %s %s" ), |
|||
GetChars( m_comp->GetSelectMenuText( aUnits ) ), |
|||
GetChars( m_pin->GetSelectMenuText( aUnits ) ) ); |
|||
#else
|
|||
tmp.Printf( _( "%s %s" ), |
|||
GetChars( m_comp->GetSelectMenuText( aUnits ) ), |
|||
GetChars( m_pin->GetSelectMenuText( aUnits ) ) ); |
|||
#endif
|
|||
|
|||
return tmp; |
|||
} |
|||
|
|||
|
|||
wxString SCH_PIN_CONNECTION::GetDefaultNetName( const SCH_SHEET_PATH aPath ) |
|||
{ |
|||
if( m_pin->IsPowerConnection() ) |
|||
return m_pin->GetName(); |
|||
|
|||
wxString name; |
|||
|
|||
try |
|||
{ |
|||
name = m_net_name_map.at( aPath ); |
|||
} |
|||
catch( const std::out_of_range& oor ) |
|||
{ |
|||
name = wxT( "Net-(" ); |
|||
|
|||
name << m_comp->GetRef( &aPath ); |
|||
|
|||
// TODO(JE) do we need adoptTimestamp?
|
|||
if( /* adoptTimestamp && */ name.Last() == '?' ) |
|||
name << m_comp->GetTimeStamp(); |
|||
|
|||
name << _( "-Pad" ) << m_pin->GetNumber() << _( ")" ); |
|||
|
|||
m_net_name_map[ aPath ] = name; |
|||
} |
|||
|
|||
return name; |
|||
} |
|||
|
|||
|
|||
wxPoint SCH_PIN_CONNECTION::GetPosition() const |
|||
{ |
|||
auto pos = m_comp->GetPosition(); |
|||
auto transform = m_comp->GetTransform(); |
|||
|
|||
return pos + transform.TransformCoordinate( m_pin->GetPosition() ); |
|||
} |
@ -0,0 +1,77 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2018 CERN |
|||
* @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 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License along |
|||
* with this program. If not, see <http://www.gnu.org/licenses/>. |
|||
*/ |
|||
|
|||
#ifndef _SCH_PIN_CONNECTION_H |
|||
#define _SCH_PIN_CONNECTION_H |
|||
|
|||
#include <sch_item_struct.h> |
|||
#include <sch_connection.h> |
|||
#include <sch_sheet_path.h> |
|||
#include <lib_pin.h> |
|||
|
|||
class SCH_COMPONENT; |
|||
|
|||
/** |
|||
* Container to describe the net connectivity of a specific pin on a component. |
|||
*/ |
|||
class SCH_PIN_CONNECTION : public SCH_ITEM |
|||
{ |
|||
public: |
|||
SCH_PIN_CONNECTION( EDA_ITEM* aParent = nullptr ); |
|||
|
|||
wxString GetClass() const override |
|||
{ |
|||
return wxT( "SCH_PIN_CONNECTION" ); |
|||
} |
|||
|
|||
wxString GetDefaultNetName( const SCH_SHEET_PATH aPath ); |
|||
|
|||
wxString GetSelectMenuText( EDA_UNITS_T aUnits ) const override; |
|||
|
|||
void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset, |
|||
GR_DRAWMODE aDrawMode, COLOR4D aColor = COLOR4D::UNSPECIFIED ) override |
|||
{ |
|||
} |
|||
|
|||
void Move( const wxPoint& aMoveVector ) override {} |
|||
|
|||
void MirrorY( int aYaxis_position ) override {} |
|||
|
|||
void MirrorX( int aXaxis_position ) override {} |
|||
|
|||
void Rotate( wxPoint aPosition ) override {} |
|||
|
|||
wxPoint GetPosition() const override; |
|||
|
|||
void SetPosition( const wxPoint& aPosition ) override {} |
|||
|
|||
#if defined(DEBUG) |
|||
void Show( int nestLevel, std::ostream& os ) const override {} |
|||
#endif |
|||
|
|||
LIB_PIN* m_pin; |
|||
|
|||
SCH_COMPONENT* m_comp; |
|||
|
|||
/// The name that this pin connection will drive onto a net |
|||
std::map<const SCH_SHEET_PATH, wxString> m_net_name_map; |
|||
}; |
|||
|
|||
#endif |
Write
Preview
Loading…
Cancel
Save
Reference in new issue