mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-14 10:13:19 +02:00
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 changes
This commit is contained in:
parent
8985badc64
commit
83c7e7fc65
@ -585,7 +585,7 @@ find_package( Pixman 0.30 REQUIRED )
|
|||||||
|
|
||||||
#
|
#
|
||||||
# Find Boost headers, required.
|
# Find Boost headers, required.
|
||||||
find_package( Boost 1.54.0 REQUIRED )
|
find_package( Boost 1.54.0 REQUIRED COMPONENTS regex )
|
||||||
|
|
||||||
# Include MinGW resource compiler.
|
# Include MinGW resource compiler.
|
||||||
include( MinGWResourceCompiler )
|
include( MinGWResourceCompiler )
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
|
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
|
||||||
* Copyright (C) 2004-2013 KiCad Developers, see change_log.txt for contributors.
|
* Copyright (C) 2004-2013 KiCad Developers, see change_log.txt for contributors.
|
||||||
|
* Copyright (C) 2018 CERN
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@ -28,6 +29,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <kicad_string.h>
|
#include <kicad_string.h>
|
||||||
|
#include <confirm.h>
|
||||||
#include <validators.h>
|
#include <validators.h>
|
||||||
|
|
||||||
#include <wx/grid.h>
|
#include <wx/grid.h>
|
||||||
@ -220,6 +222,57 @@ void ENV_VAR_NAME_VALIDATOR::OnTextChanged( wxCommandEvent& event )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool REGEX_VALIDATOR::Validate( wxWindow* aParent )
|
||||||
|
{
|
||||||
|
// If window is disabled, simply return
|
||||||
|
if( !m_validatorWindow->IsEnabled() )
|
||||||
|
return true;
|
||||||
|
|
||||||
|
wxTextEntry* const textEntry = GetTextEntry();
|
||||||
|
|
||||||
|
if( !textEntry )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool valid = true;
|
||||||
|
const wxString& value = textEntry->GetValue();
|
||||||
|
|
||||||
|
if( m_regEx.Matches( value ) )
|
||||||
|
{
|
||||||
|
size_t start, len;
|
||||||
|
m_regEx.GetMatch( &start, &len );
|
||||||
|
|
||||||
|
if( start != 0 || len != value.Length() ) // whole string must match
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
else // no match at all
|
||||||
|
{
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !valid )
|
||||||
|
{
|
||||||
|
m_validatorWindow->SetFocus();
|
||||||
|
DisplayError( aParent, wxString::Format( _( "Incorrect value: %s" ), value ) );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void REGEX_VALIDATOR::compileRegEx( const wxString& aRegEx, int aFlags )
|
||||||
|
{
|
||||||
|
if( !m_regEx.Compile( aRegEx, aFlags ) )
|
||||||
|
{
|
||||||
|
throw std::runtime_error( "REGEX_VALIDATOR: Invalid regular expression: "
|
||||||
|
+ aRegEx.ToStdString() );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_regExString = aRegEx;
|
||||||
|
m_regExFlags = aFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void KIUI::ValidatorTransferToWindowWithoutEvents( wxValidator& aValidator )
|
void KIUI::ValidatorTransferToWindowWithoutEvents( wxValidator& aValidator )
|
||||||
{
|
{
|
||||||
wxWindow* ctrl = aValidator.GetWindow();
|
wxWindow* ctrl = aValidator.GetWindow();
|
||||||
|
@ -37,6 +37,7 @@ set( EESCHEMA_DLGS
|
|||||||
dialogs/dialog_bom.cpp
|
dialogs/dialog_bom.cpp
|
||||||
dialogs/dialog_bom_base.cpp
|
dialogs/dialog_bom_base.cpp
|
||||||
dialogs/dialog_bom_cfg_keywords.cpp
|
dialogs/dialog_bom_cfg_keywords.cpp
|
||||||
|
dialogs/dialog_bus_manager.cpp
|
||||||
dialogs/dialog_fields_editor_global.cpp
|
dialogs/dialog_fields_editor_global.cpp
|
||||||
dialogs/dialog_fields_editor_global_base.cpp
|
dialogs/dialog_fields_editor_global_base.cpp
|
||||||
dialogs/dialog_choose_component.cpp
|
dialogs/dialog_choose_component.cpp
|
||||||
@ -64,6 +65,8 @@ set( EESCHEMA_DLGS
|
|||||||
dialogs/dialog_lib_edit_text_base.cpp
|
dialogs/dialog_lib_edit_text_base.cpp
|
||||||
dialogs/dialog_lib_new_component.cpp
|
dialogs/dialog_lib_new_component.cpp
|
||||||
dialogs/dialog_lib_new_component_base.cpp
|
dialogs/dialog_lib_new_component_base.cpp
|
||||||
|
dialogs/dialog_migrate_buses.cpp
|
||||||
|
dialogs/dialog_migrate_buses_base.cpp
|
||||||
dialogs/dialog_netlist.cpp
|
dialogs/dialog_netlist.cpp
|
||||||
dialogs/dialog_netlist_base.cpp
|
dialogs/dialog_netlist_base.cpp
|
||||||
dialogs/dialog_plot_schematic.cpp
|
dialogs/dialog_plot_schematic.cpp
|
||||||
@ -136,6 +139,7 @@ set( EESCHEMA_SRCS
|
|||||||
autoplace_fields.cpp
|
autoplace_fields.cpp
|
||||||
backanno.cpp
|
backanno.cpp
|
||||||
block.cpp
|
block.cpp
|
||||||
|
bus_alias.cpp
|
||||||
bus-wire-junction.cpp
|
bus-wire-junction.cpp
|
||||||
busentry.cpp
|
busentry.cpp
|
||||||
class_libentry.cpp
|
class_libentry.cpp
|
||||||
@ -144,6 +148,7 @@ set( EESCHEMA_SRCS
|
|||||||
cmp_library_lexer.cpp
|
cmp_library_lexer.cpp
|
||||||
component_references_lister.cpp
|
component_references_lister.cpp
|
||||||
controle.cpp
|
controle.cpp
|
||||||
|
connection_graph.cpp
|
||||||
cross-probing.cpp
|
cross-probing.cpp
|
||||||
drc_erc_item.cpp
|
drc_erc_item.cpp
|
||||||
edit_bitmap.cpp
|
edit_bitmap.cpp
|
||||||
@ -195,6 +200,7 @@ set( EESCHEMA_SRCS
|
|||||||
sch_bus_entry.cpp
|
sch_bus_entry.cpp
|
||||||
sch_collectors.cpp
|
sch_collectors.cpp
|
||||||
sch_component.cpp
|
sch_component.cpp
|
||||||
|
sch_connection.cpp
|
||||||
sch_eagle_plugin.cpp
|
sch_eagle_plugin.cpp
|
||||||
sch_field.cpp
|
sch_field.cpp
|
||||||
sch_io_mgr.cpp
|
sch_io_mgr.cpp
|
||||||
@ -204,6 +210,7 @@ set( EESCHEMA_SRCS
|
|||||||
sch_line.cpp
|
sch_line.cpp
|
||||||
sch_marker.cpp
|
sch_marker.cpp
|
||||||
sch_no_connect.cpp
|
sch_no_connect.cpp
|
||||||
|
sch_pin_connection.cpp
|
||||||
sch_plugin.cpp
|
sch_plugin.cpp
|
||||||
sch_preview_panel.cpp
|
sch_preview_panel.cpp
|
||||||
sch_screen.cpp
|
sch_screen.cpp
|
||||||
|
@ -62,7 +62,7 @@ void SCH_EDIT_FRAME::DeleteAnnotation( bool aCurrentSheetOnly )
|
|||||||
{
|
{
|
||||||
SCH_SCREEN* screen = GetScreen();
|
SCH_SCREEN* screen = GetScreen();
|
||||||
wxCHECK_RET( screen != NULL, wxT( "Attempt to clear annotation of a NULL screen." ) );
|
wxCHECK_RET( screen != NULL, wxT( "Attempt to clear annotation of a NULL screen." ) );
|
||||||
screen->ClearAnnotation( m_CurrentSheet );
|
screen->ClearAnnotation( g_CurrentSheet );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -71,7 +71,7 @@ void SCH_EDIT_FRAME::DeleteAnnotation( bool aCurrentSheetOnly )
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update the references for the sheet that is currently being displayed.
|
// Update the references for the sheet that is currently being displayed.
|
||||||
m_CurrentSheet->UpdateAllScreenReferences();
|
g_CurrentSheet->UpdateAllScreenReferences();
|
||||||
|
|
||||||
SyncView();
|
SyncView();
|
||||||
GetCanvas()->Refresh();
|
GetCanvas()->Refresh();
|
||||||
@ -125,7 +125,7 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_CurrentSheet->GetMultiUnitComponents( lockedComponents );
|
g_CurrentSheet->GetMultiUnitComponents( lockedComponents );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -146,7 +146,7 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_CurrentSheet->GetComponents( references );
|
g_CurrentSheet->GetComponents( references );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Break full components reference in name (prefix) and number:
|
// Break full components reference in name (prefix) and number:
|
||||||
@ -233,7 +233,7 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic,
|
|||||||
aReporter.ReportTail( _( "Annotation complete." ), REPORTER::RPT_ACTION );
|
aReporter.ReportTail( _( "Annotation complete." ), REPORTER::RPT_ACTION );
|
||||||
|
|
||||||
// Update on screen references, that can be modified by previous calculations:
|
// Update on screen references, that can be modified by previous calculations:
|
||||||
m_CurrentSheet->UpdateAllScreenReferences();
|
g_CurrentSheet->UpdateAllScreenReferences();
|
||||||
SetSheetNumberAndCount();
|
SetSheetNumberAndCount();
|
||||||
|
|
||||||
SyncView();
|
SyncView();
|
||||||
@ -252,7 +252,7 @@ int SCH_EDIT_FRAME::CheckAnnotate( REPORTER& aReporter, bool aOneSheetOnly )
|
|||||||
if( !aOneSheetOnly )
|
if( !aOneSheetOnly )
|
||||||
sheetList.GetComponents( componentsList );
|
sheetList.GetComponents( componentsList );
|
||||||
else
|
else
|
||||||
m_CurrentSheet->GetComponents( componentsList );
|
g_CurrentSheet->GetComponents( componentsList );
|
||||||
|
|
||||||
return componentsList.CheckAnnotation( aReporter );
|
return componentsList.CheckAnnotation( aReporter );
|
||||||
}
|
}
|
||||||
|
@ -455,7 +455,7 @@ void SCH_EDIT_FRAME::PasteListOfItems( wxDC* DC )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
wxFileName destFn = m_CurrentSheet->Last()->GetFileName();
|
wxFileName destFn = g_CurrentSheet->Last()->GetFileName();
|
||||||
|
|
||||||
if( destFn.IsRelative() )
|
if( destFn.IsRelative() )
|
||||||
destFn.MakeAbsolute( Prj().GetProjectPath() );
|
destFn.MakeAbsolute( Prj().GetProjectPath() );
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
#include <sch_text.h>
|
#include <sch_text.h>
|
||||||
#include <sch_component.h>
|
#include <sch_component.h>
|
||||||
#include <sch_sheet.h>
|
#include <sch_sheet.h>
|
||||||
|
#include <list_operations.h>
|
||||||
#include <sch_view.h>
|
#include <sch_view.h>
|
||||||
#include <view/view_group.h>
|
#include <view/view_group.h>
|
||||||
|
|
||||||
@ -53,7 +54,6 @@ static void ComputeBreakPoint( SCH_SCREEN* aScreen, SCH_LINE* aSegment, wxPoint&
|
|||||||
static DLIST< SCH_ITEM > s_wires; // when creating a new set of wires,
|
static DLIST< SCH_ITEM > s_wires; // when creating a new set of wires,
|
||||||
// stores here the new wires.
|
// stores here the new wires.
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In a contiguous list of wires, remove wires that backtrack over the previous
|
* In a contiguous list of wires, remove wires that backtrack over the previous
|
||||||
* wire. Example:
|
* wire. Example:
|
||||||
@ -130,15 +130,49 @@ static void DrawSegment( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosi
|
|||||||
|
|
||||||
wxPoint endpos = frame->GetCrossHairPosition();
|
wxPoint endpos = frame->GetCrossHairPosition();
|
||||||
|
|
||||||
|
auto view = static_cast<SCH_DRAW_PANEL*>( aPanel )->GetView();
|
||||||
|
view->ClearPreview();
|
||||||
|
|
||||||
|
// Update the bus unfold posture based on the mouse movement
|
||||||
|
if( frame->m_busUnfold.in_progress && !frame->m_busUnfold.label_placed )
|
||||||
|
{
|
||||||
|
auto cursor_delta = frame->GetCursorPosition( false ) - frame->m_busUnfold.origin;
|
||||||
|
auto entry = frame->m_busUnfold.entry;
|
||||||
|
|
||||||
|
bool offset = ( cursor_delta.x < 0 );
|
||||||
|
char shape = ( offset ? ( ( cursor_delta.y >= 0 ) ? '/' : '\\' )
|
||||||
|
: ( ( cursor_delta.y >= 0 ) ? '\\' : '/' ) );
|
||||||
|
|
||||||
|
// Erase and redraw if necessary
|
||||||
|
if( shape != entry->GetBusEntryShape() ||
|
||||||
|
offset != frame->m_busUnfold.offset )
|
||||||
|
{
|
||||||
|
entry->SetBusEntryShape( shape );
|
||||||
|
wxPoint entry_pos = frame->m_busUnfold.origin;
|
||||||
|
|
||||||
|
if( offset )
|
||||||
|
entry_pos -= entry->GetSize();
|
||||||
|
|
||||||
|
entry->SetPosition( entry_pos );
|
||||||
|
frame->m_busUnfold.offset = offset;
|
||||||
|
|
||||||
|
frame->RefreshItem( entry );
|
||||||
|
|
||||||
|
wxPoint wire_start = ( offset ? entry->GetPosition() : entry->m_End() );
|
||||||
|
( (SCH_LINE*) s_wires.begin() )->SetStartPoint( wire_start );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the label "ghost" position
|
||||||
|
auto label = frame->m_busUnfold.label;
|
||||||
|
label->SetPosition( endpos );
|
||||||
|
view->AddToPreview( label->Clone() );
|
||||||
|
}
|
||||||
|
|
||||||
if( frame->GetForceHVLines() ) /* Coerce the line to vertical or horizontal one: */
|
if( frame->GetForceHVLines() ) /* Coerce the line to vertical or horizontal one: */
|
||||||
ComputeBreakPoint( frame->GetScreen(), (SCH_LINE*) s_wires.GetLast()->Back(), endpos );
|
ComputeBreakPoint( frame->GetScreen(), (SCH_LINE*) s_wires.GetLast()->Back(), endpos );
|
||||||
else
|
else
|
||||||
( (SCH_LINE*) s_wires.GetLast() )->SetEndPoint( endpos );
|
( (SCH_LINE*) s_wires.GetLast() )->SetEndPoint( endpos );
|
||||||
|
|
||||||
auto view = static_cast<SCH_DRAW_PANEL*>( aPanel )->GetView();
|
|
||||||
|
|
||||||
view->ClearPreview();
|
|
||||||
|
|
||||||
for( SCH_LINE* segment = (SCH_LINE*) s_wires.begin(); segment; segment = segment->Next() )
|
for( SCH_LINE* segment = (SCH_LINE*) s_wires.begin(); segment; segment = segment->Next() )
|
||||||
{
|
{
|
||||||
if( !segment->IsNull() ) // Add to preview if segment length != 0
|
if( !segment->IsNull() ) // Add to preview if segment length != 0
|
||||||
@ -206,6 +240,30 @@ void SCH_EDIT_FRAME::BeginSegment( int type )
|
|||||||
}
|
}
|
||||||
else // A segment is in progress: terminates the current segment and add a new segment.
|
else // A segment is in progress: terminates the current segment and add a new segment.
|
||||||
{
|
{
|
||||||
|
// Place the label for bus unfolding if needed
|
||||||
|
if( IsBusUnfoldInProgress() && !m_busUnfold.label_placed )
|
||||||
|
{
|
||||||
|
wxASSERT( type == LAYER_WIRE );
|
||||||
|
|
||||||
|
AddToScreen( m_busUnfold.label );
|
||||||
|
m_busUnfold.label_placed = true;
|
||||||
|
|
||||||
|
nextSegment = new SCH_LINE( cursorpos, LAYER_WIRE );
|
||||||
|
|
||||||
|
segment->ClearFlags( IS_NEW );
|
||||||
|
segment->SetFlags( SELECTED );
|
||||||
|
|
||||||
|
nextSegment->SetStartPoint( cursorpos );
|
||||||
|
nextSegment->SetFlags( IS_NEW );
|
||||||
|
|
||||||
|
s_wires.PushBack( nextSegment );
|
||||||
|
GetScreen()->SetCurItem( nextSegment );
|
||||||
|
|
||||||
|
m_canvas->SetMouseCapture( DrawSegment, AbortCreateNewLine );
|
||||||
|
SetRepeatItem( NULL );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
SCH_LINE* prevSegment = segment->Back();
|
SCH_LINE* prevSegment = segment->Back();
|
||||||
|
|
||||||
// Be aware prevSegment can be null when the horizontal and vertical lines only switch
|
// Be aware prevSegment can be null when the horizontal and vertical lines only switch
|
||||||
@ -230,7 +288,8 @@ void SCH_EDIT_FRAME::BeginSegment( int type )
|
|||||||
m_canvas->CallMouseCapture( nullptr, wxDefaultPosition, false );
|
m_canvas->CallMouseCapture( nullptr, wxDefaultPosition, false );
|
||||||
|
|
||||||
// Terminate the command if the end point is on a pin, junction, or another wire or bus.
|
// Terminate the command if the end point is on a pin, junction, or another wire or bus.
|
||||||
if( GetScreen()->IsTerminalPoint( cursorpos, segment->GetLayer() ) )
|
if( !IsBusUnfoldInProgress() &&
|
||||||
|
GetScreen()->IsTerminalPoint( cursorpos, segment->GetLayer() ) )
|
||||||
{
|
{
|
||||||
EndSegment();
|
EndSegment();
|
||||||
return;
|
return;
|
||||||
@ -328,6 +387,18 @@ void SCH_EDIT_FRAME::EndSegment()
|
|||||||
itemList.PushItem( ITEM_PICKER( wire, UR_NEW ) );
|
itemList.PushItem( ITEM_PICKER( wire, UR_NEW ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( IsBusUnfoldInProgress() && m_busUnfold.label_placed )
|
||||||
|
{
|
||||||
|
wxASSERT( m_busUnfold.entry && m_busUnfold.label );
|
||||||
|
|
||||||
|
PICKED_ITEMS_LIST bus_items;
|
||||||
|
|
||||||
|
bus_items.PushItem( ITEM_PICKER( m_busUnfold.entry, UR_NEW ) );
|
||||||
|
bus_items.PushItem( ITEM_PICKER( m_busUnfold.label, UR_NEW ) );
|
||||||
|
|
||||||
|
SaveCopyInUndoList( bus_items, UR_NEW, false );
|
||||||
|
}
|
||||||
|
|
||||||
// Get the last non-null wire (this is the last created segment).
|
// Get the last non-null wire (this is the last created segment).
|
||||||
SetRepeatItem( segment = (SCH_LINE*) s_wires.GetLast() );
|
SetRepeatItem( segment = (SCH_LINE*) s_wires.GetLast() );
|
||||||
|
|
||||||
@ -366,7 +437,13 @@ void SCH_EDIT_FRAME::EndSegment()
|
|||||||
AddJunction( i, true );
|
AddJunction( i, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( IsBusUnfoldInProgress() )
|
||||||
|
{
|
||||||
|
FinishBusUnfold();
|
||||||
|
}
|
||||||
|
|
||||||
TestDanglingEnds();
|
TestDanglingEnds();
|
||||||
|
|
||||||
screen->ClearDrawingState();
|
screen->ClearDrawingState();
|
||||||
screen->SetCurItem( NULL );
|
screen->SetCurItem( NULL );
|
||||||
m_canvas->EndMouseCapture( -1, -1, wxEmptyString, false );
|
m_canvas->EndMouseCapture( -1, -1, wxEmptyString, false );
|
||||||
@ -564,12 +641,14 @@ bool SCH_EDIT_FRAME::TrimWire( const wxPoint& aStart, const wxPoint& aEnd, bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SCH_EDIT_FRAME::SchematicCleanUp( bool aAppend )
|
bool SCH_EDIT_FRAME::SchematicCleanUp( bool aAppend, SCH_SCREEN* aScreen )
|
||||||
{
|
{
|
||||||
SCH_ITEM* item = NULL;
|
SCH_ITEM* item = NULL;
|
||||||
SCH_ITEM* secondItem = NULL;
|
SCH_ITEM* secondItem = NULL;
|
||||||
PICKED_ITEMS_LIST itemList;
|
PICKED_ITEMS_LIST itemList;
|
||||||
SCH_SCREEN* screen = GetScreen();
|
|
||||||
|
if( aScreen == nullptr )
|
||||||
|
aScreen = GetScreen();
|
||||||
|
|
||||||
auto remove_item = [ &itemList ]( SCH_ITEM* aItem ) -> void
|
auto remove_item = [ &itemList ]( SCH_ITEM* aItem ) -> void
|
||||||
{
|
{
|
||||||
@ -577,9 +656,9 @@ bool SCH_EDIT_FRAME::SchematicCleanUp( bool aAppend )
|
|||||||
itemList.PushItem( ITEM_PICKER( aItem, UR_DELETED ) );
|
itemList.PushItem( ITEM_PICKER( aItem, UR_DELETED ) );
|
||||||
};
|
};
|
||||||
|
|
||||||
BreakSegmentsOnJunctions( true );
|
BreakSegmentsOnJunctions( true, aScreen );
|
||||||
|
|
||||||
for( item = screen->GetDrawItems(); item; item = item->Next() )
|
for( item = aScreen->GetDrawItems(); item; item = item->Next() )
|
||||||
{
|
{
|
||||||
if( ( item->Type() != SCH_LINE_T )
|
if( ( item->Type() != SCH_LINE_T )
|
||||||
&& ( item->Type() != SCH_JUNCTION_T )
|
&& ( item->Type() != SCH_JUNCTION_T )
|
||||||
@ -591,7 +670,7 @@ bool SCH_EDIT_FRAME::SchematicCleanUp( bool aAppend )
|
|||||||
|
|
||||||
// Remove unneeded junctions
|
// Remove unneeded junctions
|
||||||
if( ( item->Type() == SCH_JUNCTION_T )
|
if( ( item->Type() == SCH_JUNCTION_T )
|
||||||
&& ( !screen->IsJunctionNeeded( item->GetPosition() ) ) )
|
&& ( !aScreen->IsJunctionNeeded( item->GetPosition() ) ) )
|
||||||
{
|
{
|
||||||
remove_item( item );
|
remove_item( item );
|
||||||
continue;
|
continue;
|
||||||
@ -634,16 +713,16 @@ bool SCH_EDIT_FRAME::SchematicCleanUp( bool aAppend )
|
|||||||
|
|
||||||
// If the end points overlap, check if we still need the junction
|
// If the end points overlap, check if we still need the junction
|
||||||
if( secondLine->IsEndPoint( firstLine->GetStartPoint() ) )
|
if( secondLine->IsEndPoint( firstLine->GetStartPoint() ) )
|
||||||
needed = screen->IsJunctionNeeded( firstLine->GetStartPoint() );
|
needed = aScreen->IsJunctionNeeded( firstLine->GetStartPoint() );
|
||||||
else if( secondLine->IsEndPoint( firstLine->GetEndPoint() ) )
|
else if( secondLine->IsEndPoint( firstLine->GetEndPoint() ) )
|
||||||
needed = screen->IsJunctionNeeded( firstLine->GetEndPoint() );
|
needed = aScreen->IsJunctionNeeded( firstLine->GetEndPoint() );
|
||||||
|
|
||||||
if( !needed && ( line = (SCH_LINE*) secondLine->MergeOverlap( firstLine ) ) )
|
if( !needed && ( line = (SCH_LINE*) secondLine->MergeOverlap( firstLine ) ) )
|
||||||
{
|
{
|
||||||
remove_item( item );
|
remove_item( item );
|
||||||
remove_item( secondItem );
|
remove_item( secondItem );
|
||||||
itemList.PushItem( ITEM_PICKER( line, UR_NEW ) );
|
itemList.PushItem( ITEM_PICKER( line, UR_NEW ) );
|
||||||
AddToScreen( line );
|
AddToScreen( line, aScreen );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -653,33 +732,33 @@ bool SCH_EDIT_FRAME::SchematicCleanUp( bool aAppend )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for( item = screen->GetDrawItems(); item; item = secondItem )
|
for( item = aScreen->GetDrawItems(); item; item = secondItem )
|
||||||
{
|
{
|
||||||
secondItem = item->Next();
|
secondItem = item->Next();
|
||||||
|
|
||||||
if( item->GetFlags() & STRUCT_DELETED )
|
if( item->GetFlags() & STRUCT_DELETED )
|
||||||
RemoveFromScreen( item );
|
RemoveFromScreen( item, aScreen );
|
||||||
}
|
}
|
||||||
|
|
||||||
SaveCopyInUndoList( itemList, UR_CHANGED, aAppend );
|
|
||||||
|
|
||||||
return itemList.GetCount() > 0;
|
return itemList.GetCount() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SCH_EDIT_FRAME::BreakSegment( SCH_LINE* aSegment, const wxPoint& aPoint, bool aAppend,
|
bool SCH_EDIT_FRAME::BreakSegment( SCH_LINE* aSegment, const wxPoint& aPoint,
|
||||||
SCH_LINE** aNewSegment )
|
bool aAppend, SCH_LINE** aNewSegment,
|
||||||
|
SCH_SCREEN* aScreen )
|
||||||
{
|
{
|
||||||
if( !IsPointOnSegment( aSegment->GetStartPoint(), aSegment->GetEndPoint(), aPoint )
|
if( !IsPointOnSegment( aSegment->GetStartPoint(), aSegment->GetEndPoint(), aPoint )
|
||||||
|| aSegment->IsEndPoint( aPoint ) )
|
|| aSegment->IsEndPoint( aPoint ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
SaveCopyInUndoList( aSegment, UR_CHANGED, aAppend );
|
if( aScreen == nullptr )
|
||||||
|
aScreen = GetScreen();
|
||||||
|
|
||||||
SCH_LINE* newSegment = new SCH_LINE( *aSegment );
|
SCH_LINE* newSegment = new SCH_LINE( *aSegment );
|
||||||
SaveCopyInUndoList( newSegment, UR_NEW, true );
|
|
||||||
|
|
||||||
newSegment->SetStartPoint( aPoint );
|
newSegment->SetStartPoint( aPoint );
|
||||||
AddToScreen( newSegment );
|
AddToScreen( newSegment, aScreen );
|
||||||
|
|
||||||
RefreshItem( aSegment );
|
RefreshItem( aSegment );
|
||||||
aSegment->SetEndPoint( aPoint );
|
aSegment->SetEndPoint( aPoint );
|
||||||
@ -691,33 +770,41 @@ bool SCH_EDIT_FRAME::BreakSegment( SCH_LINE* aSegment, const wxPoint& aPoint, bo
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SCH_EDIT_FRAME::BreakSegments( const wxPoint& aPoint, bool aAppend )
|
bool SCH_EDIT_FRAME::BreakSegments( const wxPoint& aPoint, bool aAppend,
|
||||||
|
SCH_SCREEN* aScreen )
|
||||||
{
|
{
|
||||||
|
if( aScreen == nullptr )
|
||||||
|
aScreen = GetScreen();
|
||||||
|
|
||||||
bool brokenSegments = false;
|
bool brokenSegments = false;
|
||||||
|
|
||||||
for( SCH_ITEM* segment = GetScreen()->GetDrawItems(); segment; segment = segment->Next() )
|
for( SCH_ITEM* segment = aScreen->GetDrawItems(); segment; segment = segment->Next() )
|
||||||
{
|
{
|
||||||
if( ( segment->Type() != SCH_LINE_T ) || ( segment->GetLayer() == LAYER_NOTES ) )
|
if( ( segment->Type() != SCH_LINE_T ) || ( segment->GetLayer() == LAYER_NOTES ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
brokenSegments |= BreakSegment( (SCH_LINE*) segment, aPoint, aAppend || brokenSegments );
|
brokenSegments |= BreakSegment( (SCH_LINE*) segment, aPoint,
|
||||||
|
aAppend || brokenSegments, NULL, aScreen );
|
||||||
}
|
}
|
||||||
|
|
||||||
return brokenSegments;
|
return brokenSegments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SCH_EDIT_FRAME::BreakSegmentsOnJunctions( bool aAppend )
|
bool SCH_EDIT_FRAME::BreakSegmentsOnJunctions( bool aAppend, SCH_SCREEN* aScreen )
|
||||||
{
|
{
|
||||||
|
if( aScreen == nullptr )
|
||||||
|
aScreen = GetScreen();
|
||||||
|
|
||||||
bool brokenSegments = false;
|
bool brokenSegments = false;
|
||||||
|
|
||||||
for( SCH_ITEM* item = GetScreen()->GetDrawItems(); item; item = item->Next() )
|
for( SCH_ITEM* item = aScreen->GetDrawItems(); item; item = item->Next() )
|
||||||
{
|
{
|
||||||
if( item->Type() == SCH_JUNCTION_T )
|
if( item->Type() == SCH_JUNCTION_T )
|
||||||
{
|
{
|
||||||
SCH_JUNCTION* junction = ( SCH_JUNCTION* ) item;
|
SCH_JUNCTION* junction = ( SCH_JUNCTION* ) item;
|
||||||
|
|
||||||
if( BreakSegments( junction->GetPosition(), brokenSegments || aAppend ) )
|
if( BreakSegments( junction->GetPosition(), brokenSegments || aAppend, aScreen ) )
|
||||||
brokenSegments = true;
|
brokenSegments = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -725,8 +812,8 @@ bool SCH_EDIT_FRAME::BreakSegmentsOnJunctions( bool aAppend )
|
|||||||
SCH_BUS_ENTRY_BASE* busEntry = dynamic_cast<SCH_BUS_ENTRY_BASE*>( item );
|
SCH_BUS_ENTRY_BASE* busEntry = dynamic_cast<SCH_BUS_ENTRY_BASE*>( item );
|
||||||
if( busEntry )
|
if( busEntry )
|
||||||
{
|
{
|
||||||
if( BreakSegments( busEntry->GetPosition(), brokenSegments || aAppend )
|
if( BreakSegments( busEntry->GetPosition(), brokenSegments || aAppend, aScreen )
|
||||||
|| BreakSegments( busEntry->m_End(), brokenSegments || aAppend ) )
|
|| BreakSegments( busEntry->m_End(), brokenSegments || aAppend, aScreen ) )
|
||||||
brokenSegments = true;
|
brokenSegments = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -846,6 +933,7 @@ SCH_NO_CONNECT* SCH_EDIT_FRAME::AddNoConnect( const wxPoint& aPosition )
|
|||||||
static void AbortCreateNewLine( EDA_DRAW_PANEL* aPanel, wxDC* aDC )
|
static void AbortCreateNewLine( EDA_DRAW_PANEL* aPanel, wxDC* aDC )
|
||||||
{
|
{
|
||||||
SCH_SCREEN* screen = (SCH_SCREEN*) aPanel->GetScreen();
|
SCH_SCREEN* screen = (SCH_SCREEN*) aPanel->GetScreen();
|
||||||
|
|
||||||
SCH_EDIT_FRAME* parent = ( SCH_EDIT_FRAME* ) aPanel->GetParent();
|
SCH_EDIT_FRAME* parent = ( SCH_EDIT_FRAME* ) aPanel->GetParent();
|
||||||
|
|
||||||
if( screen->GetCurItem() )
|
if( screen->GetCurItem() )
|
||||||
@ -858,6 +946,11 @@ static void AbortCreateNewLine( EDA_DRAW_PANEL* aPanel, wxDC* aDC )
|
|||||||
parent->SetRepeatItem( NULL );
|
parent->SetRepeatItem( NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( parent->IsBusUnfoldInProgress() )
|
||||||
|
{
|
||||||
|
parent->CancelBusUnfold();
|
||||||
|
}
|
||||||
|
|
||||||
auto view = static_cast<SCH_DRAW_PANEL*>(aPanel)->GetView();
|
auto view = static_cast<SCH_DRAW_PANEL*>(aPanel)->GetView();
|
||||||
view->ClearPreview();
|
view->ClearPreview();
|
||||||
view->ShowPreview( false );
|
view->ShowPreview( false );
|
||||||
|
41
eeschema/bus_alias.cpp
Normal file
41
eeschema/bus_alias.cpp
Normal file
@ -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() );
|
||||||
|
}
|
100
eeschema/bus_alias.h
Normal file
100
eeschema/bus_alias.h
Normal file
@ -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
Normal file
1644
eeschema/connection_graph.cpp
Normal file
File diff suppressed because it is too large
Load Diff
327
eeschema/connection_graph.h
Normal file
327
eeschema/connection_graph.h
Normal 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
|
@ -228,9 +228,6 @@ SCH_ITEM* SCH_EDIT_FRAME::LocateItem( const wxPoint& aPosition, const KICAD_T aF
|
|||||||
|
|
||||||
if( item )
|
if( item )
|
||||||
{
|
{
|
||||||
if( item->Type() == SCH_COMPONENT_T )
|
|
||||||
( (SCH_COMPONENT*) item )->SetCurrentSheetPath( &GetCurrentSheet() );
|
|
||||||
|
|
||||||
MSG_PANEL_ITEMS items;
|
MSG_PANEL_ITEMS items;
|
||||||
item->GetMsgPanelInfo( m_UserUnits, items );
|
item->GetMsgPanelInfo( m_UserUnits, items );
|
||||||
SetMsgPanel( items );
|
SetMsgPanel( items );
|
||||||
|
517
eeschema/dialogs/dialog_bus_manager.cpp
Normal file
517
eeschema/dialogs/dialog_bus_manager.cpp
Normal file
@ -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();
|
||||||
|
}
|
90
eeschema/dialogs/dialog_bus_manager.h
Normal file
90
eeschema/dialogs/dialog_bus_manager.h
Normal file
@ -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_
|
@ -29,10 +29,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <fctsys.h>
|
#include <fctsys.h>
|
||||||
#include <wx/valgen.h>
|
|
||||||
#include <wx/valnum.h>
|
|
||||||
#include <sch_edit_frame.h>
|
#include <sch_edit_frame.h>
|
||||||
#include <base_units.h>
|
#include <base_units.h>
|
||||||
|
#include <validators.h>
|
||||||
|
|
||||||
#include <sch_draw_panel.h>
|
#include <sch_draw_panel.h>
|
||||||
#include <general.h>
|
#include <general.h>
|
||||||
@ -87,6 +86,7 @@ private:
|
|||||||
wxWindow* m_activeTextCtrl;
|
wxWindow* m_activeTextCtrl;
|
||||||
wxTextEntry* m_activeTextEntry;
|
wxTextEntry* m_activeTextEntry;
|
||||||
UNIT_BINDER m_textSize;
|
UNIT_BINDER m_textSize;
|
||||||
|
REGEX_VALIDATOR m_netNameValidator;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -108,7 +108,9 @@ const int MAX_TEXTSIZE = INT_MAX;
|
|||||||
|
|
||||||
DIALOG_LABEL_EDITOR::DIALOG_LABEL_EDITOR( SCH_EDIT_FRAME* aParent, SCH_TEXT* aTextItem ) :
|
DIALOG_LABEL_EDITOR::DIALOG_LABEL_EDITOR( SCH_EDIT_FRAME* aParent, SCH_TEXT* aTextItem ) :
|
||||||
DIALOG_LABEL_EDITOR_BASE( aParent ),
|
DIALOG_LABEL_EDITOR_BASE( aParent ),
|
||||||
m_textSize( aParent, m_textSizeLabel, m_textSizeCtrl, m_textSizeUnits, false )
|
m_textSize( aParent, m_textSizeLabel, m_textSizeCtrl, m_textSizeUnits, false ),
|
||||||
|
// first part matches single nets and bus vector, the second part matches complex buses
|
||||||
|
m_netNameValidator( "([^/ ]+)|({[^/]+})" )
|
||||||
{
|
{
|
||||||
m_Parent = aParent;
|
m_Parent = aParent;
|
||||||
m_CurrentText = aTextItem;
|
m_CurrentText = aTextItem;
|
||||||
@ -151,8 +153,9 @@ DIALOG_LABEL_EDITOR::DIALOG_LABEL_EDITOR( SCH_EDIT_FRAME* aParent, SCH_TEXT* aTe
|
|||||||
|
|
||||||
SetInitialFocus( m_activeTextCtrl );
|
SetInitialFocus( m_activeTextCtrl );
|
||||||
|
|
||||||
|
// Enable validator for net names
|
||||||
if( m_CurrentText->Type() != SCH_TEXT_T )
|
if( m_CurrentText->Type() != SCH_TEXT_T )
|
||||||
( (wxTextValidator*) m_activeTextCtrl->GetValidator() )->SetCharExcludes( wxT( " /" ) );
|
m_activeTextCtrl->SetValidator( m_netNameValidator );
|
||||||
|
|
||||||
m_TextShape->Show( m_CurrentText->Type() == SCH_GLOBAL_LABEL_T ||
|
m_TextShape->Show( m_CurrentText->Type() == SCH_GLOBAL_LABEL_T ||
|
||||||
m_CurrentText->Type() == SCH_HIERARCHICAL_LABEL_T );
|
m_CurrentText->Type() == SCH_HIERARCHICAL_LABEL_T );
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// C++ code generated with wxFormBuilder (version Aug 4 2017)
|
// C++ code generated with wxFormBuilder (version Oct 17 2016)
|
||||||
// http://www.wxformbuilder.org/
|
// http://www.wxformbuilder.org/
|
||||||
//
|
//
|
||||||
// PLEASE DO "NOT" EDIT THIS FILE!
|
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||||
@ -31,8 +31,6 @@ DIALOG_LABEL_EDITOR_BASE::DIALOG_LABEL_EDITOR_BASE( wxWindow* parent, wxWindowID
|
|||||||
m_valueSingleLine = new wxTextCtrl( this, wxID_VALUESINGLE, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER|wxTE_RICH );
|
m_valueSingleLine = new wxTextCtrl( this, wxID_VALUESINGLE, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER|wxTE_RICH );
|
||||||
m_valueSingleLine->SetMinSize( wxSize( 360,-1 ) );
|
m_valueSingleLine->SetMinSize( wxSize( 360,-1 ) );
|
||||||
|
|
||||||
m_valueSingleLine->SetValidator( wxTextValidator( wxFILTER_EXCLUDE_CHAR_LIST, &m_labelText ) );
|
|
||||||
|
|
||||||
m_textEntrySizer->Add( m_valueSingleLine, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 3 );
|
m_textEntrySizer->Add( m_valueSingleLine, 0, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxBOTTOM|wxLEFT, 3 );
|
||||||
|
|
||||||
m_labelMultiLine = new wxStaticText( this, wxID_ANY, _("Text:"), wxDefaultPosition, wxDefaultSize, 0 );
|
m_labelMultiLine = new wxStaticText( this, wxID_ANY, _("Text:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
<property name="file">dialog_edit_label_base</property>
|
<property name="file">dialog_edit_label_base</property>
|
||||||
<property name="first_id">1000</property>
|
<property name="first_id">1000</property>
|
||||||
<property name="help_provider">none</property>
|
<property name="help_provider">none</property>
|
||||||
<property name="indent_with_spaces"></property>
|
|
||||||
<property name="internationalize">1</property>
|
<property name="internationalize">1</property>
|
||||||
<property name="name">dialog_edit_label_base</property>
|
<property name="name">dialog_edit_label_base</property>
|
||||||
<property name="namespace"></property>
|
<property name="namespace"></property>
|
||||||
@ -247,10 +246,10 @@
|
|||||||
<property name="subclass"></property>
|
<property name="subclass"></property>
|
||||||
<property name="toolbar_pane">0</property>
|
<property name="toolbar_pane">0</property>
|
||||||
<property name="tooltip"></property>
|
<property name="tooltip"></property>
|
||||||
<property name="validator_data_type">wxString</property>
|
<property name="validator_data_type"></property>
|
||||||
<property name="validator_style">wxFILTER_EXCLUDE_CHAR_LIST</property>
|
<property name="validator_style">wxFILTER_NONE</property>
|
||||||
<property name="validator_type">wxTextValidator</property>
|
<property name="validator_type">wxDefaultValidator</property>
|
||||||
<property name="validator_variable">m_labelText</property>
|
<property name="validator_variable"></property>
|
||||||
<property name="value"></property>
|
<property name="value"></property>
|
||||||
<property name="window_extra_style"></property>
|
<property name="window_extra_style"></property>
|
||||||
<property name="window_name"></property>
|
<property name="window_name"></property>
|
||||||
@ -606,8 +605,6 @@
|
|||||||
<property name="window_style"></property>
|
<property name="window_style"></property>
|
||||||
<event name="OnChar"></event>
|
<event name="OnChar"></event>
|
||||||
<event name="OnCombobox"></event>
|
<event name="OnCombobox"></event>
|
||||||
<event name="OnComboboxCloseup"></event>
|
|
||||||
<event name="OnComboboxDropdown"></event>
|
|
||||||
<event name="OnEnterWindow"></event>
|
<event name="OnEnterWindow"></event>
|
||||||
<event name="OnEraseBackground"></event>
|
<event name="OnEraseBackground"></event>
|
||||||
<event name="OnKeyDown"></event>
|
<event name="OnKeyDown"></event>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// C++ code generated with wxFormBuilder (version Aug 4 2017)
|
// C++ code generated with wxFormBuilder (version Oct 17 2016)
|
||||||
// http://www.wxformbuilder.org/
|
// http://www.wxformbuilder.org/
|
||||||
//
|
//
|
||||||
// PLEASE DO "NOT" EDIT THIS FILE!
|
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||||
@ -21,8 +21,8 @@ class DIALOG_SHIM;
|
|||||||
#include <wx/colour.h>
|
#include <wx/colour.h>
|
||||||
#include <wx/settings.h>
|
#include <wx/settings.h>
|
||||||
#include <wx/textctrl.h>
|
#include <wx/textctrl.h>
|
||||||
#include <wx/valtext.h>
|
|
||||||
#include <wx/combobox.h>
|
#include <wx/combobox.h>
|
||||||
|
#include <wx/valtext.h>
|
||||||
#include <wx/sizer.h>
|
#include <wx/sizer.h>
|
||||||
#include <wx/radiobox.h>
|
#include <wx/radiobox.h>
|
||||||
#include <wx/button.h>
|
#include <wx/button.h>
|
||||||
@ -67,7 +67,6 @@ class DIALOG_LABEL_EDITOR_BASE : public DIALOG_SHIM
|
|||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
wxString m_labelText;
|
|
||||||
wxString m_comboText;
|
wxString m_comboText;
|
||||||
|
|
||||||
DIALOG_LABEL_EDITOR_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Text Editor"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
DIALOG_LABEL_EDITOR_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Text Editor"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( -1,-1 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
#include <sch_sheet.h>
|
#include <sch_sheet.h>
|
||||||
#include <lib_pin.h>
|
#include <lib_pin.h>
|
||||||
#include <sch_component.h>
|
#include <sch_component.h>
|
||||||
|
#include <connection_graph.h>
|
||||||
|
|
||||||
#include <dialog_erc.h>
|
#include <dialog_erc.h>
|
||||||
#include <erc.h>
|
#include <erc.h>
|
||||||
@ -58,10 +59,7 @@ extern int DiagErc[PINTYPE_COUNT][PINTYPE_COUNT];
|
|||||||
extern int DefaultDiagErc[PINTYPE_COUNT][PINTYPE_COUNT];
|
extern int DefaultDiagErc[PINTYPE_COUNT][PINTYPE_COUNT];
|
||||||
|
|
||||||
|
|
||||||
bool DIALOG_ERC::m_writeErcFile = false; // saved only for the current session
|
|
||||||
bool DIALOG_ERC::m_TestSimilarLabels = true; // Save in project config
|
|
||||||
bool DIALOG_ERC::m_diagErcTableInit = false; // saved only for the current session
|
bool DIALOG_ERC::m_diagErcTableInit = false; // saved only for the current session
|
||||||
bool DIALOG_ERC::m_tstUniqueGlobalLabels = true; // saved only for the current session
|
|
||||||
|
|
||||||
// Control identifiers for events
|
// Control identifiers for events
|
||||||
#define ID_MATRIX_0 1800
|
#define ID_MATRIX_0 1800
|
||||||
@ -102,8 +100,13 @@ DIALOG_ERC::DIALOG_ERC( SCH_EDIT_FRAME* parent ) :
|
|||||||
|
|
||||||
DIALOG_ERC::~DIALOG_ERC()
|
DIALOG_ERC::~DIALOG_ERC()
|
||||||
{
|
{
|
||||||
m_TestSimilarLabels = m_cbTestSimilarLabels->GetValue();
|
transferControlsToSettings();
|
||||||
m_tstUniqueGlobalLabels = m_cbTestUniqueGlbLabels->GetValue();
|
|
||||||
|
if( m_settings != m_parent->GetErcSettings() )
|
||||||
|
{
|
||||||
|
m_parent->UpdateErcSettings( m_settings );
|
||||||
|
m_parent->SaveProjectSettings( false );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -117,9 +120,8 @@ void DIALOG_ERC::Init()
|
|||||||
m_buttonList[ii][jj] = NULL;
|
m_buttonList[ii][jj] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_WriteResultOpt->SetValue( m_writeErcFile );
|
m_settings = m_parent->GetErcSettings();
|
||||||
m_cbTestSimilarLabels->SetValue( m_TestSimilarLabels );
|
transferSettingsToControls();
|
||||||
m_cbTestUniqueGlbLabels->SetValue( m_tstUniqueGlobalLabels );
|
|
||||||
|
|
||||||
SCH_SCREENS screens;
|
SCH_SCREENS screens;
|
||||||
updateMarkerCounts( &screens );
|
updateMarkerCounts( &screens );
|
||||||
@ -131,6 +133,30 @@ void DIALOG_ERC::Init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DIALOG_ERC::transferSettingsToControls()
|
||||||
|
{
|
||||||
|
m_WriteResultOpt->SetValue( m_settings.write_erc_file );
|
||||||
|
m_cbTestSimilarLabels->SetValue( m_settings.check_similar_labels );
|
||||||
|
m_cbTestUniqueGlbLabels->SetValue( m_settings.check_unique_global_labels );
|
||||||
|
m_cbCheckBusDriverConflicts->SetValue( m_settings.check_bus_driver_conflicts );
|
||||||
|
m_cbCheckBusEntries->SetValue( m_settings.check_bus_entry_conflicts );
|
||||||
|
m_cbCheckBusToBusConflicts->SetValue( m_settings.check_bus_to_bus_conflicts );
|
||||||
|
m_cbCheckBusToNetConflicts->SetValue( m_settings.check_bus_to_net_conflicts );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DIALOG_ERC::transferControlsToSettings()
|
||||||
|
{
|
||||||
|
m_settings.write_erc_file = m_WriteResultOpt->GetValue();
|
||||||
|
m_settings.check_similar_labels = m_cbTestSimilarLabels->GetValue();
|
||||||
|
m_settings.check_unique_global_labels = m_cbTestUniqueGlbLabels->GetValue();
|
||||||
|
m_settings.check_bus_driver_conflicts = m_cbCheckBusDriverConflicts->GetValue();
|
||||||
|
m_settings.check_bus_entry_conflicts = m_cbCheckBusEntries->GetValue();
|
||||||
|
m_settings.check_bus_to_bus_conflicts = m_cbCheckBusToBusConflicts->GetValue();
|
||||||
|
m_settings.check_bus_to_net_conflicts = m_cbCheckBusToNetConflicts->GetValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DIALOG_ERC::updateMarkerCounts( SCH_SCREENS *screens )
|
void DIALOG_ERC::updateMarkerCounts( SCH_SCREENS *screens )
|
||||||
{
|
{
|
||||||
int markers = screens->GetMarkerCount( MARKER_BASE::MARKER_ERC,
|
int markers = screens->GetMarkerCount( MARKER_BASE::MARKER_ERC,
|
||||||
@ -436,10 +462,8 @@ void DIALOG_ERC::ResetDefaultERCDiag( wxCommandEvent& event )
|
|||||||
{
|
{
|
||||||
memcpy( DiagErc, DefaultDiagErc, sizeof( DiagErc ) );
|
memcpy( DiagErc, DefaultDiagErc, sizeof( DiagErc ) );
|
||||||
ReBuildMatrixPanel();
|
ReBuildMatrixPanel();
|
||||||
m_TestSimilarLabels = true;
|
m_settings.LoadDefaults();
|
||||||
m_cbTestSimilarLabels->SetValue( m_TestSimilarLabels );
|
transferSettingsToControls();
|
||||||
m_tstUniqueGlobalLabels = true;
|
|
||||||
m_cbTestUniqueGlbLabels->SetValue( m_tstUniqueGlobalLabels );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -483,9 +507,7 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter )
|
|||||||
{
|
{
|
||||||
wxFileName fn;
|
wxFileName fn;
|
||||||
|
|
||||||
m_writeErcFile = m_WriteResultOpt->GetValue();
|
transferControlsToSettings();
|
||||||
m_TestSimilarLabels = m_cbTestSimilarLabels->GetValue();
|
|
||||||
m_tstUniqueGlobalLabels = m_cbTestUniqueGlbLabels->GetValue();
|
|
||||||
|
|
||||||
// Build the whole sheet list in hierarchy (sheet, not screen)
|
// Build the whole sheet list in hierarchy (sheet, not screen)
|
||||||
SCH_SHEET_LIST sheets( g_RootSheet );
|
SCH_SHEET_LIST sheets( g_RootSheet );
|
||||||
@ -509,6 +531,12 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter )
|
|||||||
*/
|
*/
|
||||||
TestDuplicateSheetNames( true );
|
TestDuplicateSheetNames( true );
|
||||||
|
|
||||||
|
TestConflictingBusAliases();
|
||||||
|
|
||||||
|
// The connection graph has a whole set of ERC checks it can run
|
||||||
|
m_parent->RecalculateConnections();
|
||||||
|
g_ConnectionGraph->RunERC( m_settings );
|
||||||
|
|
||||||
/* Test is all units of each multiunit component have the same footprint assigned.
|
/* Test is all units of each multiunit component have the same footprint assigned.
|
||||||
*/
|
*/
|
||||||
TestMultiunitFootprints( sheets );
|
TestMultiunitFootprints( sheets );
|
||||||
@ -518,9 +546,7 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter )
|
|||||||
// Reset the connection type indicator
|
// Reset the connection type indicator
|
||||||
objectsConnectedList->ResetConnectionsType();
|
objectsConnectedList->ResetConnectionsType();
|
||||||
|
|
||||||
unsigned lastItemIdx;
|
unsigned lastItemIdx = 0;
|
||||||
unsigned nextItemIdx = lastItemIdx = 0;
|
|
||||||
int MinConn = NOC;
|
|
||||||
|
|
||||||
/* Check that a pin appears in only one net. This check is necessary
|
/* Check that a pin appears in only one net. This check is necessary
|
||||||
* because multi-unit components that have shared pins can be wired to
|
* because multi-unit components that have shared pins can be wired to
|
||||||
@ -547,13 +573,6 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter )
|
|||||||
|
|
||||||
wxASSERT_MSG( lastNet <= net, wxT( "Netlist not correctly ordered" ) );
|
wxASSERT_MSG( lastNet <= net, wxT( "Netlist not correctly ordered" ) );
|
||||||
|
|
||||||
if( lastNet != net )
|
|
||||||
{
|
|
||||||
// New net found:
|
|
||||||
MinConn = NOC;
|
|
||||||
nextItemIdx = itemIdx;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch( item->m_Type )
|
switch( item->m_Type )
|
||||||
{
|
{
|
||||||
// These items do not create erc problems
|
// These items do not create erc problems
|
||||||
@ -567,30 +586,7 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter )
|
|||||||
case NET_GLOBBUSLABELMEMBER:
|
case NET_GLOBBUSLABELMEMBER:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NET_HIERLABEL:
|
// TODO(JE) Port this to the new system
|
||||||
case NET_HIERBUSLABELMEMBER:
|
|
||||||
case NET_SHEETLABEL:
|
|
||||||
case NET_SHEETBUSLABELMEMBER:
|
|
||||||
// ERC problems when pin sheets do not match hierarchical labels.
|
|
||||||
// Each pin sheet must match a hierarchical label
|
|
||||||
// Each hierarchical label must match a pin sheet
|
|
||||||
objectsConnectedList->TestforNonOrphanLabel( itemIdx, nextItemIdx );
|
|
||||||
break;
|
|
||||||
case NET_GLOBLABEL:
|
|
||||||
if( m_tstUniqueGlobalLabels )
|
|
||||||
objectsConnectedList->TestforNonOrphanLabel( itemIdx, nextItemIdx );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NET_NOCONNECT:
|
|
||||||
|
|
||||||
// ERC problems when a noconnect symbol is connected to more than one pin.
|
|
||||||
MinConn = NET_NC;
|
|
||||||
|
|
||||||
if( objectsConnectedList->CountPinsInNet( nextItemIdx ) > 1 )
|
|
||||||
Diagnose( item, NULL, MinConn, UNC );
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NET_PIN:
|
case NET_PIN:
|
||||||
{
|
{
|
||||||
// Check if this pin has appeared before on a different net
|
// Check if this pin has appeared before on a different net
|
||||||
@ -619,10 +615,13 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(JE) Remove this if new system is finished
|
||||||
// Look for ERC problems between pins:
|
// Look for ERC problems between pins:
|
||||||
TestOthersItems( objectsConnectedList.get(), itemIdx, nextItemIdx, &MinConn );
|
//TestOthersItems( objectsConnectedList.get(), itemIdx, nextItemIdx, &MinConn );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastItemIdx = itemIdx;
|
lastItemIdx = itemIdx;
|
||||||
@ -630,7 +629,7 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter )
|
|||||||
|
|
||||||
// Test similar labels (i;e. labels which are identical when
|
// Test similar labels (i;e. labels which are identical when
|
||||||
// using case insensitive comparisons)
|
// using case insensitive comparisons)
|
||||||
if( m_TestSimilarLabels )
|
if( m_settings.check_similar_labels )
|
||||||
objectsConnectedList->TestforSimilarLabels();
|
objectsConnectedList->TestforSimilarLabels();
|
||||||
|
|
||||||
// Displays global results:
|
// Displays global results:
|
||||||
@ -653,7 +652,7 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter )
|
|||||||
// Display message
|
// Display message
|
||||||
aReporter.ReportTail( _( "Finished" ), REPORTER::RPT_INFO );
|
aReporter.ReportTail( _( "Finished" ), REPORTER::RPT_INFO );
|
||||||
|
|
||||||
if( m_writeErcFile )
|
if( m_settings.write_erc_file )
|
||||||
{
|
{
|
||||||
fn = g_RootSheet->GetScreen()->GetFileName();
|
fn = g_RootSheet->GetScreen()->GetFileName();
|
||||||
fn.SetExt( wxT( "erc" ) );
|
fn.SetExt( wxT( "erc" ) );
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include <lib_pin.h> // For PINTYPE_COUNT definition
|
#include <lib_pin.h> // For PINTYPE_COUNT definition
|
||||||
|
|
||||||
#include <dialog_erc_base.h>
|
#include <dialog_erc_base.h>
|
||||||
|
#include <erc_settings.h>
|
||||||
#include "dialog_erc_listbox.h"
|
#include "dialog_erc_listbox.h"
|
||||||
|
|
||||||
// DIALOG_ERC class declaration
|
// DIALOG_ERC class declaration
|
||||||
@ -43,12 +44,8 @@ private:
|
|||||||
wxBitmapButton* m_buttonList[PINTYPE_COUNT][PINTYPE_COUNT];
|
wxBitmapButton* m_buttonList[PINTYPE_COUNT][PINTYPE_COUNT];
|
||||||
bool m_initialized;
|
bool m_initialized;
|
||||||
const SCH_MARKER* m_lastMarkerFound;
|
const SCH_MARKER* m_lastMarkerFound;
|
||||||
static bool m_writeErcFile;
|
|
||||||
static bool m_diagErcTableInit; // go to true after DiagErc init
|
static bool m_diagErcTableInit; // go to true after DiagErc init
|
||||||
static bool m_tstUniqueGlobalLabels;
|
ERC_SETTINGS m_settings;
|
||||||
|
|
||||||
public:
|
|
||||||
static bool m_TestSimilarLabels;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DIALOG_ERC( SCH_EDIT_FRAME* parent );
|
DIALOG_ERC( SCH_EDIT_FRAME* parent );
|
||||||
@ -79,6 +76,8 @@ private:
|
|||||||
void ReBuildMatrixPanel();
|
void ReBuildMatrixPanel();
|
||||||
void setDRCMatrixButtonState( wxBitmapButton *aButton, int aState );
|
void setDRCMatrixButtonState( wxBitmapButton *aButton, int aState );
|
||||||
void updateMarkerCounts( SCH_SCREENS *screens );
|
void updateMarkerCounts( SCH_SCREENS *screens );
|
||||||
|
void transferSettingsToControls();
|
||||||
|
void transferControlsToSettings();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// C++ code generated with wxFormBuilder (version Jan 17 2019)
|
// C++ code generated with wxFormBuilder (version Feb 17 2019)
|
||||||
// http://www.wxformbuilder.org/
|
// http://www.wxformbuilder.org/
|
||||||
//
|
//
|
||||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||||
@ -131,6 +131,24 @@ DIALOG_ERC_BASE::DIALOG_ERC_BASE( wxWindow* parent, wxWindowID id, const wxStrin
|
|||||||
|
|
||||||
m_panelMatrixSizer->Add( sbSizer3, 0, wxALL|wxEXPAND, 5 );
|
m_panelMatrixSizer->Add( sbSizer3, 0, wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
|
wxStaticBoxSizer* sbSizer31;
|
||||||
|
sbSizer31 = new wxStaticBoxSizer( new wxStaticBox( m_PanelERCOptions, wxID_ANY, _("Bus Connections") ), wxVERTICAL );
|
||||||
|
|
||||||
|
m_cbCheckBusToNetConflicts = new wxCheckBox( sbSizer31->GetStaticBox(), wxID_ANY, _("Check that bus wires are not connected to hierarchical net pins and vice versa"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
sbSizer31->Add( m_cbCheckBusToNetConflicts, 0, wxALL, 5 );
|
||||||
|
|
||||||
|
m_cbCheckBusToBusConflicts = new wxCheckBox( sbSizer31->GetStaticBox(), wxID_ANY, _("Check that bus-to-bus connections have shared members"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
sbSizer31->Add( m_cbCheckBusToBusConflicts, 0, wxALL, 5 );
|
||||||
|
|
||||||
|
m_cbCheckBusEntries = new wxCheckBox( sbSizer31->GetStaticBox(), wxID_ANY, _("Check that nets are members of buses they graphically connect to"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
sbSizer31->Add( m_cbCheckBusEntries, 0, wxALL, 5 );
|
||||||
|
|
||||||
|
m_cbCheckBusDriverConflicts = new wxCheckBox( sbSizer31->GetStaticBox(), wxID_ANY, _("Check buses for conflicting drivers"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||||
|
sbSizer31->Add( m_cbCheckBusDriverConflicts, 0, wxALL, 5 );
|
||||||
|
|
||||||
|
|
||||||
|
m_panelMatrixSizer->Add( sbSizer31, 0, wxALL|wxEXPAND, 5 );
|
||||||
|
|
||||||
|
|
||||||
m_PanelERCOptions->SetSizer( m_panelMatrixSizer );
|
m_PanelERCOptions->SetSizer( m_panelMatrixSizer );
|
||||||
m_PanelERCOptions->Layout();
|
m_PanelERCOptions->Layout();
|
||||||
|
@ -1318,6 +1318,373 @@
|
|||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
</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="wxStaticBoxSizer" expanded="1">
|
||||||
|
<property name="id">wxID_ANY</property>
|
||||||
|
<property name="label">Bus Connections</property>
|
||||||
|
<property name="minimum_size"></property>
|
||||||
|
<property name="name">sbSizer31</property>
|
||||||
|
<property name="orient">wxVERTICAL</property>
|
||||||
|
<property name="parent">1</property>
|
||||||
|
<property name="permission">none</property>
|
||||||
|
<event name="OnUpdateUI"></event>
|
||||||
|
<object class="sizeritem" expanded="1">
|
||||||
|
<property name="border">5</property>
|
||||||
|
<property name="flag">wxALL</property>
|
||||||
|
<property name="proportion">0</property>
|
||||||
|
<object class="wxCheckBox" expanded="1">
|
||||||
|
<property name="BottomDockable">1</property>
|
||||||
|
<property name="LeftDockable">1</property>
|
||||||
|
<property name="RightDockable">1</property>
|
||||||
|
<property name="TopDockable">1</property>
|
||||||
|
<property name="aui_layer"></property>
|
||||||
|
<property name="aui_name"></property>
|
||||||
|
<property name="aui_position"></property>
|
||||||
|
<property name="aui_row"></property>
|
||||||
|
<property name="best_size"></property>
|
||||||
|
<property name="bg"></property>
|
||||||
|
<property name="caption"></property>
|
||||||
|
<property name="caption_visible">1</property>
|
||||||
|
<property name="center_pane">0</property>
|
||||||
|
<property name="checked">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">Check that bus wires are not connected to hierarchical net pins and vice versa</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_cbCheckBusToNetConflicts</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="OnChar"></event>
|
||||||
|
<event name="OnCheckBox"></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</property>
|
||||||
|
<property name="proportion">0</property>
|
||||||
|
<object class="wxCheckBox" expanded="1">
|
||||||
|
<property name="BottomDockable">1</property>
|
||||||
|
<property name="LeftDockable">1</property>
|
||||||
|
<property name="RightDockable">1</property>
|
||||||
|
<property name="TopDockable">1</property>
|
||||||
|
<property name="aui_layer"></property>
|
||||||
|
<property name="aui_name"></property>
|
||||||
|
<property name="aui_position"></property>
|
||||||
|
<property name="aui_row"></property>
|
||||||
|
<property name="best_size"></property>
|
||||||
|
<property name="bg"></property>
|
||||||
|
<property name="caption"></property>
|
||||||
|
<property name="caption_visible">1</property>
|
||||||
|
<property name="center_pane">0</property>
|
||||||
|
<property name="checked">0</property>
|
||||||
|
<property name="close_button">1</property>
|
||||||
|
<property name="context_help"></property>
|
||||||
|
<property name="context_menu">1</property>
|
||||||
|
<property name="default_pane">0</property>
|
||||||
|
<property name="dock">Dock</property>
|
||||||
|
<property name="dock_fixed">0</property>
|
||||||
|
<property name="docking">Left</property>
|
||||||
|
<property name="enabled">1</property>
|
||||||
|
<property name="fg"></property>
|
||||||
|
<property name="floatable">1</property>
|
||||||
|
<property name="font"></property>
|
||||||
|
<property name="gripper">0</property>
|
||||||
|
<property name="hidden">0</property>
|
||||||
|
<property name="id">wxID_ANY</property>
|
||||||
|
<property name="label">Check that bus-to-bus connections have shared members</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_cbCheckBusToBusConflicts</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="OnChar"></event>
|
||||||
|
<event name="OnCheckBox"></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</property>
|
||||||
|
<property name="proportion">0</property>
|
||||||
|
<object class="wxCheckBox" expanded="1">
|
||||||
|
<property name="BottomDockable">1</property>
|
||||||
|
<property name="LeftDockable">1</property>
|
||||||
|
<property name="RightDockable">1</property>
|
||||||
|
<property name="TopDockable">1</property>
|
||||||
|
<property name="aui_layer"></property>
|
||||||
|
<property name="aui_name"></property>
|
||||||
|
<property name="aui_position"></property>
|
||||||
|
<property name="aui_row"></property>
|
||||||
|
<property name="best_size"></property>
|
||||||
|
<property name="bg"></property>
|
||||||
|
<property name="caption"></property>
|
||||||
|
<property name="caption_visible">1</property>
|
||||||
|
<property name="center_pane">0</property>
|
||||||
|
<property name="checked">0</property>
|
||||||
|
<property name="close_button">1</property>
|
||||||
|
<property name="context_help"></property>
|
||||||
|
<property name="context_menu">1</property>
|
||||||
|
<property name="default_pane">0</property>
|
||||||
|
<property name="dock">Dock</property>
|
||||||
|
<property name="dock_fixed">0</property>
|
||||||
|
<property name="docking">Left</property>
|
||||||
|
<property name="enabled">1</property>
|
||||||
|
<property name="fg"></property>
|
||||||
|
<property name="floatable">1</property>
|
||||||
|
<property name="font"></property>
|
||||||
|
<property name="gripper">0</property>
|
||||||
|
<property name="hidden">0</property>
|
||||||
|
<property name="id">wxID_ANY</property>
|
||||||
|
<property name="label">Check that nets are members of buses they graphically connect to</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_cbCheckBusEntries</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="OnChar"></event>
|
||||||
|
<event name="OnCheckBox"></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</property>
|
||||||
|
<property name="proportion">0</property>
|
||||||
|
<object class="wxCheckBox" expanded="1">
|
||||||
|
<property name="BottomDockable">1</property>
|
||||||
|
<property name="LeftDockable">1</property>
|
||||||
|
<property name="RightDockable">1</property>
|
||||||
|
<property name="TopDockable">1</property>
|
||||||
|
<property name="aui_layer"></property>
|
||||||
|
<property name="aui_name"></property>
|
||||||
|
<property name="aui_position"></property>
|
||||||
|
<property name="aui_row"></property>
|
||||||
|
<property name="best_size"></property>
|
||||||
|
<property name="bg"></property>
|
||||||
|
<property name="caption"></property>
|
||||||
|
<property name="caption_visible">1</property>
|
||||||
|
<property name="center_pane">0</property>
|
||||||
|
<property name="checked">0</property>
|
||||||
|
<property name="close_button">1</property>
|
||||||
|
<property name="context_help"></property>
|
||||||
|
<property name="context_menu">1</property>
|
||||||
|
<property name="default_pane">0</property>
|
||||||
|
<property name="dock">Dock</property>
|
||||||
|
<property name="dock_fixed">0</property>
|
||||||
|
<property name="docking">Left</property>
|
||||||
|
<property name="enabled">1</property>
|
||||||
|
<property name="fg"></property>
|
||||||
|
<property name="floatable">1</property>
|
||||||
|
<property name="font"></property>
|
||||||
|
<property name="gripper">0</property>
|
||||||
|
<property name="hidden">0</property>
|
||||||
|
<property name="id">wxID_ANY</property>
|
||||||
|
<property name="label">Check buses for conflicting drivers</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_cbCheckBusDriverConflicts</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="OnChar"></event>
|
||||||
|
<event name="OnCheckBox"></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>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
</object>
|
</object>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// C++ code generated with wxFormBuilder (version Jan 17 2019)
|
// C++ code generated with wxFormBuilder (version Feb 17 2019)
|
||||||
// http://www.wxformbuilder.org/
|
// http://www.wxformbuilder.org/
|
||||||
//
|
//
|
||||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||||
@ -65,6 +65,10 @@ class DIALOG_ERC_BASE : public DIALOG_SHIM
|
|||||||
wxCheckBox* m_cbTestUniqueGlbLabels;
|
wxCheckBox* m_cbTestUniqueGlbLabels;
|
||||||
wxPanel* m_matrixPanel;
|
wxPanel* m_matrixPanel;
|
||||||
wxButton* m_ResetOptButton;
|
wxButton* m_ResetOptButton;
|
||||||
|
wxCheckBox* m_cbCheckBusToNetConflicts;
|
||||||
|
wxCheckBox* m_cbCheckBusToBusConflicts;
|
||||||
|
wxCheckBox* m_cbCheckBusEntries;
|
||||||
|
wxCheckBox* m_cbCheckBusDriverConflicts;
|
||||||
wxButton* m_buttondelmarkers;
|
wxButton* m_buttondelmarkers;
|
||||||
wxStdDialogButtonSizer* m_sdbSizer1;
|
wxStdDialogButtonSizer* m_sdbSizer1;
|
||||||
wxButton* m_sdbSizer1OK;
|
wxButton* m_sdbSizer1OK;
|
||||||
|
229
eeschema/dialogs/dialog_migrate_buses.cpp
Normal file
229
eeschema/dialogs/dialog_migrate_buses.cpp
Normal file
@ -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 );
|
||||||
|
}
|
||||||
|
}
|
71
eeschema/dialogs/dialog_migrate_buses.h
Normal file
71
eeschema/dialogs/dialog_migrate_buses.h
Normal file
@ -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
|
70
eeschema/dialogs/dialog_migrate_buses_base.cpp
Normal file
70
eeschema/dialogs/dialog_migrate_buses_base.cpp
Normal file
@ -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()
|
||||||
|
{
|
||||||
|
}
|
669
eeschema/dialogs/dialog_migrate_buses_base.fbp
Normal file
669
eeschema/dialogs/dialog_migrate_buses_base.fbp
Normal file
@ -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>
|
57
eeschema/dialogs/dialog_migrate_buses_base.h
Normal file
57
eeschema/dialogs/dialog_migrate_buses_base.h
Normal file
@ -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__
|
@ -23,6 +23,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sch_edit_frame.h>
|
#include <sch_edit_frame.h>
|
||||||
|
#include <sch_sheet.h>
|
||||||
#include <dialog_sch_edit_sheet_pin.h>
|
#include <dialog_sch_edit_sheet_pin.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include <widgets/tab_traversal.h>
|
#include <widgets/tab_traversal.h>
|
||||||
|
|
||||||
#include <sch_edit_frame.h>
|
#include <sch_edit_frame.h>
|
||||||
|
#include <sch_sheet.h>
|
||||||
|
|
||||||
|
|
||||||
DIALOG_SCH_SHEET_PROPS::DIALOG_SCH_SHEET_PROPS( SCH_EDIT_FRAME* parent, SCH_SHEET* aSheet ) :
|
DIALOG_SCH_SHEET_PROPS::DIALOG_SCH_SHEET_PROPS( SCH_EDIT_FRAME* parent, SCH_SHEET* aSheet ) :
|
||||||
|
@ -52,8 +52,8 @@ wxString DRC_ITEM::GetErrorText() const
|
|||||||
return wxString( _("Mismatch between hierarchical labels and pins sheets"));
|
return wxString( _("Mismatch between hierarchical labels and pins sheets"));
|
||||||
case ERCE_NOCONNECT_CONNECTED:
|
case ERCE_NOCONNECT_CONNECTED:
|
||||||
return wxString( _("A pin with a \"no connection\" flag is connected"));
|
return wxString( _("A pin with a \"no connection\" flag is connected"));
|
||||||
case ERCE_GLOBLABEL:
|
case ERCE_LABEL_NOT_CONNECTED:
|
||||||
return wxString( _("Global label not connected to any other global label") );
|
return wxString( _("A label not connected to any other item") );
|
||||||
case ERCE_SIMILAR_LABELS:
|
case ERCE_SIMILAR_LABELS:
|
||||||
return wxString( _("Labels are similar (lower/upper case difference only)") );
|
return wxString( _("Labels are similar (lower/upper case difference only)") );
|
||||||
case ERCE_SIMILAR_GLBL_LABELS:
|
case ERCE_SIMILAR_GLBL_LABELS:
|
||||||
@ -62,7 +62,18 @@ wxString DRC_ITEM::GetErrorText() const
|
|||||||
return wxString( _("Different footprint assigned in another unit of the same component") );
|
return wxString( _("Different footprint assigned in another unit of the same component") );
|
||||||
case ERCE_DIFFERENT_UNIT_NET:
|
case ERCE_DIFFERENT_UNIT_NET:
|
||||||
return wxString( _("Different net assigned to a shared pin in another unit of the same component" ) );
|
return wxString( _("Different net assigned to a shared pin in another unit of the same component" ) );
|
||||||
|
case ERCE_BUS_ALIAS_CONFLICT:
|
||||||
|
return wxString( _("Conflict between bus alias definitions across schematic sheets") );
|
||||||
|
case ERCE_DRIVER_CONFLICT:
|
||||||
|
return wxString( _( "More than one name given to this bus or net" ) );
|
||||||
|
case ERCE_BUS_ENTRY_CONFLICT:
|
||||||
|
return wxString( _( "Net is graphically connected to a bus but not a bus member" ) );
|
||||||
|
case ERCE_BUS_LABEL_ERROR:
|
||||||
|
return wxString( _( "Label attached to bus item does not describe a bus" ) );
|
||||||
|
case ERCE_BUS_TO_BUS_CONFLICT:
|
||||||
|
return wxString( _( "No nets are shared between two bus items" ) );
|
||||||
|
case ERCE_BUS_TO_NET_CONFLICT:
|
||||||
|
return wxString( _( "Invalid connection between bus and net items" ) );
|
||||||
default:
|
default:
|
||||||
wxFAIL_MSG( "Missing ERC error description" );
|
wxFAIL_MSG( "Missing ERC error description" );
|
||||||
return wxString( wxT("Unknown.") );
|
return wxString( wxT("Unknown.") );
|
||||||
|
@ -77,7 +77,7 @@ void SCH_EDIT_FRAME::EditComponentFieldText( SCH_FIELD* aField )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dlg.UpdateField( aField, m_CurrentSheet );
|
dlg.UpdateField( aField, g_CurrentSheet );
|
||||||
m_canvas->MoveCursorToCrossHair();
|
m_canvas->MoveCursorToCrossHair();
|
||||||
m_canvas->SetIgnoreMouseEvents( false );
|
m_canvas->SetIgnoreMouseEvents( false );
|
||||||
|
|
||||||
@ -88,7 +88,6 @@ void SCH_EDIT_FRAME::EditComponentFieldText( SCH_FIELD* aField )
|
|||||||
OnModify();
|
OnModify();
|
||||||
|
|
||||||
MSG_PANEL_ITEMS items;
|
MSG_PANEL_ITEMS items;
|
||||||
component->SetCurrentSheetPath( &GetCurrentSheet() );
|
|
||||||
component->GetMsgPanelInfo( m_UserUnits, items );
|
component->GetMsgPanelInfo( m_UserUnits, items );
|
||||||
SetMsgPanel( items );
|
SetMsgPanel( items );
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
#include <confirm.h>
|
#include <confirm.h>
|
||||||
#include <gestfich.h>
|
#include <gestfich.h>
|
||||||
#include <sch_edit_frame.h>
|
#include <sch_edit_frame.h>
|
||||||
|
#include <sch_sheet.h>
|
||||||
#include <invoke_sch_dialog.h>
|
#include <invoke_sch_dialog.h>
|
||||||
#include <lib_edit_frame.h>
|
#include <lib_edit_frame.h>
|
||||||
#include <eeschema_config.h>
|
#include <eeschema_config.h>
|
||||||
@ -249,8 +250,26 @@ PARAM_CFG_ARRAY& SCH_EDIT_FRAME::GetProjectFileParametersList()
|
|||||||
&s_defaultTextSize,
|
&s_defaultTextSize,
|
||||||
DEFAULT_SIZE_TEXT, 5, 1000 ) );
|
DEFAULT_SIZE_TEXT, 5, 1000 ) );
|
||||||
|
|
||||||
|
m_projectFileParams.push_back( new PARAM_CFG_BOOL( wxT( "ERC_WriteFile" ),
|
||||||
|
&m_ercSettings.write_erc_file, false ) );
|
||||||
|
|
||||||
m_projectFileParams.push_back( new PARAM_CFG_BOOL( wxT( "ERC_TestSimilarLabels" ),
|
m_projectFileParams.push_back( new PARAM_CFG_BOOL( wxT( "ERC_TestSimilarLabels" ),
|
||||||
&DIALOG_ERC::m_TestSimilarLabels, true ) );
|
&m_ercSettings.check_similar_labels, true ) );
|
||||||
|
|
||||||
|
m_projectFileParams.push_back( new PARAM_CFG_BOOL( wxT( "ERC_CheckUniqueGlobalLabels" ),
|
||||||
|
&m_ercSettings.check_unique_global_labels, true ) );
|
||||||
|
|
||||||
|
m_projectFileParams.push_back( new PARAM_CFG_BOOL( wxT( "ERC_CheckBusDriverConflicts" ),
|
||||||
|
&m_ercSettings.check_bus_driver_conflicts, true ) );
|
||||||
|
|
||||||
|
m_projectFileParams.push_back( new PARAM_CFG_BOOL( wxT( "ERC_CheckBusEntryConflicts" ),
|
||||||
|
&m_ercSettings.check_bus_entry_conflicts, true ) );
|
||||||
|
|
||||||
|
m_projectFileParams.push_back( new PARAM_CFG_BOOL( wxT( "ERC_CheckBusToBusConflicts" ),
|
||||||
|
&m_ercSettings.check_bus_to_bus_conflicts, true ) );
|
||||||
|
|
||||||
|
m_projectFileParams.push_back( new PARAM_CFG_BOOL( wxT( "ERC_CheckBusToNetConflicts" ),
|
||||||
|
&m_ercSettings.check_bus_to_net_conflicts, true ) );
|
||||||
|
|
||||||
return m_projectFileParams;
|
return m_projectFileParams;
|
||||||
}
|
}
|
||||||
|
@ -66,6 +66,7 @@ enum id_eeschema_frm
|
|||||||
/* Schematic editor main menubar IDs. */
|
/* Schematic editor main menubar IDs. */
|
||||||
ID_RESCUE_CACHED,
|
ID_RESCUE_CACHED,
|
||||||
ID_EDIT_SYM_LIB_TABLE,
|
ID_EDIT_SYM_LIB_TABLE,
|
||||||
|
ID_BUS_MANAGER,
|
||||||
ID_REMAP_SYMBOLS,
|
ID_REMAP_SYMBOLS,
|
||||||
ID_EDIT_COMPONENTS_TO_SYMBOLS_LIB_ID,
|
ID_EDIT_COMPONENTS_TO_SYMBOLS_LIB_ID,
|
||||||
ID_GRID_SETTINGS,
|
ID_GRID_SETTINGS,
|
||||||
@ -166,6 +167,10 @@ enum id_eeschema_frm
|
|||||||
ID_POPUP_SCH_GETINFO_MARKER,
|
ID_POPUP_SCH_GETINFO_MARKER,
|
||||||
ID_POPUP_END_RANGE,
|
ID_POPUP_END_RANGE,
|
||||||
|
|
||||||
|
// Dynamically bound in AddMenusForBus()
|
||||||
|
ID_POPUP_SCH_UNFOLD_BUS,
|
||||||
|
ID_POPUP_SCH_UNFOLD_BUS_END = ID_POPUP_SCH_UNFOLD_BUS + 64,
|
||||||
|
|
||||||
ID_POPUP_SCH_DISPLAYDOC_CMP,
|
ID_POPUP_SCH_DISPLAYDOC_CMP,
|
||||||
ID_POPUP_SCH_CALL_LIBEDIT_AND_LOAD_CMP,
|
ID_POPUP_SCH_CALL_LIBEDIT_AND_LOAD_CMP,
|
||||||
|
|
||||||
@ -200,6 +205,7 @@ enum id_eeschema_frm
|
|||||||
ID_SCH_EDIT_COMPONENT_FOOTPRINT,
|
ID_SCH_EDIT_COMPONENT_FOOTPRINT,
|
||||||
ID_SCH_MOVE_ITEM,
|
ID_SCH_MOVE_ITEM,
|
||||||
ID_SCH_DRAG_ITEM,
|
ID_SCH_DRAG_ITEM,
|
||||||
|
ID_SCH_UNFOLD_BUS,
|
||||||
|
|
||||||
ID_AUTOPLACE_FIELDS,
|
ID_AUTOPLACE_FIELDS,
|
||||||
|
|
||||||
|
@ -225,6 +225,73 @@ int TestDuplicateSheetNames( bool aCreateMarker )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int TestConflictingBusAliases( bool aCreateMarker )
|
||||||
|
{
|
||||||
|
using std::pair;
|
||||||
|
using std::shared_ptr;
|
||||||
|
using std::vector;
|
||||||
|
|
||||||
|
int err_count = 0;
|
||||||
|
SCH_SCREENS screens;
|
||||||
|
vector< shared_ptr<BUS_ALIAS> > aliases;
|
||||||
|
vector< pair< shared_ptr<BUS_ALIAS>, shared_ptr<BUS_ALIAS> > > conflicts;
|
||||||
|
|
||||||
|
for( auto screen = screens.GetFirst(); screen != NULL; screen = screens.GetNext() )
|
||||||
|
{
|
||||||
|
auto screen_aliases = screen->GetBusAliases();
|
||||||
|
|
||||||
|
for( auto alias : screen_aliases )
|
||||||
|
{
|
||||||
|
for( auto test : aliases )
|
||||||
|
{
|
||||||
|
if( alias->GetName() == test->GetName() &&
|
||||||
|
alias->Members() != test->Members() )
|
||||||
|
{
|
||||||
|
conflicts.push_back( std::make_pair( alias, test ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
aliases.insert( aliases.end(),
|
||||||
|
screen_aliases.begin(), screen_aliases.end() );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !conflicts.empty() )
|
||||||
|
{
|
||||||
|
if( aCreateMarker )
|
||||||
|
{
|
||||||
|
wxString msg;
|
||||||
|
|
||||||
|
for( auto conflict : conflicts )
|
||||||
|
{
|
||||||
|
auto marker = new SCH_MARKER();
|
||||||
|
auto a1 = conflict.first;
|
||||||
|
auto a2 = conflict.second;
|
||||||
|
|
||||||
|
msg.Printf( _( "Bus alias %s has conflicting definitions on multiple sheets: " ),
|
||||||
|
GetChars( a1->GetName() ) );
|
||||||
|
|
||||||
|
wxFileName f1 = a1->GetParent()->GetFileName();
|
||||||
|
wxFileName f2 = a2->GetParent()->GetFileName();
|
||||||
|
|
||||||
|
msg << f1.GetFullName() << " and " << f2.GetFullName();
|
||||||
|
|
||||||
|
marker->SetData( ERCE_BUS_ALIAS_CONFLICT, wxPoint( 0, 0 ),
|
||||||
|
msg, wxPoint( 0, 0 ) );
|
||||||
|
marker->SetMarkerType( MARKER_BASE::MARKER_ERC );
|
||||||
|
marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_ERROR );
|
||||||
|
|
||||||
|
a2->GetParent()->Append( marker );
|
||||||
|
|
||||||
|
++err_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return err_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int TestMultiunitFootprints( SCH_SHEET_LIST& aSheetList )
|
int TestMultiunitFootprints( SCH_SHEET_LIST& aSheetList )
|
||||||
{
|
{
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
@ -314,6 +381,7 @@ void Diagnose( NETLIST_OBJECT* aNetItemRef, NETLIST_OBJECT* aNetItemTst,
|
|||||||
|
|
||||||
if( aMinConn < 0 )
|
if( aMinConn < 0 )
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
if( aNetItemRef->m_Type == NET_HIERLABEL || aNetItemRef->m_Type == NET_HIERBUSLABELMEMBER )
|
if( aNetItemRef->m_Type == NET_HIERLABEL || aNetItemRef->m_Type == NET_HIERBUSLABELMEMBER )
|
||||||
{
|
{
|
||||||
msg.Printf( _( "Hierarchical label %s is not connected to a sheet label." ),
|
msg.Printf( _( "Hierarchical label %s is not connected to a sheet label." ),
|
||||||
@ -341,7 +409,7 @@ void Diagnose( NETLIST_OBJECT* aNetItemRef, NETLIST_OBJECT* aNetItemTst,
|
|||||||
msg,
|
msg,
|
||||||
aNetItemRef->m_Start );
|
aNetItemRef->m_Start );
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,21 +49,28 @@ extern const wxString CommentERC_H[];
|
|||||||
extern const wxString CommentERC_V[];
|
extern const wxString CommentERC_V[];
|
||||||
|
|
||||||
/// DRC error codes:
|
/// DRC error codes:
|
||||||
#define ERCE_UNSPECIFIED 0
|
enum ERCE_T
|
||||||
#define ERCE_DUPLICATE_SHEET_NAME 1 // duplicate sheet names within a given sheet
|
{
|
||||||
#define ERCE_PIN_NOT_CONNECTED 2 // pin not connected and not no connect symbol
|
ERCE_UNSPECIFIED = 0,
|
||||||
#define ERCE_PIN_NOT_DRIVEN 3 // pin connected to some others pins but no pin to drive it
|
ERCE_DUPLICATE_SHEET_NAME, // duplicate sheet names within a given sheet
|
||||||
#define ERCE_PIN_TO_PIN_WARNING 4 // pin connected to another pin: warning level
|
ERCE_PIN_NOT_CONNECTED, // pin not connected and not no connect symbol
|
||||||
#define ERCE_PIN_TO_PIN_ERROR 5 // pin connected to another pin: error level
|
ERCE_PIN_NOT_DRIVEN, // pin connected to some others pins but no pin to drive it
|
||||||
#define ERCE_HIERACHICAL_LABEL 6 // mismatch between hierarchical labels and pins sheets
|
ERCE_PIN_TO_PIN_WARNING, // pin connected to an other pin: warning level
|
||||||
#define ERCE_NOCONNECT_CONNECTED 7 // a no connect symbol is connected to more than 1 pin
|
ERCE_PIN_TO_PIN_ERROR, // pin connected to an other pin: error level
|
||||||
#define ERCE_GLOBLABEL 8 // global label not connected to any other global label
|
ERCE_HIERACHICAL_LABEL, // mismatch between hierarchical labels and pins sheets
|
||||||
#define ERCE_SIMILAR_LABELS 9 // 2 labels are equal fir case insensitive comparisons
|
ERCE_NOCONNECT_CONNECTED, // a no connect symbol is connected to more than 1 pin
|
||||||
#define ERCE_SIMILAR_GLBL_LABELS 10 // 2 labels are equal fir case insensitive comparisons
|
ERCE_LABEL_NOT_CONNECTED, // label not connected to anything
|
||||||
#define ERCE_DIFFERENT_UNIT_FP 11 // different units of the same component have different
|
ERCE_SIMILAR_LABELS, // 2 labels are equal fir case insensitive comparisons
|
||||||
// footprints assigned
|
ERCE_SIMILAR_GLBL_LABELS, // 2 labels are equal fir case insensitive comparisons
|
||||||
#define ERCE_DIFFERENT_UNIT_NET 12 // a shared pin in a multi-unit component is connected
|
ERCE_DIFFERENT_UNIT_FP, // different units of the same component have different footprints assigned
|
||||||
// to more than one net
|
ERCE_DIFFERENT_UNIT_NET, // a shared pin in a multi-unit component is connected to more than one net
|
||||||
|
ERCE_BUS_ALIAS_CONFLICT, // conflicting bus alias definitions across sheets
|
||||||
|
ERCE_DRIVER_CONFLICT, // conflicting drivers (labels, etc) on a subgraph
|
||||||
|
ERCE_BUS_ENTRY_CONFLICT, // a wire connected to a bus doesn't match the bus
|
||||||
|
ERCE_BUS_LABEL_ERROR, // a label attached to a bus isn't in bus format
|
||||||
|
ERCE_BUS_TO_BUS_CONFLICT, // a connection between bus objects doesn't share at least one net
|
||||||
|
ERCE_BUS_TO_NET_CONFLICT, // a bus wire is graphically connected to a net port/pin (or vice versa)
|
||||||
|
};
|
||||||
|
|
||||||
/* Minimal connection table */
|
/* Minimal connection table */
|
||||||
#define NPI 4 // Net with Pin isolated, this pin has type Not Connected and must be left N.C.
|
#define NPI 4 // Net with Pin isolated, this pin has type Not Connected and must be left N.C.
|
||||||
@ -112,6 +119,18 @@ void TestOthersItems( NETLIST_OBJECT_LIST* aList,
|
|||||||
*/
|
*/
|
||||||
int TestDuplicateSheetNames( bool aCreateMarker );
|
int TestDuplicateSheetNames( bool aCreateMarker );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks that there are not conflicting bus alias definitions in the schematic
|
||||||
|
*
|
||||||
|
* (for example, two hierarchical sub-sheets contain different definitions for
|
||||||
|
* the same bus alias)
|
||||||
|
*
|
||||||
|
* @param aCreateMarker: true = create error markers in schematic,
|
||||||
|
* false = calculate error count only
|
||||||
|
* @return the error count
|
||||||
|
*/
|
||||||
|
int TestConflictingBusAliases( bool aCreateMarker = true );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if all units of each multiunit component have the same footprint assigned.
|
* Test if all units of each multiunit component have the same footprint assigned.
|
||||||
* @param aSheetList contains components to be validated.
|
* @param aSheetList contains components to be validated.
|
||||||
|
82
eeschema/erc_settings.h
Normal file
82
eeschema/erc_settings.h
Normal file
@ -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
|
@ -51,7 +51,9 @@
|
|||||||
#include <sch_eagle_plugin.h>
|
#include <sch_eagle_plugin.h>
|
||||||
#include <symbol_lib_table.h>
|
#include <symbol_lib_table.h>
|
||||||
#include <dialog_symbol_remap.h>
|
#include <dialog_symbol_remap.h>
|
||||||
|
#include <dialog_migrate_buses.h>
|
||||||
#include <worksheet_shape_builder.h>
|
#include <worksheet_shape_builder.h>
|
||||||
|
#include <connection_graph.h>
|
||||||
|
|
||||||
|
|
||||||
bool SCH_EDIT_FRAME::SaveEEFile( SCH_SCREEN* aScreen, bool aSaveUnderNewName,
|
bool SCH_EDIT_FRAME::SaveEEFile( SCH_SCREEN* aScreen, bool aSaveUnderNewName,
|
||||||
@ -287,6 +289,7 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
|||||||
SetScreen( nullptr );
|
SetScreen( nullptr );
|
||||||
delete g_RootSheet; // Delete the current project.
|
delete g_RootSheet; // Delete the current project.
|
||||||
g_RootSheet = NULL; // Force CreateScreens() to build new empty project on load failure.
|
g_RootSheet = NULL; // Force CreateScreens() to build new empty project on load failure.
|
||||||
|
|
||||||
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_LEGACY ) );
|
SCH_PLUGIN::SCH_PLUGIN_RELEASER pi( SCH_IO_MGR::FindPlugin( SCH_IO_MGR::SCH_LEGACY ) );
|
||||||
|
|
||||||
// This will rename the file if there is an autosave and the user want to recover
|
// This will rename the file if there is an autosave and the user want to recover
|
||||||
@ -295,8 +298,10 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
g_RootSheet = pi->Load( fullFileName, &Kiway() );
|
g_RootSheet = pi->Load( fullFileName, &Kiway() );
|
||||||
m_CurrentSheet->clear();
|
|
||||||
m_CurrentSheet->push_back( g_RootSheet );
|
g_CurrentSheet = new SCH_SHEET_PATH();
|
||||||
|
g_CurrentSheet->clear();
|
||||||
|
g_CurrentSheet->push_back( g_RootSheet );
|
||||||
|
|
||||||
if( !pi->GetError().IsEmpty() )
|
if( !pi->GetError().IsEmpty() )
|
||||||
{
|
{
|
||||||
@ -362,13 +367,27 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
|||||||
}
|
}
|
||||||
|
|
||||||
schematic.UpdateSymbolLinks(); // Update all symbol library links for all sheets.
|
schematic.UpdateSymbolLinks(); // Update all symbol library links for all sheets.
|
||||||
SetScreen( m_CurrentSheet->LastScreen() );
|
SetScreen( g_CurrentSheet->LastScreen() );
|
||||||
|
|
||||||
// Ensure the schematic is fully segmented on first display
|
// Ensure the schematic is fully segmented on first display
|
||||||
BreakSegmentsOnJunctions();
|
BreakSegmentsOnJunctions();
|
||||||
SchematicCleanUp( true );
|
SchematicCleanUp( true );
|
||||||
GetScreen()->ClearUndoORRedoList( GetScreen()->m_UndoList, 1 );
|
GetScreen()->ClearUndoORRedoList( GetScreen()->m_UndoList, 1 );
|
||||||
GetScreen()->TestDanglingEnds(); // Only perform the dangling end test on root sheet.
|
GetScreen()->TestDanglingEnds(); // Only perform the dangling end test on root sheet.
|
||||||
|
|
||||||
|
RecalculateConnections(); // Update connectivity graph
|
||||||
|
|
||||||
|
// Migrate conflicting bus definitions
|
||||||
|
// TODO(JE) This should only run once based on schematic file version
|
||||||
|
if( g_ConnectionGraph->GetBusesNeedingMigration().size() > 0 )
|
||||||
|
{
|
||||||
|
DIALOG_MIGRATE_BUSES dlg( this );
|
||||||
|
dlg.ShowQuasiModal();
|
||||||
|
|
||||||
|
RecalculateConnections();
|
||||||
|
OnModify();
|
||||||
|
}
|
||||||
|
|
||||||
GetScreen()->m_Initialized = true;
|
GetScreen()->m_Initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -816,9 +835,9 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
|
|||||||
newfilename.SetName( Prj().GetProjectName() );
|
newfilename.SetName( Prj().GetProjectName() );
|
||||||
newfilename.SetExt( SchematicFileExtension );
|
newfilename.SetExt( SchematicFileExtension );
|
||||||
|
|
||||||
m_CurrentSheet->clear();
|
g_CurrentSheet->clear();
|
||||||
m_CurrentSheet->push_back( g_RootSheet );
|
g_CurrentSheet->push_back( g_RootSheet );
|
||||||
SetScreen( m_CurrentSheet->LastScreen() );
|
SetScreen( g_CurrentSheet->LastScreen() );
|
||||||
|
|
||||||
g_RootSheet->SetFileName( newfilename.GetFullPath() );
|
g_RootSheet->SetFileName( newfilename.GetFullPath() );
|
||||||
GetScreen()->SetFileName( newfilename.GetFullPath() );
|
GetScreen()->SetFileName( newfilename.GetFullPath() );
|
||||||
|
@ -70,8 +70,8 @@ void SCH_EDIT_FRAME::OnFindDrcMarker( wxFindDialogEvent& event )
|
|||||||
|
|
||||||
if( event.GetFlags() & FR_CURRENT_SHEET_ONLY )
|
if( event.GetFlags() & FR_CURRENT_SHEET_ONLY )
|
||||||
{
|
{
|
||||||
sheetFoundIn = m_CurrentSheet;
|
sheetFoundIn = g_CurrentSheet;
|
||||||
lastMarker = (SCH_MARKER*) m_CurrentSheet->FindNextItem( SCH_MARKER_T, lastMarker, wrap );
|
lastMarker = (SCH_MARKER*) g_CurrentSheet->FindNextItem( SCH_MARKER_T, lastMarker, wrap );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -81,11 +81,11 @@ void SCH_EDIT_FRAME::OnFindDrcMarker( wxFindDialogEvent& event )
|
|||||||
|
|
||||||
if( lastMarker != NULL )
|
if( lastMarker != NULL )
|
||||||
{
|
{
|
||||||
if( *sheetFoundIn != *m_CurrentSheet )
|
if( *sheetFoundIn != *g_CurrentSheet )
|
||||||
{
|
{
|
||||||
sheetFoundIn->LastScreen()->SetZoom( GetScreen()->GetZoom() );
|
sheetFoundIn->LastScreen()->SetZoom( GetScreen()->GetZoom() );
|
||||||
*m_CurrentSheet = *sheetFoundIn;
|
*g_CurrentSheet = *sheetFoundIn;
|
||||||
m_CurrentSheet->UpdateAllScreenReferences();
|
g_CurrentSheet->UpdateAllScreenReferences();
|
||||||
}
|
}
|
||||||
|
|
||||||
SetCrossHairPosition( lastMarker->GetPosition() );
|
SetCrossHairPosition( lastMarker->GetPosition() );
|
||||||
@ -122,7 +122,7 @@ SCH_ITEM* SCH_EDIT_FRAME::FindComponentAndItem( const wxString& aReference,
|
|||||||
EDA_ITEM* foundItem = nullptr;
|
EDA_ITEM* foundItem = nullptr;
|
||||||
|
|
||||||
if( !aSearchHierarchy )
|
if( !aSearchHierarchy )
|
||||||
sheetList.push_back( *m_CurrentSheet );
|
sheetList.push_back( *g_CurrentSheet );
|
||||||
else
|
else
|
||||||
sheetList.BuildSheetList( g_RootSheet );
|
sheetList.BuildSheetList( g_RootSheet );
|
||||||
|
|
||||||
@ -193,10 +193,10 @@ SCH_ITEM* SCH_EDIT_FRAME::FindComponentAndItem( const wxString& aReference,
|
|||||||
{
|
{
|
||||||
sheet = sheetWithComponentFound;
|
sheet = sheetWithComponentFound;
|
||||||
|
|
||||||
if( *sheet != *m_CurrentSheet )
|
if( *sheet != *g_CurrentSheet )
|
||||||
{
|
{
|
||||||
sheet->LastScreen()->SetZoom( GetScreen()->GetZoom() );
|
sheet->LastScreen()->SetZoom( GetScreen()->GetZoom() );
|
||||||
*m_CurrentSheet = *sheet;
|
*g_CurrentSheet = *sheet;
|
||||||
DisplayCurrentSheet();
|
DisplayCurrentSheet();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,7 +279,7 @@ void SCH_EDIT_FRAME::OnFindSchematicItem( wxFindDialogEvent& aEvent )
|
|||||||
{
|
{
|
||||||
if( aEvent.GetFlags() & FR_CURRENT_SHEET_ONLY && g_RootSheet->CountSheets() > 1 )
|
if( aEvent.GetFlags() & FR_CURRENT_SHEET_ONLY && g_RootSheet->CountSheets() > 1 )
|
||||||
{
|
{
|
||||||
m_foundItems.Collect( searchCriteria, m_CurrentSheet );
|
m_foundItems.Collect( searchCriteria, g_CurrentSheet );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -317,7 +317,7 @@ void SCH_EDIT_FRAME::OnFindReplace( wxFindDialogEvent& aEvent )
|
|||||||
{
|
{
|
||||||
if( aEvent.GetFlags() & FR_CURRENT_SHEET_ONLY && g_RootSheet->CountSheets() > 1 )
|
if( aEvent.GetFlags() & FR_CURRENT_SHEET_ONLY && g_RootSheet->CountSheets() > 1 )
|
||||||
{
|
{
|
||||||
m_foundItems.Collect( searchCriteria, m_CurrentSheet );
|
m_foundItems.Collect( searchCriteria, g_CurrentSheet );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -423,11 +423,11 @@ void SCH_EDIT_FRAME::updateFindReplaceView( wxFindDialogEvent& aEvent )
|
|||||||
item->SetForceVisible( true );
|
item->SetForceVisible( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( sheet->PathHumanReadable() != m_CurrentSheet->PathHumanReadable() )
|
if( sheet->PathHumanReadable() != g_CurrentSheet->PathHumanReadable() )
|
||||||
{
|
{
|
||||||
sheet->LastScreen()->SetZoom( GetScreen()->GetZoom() );
|
sheet->LastScreen()->SetZoom( GetScreen()->GetZoom() );
|
||||||
*m_CurrentSheet = *sheet;
|
*g_CurrentSheet = *sheet;
|
||||||
m_CurrentSheet->UpdateAllScreenReferences();
|
g_CurrentSheet->UpdateAllScreenReferences();
|
||||||
SetScreen( sheet->LastScreen() );
|
SetScreen( sheet->LastScreen() );
|
||||||
sheet->LastScreen()->TestDanglingEnds();
|
sheet->LastScreen()->TestDanglingEnds();
|
||||||
}
|
}
|
||||||
|
@ -34,8 +34,10 @@
|
|||||||
|
|
||||||
using KIGFX::COLOR4D;
|
using KIGFX::COLOR4D;
|
||||||
|
|
||||||
|
class CONNECTION_GRAPH;
|
||||||
class TRANSFORM;
|
class TRANSFORM;
|
||||||
class SCH_SHEET;
|
class SCH_SHEET;
|
||||||
|
class SCH_SHEET_PATH;
|
||||||
|
|
||||||
#define EESCHEMA_VERSION 4
|
#define EESCHEMA_VERSION 4
|
||||||
#define SCHEMATIC_HEAD_STRING "Schematic File Version"
|
#define SCHEMATIC_HEAD_STRING "Schematic File Version"
|
||||||
@ -83,6 +85,18 @@ extern TRANSFORM DefaultTransform;
|
|||||||
/* First and main (root) screen */
|
/* First and main (root) screen */
|
||||||
extern SCH_SHEET* g_RootSheet;
|
extern SCH_SHEET* g_RootSheet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* With the new connectivity algorithm, many more places than before want to
|
||||||
|
* know what the current sheet is. This was moved here from SCH_EDIT_FRAME
|
||||||
|
* but we could refactor things to get rid of this global.
|
||||||
|
*/
|
||||||
|
extern SCH_SHEET_PATH* g_CurrentSheet; ///< which sheet we are presently working on.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This also wants to live in the eventual SCHEMATIC object
|
||||||
|
*/
|
||||||
|
extern CONNECTION_GRAPH* g_ConnectionGraph;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default line thickness used to draw/plot items having a
|
* Default line thickness used to draw/plot items having a
|
||||||
* default thickness line value (i.e. = 0 ).
|
* default thickness line value (i.e. = 0 ).
|
||||||
|
@ -243,7 +243,7 @@ SCH_COMPONENT* SCH_EDIT_FRAME::Load_Component( const SCHLIB_FILTER* aF
|
|||||||
if( !part )
|
if( !part )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
SCH_COMPONENT* component = new SCH_COMPONENT( *part, libId, m_CurrentSheet,
|
SCH_COMPONENT* component = new SCH_COMPONENT( *part, libId, g_CurrentSheet,
|
||||||
sel.Unit, sel.Convert,
|
sel.Unit, sel.Convert,
|
||||||
GetCrossHairPosition(), true );
|
GetCrossHairPosition(), true );
|
||||||
|
|
||||||
@ -261,7 +261,6 @@ SCH_COMPONENT* SCH_EDIT_FRAME::Load_Component( const SCHLIB_FILTER* aF
|
|||||||
|
|
||||||
MSG_PANEL_ITEMS items;
|
MSG_PANEL_ITEMS items;
|
||||||
|
|
||||||
component->SetCurrentSheetPath( &GetCurrentSheet() );
|
|
||||||
component->GetMsgPanelInfo( m_UserUnits, items );
|
component->GetMsgPanelInfo( m_UserUnits, items );
|
||||||
|
|
||||||
SetMsgPanel( items );
|
SetMsgPanel( items );
|
||||||
@ -333,7 +332,7 @@ void SCH_EDIT_FRAME::OnSelectUnit( wxCommandEvent& aEvent )
|
|||||||
SaveCopyInUndoList( component, UR_CHANGED );
|
SaveCopyInUndoList( component, UR_CHANGED );
|
||||||
|
|
||||||
/* Update the unit number. */
|
/* Update the unit number. */
|
||||||
component->SetUnitSelection( m_CurrentSheet, unit );
|
component->SetUnitSelection( g_CurrentSheet, unit );
|
||||||
component->SetUnit( unit );
|
component->SetUnit( unit );
|
||||||
component->ClearFlags();
|
component->ClearFlags();
|
||||||
component->SetFlags( flags ); // Restore m_Flag modified by SetUnit()
|
component->SetFlags( flags ); // Restore m_Flag modified by SetUnit()
|
||||||
|
@ -79,6 +79,7 @@
|
|||||||
#define HELP_RUN_LIB_EDITOR _( "Create, delete, and edit symbols" )
|
#define HELP_RUN_LIB_EDITOR _( "Create, delete, and edit symbols" )
|
||||||
#define HELP_RUN_LIB_VIEWER _( "Browse symbol libraries" )
|
#define HELP_RUN_LIB_VIEWER _( "Browse symbol libraries" )
|
||||||
#define HELP_GENERATE_BOM _( "Generate bill of materials" )
|
#define HELP_GENERATE_BOM _( "Generate bill of materials" )
|
||||||
|
#define HELP_BUS_MANAGER _( "Manage bus definitions" )
|
||||||
#define HELP_IMPORT_FOOTPRINTS \
|
#define HELP_IMPORT_FOOTPRINTS \
|
||||||
_( "Back-import symbol footprint association fields from the .cmp back import file created by Pcbnew" )
|
_( "Back-import symbol footprint association fields from the .cmp back import file created by Pcbnew" )
|
||||||
|
|
||||||
|
@ -267,7 +267,7 @@ void SCH_EDIT_FRAME::DisplayCurrentSheet()
|
|||||||
SetRepeatItem( NULL );
|
SetRepeatItem( NULL );
|
||||||
ClearMsgPanel();
|
ClearMsgPanel();
|
||||||
|
|
||||||
SCH_SCREEN* screen = m_CurrentSheet->LastScreen();
|
SCH_SCREEN* screen = g_CurrentSheet->LastScreen();
|
||||||
|
|
||||||
// Switch to current sheet,
|
// Switch to current sheet,
|
||||||
// and update the grid size, because it can be modified in latest screen
|
// and update the grid size, because it can be modified in latest screen
|
||||||
@ -275,7 +275,7 @@ void SCH_EDIT_FRAME::DisplayCurrentSheet()
|
|||||||
GetScreen()->SetGrid( m_LastGridSizeId + ID_POPUP_GRID_LEVEL_1000 );
|
GetScreen()->SetGrid( m_LastGridSizeId + ID_POPUP_GRID_LEVEL_1000 );
|
||||||
|
|
||||||
// update the References
|
// update the References
|
||||||
m_CurrentSheet->UpdateAllScreenReferences();
|
g_CurrentSheet->UpdateAllScreenReferences();
|
||||||
SetSheetNumberAndCount();
|
SetSheetNumberAndCount();
|
||||||
m_canvas->SetCanStartBlock( -1 );
|
m_canvas->SetCanStartBlock( -1 );
|
||||||
|
|
||||||
@ -284,12 +284,11 @@ void SCH_EDIT_FRAME::DisplayCurrentSheet()
|
|||||||
Zoom_Automatique( false );
|
Zoom_Automatique( false );
|
||||||
screen->m_Initialized = true;
|
screen->m_Initialized = true;
|
||||||
|
|
||||||
// Ensure the schematic is fully segmented on first display
|
// TODO(JE) should be able to just recalculate the current sheet path
|
||||||
BreakSegmentsOnJunctions();
|
// RecalculateConnections() handles cleanup and dangling ends tests
|
||||||
SchematicCleanUp( true );
|
RecalculateConnections();
|
||||||
screen->ClearUndoORRedoList( screen->m_UndoList, 1 );
|
|
||||||
|
|
||||||
screen->TestDanglingEnds();
|
screen->ClearUndoORRedoList( screen->m_UndoList, 1 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -35,42 +35,43 @@
|
|||||||
#include <erc.h>
|
#include <erc.h>
|
||||||
|
|
||||||
#include <netlist_object.h>
|
#include <netlist_object.h>
|
||||||
|
#include <sch_component.h>
|
||||||
|
#include <sch_sheet.h>
|
||||||
|
|
||||||
// List of items having the highlight option modified, therefore need to be redrawn
|
// List of items having the highlight option modified, therefore need to be redrawn
|
||||||
|
|
||||||
|
// TODO(JE) Probably use netcode rather than connection name here eventually
|
||||||
bool SCH_EDIT_FRAME::HighlightConnectionAtPosition( wxPoint aPosition )
|
bool SCH_EDIT_FRAME::HighlightConnectionAtPosition( wxPoint aPosition )
|
||||||
{
|
{
|
||||||
std::vector<EDA_ITEM*> itemsToRedraw;
|
std::vector<EDA_ITEM*> itemsToRedraw;
|
||||||
m_SelectedNetName = "";
|
m_SelectedNetName = "";
|
||||||
bool buildNetlistOk = false;
|
bool buildNetlistOk = false;
|
||||||
|
|
||||||
|
SetStatusText( "" );
|
||||||
|
|
||||||
// find which connected item is selected
|
// find which connected item is selected
|
||||||
EDA_ITEMS nodeList;
|
EDA_ITEMS nodeList;
|
||||||
wxPoint gridPosition = GetGridPosition( aPosition );
|
wxPoint gridPosition = GetGridPosition( aPosition );
|
||||||
|
|
||||||
if( GetScreen()->GetNode( gridPosition,nodeList ) )
|
if( GetScreen()->GetNode( gridPosition, nodeList ) )
|
||||||
{
|
{
|
||||||
if( TestDuplicateSheetNames( false ) > 0 )
|
if( TestDuplicateSheetNames( false ) > 0 )
|
||||||
wxMessageBox( _( "Error: duplicate sub-sheet names found in current sheet. Fix it" ) );
|
wxMessageBox( _( "Error: duplicate sub-sheet names found in current sheet. Fix it" ) );
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Build netlist info to get the proper netnames of connected items
|
if( auto item = dynamic_cast<SCH_ITEM*>( nodeList[0] ) )
|
||||||
std::unique_ptr<NETLIST_OBJECT_LIST> objectsConnectedList( BuildNetListBase() );
|
|
||||||
buildNetlistOk = true;
|
|
||||||
|
|
||||||
for( auto obj : *objectsConnectedList )
|
|
||||||
{
|
{
|
||||||
if( obj->m_SheetPath == *m_CurrentSheet && obj->m_Comp == nodeList[0] )
|
if( item->Connection( *g_CurrentSheet ) )
|
||||||
{
|
{
|
||||||
m_SelectedNetName = obj->GetNetName( true );
|
m_SelectedNetName = item->Connection( *g_CurrentSheet )->Name();
|
||||||
break;
|
SetStatusText( _( "Highlighted net: " ) + m_SelectedNetName );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SendCrossProbeNetName( m_SelectedNetName );
|
SendCrossProbeNetName( m_SelectedNetName );
|
||||||
SetStatusText( "selected net: " + m_SelectedNetName );
|
SetStatusText( _( "Selected net: " ) + m_SelectedNetName );
|
||||||
SetCurrentSheetHighlightFlags( &itemsToRedraw );
|
SetCurrentSheetHighlightFlags( &itemsToRedraw );
|
||||||
|
|
||||||
// Be sure hightlight change will be redrawn
|
// Be sure hightlight change will be redrawn
|
||||||
@ -87,7 +88,7 @@ bool SCH_EDIT_FRAME::HighlightConnectionAtPosition( wxPoint aPosition )
|
|||||||
|
|
||||||
bool SCH_EDIT_FRAME::SetCurrentSheetHighlightFlags( std::vector<EDA_ITEM*>* aItemsToRedrawList )
|
bool SCH_EDIT_FRAME::SetCurrentSheetHighlightFlags( std::vector<EDA_ITEM*>* aItemsToRedrawList )
|
||||||
{
|
{
|
||||||
SCH_SCREEN* screen = m_CurrentSheet->LastScreen();
|
SCH_SCREEN* screen = g_CurrentSheet->LastScreen();
|
||||||
|
|
||||||
if( !screen )
|
if( !screen )
|
||||||
return true;
|
return true;
|
||||||
@ -95,20 +96,33 @@ bool SCH_EDIT_FRAME::SetCurrentSheetHighlightFlags( std::vector<EDA_ITEM*>* aIte
|
|||||||
// Disable highlight flag on all items in the current screen
|
// Disable highlight flag on all items in the current screen
|
||||||
for( SCH_ITEM* ptr = screen->GetDrawItems(); ptr; ptr = ptr->Next() )
|
for( SCH_ITEM* ptr = screen->GetDrawItems(); ptr; ptr = ptr->Next() )
|
||||||
{
|
{
|
||||||
if( ptr->GetState( BRIGHTENED ) && aItemsToRedrawList )
|
auto conn = ptr->Connection( *g_CurrentSheet );
|
||||||
|
bool bright = ptr->GetState( BRIGHTENED );
|
||||||
|
|
||||||
|
if( bright && aItemsToRedrawList )
|
||||||
aItemsToRedrawList->push_back( ptr );
|
aItemsToRedrawList->push_back( ptr );
|
||||||
|
|
||||||
ptr->SetState( BRIGHTENED, false );
|
ptr->SetState( BRIGHTENED, ( conn && conn->Name() == m_SelectedNetName ) );
|
||||||
|
|
||||||
|
if( !bright && ptr->GetState( BRIGHTENED ) && aItemsToRedrawList )
|
||||||
|
aItemsToRedrawList->push_back( ptr );
|
||||||
|
|
||||||
if( ptr->Type() == SCH_SHEET_T )
|
if( ptr->Type() == SCH_SHEET_T )
|
||||||
{
|
{
|
||||||
for( SCH_SHEET_PIN& pin : static_cast<SCH_SHEET*>( ptr )->GetPins() )
|
for( SCH_SHEET_PIN& pin : static_cast<SCH_SHEET*>( ptr )->GetPins() )
|
||||||
{
|
{
|
||||||
if( ptr->GetState( BRIGHTENED ) && aItemsToRedrawList )
|
auto pin_conn = pin.Connection( *g_CurrentSheet );
|
||||||
|
|
||||||
|
bright = pin.GetState( BRIGHTENED );
|
||||||
|
|
||||||
|
if( bright && aItemsToRedrawList )
|
||||||
aItemsToRedrawList->push_back( &pin );
|
aItemsToRedrawList->push_back( &pin );
|
||||||
|
|
||||||
pin.SetState( BRIGHTENED, false );
|
pin.SetState( BRIGHTENED, ( pin_conn &&
|
||||||
|
pin_conn->Name() == m_SelectedNetName ) );
|
||||||
|
|
||||||
|
if( !bright && pin.GetState( BRIGHTENED ) && aItemsToRedrawList )
|
||||||
|
aItemsToRedrawList->push_back( &pin );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -119,37 +133,5 @@ bool SCH_EDIT_FRAME::SetCurrentSheetHighlightFlags( std::vector<EDA_ITEM*>* aIte
|
|||||||
if( TestDuplicateSheetNames( false ) > 0 )
|
if( TestDuplicateSheetNames( false ) > 0 )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Build netlist info to get the proper netnames
|
|
||||||
std::unique_ptr<NETLIST_OBJECT_LIST> objectsConnectedList( BuildNetListBase( false ) );
|
|
||||||
|
|
||||||
// highlight the items belonging to this net
|
|
||||||
for( auto obj1 : *objectsConnectedList )
|
|
||||||
{
|
|
||||||
if( obj1->m_SheetPath == *m_CurrentSheet &&
|
|
||||||
obj1->GetNetName( true ) == m_SelectedNetName && obj1->m_Comp )
|
|
||||||
{
|
|
||||||
obj1->m_Comp->SetState( BRIGHTENED, true );
|
|
||||||
|
|
||||||
if( aItemsToRedrawList )
|
|
||||||
aItemsToRedrawList->push_back( obj1->m_Comp );
|
|
||||||
|
|
||||||
//if a bus is associated with this net highlight it as well
|
|
||||||
if( obj1->m_BusNetCode )
|
|
||||||
{
|
|
||||||
for( auto obj2 : *objectsConnectedList )
|
|
||||||
{
|
|
||||||
if( obj2 && obj2->m_Comp && obj2->m_SheetPath == *m_CurrentSheet &&
|
|
||||||
obj1->m_BusNetCode == obj2->m_BusNetCode )
|
|
||||||
{
|
|
||||||
if( aItemsToRedrawList )
|
|
||||||
aItemsToRedrawList->push_back( obj2->m_Comp );
|
|
||||||
|
|
||||||
obj2->m_Comp->SetState( BRIGHTENED, true );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -220,6 +220,9 @@ static EDA_HOTKEY HkUpdatePcbFromSch( _HKI( "Update PCB from Schematic" ), HK_UP
|
|||||||
static EDA_HOTKEY HkHighlightConnection( _HKI( "Highlight Connection" ), ID_HOTKEY_HIGHLIGHT,
|
static EDA_HOTKEY HkHighlightConnection( _HKI( "Highlight Connection" ), ID_HOTKEY_HIGHLIGHT,
|
||||||
'B' + GR_KB_CTRL );
|
'B' + GR_KB_CTRL );
|
||||||
|
|
||||||
|
static EDA_HOTKEY HkUnfoldBus( _HKI( "Unfold Bus" ), HK_UNFOLD_BUS, 'D',
|
||||||
|
ID_SCH_UNFOLD_BUS );
|
||||||
|
|
||||||
// Common: hotkeys_basic.h
|
// Common: hotkeys_basic.h
|
||||||
static EDA_HOTKEY HkNew( _HKI( "New" ), HK_NEW, GR_KB_CTRL + 'N', (int) wxID_NEW );
|
static EDA_HOTKEY HkNew( _HKI( "New" ), HK_NEW, GR_KB_CTRL + 'N', (int) wxID_NEW );
|
||||||
static EDA_HOTKEY HkOpen( _HKI( "Open" ), HK_OPEN, GR_KB_CTRL + 'O', (int) wxID_OPEN );
|
static EDA_HOTKEY HkOpen( _HKI( "Open" ), HK_OPEN, GR_KB_CTRL + 'O', (int) wxID_OPEN );
|
||||||
@ -332,6 +335,7 @@ static EDA_HOTKEY* schematic_Hotkey_List[] =
|
|||||||
&HkLeaveSheet,
|
&HkLeaveSheet,
|
||||||
&HkDeleteNode,
|
&HkDeleteNode,
|
||||||
&HkHighlightConnection,
|
&HkHighlightConnection,
|
||||||
|
&HkUnfoldBus,
|
||||||
&HkCanvasCairo,
|
&HkCanvasCairo,
|
||||||
&HkCanvasOpenGL,
|
&HkCanvasOpenGL,
|
||||||
NULL
|
NULL
|
||||||
@ -639,6 +643,7 @@ bool SCH_EDIT_FRAME::OnHotKey( wxDC* aDC, int aHotKey, const wxPoint& aPosition,
|
|||||||
case HK_ROTATE: // Rotate schematic item.
|
case HK_ROTATE: // Rotate schematic item.
|
||||||
case HK_EDIT_COMPONENT_WITH_LIBEDIT: // Call Libedit and load the current component
|
case HK_EDIT_COMPONENT_WITH_LIBEDIT: // Call Libedit and load the current component
|
||||||
case HK_AUTOPLACE_FIELDS: // Autoplace all fields around component
|
case HK_AUTOPLACE_FIELDS: // Autoplace all fields around component
|
||||||
|
case HK_UNFOLD_BUS: // Unfold a bus wire
|
||||||
case HK_CANVAS_CAIRO:
|
case HK_CANVAS_CAIRO:
|
||||||
case HK_CANVAS_OPENGL:
|
case HK_CANVAS_OPENGL:
|
||||||
{
|
{
|
||||||
|
@ -80,6 +80,7 @@ enum hotkey_id_commnand {
|
|||||||
HK_AUTOPLACE_FIELDS,
|
HK_AUTOPLACE_FIELDS,
|
||||||
HK_UPDATE_PCB_FROM_SCH,
|
HK_UPDATE_PCB_FROM_SCH,
|
||||||
HK_SELECT_ITEMS_ON_PCB,
|
HK_SELECT_ITEMS_ON_PCB,
|
||||||
|
HK_UNFOLD_BUS,
|
||||||
HK_CANVAS_OPENGL,
|
HK_CANVAS_OPENGL,
|
||||||
HK_CANVAS_CAIRO,
|
HK_CANVAS_CAIRO,
|
||||||
};
|
};
|
||||||
|
@ -81,6 +81,9 @@ int InvokeDialogPrintUsingPrinter( SCH_EDIT_FRAME* aCaller );
|
|||||||
/// DIALOG_BOM::ShowModal() returns.
|
/// DIALOG_BOM::ShowModal() returns.
|
||||||
int InvokeDialogCreateBOM( SCH_EDIT_FRAME* aCaller );
|
int InvokeDialogCreateBOM( SCH_EDIT_FRAME* aCaller );
|
||||||
|
|
||||||
|
/// Create and show DIALOG_BUS_MANAGER
|
||||||
|
void InvokeDialogBusManager( SCH_EDIT_FRAME* aCaller );
|
||||||
|
|
||||||
/// Update symbol fields
|
/// Update symbol fields
|
||||||
int InvokeDialogUpdateFields( SCH_EDIT_FRAME* aCaller,
|
int InvokeDialogUpdateFields( SCH_EDIT_FRAME* aCaller,
|
||||||
const std::list<SCH_COMPONENT*> aComponents, bool aCreateUndoEntry );
|
const std::list<SCH_COMPONENT*> aComponents, bool aCreateUndoEntry );
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include <eda_rect.h>
|
#include <eda_rect.h>
|
||||||
#include <transform.h>
|
#include <transform.h>
|
||||||
#include <gr_basic.h>
|
#include <gr_basic.h>
|
||||||
|
#include <sch_connection.h>
|
||||||
|
|
||||||
|
|
||||||
class LINE_READER;
|
class LINE_READER;
|
||||||
|
@ -47,6 +47,7 @@
|
|||||||
#include <lib_pin.h>
|
#include <lib_pin.h>
|
||||||
#include <transform.h>
|
#include <transform.h>
|
||||||
#include <sch_component.h>
|
#include <sch_component.h>
|
||||||
|
#include <sch_sheet_path.h>
|
||||||
#include <trace_helpers.h>
|
#include <trace_helpers.h>
|
||||||
|
|
||||||
|
|
||||||
@ -1770,6 +1771,19 @@ void LIB_PIN::GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >
|
|||||||
aList.push_back( MSG_PANEL_ITEM( aComponent->GetField( REFERENCE )->GetShownText(),
|
aList.push_back( MSG_PANEL_ITEM( aComponent->GetField( REFERENCE )->GetShownText(),
|
||||||
aComponent->GetField( VALUE )->GetShownText(),
|
aComponent->GetField( VALUE )->GetShownText(),
|
||||||
DARKCYAN ) );
|
DARKCYAN ) );
|
||||||
|
|
||||||
|
#if defined(DEBUG)
|
||||||
|
|
||||||
|
if( auto pin_connection = aComponent->GetConnectionForPin( this ) )
|
||||||
|
{
|
||||||
|
auto conn = pin_connection->Connection( *g_CurrentSheet );
|
||||||
|
|
||||||
|
wxASSERT( conn );
|
||||||
|
|
||||||
|
conn->AppendDebugInfoToMsgPanel( aList );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
const EDA_RECT LIB_PIN::GetBoundingBox( bool aIncludeInvisibles ) const
|
const EDA_RECT LIB_PIN::GetBoundingBox( bool aIncludeInvisibles ) const
|
||||||
|
@ -571,6 +571,12 @@ void prepareToolsMenu( wxMenu* aParentMenu )
|
|||||||
HELP_GENERATE_BOM,
|
HELP_GENERATE_BOM,
|
||||||
KiBitmap( bom_xpm ) );
|
KiBitmap( bom_xpm ) );
|
||||||
|
|
||||||
|
AddMenuItem( aParentMenu,
|
||||||
|
ID_BUS_MANAGER,
|
||||||
|
_( "Bus &Definitions" ),
|
||||||
|
HELP_BUS_MANAGER,
|
||||||
|
KiBitmap( bom_xpm ) ); // TODO(JE) new icon?
|
||||||
|
|
||||||
aParentMenu->AppendSeparator();
|
aParentMenu->AppendSeparator();
|
||||||
|
|
||||||
// Run CvPcb
|
// Run CvPcb
|
||||||
|
@ -26,6 +26,9 @@
|
|||||||
#include "netlist_exporter_generic.h"
|
#include "netlist_exporter_generic.h"
|
||||||
|
|
||||||
#include <build_version.h>
|
#include <build_version.h>
|
||||||
|
#include <sch_base_frame.h>
|
||||||
|
#include <class_library.h>
|
||||||
|
#include <connection_graph.h>
|
||||||
#include <refdes_utils.h>
|
#include <refdes_utils.h>
|
||||||
|
|
||||||
#include <class_library.h>
|
#include <class_library.h>
|
||||||
@ -499,6 +502,55 @@ XNODE* NETLIST_EXPORTER_GENERIC::makeListOfNets()
|
|||||||
|
|
||||||
m_LibParts.clear(); // must call this function before using m_LibParts.
|
m_LibParts.clear(); // must call this function before using m_LibParts.
|
||||||
|
|
||||||
|
if( m_use_graph && m_graph )
|
||||||
|
{
|
||||||
|
for( auto it : m_graph->m_net_code_to_subgraphs_map )
|
||||||
|
{
|
||||||
|
bool added = false;
|
||||||
|
|
||||||
|
auto code = it.first;
|
||||||
|
auto subgraphs = it.second;
|
||||||
|
auto net_name = subgraphs[0]->GetNetName();
|
||||||
|
|
||||||
|
XNODE* xnode;
|
||||||
|
|
||||||
|
for( auto subgraph : subgraphs )
|
||||||
|
{
|
||||||
|
auto sheet = subgraph->m_sheet;
|
||||||
|
|
||||||
|
for( auto item : subgraph->m_items )
|
||||||
|
{
|
||||||
|
if( item->Type() == SCH_PIN_CONNECTION_T )
|
||||||
|
{
|
||||||
|
auto pc = static_cast<SCH_PIN_CONNECTION*>( item );
|
||||||
|
|
||||||
|
// Skip power symbols
|
||||||
|
if( (LIB_PART*)( pc->m_pin->GetParent() )->IsPower() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( !added )
|
||||||
|
{
|
||||||
|
xnets->AddChild( xnet = node( "net" ) );
|
||||||
|
netCodeTxt.Printf( "%d", code );
|
||||||
|
xnet->AddAttribute( "code", netCodeTxt );
|
||||||
|
xnet->AddAttribute( "name", net_name );
|
||||||
|
|
||||||
|
added = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto refText = pc->m_comp->GetRef( &sheet );
|
||||||
|
auto pinText = pc->m_pin->GetNumber();
|
||||||
|
|
||||||
|
xnet->AddChild( xnode = node( "node" ) );
|
||||||
|
xnode->AddAttribute( "ref", refText );
|
||||||
|
xnode->AddAttribute( "pin", pinText );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
for( unsigned ii = 0; ii < m_masterList->size(); ii++ )
|
for( unsigned ii = 0; ii < m_masterList->size(); ii++ )
|
||||||
{
|
{
|
||||||
NETLIST_OBJECT* nitem = m_masterList->GetItem( ii );
|
NETLIST_OBJECT* nitem = m_masterList->GetItem( ii );
|
||||||
@ -538,6 +590,7 @@ XNODE* NETLIST_EXPORTER_GENERIC::makeListOfNets()
|
|||||||
xnode->AddAttribute( "ref", ref );
|
xnode->AddAttribute( "ref", ref );
|
||||||
xnode->AddAttribute( "pin", nitem->GetPinNumText() );
|
xnode->AddAttribute( "pin", nitem->GetPinNumText() );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return xnets;
|
return xnets;
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
#include <sch_edit_frame.h>
|
#include <sch_edit_frame.h>
|
||||||
|
|
||||||
|
class CONNECTION_GRAPH;
|
||||||
class SYMBOL_LIB_TABLE;
|
class SYMBOL_LIB_TABLE;
|
||||||
|
|
||||||
#define GENERIC_INTERMEDIATE_NETLIST_EXT wxT( "xml" )
|
#define GENERIC_INTERMEDIATE_NETLIST_EXT wxT( "xml" )
|
||||||
@ -63,10 +64,20 @@ private:
|
|||||||
|
|
||||||
SYMBOL_LIB_TABLE* m_libTable;
|
SYMBOL_LIB_TABLE* m_libTable;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
CONNECTION_GRAPH* m_graph;
|
||||||
|
|
||||||
|
// TODO(JE) Remove if not needed
|
||||||
|
bool m_use_graph;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NETLIST_EXPORTER_GENERIC( SCH_EDIT_FRAME* aFrame, NETLIST_OBJECT_LIST* aMasterList ) :
|
NETLIST_EXPORTER_GENERIC( SCH_EDIT_FRAME* aFrame,
|
||||||
|
NETLIST_OBJECT_LIST* aMasterList,
|
||||||
|
CONNECTION_GRAPH* aGraph = nullptr ) :
|
||||||
NETLIST_EXPORTER( aMasterList ),
|
NETLIST_EXPORTER( aMasterList ),
|
||||||
m_libTable( aFrame->Prj().SchSymbolLibTable() )
|
m_libTable( aFrame->Prj().SchSymbolLibTable() ),
|
||||||
|
m_graph( aGraph ),
|
||||||
|
m_use_graph( true )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,15 +24,22 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <fctsys.h>
|
#include <fctsys.h>
|
||||||
#include <build_version.h>
|
#include <build_version.h>
|
||||||
#include <confirm.h>
|
#include <confirm.h>
|
||||||
|
|
||||||
#include <sch_edit_frame.h>
|
#include <sch_edit_frame.h>
|
||||||
|
#include <xnode.h>
|
||||||
|
#include <connection_graph.h>
|
||||||
#include "netlist_exporter_kicad.h"
|
#include "netlist_exporter_kicad.h"
|
||||||
|
|
||||||
bool NETLIST_EXPORTER_KICAD::WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions )
|
bool NETLIST_EXPORTER_KICAD::WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions )
|
||||||
{
|
{
|
||||||
|
wxASSERT( m_graph );
|
||||||
|
|
||||||
|
m_use_graph = true;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
FILE_OUTPUTFORMATTER formatter( aOutFileName );
|
FILE_OUTPUTFORMATTER formatter( aOutFileName );
|
||||||
@ -45,6 +52,130 @@ bool NETLIST_EXPORTER_KICAD::WriteNetlist( const wxString& aOutFileName, unsigne
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Temporary QC measure:
|
||||||
|
* Generate the netlist again using the old algorithm and compare.
|
||||||
|
* In theory, if the schematic does not use any of the new bus techniques
|
||||||
|
* (bus aliases, bus groups, etc) they should match. If not, we can throw
|
||||||
|
* a warning and generate some debug output to fix the new netlister.
|
||||||
|
*
|
||||||
|
* This whole block can be removed once we are confident in the new code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if( !m_graph->UsesNewBusFeatures() )
|
||||||
|
{
|
||||||
|
m_use_graph = false;
|
||||||
|
auto old_nets = makeListOfNets();
|
||||||
|
|
||||||
|
bool different = false;
|
||||||
|
|
||||||
|
for( auto it : m_graph->m_net_code_to_subgraphs_map )
|
||||||
|
{
|
||||||
|
// auto code = it.first;
|
||||||
|
auto subgraphs = it.second;
|
||||||
|
auto net_name = subgraphs[0]->GetNetName();
|
||||||
|
|
||||||
|
std::set<wxString> net_pins;
|
||||||
|
|
||||||
|
for( auto subgraph : subgraphs )
|
||||||
|
{
|
||||||
|
auto sheet = subgraph->m_sheet;
|
||||||
|
|
||||||
|
for( auto item : subgraph->m_items )
|
||||||
|
{
|
||||||
|
if( item->Type() == SCH_PIN_CONNECTION_T )
|
||||||
|
{
|
||||||
|
auto pc = static_cast<SCH_PIN_CONNECTION*>( item );
|
||||||
|
|
||||||
|
if( pc->m_pin->IsPowerConnection() ||
|
||||||
|
(LIB_PART*)( pc->m_pin->GetParent() )->IsPower() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
wxString refText = pc->m_comp->GetRef( &sheet );
|
||||||
|
wxString pinText = pc->m_pin->GetNumber();
|
||||||
|
|
||||||
|
net_pins.insert( refText + "-" + pinText );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
// Yes this is slow, but it's a temporary debugging thing.
|
||||||
|
for( auto kid = old_nets->GetChildren(); kid; kid = kid->GetNext() )
|
||||||
|
{
|
||||||
|
for( auto attr = kid->GetAttributes(); attr; attr = attr->GetNext() )
|
||||||
|
{
|
||||||
|
if( attr->GetName() == "name" && attr->GetValue() == net_name )
|
||||||
|
{
|
||||||
|
found = true;
|
||||||
|
|
||||||
|
// Check members of this net
|
||||||
|
std::set<wxString> old_net_pins;
|
||||||
|
|
||||||
|
for( auto pin_node = kid->GetChildren();
|
||||||
|
pin_node; pin_node = pin_node->GetNext() )
|
||||||
|
{
|
||||||
|
wxString ref, pin;
|
||||||
|
|
||||||
|
for( auto pin_attr = pin_node->GetAttributes();
|
||||||
|
pin_attr; pin_attr = pin_attr->GetNext() )
|
||||||
|
{
|
||||||
|
if( pin_attr->GetName() == "ref" )
|
||||||
|
ref = pin_attr->GetValue();
|
||||||
|
|
||||||
|
if( pin_attr->GetName() == "pin" )
|
||||||
|
pin = pin_attr->GetValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
old_net_pins.insert( ref + "-" + pin );
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<wxString> difference( std::max( net_pins.size(),
|
||||||
|
old_net_pins.size() ) );
|
||||||
|
|
||||||
|
auto end = std::set_symmetric_difference( net_pins.begin(),
|
||||||
|
net_pins.end(),
|
||||||
|
old_net_pins.begin(),
|
||||||
|
old_net_pins.end(),
|
||||||
|
difference.begin() );
|
||||||
|
|
||||||
|
difference.resize( end - difference.begin() );
|
||||||
|
|
||||||
|
if( difference.size() > 0 )
|
||||||
|
{
|
||||||
|
different = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !found )
|
||||||
|
{
|
||||||
|
different = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( different )
|
||||||
|
{
|
||||||
|
wxLogDebug( "NOTE: New netlist algorithm is inconsistent with old! "
|
||||||
|
"Please contact Jon Evans <jon@craftyjon.com> "
|
||||||
|
"to help debug this issue" );
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FILE_OUTPUTFORMATTER formatter( aOutFileName + ".old_algo" );
|
||||||
|
Format( &formatter, GNL_ALL );
|
||||||
|
}
|
||||||
|
|
||||||
|
catch( const IO_ERROR& ioe )
|
||||||
|
{
|
||||||
|
DisplayError( NULL, ioe.What() );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,8 +38,10 @@ class OUTPUTFORMATTER;
|
|||||||
class NETLIST_EXPORTER_KICAD : public NETLIST_EXPORTER_GENERIC
|
class NETLIST_EXPORTER_KICAD : public NETLIST_EXPORTER_GENERIC
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NETLIST_EXPORTER_KICAD( SCH_EDIT_FRAME* aFrame, NETLIST_OBJECT_LIST* aMasterList ) :
|
NETLIST_EXPORTER_KICAD( SCH_EDIT_FRAME* aFrame,
|
||||||
NETLIST_EXPORTER_GENERIC( aFrame, aMasterList )
|
NETLIST_OBJECT_LIST* aMasterList,
|
||||||
|
CONNECTION_GRAPH* aGraph = nullptr ) :
|
||||||
|
NETLIST_EXPORTER_GENERIC( aFrame, aMasterList, aGraph )
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -61,7 +61,8 @@ bool SCH_EDIT_FRAME::WriteNetListFile( NETLIST_OBJECT_LIST* aConnectedItemsList,
|
|||||||
switch( aFormat )
|
switch( aFormat )
|
||||||
{
|
{
|
||||||
case NET_TYPE_PCBNEW:
|
case NET_TYPE_PCBNEW:
|
||||||
helper = new NETLIST_EXPORTER_KICAD( this, aConnectedItemsList );
|
helper = new NETLIST_EXPORTER_KICAD( this, aConnectedItemsList,
|
||||||
|
g_ConnectionGraph );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NET_TYPE_ORCADPCB2:
|
case NET_TYPE_ORCADPCB2:
|
||||||
@ -82,7 +83,8 @@ bool SCH_EDIT_FRAME::WriteNetListFile( NETLIST_OBJECT_LIST* aConnectedItemsList,
|
|||||||
tmpFile.SetExt( GENERIC_INTERMEDIATE_NETLIST_EXT );
|
tmpFile.SetExt( GENERIC_INTERMEDIATE_NETLIST_EXT );
|
||||||
fileName = tmpFile.GetFullPath();
|
fileName = tmpFile.GetFullPath();
|
||||||
|
|
||||||
helper = new NETLIST_EXPORTER_GENERIC( this, aConnectedItemsList );
|
helper = new NETLIST_EXPORTER_GENERIC( this, aConnectedItemsList,
|
||||||
|
g_ConnectionGraph );
|
||||||
executeCommandLine = true;
|
executeCommandLine = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -30,30 +30,12 @@
|
|||||||
|
|
||||||
#include <fctsys.h>
|
#include <fctsys.h>
|
||||||
#include <macros.h>
|
#include <macros.h>
|
||||||
#include <sch_edit_frame.h>
|
#include <list>
|
||||||
|
|
||||||
#include <sch_component.h>
|
#include <sch_component.h>
|
||||||
|
#include <sch_connection.h>
|
||||||
#include <netlist_object.h>
|
#include <netlist_object.h>
|
||||||
|
#include <sch_edit_frame.h>
|
||||||
#include <wx/regex.h>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The regular expression string for label bus notation. Valid bus labels are defined as
|
|
||||||
* one or more non-whitespace characters from the beginning of the string followed by the
|
|
||||||
* bus notation [nn...mm] with no characters after the closing bracket.
|
|
||||||
*/
|
|
||||||
static wxRegEx busLabelRe( wxT( "^([^[:space:]]+)(\\[[\\d]+\\.+[\\d]+\\])$" ), wxRE_ADVANCED );
|
|
||||||
|
|
||||||
|
|
||||||
bool IsBusLabel( const wxString& aLabel )
|
|
||||||
{
|
|
||||||
wxCHECK_MSG( busLabelRe.IsValid(), false,
|
|
||||||
wxT( "Invalid regular expression in IsBusLabel()." ) );
|
|
||||||
|
|
||||||
return busLabelRe.Matches( aLabel );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
|
|
||||||
@ -240,7 +222,8 @@ bool NETLIST_OBJECT::IsLabelConnected( NETLIST_OBJECT* aNetItem )
|
|||||||
|
|
||||||
void NETLIST_OBJECT::ConvertBusToNetListItems( NETLIST_OBJECT_LIST& aNetListItems )
|
void NETLIST_OBJECT::ConvertBusToNetListItems( NETLIST_OBJECT_LIST& aNetListItems )
|
||||||
{
|
{
|
||||||
wxCHECK_RET( IsBusLabel( m_Label ),
|
SCH_CONNECTION conn;
|
||||||
|
wxCHECK_RET( conn.IsBusLabel( m_Label ),
|
||||||
wxT( "<" ) + m_Label + wxT( "> is not a valid bus label." ) );
|
wxT( "<" ) + m_Label + wxT( "> is not a valid bus label." ) );
|
||||||
|
|
||||||
if( m_Type == NET_HIERLABEL )
|
if( m_Type == NET_HIERLABEL )
|
||||||
@ -254,61 +237,109 @@ void NETLIST_OBJECT::ConvertBusToNetListItems( NETLIST_OBJECT_LIST& aNetListItem
|
|||||||
else
|
else
|
||||||
wxCHECK_RET( false, wxT( "Net list object type is not valid." ) );
|
wxCHECK_RET( false, wxT( "Net list object type is not valid." ) );
|
||||||
|
|
||||||
unsigned i;
|
// NOTE: all netlist objects generated from a single bus definition need to have different
|
||||||
wxString tmp, busName, busNumber;
|
// member codes set. For bus vectors, the member code matches the vector index, but for
|
||||||
long begin, end, member;
|
// bus groups (including with nested vectors) the code is something arbitrary.
|
||||||
|
long member_offset = 0;
|
||||||
|
|
||||||
busName = busLabelRe.GetMatch( m_Label, 1 );
|
auto alias = SCH_SCREEN::GetBusAlias( m_Label );
|
||||||
busNumber = busLabelRe.GetMatch( m_Label, 2 );
|
if( alias || conn.IsBusGroupLabel( m_Label ) )
|
||||||
|
|
||||||
/* Search for '[' because a bus label is like "busname[nn..mm]" */
|
|
||||||
i = busNumber.Find( '[' );
|
|
||||||
i++;
|
|
||||||
|
|
||||||
while( i < busNumber.Len() && busNumber[i] != '.' )
|
|
||||||
{
|
{
|
||||||
tmp.Append( busNumber[i] );
|
wxString group_name;
|
||||||
i++;
|
bool self_set = false;
|
||||||
|
std::vector<wxString> bus_contents_vec;
|
||||||
|
|
||||||
|
if( alias )
|
||||||
|
{
|
||||||
|
bus_contents_vec = alias->Members();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wxCHECK_RET( conn.ParseBusGroup( m_Label, &group_name, bus_contents_vec ),
|
||||||
|
_( "Failed to parse bus group " ) + m_Label );
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp.ToLong( &begin );
|
// For named bus groups, like "USB{DP DM}"
|
||||||
|
auto group_prefix = ( group_name != "" ) ? ( group_name + "." ) : "";
|
||||||
|
|
||||||
while( i < busNumber.Len() && busNumber[i] == '.' )
|
std::list<wxString> bus_contents( bus_contents_vec.begin(),
|
||||||
i++;
|
bus_contents_vec.end() );
|
||||||
|
|
||||||
tmp.Empty();
|
for( auto bus_member : bus_contents )
|
||||||
|
|
||||||
while( i < busNumber.Len() && busNumber[i] != ']' )
|
|
||||||
{
|
{
|
||||||
tmp.Append( busNumber[i] );
|
// Nested bus vector inside a bus group
|
||||||
i++;
|
if( conn.IsBusVectorLabel( bus_member ) )
|
||||||
|
{
|
||||||
|
wxString prefix;
|
||||||
|
long begin, end;
|
||||||
|
|
||||||
|
conn.ParseBusVector( bus_member, &prefix, &begin, &end );
|
||||||
|
prefix = group_prefix + prefix;
|
||||||
|
|
||||||
|
if( !self_set )
|
||||||
|
{
|
||||||
|
m_Label = prefix;
|
||||||
|
m_Label << begin;
|
||||||
|
m_Member = ( begin++ ) + ( member_offset++ );
|
||||||
|
|
||||||
|
self_set = true;
|
||||||
|
begin++;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp.ToLong( &end );
|
fillBusVector( aNetListItems, prefix, begin, end, member_offset );
|
||||||
|
member_offset += std::abs( end - begin );
|
||||||
if( begin < 0 )
|
}
|
||||||
begin = 0;
|
else if( auto nested_alias = SCH_SCREEN::GetBusAlias( bus_member ) )
|
||||||
|
|
||||||
if( end < 0 )
|
|
||||||
end = 0;
|
|
||||||
|
|
||||||
if( begin > end )
|
|
||||||
std::swap( begin, end );
|
|
||||||
|
|
||||||
member = begin;
|
|
||||||
tmp = busName;
|
|
||||||
tmp << member;
|
|
||||||
m_Label = tmp;
|
|
||||||
m_Member = member;
|
|
||||||
|
|
||||||
for( member++; member <= end; member++ )
|
|
||||||
{
|
{
|
||||||
NETLIST_OBJECT* item = new NETLIST_OBJECT( *this );
|
// Nested alias inside a group
|
||||||
|
for( auto alias_member : nested_alias->Members() )
|
||||||
|
{
|
||||||
|
bus_contents.push_back( alias_member );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( !self_set )
|
||||||
|
{
|
||||||
|
m_Label = group_prefix + bus_member;
|
||||||
|
m_Member = member_offset++;
|
||||||
|
self_set = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto item = new NETLIST_OBJECT( *this );
|
||||||
|
item->m_Label = group_prefix + bus_member;
|
||||||
|
item->m_Member = member_offset++;
|
||||||
|
aNetListItems.push_back( item );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Plain bus vector
|
||||||
|
wxString prefix;
|
||||||
|
long begin, end;
|
||||||
|
|
||||||
// Conversion of bus label to the root name + the current member id.
|
conn.ParseBusVector( m_Label, &prefix, &begin, &end );
|
||||||
tmp = busName;
|
|
||||||
tmp << member;
|
m_Label = prefix;
|
||||||
item->m_Label = tmp;
|
m_Label << begin;
|
||||||
|
m_Member = begin;
|
||||||
|
|
||||||
|
fillBusVector( aNetListItems, prefix, begin + 1, end, 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NETLIST_OBJECT::fillBusVector( NETLIST_OBJECT_LIST& aNetListItems,
|
||||||
|
wxString aName, long aBegin, long aEnd, long aOffset )
|
||||||
|
{
|
||||||
|
for( long member = aBegin; member <= aEnd; member++ )
|
||||||
|
{
|
||||||
|
auto item = new NETLIST_OBJECT( *this );
|
||||||
|
|
||||||
|
item->m_Label = aName;
|
||||||
|
item->m_Label << member;
|
||||||
item->m_Member = member;
|
item->m_Member = member;
|
||||||
|
|
||||||
aNetListItems.push_back( item );
|
aNetListItems.push_back( item );
|
||||||
|
@ -264,6 +264,21 @@ public:
|
|||||||
* the bus label NETLIST_OBJECTs.
|
* the bus label NETLIST_OBJECTs.
|
||||||
*/
|
*/
|
||||||
void ConvertBusToNetListItems( NETLIST_OBJECT_LIST& aNetListItems );
|
void ConvertBusToNetListItems( NETLIST_OBJECT_LIST& aNetListItems );
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**
|
||||||
|
* Given a bus vector, append the appropriate members into the list
|
||||||
|
* If given something like "DATA", 7, 0, will append "DATA7", "DATA6", etc.
|
||||||
|
*
|
||||||
|
* @param aNetListItems is the list to append to
|
||||||
|
* @param aName is the prefix for the vector, like "DATA"
|
||||||
|
* @param aBegin is the first entry in the vector
|
||||||
|
* @param aEnd is the last entry in the vector
|
||||||
|
* @param aOffset is an offset to add to the member code for each member
|
||||||
|
*/
|
||||||
|
void fillBusVector( NETLIST_OBJECT_LIST& aNetListItems, wxString aName,
|
||||||
|
long aBegin, long aEnd, long aOffset );
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -408,7 +408,7 @@ void SCH_EDIT_FRAME::OnLeftDClick( wxDC* aDC, const wxPoint& aPosition )
|
|||||||
switch( item->Type() )
|
switch( item->Type() )
|
||||||
{
|
{
|
||||||
case SCH_SHEET_T:
|
case SCH_SHEET_T:
|
||||||
m_CurrentSheet->push_back( (SCH_SHEET*) item );
|
g_CurrentSheet->push_back( (SCH_SHEET*) item );
|
||||||
DisplayCurrentSheet();
|
DisplayCurrentSheet();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -34,9 +34,10 @@
|
|||||||
#include <sch_edit_frame.h>
|
#include <sch_edit_frame.h>
|
||||||
#include <menus_helpers.h>
|
#include <menus_helpers.h>
|
||||||
|
|
||||||
|
#include <class_library.h>
|
||||||
#include <general.h>
|
#include <general.h>
|
||||||
#include <hotkeys.h>
|
#include <hotkeys.h>
|
||||||
#include <class_library.h>
|
#include <netlist_object.h>
|
||||||
#include <sch_bus_entry.h>
|
#include <sch_bus_entry.h>
|
||||||
#include <sch_marker.h>
|
#include <sch_marker.h>
|
||||||
#include <sch_text.h>
|
#include <sch_text.h>
|
||||||
@ -48,6 +49,7 @@
|
|||||||
#include <sch_sheet_path.h>
|
#include <sch_sheet_path.h>
|
||||||
#include <sch_bitmap.h>
|
#include <sch_bitmap.h>
|
||||||
#include <symbol_lib_table.h>
|
#include <symbol_lib_table.h>
|
||||||
|
#include <sch_connection.h>
|
||||||
#include <sch_view.h>
|
#include <sch_view.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -208,7 +210,7 @@ bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu )
|
|||||||
PopMenu->AppendSeparator();
|
PopMenu->AppendSeparator();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( m_CurrentSheet->Last() != g_RootSheet )
|
if( g_CurrentSheet->Last() != g_RootSheet )
|
||||||
{
|
{
|
||||||
msg = AddHotkeyName( _( "Leave Sheet" ), g_Schematic_Hokeys_Descr, HK_LEAVE_SHEET );
|
msg = AddHotkeyName( _( "Leave Sheet" ), g_Schematic_Hokeys_Descr, HK_LEAVE_SHEET );
|
||||||
AddMenuItem( PopMenu, ID_POPUP_SCH_LEAVE_SHEET, msg,
|
AddMenuItem( PopMenu, ID_POPUP_SCH_LEAVE_SHEET, msg,
|
||||||
@ -766,6 +768,58 @@ void AddMenusForBus( wxMenu* PopMenu, SCH_LINE* Bus, SCH_EDIT_FRAME* frame )
|
|||||||
|
|
||||||
AddMenuItem( PopMenu, ID_POPUP_SCH_BREAK_WIRE, _( "Break Bus" ), KiBitmap( break_bus_xpm ) );
|
AddMenuItem( PopMenu, ID_POPUP_SCH_BREAK_WIRE, _( "Break Bus" ), KiBitmap( break_bus_xpm ) );
|
||||||
|
|
||||||
|
// Bus unfolding menu (only available if bus is properly defined)
|
||||||
|
auto connection = Bus->Connection( *g_CurrentSheet );
|
||||||
|
|
||||||
|
if( connection && connection->IsBus() && connection->Members().size() > 0 )
|
||||||
|
{
|
||||||
|
int idx = 0;
|
||||||
|
wxMenu* bus_unfolding_menu = new wxMenu;
|
||||||
|
|
||||||
|
PopMenu->AppendSubMenu( bus_unfolding_menu, _( "Unfold Bus" ) );
|
||||||
|
|
||||||
|
for( const auto& member : connection->Members() )
|
||||||
|
{
|
||||||
|
int id = ID_POPUP_SCH_UNFOLD_BUS + ( idx++ );
|
||||||
|
auto name = member->Name( true );
|
||||||
|
|
||||||
|
if( member->Type() == CONNECTION_BUS )
|
||||||
|
{
|
||||||
|
wxMenu* submenu = new wxMenu;
|
||||||
|
bus_unfolding_menu->AppendSubMenu( submenu, _( name ) );
|
||||||
|
|
||||||
|
for( const auto& sub_member : member->Members() )
|
||||||
|
{
|
||||||
|
id = ID_POPUP_SCH_UNFOLD_BUS + ( idx++ );
|
||||||
|
|
||||||
|
submenu->Append( id, sub_member->Name( true ), wxEmptyString );
|
||||||
|
|
||||||
|
// See comment in else clause below
|
||||||
|
auto sub_item_clone = new wxMenuItem();
|
||||||
|
sub_item_clone->SetItemLabel( sub_member->Name( true ) );
|
||||||
|
|
||||||
|
frame->Bind( wxEVT_COMMAND_MENU_SELECTED, &SCH_EDIT_FRAME::OnUnfoldBus,
|
||||||
|
frame, id, id, sub_item_clone );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bus_unfolding_menu->Append( id, name, wxEmptyString );
|
||||||
|
|
||||||
|
// Because Bind() takes ownership of the user data item, we
|
||||||
|
// make a new menu item here and set its label. Why create a
|
||||||
|
// menu item instead of just a wxString or something? Because
|
||||||
|
// Bind() requires a pointer to wxObject rather than a void
|
||||||
|
// pointer. Maybe at some point I'll think of a better way...
|
||||||
|
auto item_clone = new wxMenuItem();
|
||||||
|
item_clone->SetItemLabel( name );
|
||||||
|
|
||||||
|
frame->Bind( wxEVT_COMMAND_MENU_SELECTED, &SCH_EDIT_FRAME::OnUnfoldBus,
|
||||||
|
frame, id, id, item_clone );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PopMenu->AppendSeparator();
|
PopMenu->AppendSeparator();
|
||||||
msg = AddHotkeyName( _( "Add Junction" ), g_Schematic_Hokeys_Descr, HK_ADD_JUNCTION );
|
msg = AddHotkeyName( _( "Add Junction" ), g_Schematic_Hokeys_Descr, HK_ADD_JUNCTION );
|
||||||
AddMenuItem( PopMenu, ID_POPUP_SCH_ADD_JUNCTION, msg, KiBitmap( add_junction_xpm ) );
|
AddMenuItem( PopMenu, ID_POPUP_SCH_ADD_JUNCTION, msg, KiBitmap( add_junction_xpm ) );
|
||||||
|
@ -441,6 +441,8 @@ void SCH_BASE_FRAME::RedrawScreen( const wxPoint& aCenterPoint, bool aWarpPointe
|
|||||||
else
|
else
|
||||||
GetCanvas()->GetView()->SetScale( scale );
|
GetCanvas()->GetView()->SetScale( scale );
|
||||||
|
|
||||||
|
GetCanvas()->GetView()->SetCenter( aCenterPoint );
|
||||||
|
|
||||||
if( aWarpPointer )
|
if( aWarpPointer )
|
||||||
GetCanvas()->GetViewControls()->CenterOnCursor();
|
GetCanvas()->GetViewControls()->CenterOnCursor();
|
||||||
|
|
||||||
@ -623,30 +625,56 @@ void SCH_BASE_FRAME::RefreshItem( SCH_ITEM* aItem, bool isAddOrDelete )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_BASE_FRAME::AddToScreen( SCH_ITEM* aItem )
|
void SCH_BASE_FRAME::AddToScreen( SCH_ITEM* aItem, SCH_SCREEN* aScreen )
|
||||||
{
|
{
|
||||||
GetScreen()->Append( aItem );
|
auto screen = aScreen;
|
||||||
|
|
||||||
|
if( aScreen == nullptr )
|
||||||
|
screen = GetScreen();
|
||||||
|
|
||||||
|
screen->Append( aItem );
|
||||||
|
|
||||||
|
if( screen == GetScreen() )
|
||||||
|
{
|
||||||
GetCanvas()->GetView()->Add( aItem );
|
GetCanvas()->GetView()->Add( aItem );
|
||||||
RefreshItem( aItem, true ); // handle any additional parent semantics
|
RefreshItem( aItem, true ); // handle any additional parent semantics
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_BASE_FRAME::AddToScreen( DLIST<SCH_ITEM>& aItems )
|
void SCH_BASE_FRAME::AddToScreen( DLIST<SCH_ITEM>& aItems, SCH_SCREEN* aScreen )
|
||||||
{
|
{
|
||||||
|
auto screen = aScreen;
|
||||||
|
|
||||||
|
if( aScreen == nullptr )
|
||||||
|
screen = GetScreen();
|
||||||
|
|
||||||
|
if( screen == GetScreen() )
|
||||||
|
{
|
||||||
for( SCH_ITEM* item = aItems.begin(); item; item = item->Next() )
|
for( SCH_ITEM* item = aItems.begin(); item; item = item->Next() )
|
||||||
{
|
{
|
||||||
GetCanvas()->GetView()->Add( item );
|
GetCanvas()->GetView()->Add( item );
|
||||||
RefreshItem( item, true ); // handle any additional parent semantics
|
RefreshItem( item, true ); // handle any additional parent semantics
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GetScreen()->Append( aItems );
|
screen->Append( aItems );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_BASE_FRAME::RemoveFromScreen( SCH_ITEM* aItem )
|
void SCH_BASE_FRAME::RemoveFromScreen( SCH_ITEM* aItem, SCH_SCREEN* aScreen )
|
||||||
{
|
{
|
||||||
|
auto screen = aScreen;
|
||||||
|
|
||||||
|
if( aScreen == nullptr )
|
||||||
|
screen = GetScreen();
|
||||||
|
|
||||||
|
if( screen == GetScreen() )
|
||||||
GetCanvas()->GetView()->Remove( aItem );
|
GetCanvas()->GetView()->Remove( aItem );
|
||||||
GetScreen()->Remove( aItem );
|
|
||||||
|
screen->Remove( aItem );
|
||||||
|
|
||||||
|
if( screen == GetScreen() )
|
||||||
RefreshItem( aItem, true ); // handle any additional parent semantics
|
RefreshItem( aItem, true ); // handle any additional parent semantics
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,18 +298,21 @@ public:
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an item to the screen (and view)
|
* Add an item to the screen (and view)
|
||||||
|
* aScreen is the screen the item is located on, if not the current screen
|
||||||
*/
|
*/
|
||||||
void AddToScreen( SCH_ITEM* aItem );
|
void AddToScreen( SCH_ITEM* aItem, SCH_SCREEN* aScreen = nullptr );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a list of items to the screen (and view)
|
* Add a list of items to the screen (and view)
|
||||||
|
* aScreen is the screen the item is located on, if not the current screen
|
||||||
*/
|
*/
|
||||||
void AddToScreen( DLIST<SCH_ITEM>& aItems );
|
void AddToScreen( DLIST<SCH_ITEM>& aItems, SCH_SCREEN* aScreen = nullptr );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove an item from the screen (and view)
|
* Remove an item from the screen (and view)
|
||||||
|
* aScreen is the screen the item is located on, if not the current screen
|
||||||
*/
|
*/
|
||||||
void RemoveFromScreen( SCH_ITEM* aItem );
|
void RemoveFromScreen( SCH_ITEM* aItem, SCH_SCREEN* aScreen = nullptr );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mark an item for refresh.
|
* Mark an item for refresh.
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#include <eeschema_config.h>
|
#include <eeschema_config.h>
|
||||||
#include <general.h>
|
#include <general.h>
|
||||||
#include <sch_bus_entry.h>
|
#include <sch_bus_entry.h>
|
||||||
|
#include <sch_line.h>
|
||||||
|
|
||||||
|
|
||||||
SCH_BUS_ENTRY_BASE::SCH_BUS_ENTRY_BASE( KICAD_T aType, const wxPoint& pos, char shape ) :
|
SCH_BUS_ENTRY_BASE::SCH_BUS_ENTRY_BASE( KICAD_T aType, const wxPoint& pos, char shape ) :
|
||||||
@ -59,12 +60,15 @@ SCH_BUS_WIRE_ENTRY::SCH_BUS_WIRE_ENTRY( const wxPoint& pos, char shape ) :
|
|||||||
SCH_BUS_ENTRY_BASE( SCH_BUS_WIRE_ENTRY_T, pos, shape )
|
SCH_BUS_ENTRY_BASE( SCH_BUS_WIRE_ENTRY_T, pos, shape )
|
||||||
{
|
{
|
||||||
m_Layer = LAYER_WIRE;
|
m_Layer = LAYER_WIRE;
|
||||||
|
m_connected_bus_item = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
SCH_BUS_BUS_ENTRY::SCH_BUS_BUS_ENTRY( const wxPoint& pos, char shape ) :
|
SCH_BUS_BUS_ENTRY::SCH_BUS_BUS_ENTRY( const wxPoint& pos, char shape ) :
|
||||||
SCH_BUS_ENTRY_BASE( SCH_BUS_BUS_ENTRY_T, pos, shape )
|
SCH_BUS_ENTRY_BASE( SCH_BUS_BUS_ENTRY_T, pos, shape )
|
||||||
{
|
{
|
||||||
m_Layer = LAYER_BUS;
|
m_Layer = LAYER_BUS;
|
||||||
|
m_connected_bus_items[0] = nullptr;
|
||||||
|
m_connected_bus_items[1] = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
EDA_ITEM* SCH_BUS_WIRE_ENTRY::Clone() const
|
EDA_ITEM* SCH_BUS_WIRE_ENTRY::Clone() const
|
||||||
@ -416,3 +420,30 @@ char SCH_BUS_ENTRY_BASE::GetBusEntryShape() const
|
|||||||
else
|
else
|
||||||
return '\\';
|
return '\\';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_BUS_ENTRY_BASE::GetMsgPanelInfo( EDA_UNITS_T aUnits, MSG_PANEL_ITEMS& aList )
|
||||||
|
{
|
||||||
|
if( auto conn = Connection( *g_CurrentSheet ) )
|
||||||
|
{
|
||||||
|
#if defined(DEBUG)
|
||||||
|
conn->AppendDebugInfoToMsgPanel( aList );
|
||||||
|
#else
|
||||||
|
conn->AppendInfoToMsgPanel( aList );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SCH_BUS_WIRE_ENTRY::ConnectionPropagatesTo( const EDA_ITEM* aItem ) const
|
||||||
|
{
|
||||||
|
// Don't generate connections between bus entries and buses, since there is
|
||||||
|
// a connectivity change at that point (e.g. A[7..0] to A7)
|
||||||
|
if( ( aItem->Type() == SCH_LINE_T ) &&
|
||||||
|
( static_cast<const SCH_LINE*>( aItem )->GetLayer() == LAYER_BUS ) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -120,6 +120,8 @@ public:
|
|||||||
|
|
||||||
void Plot( PLOTTER* aPlotter ) override;
|
void Plot( PLOTTER* aPlotter ) override;
|
||||||
|
|
||||||
|
void GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList ) override;
|
||||||
|
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
|
void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
|
||||||
#endif
|
#endif
|
||||||
@ -157,9 +159,17 @@ public:
|
|||||||
|
|
||||||
EDA_ITEM* Clone() const override;
|
EDA_ITEM* Clone() const override;
|
||||||
|
|
||||||
|
virtual bool ConnectionPropagatesTo( const EDA_ITEM* aItem ) const override;
|
||||||
|
|
||||||
BITMAP_DEF GetMenuImage() const override;
|
BITMAP_DEF GetMenuImage() const override;
|
||||||
|
|
||||||
bool UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList ) override;
|
bool UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList ) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pointer to the bus item (usually a bus wire) connected to this bus-wire
|
||||||
|
* entry, if it is connected to one.
|
||||||
|
*/
|
||||||
|
SCH_ITEM* m_connected_bus_item;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -193,6 +203,12 @@ public:
|
|||||||
BITMAP_DEF GetMenuImage() const override;
|
BITMAP_DEF GetMenuImage() const override;
|
||||||
|
|
||||||
bool UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList ) override;
|
bool UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList ) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pointer to the bus items (usually bus wires) connected to this bus-bus
|
||||||
|
* entry (either or both may be nullptr)
|
||||||
|
*/
|
||||||
|
SCH_ITEM* m_connected_bus_items[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _SCH_BUS_ENTRY_H_
|
#endif // _SCH_BUS_ENTRY_H_
|
||||||
|
@ -123,7 +123,6 @@ SCH_COMPONENT::SCH_COMPONENT( const wxPoint& aPos, SCH_ITEM* aParent ) :
|
|||||||
SCH_ITEM( aParent, SCH_COMPONENT_T )
|
SCH_ITEM( aParent, SCH_COMPONENT_T )
|
||||||
{
|
{
|
||||||
Init( aPos );
|
Init( aPos );
|
||||||
m_currentSheetPath = NULL;
|
|
||||||
m_fieldsAutoplaced = AUTOPLACED_NO;
|
m_fieldsAutoplaced = AUTOPLACED_NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +137,6 @@ SCH_COMPONENT::SCH_COMPONENT( LIB_PART& aPart, LIB_ID aLibId, SCH_SHEET_PATH* sh
|
|||||||
m_convert = convert;
|
m_convert = convert;
|
||||||
m_lib_id = aLibId;
|
m_lib_id = aLibId;
|
||||||
m_part = aPart.SharedPtr();
|
m_part = aPart.SharedPtr();
|
||||||
m_currentSheetPath = NULL;
|
|
||||||
m_fieldsAutoplaced = AUTOPLACED_NO;
|
m_fieldsAutoplaced = AUTOPLACED_NO;
|
||||||
|
|
||||||
SetTimeStamp( GetNewTimeStamp() );
|
SetTimeStamp( GetNewTimeStamp() );
|
||||||
@ -163,7 +161,6 @@ SCH_COMPONENT::SCH_COMPONENT( LIB_PART& aPart, LIB_ID aLibId, SCH_SHEET_PATH* sh
|
|||||||
SCH_COMPONENT::SCH_COMPONENT( const SCH_COMPONENT& aComponent ) :
|
SCH_COMPONENT::SCH_COMPONENT( const SCH_COMPONENT& aComponent ) :
|
||||||
SCH_ITEM( aComponent )
|
SCH_ITEM( aComponent )
|
||||||
{
|
{
|
||||||
m_currentSheetPath = NULL;
|
|
||||||
m_Parent = aComponent.m_Parent;
|
m_Parent = aComponent.m_Parent;
|
||||||
m_Pos = aComponent.m_Pos;
|
m_Pos = aComponent.m_Pos;
|
||||||
m_unit = aComponent.m_unit;
|
m_unit = aComponent.m_unit;
|
||||||
@ -471,6 +468,7 @@ void SCH_COMPONENT::UpdatePinCache()
|
|||||||
if( PART_SPTR part = m_part.lock() )
|
if( PART_SPTR part = m_part.lock() )
|
||||||
{
|
{
|
||||||
m_Pins.clear();
|
m_Pins.clear();
|
||||||
|
|
||||||
for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
|
for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
|
||||||
{
|
{
|
||||||
wxASSERT( pin->Type() == LIB_PIN_T );
|
wxASSERT( pin->Type() == LIB_PIN_T );
|
||||||
@ -534,6 +532,54 @@ void SCH_COMPONENT::UpdateAllPinCaches( const SCH_COLLECTOR& aComponents )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_COMPONENT::UpdatePinConnections( SCH_SHEET_PATH aSheet )
|
||||||
|
{
|
||||||
|
if( PART_SPTR part = m_part.lock() )
|
||||||
|
{
|
||||||
|
for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
|
||||||
|
{
|
||||||
|
wxASSERT( pin->Type() == LIB_PIN_T );
|
||||||
|
|
||||||
|
if( pin->GetUnit() && m_unit && ( m_unit != pin->GetUnit() ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( pin->GetConvert() && m_convert && ( m_convert != pin->GetConvert() ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
SCH_PIN_CONNECTION* connection = nullptr;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
connection = m_pin_connections.at( pin );
|
||||||
|
}
|
||||||
|
catch( const std::out_of_range& oor )
|
||||||
|
{
|
||||||
|
connection = new SCH_PIN_CONNECTION();
|
||||||
|
m_pin_connections[ pin ] = connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
connection->m_pin = pin;
|
||||||
|
connection->m_comp = this;
|
||||||
|
connection->InitializeConnection( aSheet );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SCH_PIN_CONNECTION* SCH_COMPONENT::GetConnectionForPin( LIB_PIN* aPin )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return m_pin_connections.at( aPin );
|
||||||
|
}
|
||||||
|
catch( const std::out_of_range& oor )
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_COMPONENT::SetUnit( int aUnit )
|
void SCH_COMPONENT::SetUnit( int aUnit )
|
||||||
{
|
{
|
||||||
if( m_unit != aUnit )
|
if( m_unit != aUnit )
|
||||||
@ -1436,9 +1482,9 @@ void SCH_COMPONENT::GetMsgPanelInfo( EDA_UNITS_T aUnits, MSG_PANEL_ITEMS& aList
|
|||||||
if( !alias )
|
if( !alias )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( m_currentSheetPath )
|
if( g_CurrentSheet )
|
||||||
aList.push_back( MSG_PANEL_ITEM( _( "Reference" ),
|
aList.push_back( MSG_PANEL_ITEM( _( "Reference" ),
|
||||||
GetRef( m_currentSheetPath ),
|
GetRef( g_CurrentSheet ),
|
||||||
DARKCYAN ) );
|
DARKCYAN ) );
|
||||||
|
|
||||||
msg = part->IsPower() ? _( "Power symbol" ) : _( "Value" );
|
msg = part->IsPower() ? _( "Power symbol" ) : _( "Value" );
|
||||||
@ -1476,8 +1522,8 @@ void SCH_COMPONENT::GetMsgPanelInfo( EDA_UNITS_T aUnits, MSG_PANEL_ITEMS& aList
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( m_currentSheetPath )
|
if( g_CurrentSheet )
|
||||||
aList.push_back( MSG_PANEL_ITEM( _( "Reference" ), GetRef( m_currentSheetPath ),
|
aList.push_back( MSG_PANEL_ITEM( _( "Reference" ), GetRef( g_CurrentSheet ),
|
||||||
DARKCYAN ) );
|
DARKCYAN ) );
|
||||||
|
|
||||||
aList.push_back( MSG_PANEL_ITEM( _( "Value" ), GetField( VALUE )->GetShownText(),
|
aList.push_back( MSG_PANEL_ITEM( _( "Value" ), GetField( VALUE )->GetShownText(),
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <lib_draw_item.h>
|
#include <lib_draw_item.h>
|
||||||
|
#include <sch_pin_connection.h>
|
||||||
|
|
||||||
class SCH_SCREEN;
|
class SCH_SCREEN;
|
||||||
class SCH_SHEET_PATH;
|
class SCH_SHEET_PATH;
|
||||||
@ -71,6 +72,7 @@ class SCH_COMPONENT : public SCH_ITEM
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum AUTOPLACED { AUTOPLACED_NO = 0, AUTOPLACED_AUTO, AUTOPLACED_MANUAL };
|
enum AUTOPLACED { AUTOPLACED_NO = 0, AUTOPLACED_AUTO, AUTOPLACED_MANUAL };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
wxPoint m_Pos;
|
wxPoint m_Pos;
|
||||||
@ -97,14 +99,6 @@ private:
|
|||||||
|
|
||||||
AUTOPLACED m_fieldsAutoplaced; ///< indicates status of field autoplacement
|
AUTOPLACED m_fieldsAutoplaced; ///< indicates status of field autoplacement
|
||||||
|
|
||||||
/**
|
|
||||||
* A temporary sheet path is required to generate the correct reference designator string
|
|
||||||
* in complex hierarchies. Hopefully this is only a temporary hack to decouple schematic
|
|
||||||
* objects from the drawing window until a better design for handling complex hierarchies
|
|
||||||
* can be implemented.
|
|
||||||
*/
|
|
||||||
const SCH_SHEET_PATH* m_currentSheetPath;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the hierarchical path and reference of the component. This allows support
|
* Defines the hierarchical path and reference of the component. This allows support
|
||||||
* for hierarchical sheets that reference the same schematic. The format for the path
|
* for hierarchical sheets that reference the same schematic. The format for the path
|
||||||
@ -113,6 +107,8 @@ private:
|
|||||||
*/
|
*/
|
||||||
wxArrayString m_PathsAndReferences;
|
wxArrayString m_PathsAndReferences;
|
||||||
|
|
||||||
|
std::unordered_map<LIB_PIN*, SCH_PIN_CONNECTION*> m_pin_connections;
|
||||||
|
|
||||||
void Init( const wxPoint& pos = wxPoint( 0, 0 ) );
|
void Init( const wxPoint& pos = wxPoint( 0, 0 ) );
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -219,6 +215,21 @@ public:
|
|||||||
*/
|
*/
|
||||||
static void UpdateAllPinCaches( const SCH_COLLECTOR& aComponents );
|
static void UpdateAllPinCaches( const SCH_COLLECTOR& aComponents );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the local cache of SCH_PIN_CONNECTION objects for each pin
|
||||||
|
*/
|
||||||
|
void UpdatePinConnections( SCH_SHEET_PATH aSheet );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the pin connection for a given pin of the component
|
||||||
|
*/
|
||||||
|
SCH_PIN_CONNECTION* GetConnectionForPin( LIB_PIN* aPin );
|
||||||
|
|
||||||
|
const std::unordered_map<LIB_PIN*, SCH_PIN_CONNECTION*>& PinConnections()
|
||||||
|
{
|
||||||
|
return m_pin_connections;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change the unit number to \a aUnit
|
* Change the unit number to \a aUnit
|
||||||
*
|
*
|
||||||
@ -513,11 +524,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
static bool IsReferenceStringValid( const wxString& aReferenceString );
|
static bool IsReferenceStringValid( const wxString& aReferenceString );
|
||||||
|
|
||||||
void SetCurrentSheetPath( const SCH_SHEET_PATH* aSheetPath )
|
|
||||||
{
|
|
||||||
m_currentSheetPath = aSheetPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the reference for the given sheet path.
|
* Return the reference for the given sheet path.
|
||||||
*
|
*
|
||||||
@ -666,5 +672,4 @@ private:
|
|||||||
bool doIsConnected( const wxPoint& aPosition ) const override;
|
bool doIsConnected( const wxPoint& aPosition ) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif /* COMPONENT_CLASS_H */
|
#endif /* COMPONENT_CLASS_H */
|
||||||
|
469
eeschema/sch_connection.cpp
Normal file
469
eeschema/sch_connection.cpp
Normal file
@ -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;
|
||||||
|
}
|
347
eeschema/sch_connection.h
Normal file
347
eeschema/sch_connection.h
Normal file
@ -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
|
||||||
|
|
@ -69,6 +69,7 @@
|
|||||||
#include <wildcards_and_files_ext.h>
|
#include <wildcards_and_files_ext.h>
|
||||||
|
|
||||||
#include <netlist_exporter_kicad.h>
|
#include <netlist_exporter_kicad.h>
|
||||||
|
#include <connection_graph.h>
|
||||||
#include <kiway.h>
|
#include <kiway.h>
|
||||||
#include <dialogs/dialog_fields_editor_global.h>
|
#include <dialogs/dialog_fields_editor_global.h>
|
||||||
|
|
||||||
@ -77,6 +78,9 @@
|
|||||||
|
|
||||||
#include <gal/graphics_abstraction_layer.h>
|
#include <gal/graphics_abstraction_layer.h>
|
||||||
|
|
||||||
|
SCH_SHEET_PATH* g_CurrentSheet = nullptr; // declared in general.h
|
||||||
|
CONNECTION_GRAPH* g_ConnectionGraph = nullptr;
|
||||||
|
|
||||||
// non-member so it can be moved easily, and kept REALLY private.
|
// non-member so it can be moved easily, and kept REALLY private.
|
||||||
// Do NOT Clear() in here.
|
// Do NOT Clear() in here.
|
||||||
static void add_search_paths( SEARCH_STACK* aDst, const SEARCH_STACK& aSrc, int aIndex )
|
static void add_search_paths( SEARCH_STACK* aDst, const SEARCH_STACK& aSrc, int aIndex )
|
||||||
@ -284,6 +288,7 @@ BEGIN_EVENT_TABLE( SCH_EDIT_FRAME, EDA_DRAW_FRAME )
|
|||||||
EVT_TOOL( ID_UPDATE_PCB_FROM_SCH, SCH_EDIT_FRAME::OnUpdatePCB )
|
EVT_TOOL( ID_UPDATE_PCB_FROM_SCH, SCH_EDIT_FRAME::OnUpdatePCB )
|
||||||
EVT_TOOL( ID_GET_TOOLS, SCH_EDIT_FRAME::OnCreateBillOfMaterials )
|
EVT_TOOL( ID_GET_TOOLS, SCH_EDIT_FRAME::OnCreateBillOfMaterials )
|
||||||
EVT_TOOL( ID_OPEN_CMP_TABLE, SCH_EDIT_FRAME::OnLaunchBomManager )
|
EVT_TOOL( ID_OPEN_CMP_TABLE, SCH_EDIT_FRAME::OnLaunchBomManager )
|
||||||
|
EVT_TOOL( ID_BUS_MANAGER, SCH_EDIT_FRAME::OnLaunchBusManager )
|
||||||
EVT_TOOL( ID_FIND_ITEMS, SCH_EDIT_FRAME::OnFindItems )
|
EVT_TOOL( ID_FIND_ITEMS, SCH_EDIT_FRAME::OnFindItems )
|
||||||
EVT_TOOL( wxID_REPLACE, SCH_EDIT_FRAME::OnFindItems )
|
EVT_TOOL( wxID_REPLACE, SCH_EDIT_FRAME::OnFindItems )
|
||||||
EVT_TOOL( ID_BACKANNO_ITEMS, SCH_EDIT_FRAME::OnLoadCmpToFootprintLinkFile )
|
EVT_TOOL( ID_BACKANNO_ITEMS, SCH_EDIT_FRAME::OnLoadCmpToFootprintLinkFile )
|
||||||
@ -321,6 +326,7 @@ BEGIN_EVENT_TABLE( SCH_EDIT_FRAME, EDA_DRAW_FRAME )
|
|||||||
EVT_MENU_RANGE( ID_SCH_MIRROR_X, ID_SCH_ORIENT_NORMAL, SCH_EDIT_FRAME::OnOrient )
|
EVT_MENU_RANGE( ID_SCH_MIRROR_X, ID_SCH_ORIENT_NORMAL, SCH_EDIT_FRAME::OnOrient )
|
||||||
EVT_MENU_RANGE( ID_POPUP_START_RANGE, ID_POPUP_END_RANGE,
|
EVT_MENU_RANGE( ID_POPUP_START_RANGE, ID_POPUP_END_RANGE,
|
||||||
SCH_EDIT_FRAME::Process_Special_Functions )
|
SCH_EDIT_FRAME::Process_Special_Functions )
|
||||||
|
EVT_MENU( ID_SCH_UNFOLD_BUS, SCH_EDIT_FRAME::OnUnfoldBusHotkey )
|
||||||
EVT_MENU( ID_POPUP_SCH_DISPLAYDOC_CMP, SCH_EDIT_FRAME::OnEditItem )
|
EVT_MENU( ID_POPUP_SCH_DISPLAYDOC_CMP, SCH_EDIT_FRAME::OnEditItem )
|
||||||
|
|
||||||
EVT_MENU( ID_MENU_CANVAS_CAIRO, SCH_EDIT_FRAME::OnSwitchCanvas )
|
EVT_MENU( ID_MENU_CANVAS_CAIRO, SCH_EDIT_FRAME::OnSwitchCanvas )
|
||||||
@ -371,9 +377,11 @@ SCH_EDIT_FRAME::SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ):
|
|||||||
wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, SCH_EDIT_FRAME_NAME ),
|
wxDefaultPosition, wxDefaultSize, KICAD_DEFAULT_DRAWFRAME_STYLE, SCH_EDIT_FRAME_NAME ),
|
||||||
m_item_to_repeat( 0 )
|
m_item_to_repeat( 0 )
|
||||||
{
|
{
|
||||||
|
g_CurrentSheet = new SCH_SHEET_PATH();
|
||||||
|
g_ConnectionGraph = new CONNECTION_GRAPH( this );
|
||||||
|
|
||||||
m_showAxis = false; // true to show axis
|
m_showAxis = false; // true to show axis
|
||||||
m_showBorderAndTitleBlock = true; // true to show sheet references
|
m_showBorderAndTitleBlock = true; // true to show sheet references
|
||||||
m_CurrentSheet = new SCH_SHEET_PATH;
|
|
||||||
m_DefaultSchematicFileName = NAMELESS_PROJECT;
|
m_DefaultSchematicFileName = NAMELESS_PROJECT;
|
||||||
m_DefaultSchematicFileName += wxT( ".sch" );
|
m_DefaultSchematicFileName += wxT( ".sch" );
|
||||||
m_showAllPins = false;
|
m_showAllPins = false;
|
||||||
@ -386,6 +394,7 @@ SCH_EDIT_FRAME::SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ):
|
|||||||
m_findReplaceStatus = new wxString( wxEmptyString );
|
m_findReplaceStatus = new wxString( wxEmptyString );
|
||||||
m_undoItem = NULL;
|
m_undoItem = NULL;
|
||||||
m_hasAutoSave = true;
|
m_hasAutoSave = true;
|
||||||
|
m_busUnfold = {};
|
||||||
m_FrameSize = ConvertDialogToPixels( wxSize( 500, 350 ) ); // default in case of no prefs
|
m_FrameSize = ConvertDialogToPixels( wxSize( 500, 350 ) ); // default in case of no prefs
|
||||||
|
|
||||||
m_toolManager = new TOOL_MANAGER;
|
m_toolManager = new TOOL_MANAGER;
|
||||||
@ -458,12 +467,15 @@ SCH_EDIT_FRAME::~SCH_EDIT_FRAME()
|
|||||||
|
|
||||||
SetScreen( NULL );
|
SetScreen( NULL );
|
||||||
|
|
||||||
delete m_CurrentSheet; // a SCH_SHEET_PATH, on the heap.
|
delete g_CurrentSheet; // a SCH_SHEET_PATH, on the heap.
|
||||||
|
delete g_ConnectionGraph;
|
||||||
delete m_undoItem;
|
delete m_undoItem;
|
||||||
delete m_findReplaceData;
|
delete m_findReplaceData;
|
||||||
delete m_findReplaceStatus;
|
delete m_findReplaceStatus;
|
||||||
|
|
||||||
delete g_RootSheet;
|
delete g_RootSheet;
|
||||||
|
|
||||||
|
g_CurrentSheet = nullptr;
|
||||||
|
g_ConnectionGraph = nullptr;
|
||||||
g_RootSheet = NULL;
|
g_RootSheet = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -503,7 +515,7 @@ void SCH_EDIT_FRAME::SetSheetNumberAndCount()
|
|||||||
*/
|
*/
|
||||||
int sheet_count = g_RootSheet->CountSheets();
|
int sheet_count = g_RootSheet->CountSheets();
|
||||||
int SheetNumber = 1;
|
int SheetNumber = 1;
|
||||||
wxString current_sheetpath = m_CurrentSheet->Path();
|
wxString current_sheetpath = g_CurrentSheet->Path();
|
||||||
SCH_SHEET_LIST sheetList( g_RootSheet );
|
SCH_SHEET_LIST sheetList( g_RootSheet );
|
||||||
|
|
||||||
// Examine all sheets path to find the current sheets path,
|
// Examine all sheets path to find the current sheets path,
|
||||||
@ -520,7 +532,7 @@ void SCH_EDIT_FRAME::SetSheetNumberAndCount()
|
|||||||
* path */
|
* path */
|
||||||
}
|
}
|
||||||
|
|
||||||
m_CurrentSheet->SetPageNumber( SheetNumber );
|
g_CurrentSheet->SetPageNumber( SheetNumber );
|
||||||
|
|
||||||
for( screen = s_list.GetFirst(); screen != NULL; screen = s_list.GetNext() )
|
for( screen = s_list.GetFirst(); screen != NULL; screen = s_list.GetNext() )
|
||||||
{
|
{
|
||||||
@ -533,13 +545,13 @@ void SCH_EDIT_FRAME::SetSheetNumberAndCount()
|
|||||||
|
|
||||||
SCH_SCREEN* SCH_EDIT_FRAME::GetScreen() const
|
SCH_SCREEN* SCH_EDIT_FRAME::GetScreen() const
|
||||||
{
|
{
|
||||||
return m_CurrentSheet->LastScreen();
|
return g_CurrentSheet->LastScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
wxString SCH_EDIT_FRAME::GetScreenDesc() const
|
wxString SCH_EDIT_FRAME::GetScreenDesc() const
|
||||||
{
|
{
|
||||||
wxString s = m_CurrentSheet->PathHumanReadable();
|
wxString s = g_CurrentSheet->PathHumanReadable();
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
@ -562,8 +574,9 @@ void SCH_EDIT_FRAME::CreateScreens()
|
|||||||
|
|
||||||
g_RootSheet->GetScreen()->SetFileName( m_DefaultSchematicFileName );
|
g_RootSheet->GetScreen()->SetFileName( m_DefaultSchematicFileName );
|
||||||
|
|
||||||
m_CurrentSheet->clear();
|
g_CurrentSheet->clear();
|
||||||
m_CurrentSheet->push_back( g_RootSheet );
|
g_CurrentSheet->push_back( g_RootSheet );
|
||||||
|
g_ConnectionGraph->Reset();
|
||||||
|
|
||||||
if( GetScreen() == NULL )
|
if( GetScreen() == NULL )
|
||||||
{
|
{
|
||||||
@ -578,26 +591,26 @@ void SCH_EDIT_FRAME::CreateScreens()
|
|||||||
|
|
||||||
SCH_SHEET_PATH& SCH_EDIT_FRAME::GetCurrentSheet()
|
SCH_SHEET_PATH& SCH_EDIT_FRAME::GetCurrentSheet()
|
||||||
{
|
{
|
||||||
wxASSERT_MSG( m_CurrentSheet != NULL, wxT( "SCH_EDIT_FRAME m_CurrentSheet member is NULL." ) );
|
wxASSERT_MSG( g_CurrentSheet != NULL, wxT( "SCH_EDIT_FRAME g_CurrentSheet member is NULL." ) );
|
||||||
|
|
||||||
return *m_CurrentSheet;
|
return *g_CurrentSheet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_EDIT_FRAME::SetCurrentSheet( const SCH_SHEET_PATH& aSheet )
|
void SCH_EDIT_FRAME::SetCurrentSheet( const SCH_SHEET_PATH& aSheet )
|
||||||
{
|
{
|
||||||
if( aSheet != *m_CurrentSheet )
|
if( aSheet != *g_CurrentSheet )
|
||||||
{
|
{
|
||||||
*m_CurrentSheet = aSheet;
|
*g_CurrentSheet = aSheet;
|
||||||
|
|
||||||
static_cast<SCH_DRAW_PANEL*>( m_canvas )->DisplaySheet( m_CurrentSheet->LastScreen() );
|
static_cast<SCH_DRAW_PANEL*>( m_canvas )->DisplaySheet( g_CurrentSheet->LastScreen() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_EDIT_FRAME::HardRedraw()
|
void SCH_EDIT_FRAME::HardRedraw()
|
||||||
{
|
{
|
||||||
static_cast<SCH_DRAW_PANEL*>( m_canvas )->DisplaySheet( m_CurrentSheet->LastScreen() );
|
static_cast<SCH_DRAW_PANEL*>( m_canvas )->DisplaySheet( g_CurrentSheet->LastScreen() );
|
||||||
GetCanvas()->Refresh();
|
GetCanvas()->Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -709,7 +722,7 @@ void SCH_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
|
|||||||
g_RootSheet->GetScreen()->Clear();
|
g_RootSheet->GetScreen()->Clear();
|
||||||
|
|
||||||
// all sub sheets are deleted, only the main sheet is usable
|
// all sub sheets are deleted, only the main sheet is usable
|
||||||
m_CurrentSheet->clear();
|
g_CurrentSheet->clear();
|
||||||
|
|
||||||
Destroy();
|
Destroy();
|
||||||
}
|
}
|
||||||
@ -739,7 +752,7 @@ wxString SCH_EDIT_FRAME::GetUniqueFilenameForCurrentSheet()
|
|||||||
#define FN_LEN_MAX 80 // A reasonable value for the short filename len
|
#define FN_LEN_MAX 80 // A reasonable value for the short filename len
|
||||||
|
|
||||||
wxString filename = fn.GetName();
|
wxString filename = fn.GetName();
|
||||||
wxString sheetFullName = m_CurrentSheet->PathHumanReadable();
|
wxString sheetFullName = g_CurrentSheet->PathHumanReadable();
|
||||||
|
|
||||||
// Remove the last '/' of the path human readable
|
// Remove the last '/' of the path human readable
|
||||||
// (and for the root sheet, make sheetFullName empty):
|
// (and for the root sheet, make sheetFullName empty):
|
||||||
@ -767,6 +780,9 @@ void SCH_EDIT_FRAME::OnModify()
|
|||||||
|
|
||||||
m_foundItems.SetForceSearch();
|
m_foundItems.SetForceSearch();
|
||||||
|
|
||||||
|
//RecalculateConnections( SCH_SHEET_LIST( g_CurrentSheet->Last() ) );
|
||||||
|
RecalculateConnections();
|
||||||
|
|
||||||
m_canvas->Refresh();
|
m_canvas->Refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -824,7 +840,7 @@ void SCH_EDIT_FRAME::OnUpdateSaveSheet( wxUpdateUIEvent& aEvent )
|
|||||||
|
|
||||||
void SCH_EDIT_FRAME::OnUpdateHierarchySheet( wxUpdateUIEvent& aEvent )
|
void SCH_EDIT_FRAME::OnUpdateHierarchySheet( wxUpdateUIEvent& aEvent )
|
||||||
{
|
{
|
||||||
aEvent.Enable( m_CurrentSheet->Last() != g_RootSheet );
|
aEvent.Enable( g_CurrentSheet->Last() != g_RootSheet );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -910,7 +926,7 @@ void SCH_EDIT_FRAME::doUpdatePcb( const wxString& aUpdateOptions )
|
|||||||
}
|
}
|
||||||
|
|
||||||
NETLIST_OBJECT_LIST* net_atoms = BuildNetListBase();
|
NETLIST_OBJECT_LIST* net_atoms = BuildNetListBase();
|
||||||
NETLIST_EXPORTER_KICAD exporter( this, net_atoms );
|
NETLIST_EXPORTER_KICAD exporter( this, net_atoms, g_ConnectionGraph );
|
||||||
STRING_FORMATTER formatter;
|
STRING_FORMATTER formatter;
|
||||||
|
|
||||||
exporter.Format( &formatter, GNL_ALL );
|
exporter.Format( &formatter, GNL_ALL );
|
||||||
@ -951,6 +967,12 @@ void SCH_EDIT_FRAME::OnLaunchBomManager( wxCommandEvent& event )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_EDIT_FRAME::OnLaunchBusManager( wxCommandEvent& )
|
||||||
|
{
|
||||||
|
InvokeDialogBusManager( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_EDIT_FRAME::OnFindItems( wxCommandEvent& aEvent )
|
void SCH_EDIT_FRAME::OnFindItems( wxCommandEvent& aEvent )
|
||||||
{
|
{
|
||||||
wxCHECK_RET( m_findReplaceData != NULL,
|
wxCHECK_RET( m_findReplaceData != NULL,
|
||||||
@ -1393,7 +1415,7 @@ void SCH_EDIT_FRAME::addCurrentItemToScreen()
|
|||||||
// the m_mouseCaptureCallback function.
|
// the m_mouseCaptureCallback function.
|
||||||
m_canvas->SetMouseCapture( NULL, NULL );
|
m_canvas->SetMouseCapture( NULL, NULL );
|
||||||
|
|
||||||
if( !EditSheet( (SCH_SHEET*)item, m_CurrentSheet, &doClearAnnotation ) )
|
if( !EditSheet( (SCH_SHEET*)item, g_CurrentSheet, &doClearAnnotation ) )
|
||||||
{
|
{
|
||||||
screen->SetCurItem( NULL );
|
screen->SetCurItem( NULL );
|
||||||
delete item;
|
delete item;
|
||||||
@ -1438,6 +1460,9 @@ void SCH_EDIT_FRAME::addCurrentItemToScreen()
|
|||||||
SCH_SCREENS screensList( g_RootSheet );
|
SCH_SCREENS screensList( g_RootSheet );
|
||||||
screensList.ClearAnnotationOfNewSheetPaths( initial_sheetpathList );
|
screensList.ClearAnnotationOfNewSheetPaths( initial_sheetpathList );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update connectivity info for new item
|
||||||
|
RecalculateConnections();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1488,7 +1513,7 @@ void SCH_EDIT_FRAME::UpdateTitle()
|
|||||||
wxFileName fn = fileName;
|
wxFileName fn = fileName;
|
||||||
|
|
||||||
title.Printf( _( "Eeschema" ) + wxT( " \u2014 %s [%s] \u2014 %s" ),
|
title.Printf( _( "Eeschema" ) + wxT( " \u2014 %s [%s] \u2014 %s" ),
|
||||||
fn.GetFullName(), m_CurrentSheet->PathHumanReadable(),
|
fn.GetFullName(), g_CurrentSheet->PathHumanReadable(),
|
||||||
fn.GetPath() );
|
fn.GetPath() );
|
||||||
|
|
||||||
if( fn.FileExists() )
|
if( fn.FileExists() )
|
||||||
@ -1504,6 +1529,18 @@ void SCH_EDIT_FRAME::UpdateTitle()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_EDIT_FRAME::RecalculateConnections()
|
||||||
|
{
|
||||||
|
SCH_SHEET_LIST list( g_RootSheet );
|
||||||
|
|
||||||
|
// Ensure schematic graph is accurate
|
||||||
|
for( const auto& sheet : list )
|
||||||
|
SchematicCleanUp( true, sheet.LastScreen() );
|
||||||
|
|
||||||
|
g_ConnectionGraph->Recalculate( list );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_EDIT_FRAME::CommonSettingsChanged()
|
void SCH_EDIT_FRAME::CommonSettingsChanged()
|
||||||
{
|
{
|
||||||
SCH_BASE_FRAME::CommonSettingsChanged();
|
SCH_BASE_FRAME::CommonSettingsChanged();
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include <template_fieldnames.h>
|
#include <template_fieldnames.h>
|
||||||
#include <block_commande.h>
|
#include <block_commande.h>
|
||||||
#include <sch_collectors.h>
|
#include <sch_collectors.h>
|
||||||
|
#include <erc_settings.h>
|
||||||
#include <sch_draw_panel.h>
|
#include <sch_draw_panel.h>
|
||||||
|
|
||||||
// enum PINSHEETLABEL_SHAPE
|
// enum PINSHEETLABEL_SHAPE
|
||||||
@ -66,6 +67,7 @@ class wxFindDialogEvent;
|
|||||||
class wxFindReplaceData;
|
class wxFindReplaceData;
|
||||||
class SCHLIB_FILTER;
|
class SCHLIB_FILTER;
|
||||||
class RESCUER;
|
class RESCUER;
|
||||||
|
class CONNECTION_GRAPH;
|
||||||
|
|
||||||
|
|
||||||
/// enum used in RotationMiroir()
|
/// enum used in RotationMiroir()
|
||||||
@ -111,18 +113,36 @@ enum SCH_SEARCH_T {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// Collection of data related to the bus unfolding tool
|
||||||
|
struct BUS_UNFOLDING_T {
|
||||||
|
bool in_progress; ///< True if bus unfold operation is running
|
||||||
|
|
||||||
|
bool offset; ///< True if the bus entry should be offset from origin
|
||||||
|
|
||||||
|
bool label_placed; ///< True if user has placed the net label
|
||||||
|
|
||||||
|
wxPoint origin; ///< Origin (on the bus) of the unfold
|
||||||
|
|
||||||
|
wxString net_name; ///< Net label for the unfolding operation
|
||||||
|
|
||||||
|
SCH_BUS_WIRE_ENTRY* entry;
|
||||||
|
|
||||||
|
SCH_LABEL* label;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Schematic editor (Eeschema) main window.
|
* Schematic editor (Eeschema) main window.
|
||||||
*/
|
*/
|
||||||
class SCH_EDIT_FRAME : public SCH_BASE_FRAME
|
class SCH_EDIT_FRAME : public SCH_BASE_FRAME
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
SCH_SHEET_PATH* m_CurrentSheet; ///< which sheet we are presently working on.
|
|
||||||
wxString m_DefaultSchematicFileName;
|
wxString m_DefaultSchematicFileName;
|
||||||
wxString m_SelectedNetName;
|
wxString m_SelectedNetName;
|
||||||
|
|
||||||
PARAM_CFG_ARRAY m_projectFileParams;
|
PARAM_CFG_ARRAY m_projectFileParams;
|
||||||
PARAM_CFG_ARRAY m_configSettings;
|
PARAM_CFG_ARRAY m_configSettings;
|
||||||
|
ERC_SETTINGS m_ercSettings;
|
||||||
wxPageSetupDialogData m_pageSetupData;
|
wxPageSetupDialogData m_pageSetupData;
|
||||||
wxFindReplaceData* m_findReplaceData;
|
wxFindReplaceData* m_findReplaceData;
|
||||||
wxString* m_findReplaceStatus;
|
wxString* m_findReplaceStatus;
|
||||||
@ -166,6 +186,18 @@ private:
|
|||||||
/// Use netcodes (net number) as net names when generating spice net lists.
|
/// Use netcodes (net number) as net names when generating spice net lists.
|
||||||
bool m_spiceAjustPassiveValues;
|
bool m_spiceAjustPassiveValues;
|
||||||
|
|
||||||
|
public: // TODO(JE) Make private
|
||||||
|
|
||||||
|
/// Data related to bus unfolding tool
|
||||||
|
BUS_UNFOLDING_T m_busUnfold;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
/* these are PROJECT specific, not schematic editor specific
|
||||||
|
wxString m_userLibraryPath;
|
||||||
|
wxArrayString m_componentLibFiles;
|
||||||
|
*/
|
||||||
|
|
||||||
static PINSHEETLABEL_SHAPE m_lastSheetPinType; ///< Last sheet pin type.
|
static PINSHEETLABEL_SHAPE m_lastSheetPinType; ///< Last sheet pin type.
|
||||||
static wxSize m_lastSheetPinTextSize; ///< Last sheet pin text size.
|
static wxSize m_lastSheetPinTextSize; ///< Last sheet pin text size.
|
||||||
static wxPoint m_lastSheetPinPosition; ///< Last sheet pin position.
|
static wxPoint m_lastSheetPinPosition; ///< Last sheet pin position.
|
||||||
@ -251,6 +283,13 @@ public:
|
|||||||
void Process_Config( wxCommandEvent& event );
|
void Process_Config( wxCommandEvent& event );
|
||||||
void OnSelectTool( wxCommandEvent& aEvent );
|
void OnSelectTool( wxCommandEvent& aEvent );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes an "Unfold Bus" command from the right-click menu.
|
||||||
|
* Depending on what the user clicked, this can result in the creation
|
||||||
|
* of one or more new objects.
|
||||||
|
*/
|
||||||
|
void OnUnfoldBus( wxCommandEvent& event );
|
||||||
|
|
||||||
bool GeneralControl( wxDC* aDC, const wxPoint& aPosition, EDA_KEY aHotKey ) override;
|
bool GeneralControl( wxDC* aDC, const wxPoint& aPosition, EDA_KEY aHotKey ) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -277,6 +316,10 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool LoadProjectFile();
|
bool LoadProjectFile();
|
||||||
|
|
||||||
|
const ERC_SETTINGS& GetErcSettings() { return m_ercSettings; }
|
||||||
|
|
||||||
|
void UpdateErcSettings( const ERC_SETTINGS& aSettings ) { m_ercSettings = aSettings; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a default symbol field name for field \a aFieldNdx for all components.
|
* Return a default symbol field name for field \a aFieldNdx for all components.
|
||||||
*
|
*
|
||||||
@ -447,10 +490,12 @@ public:
|
|||||||
* @param aPoint Point at which to break the segment
|
* @param aPoint Point at which to break the segment
|
||||||
* @param aAppend Add the changes to the previous undo state
|
* @param aAppend Add the changes to the previous undo state
|
||||||
* @param aNewSegment Pointer to the newly created segment (if given and created)
|
* @param aNewSegment Pointer to the newly created segment (if given and created)
|
||||||
|
* @param aScreen is the screen to examine, or nullptr to examine the current screen
|
||||||
* @return True if any wires or buses were broken.
|
* @return True if any wires or buses were broken.
|
||||||
*/
|
*/
|
||||||
bool BreakSegment( SCH_LINE* aSegment, const wxPoint& aPoint, bool aAppend = false,
|
bool BreakSegment( SCH_LINE* aSegment, const wxPoint& aPoint,
|
||||||
SCH_LINE** aNewSegment = NULL );
|
bool aAppend = false, SCH_LINE** aNewSegment = NULL,
|
||||||
|
SCH_SCREEN* aScreen = nullptr );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks every wire and bus for a intersection at \a aPoint and break into two segments
|
* Checks every wire and bus for a intersection at \a aPoint and break into two segments
|
||||||
@ -458,18 +503,22 @@ public:
|
|||||||
*
|
*
|
||||||
* @param aPoint Test this point for an intersection.
|
* @param aPoint Test this point for an intersection.
|
||||||
* @param aAppend Add the changes to the previous undo state
|
* @param aAppend Add the changes to the previous undo state
|
||||||
|
* @param aScreen is the screen to examine, or nullptr to examine the current screen
|
||||||
* @return True if any wires or buses were broken.
|
* @return True if any wires or buses were broken.
|
||||||
*/
|
*/
|
||||||
bool BreakSegments( const wxPoint& aPoint, bool aAppend = false );
|
bool BreakSegments( const wxPoint& aPoint, bool aAppend = false,
|
||||||
|
SCH_SCREEN* aScreen = nullptr );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests all junctions and bus entries in the schematic for intersections with wires and
|
* Tests all junctions and bus entries in the schematic for intersections with wires and
|
||||||
* buses and breaks any intersections into multiple segments.
|
* buses and breaks any intersections into multiple segments.
|
||||||
*
|
*
|
||||||
* @param aAppend Add the changes to the previous undo state
|
* @param aAppend Add the changes to the previous undo state
|
||||||
|
* @param aScreen is the screen to examine, or nullptr to examine the current screen
|
||||||
* @return True if any wires or buses were broken.
|
* @return True if any wires or buses were broken.
|
||||||
*/
|
*/
|
||||||
bool BreakSegmentsOnJunctions( bool aApped = false );
|
bool BreakSegmentsOnJunctions( bool aApped = false,
|
||||||
|
SCH_SCREEN* aScreen = nullptr );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test all of the connectable objects in the schematic for unused connection points.
|
* Test all of the connectable objects in the schematic for unused connection points.
|
||||||
@ -795,6 +844,27 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool AskToSaveChanges();
|
bool AskToSaveChanges();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a bus unfolding operation is in progress, so that it can be
|
||||||
|
* properly canceled / commited along with the wire draw operation.
|
||||||
|
*/
|
||||||
|
bool IsBusUnfoldInProgress()
|
||||||
|
{
|
||||||
|
return m_busUnfold.in_progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancels a bus unfolding operation, cleaning up the bus entry and label
|
||||||
|
* that were created
|
||||||
|
*/
|
||||||
|
void CancelBusUnfold();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Completes a bus unfolding operation after the user finishes drawing the
|
||||||
|
* unfolded wire
|
||||||
|
*/
|
||||||
|
void FinishBusUnfold();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -835,6 +905,11 @@ private:
|
|||||||
*/
|
*/
|
||||||
void OnOrient( wxCommandEvent& aEvent );
|
void OnOrient( wxCommandEvent& aEvent );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the keyboard hotkey for unfolding a bus
|
||||||
|
*/
|
||||||
|
void OnUnfoldBusHotkey( wxCommandEvent& event );
|
||||||
|
|
||||||
void OnExit( wxCommandEvent& event );
|
void OnExit( wxCommandEvent& event );
|
||||||
void OnAnnotate( wxCommandEvent& event );
|
void OnAnnotate( wxCommandEvent& event );
|
||||||
void OnErc( wxCommandEvent& event );
|
void OnErc( wxCommandEvent& event );
|
||||||
@ -843,6 +918,7 @@ private:
|
|||||||
void OnSimulate( wxCommandEvent& event );
|
void OnSimulate( wxCommandEvent& event );
|
||||||
void OnCreateBillOfMaterials( wxCommandEvent& event );
|
void OnCreateBillOfMaterials( wxCommandEvent& event );
|
||||||
void OnLaunchBomManager( wxCommandEvent& event );
|
void OnLaunchBomManager( wxCommandEvent& event );
|
||||||
|
void OnLaunchBusManager( wxCommandEvent& event );
|
||||||
void OnFindItems( wxCommandEvent& event );
|
void OnFindItems( wxCommandEvent& event );
|
||||||
void OnFindDialogClose( wxFindDialogEvent& event );
|
void OnFindDialogClose( wxFindDialogEvent& event );
|
||||||
void OnFindDrcMarker( wxFindDialogEvent& event );
|
void OnFindDrcMarker( wxFindDialogEvent& event );
|
||||||
@ -952,9 +1028,10 @@ private:
|
|||||||
* deleting identical objects superimposed on top of each other.
|
* deleting identical objects superimposed on top of each other.
|
||||||
*
|
*
|
||||||
* @param aAppend The changes to the schematic should be appended to the previous undo
|
* @param aAppend The changes to the schematic should be appended to the previous undo
|
||||||
|
* @param aScreen is the screen to examine, or nullptr to examine the current screen
|
||||||
* @return True if any schematic clean up was performed.
|
* @return True if any schematic clean up was performed.
|
||||||
*/
|
*/
|
||||||
bool SchematicCleanUp( bool aAppend = false );
|
bool SchematicCleanUp( bool aAppend = false, SCH_SCREEN* aScreen = nullptr );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If any single wire passes through _both points_, remove the portion between the two points,
|
* If any single wire passes through _both points_, remove the portion between the two points,
|
||||||
@ -1475,6 +1552,11 @@ public:
|
|||||||
|
|
||||||
wxString GetNetListerCommand() const { return m_netListerCommand; }
|
wxString GetNetListerCommand() const { return m_netListerCommand; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates the connection data for the entire schematic hierarchy.
|
||||||
|
*/
|
||||||
|
void RecalculateConnections();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates netlist and sends it to pcbnew.
|
* Updates netlist and sends it to pcbnew.
|
||||||
* @param aUpdateOptions is a string defining update options:
|
* @param aUpdateOptions is a string defining update options:
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include <trace_helpers.h>
|
#include <trace_helpers.h>
|
||||||
#include <sch_item_struct.h>
|
#include <sch_item_struct.h>
|
||||||
#include <sch_screen.h>
|
#include <sch_screen.h>
|
||||||
|
#include <sch_sheet_path.h>
|
||||||
#include <sch_draw_panel.h>
|
#include <sch_draw_panel.h>
|
||||||
#include <sch_edit_frame.h>
|
#include <sch_edit_frame.h>
|
||||||
|
|
||||||
@ -85,6 +86,49 @@ bool SCH_ITEM::IsConnected( const wxPoint& aPosition ) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SCH_CONNECTION* SCH_ITEM::Connection( const SCH_SHEET_PATH& aSheet ) const
|
||||||
|
{
|
||||||
|
SCH_CONNECTION* conn = nullptr;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
conn = m_connection_map.at( aSheet );
|
||||||
|
}
|
||||||
|
catch( const std::out_of_range& oor )
|
||||||
|
{
|
||||||
|
// TODO(JE) should we just call InitializeConnection here?
|
||||||
|
}
|
||||||
|
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::unordered_set<SCH_ITEM*>& SCH_ITEM::ConnectedItems()
|
||||||
|
{
|
||||||
|
return m_connected_items;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_ITEM::AddConnectionTo( SCH_ITEM* aItem )
|
||||||
|
{
|
||||||
|
m_connected_items.insert( aItem );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_ITEM::InitializeConnection( const SCH_SHEET_PATH& aSheet )
|
||||||
|
{
|
||||||
|
if( Connection( aSheet ) )
|
||||||
|
{
|
||||||
|
Connection( aSheet )->Reset();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto connection = new SCH_CONNECTION( this );
|
||||||
|
connection->SetSheet( aSheet );
|
||||||
|
m_connection_map.insert( std::make_pair( aSheet, connection ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_ITEM::SwapData( SCH_ITEM* aItem )
|
void SCH_ITEM::SwapData( SCH_ITEM* aItem )
|
||||||
{
|
{
|
||||||
wxFAIL_MSG( wxT( "SwapData() method not implemented for class " ) + GetClass() );
|
wxFAIL_MSG( wxT( "SwapData() method not implemented for class " ) + GetClass() );
|
||||||
|
@ -30,12 +30,16 @@
|
|||||||
#ifndef SCH_ITEM_STRUCT_H
|
#ifndef SCH_ITEM_STRUCT_H
|
||||||
#define SCH_ITEM_STRUCT_H
|
#define SCH_ITEM_STRUCT_H
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <base_screen.h>
|
#include <base_screen.h>
|
||||||
#include <general.h>
|
#include <general.h>
|
||||||
|
#include <sch_connection.h>
|
||||||
|
#include <sch_sheet_path.h>
|
||||||
|
|
||||||
class SCH_ITEM;
|
class SCH_ITEM;
|
||||||
class SCH_SHEET_PATH;
|
//class SCH_SHEET_PATH;
|
||||||
class LINE_READER;
|
class LINE_READER;
|
||||||
class SCH_EDIT_FRAME;
|
class SCH_EDIT_FRAME;
|
||||||
class wxFindReplaceData;
|
class wxFindReplaceData;
|
||||||
@ -69,7 +73,7 @@ class DANGLING_END_ITEM
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
/// A pointer to the connectable object.
|
/// A pointer to the connectable object.
|
||||||
const EDA_ITEM* m_item;
|
EDA_ITEM* m_item;
|
||||||
|
|
||||||
/// The position of the connection point.
|
/// The position of the connection point.
|
||||||
wxPoint m_pos;
|
wxPoint m_pos;
|
||||||
@ -81,7 +85,7 @@ private:
|
|||||||
const EDA_ITEM* m_parent;
|
const EDA_ITEM* m_parent;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DANGLING_END_ITEM( DANGLING_END_T aType, const EDA_ITEM* aItem, const wxPoint& aPosition )
|
DANGLING_END_ITEM( DANGLING_END_T aType, EDA_ITEM* aItem, const wxPoint& aPosition )
|
||||||
{
|
{
|
||||||
m_item = aItem;
|
m_item = aItem;
|
||||||
m_type = aType;
|
m_type = aType;
|
||||||
@ -89,7 +93,7 @@ public:
|
|||||||
m_parent = aItem;
|
m_parent = aItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
DANGLING_END_ITEM( DANGLING_END_T aType, const EDA_ITEM* aItem,
|
DANGLING_END_ITEM( DANGLING_END_T aType, EDA_ITEM* aItem,
|
||||||
const wxPoint& aPosition, const EDA_ITEM* aParent )
|
const wxPoint& aPosition, const EDA_ITEM* aParent )
|
||||||
{
|
{
|
||||||
m_item = aItem;
|
m_item = aItem;
|
||||||
@ -99,7 +103,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
wxPoint GetPosition() const { return m_pos; }
|
wxPoint GetPosition() const { return m_pos; }
|
||||||
const EDA_ITEM* GetItem() const { return m_item; }
|
EDA_ITEM* GetItem() const { return m_item; }
|
||||||
const EDA_ITEM* GetParent() const { return m_parent; }
|
const EDA_ITEM* GetParent() const { return m_parent; }
|
||||||
DANGLING_END_T GetType() const { return m_type; }
|
DANGLING_END_T GetType() const { return m_type; }
|
||||||
};
|
};
|
||||||
@ -114,12 +118,20 @@ public:
|
|||||||
*/
|
*/
|
||||||
class SCH_ITEM : public EDA_ITEM
|
class SCH_ITEM : public EDA_ITEM
|
||||||
{
|
{
|
||||||
|
friend class CONNECTION_GRAPH;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SCH_LAYER_ID m_Layer;
|
SCH_LAYER_ID m_Layer;
|
||||||
EDA_ITEMS m_connections; ///< List of items connected to this item.
|
EDA_ITEMS m_connections; ///< List of items connected to this item.
|
||||||
wxPoint m_storedPos; ///< a temporary variable used in some move commands
|
wxPoint m_storedPos; ///< a temporary variable used in some move commands
|
||||||
///> to store a initial pos (of the item or mouse cursor)
|
///> to store a initial pos (of the item or mouse cursor)
|
||||||
|
|
||||||
|
/// Stores pointers to other items that are connected to this one (schematic only)
|
||||||
|
std::unordered_set<SCH_ITEM*> m_connected_items;
|
||||||
|
|
||||||
|
/// Stores connectivity information, per sheet
|
||||||
|
std::unordered_map<SCH_SHEET_PATH, SCH_CONNECTION*> m_connection_map;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SCH_ITEM( EDA_ITEM* aParent, KICAD_T aType );
|
SCH_ITEM( EDA_ITEM* aParent, KICAD_T aType );
|
||||||
|
|
||||||
@ -312,6 +324,33 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool IsConnected( const wxPoint& aPoint ) const;
|
bool IsConnected( const wxPoint& aPoint ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the connection associated with this object in the given sheet
|
||||||
|
*/
|
||||||
|
SCH_CONNECTION* Connection( const SCH_SHEET_PATH& aPath ) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the set of items connected to this item (schematic only)
|
||||||
|
*/
|
||||||
|
std::unordered_set<SCH_ITEM*>& ConnectedItems();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a connection link between this item and another
|
||||||
|
*/
|
||||||
|
void AddConnectionTo( SCH_ITEM* aItem );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new connection object associated with this object
|
||||||
|
*
|
||||||
|
* @param aPath is the sheet path to initialize
|
||||||
|
*/
|
||||||
|
void InitializeConnection( const SCH_SHEET_PATH& aPath );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if this item should propagate connection info to aItem
|
||||||
|
*/
|
||||||
|
virtual bool ConnectionPropagatesTo( const EDA_ITEM* aItem ) const { return true; }
|
||||||
|
|
||||||
virtual bool HitTest( const wxPoint& aPosition ) const override
|
virtual bool HitTest( const wxPoint& aPosition ) const override
|
||||||
{
|
{
|
||||||
return HitTest( aPosition, 0 );
|
return HitTest( aPosition, 0 );
|
||||||
|
@ -96,10 +96,14 @@ void SCH_JUNCTION::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffs
|
|||||||
{
|
{
|
||||||
COLOR4D color;
|
COLOR4D color;
|
||||||
|
|
||||||
|
auto conn = Connection( *g_CurrentSheet );
|
||||||
|
|
||||||
if( aColor != COLOR4D::UNSPECIFIED )
|
if( aColor != COLOR4D::UNSPECIFIED )
|
||||||
color = aColor;
|
color = aColor;
|
||||||
else
|
else
|
||||||
color = GetLayerColor( GetState( BRIGHTENED ) ? LAYER_BRIGHTENED : m_Layer );
|
color = GetLayerColor( GetState( BRIGHTENED ) ? LAYER_BRIGHTENED :
|
||||||
|
( conn && conn->IsBus() ) ?
|
||||||
|
LAYER_BUS : m_Layer );
|
||||||
|
|
||||||
GRSetDrawMode( aDC, aDrawMode );
|
GRSetDrawMode( aDC, aDrawMode );
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <boost/algorithm/string/join.hpp>
|
||||||
|
|
||||||
#include <wx/mstream.h>
|
#include <wx/mstream.h>
|
||||||
#include <wx/filename.h>
|
#include <wx/filename.h>
|
||||||
@ -45,6 +46,8 @@
|
|||||||
#include <sch_no_connect.h>
|
#include <sch_no_connect.h>
|
||||||
#include <sch_text.h>
|
#include <sch_text.h>
|
||||||
#include <sch_sheet.h>
|
#include <sch_sheet.h>
|
||||||
|
#include <sch_bitmap.h>
|
||||||
|
#include <bus_alias.h>
|
||||||
#include <sch_legacy_plugin.h>
|
#include <sch_legacy_plugin.h>
|
||||||
#include <template_fieldnames.h>
|
#include <template_fieldnames.h>
|
||||||
#include <sch_screen.h>
|
#include <sch_screen.h>
|
||||||
@ -759,6 +762,8 @@ void SCH_LEGACY_PLUGIN::loadFile( const wxString& aFileName, SCH_SCREEN* aScreen
|
|||||||
aScreen->Append( loadBusEntry( reader ) );
|
aScreen->Append( loadBusEntry( reader ) );
|
||||||
else if( strCompare( "Text", line ) )
|
else if( strCompare( "Text", line ) )
|
||||||
aScreen->Append( loadText( reader ) );
|
aScreen->Append( loadText( reader ) );
|
||||||
|
else if( strCompare( "BusAlias", line ) )
|
||||||
|
aScreen->AddBusAlias( loadBusAlias( reader, aScreen ) );
|
||||||
else if( strCompare( "$EndSCHEMATC", line ) )
|
else if( strCompare( "$EndSCHEMATC", line ) )
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1718,6 +1723,32 @@ SCH_COMPONENT* SCH_LEGACY_PLUGIN::loadComponent( FILE_LINE_READER& aReader )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::shared_ptr< BUS_ALIAS > SCH_LEGACY_PLUGIN::loadBusAlias( FILE_LINE_READER& aReader,
|
||||||
|
SCH_SCREEN* aScreen )
|
||||||
|
{
|
||||||
|
auto busAlias = std::make_shared< BUS_ALIAS >( aScreen );
|
||||||
|
const char* line = aReader.Line();
|
||||||
|
|
||||||
|
wxCHECK( strCompare( "BusAlias", line, &line ), NULL );
|
||||||
|
|
||||||
|
wxString buf;
|
||||||
|
parseUnquotedString( buf, aReader, line, &line );
|
||||||
|
busAlias->SetName( buf );
|
||||||
|
|
||||||
|
while( *line != '\0' )
|
||||||
|
{
|
||||||
|
buf.clear();
|
||||||
|
parseUnquotedString( buf, aReader, line, &line, true );
|
||||||
|
if( buf.Len() > 0 )
|
||||||
|
{
|
||||||
|
busAlias->AddMember( buf );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return busAlias;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_LEGACY_PLUGIN::Save( const wxString& aFileName, SCH_SCREEN* aScreen, KIWAY* aKiway,
|
void SCH_LEGACY_PLUGIN::Save( const wxString& aFileName, SCH_SCREEN* aScreen, KIWAY* aKiway,
|
||||||
const PROPERTIES* aProperties )
|
const PROPERTIES* aProperties )
|
||||||
{
|
{
|
||||||
@ -1782,6 +1813,11 @@ void SCH_LEGACY_PLUGIN::Format( SCH_SCREEN* aScreen )
|
|||||||
m_out->Print( 0, "Comment4 %s\n", EscapedUTF8( tb.GetComment4() ).c_str() );
|
m_out->Print( 0, "Comment4 %s\n", EscapedUTF8( tb.GetComment4() ).c_str() );
|
||||||
m_out->Print( 0, "$EndDescr\n" );
|
m_out->Print( 0, "$EndDescr\n" );
|
||||||
|
|
||||||
|
for( auto alias : aScreen->GetBusAliases() )
|
||||||
|
{
|
||||||
|
saveBusAlias( alias );
|
||||||
|
}
|
||||||
|
|
||||||
for( SCH_ITEM* item = aScreen->GetDrawItems(); item; item = item->Next() )
|
for( SCH_ITEM* item = aScreen->GetDrawItems(); item; item = item->Next() )
|
||||||
{
|
{
|
||||||
switch( item->Type() )
|
switch( item->Type() )
|
||||||
@ -2206,6 +2242,17 @@ void SCH_LEGACY_PLUGIN::saveText( SCH_TEXT* aText )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_LEGACY_PLUGIN::saveBusAlias( std::shared_ptr< BUS_ALIAS > aAlias )
|
||||||
|
{
|
||||||
|
wxCHECK_RET( aAlias != NULL, "BUS_ALIAS* is NULL" );
|
||||||
|
|
||||||
|
wxString members = boost::algorithm::join( aAlias->Members(), " " );
|
||||||
|
|
||||||
|
m_out->Print( 0, "BusAlias %s %s\n",
|
||||||
|
TO_UTF8( aAlias->GetName() ), TO_UTF8( members ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int SCH_LEGACY_PLUGIN_CACHE::m_modHash = 1; // starts at 1 and goes up
|
int SCH_LEGACY_PLUGIN_CACHE::m_modHash = 1; // starts at 1 and goes up
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <sch_io_mgr.h>
|
#include <sch_io_mgr.h>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
|
||||||
@ -44,6 +45,7 @@ class SCH_LEGACY_PLUGIN_CACHE;
|
|||||||
class LIB_PART;
|
class LIB_PART;
|
||||||
class PART_LIB;
|
class PART_LIB;
|
||||||
class LIB_ALIAS;
|
class LIB_ALIAS;
|
||||||
|
class BUS_ALIAS;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -145,6 +147,7 @@ private:
|
|||||||
SCH_BUS_ENTRY_BASE* loadBusEntry( FILE_LINE_READER& aReader );
|
SCH_BUS_ENTRY_BASE* loadBusEntry( FILE_LINE_READER& aReader );
|
||||||
SCH_TEXT* loadText( FILE_LINE_READER& aReader );
|
SCH_TEXT* loadText( FILE_LINE_READER& aReader );
|
||||||
SCH_COMPONENT* loadComponent( FILE_LINE_READER& aReader );
|
SCH_COMPONENT* loadComponent( FILE_LINE_READER& aReader );
|
||||||
|
std::shared_ptr< BUS_ALIAS > loadBusAlias( FILE_LINE_READER& aReader, SCH_SCREEN* aScreen );
|
||||||
|
|
||||||
void saveComponent( SCH_COMPONENT* aComponent );
|
void saveComponent( SCH_COMPONENT* aComponent );
|
||||||
void saveField( SCH_FIELD* aField );
|
void saveField( SCH_FIELD* aField );
|
||||||
@ -155,6 +158,7 @@ private:
|
|||||||
void saveBusEntry( SCH_BUS_ENTRY_BASE* aBusEntry );
|
void saveBusEntry( SCH_BUS_ENTRY_BASE* aBusEntry );
|
||||||
void saveLine( SCH_LINE* aLine );
|
void saveLine( SCH_LINE* aLine );
|
||||||
void saveText( SCH_TEXT* aText );
|
void saveText( SCH_TEXT* aText );
|
||||||
|
void saveBusAlias( std::shared_ptr< BUS_ALIAS > aAlias );
|
||||||
|
|
||||||
void cacheLib( const wxString& aLibraryFileName );
|
void cacheLib( const wxString& aLibraryFileName );
|
||||||
bool writeDocFile( const PROPERTIES* aProperties );
|
bool writeDocFile( const PROPERTIES* aProperties );
|
||||||
|
@ -781,6 +781,41 @@ wxPoint SCH_LINE::MidPoint()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_LINE::GetMsgPanelInfo( EDA_UNITS_T aUnits, MSG_PANEL_ITEMS& aList )
|
||||||
|
{
|
||||||
|
wxString msg;
|
||||||
|
|
||||||
|
switch( GetLayer() )
|
||||||
|
{
|
||||||
|
case LAYER_WIRE:
|
||||||
|
msg = _( "Net Wire" );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LAYER_BUS:
|
||||||
|
msg = _( "Bus Wire" );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
msg = _( "Graphical" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
aList.push_back( MSG_PANEL_ITEM( _( "Line Type" ), msg, DARKCYAN ) );
|
||||||
|
|
||||||
|
if( auto conn = Connection( *g_CurrentSheet ) )
|
||||||
|
{
|
||||||
|
#if defined(DEBUG)
|
||||||
|
conn->AppendDebugInfoToMsgPanel( aList );
|
||||||
|
|
||||||
|
msg.Printf( "%zu", m_connected_items.size() );
|
||||||
|
aList.push_back( MSG_PANEL_ITEM( _( "Connections" ), msg, BROWN ) );
|
||||||
|
#else
|
||||||
|
conn->AppendInfoToMsgPanel( aList );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int SCH_EDIT_FRAME::EditLine( SCH_LINE* aLine, bool aRedraw )
|
int SCH_EDIT_FRAME::EditLine( SCH_LINE* aLine, bool aRedraw )
|
||||||
{
|
{
|
||||||
if( aLine == NULL )
|
if( aLine == NULL )
|
||||||
|
@ -195,6 +195,8 @@ public:
|
|||||||
|
|
||||||
void SwapData( SCH_ITEM* aItem ) override;
|
void SwapData( SCH_ITEM* aItem ) override;
|
||||||
|
|
||||||
|
void GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList ) override;
|
||||||
|
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
void Show( int nestLevel, std::ostream& os ) const override;
|
void Show( int nestLevel, std::ostream& os ) const override;
|
||||||
#endif
|
#endif
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
#include <sch_no_connect.h>
|
#include <sch_no_connect.h>
|
||||||
#include <sch_bus_entry.h>
|
#include <sch_bus_entry.h>
|
||||||
#include <sch_bitmap.h>
|
#include <sch_bitmap.h>
|
||||||
|
#include <sch_sheet.h>
|
||||||
#include <draw_graphic_text.h>
|
#include <draw_graphic_text.h>
|
||||||
#include <geometry/geometry_utils.h>
|
#include <geometry/geometry_utils.h>
|
||||||
#include <lib_edit_frame.h>
|
#include <lib_edit_frame.h>
|
||||||
@ -54,6 +55,7 @@
|
|||||||
#include <view/view.h>
|
#include <view/view.h>
|
||||||
#include <gal/graphics_abstraction_layer.h>
|
#include <gal/graphics_abstraction_layer.h>
|
||||||
#include <colors_design_settings.h>
|
#include <colors_design_settings.h>
|
||||||
|
#include <connection_graph.h>
|
||||||
#include <geometry/shape_line_chain.h>
|
#include <geometry/shape_line_chain.h>
|
||||||
#include <bezier_curves.h>
|
#include <bezier_curves.h>
|
||||||
|
|
||||||
@ -167,6 +169,26 @@ bool SCH_PAINTER::Draw( const VIEW_ITEM *aItem, int aLayer )
|
|||||||
|
|
||||||
m_schSettings.ImportLegacyColors( nullptr );
|
m_schSettings.ImportLegacyColors( nullptr );
|
||||||
|
|
||||||
|
#ifdef CONNECTIVITY_DEBUG
|
||||||
|
|
||||||
|
auto sch_item = dynamic_cast<SCH_ITEM*>( item );
|
||||||
|
auto conn = sch_item ? sch_item->Connection( *g_CurrentSheet ) : nullptr;
|
||||||
|
|
||||||
|
if( conn )
|
||||||
|
{
|
||||||
|
auto pos = item->GetBoundingBox().Centre();
|
||||||
|
auto label = conn->Name( true );
|
||||||
|
|
||||||
|
m_gal->SetHorizontalJustify( GR_TEXT_HJUSTIFY_CENTER );
|
||||||
|
m_gal->SetVerticalJustify( GR_TEXT_VJUSTIFY_CENTER );
|
||||||
|
m_gal->SetStrokeColor( COLOR4D( LIGHTRED ) );
|
||||||
|
m_gal->SetLineWidth( 2 );
|
||||||
|
m_gal->SetGlyphSize( VECTOR2D( 20, 20 ) );
|
||||||
|
m_gal->StrokeText( conn->Name( true ), pos, 0.0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
switch( item->Type() )
|
switch( item->Type() )
|
||||||
{
|
{
|
||||||
HANDLE_ITEM(LIB_ALIAS_T, LIB_ALIAS);
|
HANDLE_ITEM(LIB_ALIAS_T, LIB_ALIAS);
|
||||||
@ -903,6 +925,10 @@ static void drawDanglingSymbol( GAL* aGal, const wxPoint& aPos )
|
|||||||
void SCH_PAINTER::draw( SCH_JUNCTION *aJct, int aLayer )
|
void SCH_PAINTER::draw( SCH_JUNCTION *aJct, int aLayer )
|
||||||
{
|
{
|
||||||
COLOR4D color = m_schSettings.GetLayerColor( LAYER_JUNCTION );
|
COLOR4D color = m_schSettings.GetLayerColor( LAYER_JUNCTION );
|
||||||
|
auto conn = aJct->Connection( *g_CurrentSheet );
|
||||||
|
|
||||||
|
if( conn && conn->IsBus() )
|
||||||
|
color = m_schSettings.GetLayerColor( LAYER_BUS );
|
||||||
|
|
||||||
if( aJct->GetState( BRIGHTENED ) )
|
if( aJct->GetState( BRIGHTENED ) )
|
||||||
color = m_schSettings.GetLayerColor( LAYER_BRIGHTENED );
|
color = m_schSettings.GetLayerColor( LAYER_BRIGHTENED );
|
||||||
@ -1003,6 +1029,13 @@ void SCH_PAINTER::draw( SCH_TEXT *aText, int aLayer )
|
|||||||
default: color = m_schSettings.GetLayerColor( LAYER_NOTES ); break;
|
default: color = m_schSettings.GetLayerColor( LAYER_NOTES ); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto conn = aText->Connection( *g_CurrentSheet );
|
||||||
|
|
||||||
|
if( conn && conn->IsBus() &&
|
||||||
|
( aText->Type() == SCH_SHEET_PIN_T ||
|
||||||
|
aText->Type() == SCH_HIERARCHICAL_LABEL_T ) )
|
||||||
|
color = m_schSettings.GetLayerColor( LAYER_BUS );
|
||||||
|
|
||||||
if( aText->GetState( BRIGHTENED ) )
|
if( aText->GetState( BRIGHTENED ) )
|
||||||
color = m_schSettings.GetLayerColor( LAYER_BRIGHTENED );
|
color = m_schSettings.GetLayerColor( LAYER_BRIGHTENED );
|
||||||
|
|
||||||
@ -1243,6 +1276,10 @@ void SCH_PAINTER::draw( SCH_HIERLABEL *aLabel, int aLayer )
|
|||||||
auto back_color = m_schSettings.GetLayerColor( LAYER_SCHEMATIC_BACKGROUND );
|
auto back_color = m_schSettings.GetLayerColor( LAYER_SCHEMATIC_BACKGROUND );
|
||||||
int width = aLabel->GetThickness() ? aLabel->GetThickness() : GetDefaultLineThickness();
|
int width = aLabel->GetThickness() ? aLabel->GetThickness() : GetDefaultLineThickness();
|
||||||
|
|
||||||
|
auto conn = aLabel->Connection( *g_CurrentSheet );
|
||||||
|
|
||||||
|
if( conn && conn->IsBus() )
|
||||||
|
color = m_schSettings.GetLayerColor( LAYER_BUS );
|
||||||
if( aLabel->GetState( BRIGHTENED ) )
|
if( aLabel->GetState( BRIGHTENED ) )
|
||||||
color = m_schSettings.GetLayerColor( LAYER_BRIGHTENED );
|
color = m_schSettings.GetLayerColor( LAYER_BRIGHTENED );
|
||||||
|
|
||||||
|
87
eeschema/sch_pin_connection.cpp
Normal file
87
eeschema/sch_pin_connection.cpp
Normal file
@ -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() );
|
||||||
|
}
|
77
eeschema/sch_pin_connection.h
Normal file
77
eeschema/sch_pin_connection.h
Normal file
@ -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
|
@ -38,6 +38,7 @@
|
|||||||
#include <kiway.h>
|
#include <kiway.h>
|
||||||
#include <sch_draw_panel.h>
|
#include <sch_draw_panel.h>
|
||||||
#include <sch_item_struct.h>
|
#include <sch_item_struct.h>
|
||||||
|
#include <draw_graphic_text.h>
|
||||||
#include <sch_edit_frame.h>
|
#include <sch_edit_frame.h>
|
||||||
#include <plotter.h>
|
#include <plotter.h>
|
||||||
|
|
||||||
@ -56,6 +57,11 @@
|
|||||||
#include <symbol_lib_table.h>
|
#include <symbol_lib_table.h>
|
||||||
#include <tool/common_tools.h>
|
#include <tool/common_tools.h>
|
||||||
|
|
||||||
|
// TODO(JE) Debugging only
|
||||||
|
#include <profile.h>
|
||||||
|
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
#define EESCHEMA_FILE_STAMP "EESchema"
|
#define EESCHEMA_FILE_STAMP "EESchema"
|
||||||
|
|
||||||
/* Default zoom values. Limited to these values to keep a decent size
|
/* Default zoom values. Limited to these values to keep a decent size
|
||||||
@ -198,6 +204,9 @@ void SCH_SCREEN::DeleteItem( SCH_ITEM* aItem )
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if( GetCurItem() == aItem )
|
||||||
|
SetCurItem( nullptr );
|
||||||
|
|
||||||
m_drawList.Remove( aItem );
|
m_drawList.Remove( aItem );
|
||||||
delete aItem;
|
delete aItem;
|
||||||
}
|
}
|
||||||
@ -411,6 +420,7 @@ bool SCH_SCREEN::IsTerminalPoint( const wxPoint& aPosition, int aLayer )
|
|||||||
|
|
||||||
SCH_SHEET_PIN* label;
|
SCH_SHEET_PIN* label;
|
||||||
SCH_TEXT* text;
|
SCH_TEXT* text;
|
||||||
|
SCH_CONNECTION conn;
|
||||||
|
|
||||||
switch( aLayer )
|
switch( aLayer )
|
||||||
{
|
{
|
||||||
@ -421,12 +431,12 @@ bool SCH_SCREEN::IsTerminalPoint( const wxPoint& aPosition, int aLayer )
|
|||||||
|
|
||||||
label = GetSheetLabel( aPosition );
|
label = GetSheetLabel( aPosition );
|
||||||
|
|
||||||
if( label && IsBusLabel( label->GetText() ) && label->IsConnected( aPosition ) )
|
if( label && conn.IsBusLabel( label->GetText() ) && label->IsConnected( aPosition ) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
text = GetLabel( aPosition );
|
text = GetLabel( aPosition );
|
||||||
|
|
||||||
if( text && IsBusLabel( text->GetText() ) && text->IsConnected( aPosition )
|
if( text && conn.IsBusLabel( text->GetText() ) && text->IsConnected( aPosition )
|
||||||
&& (text->Type() != SCH_LABEL_T) )
|
&& (text->Type() != SCH_LABEL_T) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
@ -457,12 +467,12 @@ bool SCH_SCREEN::IsTerminalPoint( const wxPoint& aPosition, int aLayer )
|
|||||||
|
|
||||||
text = GetLabel( aPosition );
|
text = GetLabel( aPosition );
|
||||||
|
|
||||||
if( text && text->IsConnected( aPosition ) && !IsBusLabel( text->GetText() ) )
|
if( text && text->IsConnected( aPosition ) && !conn.IsBusLabel( text->GetText() ) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
label = GetSheetLabel( aPosition );
|
label = GetSheetLabel( aPosition );
|
||||||
|
|
||||||
if( label && label->IsConnected( aPosition ) && !IsBusLabel( label->GetText() ) )
|
if( label && label->IsConnected( aPosition ) && !conn.IsBusLabel( label->GetText() ) )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -525,6 +535,23 @@ void SCH_SCREEN::Draw( EDA_DRAW_PANEL* aCanvas, wxDC* aDC, GR_DRAWMODE aDrawMode
|
|||||||
// uncomment line below when there is a virtual EDA_ITEM::GetBoundingBox()
|
// uncomment line below when there is a virtual EDA_ITEM::GetBoundingBox()
|
||||||
// if( panel->GetClipBox().Intersects( item->GetBoundingBox() ) )
|
// if( panel->GetClipBox().Intersects( item->GetBoundingBox() ) )
|
||||||
item->Draw( aCanvas, aDC, wxPoint( 0, 0 ), aDrawMode, aColor );
|
item->Draw( aCanvas, aDC, wxPoint( 0, 0 ), aDrawMode, aColor );
|
||||||
|
|
||||||
|
// TODO(JE) Remove debugging code
|
||||||
|
#ifdef DEBUG
|
||||||
|
|
||||||
|
auto conn = item->Connection( *g_CurrentSheet );
|
||||||
|
|
||||||
|
if( conn )
|
||||||
|
{
|
||||||
|
auto pos = item->GetBoundingBox().Centre();
|
||||||
|
int sz = Mils2iu( 15 );
|
||||||
|
auto label = conn->Name( true );
|
||||||
|
|
||||||
|
auto text = SCH_TEXT( pos, label, SCH_TEXT_T );
|
||||||
|
text.SetTextSize( wxSize( sz, sz ) );
|
||||||
|
text.Draw( aCanvas, aDC, wxPoint( 10, 10 ), aDrawMode, COLOR4D( LIGHTRED ) );
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
for( auto item : junctions )
|
for( auto item : junctions )
|
||||||
@ -1209,6 +1236,48 @@ int SCH_SCREEN::GetConnection( const wxPoint& aPosition, PICKED_ITEMS_LIST& aLis
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_SCREEN::AddBusAlias( std::shared_ptr<BUS_ALIAS> aAlias )
|
||||||
|
{
|
||||||
|
m_aliases.insert( aAlias );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SCH_SCREEN::IsBusAlias( const wxString& aLabel )
|
||||||
|
{
|
||||||
|
SCH_SHEET_LIST aSheets( g_RootSheet );
|
||||||
|
for( unsigned i = 0; i < aSheets.size(); i++ )
|
||||||
|
{
|
||||||
|
for( auto alias : aSheets[i].LastScreen()->GetBusAliases() )
|
||||||
|
{
|
||||||
|
if( alias->GetName() == aLabel )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::shared_ptr<BUS_ALIAS> SCH_SCREEN::GetBusAlias( const wxString& aLabel )
|
||||||
|
{
|
||||||
|
SCH_SHEET_LIST aSheets( g_RootSheet );
|
||||||
|
for( unsigned i = 0; i < aSheets.size(); i++ )
|
||||||
|
{
|
||||||
|
for( auto alias : aSheets[i].LastScreen()->GetBusAliases() )
|
||||||
|
{
|
||||||
|
if( alias->GetName() == aLabel )
|
||||||
|
{
|
||||||
|
return alias;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
void SCH_SCREEN::Show( int nestLevel, std::ostream& os ) const
|
void SCH_SCREEN::Show( int nestLevel, std::ostream& os ) const
|
||||||
{
|
{
|
||||||
|
@ -30,6 +30,8 @@
|
|||||||
#ifndef SCREEN_H
|
#ifndef SCREEN_H
|
||||||
#define SCREEN_H
|
#define SCREEN_H
|
||||||
|
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
#include <macros.h>
|
#include <macros.h>
|
||||||
#include <dlist.h>
|
#include <dlist.h>
|
||||||
#include <sch_item_struct.h>
|
#include <sch_item_struct.h>
|
||||||
@ -39,12 +41,14 @@
|
|||||||
#include <page_info.h>
|
#include <page_info.h>
|
||||||
#include <kiway_player.h>
|
#include <kiway_player.h>
|
||||||
#include <sch_marker.h>
|
#include <sch_marker.h>
|
||||||
|
#include <bus_alias.h>
|
||||||
|
|
||||||
#include <../eeschema/general.h>
|
#include <../eeschema/general.h>
|
||||||
|
|
||||||
|
|
||||||
class LIB_PIN;
|
class LIB_PIN;
|
||||||
class SCH_COMPONENT;
|
class SCH_COMPONENT;
|
||||||
|
class SCH_SHEET_LIST;
|
||||||
class SCH_SHEET_PATH;
|
class SCH_SHEET_PATH;
|
||||||
class SCH_SHEET_PIN;
|
class SCH_SHEET_PIN;
|
||||||
class SCH_LINE;
|
class SCH_LINE;
|
||||||
@ -95,6 +99,9 @@ private:
|
|||||||
int m_modification_sync; ///< inequality with PART_LIBS::GetModificationHash()
|
int m_modification_sync; ///< inequality with PART_LIBS::GetModificationHash()
|
||||||
///< will trigger ResolveAll().
|
///< will trigger ResolveAll().
|
||||||
|
|
||||||
|
/// List of bus aliases stored in this screen
|
||||||
|
std::unordered_set< std::shared_ptr< BUS_ALIAS > > m_aliases;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add items connected at \a aPosition to the block pick list.
|
* Add items connected at \a aPosition to the block pick list.
|
||||||
* <p>
|
* <p>
|
||||||
@ -509,6 +516,38 @@ public:
|
|||||||
*/
|
*/
|
||||||
int UpdatePickList();
|
int UpdatePickList();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a bus alias definition (and transfers ownership of the pointer)
|
||||||
|
*/
|
||||||
|
void AddBusAlias( std::shared_ptr<BUS_ALIAS> aAlias );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all bus alias definitions
|
||||||
|
*/
|
||||||
|
void ClearBusAliases()
|
||||||
|
{
|
||||||
|
m_aliases.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a list of bus aliases defined in this screen
|
||||||
|
*/
|
||||||
|
std::unordered_set< std::shared_ptr<BUS_ALIAS> > GetBusAliases()
|
||||||
|
{
|
||||||
|
return m_aliases;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the given string is a valid bus alias in a loaded screen
|
||||||
|
*/
|
||||||
|
static bool IsBusAlias( const wxString& aLabel );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a pointer to a bus alias object for the given label,
|
||||||
|
* or null if one doesn't exist
|
||||||
|
*/
|
||||||
|
static std::shared_ptr<BUS_ALIAS> GetBusAlias( const wxString& aLabel );
|
||||||
|
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
void Show( int nestLevel, std::ostream& os ) const override;
|
void Show( int nestLevel, std::ostream& os ) const override;
|
||||||
#endif
|
#endif
|
||||||
|
@ -926,7 +926,8 @@ void SCH_SHEET::GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
|
|||||||
item->m_Start = item->m_End = m_pins[i].GetPosition();
|
item->m_Start = item->m_End = m_pins[i].GetPosition();
|
||||||
aNetListItems.push_back( item );
|
aNetListItems.push_back( item );
|
||||||
|
|
||||||
if( IsBusLabel( m_pins[i].GetText() ) )
|
SCH_CONNECTION conn;
|
||||||
|
if( conn.IsBusLabel( m_pins[i].GetText() ) )
|
||||||
item->ConvertBusToNetListItems( aNetListItems );
|
item->ConvertBusToNetListItems( aNetListItems );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -573,6 +573,6 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef std::vector< SCH_SHEET* > SCH_SHEETS; // no ownership over contained SCH_SHEETs
|
//typedef std::vector< SCH_SHEET* > SCH_SHEETS; // no ownership over contained SCH_SHEETs
|
||||||
|
|
||||||
#endif // SCH_SHEEET_H
|
#endif // SCH_SHEEET_H
|
||||||
|
@ -38,13 +38,29 @@
|
|||||||
#include <class_library.h>
|
#include <class_library.h>
|
||||||
#include <sch_sheet_path.h>
|
#include <sch_sheet_path.h>
|
||||||
#include <sch_component.h>
|
#include <sch_component.h>
|
||||||
|
#include <sch_sheet.h>
|
||||||
#include <template_fieldnames.h>
|
#include <template_fieldnames.h>
|
||||||
|
|
||||||
#include <dialogs/dialog_schematic_find.h>
|
#include <dialogs/dialog_schematic_find.h>
|
||||||
|
|
||||||
|
#include <boost/functional/hash.hpp>
|
||||||
#include <wx/filename.h>
|
#include <wx/filename.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
size_t hash<SCH_SHEET_PATH>::operator()( const SCH_SHEET_PATH& path ) const
|
||||||
|
{
|
||||||
|
size_t seed = 0;
|
||||||
|
|
||||||
|
for( auto sheet : path )
|
||||||
|
boost::hash_combine( seed, sheet->GetTimeStamp() );
|
||||||
|
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SCH_SHEET_PATH::SCH_SHEET_PATH()
|
SCH_SHEET_PATH::SCH_SHEET_PATH()
|
||||||
{
|
{
|
||||||
m_pageNumber = 0;
|
m_pageNumber = 0;
|
||||||
|
@ -78,9 +78,9 @@
|
|||||||
* (usable in flat and simple hierarchies).
|
* (usable in flat and simple hierarchies).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "sch_sheet.h" // SCH_SHEETS
|
|
||||||
|
|
||||||
class wxFindReplaceData;
|
class wxFindReplaceData;
|
||||||
|
class SCH_SHEET;
|
||||||
class SCH_SCREEN;
|
class SCH_SCREEN;
|
||||||
class SCH_MARKER;
|
class SCH_MARKER;
|
||||||
class SCH_ITEM;
|
class SCH_ITEM;
|
||||||
@ -89,6 +89,8 @@ class SCH_REFERENCE_LIST;
|
|||||||
|
|
||||||
#define SHEET_NOT_FOUND -1
|
#define SHEET_NOT_FOUND -1
|
||||||
|
|
||||||
|
typedef std::vector< SCH_SHEET* > SCH_SHEETS; // no ownership over contained SCH_SHEETs
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type SCH_MULTI_UNIT_REFERENCE_MAP
|
* Type SCH_MULTI_UNIT_REFERENCE_MAP
|
||||||
@ -304,6 +306,15 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
template<> struct hash<SCH_SHEET_PATH>
|
||||||
|
{
|
||||||
|
size_t operator()( const SCH_SHEET_PATH& path ) const;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef std::vector< SCH_SHEET_PATH > SCH_SHEET_PATHS;
|
typedef std::vector< SCH_SHEET_PATH > SCH_SHEET_PATHS;
|
||||||
typedef SCH_SHEET_PATHS::iterator SCH_SHEET_PATHS_ITER;
|
typedef SCH_SHEET_PATHS::iterator SCH_SHEET_PATHS_ITER;
|
||||||
typedef SCH_SHEET_PATHS::const_iterator SCH_SHEET_PATHS_CITER;
|
typedef SCH_SHEET_PATHS::const_iterator SCH_SHEET_PATHS_CITER;
|
||||||
|
@ -113,6 +113,7 @@ SCH_TEXT::SCH_TEXT( const wxPoint& pos, const wxString& text, KICAD_T aType ) :
|
|||||||
m_Layer = LAYER_NOTES;
|
m_Layer = LAYER_NOTES;
|
||||||
SetTextPos( pos );
|
SetTextPos( pos );
|
||||||
m_isDangling = false;
|
m_isDangling = false;
|
||||||
|
m_connectionType = CONNECTION_NONE;
|
||||||
m_spin_style = 0;
|
m_spin_style = 0;
|
||||||
|
|
||||||
SetMultilineAllowed( true );
|
SetMultilineAllowed( true );
|
||||||
@ -361,6 +362,7 @@ bool SCH_TEXT::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList )
|
|||||||
|
|
||||||
bool previousState = m_isDangling;
|
bool previousState = m_isDangling;
|
||||||
m_isDangling = true;
|
m_isDangling = true;
|
||||||
|
m_connectionType = CONNECTION_NONE;
|
||||||
|
|
||||||
for( unsigned ii = 0; ii < aItemList.size(); ii++ )
|
for( unsigned ii = 0; ii < aItemList.size(); ii++ )
|
||||||
{
|
{
|
||||||
@ -376,12 +378,21 @@ bool SCH_TEXT::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList )
|
|||||||
case SHEET_LABEL_END:
|
case SHEET_LABEL_END:
|
||||||
case NO_CONNECT_END:
|
case NO_CONNECT_END:
|
||||||
if( GetTextPos() == item.GetPosition() )
|
if( GetTextPos() == item.GetPosition() )
|
||||||
|
{
|
||||||
m_isDangling = false;
|
m_isDangling = false;
|
||||||
|
|
||||||
|
if( item.GetType() != PIN_END )
|
||||||
|
m_connected_items.insert( static_cast< SCH_ITEM* >( item.GetItem() ) );
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WIRE_START_END:
|
|
||||||
case BUS_START_END:
|
case BUS_START_END:
|
||||||
|
m_connectionType = CONNECTION_BUS;
|
||||||
|
// fall through
|
||||||
|
|
||||||
|
case WIRE_START_END:
|
||||||
{
|
{
|
||||||
// These schematic items have created 2 DANGLING_END_ITEM one per end. But being
|
// These schematic items have created 2 DANGLING_END_ITEM one per end. But being
|
||||||
// a paranoid programmer, I'll check just in case.
|
// a paranoid programmer, I'll check just in case.
|
||||||
@ -392,6 +403,18 @@ bool SCH_TEXT::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList )
|
|||||||
|
|
||||||
DANGLING_END_ITEM & nextItem = aItemList[ii];
|
DANGLING_END_ITEM & nextItem = aItemList[ii];
|
||||||
m_isDangling = !IsPointOnSegment( item.GetPosition(), nextItem.GetPosition(), GetTextPos() );
|
m_isDangling = !IsPointOnSegment( item.GetPosition(), nextItem.GetPosition(), GetTextPos() );
|
||||||
|
|
||||||
|
if( !m_isDangling )
|
||||||
|
{
|
||||||
|
if( m_connectionType != CONNECTION_BUS )
|
||||||
|
m_connectionType = CONNECTION_NET;
|
||||||
|
|
||||||
|
// Add the line to the connected items, since it won't be picked
|
||||||
|
// up by a search of intersecting connection points
|
||||||
|
auto sch_item = static_cast< SCH_ITEM* >( item.GetItem() );
|
||||||
|
AddConnectionTo( sch_item );
|
||||||
|
sch_item->AddConnectionTo( this );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -403,6 +426,9 @@ bool SCH_TEXT::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList )
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( m_isDangling )
|
||||||
|
m_connectionType = CONNECTION_NONE;
|
||||||
|
|
||||||
return previousState != m_isDangling;
|
return previousState != m_isDangling;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -492,8 +518,10 @@ void SCH_TEXT::GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
|
|||||||
aNetListItems.push_back( item );
|
aNetListItems.push_back( item );
|
||||||
|
|
||||||
// If a bus connects to label
|
// If a bus connects to label
|
||||||
if( IsBusLabel( m_Text ) )
|
if( Connection( *aSheetPath )->IsBusLabel( m_Text ) )
|
||||||
|
{
|
||||||
item->ConvertBusToNetListItems( aNetListItems );
|
item->ConvertBusToNetListItems( aNetListItems );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -629,6 +657,18 @@ void SCH_TEXT::GetMsgPanelInfo( EDA_UNITS_T aUnits, MSG_PANEL_ITEMS& aList )
|
|||||||
// Display text size (X or Y value, with are the same value in Eeschema)
|
// Display text size (X or Y value, with are the same value in Eeschema)
|
||||||
msg = MessageTextFromValue( aUnits, GetTextWidth(), true );
|
msg = MessageTextFromValue( aUnits, GetTextWidth(), true );
|
||||||
aList.push_back( MSG_PANEL_ITEM( _( "Size" ), msg, RED ) );
|
aList.push_back( MSG_PANEL_ITEM( _( "Size" ), msg, RED ) );
|
||||||
|
|
||||||
|
#if defined(DEBUG)
|
||||||
|
|
||||||
|
if( auto conn = Connection( *g_CurrentSheet ) )
|
||||||
|
{
|
||||||
|
conn->AppendDebugInfoToMsgPanel( aList );
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.Printf( "%p", this );
|
||||||
|
aList.push_back( MSG_PANEL_ITEM( _( "Object Address" ), msg, RED ) );
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(DEBUG)
|
#if defined(DEBUG)
|
||||||
@ -1066,10 +1106,14 @@ void SCH_HIERLABEL::Draw( EDA_DRAW_PANEL* panel,
|
|||||||
|
|
||||||
linewidth = Clamp_Text_PenSize( linewidth, GetTextSize(), IsBold() );
|
linewidth = Clamp_Text_PenSize( linewidth, GetTextSize(), IsBold() );
|
||||||
|
|
||||||
|
auto conn = Connection( *g_CurrentSheet );
|
||||||
|
|
||||||
if( Color != COLOR4D::UNSPECIFIED )
|
if( Color != COLOR4D::UNSPECIFIED )
|
||||||
color = Color;
|
color = Color;
|
||||||
else
|
else
|
||||||
color = GetLayerColor( GetState( BRIGHTENED ) ? LAYER_BRIGHTENED : m_Layer );
|
color = GetLayerColor( GetState( BRIGHTENED ) ? LAYER_BRIGHTENED :
|
||||||
|
( conn && conn->IsBus() ) ?
|
||||||
|
LAYER_BUS : m_Layer );
|
||||||
|
|
||||||
GRSetDrawMode( DC, DrawMode );
|
GRSetDrawMode( DC, DrawMode );
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include <macros.h>
|
#include <macros.h>
|
||||||
#include <eda_text.h>
|
#include <eda_text.h>
|
||||||
#include <sch_item_struct.h>
|
#include <sch_item_struct.h>
|
||||||
|
#include <sch_connection.h> // for CONNECTION_TYPE
|
||||||
|
|
||||||
|
|
||||||
class LINE_READER;
|
class LINE_READER;
|
||||||
@ -64,6 +65,8 @@ protected:
|
|||||||
/// supports connections.
|
/// supports connections.
|
||||||
bool m_isDangling;
|
bool m_isDangling;
|
||||||
|
|
||||||
|
CONNECTION_TYPE m_connectionType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The orientation of text and any associated drawing elements of derived objects.
|
* The orientation of text and any associated drawing elements of derived objects.
|
||||||
* 0 is the horizontal and left justified.
|
* 0 is the horizontal and left justified.
|
||||||
|
@ -279,16 +279,16 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
|
|||||||
|
|
||||||
if( item && (item->Type() == SCH_SHEET_T) )
|
if( item && (item->Type() == SCH_SHEET_T) )
|
||||||
{
|
{
|
||||||
m_CurrentSheet->push_back( (SCH_SHEET*) item );
|
g_CurrentSheet->push_back( (SCH_SHEET*) item );
|
||||||
DisplayCurrentSheet();
|
DisplayCurrentSheet();
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ID_POPUP_SCH_LEAVE_SHEET:
|
case ID_POPUP_SCH_LEAVE_SHEET:
|
||||||
if( m_CurrentSheet->Last() != g_RootSheet )
|
if( g_CurrentSheet->Last() != g_RootSheet )
|
||||||
{
|
{
|
||||||
m_CurrentSheet->pop_back();
|
g_CurrentSheet->pop_back();
|
||||||
DisplayCurrentSheet();
|
DisplayCurrentSheet();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,6 +376,81 @@ void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_EDIT_FRAME::OnUnfoldBus( wxCommandEvent& event )
|
||||||
|
{
|
||||||
|
auto screen = GetScreen();
|
||||||
|
auto item = static_cast< wxMenuItem* >( event.GetEventUserData() );
|
||||||
|
auto net = item->GetItemLabelText();
|
||||||
|
|
||||||
|
auto pos = GetCrossHairPosition();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unfolding a bus consists of the following user inputs:
|
||||||
|
* 1) User selects a bus to unfold (see AddMenusForBus())
|
||||||
|
* We land in this event handler.
|
||||||
|
*
|
||||||
|
* 2) User clicks to set the net label location (handled by BeginSegment())
|
||||||
|
* Before this first click, the posture of the bus entry follows the
|
||||||
|
* mouse cursor in X and Y (handled by DrawSegment())
|
||||||
|
*
|
||||||
|
* 3) User is now in normal wiring mode and can exit in any normal way.
|
||||||
|
*/
|
||||||
|
|
||||||
|
wxASSERT( !m_busUnfold.in_progress );
|
||||||
|
|
||||||
|
m_busUnfold.entry = new SCH_BUS_WIRE_ENTRY( pos, '\\' );
|
||||||
|
|
||||||
|
SetSchItemParent( m_busUnfold.entry, screen );
|
||||||
|
AddToScreen( m_busUnfold.entry );
|
||||||
|
|
||||||
|
m_busUnfold.label = new SCH_LABEL( m_busUnfold.entry->m_End(), net );
|
||||||
|
|
||||||
|
m_busUnfold.label->SetTextSize( wxSize( GetDefaultTextSize(),
|
||||||
|
GetDefaultTextSize() ) );
|
||||||
|
m_busUnfold.label->SetLabelSpinStyle( 0 );
|
||||||
|
|
||||||
|
SetSchItemParent( m_busUnfold.label, screen );
|
||||||
|
|
||||||
|
m_busUnfold.in_progress = true;
|
||||||
|
m_busUnfold.origin = pos;
|
||||||
|
m_busUnfold.net_name = net;
|
||||||
|
|
||||||
|
SetToolID( ID_WIRE_BUTT, wxCURSOR_PENCIL, _( "Add wire" ) );
|
||||||
|
|
||||||
|
SetCrossHairPosition( m_busUnfold.entry->m_End() );
|
||||||
|
BeginSegment( LAYER_WIRE );
|
||||||
|
m_canvas->SetAutoPanRequest( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_EDIT_FRAME::CancelBusUnfold()
|
||||||
|
{
|
||||||
|
if( m_busUnfold.entry )
|
||||||
|
{
|
||||||
|
RemoveFromScreen( m_busUnfold.entry );
|
||||||
|
delete m_busUnfold.entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_busUnfold.label )
|
||||||
|
{
|
||||||
|
if( m_busUnfold.label_placed )
|
||||||
|
RemoveFromScreen( m_busUnfold.label );
|
||||||
|
|
||||||
|
delete m_busUnfold.label;
|
||||||
|
}
|
||||||
|
|
||||||
|
FinishBusUnfold();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_EDIT_FRAME::FinishBusUnfold()
|
||||||
|
{
|
||||||
|
m_busUnfold = {};
|
||||||
|
|
||||||
|
SetToolID( ID_NO_TOOL_SELECTED, GetGalCanvas()->GetDefaultCursor(), wxEmptyString );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_EDIT_FRAME::OnMoveItem( wxCommandEvent& aEvent )
|
void SCH_EDIT_FRAME::OnMoveItem( wxCommandEvent& aEvent )
|
||||||
{
|
{
|
||||||
SCH_SCREEN* screen = GetScreen();
|
SCH_SCREEN* screen = GetScreen();
|
||||||
@ -1058,17 +1133,17 @@ void SCH_EDIT_FRAME::OnEditItem( wxCommandEvent& aEvent )
|
|||||||
// Keep trace of existing sheet paths. EditSheet() can modify this list
|
// Keep trace of existing sheet paths. EditSheet() can modify this list
|
||||||
SCH_SHEET_LIST initial_sheetpathList( g_RootSheet );
|
SCH_SHEET_LIST initial_sheetpathList( g_RootSheet );
|
||||||
|
|
||||||
doRefresh = EditSheet( (SCH_SHEET*) item, m_CurrentSheet, &doClearAnnotation );
|
doRefresh = EditSheet( (SCH_SHEET*) item, g_CurrentSheet, &doClearAnnotation );
|
||||||
|
|
||||||
if( doClearAnnotation ) // happens when the current sheet load a existing file
|
if( doClearAnnotation ) // happens when the current sheet load a existing file
|
||||||
{ // we must clear "new" components annotation
|
{ // we must clear "new" components annotation
|
||||||
SCH_SCREENS screensList( g_RootSheet );
|
SCH_SCREENS screensList( g_RootSheet );
|
||||||
// We clear annotation of new sheet paths here:
|
// We clear annotation of new sheet paths here:
|
||||||
screensList.ClearAnnotationOfNewSheetPaths( initial_sheetpathList );
|
screensList.ClearAnnotationOfNewSheetPaths( initial_sheetpathList );
|
||||||
// Clear annotation of m_CurrentSheet itself, because its sheetpath
|
// Clear annotation of g_CurrentSheet itself, because its sheetpath
|
||||||
// is not a new path, but components managed by its sheet path must have
|
// is not a new path, but components managed by its sheet path must have
|
||||||
// their annotation cleared, becuase they are new:
|
// their annotation cleared, becuase they are new:
|
||||||
((SCH_SHEET*) item)->GetScreen()->ClearAnnotation( m_CurrentSheet );
|
((SCH_SHEET*) item)->GetScreen()->ClearAnnotation( g_CurrentSheet );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( doRefresh )
|
if( doRefresh )
|
||||||
@ -1331,3 +1406,77 @@ void SCH_EDIT_FRAME::OnOrient( wxCommandEvent& aEvent )
|
|||||||
if( item->GetFlags() == 0 )
|
if( item->GetFlags() == 0 )
|
||||||
screen->SetCurItem( NULL );
|
screen->SetCurItem( NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_EDIT_FRAME::OnUnfoldBusHotkey( wxCommandEvent& aEvent )
|
||||||
|
{
|
||||||
|
auto data = (EDA_HOTKEY_CLIENT_DATA*) aEvent.GetClientObject();
|
||||||
|
auto item = GetScreen()->GetCurItem();
|
||||||
|
|
||||||
|
wxCHECK_RET( data != NULL, wxT( "Invalid hot key client object." ) );
|
||||||
|
|
||||||
|
if( item == NULL )
|
||||||
|
{
|
||||||
|
// If we didn't get here by a hot key, then something has gone wrong.
|
||||||
|
if( aEvent.GetInt() == 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
item = LocateAndShowItem( data->GetPosition(), SCH_COLLECTOR::EditableItems,
|
||||||
|
aEvent.GetInt() );
|
||||||
|
|
||||||
|
// Exit if no item found at the current location or the item is already being edited.
|
||||||
|
if( (item == NULL) || (item->GetFlags() != 0) )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto connection = item->Connection( *g_CurrentSheet );
|
||||||
|
|
||||||
|
if( connection && connection->IsBus() )
|
||||||
|
{
|
||||||
|
int idx = 0;
|
||||||
|
wxMenu* bus_unfolding_menu = new wxMenu;
|
||||||
|
|
||||||
|
for( const auto& member : connection->Members() )
|
||||||
|
{
|
||||||
|
int id = ID_POPUP_SCH_UNFOLD_BUS + ( idx++ );
|
||||||
|
|
||||||
|
if( member->Type() == CONNECTION_BUS )
|
||||||
|
{
|
||||||
|
wxMenu* submenu = new wxMenu;
|
||||||
|
bus_unfolding_menu->AppendSubMenu( submenu, _( member->Name() ) );
|
||||||
|
|
||||||
|
for( const auto& sub_member : member->Members() )
|
||||||
|
{
|
||||||
|
id = ID_POPUP_SCH_UNFOLD_BUS + ( idx++ );
|
||||||
|
|
||||||
|
submenu->Append( id, sub_member->Name(), wxEmptyString );
|
||||||
|
|
||||||
|
// See comment in else clause below
|
||||||
|
auto sub_item_clone = new wxMenuItem();
|
||||||
|
sub_item_clone->SetItemLabel( sub_member->Name() );
|
||||||
|
|
||||||
|
Bind( wxEVT_COMMAND_MENU_SELECTED, &SCH_EDIT_FRAME::OnUnfoldBus,
|
||||||
|
this, id, id, sub_item_clone );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bus_unfolding_menu->Append( id, member->Name(),
|
||||||
|
wxEmptyString );
|
||||||
|
|
||||||
|
// Because Bind() takes ownership of the user data item, we
|
||||||
|
// make a new menu item here and set its label. Why create a
|
||||||
|
// menu item instead of just a wxString or something? Because
|
||||||
|
// Bind() requires a pointer to wxObject rather than a void
|
||||||
|
// pointer. Maybe at some point I'll think of a better way...
|
||||||
|
auto item_clone = new wxMenuItem();
|
||||||
|
item_clone->SetItemLabel( member->Name() );
|
||||||
|
|
||||||
|
Bind( wxEVT_COMMAND_MENU_SELECTED, &SCH_EDIT_FRAME::OnUnfoldBus,
|
||||||
|
this, id, id, item_clone );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GetGalCanvas()->PopupMenu( bus_unfolding_menu, GetCrossHairScreenPosition() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -121,6 +121,7 @@ enum KICAD_T
|
|||||||
SCH_COMPONENT_T,
|
SCH_COMPONENT_T,
|
||||||
SCH_SHEET_PIN_T,
|
SCH_SHEET_PIN_T,
|
||||||
SCH_SHEET_T,
|
SCH_SHEET_T,
|
||||||
|
SCH_PIN_CONNECTION_T,
|
||||||
|
|
||||||
// Be prudent with these 3 types:
|
// Be prudent with these 3 types:
|
||||||
// they should be used only to locate a specific field type
|
// they should be used only to locate a specific field type
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
|
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
|
||||||
* Copyright (C) 2004-2013 KiCad Developers, see change_log.txt for contributors.
|
* Copyright (C) 2004-2013 KiCad Developers, see change_log.txt for contributors.
|
||||||
|
* Copyright (C) 2018 CERN
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or
|
* This program is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU General Public License
|
* modify it under the terms of the GNU General Public License
|
||||||
@ -32,6 +33,7 @@
|
|||||||
|
|
||||||
#include <wx/valtext.h>
|
#include <wx/valtext.h>
|
||||||
#include <wx/grid.h>
|
#include <wx/grid.h>
|
||||||
|
#include <wx/regex.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class GRID_CELL_TEXT_EDITOR
|
* Class GRID_CELL_TEXT_EDITOR
|
||||||
@ -112,6 +114,66 @@ public:
|
|||||||
void OnTextChanged( wxCommandEvent& event );
|
void OnTextChanged( wxCommandEvent& event );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom validator that checks verifies that a string *exactly* matches a
|
||||||
|
* regular expression.
|
||||||
|
*/
|
||||||
|
class REGEX_VALIDATOR : public wxTextValidator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param aRegEx is a regular expression to validate strings.
|
||||||
|
* @param aValue is a pointer to a wxString containing the value to validate.
|
||||||
|
*/
|
||||||
|
REGEX_VALIDATOR( const wxString& aRegEx, wxString* aValue = NULL )
|
||||||
|
: wxTextValidator( wxFILTER_NONE, aValue )
|
||||||
|
{
|
||||||
|
compileRegEx( aRegEx, wxRE_DEFAULT );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param aRegEx is a regular expression to validate strings.
|
||||||
|
* @param aFlags are compilation flags (normally wxRE_DEFAULT).
|
||||||
|
* @param aValue is a pointer to a wxString containing the value to validate.
|
||||||
|
*/
|
||||||
|
REGEX_VALIDATOR( const wxString& aRegEx, int aFlags, wxString* aValue = NULL )
|
||||||
|
: wxTextValidator( wxFILTER_NONE, aValue )
|
||||||
|
{
|
||||||
|
compileRegEx( aRegEx, aFlags );
|
||||||
|
}
|
||||||
|
|
||||||
|
REGEX_VALIDATOR( const REGEX_VALIDATOR& aOther )
|
||||||
|
{
|
||||||
|
wxValidator::Copy( aOther );
|
||||||
|
compileRegEx( aOther.m_regExString, aOther.m_regExFlags );
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual wxObject* Clone() const override
|
||||||
|
{
|
||||||
|
return new REGEX_VALIDATOR( *this );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Validate( wxWindow* aParent ) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
///> Compiles and stores a regular expression
|
||||||
|
void compileRegEx( const wxString& aRegEx, int aFlags );
|
||||||
|
|
||||||
|
///> Original regular expression (for copy constructor)
|
||||||
|
wxString m_regExString;
|
||||||
|
|
||||||
|
///> Original compilation flags (for copy constructor)
|
||||||
|
int m_regExFlags;
|
||||||
|
|
||||||
|
///> Compiled regex
|
||||||
|
wxRegEx m_regEx;
|
||||||
|
};
|
||||||
|
|
||||||
namespace KIUI
|
namespace KIUI
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
Loading…
x
Reference in New Issue
Block a user