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_package( Boost 1.54.0 REQUIRED )
|
||||
find_package( Boost 1.54.0 REQUIRED COMPONENTS regex )
|
||||
|
||||
# Include MinGW resource compiler.
|
||||
include( MinGWResourceCompiler )
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
*
|
||||
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
|
||||
* 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
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -28,6 +29,7 @@
|
|||
*/
|
||||
|
||||
#include <kicad_string.h>
|
||||
#include <confirm.h>
|
||||
#include <validators.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 )
|
||||
{
|
||||
wxWindow* ctrl = aValidator.GetWindow();
|
||||
|
|
|
@ -37,6 +37,7 @@ set( EESCHEMA_DLGS
|
|||
dialogs/dialog_bom.cpp
|
||||
dialogs/dialog_bom_base.cpp
|
||||
dialogs/dialog_bom_cfg_keywords.cpp
|
||||
dialogs/dialog_bus_manager.cpp
|
||||
dialogs/dialog_fields_editor_global.cpp
|
||||
dialogs/dialog_fields_editor_global_base.cpp
|
||||
dialogs/dialog_choose_component.cpp
|
||||
|
@ -64,6 +65,8 @@ set( EESCHEMA_DLGS
|
|||
dialogs/dialog_lib_edit_text_base.cpp
|
||||
dialogs/dialog_lib_new_component.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_base.cpp
|
||||
dialogs/dialog_plot_schematic.cpp
|
||||
|
@ -136,6 +139,7 @@ set( EESCHEMA_SRCS
|
|||
autoplace_fields.cpp
|
||||
backanno.cpp
|
||||
block.cpp
|
||||
bus_alias.cpp
|
||||
bus-wire-junction.cpp
|
||||
busentry.cpp
|
||||
class_libentry.cpp
|
||||
|
@ -144,6 +148,7 @@ set( EESCHEMA_SRCS
|
|||
cmp_library_lexer.cpp
|
||||
component_references_lister.cpp
|
||||
controle.cpp
|
||||
connection_graph.cpp
|
||||
cross-probing.cpp
|
||||
drc_erc_item.cpp
|
||||
edit_bitmap.cpp
|
||||
|
@ -195,6 +200,7 @@ set( EESCHEMA_SRCS
|
|||
sch_bus_entry.cpp
|
||||
sch_collectors.cpp
|
||||
sch_component.cpp
|
||||
sch_connection.cpp
|
||||
sch_eagle_plugin.cpp
|
||||
sch_field.cpp
|
||||
sch_io_mgr.cpp
|
||||
|
@ -204,6 +210,7 @@ set( EESCHEMA_SRCS
|
|||
sch_line.cpp
|
||||
sch_marker.cpp
|
||||
sch_no_connect.cpp
|
||||
sch_pin_connection.cpp
|
||||
sch_plugin.cpp
|
||||
sch_preview_panel.cpp
|
||||
sch_screen.cpp
|
||||
|
|
|
@ -62,7 +62,7 @@ void SCH_EDIT_FRAME::DeleteAnnotation( bool aCurrentSheetOnly )
|
|||
{
|
||||
SCH_SCREEN* screen = GetScreen();
|
||||
wxCHECK_RET( screen != NULL, wxT( "Attempt to clear annotation of a NULL screen." ) );
|
||||
screen->ClearAnnotation( m_CurrentSheet );
|
||||
screen->ClearAnnotation( g_CurrentSheet );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -71,7 +71,7 @@ void SCH_EDIT_FRAME::DeleteAnnotation( bool aCurrentSheetOnly )
|
|||
}
|
||||
|
||||
// Update the references for the sheet that is currently being displayed.
|
||||
m_CurrentSheet->UpdateAllScreenReferences();
|
||||
g_CurrentSheet->UpdateAllScreenReferences();
|
||||
|
||||
SyncView();
|
||||
GetCanvas()->Refresh();
|
||||
|
@ -125,7 +125,7 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic,
|
|||
}
|
||||
else
|
||||
{
|
||||
m_CurrentSheet->GetMultiUnitComponents( lockedComponents );
|
||||
g_CurrentSheet->GetMultiUnitComponents( lockedComponents );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,7 +146,7 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic,
|
|||
}
|
||||
else
|
||||
{
|
||||
m_CurrentSheet->GetComponents( references );
|
||||
g_CurrentSheet->GetComponents( references );
|
||||
}
|
||||
|
||||
// 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 );
|
||||
|
||||
// Update on screen references, that can be modified by previous calculations:
|
||||
m_CurrentSheet->UpdateAllScreenReferences();
|
||||
g_CurrentSheet->UpdateAllScreenReferences();
|
||||
SetSheetNumberAndCount();
|
||||
|
||||
SyncView();
|
||||
|
@ -252,7 +252,7 @@ int SCH_EDIT_FRAME::CheckAnnotate( REPORTER& aReporter, bool aOneSheetOnly )
|
|||
if( !aOneSheetOnly )
|
||||
sheetList.GetComponents( componentsList );
|
||||
else
|
||||
m_CurrentSheet->GetComponents( componentsList );
|
||||
g_CurrentSheet->GetComponents( componentsList );
|
||||
|
||||
return componentsList.CheckAnnotation( aReporter );
|
||||
}
|
||||
|
|
|
@ -455,7 +455,7 @@ void SCH_EDIT_FRAME::PasteListOfItems( wxDC* DC )
|
|||
return;
|
||||
}
|
||||
|
||||
wxFileName destFn = m_CurrentSheet->Last()->GetFileName();
|
||||
wxFileName destFn = g_CurrentSheet->Last()->GetFileName();
|
||||
|
||||
if( destFn.IsRelative() )
|
||||
destFn.MakeAbsolute( Prj().GetProjectPath() );
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include <sch_text.h>
|
||||
#include <sch_component.h>
|
||||
#include <sch_sheet.h>
|
||||
#include <list_operations.h>
|
||||
#include <sch_view.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,
|
||||
// stores here the new wires.
|
||||
|
||||
|
||||
/**
|
||||
* In a contiguous list of wires, remove wires that backtrack over the previous
|
||||
* wire. Example:
|
||||
|
@ -130,15 +130,49 @@ static void DrawSegment( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aPosi
|
|||
|
||||
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: */
|
||||
ComputeBreakPoint( frame->GetScreen(), (SCH_LINE*) s_wires.GetLast()->Back(), endpos );
|
||||
else
|
||||
( (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() )
|
||||
{
|
||||
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.
|
||||
{
|
||||
// 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();
|
||||
|
||||
// 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 );
|
||||
|
||||
// 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();
|
||||
return;
|
||||
|
@ -328,6 +387,18 @@ void SCH_EDIT_FRAME::EndSegment()
|
|||
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).
|
||||
SetRepeatItem( segment = (SCH_LINE*) s_wires.GetLast() );
|
||||
|
||||
|
@ -366,7 +437,13 @@ void SCH_EDIT_FRAME::EndSegment()
|
|||
AddJunction( i, true );
|
||||
}
|
||||
|
||||
if( IsBusUnfoldInProgress() )
|
||||
{
|
||||
FinishBusUnfold();
|
||||
}
|
||||
|
||||
TestDanglingEnds();
|
||||
|
||||
screen->ClearDrawingState();
|
||||
screen->SetCurItem( NULL );
|
||||
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* secondItem = NULL;
|
||||
PICKED_ITEMS_LIST itemList;
|
||||
SCH_SCREEN* screen = GetScreen();
|
||||
|
||||
if( aScreen == nullptr )
|
||||
aScreen = GetScreen();
|
||||
|
||||
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 ) );
|
||||
};
|
||||
|
||||
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 )
|
||||
&& ( item->Type() != SCH_JUNCTION_T )
|
||||
|
@ -591,7 +670,7 @@ bool SCH_EDIT_FRAME::SchematicCleanUp( bool aAppend )
|
|||
|
||||
// Remove unneeded junctions
|
||||
if( ( item->Type() == SCH_JUNCTION_T )
|
||||
&& ( !screen->IsJunctionNeeded( item->GetPosition() ) ) )
|
||||
&& ( !aScreen->IsJunctionNeeded( item->GetPosition() ) ) )
|
||||
{
|
||||
remove_item( item );
|
||||
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( secondLine->IsEndPoint( firstLine->GetStartPoint() ) )
|
||||
needed = screen->IsJunctionNeeded( firstLine->GetStartPoint() );
|
||||
needed = aScreen->IsJunctionNeeded( firstLine->GetStartPoint() );
|
||||
else if( secondLine->IsEndPoint( firstLine->GetEndPoint() ) )
|
||||
needed = screen->IsJunctionNeeded( firstLine->GetEndPoint() );
|
||||
needed = aScreen->IsJunctionNeeded( firstLine->GetEndPoint() );
|
||||
|
||||
if( !needed && ( line = (SCH_LINE*) secondLine->MergeOverlap( firstLine ) ) )
|
||||
{
|
||||
remove_item( item );
|
||||
remove_item( secondItem );
|
||||
itemList.PushItem( ITEM_PICKER( line, UR_NEW ) );
|
||||
AddToScreen( line );
|
||||
AddToScreen( line, aScreen );
|
||||
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();
|
||||
|
||||
if( item->GetFlags() & STRUCT_DELETED )
|
||||
RemoveFromScreen( item );
|
||||
RemoveFromScreen( item, aScreen );
|
||||
}
|
||||
|
||||
SaveCopyInUndoList( itemList, UR_CHANGED, aAppend );
|
||||
|
||||
return itemList.GetCount() > 0;
|
||||
}
|
||||
|
||||
|
||||
bool SCH_EDIT_FRAME::BreakSegment( SCH_LINE* aSegment, const wxPoint& aPoint, bool aAppend,
|
||||
SCH_LINE** aNewSegment )
|
||||
bool SCH_EDIT_FRAME::BreakSegment( SCH_LINE* aSegment, const wxPoint& aPoint,
|
||||
bool aAppend, SCH_LINE** aNewSegment,
|
||||
SCH_SCREEN* aScreen )
|
||||
{
|
||||
if( !IsPointOnSegment( aSegment->GetStartPoint(), aSegment->GetEndPoint(), aPoint )
|
||||
|| aSegment->IsEndPoint( aPoint ) )
|
||||
return false;
|
||||
|
||||
SaveCopyInUndoList( aSegment, UR_CHANGED, aAppend );
|
||||
if( aScreen == nullptr )
|
||||
aScreen = GetScreen();
|
||||
|
||||
SCH_LINE* newSegment = new SCH_LINE( *aSegment );
|
||||
SaveCopyInUndoList( newSegment, UR_NEW, true );
|
||||
|
||||
newSegment->SetStartPoint( aPoint );
|
||||
AddToScreen( newSegment );
|
||||
AddToScreen( newSegment, aScreen );
|
||||
|
||||
RefreshItem( aSegment );
|
||||
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;
|
||||
|
||||
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 ) )
|
||||
continue;
|
||||
|
||||
brokenSegments |= BreakSegment( (SCH_LINE*) segment, aPoint, aAppend || brokenSegments );
|
||||
brokenSegments |= BreakSegment( (SCH_LINE*) segment, aPoint,
|
||||
aAppend || brokenSegments, NULL, aScreen );
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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 )
|
||||
{
|
||||
SCH_JUNCTION* junction = ( SCH_JUNCTION* ) item;
|
||||
|
||||
if( BreakSegments( junction->GetPosition(), brokenSegments || aAppend ) )
|
||||
if( BreakSegments( junction->GetPosition(), brokenSegments || aAppend, aScreen ) )
|
||||
brokenSegments = true;
|
||||
}
|
||||
else
|
||||
|
@ -725,8 +812,8 @@ bool SCH_EDIT_FRAME::BreakSegmentsOnJunctions( bool aAppend )
|
|||
SCH_BUS_ENTRY_BASE* busEntry = dynamic_cast<SCH_BUS_ENTRY_BASE*>( item );
|
||||
if( busEntry )
|
||||
{
|
||||
if( BreakSegments( busEntry->GetPosition(), brokenSegments || aAppend )
|
||||
|| BreakSegments( busEntry->m_End(), brokenSegments || aAppend ) )
|
||||
if( BreakSegments( busEntry->GetPosition(), brokenSegments || aAppend, aScreen )
|
||||
|| BreakSegments( busEntry->m_End(), brokenSegments || aAppend, aScreen ) )
|
||||
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 )
|
||||
{
|
||||
SCH_SCREEN* screen = (SCH_SCREEN*) aPanel->GetScreen();
|
||||
|
||||
SCH_EDIT_FRAME* parent = ( SCH_EDIT_FRAME* ) aPanel->GetParent();
|
||||
|
||||
if( screen->GetCurItem() )
|
||||
|
@ -858,6 +946,11 @@ static void AbortCreateNewLine( EDA_DRAW_PANEL* aPanel, wxDC* aDC )
|
|||
parent->SetRepeatItem( NULL );
|
||||
}
|
||||
|
||||
if( parent->IsBusUnfoldInProgress() )
|
||||
{
|
||||
parent->CancelBusUnfold();
|
||||
}
|
||||
|
||||
auto view = static_cast<SCH_DRAW_PANEL*>(aPanel)->GetView();
|
||||
view->ClearPreview();
|
||||
view->ShowPreview( false );
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2018 CERN
|
||||
* @author Jon Evans <jon@craftyjon.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "bus_alias.h"
|
||||
|
||||
|
||||
BUS_ALIAS::BUS_ALIAS( SCH_SCREEN* aParent ) :
|
||||
m_parent( aParent )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
BUS_ALIAS::~BUS_ALIAS()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool BUS_ALIAS::Contains( const wxString& aName )
|
||||
{
|
||||
return ( std::find( m_members.begin(), m_members.end(), aName )
|
||||
!= m_members.end() );
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2018 CERN
|
||||
* @author Jon Evans <jon@craftyjon.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _BUS_ALIAS_H
|
||||
#define _BUS_ALIAS_H
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <wx/string.h>
|
||||
|
||||
|
||||
class SCH_SCREEN;
|
||||
|
||||
|
||||
class BUS_ALIAS
|
||||
{
|
||||
public:
|
||||
BUS_ALIAS( SCH_SCREEN* aParent = NULL );
|
||||
|
||||
~BUS_ALIAS();
|
||||
|
||||
std::shared_ptr< BUS_ALIAS > Clone() const
|
||||
{
|
||||
return std::make_shared< BUS_ALIAS >( *this );
|
||||
}
|
||||
|
||||
wxString GetName()
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
void SetName( const wxString& aName )
|
||||
{
|
||||
m_name = aName;
|
||||
}
|
||||
|
||||
void ClearMembers()
|
||||
{
|
||||
m_members.clear();
|
||||
}
|
||||
|
||||
void AddMember( const wxString& aName )
|
||||
{
|
||||
m_members.push_back( aName );
|
||||
}
|
||||
|
||||
int GetMemberCount()
|
||||
{
|
||||
return m_members.size();
|
||||
}
|
||||
|
||||
std::vector< wxString >& Members()
|
||||
{
|
||||
return m_members;
|
||||
}
|
||||
|
||||
bool Contains( const wxString& aName );
|
||||
|
||||
SCH_SCREEN* GetParent()
|
||||
{
|
||||
return m_parent;
|
||||
}
|
||||
|
||||
void SetParent( SCH_SCREEN* aParent )
|
||||
{
|
||||
m_parent = aParent;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
wxString m_name;
|
||||
|
||||
std::vector< wxString > m_members;
|
||||
|
||||
/**
|
||||
* The bus alias editor dialog can edit aliases from all open sheets.
|
||||
* This means we have to store a reference back to our parent so that
|
||||
* the dialog can update the parent if aliases are changed or removed.
|
||||
*/
|
||||
SCH_SCREEN* m_parent;
|
||||
};
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -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->Type() == SCH_COMPONENT_T )
|
||||
( (SCH_COMPONENT*) item )->SetCurrentSheetPath( &GetCurrentSheet() );
|
||||
|
||||
MSG_PANEL_ITEMS items;
|
||||
item->GetMsgPanelInfo( m_UserUnits, items );
|
||||
SetMsgPanel( items );
|
||||
|
|
|
@ -0,0 +1,517 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2018 CERN
|
||||
* @author Jon Evans <jon@craftyjon.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <wx/tokenzr.h>
|
||||
|
||||
#include <invoke_sch_dialog.h>
|
||||
#include <sch_sheet_path.h>
|
||||
|
||||
#include "dialog_bus_manager.h"
|
||||
|
||||
|
||||
BEGIN_EVENT_TABLE( DIALOG_BUS_MANAGER, DIALOG_SHIM )
|
||||
EVT_BUTTON( wxID_OK, DIALOG_BUS_MANAGER::OnOkClick )
|
||||
EVT_BUTTON( wxID_CANCEL, DIALOG_BUS_MANAGER::OnCancelClick )
|
||||
END_EVENT_TABLE()
|
||||
|
||||
|
||||
DIALOG_BUS_MANAGER::DIALOG_BUS_MANAGER( SCH_EDIT_FRAME* aParent )
|
||||
: DIALOG_SHIM( aParent, wxID_ANY, _( "Bus Definitions" ),
|
||||
wxDefaultPosition, wxSize( 640, 480 ),
|
||||
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER ),
|
||||
m_parent( aParent )
|
||||
{
|
||||
auto sizer = new wxBoxSizer( wxVERTICAL );
|
||||
auto buttons = new wxStdDialogButtonSizer();
|
||||
|
||||
buttons->AddButton( new wxButton( this, wxID_OK ) );
|
||||
buttons->AddButton( new wxButton( this, wxID_CANCEL ) );
|
||||
buttons->Realize();
|
||||
|
||||
auto top_container = new wxBoxSizer( wxHORIZONTAL );
|
||||
auto left_pane = new wxBoxSizer( wxVERTICAL );
|
||||
auto right_pane = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
// Left pane: alias list
|
||||
auto lbl_aliases = new wxStaticText( this, wxID_ANY, _( "Bus Aliases" ),
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
wxALIGN_LEFT );
|
||||
|
||||
m_bus_list_view = new wxListView( this, wxID_ANY, wxDefaultPosition,
|
||||
wxSize( 300, 300 ), wxLC_ALIGN_LEFT |
|
||||
wxLC_NO_HEADER | wxLC_REPORT |
|
||||
wxLC_SINGLE_SEL );
|
||||
m_bus_list_view->InsertColumn( 0, "" );
|
||||
|
||||
auto lbl_alias_edit = new wxStaticText( this, wxID_ANY, _( "Alias Name" ),
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
wxALIGN_LEFT );
|
||||
|
||||
m_bus_edit = new wxTextCtrl( this, wxID_ANY, wxEmptyString,
|
||||
wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
|
||||
|
||||
auto left_button_sizer = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
m_btn_add_bus = new wxButton( this, wxID_ANY, _( "Add" ) );
|
||||
m_btn_rename_bus = new wxButton( this, wxID_ANY, _( "Rename" ) );
|
||||
m_btn_remove_bus = new wxButton( this, wxID_ANY, _( "Remove" ) );
|
||||
|
||||
left_button_sizer->Add( m_btn_add_bus );
|
||||
left_button_sizer->Add( m_btn_rename_bus );
|
||||
left_button_sizer->Add( m_btn_remove_bus );
|
||||
|
||||
left_pane->Add( lbl_aliases, 0, wxEXPAND | wxALL, 5 );
|
||||
left_pane->Add( m_bus_list_view, 1, wxEXPAND | wxALL, 5 );
|
||||
left_pane->Add( lbl_alias_edit, 0, wxEXPAND | wxALL, 5 );
|
||||
left_pane->Add( m_bus_edit, 0, wxEXPAND | wxALL, 5 );
|
||||
left_pane->Add( left_button_sizer, 0, wxEXPAND | wxALL, 5 );
|
||||
|
||||
// Right pane: signal list
|
||||
auto lbl_signals = new wxStaticText( this, wxID_ANY, _( "Alias Members" ),
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
wxALIGN_LEFT );
|
||||
|
||||
m_signal_list_view = new wxListView( this, wxID_ANY, wxDefaultPosition,
|
||||
wxSize( 300, 300 ), wxLC_ALIGN_LEFT |
|
||||
wxLC_NO_HEADER | wxLC_REPORT |
|
||||
wxLC_SINGLE_SEL );
|
||||
m_signal_list_view->InsertColumn( 0, "" );
|
||||
|
||||
auto lbl_signal_edit = new wxStaticText( this, wxID_ANY, _( "Member Name" ),
|
||||
wxDefaultPosition, wxDefaultSize,
|
||||
wxALIGN_LEFT );
|
||||
|
||||
m_signal_edit = new wxTextCtrl( this, wxID_ANY, wxEmptyString,
|
||||
wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER );
|
||||
|
||||
auto right_button_sizer = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
m_btn_add_signal = new wxButton( this, wxID_ANY, _( "Add" ) );
|
||||
m_btn_rename_signal = new wxButton( this, wxID_ANY, _( "Rename" ) );
|
||||
m_btn_remove_signal = new wxButton( this, wxID_ANY, _( "Remove" ) );
|
||||
|
||||
right_button_sizer->Add( m_btn_add_signal );
|
||||
right_button_sizer->Add( m_btn_rename_signal );
|
||||
right_button_sizer->Add( m_btn_remove_signal );
|
||||
|
||||
right_pane->Add( lbl_signals, 0, wxEXPAND | wxALL, 5 );
|
||||
right_pane->Add( m_signal_list_view, 1, wxEXPAND | wxALL, 5 );
|
||||
right_pane->Add( lbl_signal_edit, 0, wxEXPAND | wxALL, 5 );
|
||||
right_pane->Add( m_signal_edit, 0, wxEXPAND | wxALL, 5 );
|
||||
right_pane->Add( right_button_sizer, 0, wxEXPAND | wxALL, 5 );
|
||||
|
||||
top_container->Add( left_pane, 1, wxEXPAND );
|
||||
top_container->Add( right_pane, 1, wxEXPAND );
|
||||
|
||||
sizer->Add( top_container, 1, wxEXPAND | wxALL, 5 );
|
||||
sizer->Add( buttons, 0, wxEXPAND | wxBOTTOM, 10 );
|
||||
SetSizer( sizer );
|
||||
|
||||
// Setup validators
|
||||
|
||||
wxTextValidator validator;
|
||||
validator.SetStyle( wxFILTER_EXCLUDE_CHAR_LIST );
|
||||
validator.SetCharExcludes( "\r\n\t " );
|
||||
m_bus_edit->SetValidator( validator );
|
||||
|
||||
// Allow spaces in the signal edit, so that you can type in a list of
|
||||
// signals in the box and it can automatically split them when you add.
|
||||
validator.SetCharExcludes( "\r\n\t" );
|
||||
m_signal_edit->SetValidator( validator );
|
||||
|
||||
// Setup events
|
||||
|
||||
Bind( wxEVT_INIT_DIALOG, &DIALOG_BUS_MANAGER::OnInitDialog, this );
|
||||
m_bus_list_view->Connect( wxEVT_COMMAND_LIST_ITEM_DESELECTED,
|
||||
wxListEventHandler( DIALOG_BUS_MANAGER::OnSelectBus ), NULL, this );
|
||||
m_bus_list_view->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED,
|
||||
wxListEventHandler( DIALOG_BUS_MANAGER::OnSelectBus ), NULL, this );
|
||||
m_signal_list_view->Connect( wxEVT_COMMAND_LIST_ITEM_DESELECTED,
|
||||
wxListEventHandler( DIALOG_BUS_MANAGER::OnSelectSignal ), NULL, this );
|
||||
m_signal_list_view->Connect( wxEVT_COMMAND_LIST_ITEM_SELECTED,
|
||||
wxListEventHandler( DIALOG_BUS_MANAGER::OnSelectSignal ), NULL, this );
|
||||
|
||||
m_btn_add_bus->Connect( wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
wxCommandEventHandler( DIALOG_BUS_MANAGER::OnAddBus ), NULL, this );
|
||||
m_btn_rename_bus->Connect( wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
wxCommandEventHandler( DIALOG_BUS_MANAGER::OnRenameBus ), NULL, this );
|
||||
m_btn_remove_bus->Connect( wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
wxCommandEventHandler( DIALOG_BUS_MANAGER::OnRemoveBus ), NULL, this );
|
||||
m_signal_edit->Connect( wxEVT_TEXT_ENTER,
|
||||
wxCommandEventHandler( DIALOG_BUS_MANAGER::OnAddSignal ), NULL, this );
|
||||
|
||||
m_btn_add_signal->Connect( wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
wxCommandEventHandler( DIALOG_BUS_MANAGER::OnAddSignal ), NULL, this );
|
||||
m_btn_rename_signal->Connect( wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
wxCommandEventHandler( DIALOG_BUS_MANAGER::OnRenameSignal ), NULL, this );
|
||||
m_btn_remove_signal->Connect( wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
wxCommandEventHandler( DIALOG_BUS_MANAGER::OnRemoveSignal ), NULL, this );
|
||||
m_bus_edit->Connect( wxEVT_TEXT_ENTER,
|
||||
wxCommandEventHandler( DIALOG_BUS_MANAGER::OnAddBus ), NULL, this );
|
||||
|
||||
// Set initial UI state
|
||||
|
||||
m_btn_rename_bus->Disable();
|
||||
m_btn_remove_bus->Disable();
|
||||
|
||||
m_btn_add_signal->Disable();
|
||||
m_btn_rename_signal->Disable();
|
||||
m_btn_remove_signal->Disable();
|
||||
|
||||
m_bus_edit->SetHint( _T( "Bus Alias Name" ) );
|
||||
m_signal_edit->SetHint( _T( "Net or Bus Name" ) );
|
||||
|
||||
FinishDialogSettings();
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_BUS_MANAGER::OnInitDialog( wxInitDialogEvent& aEvent )
|
||||
{
|
||||
TransferDataToWindow();
|
||||
}
|
||||
|
||||
|
||||
bool DIALOG_BUS_MANAGER::TransferDataToWindow()
|
||||
{
|
||||
m_aliases.clear();
|
||||
|
||||
SCH_SHEET_LIST aSheets( g_RootSheet );
|
||||
std::vector< std::shared_ptr< BUS_ALIAS > > original_aliases;
|
||||
|
||||
// collect aliases from each open sheet
|
||||
for( unsigned i = 0; i < aSheets.size(); i++ )
|
||||
{
|
||||
auto sheet_aliases = aSheets[i].LastScreen()->GetBusAliases();
|
||||
original_aliases.insert( original_aliases.end(), sheet_aliases.begin(),
|
||||
sheet_aliases.end() );
|
||||
}
|
||||
|
||||
original_aliases.erase( std::unique( original_aliases.begin(),
|
||||
original_aliases.end() ),
|
||||
original_aliases.end() );
|
||||
|
||||
// clone into a temporary working set
|
||||
int idx = 0;
|
||||
for( auto alias : original_aliases )
|
||||
{
|
||||
m_aliases.push_back( alias->Clone() );
|
||||
auto text = getAliasDisplayText( alias );
|
||||
m_bus_list_view->InsertItem( idx, text );
|
||||
m_bus_list_view->SetItemPtrData( idx, wxUIntPtr( m_aliases[idx].get() ) );
|
||||
idx++;
|
||||
}
|
||||
|
||||
m_bus_list_view->SetColumnWidth( 0, -1 );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_BUS_MANAGER::OnOkClick( wxCommandEvent& aEvent )
|
||||
{
|
||||
if( TransferDataFromWindow() )
|
||||
{
|
||||
( ( SCH_EDIT_FRAME* )GetParent() )->OnModify();
|
||||
EndModal( wxID_OK );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_BUS_MANAGER::OnCancelClick( wxCommandEvent& aEvent )
|
||||
{
|
||||
EndModal( wxID_CANCEL );
|
||||
}
|
||||
|
||||
|
||||
bool DIALOG_BUS_MANAGER::TransferDataFromWindow()
|
||||
{
|
||||
// Since we have a clone of all the data, and it is from potentially
|
||||
// multiple screens, the way this works is to rebuild each screen's aliases.
|
||||
// A list of screens is stored here so that the screen's alias list is only
|
||||
// cleared once.
|
||||
|
||||
std::unordered_set< SCH_SCREEN* > cleared_list;
|
||||
|
||||
for( auto alias : m_aliases )
|
||||
{
|
||||
auto screen = alias->GetParent();
|
||||
|
||||
if( cleared_list.count( screen ) == 0 )
|
||||
{
|
||||
screen->ClearBusAliases();
|
||||
cleared_list.insert( screen );
|
||||
}
|
||||
|
||||
screen->AddBusAlias( alias );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_BUS_MANAGER::OnSelectBus( wxListEvent& event )
|
||||
{
|
||||
if( event.GetEventType() == wxEVT_COMMAND_LIST_ITEM_SELECTED )
|
||||
{
|
||||
auto alias = m_aliases[ event.GetIndex() ];
|
||||
|
||||
if( m_active_alias != alias )
|
||||
{
|
||||
m_active_alias = alias;
|
||||
|
||||
m_bus_edit->ChangeValue( alias->GetName() );
|
||||
|
||||
m_btn_add_bus->Disable();
|
||||
m_btn_rename_bus->Enable();
|
||||
m_btn_remove_bus->Enable();
|
||||
|
||||
auto members = alias->Members();
|
||||
|
||||
// TODO(JE) Clear() seems to be clearing the hint, contrary to
|
||||
// the wx documentation.
|
||||
m_signal_edit->Clear();
|
||||
m_signal_list_view->DeleteAllItems();
|
||||
|
||||
for( unsigned i = 0; i < members.size(); i++ )
|
||||
{
|
||||
m_signal_list_view->InsertItem( i, members[i] );
|
||||
}
|
||||
|
||||
m_signal_list_view->SetColumnWidth( 0, -1 );
|
||||
|
||||
m_btn_add_signal->Enable();
|
||||
m_btn_rename_signal->Disable();
|
||||
m_btn_remove_signal->Disable();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_active_alias = NULL;
|
||||
m_bus_edit->Clear();
|
||||
m_signal_edit->Clear();
|
||||
m_signal_list_view->DeleteAllItems();
|
||||
|
||||
m_btn_add_bus->Enable();
|
||||
m_btn_rename_bus->Disable();
|
||||
m_btn_remove_bus->Disable();
|
||||
|
||||
m_btn_add_signal->Disable();
|
||||
m_btn_rename_signal->Disable();
|
||||
m_btn_remove_signal->Disable();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_BUS_MANAGER::OnSelectSignal( wxListEvent& event )
|
||||
{
|
||||
if( event.GetEventType() == wxEVT_COMMAND_LIST_ITEM_SELECTED )
|
||||
{
|
||||
m_signal_edit->ChangeValue( event.GetText() );
|
||||
m_btn_rename_signal->Enable();
|
||||
m_btn_remove_signal->Enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_signal_edit->Clear();
|
||||
m_btn_rename_signal->Disable();
|
||||
m_btn_remove_signal->Disable();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_BUS_MANAGER::OnAddBus( wxCommandEvent& aEvent )
|
||||
{
|
||||
// If there is an active alias, then check that the user actually
|
||||
// changed the text in the edit box (we can't have duplicate aliases)
|
||||
|
||||
auto new_name = m_bus_edit->GetValue();
|
||||
|
||||
if( new_name.Length() == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for( auto alias : m_aliases )
|
||||
{
|
||||
if( alias->GetName() == new_name )
|
||||
{
|
||||
// TODO(JE) display error?
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if( !m_active_alias ||
|
||||
( m_active_alias && m_active_alias->GetName().Cmp( new_name ) ) )
|
||||
{
|
||||
// The values are different; create a new alias
|
||||
auto alias = std::make_shared<BUS_ALIAS>();
|
||||
alias->SetName( new_name );
|
||||
|
||||
// New aliases get stored on the currently visible sheet
|
||||
alias->SetParent( static_cast<SCH_EDIT_FRAME*>( GetParent() )->GetScreen() );
|
||||
auto text = getAliasDisplayText( alias );
|
||||
|
||||
m_aliases.push_back( alias );
|
||||
long idx = m_bus_list_view->InsertItem( m_aliases.size() - 1, text );
|
||||
m_bus_list_view->SetColumnWidth( 0, -1 );
|
||||
m_bus_list_view->Select( idx );
|
||||
m_bus_edit->Clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO(JE) Check about desired result here.
|
||||
// Maybe warn the user? Or just do nothing
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_BUS_MANAGER::OnRenameBus( wxCommandEvent& aEvent )
|
||||
{
|
||||
// We should only get here if there is an active alias
|
||||
wxASSERT( m_active_alias );
|
||||
|
||||
m_active_alias->SetName( m_bus_edit->GetValue() );
|
||||
long idx = m_bus_list_view->FindItem( -1, wxUIntPtr( m_active_alias.get() ) );
|
||||
|
||||
wxASSERT( idx >= 0 );
|
||||
|
||||
m_bus_list_view->SetItemText( idx, getAliasDisplayText( m_active_alias ) );
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_BUS_MANAGER::OnRemoveBus( wxCommandEvent& aEvent )
|
||||
{
|
||||
// We should only get here if there is an active alias
|
||||
wxASSERT( m_active_alias );
|
||||
long i = m_bus_list_view->GetFirstSelected();
|
||||
wxASSERT( m_active_alias == m_aliases[ i ] );
|
||||
|
||||
m_bus_list_view->DeleteItem( i );
|
||||
m_aliases.erase( m_aliases.begin() + i );
|
||||
m_bus_edit->Clear();
|
||||
|
||||
m_active_alias = NULL;
|
||||
|
||||
auto evt = wxListEvent( wxEVT_COMMAND_LIST_ITEM_DESELECTED );
|
||||
OnSelectBus( evt );
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_BUS_MANAGER::OnAddSignal( wxCommandEvent& aEvent )
|
||||
{
|
||||
auto name_list = m_signal_edit->GetValue();
|
||||
|
||||
if( !m_active_alias || name_list.Length() == 0 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// String collecting net names that were not added to the bus
|
||||
wxString notAdded;
|
||||
|
||||
// Parse a space-separated list and add each one
|
||||
wxStringTokenizer tok( name_list, " " );
|
||||
while( tok.HasMoreTokens() )
|
||||
{
|
||||
auto name = tok.GetNextToken();
|
||||
|
||||
if( !m_active_alias->Contains( name ) )
|
||||
{
|
||||
m_active_alias->AddMember( name );
|
||||
|
||||
long idx = m_signal_list_view->InsertItem(
|
||||
m_active_alias->GetMemberCount() - 1, name );
|
||||
|
||||
m_signal_list_view->SetColumnWidth( 0, -1 );
|
||||
m_signal_list_view->Select( idx );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Some of the requested net names were not added to the list, so keep them for editing
|
||||
notAdded = notAdded.IsEmpty() ? name : notAdded + " " + name;
|
||||
}
|
||||
}
|
||||
|
||||
m_signal_edit->SetValue( notAdded );
|
||||
m_signal_edit->SetInsertionPointEnd();
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_BUS_MANAGER::OnRenameSignal( wxCommandEvent& aEvent )
|
||||
{
|
||||
// We should only get here if there is an active alias
|
||||
wxASSERT( m_active_alias );
|
||||
|
||||
auto new_name = m_signal_edit->GetValue();
|
||||
long idx = m_signal_list_view->GetFirstSelected();
|
||||
|
||||
wxASSERT( idx >= 0 );
|
||||
|
||||
auto old_name = m_active_alias->Members()[ idx ];
|
||||
|
||||
// User could have typed a space here, so check first
|
||||
if( new_name.Find( " " ) != wxNOT_FOUND )
|
||||
{
|
||||
// TODO(JE) error feedback
|
||||
m_signal_edit->ChangeValue( old_name );
|
||||
return;
|
||||
}
|
||||
|
||||
m_active_alias->Members()[ idx ] = new_name;
|
||||
m_signal_list_view->SetItemText( idx, new_name );
|
||||
m_signal_list_view->SetColumnWidth( 0, -1 );
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_BUS_MANAGER::OnRemoveSignal( wxCommandEvent& aEvent )
|
||||
{
|
||||
// We should only get here if there is an active alias
|
||||
wxASSERT( m_active_alias );
|
||||
|
||||
long idx = m_signal_list_view->GetFirstSelected();
|
||||
|
||||
wxASSERT( idx >= 0 );
|
||||
|
||||
m_active_alias->Members().erase( m_active_alias->Members().begin() + idx );
|
||||
|
||||
m_signal_list_view->DeleteItem( idx );
|
||||
m_signal_edit->Clear();
|
||||
m_btn_rename_signal->Disable();
|
||||
m_btn_remove_signal->Disable();
|
||||
}
|
||||
|
||||
|
||||
wxString DIALOG_BUS_MANAGER::getAliasDisplayText( std::shared_ptr< BUS_ALIAS > aAlias )
|
||||
{
|
||||
wxString name = aAlias->GetName();
|
||||
wxFileName sheet_name( aAlias->GetParent()->GetFileName() );
|
||||
|
||||
name += _T( " (" ) + sheet_name.GetFullName() + _T( ")" );
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
// see invoke_sch_dialog.h
|
||||
void InvokeDialogBusManager( SCH_EDIT_FRAME* aCaller )
|
||||
{
|
||||
DIALOG_BUS_MANAGER dlg( aCaller );
|
||||
dlg.ShowModal();
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2018 CERN
|
||||
* @author Jon Evans <jon@craftyjon.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _DIALOG_BUS_MANAGER_H_
|
||||
#define _DIALOG_BUS_MANAGER_H_
|
||||
|
||||
#include "dialog_shim.h"
|
||||
|
||||
#include <sch_edit_frame.h>
|
||||
#include <wx/listctrl.h>
|
||||
|
||||
#include <bus_alias.h>
|
||||
|
||||
class DIALOG_BUS_MANAGER : public DIALOG_SHIM
|
||||
{
|
||||
public:
|
||||
DIALOG_BUS_MANAGER( SCH_EDIT_FRAME* aParent );
|
||||
|
||||
~DIALOG_BUS_MANAGER() {}
|
||||
|
||||
bool TransferDataFromWindow() override;
|
||||
|
||||
bool TransferDataToWindow() override;
|
||||
|
||||
void OnAddBus( wxCommandEvent& aEvent );
|
||||
void OnRenameBus( wxCommandEvent& aEvent );
|
||||
void OnRemoveBus( wxCommandEvent& aEvent );
|
||||
|
||||
void OnAddSignal( wxCommandEvent& aEvent );
|
||||
void OnRenameSignal( wxCommandEvent& aEvent );
|
||||
void OnRemoveSignal( wxCommandEvent& aEvent );
|
||||
|
||||
protected:
|
||||
|
||||
void OnInitDialog( wxInitDialogEvent& aEvent );
|
||||
|
||||
void OnSelectBus( wxListEvent& event );
|
||||
|
||||
void OnSelectSignal( wxListEvent& event );
|
||||
|
||||
SCH_EDIT_FRAME* m_parent;
|
||||
|
||||
wxListView* m_bus_list_view;
|
||||
wxListView* m_signal_list_view;
|
||||
wxTextCtrl* m_bus_edit;
|
||||
wxTextCtrl* m_signal_edit;
|
||||
|
||||
wxButton* m_btn_add_bus;
|
||||
wxButton* m_btn_rename_bus;
|
||||
wxButton* m_btn_remove_bus;
|
||||
|
||||
wxButton* m_btn_add_signal;
|
||||
wxButton* m_btn_rename_signal;
|
||||
wxButton* m_btn_remove_signal;
|
||||
|
||||
private:
|
||||
virtual void OnOkClick( wxCommandEvent& aEvent );
|
||||
|
||||
virtual void OnCancelClick( wxCommandEvent& aEvent );
|
||||
|
||||
wxString getAliasDisplayText( std::shared_ptr< BUS_ALIAS > aAlias );
|
||||
|
||||
std::vector< std::shared_ptr< BUS_ALIAS > > m_aliases;
|
||||
|
||||
std::shared_ptr< BUS_ALIAS > m_active_alias;
|
||||
|
||||
DECLARE_EVENT_TABLE()
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// _DIALOG_BUS_MANAGER_H_
|
|
@ -29,10 +29,9 @@
|
|||
*/
|
||||
|
||||
#include <fctsys.h>
|
||||
#include <wx/valgen.h>
|
||||
#include <wx/valnum.h>
|
||||
#include <sch_edit_frame.h>
|
||||
#include <base_units.h>
|
||||
#include <validators.h>
|
||||
|
||||
#include <sch_draw_panel.h>
|
||||
#include <general.h>
|
||||
|
@ -87,6 +86,7 @@ private:
|
|||
wxWindow* m_activeTextCtrl;
|
||||
wxTextEntry* m_activeTextEntry;
|
||||
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_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_CurrentText = aTextItem;
|
||||
|
@ -151,8 +153,9 @@ DIALOG_LABEL_EDITOR::DIALOG_LABEL_EDITOR( SCH_EDIT_FRAME* aParent, SCH_TEXT* aTe
|
|||
|
||||
SetInitialFocus( m_activeTextCtrl );
|
||||
|
||||
// Enable validator for net names
|
||||
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_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/
|
||||
//
|
||||
// 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->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_labelMultiLine = new wxStaticText( this, wxID_ANY, _("Text:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
<property name="file">dialog_edit_label_base</property>
|
||||
<property name="first_id">1000</property>
|
||||
<property name="help_provider">none</property>
|
||||
<property name="indent_with_spaces"></property>
|
||||
<property name="internationalize">1</property>
|
||||
<property name="name">dialog_edit_label_base</property>
|
||||
<property name="namespace"></property>
|
||||
|
@ -247,10 +246,10 @@
|
|||
<property name="subclass"></property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="validator_data_type">wxString</property>
|
||||
<property name="validator_style">wxFILTER_EXCLUDE_CHAR_LIST</property>
|
||||
<property name="validator_type">wxTextValidator</property>
|
||||
<property name="validator_variable">m_labelText</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>
|
||||
|
@ -606,8 +605,6 @@
|
|||
<property name="window_style"></property>
|
||||
<event name="OnChar"></event>
|
||||
<event name="OnCombobox"></event>
|
||||
<event name="OnComboboxCloseup"></event>
|
||||
<event name="OnComboboxDropdown"></event>
|
||||
<event name="OnEnterWindow"></event>
|
||||
<event name="OnEraseBackground"></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/
|
||||
//
|
||||
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||
|
@ -21,8 +21,8 @@ class DIALOG_SHIM;
|
|||
#include <wx/colour.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/textctrl.h>
|
||||
#include <wx/valtext.h>
|
||||
#include <wx/combobox.h>
|
||||
#include <wx/valtext.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/radiobox.h>
|
||||
#include <wx/button.h>
|
||||
|
@ -67,7 +67,6 @@ class DIALOG_LABEL_EDITOR_BASE : public DIALOG_SHIM
|
|||
|
||||
|
||||
public:
|
||||
wxString m_labelText;
|
||||
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 );
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include <sch_sheet.h>
|
||||
#include <lib_pin.h>
|
||||
#include <sch_component.h>
|
||||
#include <connection_graph.h>
|
||||
|
||||
#include <dialog_erc.h>
|
||||
#include <erc.h>
|
||||
|
@ -58,10 +59,7 @@ extern int DiagErc[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_tstUniqueGlobalLabels = true; // saved only for the current session
|
||||
|
||||
// Control identifiers for events
|
||||
#define ID_MATRIX_0 1800
|
||||
|
@ -102,8 +100,13 @@ DIALOG_ERC::DIALOG_ERC( SCH_EDIT_FRAME* parent ) :
|
|||
|
||||
DIALOG_ERC::~DIALOG_ERC()
|
||||
{
|
||||
m_TestSimilarLabels = m_cbTestSimilarLabels->GetValue();
|
||||
m_tstUniqueGlobalLabels = m_cbTestUniqueGlbLabels->GetValue();
|
||||
transferControlsToSettings();
|
||||
|
||||
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_WriteResultOpt->SetValue( m_writeErcFile );
|
||||
m_cbTestSimilarLabels->SetValue( m_TestSimilarLabels );
|
||||
m_cbTestUniqueGlbLabels->SetValue( m_tstUniqueGlobalLabels );
|
||||
m_settings = m_parent->GetErcSettings();
|
||||
transferSettingsToControls();
|
||||
|
||||
SCH_SCREENS 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 )
|
||||
{
|
||||
int markers = screens->GetMarkerCount( MARKER_BASE::MARKER_ERC,
|
||||
|
@ -436,10 +462,8 @@ void DIALOG_ERC::ResetDefaultERCDiag( wxCommandEvent& event )
|
|||
{
|
||||
memcpy( DiagErc, DefaultDiagErc, sizeof( DiagErc ) );
|
||||
ReBuildMatrixPanel();
|
||||
m_TestSimilarLabels = true;
|
||||
m_cbTestSimilarLabels->SetValue( m_TestSimilarLabels );
|
||||
m_tstUniqueGlobalLabels = true;
|
||||
m_cbTestUniqueGlbLabels->SetValue( m_tstUniqueGlobalLabels );
|
||||
m_settings.LoadDefaults();
|
||||
transferSettingsToControls();
|
||||
}
|
||||
|
||||
|
||||
|
@ -483,9 +507,7 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter )
|
|||
{
|
||||
wxFileName fn;
|
||||
|
||||
m_writeErcFile = m_WriteResultOpt->GetValue();
|
||||
m_TestSimilarLabels = m_cbTestSimilarLabels->GetValue();
|
||||
m_tstUniqueGlobalLabels = m_cbTestUniqueGlbLabels->GetValue();
|
||||
transferControlsToSettings();
|
||||
|
||||
// Build the whole sheet list in hierarchy (sheet, not screen)
|
||||
SCH_SHEET_LIST sheets( g_RootSheet );
|
||||
|
@ -509,6 +531,12 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter )
|
|||
*/
|
||||
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.
|
||||
*/
|
||||
TestMultiunitFootprints( sheets );
|
||||
|
@ -518,9 +546,7 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter )
|
|||
// Reset the connection type indicator
|
||||
objectsConnectedList->ResetConnectionsType();
|
||||
|
||||
unsigned lastItemIdx;
|
||||
unsigned nextItemIdx = lastItemIdx = 0;
|
||||
int MinConn = NOC;
|
||||
unsigned lastItemIdx = 0;
|
||||
|
||||
/* 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
|
||||
|
@ -547,13 +573,6 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter )
|
|||
|
||||
wxASSERT_MSG( lastNet <= net, wxT( "Netlist not correctly ordered" ) );
|
||||
|
||||
if( lastNet != net )
|
||||
{
|
||||
// New net found:
|
||||
MinConn = NOC;
|
||||
nextItemIdx = itemIdx;
|
||||
}
|
||||
|
||||
switch( item->m_Type )
|
||||
{
|
||||
// These items do not create erc problems
|
||||
|
@ -567,30 +586,7 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter )
|
|||
case NET_GLOBBUSLABELMEMBER:
|
||||
break;
|
||||
|
||||
case NET_HIERLABEL:
|
||||
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;
|
||||
|
||||
// TODO(JE) Port this to the new system
|
||||
case NET_PIN:
|
||||
{
|
||||
// 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:
|
||||
TestOthersItems( objectsConnectedList.get(), itemIdx, nextItemIdx, &MinConn );
|
||||
//TestOthersItems( objectsConnectedList.get(), itemIdx, nextItemIdx, &MinConn );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
lastItemIdx = itemIdx;
|
||||
|
@ -630,7 +629,7 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter )
|
|||
|
||||
// Test similar labels (i;e. labels which are identical when
|
||||
// using case insensitive comparisons)
|
||||
if( m_TestSimilarLabels )
|
||||
if( m_settings.check_similar_labels )
|
||||
objectsConnectedList->TestforSimilarLabels();
|
||||
|
||||
// Displays global results:
|
||||
|
@ -653,7 +652,7 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter )
|
|||
// Display message
|
||||
aReporter.ReportTail( _( "Finished" ), REPORTER::RPT_INFO );
|
||||
|
||||
if( m_writeErcFile )
|
||||
if( m_settings.write_erc_file )
|
||||
{
|
||||
fn = g_RootSheet->GetScreen()->GetFileName();
|
||||
fn.SetExt( wxT( "erc" ) );
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <lib_pin.h> // For PINTYPE_COUNT definition
|
||||
|
||||
#include <dialog_erc_base.h>
|
||||
#include <erc_settings.h>
|
||||
#include "dialog_erc_listbox.h"
|
||||
|
||||
// DIALOG_ERC class declaration
|
||||
|
@ -43,12 +44,8 @@ private:
|
|||
wxBitmapButton* m_buttonList[PINTYPE_COUNT][PINTYPE_COUNT];
|
||||
bool m_initialized;
|
||||
const SCH_MARKER* m_lastMarkerFound;
|
||||
static bool m_writeErcFile;
|
||||
static bool m_diagErcTableInit; // go to true after DiagErc init
|
||||
static bool m_tstUniqueGlobalLabels;
|
||||
|
||||
public:
|
||||
static bool m_TestSimilarLabels;
|
||||
ERC_SETTINGS m_settings;
|
||||
|
||||
public:
|
||||
DIALOG_ERC( SCH_EDIT_FRAME* parent );
|
||||
|
@ -79,6 +76,8 @@ private:
|
|||
void ReBuildMatrixPanel();
|
||||
void setDRCMatrixButtonState( wxBitmapButton *aButton, int aState );
|
||||
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/
|
||||
//
|
||||
// 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 );
|
||||
|
||||
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->Layout();
|
||||
|
|
|
@ -1318,6 +1318,373 @@
|
|||
</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>
|
||||
|
|
|
@ -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/
|
||||
//
|
||||
// PLEASE DO *NOT* EDIT THIS FILE!
|
||||
|
@ -65,6 +65,10 @@ class DIALOG_ERC_BASE : public DIALOG_SHIM
|
|||
wxCheckBox* m_cbTestUniqueGlbLabels;
|
||||
wxPanel* m_matrixPanel;
|
||||
wxButton* m_ResetOptButton;
|
||||
wxCheckBox* m_cbCheckBusToNetConflicts;
|
||||
wxCheckBox* m_cbCheckBusToBusConflicts;
|
||||
wxCheckBox* m_cbCheckBusEntries;
|
||||
wxCheckBox* m_cbCheckBusDriverConflicts;
|
||||
wxButton* m_buttondelmarkers;
|
||||
wxStdDialogButtonSizer* m_sdbSizer1;
|
||||
wxButton* m_sdbSizer1OK;
|
||||
|
|
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2018 CERN
|
||||
* @author Jon Evans <jon@craftyjon.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <sch_connection.h>
|
||||
#include <connection_graph.h>
|
||||
|
||||
#include <dialog_migrate_buses.h>
|
||||
|
||||
/**
|
||||
* Migrates buses using legacy multi-label joining behavior.
|
||||
*
|
||||
* In KiCad verions before 6.0, you were allowed to place multiple labels
|
||||
* on a given bus subgraph, and that would have the effect of making those
|
||||
* bus descriptions equivalent according to the bus vector number.
|
||||
*
|
||||
* For example, if the labels PCA[0..15], ADR[0.7], and BUS[5..10] are all
|
||||
* attached to the same subgraph, the intention is that there is connectivity
|
||||
* between PCA0 and ADR0, between PCA10 and BUS10, and between PCA5, ADR5,
|
||||
* and BUS5 (basically connect all the prefix names where the vector numbers
|
||||
* line up).
|
||||
*
|
||||
* This is no longer allowed, because it doesn't map well onto the new
|
||||
* bus groups feature and because it is confusing (the netlist will take on
|
||||
* one of the possible names and it's impossible to control which one is
|
||||
* used).
|
||||
*
|
||||
* This dialog identifies all of the subgraphs that have this behavior,
|
||||
* and corrects them by determining a new name for the subgraph and removing
|
||||
* all but one label. The name is determined by choosing a prefix and bus
|
||||
* vector notation that can capture all the attached buses. In the above
|
||||
* example, the result would need to have the vector notation [0..15] to
|
||||
* capture all of the attached buses, and the name could be any of PCA, ADR,
|
||||
* or BUS. We present a dialog to the user for them to select which name
|
||||
* they want to use.
|
||||
*/
|
||||
|
||||
|
||||
DIALOG_MIGRATE_BUSES::DIALOG_MIGRATE_BUSES( SCH_EDIT_FRAME* aParent ) :
|
||||
DIALOG_MIGRATE_BUSES_BASE( aParent ),
|
||||
m_frame( aParent )
|
||||
{
|
||||
m_migration_list->Bind( wxEVT_LIST_ITEM_SELECTED,
|
||||
&DIALOG_MIGRATE_BUSES::onItemSelected, this );
|
||||
|
||||
m_btn_accept->Bind( wxEVT_COMMAND_BUTTON_CLICKED,
|
||||
&DIALOG_MIGRATE_BUSES::onAcceptClicked, this );
|
||||
|
||||
loadGraphData();
|
||||
updateUi();
|
||||
|
||||
m_frame->Zoom_Automatique( false );
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_MIGRATE_BUSES::loadGraphData()
|
||||
{
|
||||
m_items.clear();
|
||||
auto subgraphs = g_ConnectionGraph->GetBusesNeedingMigration();
|
||||
|
||||
for( auto subgraph : subgraphs )
|
||||
{
|
||||
BUS_MIGRATION_STATUS status;
|
||||
|
||||
status.subgraph = subgraph;
|
||||
status.approved = false;
|
||||
|
||||
auto labels = subgraph->GetBusLabels();
|
||||
wxASSERT( labels.size() > 1 );
|
||||
|
||||
for( auto label : labels )
|
||||
status.labels.push_back( static_cast<SCH_TEXT*>( label )->GetText() );
|
||||
|
||||
status.possible_labels = getProposedLabels( status.labels );
|
||||
m_items.push_back( status );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_MIGRATE_BUSES::updateUi()
|
||||
{
|
||||
m_migration_list->DeleteAllItems();
|
||||
|
||||
m_migration_list->InsertColumn( 0, _( "Sheet" ) );
|
||||
m_migration_list->InsertColumn( 1, _( "Conflicting Labels" ) );
|
||||
m_migration_list->InsertColumn( 2, _( "New Label" ) );
|
||||
m_migration_list->InsertColumn( 3, _( "Status" ) );
|
||||
|
||||
for( auto item : m_items )
|
||||
{
|
||||
wxString old = item.labels[0];
|
||||
for( unsigned j = 1; j < item.labels.size(); j++ )
|
||||
old << ", " << item.labels[j];
|
||||
|
||||
auto i = m_migration_list->InsertItem( m_migration_list->GetItemCount(),
|
||||
wxEmptyString );
|
||||
|
||||
m_migration_list->SetItem( i, 0, item.subgraph->m_sheet.PathHumanReadable() );
|
||||
m_migration_list->SetItem( i, 1, old );
|
||||
m_migration_list->SetItem( i, 2, item.possible_labels[0] );
|
||||
m_migration_list->SetItem( i, 3, "" );
|
||||
}
|
||||
|
||||
m_migration_list->Select( 0 );
|
||||
m_migration_list->SetColumnWidth( 1, -1 );
|
||||
}
|
||||
|
||||
|
||||
std::vector<wxString> DIALOG_MIGRATE_BUSES::getProposedLabels( std::vector<wxString> aLabelList )
|
||||
{
|
||||
int lowest_start = INT_MAX;
|
||||
int highest_end = -1;
|
||||
int widest_bus = -1;
|
||||
|
||||
for( auto label : aLabelList )
|
||||
{
|
||||
SCH_CONNECTION conn;
|
||||
conn.ConfigureFromLabel( label );
|
||||
|
||||
int start = conn.VectorStart();
|
||||
int end = conn.VectorEnd();
|
||||
|
||||
if( start < lowest_start )
|
||||
lowest_start = start;
|
||||
|
||||
if( end > highest_end )
|
||||
highest_end = end;
|
||||
|
||||
if( end - start + 1 > widest_bus )
|
||||
widest_bus = end - start + 1;
|
||||
}
|
||||
|
||||
SCH_CONNECTION conn;
|
||||
std::vector<wxString> proposals;
|
||||
|
||||
for( auto label : aLabelList )
|
||||
{
|
||||
conn.ConfigureFromLabel( label );
|
||||
wxString proposal = conn.VectorPrefix();
|
||||
proposal << "[" << highest_end << ".." << lowest_start << "]";
|
||||
proposals.push_back( proposal );
|
||||
}
|
||||
|
||||
return proposals;
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_MIGRATE_BUSES::onItemSelected( wxListEvent& aEvent )
|
||||
{
|
||||
unsigned sel = aEvent.GetIndex();
|
||||
wxASSERT( sel < m_items.size() );
|
||||
|
||||
m_selected_index = sel;
|
||||
|
||||
auto subgraph = m_items[sel].subgraph;
|
||||
|
||||
auto sheet = subgraph->m_sheet;
|
||||
auto driver = subgraph->m_driver;
|
||||
|
||||
if( sheet != *g_CurrentSheet )
|
||||
{
|
||||
sheet.LastScreen()->SetZoom( m_frame->GetScreen()->GetZoom() );
|
||||
*g_CurrentSheet = sheet;
|
||||
g_CurrentSheet->UpdateAllScreenReferences();
|
||||
sheet.LastScreen()->TestDanglingEnds();
|
||||
}
|
||||
|
||||
auto pos = driver->GetPosition();
|
||||
|
||||
m_frame->SetCrossHairPosition( pos );
|
||||
m_frame->RedrawScreen( pos, false );
|
||||
|
||||
m_cb_new_name->Clear();
|
||||
|
||||
for( auto option : m_items[sel].possible_labels )
|
||||
m_cb_new_name->Append( option );
|
||||
|
||||
m_cb_new_name->Select( 0 );
|
||||
}
|
||||
|
||||
|
||||
void DIALOG_MIGRATE_BUSES::onAcceptClicked( wxCommandEvent& aEvent )
|
||||
{
|
||||
wxASSERT( m_selected_index < m_items.size() );
|
||||
|
||||
auto sel = m_selected_index;
|
||||
|
||||
m_items[sel].approved_label = m_cb_new_name->GetStringSelection();
|
||||
m_items[sel].approved = true;
|
||||
|
||||
auto sheet = m_items[sel].subgraph->m_sheet;
|
||||
auto screen = sheet.LastScreen();
|
||||
|
||||
auto labels = m_items[sel].subgraph->GetBusLabels();
|
||||
|
||||
static_cast<SCH_TEXT*>( labels[0] )->SetText( m_items[sel].approved_label );
|
||||
|
||||
labels.erase( labels.begin() );
|
||||
|
||||
for( auto label : labels )
|
||||
{
|
||||
label->SetFlags( STRUCT_DELETED );
|
||||
screen->Remove( label );
|
||||
}
|
||||
|
||||
m_migration_list->SetItem( sel, 2, m_items[sel].approved_label );
|
||||
m_migration_list->SetItem( sel, 3, _( "Updated" ) );
|
||||
|
||||
if( sel < m_items.size() - 1 )
|
||||
{
|
||||
m_migration_list->Select( sel + 1 );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2018 CERN
|
||||
* @author Jon Evans <jon@craftyjon.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _DIALOG_MIGRATE_BUSES_H
|
||||
#define _DIALOG_MIGRATE_BUSES_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <sch_edit_frame.h>
|
||||
|
||||
#include <dialog_migrate_buses_base.h>
|
||||
|
||||
class CONNECTION_SUBGRAPH;
|
||||
|
||||
|
||||
struct BUS_MIGRATION_STATUS
|
||||
{
|
||||
CONNECTION_SUBGRAPH* subgraph;
|
||||
|
||||
std::vector<wxString> labels;
|
||||
|
||||
std::vector<wxString> possible_labels;
|
||||
|
||||
wxString approved_label;
|
||||
|
||||
bool approved;
|
||||
};
|
||||
|
||||
class DIALOG_MIGRATE_BUSES : public DIALOG_MIGRATE_BUSES_BASE
|
||||
{
|
||||
public:
|
||||
|
||||
DIALOG_MIGRATE_BUSES( SCH_EDIT_FRAME* aParent );
|
||||
|
||||
private:
|
||||
|
||||
SCH_EDIT_FRAME* m_frame;
|
||||
|
||||
unsigned m_selected_index;
|
||||
|
||||
void loadGraphData();
|
||||
|
||||
void updateUi();
|
||||
|
||||
std::vector<wxString> getProposedLabels( std::vector<wxString> aLabelList );
|
||||
|
||||
void onItemSelected( wxListEvent& aEvent );
|
||||
|
||||
void onAcceptClicked( wxCommandEvent& aEvent );
|
||||
|
||||
std::vector<BUS_MIGRATION_STATUS> m_items;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,70 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Oct 17 2016)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "dialog_migrate_buses_base.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DIALOG_MIGRATE_BUSES_BASE::DIALOG_MIGRATE_BUSES_BASE( wxWindow* parent, wxWindowID id, const wxString& title, const wxPoint& pos, const wxSize& size, long style ) : DIALOG_SHIM( parent, id, title, pos, size, style )
|
||||
{
|
||||
this->SetSizeHints( wxDefaultSize, wxDefaultSize );
|
||||
|
||||
wxBoxSizer* main_sizer;
|
||||
main_sizer = new wxBoxSizer( wxVERTICAL );
|
||||
|
||||
m_staticText5 = new wxStaticText( this, wxID_ANY, _("This schematic has one or more buses with more than one label. This was allowed in previous KiCad versions but is no longer permitted."), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText5->Wrap( 480 );
|
||||
main_sizer->Add( m_staticText5, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
m_staticText7 = new wxStaticText( this, wxID_ANY, _("Please select a new name for each of the buses below.\nA name has been suggested for you based on the labels attached to the bus."), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText7->Wrap( 480 );
|
||||
m_staticText7->SetMinSize( wxSize( -1,60 ) );
|
||||
|
||||
main_sizer->Add( m_staticText7, 0, wxALL|wxEXPAND, 5 );
|
||||
|
||||
m_migration_list = new wxListView( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_HRULES|wxLC_REPORT|wxLC_SINGLE_SEL|wxLC_VRULES );
|
||||
m_migration_list->SetMinSize( wxSize( 460,100 ) );
|
||||
|
||||
main_sizer->Add( m_migration_list, 1, wxALL|wxEXPAND, 5 );
|
||||
|
||||
m_staticText6 = new wxStaticText( this, wxID_ANY, _("Proposed new name:"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
m_staticText6->Wrap( -1 );
|
||||
main_sizer->Add( m_staticText6, 0, wxALL, 5 );
|
||||
|
||||
wxBoxSizer* bSizer7;
|
||||
bSizer7 = new wxBoxSizer( wxHORIZONTAL );
|
||||
|
||||
m_cb_new_name = new wxComboBox( this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 );
|
||||
m_cb_new_name->SetMinSize( wxSize( 300,-1 ) );
|
||||
m_cb_new_name->SetMaxSize( wxSize( 460,-1 ) );
|
||||
|
||||
bSizer7->Add( m_cb_new_name, 1, wxALL|wxEXPAND, 5 );
|
||||
|
||||
m_btn_accept = new wxButton( this, wxID_ANY, _("Accept Name"), wxDefaultPosition, wxDefaultSize, 0 );
|
||||
bSizer7->Add( m_btn_accept, 0, wxALL, 5 );
|
||||
|
||||
|
||||
main_sizer->Add( bSizer7, 0, wxEXPAND, 5 );
|
||||
|
||||
m_sdbSizer1 = new wxStdDialogButtonSizer();
|
||||
m_sdbSizer1OK = new wxButton( this, wxID_OK );
|
||||
m_sdbSizer1->AddButton( m_sdbSizer1OK );
|
||||
m_sdbSizer1->Realize();
|
||||
|
||||
main_sizer->Add( m_sdbSizer1, 0, wxEXPAND, 5 );
|
||||
|
||||
|
||||
this->SetSizer( main_sizer );
|
||||
this->Layout();
|
||||
main_sizer->Fit( this );
|
||||
|
||||
this->Centre( wxBOTH );
|
||||
}
|
||||
|
||||
DIALOG_MIGRATE_BUSES_BASE::~DIALOG_MIGRATE_BUSES_BASE()
|
||||
{
|
||||
}
|
|
@ -0,0 +1,669 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
|
||||
<wxFormBuilder_Project>
|
||||
<FileVersion major="1" minor="13" />
|
||||
<object class="Project" expanded="1">
|
||||
<property name="class_decoration"></property>
|
||||
<property name="code_generation">C++</property>
|
||||
<property name="disconnect_events">1</property>
|
||||
<property name="disconnect_mode">source_name</property>
|
||||
<property name="disconnect_php_events">0</property>
|
||||
<property name="disconnect_python_events">0</property>
|
||||
<property name="embedded_files_path">res</property>
|
||||
<property name="encoding">UTF-8</property>
|
||||
<property name="event_generation">connect</property>
|
||||
<property name="file">dialog_migrate_buses_base</property>
|
||||
<property name="first_id">1000</property>
|
||||
<property name="help_provider">none</property>
|
||||
<property name="internationalize">1</property>
|
||||
<property name="name">DIALOG_MIGRATE_BUSES_BASE</property>
|
||||
<property name="namespace"></property>
|
||||
<property name="path">.</property>
|
||||
<property name="precompiled_header"></property>
|
||||
<property name="relative_path">1</property>
|
||||
<property name="skip_lua_events">1</property>
|
||||
<property name="skip_php_events">1</property>
|
||||
<property name="skip_python_events">1</property>
|
||||
<property name="ui_table">UI</property>
|
||||
<property name="use_enum">0</property>
|
||||
<property name="use_microsoft_bom">0</property>
|
||||
<object class="Dialog" expanded="1">
|
||||
<property name="aui_managed">0</property>
|
||||
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
|
||||
<property name="bg"></property>
|
||||
<property name="center">wxBOTH</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="event_handler">impl_virtual</property>
|
||||
<property name="extra_style"></property>
|
||||
<property name="fg"></property>
|
||||
<property name="font"></property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">DIALOG_MIGRATE_BUSES_BASE</property>
|
||||
<property name="pos"></property>
|
||||
<property name="size"></property>
|
||||
<property name="style">wxDEFAULT_DIALOG_STYLE</property>
|
||||
<property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
|
||||
<property name="title">Migrate Buses</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnActivate"></event>
|
||||
<event name="OnActivateApp"></event>
|
||||
<event name="OnAuiFindManager"></event>
|
||||
<event name="OnAuiPaneButton"></event>
|
||||
<event name="OnAuiPaneClose"></event>
|
||||
<event name="OnAuiPaneMaximize"></event>
|
||||
<event name="OnAuiPaneRestore"></event>
|
||||
<event name="OnAuiRender"></event>
|
||||
<event name="OnChar"></event>
|
||||
<event name="OnClose"></event>
|
||||
<event name="OnEnterWindow"></event>
|
||||
<event name="OnEraseBackground"></event>
|
||||
<event name="OnHibernate"></event>
|
||||
<event name="OnIconize"></event>
|
||||
<event name="OnIdle"></event>
|
||||
<event name="OnInitDialog"></event>
|
||||
<event name="OnKeyDown"></event>
|
||||
<event name="OnKeyUp"></event>
|
||||
<event name="OnKillFocus"></event>
|
||||
<event name="OnLeaveWindow"></event>
|
||||
<event name="OnLeftDClick"></event>
|
||||
<event name="OnLeftDown"></event>
|
||||
<event name="OnLeftUp"></event>
|
||||
<event name="OnMiddleDClick"></event>
|
||||
<event name="OnMiddleDown"></event>
|
||||
<event name="OnMiddleUp"></event>
|
||||
<event name="OnMotion"></event>
|
||||
<event name="OnMouseEvents"></event>
|
||||
<event name="OnMouseWheel"></event>
|
||||
<event name="OnPaint"></event>
|
||||
<event name="OnRightDClick"></event>
|
||||
<event name="OnRightDown"></event>
|
||||
<event name="OnRightUp"></event>
|
||||
<event name="OnSetFocus"></event>
|
||||
<event name="OnSize"></event>
|
||||
<event name="OnUpdateUI"></event>
|
||||
<object class="wxBoxSizer" expanded="1">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">main_sizer</property>
|
||||
<property name="orient">wxVERTICAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALL|wxEXPAND</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticText" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">This schematic has one or more buses with more than one label. This was allowed in previous KiCad versions but is no longer permitted.</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_staticText5</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass"></property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<property name="wrap">480</property>
|
||||
<event name="OnChar"></event>
|
||||
<event name="OnEnterWindow"></event>
|
||||
<event name="OnEraseBackground"></event>
|
||||
<event name="OnKeyDown"></event>
|
||||
<event name="OnKeyUp"></event>
|
||||
<event name="OnKillFocus"></event>
|
||||
<event name="OnLeaveWindow"></event>
|
||||
<event name="OnLeftDClick"></event>
|
||||
<event name="OnLeftDown"></event>
|
||||
<event name="OnLeftUp"></event>
|
||||
<event name="OnMiddleDClick"></event>
|
||||
<event name="OnMiddleDown"></event>
|
||||
<event name="OnMiddleUp"></event>
|
||||
<event name="OnMotion"></event>
|
||||
<event name="OnMouseEvents"></event>
|
||||
<event name="OnMouseWheel"></event>
|
||||
<event name="OnPaint"></event>
|
||||
<event name="OnRightDClick"></event>
|
||||
<event name="OnRightDown"></event>
|
||||
<event name="OnRightUp"></event>
|
||||
<event name="OnSetFocus"></event>
|
||||
<event name="OnSize"></event>
|
||||
<event name="OnUpdateUI"></event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALL|wxEXPAND</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticText" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Please select a new name for each of the buses below.
A name has been suggested for you based on the labels attached to the bus.</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size">-1,60</property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_staticText7</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass"></property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<property name="wrap">480</property>
|
||||
<event name="OnChar"></event>
|
||||
<event name="OnEnterWindow"></event>
|
||||
<event name="OnEraseBackground"></event>
|
||||
<event name="OnKeyDown"></event>
|
||||
<event name="OnKeyUp"></event>
|
||||
<event name="OnKillFocus"></event>
|
||||
<event name="OnLeaveWindow"></event>
|
||||
<event name="OnLeftDClick"></event>
|
||||
<event name="OnLeftDown"></event>
|
||||
<event name="OnLeftUp"></event>
|
||||
<event name="OnMiddleDClick"></event>
|
||||
<event name="OnMiddleDown"></event>
|
||||
<event name="OnMiddleUp"></event>
|
||||
<event name="OnMotion"></event>
|
||||
<event name="OnMouseEvents"></event>
|
||||
<event name="OnMouseWheel"></event>
|
||||
<event name="OnPaint"></event>
|
||||
<event name="OnRightDClick"></event>
|
||||
<event name="OnRightDown"></event>
|
||||
<event name="OnRightUp"></event>
|
||||
<event name="OnSetFocus"></event>
|
||||
<event name="OnSize"></event>
|
||||
<event name="OnUpdateUI"></event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALL|wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxListCtrl" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size">460,100</property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_migration_list</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style">wxLC_HRULES|wxLC_REPORT|wxLC_SINGLE_SEL|wxLC_VRULES</property>
|
||||
<property name="subclass">wxListView; </property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnChar"></event>
|
||||
<event name="OnEnterWindow"></event>
|
||||
<event name="OnEraseBackground"></event>
|
||||
<event name="OnKeyDown"></event>
|
||||
<event name="OnKeyUp"></event>
|
||||
<event name="OnKillFocus"></event>
|
||||
<event name="OnLeaveWindow"></event>
|
||||
<event name="OnLeftDClick"></event>
|
||||
<event name="OnLeftDown"></event>
|
||||
<event name="OnLeftUp"></event>
|
||||
<event name="OnListBeginDrag"></event>
|
||||
<event name="OnListBeginLabelEdit"></event>
|
||||
<event name="OnListBeginRDrag"></event>
|
||||
<event name="OnListCacheHint"></event>
|
||||
<event name="OnListColBeginDrag"></event>
|
||||
<event name="OnListColClick"></event>
|
||||
<event name="OnListColDragging"></event>
|
||||
<event name="OnListColEndDrag"></event>
|
||||
<event name="OnListColRightClick"></event>
|
||||
<event name="OnListDeleteAllItems"></event>
|
||||
<event name="OnListDeleteItem"></event>
|
||||
<event name="OnListEndLabelEdit"></event>
|
||||
<event name="OnListInsertItem"></event>
|
||||
<event name="OnListItemActivated"></event>
|
||||
<event name="OnListItemDeselected"></event>
|
||||
<event name="OnListItemFocused"></event>
|
||||
<event name="OnListItemMiddleClick"></event>
|
||||
<event name="OnListItemRightClick"></event>
|
||||
<event name="OnListItemSelected"></event>
|
||||
<event name="OnListKeyDown"></event>
|
||||
<event name="OnMiddleDClick"></event>
|
||||
<event name="OnMiddleDown"></event>
|
||||
<event name="OnMiddleUp"></event>
|
||||
<event name="OnMotion"></event>
|
||||
<event name="OnMouseEvents"></event>
|
||||
<event name="OnMouseWheel"></event>
|
||||
<event name="OnPaint"></event>
|
||||
<event name="OnRightDClick"></event>
|
||||
<event name="OnRightDown"></event>
|
||||
<event name="OnRightUp"></event>
|
||||
<event name="OnSetFocus"></event>
|
||||
<event name="OnSize"></event>
|
||||
<event name="OnUpdateUI"></event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStaticText" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Proposed new name:</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_staticText6</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass"></property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<property name="wrap">-1</property>
|
||||
<event name="OnChar"></event>
|
||||
<event name="OnEnterWindow"></event>
|
||||
<event name="OnEraseBackground"></event>
|
||||
<event name="OnKeyDown"></event>
|
||||
<event name="OnKeyUp"></event>
|
||||
<event name="OnKillFocus"></event>
|
||||
<event name="OnLeaveWindow"></event>
|
||||
<event name="OnLeftDClick"></event>
|
||||
<event name="OnLeftDown"></event>
|
||||
<event name="OnLeftUp"></event>
|
||||
<event name="OnMiddleDClick"></event>
|
||||
<event name="OnMiddleDown"></event>
|
||||
<event name="OnMiddleUp"></event>
|
||||
<event name="OnMotion"></event>
|
||||
<event name="OnMouseEvents"></event>
|
||||
<event name="OnMouseWheel"></event>
|
||||
<event name="OnPaint"></event>
|
||||
<event name="OnRightDClick"></event>
|
||||
<event name="OnRightDown"></event>
|
||||
<event name="OnRightUp"></event>
|
||||
<event name="OnSetFocus"></event>
|
||||
<event name="OnSize"></event>
|
||||
<event name="OnUpdateUI"></event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxBoxSizer" expanded="1">
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">bSizer7</property>
|
||||
<property name="orient">wxHORIZONTAL</property>
|
||||
<property name="permission">none</property>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALL|wxEXPAND</property>
|
||||
<property name="proportion">1</property>
|
||||
<object class="wxComboBox" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="choices"></property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size">460,-1</property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size">300,-1</property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_cb_new_name</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="selection">-1</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass"></property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="value"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnChar"></event>
|
||||
<event name="OnCombobox"></event>
|
||||
<event name="OnEnterWindow"></event>
|
||||
<event name="OnEraseBackground"></event>
|
||||
<event name="OnKeyDown"></event>
|
||||
<event name="OnKeyUp"></event>
|
||||
<event name="OnKillFocus"></event>
|
||||
<event name="OnLeaveWindow"></event>
|
||||
<event name="OnLeftDClick"></event>
|
||||
<event name="OnLeftDown"></event>
|
||||
<event name="OnLeftUp"></event>
|
||||
<event name="OnMiddleDClick"></event>
|
||||
<event name="OnMiddleDown"></event>
|
||||
<event name="OnMiddleUp"></event>
|
||||
<event name="OnMotion"></event>
|
||||
<event name="OnMouseEvents"></event>
|
||||
<event name="OnMouseWheel"></event>
|
||||
<event name="OnPaint"></event>
|
||||
<event name="OnRightDClick"></event>
|
||||
<event name="OnRightDown"></event>
|
||||
<event name="OnRightUp"></event>
|
||||
<event name="OnSetFocus"></event>
|
||||
<event name="OnSize"></event>
|
||||
<event name="OnText"></event>
|
||||
<event name="OnTextEnter"></event>
|
||||
<event name="OnUpdateUI"></event>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxALL</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxButton" expanded="1">
|
||||
<property name="BottomDockable">1</property>
|
||||
<property name="LeftDockable">1</property>
|
||||
<property name="RightDockable">1</property>
|
||||
<property name="TopDockable">1</property>
|
||||
<property name="aui_layer"></property>
|
||||
<property name="aui_name"></property>
|
||||
<property name="aui_position"></property>
|
||||
<property name="aui_row"></property>
|
||||
<property name="best_size"></property>
|
||||
<property name="bg"></property>
|
||||
<property name="caption"></property>
|
||||
<property name="caption_visible">1</property>
|
||||
<property name="center_pane">0</property>
|
||||
<property name="close_button">1</property>
|
||||
<property name="context_help"></property>
|
||||
<property name="context_menu">1</property>
|
||||
<property name="default">0</property>
|
||||
<property name="default_pane">0</property>
|
||||
<property name="dock">Dock</property>
|
||||
<property name="dock_fixed">0</property>
|
||||
<property name="docking">Left</property>
|
||||
<property name="enabled">1</property>
|
||||
<property name="fg"></property>
|
||||
<property name="floatable">1</property>
|
||||
<property name="font"></property>
|
||||
<property name="gripper">0</property>
|
||||
<property name="hidden">0</property>
|
||||
<property name="id">wxID_ANY</property>
|
||||
<property name="label">Accept Name</property>
|
||||
<property name="max_size"></property>
|
||||
<property name="maximize_button">0</property>
|
||||
<property name="maximum_size"></property>
|
||||
<property name="min_size"></property>
|
||||
<property name="minimize_button">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="moveable">1</property>
|
||||
<property name="name">m_btn_accept</property>
|
||||
<property name="pane_border">1</property>
|
||||
<property name="pane_position"></property>
|
||||
<property name="pane_size"></property>
|
||||
<property name="permission">protected</property>
|
||||
<property name="pin_button">1</property>
|
||||
<property name="pos"></property>
|
||||
<property name="resize">Resizable</property>
|
||||
<property name="show">1</property>
|
||||
<property name="size"></property>
|
||||
<property name="style"></property>
|
||||
<property name="subclass"></property>
|
||||
<property name="toolbar_pane">0</property>
|
||||
<property name="tooltip"></property>
|
||||
<property name="validator_data_type"></property>
|
||||
<property name="validator_style">wxFILTER_NONE</property>
|
||||
<property name="validator_type">wxDefaultValidator</property>
|
||||
<property name="validator_variable"></property>
|
||||
<property name="window_extra_style"></property>
|
||||
<property name="window_name"></property>
|
||||
<property name="window_style"></property>
|
||||
<event name="OnButtonClick"></event>
|
||||
<event name="OnChar"></event>
|
||||
<event name="OnEnterWindow"></event>
|
||||
<event name="OnEraseBackground"></event>
|
||||
<event name="OnKeyDown"></event>
|
||||
<event name="OnKeyUp"></event>
|
||||
<event name="OnKillFocus"></event>
|
||||
<event name="OnLeaveWindow"></event>
|
||||
<event name="OnLeftDClick"></event>
|
||||
<event name="OnLeftDown"></event>
|
||||
<event name="OnLeftUp"></event>
|
||||
<event name="OnMiddleDClick"></event>
|
||||
<event name="OnMiddleDown"></event>
|
||||
<event name="OnMiddleUp"></event>
|
||||
<event name="OnMotion"></event>
|
||||
<event name="OnMouseEvents"></event>
|
||||
<event name="OnMouseWheel"></event>
|
||||
<event name="OnPaint"></event>
|
||||
<event name="OnRightDClick"></event>
|
||||
<event name="OnRightDown"></event>
|
||||
<event name="OnRightUp"></event>
|
||||
<event name="OnSetFocus"></event>
|
||||
<event name="OnSize"></event>
|
||||
<event name="OnUpdateUI"></event>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
<object class="sizeritem" expanded="1">
|
||||
<property name="border">5</property>
|
||||
<property name="flag">wxEXPAND</property>
|
||||
<property name="proportion">0</property>
|
||||
<object class="wxStdDialogButtonSizer" expanded="1">
|
||||
<property name="Apply">0</property>
|
||||
<property name="Cancel">0</property>
|
||||
<property name="ContextHelp">0</property>
|
||||
<property name="Help">0</property>
|
||||
<property name="No">0</property>
|
||||
<property name="OK">1</property>
|
||||
<property name="Save">0</property>
|
||||
<property name="Yes">0</property>
|
||||
<property name="minimum_size"></property>
|
||||
<property name="name">m_sdbSizer1</property>
|
||||
<property name="permission">protected</property>
|
||||
<event name="OnApplyButtonClick"></event>
|
||||
<event name="OnCancelButtonClick"></event>
|
||||
<event name="OnContextHelpButtonClick"></event>
|
||||
<event name="OnHelpButtonClick"></event>
|
||||
<event name="OnNoButtonClick"></event>
|
||||
<event name="OnOKButtonClick"></event>
|
||||
<event name="OnSaveButtonClick"></event>
|
||||
<event name="OnYesButtonClick"></event>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</object>
|
||||
</wxFormBuilder_Project>
|
|
@ -0,0 +1,57 @@
|
|||
///////////////////////////////////////////////////////////////////////////
|
||||
// C++ code generated with wxFormBuilder (version Oct 17 2016)
|
||||
// http://www.wxformbuilder.org/
|
||||
//
|
||||
// PLEASE DO "NOT" EDIT THIS FILE!
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef __DIALOG_MIGRATE_BUSES_BASE_H__
|
||||
#define __DIALOG_MIGRATE_BUSES_BASE_H__
|
||||
|
||||
#include <wx/artprov.h>
|
||||
#include <wx/xrc/xmlres.h>
|
||||
#include <wx/intl.h>
|
||||
class DIALOG_SHIM;
|
||||
class wxListView;
|
||||
|
||||
#include "dialog_shim.h"
|
||||
#include <wx/string.h>
|
||||
#include <wx/stattext.h>
|
||||
#include <wx/gdicmn.h>
|
||||
#include <wx/font.h>
|
||||
#include <wx/colour.h>
|
||||
#include <wx/settings.h>
|
||||
#include <wx/listctrl.h>
|
||||
#include <wx/combobox.h>
|
||||
#include <wx/button.h>
|
||||
#include <wx/sizer.h>
|
||||
#include <wx/dialog.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
/// Class DIALOG_MIGRATE_BUSES_BASE
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class DIALOG_MIGRATE_BUSES_BASE : public DIALOG_SHIM
|
||||
{
|
||||
private:
|
||||
|
||||
protected:
|
||||
wxStaticText* m_staticText5;
|
||||
wxStaticText* m_staticText7;
|
||||
wxListView* m_migration_list;
|
||||
wxStaticText* m_staticText6;
|
||||
wxComboBox* m_cb_new_name;
|
||||
wxButton* m_btn_accept;
|
||||
wxStdDialogButtonSizer* m_sdbSizer1;
|
||||
wxButton* m_sdbSizer1OK;
|
||||
|
||||
public:
|
||||
|
||||
DIALOG_MIGRATE_BUSES_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Migrate Buses"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxDEFAULT_DIALOG_STYLE );
|
||||
~DIALOG_MIGRATE_BUSES_BASE();
|
||||
|
||||
};
|
||||
|
||||
#endif //__DIALOG_MIGRATE_BUSES_BASE_H__
|
|
@ -23,6 +23,7 @@
|
|||
*/
|
||||
|
||||
#include <sch_edit_frame.h>
|
||||
#include <sch_sheet.h>
|
||||
#include <dialog_sch_edit_sheet_pin.h>
|
||||
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <widgets/tab_traversal.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 ) :
|
||||
|
|
|
@ -52,8 +52,8 @@ wxString DRC_ITEM::GetErrorText() const
|
|||
return wxString( _("Mismatch between hierarchical labels and pins sheets"));
|
||||
case ERCE_NOCONNECT_CONNECTED:
|
||||
return wxString( _("A pin with a \"no connection\" flag is connected"));
|
||||
case ERCE_GLOBLABEL:
|
||||
return wxString( _("Global label not connected to any other global label") );
|
||||
case ERCE_LABEL_NOT_CONNECTED:
|
||||
return wxString( _("A label not connected to any other item") );
|
||||
case ERCE_SIMILAR_LABELS:
|
||||
return wxString( _("Labels are similar (lower/upper case difference only)") );
|
||||
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") );
|
||||
case ERCE_DIFFERENT_UNIT_NET:
|
||||
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:
|
||||
wxFAIL_MSG( "Missing ERC error description" );
|
||||
return wxString( wxT("Unknown.") );
|
||||
|
|
|
@ -77,7 +77,7 @@ void SCH_EDIT_FRAME::EditComponentFieldText( SCH_FIELD* aField )
|
|||
return;
|
||||
}
|
||||
|
||||
dlg.UpdateField( aField, m_CurrentSheet );
|
||||
dlg.UpdateField( aField, g_CurrentSheet );
|
||||
m_canvas->MoveCursorToCrossHair();
|
||||
m_canvas->SetIgnoreMouseEvents( false );
|
||||
|
||||
|
@ -88,7 +88,6 @@ void SCH_EDIT_FRAME::EditComponentFieldText( SCH_FIELD* aField )
|
|||
OnModify();
|
||||
|
||||
MSG_PANEL_ITEMS items;
|
||||
component->SetCurrentSheetPath( &GetCurrentSheet() );
|
||||
component->GetMsgPanelInfo( m_UserUnits, items );
|
||||
SetMsgPanel( items );
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include <confirm.h>
|
||||
#include <gestfich.h>
|
||||
#include <sch_edit_frame.h>
|
||||
#include <sch_sheet.h>
|
||||
#include <invoke_sch_dialog.h>
|
||||
#include <lib_edit_frame.h>
|
||||
#include <eeschema_config.h>
|
||||
|
@ -249,8 +250,26 @@ PARAM_CFG_ARRAY& SCH_EDIT_FRAME::GetProjectFileParametersList()
|
|||
&s_defaultTextSize,
|
||||
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" ),
|
||||
&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;
|
||||
}
|
||||
|
|
|
@ -66,6 +66,7 @@ enum id_eeschema_frm
|
|||
/* Schematic editor main menubar IDs. */
|
||||
ID_RESCUE_CACHED,
|
||||
ID_EDIT_SYM_LIB_TABLE,
|
||||
ID_BUS_MANAGER,
|
||||
ID_REMAP_SYMBOLS,
|
||||
ID_EDIT_COMPONENTS_TO_SYMBOLS_LIB_ID,
|
||||
ID_GRID_SETTINGS,
|
||||
|
@ -166,6 +167,10 @@ enum id_eeschema_frm
|
|||
ID_POPUP_SCH_GETINFO_MARKER,
|
||||
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_CALL_LIBEDIT_AND_LOAD_CMP,
|
||||
|
||||
|
@ -200,6 +205,7 @@ enum id_eeschema_frm
|
|||
ID_SCH_EDIT_COMPONENT_FOOTPRINT,
|
||||
ID_SCH_MOVE_ITEM,
|
||||
ID_SCH_DRAG_ITEM,
|
||||
ID_SCH_UNFOLD_BUS,
|
||||
|
||||
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 errors = 0;
|
||||
|
@ -314,6 +381,7 @@ void Diagnose( NETLIST_OBJECT* aNetItemRef, NETLIST_OBJECT* aNetItemTst,
|
|||
|
||||
if( aMinConn < 0 )
|
||||
{
|
||||
#if 0
|
||||
if( aNetItemRef->m_Type == NET_HIERLABEL || aNetItemRef->m_Type == NET_HIERBUSLABELMEMBER )
|
||||
{
|
||||
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,
|
||||
aNetItemRef->m_Start );
|
||||
}
|
||||
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,21 +49,28 @@ extern const wxString CommentERC_H[];
|
|||
extern const wxString CommentERC_V[];
|
||||
|
||||
/// DRC error codes:
|
||||
#define ERCE_UNSPECIFIED 0
|
||||
#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
|
||||
#define ERCE_PIN_NOT_DRIVEN 3 // pin connected to some others pins but no pin to drive it
|
||||
#define ERCE_PIN_TO_PIN_WARNING 4 // pin connected to another pin: warning level
|
||||
#define ERCE_PIN_TO_PIN_ERROR 5 // pin connected to another pin: error level
|
||||
#define ERCE_HIERACHICAL_LABEL 6 // mismatch between hierarchical labels and pins sheets
|
||||
#define ERCE_NOCONNECT_CONNECTED 7 // a no connect symbol is connected to more than 1 pin
|
||||
#define ERCE_GLOBLABEL 8 // global label not connected to any other global label
|
||||
#define ERCE_SIMILAR_LABELS 9 // 2 labels are equal fir case insensitive comparisons
|
||||
#define ERCE_SIMILAR_GLBL_LABELS 10 // 2 labels are equal fir case insensitive comparisons
|
||||
#define ERCE_DIFFERENT_UNIT_FP 11 // different units of the same component have different
|
||||
// footprints assigned
|
||||
#define ERCE_DIFFERENT_UNIT_NET 12 // a shared pin in a multi-unit component is connected
|
||||
// to more than one net
|
||||
enum ERCE_T
|
||||
{
|
||||
ERCE_UNSPECIFIED = 0,
|
||||
ERCE_DUPLICATE_SHEET_NAME, // duplicate sheet names within a given sheet
|
||||
ERCE_PIN_NOT_CONNECTED, // pin not connected and not no connect symbol
|
||||
ERCE_PIN_NOT_DRIVEN, // pin connected to some others pins but no pin to drive it
|
||||
ERCE_PIN_TO_PIN_WARNING, // pin connected to an other pin: warning level
|
||||
ERCE_PIN_TO_PIN_ERROR, // pin connected to an other pin: error level
|
||||
ERCE_HIERACHICAL_LABEL, // mismatch between hierarchical labels and pins sheets
|
||||
ERCE_NOCONNECT_CONNECTED, // a no connect symbol is connected to more than 1 pin
|
||||
ERCE_LABEL_NOT_CONNECTED, // label not connected to anything
|
||||
ERCE_SIMILAR_LABELS, // 2 labels are equal fir case insensitive comparisons
|
||||
ERCE_SIMILAR_GLBL_LABELS, // 2 labels are equal fir case insensitive comparisons
|
||||
ERCE_DIFFERENT_UNIT_FP, // different units of the same component have different footprints assigned
|
||||
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 */
|
||||
#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 );
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @param aSheetList contains components to be validated.
|
||||
|
|
|
@ -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 <symbol_lib_table.h>
|
||||
#include <dialog_symbol_remap.h>
|
||||
#include <dialog_migrate_buses.h>
|
||||
#include <worksheet_shape_builder.h>
|
||||
#include <connection_graph.h>
|
||||
|
||||
|
||||
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 );
|
||||
delete g_RootSheet; // Delete the current project.
|
||||
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 ) );
|
||||
|
||||
// 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
|
||||
{
|
||||
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() )
|
||||
{
|
||||
|
@ -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.
|
||||
SetScreen( m_CurrentSheet->LastScreen() );
|
||||
SetScreen( g_CurrentSheet->LastScreen() );
|
||||
|
||||
// Ensure the schematic is fully segmented on first display
|
||||
BreakSegmentsOnJunctions();
|
||||
SchematicCleanUp( true );
|
||||
GetScreen()->ClearUndoORRedoList( GetScreen()->m_UndoList, 1 );
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -816,9 +835,9 @@ bool SCH_EDIT_FRAME::importFile( const wxString& aFileName, int aFileType )
|
|||
newfilename.SetName( Prj().GetProjectName() );
|
||||
newfilename.SetExt( SchematicFileExtension );
|
||||
|
||||
m_CurrentSheet->clear();
|
||||
m_CurrentSheet->push_back( g_RootSheet );
|
||||
SetScreen( m_CurrentSheet->LastScreen() );
|
||||
g_CurrentSheet->clear();
|
||||
g_CurrentSheet->push_back( g_RootSheet );
|
||||
SetScreen( g_CurrentSheet->LastScreen() );
|
||||
|
||||
g_RootSheet->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 )
|
||||
{
|
||||
sheetFoundIn = m_CurrentSheet;
|
||||
lastMarker = (SCH_MARKER*) m_CurrentSheet->FindNextItem( SCH_MARKER_T, lastMarker, wrap );
|
||||
sheetFoundIn = g_CurrentSheet;
|
||||
lastMarker = (SCH_MARKER*) g_CurrentSheet->FindNextItem( SCH_MARKER_T, lastMarker, wrap );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -81,11 +81,11 @@ void SCH_EDIT_FRAME::OnFindDrcMarker( wxFindDialogEvent& event )
|
|||
|
||||
if( lastMarker != NULL )
|
||||
{
|
||||
if( *sheetFoundIn != *m_CurrentSheet )
|
||||
if( *sheetFoundIn != *g_CurrentSheet )
|
||||
{
|
||||
sheetFoundIn->LastScreen()->SetZoom( GetScreen()->GetZoom() );
|
||||
*m_CurrentSheet = *sheetFoundIn;
|
||||
m_CurrentSheet->UpdateAllScreenReferences();
|
||||
*g_CurrentSheet = *sheetFoundIn;
|
||||
g_CurrentSheet->UpdateAllScreenReferences();
|
||||
}
|
||||
|
||||
SetCrossHairPosition( lastMarker->GetPosition() );
|
||||
|
@ -122,7 +122,7 @@ SCH_ITEM* SCH_EDIT_FRAME::FindComponentAndItem( const wxString& aReference,
|
|||
EDA_ITEM* foundItem = nullptr;
|
||||
|
||||
if( !aSearchHierarchy )
|
||||
sheetList.push_back( *m_CurrentSheet );
|
||||
sheetList.push_back( *g_CurrentSheet );
|
||||
else
|
||||
sheetList.BuildSheetList( g_RootSheet );
|
||||
|
||||
|
@ -193,10 +193,10 @@ SCH_ITEM* SCH_EDIT_FRAME::FindComponentAndItem( const wxString& aReference,
|
|||
{
|
||||
sheet = sheetWithComponentFound;
|
||||
|
||||
if( *sheet != *m_CurrentSheet )
|
||||
if( *sheet != *g_CurrentSheet )
|
||||
{
|
||||
sheet->LastScreen()->SetZoom( GetScreen()->GetZoom() );
|
||||
*m_CurrentSheet = *sheet;
|
||||
*g_CurrentSheet = *sheet;
|
||||
DisplayCurrentSheet();
|
||||
}
|
||||
|
||||
|
@ -279,7 +279,7 @@ void SCH_EDIT_FRAME::OnFindSchematicItem( wxFindDialogEvent& aEvent )
|
|||
{
|
||||
if( aEvent.GetFlags() & FR_CURRENT_SHEET_ONLY && g_RootSheet->CountSheets() > 1 )
|
||||
{
|
||||
m_foundItems.Collect( searchCriteria, m_CurrentSheet );
|
||||
m_foundItems.Collect( searchCriteria, g_CurrentSheet );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -317,7 +317,7 @@ void SCH_EDIT_FRAME::OnFindReplace( wxFindDialogEvent& aEvent )
|
|||
{
|
||||
if( aEvent.GetFlags() & FR_CURRENT_SHEET_ONLY && g_RootSheet->CountSheets() > 1 )
|
||||
{
|
||||
m_foundItems.Collect( searchCriteria, m_CurrentSheet );
|
||||
m_foundItems.Collect( searchCriteria, g_CurrentSheet );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -423,11 +423,11 @@ void SCH_EDIT_FRAME::updateFindReplaceView( wxFindDialogEvent& aEvent )
|
|||
item->SetForceVisible( true );
|
||||
}
|
||||
|
||||
if( sheet->PathHumanReadable() != m_CurrentSheet->PathHumanReadable() )
|
||||
if( sheet->PathHumanReadable() != g_CurrentSheet->PathHumanReadable() )
|
||||
{
|
||||
sheet->LastScreen()->SetZoom( GetScreen()->GetZoom() );
|
||||
*m_CurrentSheet = *sheet;
|
||||
m_CurrentSheet->UpdateAllScreenReferences();
|
||||
*g_CurrentSheet = *sheet;
|
||||
g_CurrentSheet->UpdateAllScreenReferences();
|
||||
SetScreen( sheet->LastScreen() );
|
||||
sheet->LastScreen()->TestDanglingEnds();
|
||||
}
|
||||
|
|
|
@ -34,8 +34,10 @@
|
|||
|
||||
using KIGFX::COLOR4D;
|
||||
|
||||
class CONNECTION_GRAPH;
|
||||
class TRANSFORM;
|
||||
class SCH_SHEET;
|
||||
class SCH_SHEET_PATH;
|
||||
|
||||
#define EESCHEMA_VERSION 4
|
||||
#define SCHEMATIC_HEAD_STRING "Schematic File Version"
|
||||
|
@ -83,6 +85,18 @@ extern TRANSFORM DefaultTransform;
|
|||
/* First and main (root) screen */
|
||||
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 thickness line value (i.e. = 0 ).
|
||||
|
|
|
@ -243,7 +243,7 @@ SCH_COMPONENT* SCH_EDIT_FRAME::Load_Component( const SCHLIB_FILTER* aF
|
|||
if( !part )
|
||||
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,
|
||||
GetCrossHairPosition(), true );
|
||||
|
||||
|
@ -261,7 +261,6 @@ SCH_COMPONENT* SCH_EDIT_FRAME::Load_Component( const SCHLIB_FILTER* aF
|
|||
|
||||
MSG_PANEL_ITEMS items;
|
||||
|
||||
component->SetCurrentSheetPath( &GetCurrentSheet() );
|
||||
component->GetMsgPanelInfo( m_UserUnits, items );
|
||||
|
||||
SetMsgPanel( items );
|
||||
|
@ -333,7 +332,7 @@ void SCH_EDIT_FRAME::OnSelectUnit( wxCommandEvent& aEvent )
|
|||
SaveCopyInUndoList( component, UR_CHANGED );
|
||||
|
||||
/* Update the unit number. */
|
||||
component->SetUnitSelection( m_CurrentSheet, unit );
|
||||
component->SetUnitSelection( g_CurrentSheet, unit );
|
||||
component->SetUnit( unit );
|
||||
component->ClearFlags();
|
||||
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_VIEWER _( "Browse symbol libraries" )
|
||||
#define HELP_GENERATE_BOM _( "Generate bill of materials" )
|
||||
#define HELP_BUS_MANAGER _( "Manage bus definitions" )
|
||||
#define HELP_IMPORT_FOOTPRINTS \
|
||||
_( "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 );
|
||||
ClearMsgPanel();
|
||||
|
||||
SCH_SCREEN* screen = m_CurrentSheet->LastScreen();
|
||||
SCH_SCREEN* screen = g_CurrentSheet->LastScreen();
|
||||
|
||||
// Switch to current sheet,
|
||||
// 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 );
|
||||
|
||||
// update the References
|
||||
m_CurrentSheet->UpdateAllScreenReferences();
|
||||
g_CurrentSheet->UpdateAllScreenReferences();
|
||||
SetSheetNumberAndCount();
|
||||
m_canvas->SetCanStartBlock( -1 );
|
||||
|
||||
|
@ -284,12 +284,11 @@ void SCH_EDIT_FRAME::DisplayCurrentSheet()
|
|||
Zoom_Automatique( false );
|
||||
screen->m_Initialized = true;
|
||||
|
||||
// Ensure the schematic is fully segmented on first display
|
||||
BreakSegmentsOnJunctions();
|
||||
SchematicCleanUp( true );
|
||||
screen->ClearUndoORRedoList( screen->m_UndoList, 1 );
|
||||
// TODO(JE) should be able to just recalculate the current sheet path
|
||||
// RecalculateConnections() handles cleanup and dangling ends tests
|
||||
RecalculateConnections();
|
||||
|
||||
screen->TestDanglingEnds();
|
||||
screen->ClearUndoORRedoList( screen->m_UndoList, 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -35,15 +35,20 @@
|
|||
#include <erc.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
|
||||
|
||||
// TODO(JE) Probably use netcode rather than connection name here eventually
|
||||
bool SCH_EDIT_FRAME::HighlightConnectionAtPosition( wxPoint aPosition )
|
||||
{
|
||||
std::vector<EDA_ITEM*> itemsToRedraw;
|
||||
m_SelectedNetName = "";
|
||||
bool buildNetlistOk = false;
|
||||
|
||||
SetStatusText( "" );
|
||||
|
||||
// find which connected item is selected
|
||||
EDA_ITEMS nodeList;
|
||||
wxPoint gridPosition = GetGridPosition( aPosition );
|
||||
|
@ -54,23 +59,19 @@ bool SCH_EDIT_FRAME::HighlightConnectionAtPosition( wxPoint aPosition )
|
|||
wxMessageBox( _( "Error: duplicate sub-sheet names found in current sheet. Fix it" ) );
|
||||
else
|
||||
{
|
||||
// Build netlist info to get the proper netnames of connected items
|
||||
std::unique_ptr<NETLIST_OBJECT_LIST> objectsConnectedList( BuildNetListBase() );
|
||||
buildNetlistOk = true;
|
||||
|
||||
for( auto obj : *objectsConnectedList )
|
||||
if( auto item = dynamic_cast<SCH_ITEM*>( nodeList[0] ) )
|
||||
{
|
||||
if( obj->m_SheetPath == *m_CurrentSheet && obj->m_Comp == nodeList[0] )
|
||||
if( item->Connection( *g_CurrentSheet ) )
|
||||
{
|
||||
m_SelectedNetName = obj->GetNetName( true );
|
||||
break;
|
||||
m_SelectedNetName = item->Connection( *g_CurrentSheet )->Name();
|
||||
SetStatusText( _( "Highlighted net: " ) + m_SelectedNetName );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SendCrossProbeNetName( m_SelectedNetName );
|
||||
SetStatusText( "selected net: " + m_SelectedNetName );
|
||||
SetStatusText( _( "Selected net: " ) + m_SelectedNetName );
|
||||
SetCurrentSheetHighlightFlags( &itemsToRedraw );
|
||||
|
||||
// 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 )
|
||||
{
|
||||
SCH_SCREEN* screen = m_CurrentSheet->LastScreen();
|
||||
SCH_SCREEN* screen = g_CurrentSheet->LastScreen();
|
||||
|
||||
if( !screen )
|
||||
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
|
||||
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 );
|
||||
|
||||
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 )
|
||||
{
|
||||
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 );
|
||||
|
||||
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 )
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
'B' + GR_KB_CTRL );
|
||||
|
||||
static EDA_HOTKEY HkUnfoldBus( _HKI( "Unfold Bus" ), HK_UNFOLD_BUS, 'D',
|
||||
ID_SCH_UNFOLD_BUS );
|
||||
|
||||
// Common: hotkeys_basic.h
|
||||
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 );
|
||||
|
@ -332,6 +335,7 @@ static EDA_HOTKEY* schematic_Hotkey_List[] =
|
|||
&HkLeaveSheet,
|
||||
&HkDeleteNode,
|
||||
&HkHighlightConnection,
|
||||
&HkUnfoldBus,
|
||||
&HkCanvasCairo,
|
||||
&HkCanvasOpenGL,
|
||||
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_EDIT_COMPONENT_WITH_LIBEDIT: // Call Libedit and load the current 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_OPENGL:
|
||||
{
|
||||
|
|
|
@ -80,6 +80,7 @@ enum hotkey_id_commnand {
|
|||
HK_AUTOPLACE_FIELDS,
|
||||
HK_UPDATE_PCB_FROM_SCH,
|
||||
HK_SELECT_ITEMS_ON_PCB,
|
||||
HK_UNFOLD_BUS,
|
||||
HK_CANVAS_OPENGL,
|
||||
HK_CANVAS_CAIRO,
|
||||
};
|
||||
|
|
|
@ -81,6 +81,9 @@ int InvokeDialogPrintUsingPrinter( SCH_EDIT_FRAME* aCaller );
|
|||
/// DIALOG_BOM::ShowModal() returns.
|
||||
int InvokeDialogCreateBOM( SCH_EDIT_FRAME* aCaller );
|
||||
|
||||
/// Create and show DIALOG_BUS_MANAGER
|
||||
void InvokeDialogBusManager( SCH_EDIT_FRAME* aCaller );
|
||||
|
||||
/// Update symbol fields
|
||||
int InvokeDialogUpdateFields( SCH_EDIT_FRAME* aCaller,
|
||||
const std::list<SCH_COMPONENT*> aComponents, bool aCreateUndoEntry );
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <eda_rect.h>
|
||||
#include <transform.h>
|
||||
#include <gr_basic.h>
|
||||
#include <sch_connection.h>
|
||||
|
||||
|
||||
class LINE_READER;
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include <lib_pin.h>
|
||||
#include <transform.h>
|
||||
#include <sch_component.h>
|
||||
#include <sch_sheet_path.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(),
|
||||
aComponent->GetField( VALUE )->GetShownText(),
|
||||
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
|
||||
|
|
|
@ -571,6 +571,12 @@ void prepareToolsMenu( wxMenu* aParentMenu )
|
|||
HELP_GENERATE_BOM,
|
||||
KiBitmap( bom_xpm ) );
|
||||
|
||||
AddMenuItem( aParentMenu,
|
||||
ID_BUS_MANAGER,
|
||||
_( "Bus &Definitions" ),
|
||||
HELP_BUS_MANAGER,
|
||||
KiBitmap( bom_xpm ) ); // TODO(JE) new icon?
|
||||
|
||||
aParentMenu->AppendSeparator();
|
||||
|
||||
// Run CvPcb
|
||||
|
|
|
@ -26,6 +26,9 @@
|
|||
#include "netlist_exporter_generic.h"
|
||||
|
||||
#include <build_version.h>
|
||||
#include <sch_base_frame.h>
|
||||
#include <class_library.h>
|
||||
#include <connection_graph.h>
|
||||
#include <refdes_utils.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.
|
||||
|
||||
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++ )
|
||||
{
|
||||
NETLIST_OBJECT* nitem = m_masterList->GetItem( ii );
|
||||
|
@ -538,6 +590,7 @@ XNODE* NETLIST_EXPORTER_GENERIC::makeListOfNets()
|
|||
xnode->AddAttribute( "ref", ref );
|
||||
xnode->AddAttribute( "pin", nitem->GetPinNumText() );
|
||||
}
|
||||
}
|
||||
|
||||
return xnets;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include <sch_edit_frame.h>
|
||||
|
||||
class CONNECTION_GRAPH;
|
||||
class SYMBOL_LIB_TABLE;
|
||||
|
||||
#define GENERIC_INTERMEDIATE_NETLIST_EXT wxT( "xml" )
|
||||
|
@ -63,10 +64,20 @@ private:
|
|||
|
||||
SYMBOL_LIB_TABLE* m_libTable;
|
||||
|
||||
protected:
|
||||
CONNECTION_GRAPH* m_graph;
|
||||
|
||||
// TODO(JE) Remove if not needed
|
||||
bool m_use_graph;
|
||||
|
||||
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 ),
|
||||
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 <build_version.h>
|
||||
#include <confirm.h>
|
||||
|
||||
#include <sch_edit_frame.h>
|
||||
#include <xnode.h>
|
||||
#include <connection_graph.h>
|
||||
#include "netlist_exporter_kicad.h"
|
||||
|
||||
bool NETLIST_EXPORTER_KICAD::WriteNetlist( const wxString& aOutFileName, unsigned aNetlistOptions )
|
||||
{
|
||||
wxASSERT( m_graph );
|
||||
|
||||
m_use_graph = true;
|
||||
|
||||
try
|
||||
{
|
||||
FILE_OUTPUTFORMATTER formatter( aOutFileName );
|
||||
|
@ -45,6 +52,130 @@ bool NETLIST_EXPORTER_KICAD::WriteNetlist( const wxString& aOutFileName, unsigne
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,8 +38,10 @@ class OUTPUTFORMATTER;
|
|||
class NETLIST_EXPORTER_KICAD : public NETLIST_EXPORTER_GENERIC
|
||||
{
|
||||
public:
|
||||
NETLIST_EXPORTER_KICAD( SCH_EDIT_FRAME* aFrame, NETLIST_OBJECT_LIST* aMasterList ) :
|
||||
NETLIST_EXPORTER_GENERIC( aFrame, aMasterList )
|
||||
NETLIST_EXPORTER_KICAD( SCH_EDIT_FRAME* aFrame,
|
||||
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 )
|
||||
{
|
||||
case NET_TYPE_PCBNEW:
|
||||
helper = new NETLIST_EXPORTER_KICAD( this, aConnectedItemsList );
|
||||
helper = new NETLIST_EXPORTER_KICAD( this, aConnectedItemsList,
|
||||
g_ConnectionGraph );
|
||||
break;
|
||||
|
||||
case NET_TYPE_ORCADPCB2:
|
||||
|
@ -82,7 +83,8 @@ bool SCH_EDIT_FRAME::WriteNetListFile( NETLIST_OBJECT_LIST* aConnectedItemsList,
|
|||
tmpFile.SetExt( GENERIC_INTERMEDIATE_NETLIST_EXT );
|
||||
fileName = tmpFile.GetFullPath();
|
||||
|
||||
helper = new NETLIST_EXPORTER_GENERIC( this, aConnectedItemsList );
|
||||
helper = new NETLIST_EXPORTER_GENERIC( this, aConnectedItemsList,
|
||||
g_ConnectionGraph );
|
||||
executeCommandLine = true;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -30,30 +30,12 @@
|
|||
|
||||
#include <fctsys.h>
|
||||
#include <macros.h>
|
||||
#include <sch_edit_frame.h>
|
||||
#include <list>
|
||||
|
||||
#include <sch_component.h>
|
||||
#include <sch_connection.h>
|
||||
#include <netlist_object.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 );
|
||||
}
|
||||
|
||||
#include <sch_edit_frame.h>
|
||||
|
||||
#if defined(DEBUG)
|
||||
|
||||
|
@ -240,7 +222,8 @@ bool NETLIST_OBJECT::IsLabelConnected( NETLIST_OBJECT* aNetItem )
|
|||
|
||||
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." ) );
|
||||
|
||||
if( m_Type == NET_HIERLABEL )
|
||||
|
@ -254,61 +237,109 @@ void NETLIST_OBJECT::ConvertBusToNetListItems( NETLIST_OBJECT_LIST& aNetListItem
|
|||
else
|
||||
wxCHECK_RET( false, wxT( "Net list object type is not valid." ) );
|
||||
|
||||
unsigned i;
|
||||
wxString tmp, busName, busNumber;
|
||||
long begin, end, member;
|
||||
// NOTE: all netlist objects generated from a single bus definition need to have different
|
||||
// member codes set. For bus vectors, the member code matches the vector index, but for
|
||||
// bus groups (including with nested vectors) the code is something arbitrary.
|
||||
long member_offset = 0;
|
||||
|
||||
busName = busLabelRe.GetMatch( m_Label, 1 );
|
||||
busNumber = busLabelRe.GetMatch( m_Label, 2 );
|
||||
|
||||
/* Search for '[' because a bus label is like "busname[nn..mm]" */
|
||||
i = busNumber.Find( '[' );
|
||||
i++;
|
||||
|
||||
while( i < busNumber.Len() && busNumber[i] != '.' )
|
||||
auto alias = SCH_SCREEN::GetBusAlias( m_Label );
|
||||
if( alias || conn.IsBusGroupLabel( m_Label ) )
|
||||
{
|
||||
tmp.Append( busNumber[i] );
|
||||
i++;
|
||||
wxString group_name;
|
||||
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] == '.' )
|
||||
i++;
|
||||
std::list<wxString> bus_contents( bus_contents_vec.begin(),
|
||||
bus_contents_vec.end() );
|
||||
|
||||
tmp.Empty();
|
||||
|
||||
while( i < busNumber.Len() && busNumber[i] != ']' )
|
||||
for( auto bus_member : bus_contents )
|
||||
{
|
||||
tmp.Append( busNumber[i] );
|
||||
i++;
|
||||
// Nested bus vector inside a bus group
|
||||
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 );
|
||||
|
||||
if( begin < 0 )
|
||||
begin = 0;
|
||||
|
||||
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++ )
|
||||
fillBusVector( aNetListItems, prefix, begin, end, member_offset );
|
||||
member_offset += std::abs( end - begin );
|
||||
}
|
||||
else if( auto nested_alias = SCH_SCREEN::GetBusAlias( bus_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.
|
||||
tmp = busName;
|
||||
tmp << member;
|
||||
item->m_Label = tmp;
|
||||
conn.ParseBusVector( m_Label, &prefix, &begin, &end );
|
||||
|
||||
m_Label = prefix;
|
||||
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;
|
||||
|
||||
aNetListItems.push_back( item );
|
||||
|
|
|
@ -264,6 +264,21 @@ public:
|
|||
* the bus label NETLIST_OBJECTs.
|
||||
*/
|
||||
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() )
|
||||
{
|
||||
case SCH_SHEET_T:
|
||||
m_CurrentSheet->push_back( (SCH_SHEET*) item );
|
||||
g_CurrentSheet->push_back( (SCH_SHEET*) item );
|
||||
DisplayCurrentSheet();
|
||||
break;
|
||||
|
||||
|
|
|
@ -34,9 +34,10 @@
|
|||
#include <sch_edit_frame.h>
|
||||
#include <menus_helpers.h>
|
||||
|
||||
#include <class_library.h>
|
||||
#include <general.h>
|
||||
#include <hotkeys.h>
|
||||
#include <class_library.h>
|
||||
#include <netlist_object.h>
|
||||
#include <sch_bus_entry.h>
|
||||
#include <sch_marker.h>
|
||||
#include <sch_text.h>
|
||||
|
@ -48,6 +49,7 @@
|
|||
#include <sch_sheet_path.h>
|
||||
#include <sch_bitmap.h>
|
||||
#include <symbol_lib_table.h>
|
||||
#include <sch_connection.h>
|
||||
#include <sch_view.h>
|
||||
|
||||
#include <iostream>
|
||||
|
@ -208,7 +210,7 @@ bool SCH_EDIT_FRAME::OnRightClick( const wxPoint& aPosition, wxMenu* PopMenu )
|
|||
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 );
|
||||
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 ) );
|
||||
|
||||
// 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();
|
||||
msg = AddHotkeyName( _( "Add Junction" ), g_Schematic_Hokeys_Descr, HK_ADD_JUNCTION );
|
||||
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
|
||||
GetCanvas()->GetView()->SetScale( scale );
|
||||
|
||||
GetCanvas()->GetView()->SetCenter( aCenterPoint );
|
||||
|
||||
if( aWarpPointer )
|
||||
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 )
|
||||
{
|
||||
auto screen = aScreen;
|
||||
|
||||
if( aScreen == nullptr )
|
||||
screen = GetScreen();
|
||||
|
||||
screen->Append( aItem );
|
||||
|
||||
if( screen == GetScreen() )
|
||||
{
|
||||
GetScreen()->Append( aItem );
|
||||
GetCanvas()->GetView()->Add( aItem );
|
||||
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() )
|
||||
{
|
||||
GetCanvas()->GetView()->Add( item );
|
||||
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 );
|
||||
GetScreen()->Remove( aItem );
|
||||
|
||||
screen->Remove( aItem );
|
||||
|
||||
if( screen == GetScreen() )
|
||||
RefreshItem( aItem, true ); // handle any additional parent semantics
|
||||
}
|
||||
|
||||
|
|
|
@ -298,18 +298,21 @@ public:
|
|||
|
||||
/**
|
||||
* 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)
|
||||
* 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)
|
||||
* 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.
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include <eeschema_config.h>
|
||||
#include <general.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 ) :
|
||||
|
@ -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 )
|
||||
{
|
||||
m_Layer = LAYER_WIRE;
|
||||
m_connected_bus_item = nullptr;
|
||||
}
|
||||
|
||||
SCH_BUS_BUS_ENTRY::SCH_BUS_BUS_ENTRY( const wxPoint& pos, char shape ) :
|
||||
SCH_BUS_ENTRY_BASE( SCH_BUS_BUS_ENTRY_T, pos, shape )
|
||||
{
|
||||
m_Layer = LAYER_BUS;
|
||||
m_connected_bus_items[0] = nullptr;
|
||||
m_connected_bus_items[1] = nullptr;
|
||||
}
|
||||
|
||||
EDA_ITEM* SCH_BUS_WIRE_ENTRY::Clone() const
|
||||
|
@ -416,3 +420,30 @@ char SCH_BUS_ENTRY_BASE::GetBusEntryShape() const
|
|||
else
|
||||
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 GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList ) override;
|
||||
|
||||
#if defined(DEBUG)
|
||||
void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
|
||||
#endif
|
||||
|
@ -157,9 +159,17 @@ public:
|
|||
|
||||
EDA_ITEM* Clone() const override;
|
||||
|
||||
virtual bool ConnectionPropagatesTo( const EDA_ITEM* aItem ) const override;
|
||||
|
||||
BITMAP_DEF GetMenuImage() const 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;
|
||||
|
||||
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_
|
||||
|
|
|
@ -123,7 +123,6 @@ SCH_COMPONENT::SCH_COMPONENT( const wxPoint& aPos, SCH_ITEM* aParent ) :
|
|||
SCH_ITEM( aParent, SCH_COMPONENT_T )
|
||||
{
|
||||
Init( aPos );
|
||||
m_currentSheetPath = NULL;
|
||||
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_lib_id = aLibId;
|
||||
m_part = aPart.SharedPtr();
|
||||
m_currentSheetPath = NULL;
|
||||
m_fieldsAutoplaced = AUTOPLACED_NO;
|
||||
|
||||
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_ITEM( aComponent )
|
||||
{
|
||||
m_currentSheetPath = NULL;
|
||||
m_Parent = aComponent.m_Parent;
|
||||
m_Pos = aComponent.m_Pos;
|
||||
m_unit = aComponent.m_unit;
|
||||
|
@ -471,6 +468,7 @@ void SCH_COMPONENT::UpdatePinCache()
|
|||
if( PART_SPTR part = m_part.lock() )
|
||||
{
|
||||
m_Pins.clear();
|
||||
|
||||
for( LIB_PIN* pin = part->GetNextPin(); pin; pin = part->GetNextPin( pin ) )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
if( m_unit != aUnit )
|
||||
|
@ -1436,9 +1482,9 @@ void SCH_COMPONENT::GetMsgPanelInfo( EDA_UNITS_T aUnits, MSG_PANEL_ITEMS& aList
|
|||
if( !alias )
|
||||
return;
|
||||
|
||||
if( m_currentSheetPath )
|
||||
if( g_CurrentSheet )
|
||||
aList.push_back( MSG_PANEL_ITEM( _( "Reference" ),
|
||||
GetRef( m_currentSheetPath ),
|
||||
GetRef( g_CurrentSheet ),
|
||||
DARKCYAN ) );
|
||||
|
||||
msg = part->IsPower() ? _( "Power symbol" ) : _( "Value" );
|
||||
|
@ -1476,8 +1522,8 @@ void SCH_COMPONENT::GetMsgPanelInfo( EDA_UNITS_T aUnits, MSG_PANEL_ITEMS& aList
|
|||
}
|
||||
else
|
||||
{
|
||||
if( m_currentSheetPath )
|
||||
aList.push_back( MSG_PANEL_ITEM( _( "Reference" ), GetRef( m_currentSheetPath ),
|
||||
if( g_CurrentSheet )
|
||||
aList.push_back( MSG_PANEL_ITEM( _( "Reference" ), GetRef( g_CurrentSheet ),
|
||||
DARKCYAN ) );
|
||||
|
||||
aList.push_back( MSG_PANEL_ITEM( _( "Value" ), GetField( VALUE )->GetShownText(),
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include <vector>
|
||||
#include <set>
|
||||
#include <lib_draw_item.h>
|
||||
#include <sch_pin_connection.h>
|
||||
|
||||
class SCH_SCREEN;
|
||||
class SCH_SHEET_PATH;
|
||||
|
@ -71,6 +72,7 @@ class SCH_COMPONENT : public SCH_ITEM
|
|||
{
|
||||
public:
|
||||
enum AUTOPLACED { AUTOPLACED_NO = 0, AUTOPLACED_AUTO, AUTOPLACED_MANUAL };
|
||||
|
||||
private:
|
||||
|
||||
wxPoint m_Pos;
|
||||
|
@ -97,14 +99,6 @@ private:
|
|||
|
||||
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
|
||||
* for hierarchical sheets that reference the same schematic. The format for the path
|
||||
|
@ -113,6 +107,8 @@ private:
|
|||
*/
|
||||
wxArrayString m_PathsAndReferences;
|
||||
|
||||
std::unordered_map<LIB_PIN*, SCH_PIN_CONNECTION*> m_pin_connections;
|
||||
|
||||
void Init( const wxPoint& pos = wxPoint( 0, 0 ) );
|
||||
|
||||
public:
|
||||
|
@ -219,6 +215,21 @@ public:
|
|||
*/
|
||||
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
|
||||
*
|
||||
|
@ -513,11 +524,6 @@ public:
|
|||
*/
|
||||
static bool IsReferenceStringValid( const wxString& aReferenceString );
|
||||
|
||||
void SetCurrentSheetPath( const SCH_SHEET_PATH* aSheetPath )
|
||||
{
|
||||
m_currentSheetPath = aSheetPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the reference for the given sheet path.
|
||||
*
|
||||
|
@ -666,5 +672,4 @@ private:
|
|||
bool doIsConnected( const wxPoint& aPosition ) const override;
|
||||
};
|
||||
|
||||
|
||||
#endif /* COMPONENT_CLASS_H */
|
||||
|
|
|
@ -0,0 +1,469 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2018 CERN
|
||||
* @author Jon Evans <jon@craftyjon.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <boost/regex.hpp>
|
||||
#include <wx/tokenzr.h>
|
||||
|
||||
#include <connection_graph.h>
|
||||
#include <sch_pin_connection.h>
|
||||
#include <sch_screen.h>
|
||||
|
||||
#include <sch_connection.h>
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* Buses can be defined in multiple ways. A bus vector consists of a prefix and
|
||||
* a numeric range of suffixes:
|
||||
*
|
||||
* BUS_NAME[M..N]
|
||||
*
|
||||
* For example, the bus A[3..0] will contain nets A3, A2, A1, and A0.
|
||||
* The BUS_NAME is required. M and N must be integers but do not need to be in
|
||||
* any particular order -- A[0..3] produces the same result.
|
||||
*
|
||||
* Like net names, bus names cannot contain whitespace.
|
||||
*
|
||||
* A bus group is just a grouping of signals, separated by spaces, some
|
||||
* of which may be bus vectors. Bus groups can have names, but do not need to.
|
||||
*
|
||||
* MEMORY{A[15..0] D[7..0] RW CE OE}
|
||||
*
|
||||
* In named bus groups, the net names are expanded as <BUS_NAME>.<NET_NAME>
|
||||
* In the above example, the nets would be named like MEMORY.A15, MEMORY.D0, etc.
|
||||
*
|
||||
* {USB_DP USB_DN}
|
||||
*
|
||||
* In the above example, the bus is unnamed and so the underlying net names are
|
||||
* just USB_DP and USB_DN.
|
||||
*
|
||||
*/
|
||||
static boost::regex bus_label_re( "^([^[:space:]]+)(\\[[\\d]+\\.+[\\d]+\\])$" );
|
||||
|
||||
static boost::regex bus_group_label_re( "^([^[:space:]]+)?\\{((?:[^[:space:]]+(?:\\[[\\d]+\\.+[\\d]+\\])? ?)+)\\}$" );
|
||||
|
||||
|
||||
SCH_CONNECTION::SCH_CONNECTION( SCH_ITEM* aParent, SCH_SHEET_PATH aPath ) :
|
||||
m_sheet( aPath ),
|
||||
m_parent( aParent )
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
|
||||
bool SCH_CONNECTION::operator==( const SCH_CONNECTION& aOther ) const
|
||||
{
|
||||
// NOTE: Not comparing m_dirty or net/bus/subgraph codes
|
||||
if( ( aOther.m_driver == m_driver ) &&
|
||||
( aOther.m_type == m_type ) &&
|
||||
( aOther.m_name == m_name ) &&
|
||||
( aOther.m_sheet == m_sheet ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void SCH_CONNECTION::SetDriver( SCH_ITEM* aItem )
|
||||
{
|
||||
m_driver = aItem;
|
||||
|
||||
for( auto member : m_members )
|
||||
member->SetDriver( aItem );
|
||||
}
|
||||
|
||||
|
||||
void SCH_CONNECTION::SetSheet( SCH_SHEET_PATH aSheet )
|
||||
{
|
||||
m_sheet = aSheet;
|
||||
|
||||
for( auto member : m_members )
|
||||
member->SetSheet( aSheet );
|
||||
}
|
||||
|
||||
|
||||
bool SCH_CONNECTION::operator!=( const SCH_CONNECTION& aOther ) const
|
||||
{
|
||||
return !( aOther == *this );
|
||||
}
|
||||
|
||||
|
||||
void SCH_CONNECTION::ConfigureFromLabel( wxString aLabel )
|
||||
{
|
||||
if( IsBusVectorLabel( aLabel ) )
|
||||
{
|
||||
m_name = aLabel;
|
||||
m_type = CONNECTION_BUS;
|
||||
|
||||
ParseBusVector( aLabel, &m_vector_prefix, &m_vector_start, &m_vector_end );
|
||||
|
||||
for( long i = m_vector_start; i <= m_vector_end; ++i )
|
||||
{
|
||||
auto member = std::make_shared< SCH_CONNECTION >( m_parent, m_sheet );
|
||||
wxString name = m_vector_prefix;
|
||||
name << i;
|
||||
member->m_type = CONNECTION_NET;
|
||||
member->m_name = m_prefix + name;
|
||||
member->m_vector_index = i;
|
||||
m_members.push_back( member );
|
||||
}
|
||||
}
|
||||
else if( IsBusGroupLabel( aLabel ) )
|
||||
{
|
||||
m_type = CONNECTION_BUS_GROUP;
|
||||
m_name = aLabel;
|
||||
|
||||
std::vector<wxString> members;
|
||||
wxString group_name;
|
||||
|
||||
if( ParseBusGroup( aLabel, &group_name, members ) )
|
||||
{
|
||||
// Named bus groups generate a net prefix, unnamed ones don't
|
||||
auto prefix = ( group_name != "" ) ? ( group_name + "." ) : "";
|
||||
|
||||
for( auto group_member : members )
|
||||
{
|
||||
// Handle alias inside bus group member list
|
||||
if( auto alias = g_ConnectionGraph->GetBusAlias( group_member ) )
|
||||
{
|
||||
for( auto alias_member : alias->Members() )
|
||||
{
|
||||
auto member = std::make_shared< SCH_CONNECTION >( m_parent, m_sheet );
|
||||
member->SetPrefix( prefix );
|
||||
member->ConfigureFromLabel( alias_member );
|
||||
m_members.push_back( member );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
auto member = std::make_shared< SCH_CONNECTION >( m_parent, m_sheet );
|
||||
member->SetPrefix( prefix );
|
||||
member->ConfigureFromLabel( group_member );
|
||||
m_members.push_back( member );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( auto alias = g_ConnectionGraph->GetBusAlias( aLabel ) )
|
||||
{
|
||||
m_type = CONNECTION_BUS_GROUP;
|
||||
m_name = aLabel;
|
||||
|
||||
for( auto alias_member : alias->Members() )
|
||||
{
|
||||
auto member = std::make_shared< SCH_CONNECTION >( m_parent );
|
||||
member->ConfigureFromLabel( alias_member );
|
||||
m_members.push_back( member );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_name = m_prefix + aLabel;
|
||||
m_type = CONNECTION_NET;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SCH_CONNECTION::Reset()
|
||||
{
|
||||
m_type = CONNECTION_NONE;
|
||||
m_name = "<NO NET>";
|
||||
m_prefix = "";
|
||||
m_driver = nullptr;
|
||||
m_members.clear();
|
||||
m_dirty = true;
|
||||
m_net_code = 0;
|
||||
m_bus_code = 0;
|
||||
m_subgraph_code = 0;
|
||||
m_vector_start = 0;
|
||||
m_vector_end = 0;
|
||||
m_vector_index = 0;
|
||||
m_vector_prefix = "";
|
||||
}
|
||||
|
||||
|
||||
void SCH_CONNECTION::Clone( SCH_CONNECTION& aOther )
|
||||
{
|
||||
m_type = aOther.Type();
|
||||
m_driver = aOther.Driver();
|
||||
m_sheet = aOther.Sheet();
|
||||
m_name = aOther.Name( true );
|
||||
m_prefix = aOther.Prefix();
|
||||
m_members = aOther.Members();
|
||||
m_net_code = aOther.NetCode();
|
||||
m_bus_code = aOther.BusCode();
|
||||
//m_subgraph_code = aOther.SubgraphCode();
|
||||
m_vector_start = aOther.VectorStart();
|
||||
m_vector_end = aOther.VectorEnd();
|
||||
m_vector_index = aOther.VectorIndex();
|
||||
m_vector_prefix = aOther.VectorPrefix();
|
||||
}
|
||||
|
||||
|
||||
bool SCH_CONNECTION::IsDriver() const
|
||||
{
|
||||
wxASSERT( Parent() );
|
||||
|
||||
switch( Parent()->Type() )
|
||||
{
|
||||
case SCH_LABEL_T:
|
||||
case SCH_GLOBAL_LABEL_T:
|
||||
case SCH_HIERARCHICAL_LABEL_T:
|
||||
case SCH_PIN_CONNECTION_T:
|
||||
case SCH_SHEET_PIN_T:
|
||||
case SCH_SHEET_T:
|
||||
case LIB_PIN_T:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
wxString SCH_CONNECTION::Name( bool aIgnoreSheet ) const
|
||||
{
|
||||
wxString ret = m_name;
|
||||
|
||||
if( !Parent() || m_type == CONNECTION_NONE )
|
||||
return ret;
|
||||
|
||||
bool prepend_path = true;
|
||||
|
||||
switch( Parent()->Type() )
|
||||
{
|
||||
case SCH_PIN_CONNECTION_T:
|
||||
// Pins are either power connections or belong to a uniquely-annotated
|
||||
// component, so they don't need a path
|
||||
prepend_path = false;
|
||||
break;
|
||||
|
||||
case SCH_GLOBAL_LABEL_T:
|
||||
prepend_path = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if( prepend_path && !aIgnoreSheet )
|
||||
ret = m_sheet.PathHumanReadable() + ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void SCH_CONNECTION::AppendInfoToMsgPanel( MSG_PANEL_ITEMS& aList ) const
|
||||
{
|
||||
wxString msg, group_name;
|
||||
std::vector<wxString> group_members;
|
||||
|
||||
aList.push_back( MSG_PANEL_ITEM( _( "Connection Name" ), m_name, BROWN ) );
|
||||
|
||||
msg.Printf( "%d", m_net_code );
|
||||
aList.push_back( MSG_PANEL_ITEM( _( "Net Code" ), msg, BROWN ) );
|
||||
|
||||
if( auto alias = g_ConnectionGraph->GetBusAlias( m_name ) )
|
||||
{
|
||||
msg.Printf( _( "Bus Alias %s Members" ), m_name );
|
||||
|
||||
wxString members;
|
||||
|
||||
for( auto member : alias->Members() )
|
||||
members << member << " ";
|
||||
|
||||
aList.push_back( MSG_PANEL_ITEM( msg, members, RED ) );
|
||||
}
|
||||
else if( ParseBusGroup( m_name, &group_name, group_members ) )
|
||||
{
|
||||
for( auto group_member : group_members )
|
||||
{
|
||||
if( auto group_alias = g_ConnectionGraph->GetBusAlias( group_member ) )
|
||||
{
|
||||
msg.Printf( _( "Bus Alias %s Members" ), group_alias->GetName() );
|
||||
|
||||
wxString members;
|
||||
|
||||
for( auto member : group_alias->Members() )
|
||||
members << member << " ";
|
||||
|
||||
aList.push_back( MSG_PANEL_ITEM( msg, members, RED ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SCH_CONNECTION::AppendDebugInfoToMsgPanel( MSG_PANEL_ITEMS& aList ) const
|
||||
{
|
||||
wxString msg;
|
||||
|
||||
AppendInfoToMsgPanel( aList );
|
||||
|
||||
msg.Printf( "%d", m_bus_code );
|
||||
aList.push_back( MSG_PANEL_ITEM( _( "Bus Code" ), msg, BROWN ) );
|
||||
|
||||
msg.Printf( "%d", m_subgraph_code );
|
||||
aList.push_back( MSG_PANEL_ITEM( _( "Subgraph Code" ), msg, BROWN ) );
|
||||
|
||||
if( auto driver = Driver() )
|
||||
{
|
||||
msg.Printf( "%s at %p", driver->GetSelectMenuText( MILLIMETRES ), driver );
|
||||
aList.push_back( MSG_PANEL_ITEM( _( "Connection Source" ), msg, RED ) );
|
||||
}
|
||||
|
||||
msg.Printf( "%s at %p", Parent()->GetSelectMenuText( MILLIMETRES ), Parent() );
|
||||
aList.push_back( MSG_PANEL_ITEM( _( "Attached To" ), msg, RED ) );
|
||||
}
|
||||
|
||||
|
||||
bool SCH_CONNECTION::IsBusLabel( const wxString& aLabel )
|
||||
{
|
||||
return IsBusVectorLabel( aLabel ) || IsBusGroupLabel( aLabel );
|
||||
}
|
||||
|
||||
|
||||
bool SCH_CONNECTION::IsBusVectorLabel( const wxString& aLabel )
|
||||
{
|
||||
return boost::regex_match( std::string( aLabel.mb_str() ), bus_label_re );
|
||||
}
|
||||
|
||||
|
||||
bool SCH_CONNECTION::IsBusGroupLabel( const wxString& aLabel )
|
||||
{
|
||||
return boost::regex_match( std::string( aLabel.mb_str() ), bus_group_label_re );
|
||||
}
|
||||
|
||||
|
||||
void SCH_CONNECTION::ParseBusVector( wxString aVector, wxString* aName,
|
||||
long* begin, long* end ) const
|
||||
{
|
||||
auto ss_vector = std::string( aVector.mb_str() );
|
||||
boost::smatch matches;
|
||||
|
||||
if( !boost::regex_match( ss_vector, matches, bus_label_re ) )
|
||||
{
|
||||
wxFAIL_MSG( wxT( "<" ) + aVector + wxT( "> is not a valid bus vector." ) );
|
||||
return;
|
||||
}
|
||||
|
||||
*aName = wxString( matches[1] );
|
||||
wxString numberString( matches[2] );
|
||||
|
||||
// numberString will include the brackets, e.g. [5..0] so skip the first one
|
||||
size_t i = 1, len = numberString.Len();
|
||||
wxString tmp;
|
||||
|
||||
while( i < len && numberString[i] != '.' )
|
||||
{
|
||||
tmp.Append( numberString[i] );
|
||||
i++;
|
||||
}
|
||||
|
||||
tmp.ToLong( begin );
|
||||
|
||||
while( i < len && numberString[i] == '.' )
|
||||
i++;
|
||||
|
||||
tmp.Empty();
|
||||
|
||||
while( i < len && numberString[i] != ']' )
|
||||
{
|
||||
tmp.Append( numberString[i] );
|
||||
i++;
|
||||
}
|
||||
|
||||
tmp.ToLong( end );
|
||||
|
||||
if( *begin < 0 )
|
||||
*begin = 0;
|
||||
|
||||
if( *end < 0 )
|
||||
*end = 0;
|
||||
|
||||
if( *begin > *end )
|
||||
std::swap( *begin, *end );
|
||||
}
|
||||
|
||||
|
||||
bool SCH_CONNECTION::ParseBusGroup( wxString aGroup, wxString* aName,
|
||||
std::vector<wxString>& aMemberList ) const
|
||||
{
|
||||
auto ss_group = std::string( aGroup.mb_str() );
|
||||
boost::smatch matches;
|
||||
|
||||
if( !boost::regex_match( ss_group, matches, bus_group_label_re ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
*aName = wxString( matches[1] );
|
||||
|
||||
wxStringTokenizer tokenizer( wxString( matches[2] ), " " );
|
||||
while( tokenizer.HasMoreTokens() )
|
||||
{
|
||||
aMemberList.push_back( tokenizer.GetNextToken() );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool SCH_CONNECTION::IsSubsetOf( SCH_CONNECTION* aOther ) const
|
||||
{
|
||||
if( aOther->IsNet() )
|
||||
return IsNet() ? ( aOther->Name( true ) == Name( true ) ) : false;
|
||||
|
||||
if( !IsBus() )
|
||||
return false;
|
||||
|
||||
std::vector<wxString> mine, theirs;
|
||||
|
||||
for( auto m : Members() )
|
||||
mine.push_back( m->Name( true ) );
|
||||
|
||||
for( auto m : aOther->Members() )
|
||||
theirs.push_back( m->Name( true ) );
|
||||
|
||||
std::set<wxString> subset;
|
||||
|
||||
std::set_intersection( mine.begin(), mine.end(),
|
||||
theirs.begin(), theirs.end(),
|
||||
std::inserter(subset, subset.begin() ) );
|
||||
|
||||
return ( !subset.empty() );
|
||||
}
|
||||
|
||||
|
||||
bool SCH_CONNECTION::IsMemberOfBus( SCH_CONNECTION* aOther ) const
|
||||
{
|
||||
if( !aOther->IsBus() )
|
||||
return false;
|
||||
|
||||
auto me = Name( true );
|
||||
|
||||
for( auto m : aOther->Members() )
|
||||
if( m->Name( true ) == me )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
|
@ -0,0 +1,347 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2018 CERN
|
||||
* @author Jon Evans <jon@craftyjon.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _SCH_CONNECTION_H
|
||||
#define _SCH_CONNECTION_H
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_set>
|
||||
|
||||
#include <boost/optional.hpp>
|
||||
#include <wx/regex.h>
|
||||
|
||||
#include <bus_alias.h>
|
||||
#include <msgpanel.h>
|
||||
#include <sch_sheet_path.h>
|
||||
|
||||
|
||||
class SCH_ITEM;
|
||||
class SCH_SHEET_PATH;
|
||||
|
||||
|
||||
enum CONNECTION_TYPE
|
||||
{
|
||||
CONNECTION_NONE, ///< No connection to this item
|
||||
CONNECTION_NET, ///< This item represents a net
|
||||
CONNECTION_BUS, ///< This item represents a bus vector
|
||||
CONNECTION_BUS_GROUP, ///< This item represents a bus group
|
||||
};
|
||||
|
||||
/**
|
||||
* Each graphical item can have a SCH_CONNECTION describing its logical
|
||||
* connection (to a bus or net). These are generated when netlisting, or when
|
||||
* editing operations that can change the netlist are performed.
|
||||
*
|
||||
* In hierarchical schematics, a single SCH_ITEM object can refer to multiple
|
||||
* distinct parts of a design (in the case of a sub-sheet that is instanced
|
||||
* more than once in a higher level sheet). Because of this, a single item may
|
||||
* contain more than one SCH_CONNECTION -- each is specific to a sheet.
|
||||
*
|
||||
* Components contain connections for each of their pins (and for each sheet
|
||||
* they exist on) but don't use their own connection object.
|
||||
*/
|
||||
class SCH_CONNECTION
|
||||
{
|
||||
public:
|
||||
SCH_CONNECTION( SCH_ITEM* aParent = nullptr, SCH_SHEET_PATH aPath = SCH_SHEET_PATH() );
|
||||
|
||||
~SCH_CONNECTION()
|
||||
{}
|
||||
|
||||
/**
|
||||
* Note: the equality operator for SCH_CONNECTION only tests the net
|
||||
* properties, not the ownership / sheet location!
|
||||
*/
|
||||
bool operator==( const SCH_CONNECTION& aOther ) const;
|
||||
|
||||
bool operator!=( const SCH_CONNECTION& aOther ) const;
|
||||
|
||||
/**
|
||||
* Configures the connection given a label.
|
||||
* For CONNECTION_NET, this just sets the name.
|
||||
* For CONNECTION_BUS, this will deduce the correct BUS_TYPE and also
|
||||
* generate a correct list of members.
|
||||
*/
|
||||
void ConfigureFromLabel( wxString aLabel );
|
||||
|
||||
/**
|
||||
* Clears connectivity information
|
||||
*/
|
||||
void Reset();
|
||||
|
||||
/**
|
||||
* Copies connectivity information (but not parent) from another connection
|
||||
*
|
||||
* @param aOther is the connection to clone
|
||||
*/
|
||||
void Clone( SCH_CONNECTION& aOther );
|
||||
|
||||
SCH_ITEM* Parent() const
|
||||
{
|
||||
return m_parent;
|
||||
}
|
||||
|
||||
SCH_ITEM* Driver() const
|
||||
{
|
||||
return m_driver;
|
||||
}
|
||||
|
||||
SCH_SHEET_PATH Sheet() const
|
||||
{
|
||||
return m_sheet;
|
||||
}
|
||||
|
||||
void SetDriver( SCH_ITEM* aItem );
|
||||
|
||||
void SetSheet( SCH_SHEET_PATH aSheet );
|
||||
|
||||
/**
|
||||
* Checks if the SCH_ITEM this connection is attached to can drive connections
|
||||
* Drivers can be labels, sheet pins, or component pins.
|
||||
*
|
||||
* @return true if the attached items is a driver
|
||||
*/
|
||||
bool IsDriver() const;
|
||||
|
||||
bool IsBus() const
|
||||
{
|
||||
return ( m_type == CONNECTION_BUS || m_type == CONNECTION_BUS_GROUP );
|
||||
}
|
||||
|
||||
bool IsNet() const
|
||||
{
|
||||
return ( m_type == CONNECTION_NET );
|
||||
}
|
||||
|
||||
bool IsDirty() const
|
||||
{
|
||||
return m_dirty;
|
||||
}
|
||||
|
||||
void SetDirty()
|
||||
{
|
||||
m_dirty = true;
|
||||
}
|
||||
|
||||
void ClearDirty()
|
||||
{
|
||||
m_dirty = false;
|
||||
}
|
||||
|
||||
wxString Name( bool aIgnoreSheet = false ) const;
|
||||
|
||||
wxString Prefix() const
|
||||
{
|
||||
return m_prefix;
|
||||
}
|
||||
|
||||
void SetPrefix( wxString aPrefix )
|
||||
{
|
||||
m_prefix = aPrefix;
|
||||
}
|
||||
|
||||
CONNECTION_TYPE Type() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
void SetType( CONNECTION_TYPE aType )
|
||||
{
|
||||
m_type = aType;
|
||||
}
|
||||
|
||||
int NetCode() const
|
||||
{
|
||||
return m_net_code;
|
||||
}
|
||||
|
||||
void SetNetCode( int aCode )
|
||||
{
|
||||
m_net_code = aCode;
|
||||
}
|
||||
|
||||
int BusCode() const
|
||||
{
|
||||
return m_bus_code;
|
||||
}
|
||||
|
||||
void SetBusCode( int aCode )
|
||||
{
|
||||
m_bus_code = aCode;
|
||||
}
|
||||
|
||||
int SubgraphCode() const
|
||||
{
|
||||
return m_subgraph_code;
|
||||
}
|
||||
|
||||
void SetSubgraphCode( int aCode )
|
||||
{
|
||||
m_subgraph_code = aCode;
|
||||
}
|
||||
|
||||
long VectorStart() const
|
||||
{
|
||||
return m_vector_start;
|
||||
}
|
||||
|
||||
long VectorEnd() const
|
||||
{
|
||||
return m_vector_end;
|
||||
}
|
||||
|
||||
long VectorIndex() const
|
||||
{
|
||||
return m_vector_index;
|
||||
}
|
||||
|
||||
wxString VectorPrefix() const
|
||||
{
|
||||
return m_vector_prefix;
|
||||
}
|
||||
|
||||
std::vector< std::shared_ptr< SCH_CONNECTION > >& Members()
|
||||
{
|
||||
return m_members;
|
||||
}
|
||||
|
||||
const std::vector< std::shared_ptr< SCH_CONNECTION > >& Members() const
|
||||
{
|
||||
return m_members;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if aOther is a subset of this connection or vice versa.
|
||||
*
|
||||
* For plain nets, this just tests whether or not the connectio names are
|
||||
* the same. For buses, this tests whether the two have any shared members.
|
||||
*
|
||||
* Will always return false if one connection is a bus and the other a net.
|
||||
*/
|
||||
bool IsSubsetOf( SCH_CONNECTION* aOther ) const;
|
||||
|
||||
/**
|
||||
* Returns true if this connection is a member of bus connection aOther
|
||||
*
|
||||
* Will always return false if aOther is not a bus connection
|
||||
*/
|
||||
bool IsMemberOfBus( SCH_CONNECTION* aOther ) const;
|
||||
|
||||
/**
|
||||
* Parses a bus vector (e.g. A[7..0]) into name, begin, and end.
|
||||
* Ensures that begin and end are positive and that end > begin.
|
||||
*
|
||||
* @param vector is a bus vector label string
|
||||
* @param name output of the name portion of the label
|
||||
* @param begin is the first entry in the vector
|
||||
* @param end is the last entry in the vector
|
||||
*/
|
||||
void ParseBusVector( wxString vector, wxString* name,
|
||||
long* begin, long* end ) const;
|
||||
|
||||
/**
|
||||
* Parses a bus group label into the name and a list of components
|
||||
*
|
||||
* @param aGroup is the input label, e.g. "USB{DP DM}"
|
||||
* @param name is the output group name, e.g. "USB"
|
||||
* @param aMemberList is a list of member strings, e.g. "DP", "DM"
|
||||
* @return true if aGroup was successfully parsed
|
||||
*/
|
||||
bool ParseBusGroup( wxString aGroup, wxString* name,
|
||||
std::vector<wxString>& aMemberList ) const;
|
||||
|
||||
/**
|
||||
* Adds information about the connection object to aList
|
||||
*/
|
||||
void AppendInfoToMsgPanel( MSG_PANEL_ITEMS& aList ) const;
|
||||
|
||||
/**
|
||||
* Adds extended debug information about the connection object to aList
|
||||
*/
|
||||
void AppendDebugInfoToMsgPanel( MSG_PANEL_ITEMS& aList ) const;
|
||||
|
||||
/**
|
||||
* Test if \a aLabel has a bus notation.
|
||||
*
|
||||
* @param aLabel A wxString object containing the label to test.
|
||||
* @return true if text is a bus notation format otherwise false is returned.
|
||||
*/
|
||||
bool IsBusLabel( const wxString& aLabel );
|
||||
|
||||
/**
|
||||
* Test if \a aLabel has a bus vector notation (simple bus, e.g. A[7..0])
|
||||
*
|
||||
* @param aLabel A wxString object containing the label to test.
|
||||
* @return true if text is a bus notation format otherwise false is returned.
|
||||
*/
|
||||
bool IsBusVectorLabel( const wxString& aLabel );
|
||||
|
||||
/**
|
||||
* Test if \a aLabel has a bus group notation.
|
||||
*
|
||||
* @param aLabel A wxString object containing the label to test.
|
||||
* @return true if text is a bus group notation format
|
||||
*/
|
||||
bool IsBusGroupLabel( const wxString& aLabel );
|
||||
|
||||
private:
|
||||
|
||||
bool m_dirty;
|
||||
|
||||
SCH_SHEET_PATH m_sheet; ///< The hierarchical sheet this connection is on
|
||||
|
||||
SCH_ITEM* m_parent; ///< The SCH_ITEM this connection is owned by
|
||||
|
||||
SCH_ITEM* m_driver; ///< The SCH_ITEM that drives this connection's net
|
||||
|
||||
CONNECTION_TYPE m_type; ///< @see enum CONNECTION_TYPE
|
||||
|
||||
wxString m_name; ///< Name of the bus.
|
||||
|
||||
///< Prefix if connection is member of a labeled bus group (or "" if not)
|
||||
wxString m_prefix;
|
||||
|
||||
int m_net_code; // TODO(JE) remove if unused
|
||||
|
||||
int m_bus_code; // TODO(JE) remove if unused
|
||||
|
||||
int m_subgraph_code; ///< Groups directly-connected items
|
||||
|
||||
long m_vector_index; ///< Index of bus vector member nets
|
||||
|
||||
long m_vector_start; ///< Highest member of a vector bus
|
||||
|
||||
long m_vector_end; ///< Lowest member of a vector bus
|
||||
|
||||
///< Prefix name of the vector, if m_type == CONNECTION_BUS (or "" if not)
|
||||
wxString m_vector_prefix;
|
||||
|
||||
/**
|
||||
* For bus connections, store a list of member connections
|
||||
*
|
||||
* NOTE: All connections that Clone() others share the list of member
|
||||
* pointers. This seems fine at the moment.
|
||||
*/
|
||||
std::vector< std::shared_ptr< SCH_CONNECTION > > m_members;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -69,6 +69,7 @@
|
|||
#include <wildcards_and_files_ext.h>
|
||||
|
||||
#include <netlist_exporter_kicad.h>
|
||||
#include <connection_graph.h>
|
||||
#include <kiway.h>
|
||||
#include <dialogs/dialog_fields_editor_global.h>
|
||||
|
||||
|
@ -77,6 +78,9 @@
|
|||
|
||||
#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.
|
||||
// Do NOT Clear() in here.
|
||||
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_GET_TOOLS, SCH_EDIT_FRAME::OnCreateBillOfMaterials )
|
||||
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( wxID_REPLACE, SCH_EDIT_FRAME::OnFindItems )
|
||||
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_POPUP_START_RANGE, ID_POPUP_END_RANGE,
|
||||
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_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 ),
|
||||
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_showBorderAndTitleBlock = true; // true to show sheet references
|
||||
m_CurrentSheet = new SCH_SHEET_PATH;
|
||||
m_DefaultSchematicFileName = NAMELESS_PROJECT;
|
||||
m_DefaultSchematicFileName += wxT( ".sch" );
|
||||
m_showAllPins = false;
|
||||
|
@ -386,6 +394,7 @@ SCH_EDIT_FRAME::SCH_EDIT_FRAME( KIWAY* aKiway, wxWindow* aParent ):
|
|||
m_findReplaceStatus = new wxString( wxEmptyString );
|
||||
m_undoItem = NULL;
|
||||
m_hasAutoSave = true;
|
||||
m_busUnfold = {};
|
||||
m_FrameSize = ConvertDialogToPixels( wxSize( 500, 350 ) ); // default in case of no prefs
|
||||
|
||||
m_toolManager = new TOOL_MANAGER;
|
||||
|
@ -458,12 +467,15 @@ SCH_EDIT_FRAME::~SCH_EDIT_FRAME()
|
|||
|
||||
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_findReplaceData;
|
||||
delete m_findReplaceStatus;
|
||||
|
||||
delete g_RootSheet;
|
||||
|
||||
g_CurrentSheet = nullptr;
|
||||
g_ConnectionGraph = nullptr;
|
||||
g_RootSheet = NULL;
|
||||
}
|
||||
|
||||
|
@ -503,7 +515,7 @@ void SCH_EDIT_FRAME::SetSheetNumberAndCount()
|
|||
*/
|
||||
int sheet_count = g_RootSheet->CountSheets();
|
||||
int SheetNumber = 1;
|
||||
wxString current_sheetpath = m_CurrentSheet->Path();
|
||||
wxString current_sheetpath = g_CurrentSheet->Path();
|
||||
SCH_SHEET_LIST sheetList( g_RootSheet );
|
||||
|
||||
// Examine all sheets path to find the current sheets path,
|
||||
|
@ -520,7 +532,7 @@ void SCH_EDIT_FRAME::SetSheetNumberAndCount()
|
|||
* path */
|
||||
}
|
||||
|
||||
m_CurrentSheet->SetPageNumber( SheetNumber );
|
||||
g_CurrentSheet->SetPageNumber( SheetNumber );
|
||||
|
||||
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
|
||||
{
|
||||
return m_CurrentSheet->LastScreen();
|
||||
return g_CurrentSheet->LastScreen();
|
||||
}
|
||||
|
||||
|
||||
wxString SCH_EDIT_FRAME::GetScreenDesc() const
|
||||
{
|
||||
wxString s = m_CurrentSheet->PathHumanReadable();
|
||||
wxString s = g_CurrentSheet->PathHumanReadable();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
@ -562,8 +574,9 @@ void SCH_EDIT_FRAME::CreateScreens()
|
|||
|
||||
g_RootSheet->GetScreen()->SetFileName( m_DefaultSchematicFileName );
|
||||
|
||||
m_CurrentSheet->clear();
|
||||
m_CurrentSheet->push_back( g_RootSheet );
|
||||
g_CurrentSheet->clear();
|
||||
g_CurrentSheet->push_back( g_RootSheet );
|
||||
g_ConnectionGraph->Reset();
|
||||
|
||||
if( GetScreen() == NULL )
|
||||
{
|
||||
|
@ -578,26 +591,26 @@ void SCH_EDIT_FRAME::CreateScreens()
|
|||
|
||||
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 )
|
||||
{
|
||||
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()
|
||||
{
|
||||
static_cast<SCH_DRAW_PANEL*>( m_canvas )->DisplaySheet( m_CurrentSheet->LastScreen() );
|
||||
static_cast<SCH_DRAW_PANEL*>( m_canvas )->DisplaySheet( g_CurrentSheet->LastScreen() );
|
||||
GetCanvas()->Refresh();
|
||||
}
|
||||
|
||||
|
@ -709,7 +722,7 @@ void SCH_EDIT_FRAME::OnCloseWindow( wxCloseEvent& aEvent )
|
|||
g_RootSheet->GetScreen()->Clear();
|
||||
|
||||
// all sub sheets are deleted, only the main sheet is usable
|
||||
m_CurrentSheet->clear();
|
||||
g_CurrentSheet->clear();
|
||||
|
||||
Destroy();
|
||||
}
|
||||
|
@ -739,7 +752,7 @@ wxString SCH_EDIT_FRAME::GetUniqueFilenameForCurrentSheet()
|
|||
#define FN_LEN_MAX 80 // A reasonable value for the short filename len
|
||||
|
||||
wxString filename = fn.GetName();
|
||||
wxString sheetFullName = m_CurrentSheet->PathHumanReadable();
|
||||
wxString sheetFullName = g_CurrentSheet->PathHumanReadable();
|
||||
|
||||
// Remove the last '/' of the path human readable
|
||||
// (and for the root sheet, make sheetFullName empty):
|
||||
|
@ -767,6 +780,9 @@ void SCH_EDIT_FRAME::OnModify()
|
|||
|
||||
m_foundItems.SetForceSearch();
|
||||
|
||||
//RecalculateConnections( SCH_SHEET_LIST( g_CurrentSheet->Last() ) );
|
||||
RecalculateConnections();
|
||||
|
||||
m_canvas->Refresh();
|
||||
}
|
||||
|
||||
|
@ -824,7 +840,7 @@ void SCH_EDIT_FRAME::OnUpdateSaveSheet( 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_EXPORTER_KICAD exporter( this, net_atoms );
|
||||
NETLIST_EXPORTER_KICAD exporter( this, net_atoms, g_ConnectionGraph );
|
||||
STRING_FORMATTER formatter;
|
||||
|
||||
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 )
|
||||
{
|
||||
wxCHECK_RET( m_findReplaceData != NULL,
|
||||
|
@ -1393,7 +1415,7 @@ void SCH_EDIT_FRAME::addCurrentItemToScreen()
|
|||
// the m_mouseCaptureCallback function.
|
||||
m_canvas->SetMouseCapture( NULL, NULL );
|
||||
|
||||
if( !EditSheet( (SCH_SHEET*)item, m_CurrentSheet, &doClearAnnotation ) )
|
||||
if( !EditSheet( (SCH_SHEET*)item, g_CurrentSheet, &doClearAnnotation ) )
|
||||
{
|
||||
screen->SetCurItem( NULL );
|
||||
delete item;
|
||||
|
@ -1438,6 +1460,9 @@ void SCH_EDIT_FRAME::addCurrentItemToScreen()
|
|||
SCH_SCREENS screensList( g_RootSheet );
|
||||
screensList.ClearAnnotationOfNewSheetPaths( initial_sheetpathList );
|
||||
}
|
||||
|
||||
// Update connectivity info for new item
|
||||
RecalculateConnections();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1488,7 +1513,7 @@ void SCH_EDIT_FRAME::UpdateTitle()
|
|||
wxFileName fn = fileName;
|
||||
|
||||
title.Printf( _( "Eeschema" ) + wxT( " \u2014 %s [%s] \u2014 %s" ),
|
||||
fn.GetFullName(), m_CurrentSheet->PathHumanReadable(),
|
||||
fn.GetFullName(), g_CurrentSheet->PathHumanReadable(),
|
||||
fn.GetPath() );
|
||||
|
||||
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()
|
||||
{
|
||||
SCH_BASE_FRAME::CommonSettingsChanged();
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include <template_fieldnames.h>
|
||||
#include <block_commande.h>
|
||||
#include <sch_collectors.h>
|
||||
#include <erc_settings.h>
|
||||
#include <sch_draw_panel.h>
|
||||
|
||||
// enum PINSHEETLABEL_SHAPE
|
||||
|
@ -66,6 +67,7 @@ class wxFindDialogEvent;
|
|||
class wxFindReplaceData;
|
||||
class SCHLIB_FILTER;
|
||||
class RESCUER;
|
||||
class CONNECTION_GRAPH;
|
||||
|
||||
|
||||
/// 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.
|
||||
*/
|
||||
class SCH_EDIT_FRAME : public SCH_BASE_FRAME
|
||||
{
|
||||
private:
|
||||
SCH_SHEET_PATH* m_CurrentSheet; ///< which sheet we are presently working on.
|
||||
wxString m_DefaultSchematicFileName;
|
||||
wxString m_SelectedNetName;
|
||||
|
||||
PARAM_CFG_ARRAY m_projectFileParams;
|
||||
PARAM_CFG_ARRAY m_configSettings;
|
||||
ERC_SETTINGS m_ercSettings;
|
||||
wxPageSetupDialogData m_pageSetupData;
|
||||
wxFindReplaceData* m_findReplaceData;
|
||||
wxString* m_findReplaceStatus;
|
||||
|
@ -166,6 +186,18 @@ private:
|
|||
/// Use netcodes (net number) as net names when generating spice net lists.
|
||||
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 wxSize m_lastSheetPinTextSize; ///< Last sheet pin text size.
|
||||
static wxPoint m_lastSheetPinPosition; ///< Last sheet pin position.
|
||||
|
@ -251,6 +283,13 @@ public:
|
|||
void Process_Config( wxCommandEvent& event );
|
||||
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;
|
||||
|
||||
/**
|
||||
|
@ -277,6 +316,10 @@ public:
|
|||
*/
|
||||
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.
|
||||
*
|
||||
|
@ -447,10 +490,12 @@ public:
|
|||
* @param aPoint Point at which to break the segment
|
||||
* @param aAppend Add the changes to the previous undo state
|
||||
* @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.
|
||||
*/
|
||||
bool BreakSegment( SCH_LINE* aSegment, const wxPoint& aPoint, bool aAppend = false,
|
||||
SCH_LINE** aNewSegment = NULL );
|
||||
bool BreakSegment( SCH_LINE* aSegment, const wxPoint& aPoint,
|
||||
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
|
||||
|
@ -458,18 +503,22 @@ public:
|
|||
*
|
||||
* @param aPoint Test this point for an intersection.
|
||||
* @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.
|
||||
*/
|
||||
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
|
||||
* buses and breaks any intersections into multiple segments.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
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.
|
||||
|
@ -795,6 +844,27 @@ public:
|
|||
*/
|
||||
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:
|
||||
|
||||
/**
|
||||
|
@ -835,6 +905,11 @@ private:
|
|||
*/
|
||||
void OnOrient( wxCommandEvent& aEvent );
|
||||
|
||||
/**
|
||||
* Handles the keyboard hotkey for unfolding a bus
|
||||
*/
|
||||
void OnUnfoldBusHotkey( wxCommandEvent& event );
|
||||
|
||||
void OnExit( wxCommandEvent& event );
|
||||
void OnAnnotate( wxCommandEvent& event );
|
||||
void OnErc( wxCommandEvent& event );
|
||||
|
@ -843,6 +918,7 @@ private:
|
|||
void OnSimulate( wxCommandEvent& event );
|
||||
void OnCreateBillOfMaterials( wxCommandEvent& event );
|
||||
void OnLaunchBomManager( wxCommandEvent& event );
|
||||
void OnLaunchBusManager( wxCommandEvent& event );
|
||||
void OnFindItems( wxCommandEvent& event );
|
||||
void OnFindDialogClose( wxFindDialogEvent& event );
|
||||
void OnFindDrcMarker( wxFindDialogEvent& event );
|
||||
|
@ -952,9 +1028,10 @@ private:
|
|||
* deleting identical objects superimposed on top of each other.
|
||||
*
|
||||
* @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.
|
||||
*/
|
||||
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,
|
||||
|
@ -1475,6 +1552,11 @@ public:
|
|||
|
||||
wxString GetNetListerCommand() const { return m_netListerCommand; }
|
||||
|
||||
/**
|
||||
* Generates the connection data for the entire schematic hierarchy.
|
||||
*/
|
||||
void RecalculateConnections();
|
||||
|
||||
/**
|
||||
* Updates netlist and sends it to pcbnew.
|
||||
* @param aUpdateOptions is a string defining update options:
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <trace_helpers.h>
|
||||
#include <sch_item_struct.h>
|
||||
#include <sch_screen.h>
|
||||
#include <sch_sheet_path.h>
|
||||
#include <sch_draw_panel.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 )
|
||||
{
|
||||
wxFAIL_MSG( wxT( "SwapData() method not implemented for class " ) + GetClass() );
|
||||
|
|
|
@ -30,12 +30,16 @@
|
|||
#ifndef SCH_ITEM_STRUCT_H
|
||||
#define SCH_ITEM_STRUCT_H
|
||||
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include <base_screen.h>
|
||||
#include <general.h>
|
||||
#include <sch_connection.h>
|
||||
#include <sch_sheet_path.h>
|
||||
|
||||
class SCH_ITEM;
|
||||
class SCH_SHEET_PATH;
|
||||
//class SCH_SHEET_PATH;
|
||||
class LINE_READER;
|
||||
class SCH_EDIT_FRAME;
|
||||
class wxFindReplaceData;
|
||||
|
@ -69,7 +73,7 @@ class DANGLING_END_ITEM
|
|||
{
|
||||
private:
|
||||
/// A pointer to the connectable object.
|
||||
const EDA_ITEM* m_item;
|
||||
EDA_ITEM* m_item;
|
||||
|
||||
/// The position of the connection point.
|
||||
wxPoint m_pos;
|
||||
|
@ -81,7 +85,7 @@ private:
|
|||
const EDA_ITEM* m_parent;
|
||||
|
||||
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_type = aType;
|
||||
|
@ -89,7 +93,7 @@ public:
|
|||
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 )
|
||||
{
|
||||
m_item = aItem;
|
||||
|
@ -99,7 +103,7 @@ public:
|
|||
}
|
||||
|
||||
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; }
|
||||
DANGLING_END_T GetType() const { return m_type; }
|
||||
};
|
||||
|
@ -114,12 +118,20 @@ public:
|
|||
*/
|
||||
class SCH_ITEM : public EDA_ITEM
|
||||
{
|
||||
friend class CONNECTION_GRAPH;
|
||||
|
||||
protected:
|
||||
SCH_LAYER_ID m_Layer;
|
||||
EDA_ITEMS m_connections; ///< List of items connected to this item.
|
||||
wxPoint m_storedPos; ///< a temporary variable used in some move commands
|
||||
///> 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:
|
||||
SCH_ITEM( EDA_ITEM* aParent, KICAD_T aType );
|
||||
|
||||
|
@ -312,6 +324,33 @@ public:
|
|||
*/
|
||||
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
|
||||
{
|
||||
return HitTest( aPosition, 0 );
|
||||
|
|
|
@ -96,10 +96,14 @@ void SCH_JUNCTION::Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffs
|
|||
{
|
||||
COLOR4D color;
|
||||
|
||||
auto conn = Connection( *g_CurrentSheet );
|
||||
|
||||
if( aColor != COLOR4D::UNSPECIFIED )
|
||||
color = aColor;
|
||||
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 );
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include <ctype.h>
|
||||
#include <algorithm>
|
||||
#include <boost/algorithm/string/join.hpp>
|
||||
|
||||
#include <wx/mstream.h>
|
||||
#include <wx/filename.h>
|
||||
|
@ -45,6 +46,8 @@
|
|||
#include <sch_no_connect.h>
|
||||
#include <sch_text.h>
|
||||
#include <sch_sheet.h>
|
||||
#include <sch_bitmap.h>
|
||||
#include <bus_alias.h>
|
||||
#include <sch_legacy_plugin.h>
|
||||
#include <template_fieldnames.h>
|
||||
#include <sch_screen.h>
|
||||
|
@ -759,6 +762,8 @@ void SCH_LEGACY_PLUGIN::loadFile( const wxString& aFileName, SCH_SCREEN* aScreen
|
|||
aScreen->Append( loadBusEntry( reader ) );
|
||||
else if( strCompare( "Text", line ) )
|
||||
aScreen->Append( loadText( reader ) );
|
||||
else if( strCompare( "BusAlias", line ) )
|
||||
aScreen->AddBusAlias( loadBusAlias( reader, aScreen ) );
|
||||
else if( strCompare( "$EndSCHEMATC", line ) )
|
||||
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,
|
||||
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, "$EndDescr\n" );
|
||||
|
||||
for( auto alias : aScreen->GetBusAliases() )
|
||||
{
|
||||
saveBusAlias( alias );
|
||||
}
|
||||
|
||||
for( SCH_ITEM* item = aScreen->GetDrawItems(); item; item = item->Next() )
|
||||
{
|
||||
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
|
||||
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
#include <sch_io_mgr.h>
|
||||
#include <stack>
|
||||
|
||||
|
@ -44,6 +45,7 @@ class SCH_LEGACY_PLUGIN_CACHE;
|
|||
class LIB_PART;
|
||||
class PART_LIB;
|
||||
class LIB_ALIAS;
|
||||
class BUS_ALIAS;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -145,6 +147,7 @@ private:
|
|||
SCH_BUS_ENTRY_BASE* loadBusEntry( FILE_LINE_READER& aReader );
|
||||
SCH_TEXT* loadText( 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 saveField( SCH_FIELD* aField );
|
||||
|
@ -155,6 +158,7 @@ private:
|
|||
void saveBusEntry( SCH_BUS_ENTRY_BASE* aBusEntry );
|
||||
void saveLine( SCH_LINE* aLine );
|
||||
void saveText( SCH_TEXT* aText );
|
||||
void saveBusAlias( std::shared_ptr< BUS_ALIAS > aAlias );
|
||||
|
||||
void cacheLib( const wxString& aLibraryFileName );
|
||||
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 )
|
||||
{
|
||||
if( aLine == NULL )
|
||||
|
|
|
@ -195,6 +195,8 @@ public:
|
|||
|
||||
void SwapData( SCH_ITEM* aItem ) override;
|
||||
|
||||
void GetMsgPanelInfo( EDA_UNITS_T aUnits, std::vector< MSG_PANEL_ITEM >& aList ) override;
|
||||
|
||||
#if defined(DEBUG)
|
||||
void Show( int nestLevel, std::ostream& os ) const override;
|
||||
#endif
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include <sch_no_connect.h>
|
||||
#include <sch_bus_entry.h>
|
||||
#include <sch_bitmap.h>
|
||||
#include <sch_sheet.h>
|
||||
#include <draw_graphic_text.h>
|
||||
#include <geometry/geometry_utils.h>
|
||||
#include <lib_edit_frame.h>
|
||||
|
@ -54,6 +55,7 @@
|
|||
#include <view/view.h>
|
||||
#include <gal/graphics_abstraction_layer.h>
|
||||
#include <colors_design_settings.h>
|
||||
#include <connection_graph.h>
|
||||
#include <geometry/shape_line_chain.h>
|
||||
#include <bezier_curves.h>
|
||||
|
||||
|
@ -167,6 +169,26 @@ bool SCH_PAINTER::Draw( const VIEW_ITEM *aItem, int aLayer )
|
|||
|
||||
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() )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
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 ) )
|
||||
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;
|
||||
}
|
||||
|
||||
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 ) )
|
||||
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 );
|
||||
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 ) )
|
||||
color = m_schSettings.GetLayerColor( LAYER_BRIGHTENED );
|
||||
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2018 CERN
|
||||
* @author Jon Evans <jon@craftyjon.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <lib_pin.h>
|
||||
#include <sch_component.h>
|
||||
#include <sch_pin_connection.h>
|
||||
#include <sch_sheet_path.h>
|
||||
|
||||
|
||||
SCH_PIN_CONNECTION::SCH_PIN_CONNECTION( EDA_ITEM* aParent ) :
|
||||
SCH_ITEM( aParent, SCH_PIN_CONNECTION_T )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
wxString SCH_PIN_CONNECTION::GetSelectMenuText( EDA_UNITS_T aUnits ) const
|
||||
{
|
||||
wxString tmp;
|
||||
|
||||
#ifdef DEBUG
|
||||
tmp.Printf( _( "SCH_PIN_CONNECTION for %s %s" ),
|
||||
GetChars( m_comp->GetSelectMenuText( aUnits ) ),
|
||||
GetChars( m_pin->GetSelectMenuText( aUnits ) ) );
|
||||
#else
|
||||
tmp.Printf( _( "%s %s" ),
|
||||
GetChars( m_comp->GetSelectMenuText( aUnits ) ),
|
||||
GetChars( m_pin->GetSelectMenuText( aUnits ) ) );
|
||||
#endif
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
wxString SCH_PIN_CONNECTION::GetDefaultNetName( const SCH_SHEET_PATH aPath )
|
||||
{
|
||||
if( m_pin->IsPowerConnection() )
|
||||
return m_pin->GetName();
|
||||
|
||||
wxString name;
|
||||
|
||||
try
|
||||
{
|
||||
name = m_net_name_map.at( aPath );
|
||||
}
|
||||
catch( const std::out_of_range& oor )
|
||||
{
|
||||
name = wxT( "Net-(" );
|
||||
|
||||
name << m_comp->GetRef( &aPath );
|
||||
|
||||
// TODO(JE) do we need adoptTimestamp?
|
||||
if( /* adoptTimestamp && */ name.Last() == '?' )
|
||||
name << m_comp->GetTimeStamp();
|
||||
|
||||
name << _( "-Pad" ) << m_pin->GetNumber() << _( ")" );
|
||||
|
||||
m_net_name_map[ aPath ] = name;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
wxPoint SCH_PIN_CONNECTION::GetPosition() const
|
||||
{
|
||||
auto pos = m_comp->GetPosition();
|
||||
auto transform = m_comp->GetTransform();
|
||||
|
||||
return pos + transform.TransformCoordinate( m_pin->GetPosition() );
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2018 CERN
|
||||
* @author Jon Evans <jon@craftyjon.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _SCH_PIN_CONNECTION_H
|
||||
#define _SCH_PIN_CONNECTION_H
|
||||
|
||||
#include <sch_item_struct.h>
|
||||
#include <sch_connection.h>
|
||||
#include <sch_sheet_path.h>
|
||||
#include <lib_pin.h>
|
||||
|
||||
class SCH_COMPONENT;
|
||||
|
||||
/**
|
||||
* Container to describe the net connectivity of a specific pin on a component.
|
||||
*/
|
||||
class SCH_PIN_CONNECTION : public SCH_ITEM
|
||||
{
|
||||
public:
|
||||
SCH_PIN_CONNECTION( EDA_ITEM* aParent = nullptr );
|
||||
|
||||
wxString GetClass() const override
|
||||
{
|
||||
return wxT( "SCH_PIN_CONNECTION" );
|
||||
}
|
||||
|
||||
wxString GetDefaultNetName( const SCH_SHEET_PATH aPath );
|
||||
|
||||
wxString GetSelectMenuText( EDA_UNITS_T aUnits ) const override;
|
||||
|
||||
void Draw( EDA_DRAW_PANEL* aPanel, wxDC* aDC, const wxPoint& aOffset,
|
||||
GR_DRAWMODE aDrawMode, COLOR4D aColor = COLOR4D::UNSPECIFIED ) override
|
||||
{
|
||||
}
|
||||
|
||||
void Move( const wxPoint& aMoveVector ) override {}
|
||||
|
||||
void MirrorY( int aYaxis_position ) override {}
|
||||
|
||||
void MirrorX( int aXaxis_position ) override {}
|
||||
|
||||
void Rotate( wxPoint aPosition ) override {}
|
||||
|
||||
wxPoint GetPosition() const override;
|
||||
|
||||
void SetPosition( const wxPoint& aPosition ) override {}
|
||||
|
||||
#if defined(DEBUG)
|
||||
void Show( int nestLevel, std::ostream& os ) const override {}
|
||||
#endif
|
||||
|
||||
LIB_PIN* m_pin;
|
||||
|
||||
SCH_COMPONENT* m_comp;
|
||||
|
||||
/// The name that this pin connection will drive onto a net
|
||||
std::map<const SCH_SHEET_PATH, wxString> m_net_name_map;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -38,6 +38,7 @@
|
|||
#include <kiway.h>
|
||||
#include <sch_draw_panel.h>
|
||||
#include <sch_item_struct.h>
|
||||
#include <draw_graphic_text.h>
|
||||
#include <sch_edit_frame.h>
|
||||
#include <plotter.h>
|
||||
|
||||
|
@ -56,6 +57,11 @@
|
|||
#include <symbol_lib_table.h>
|
||||
#include <tool/common_tools.h>
|
||||
|
||||
// TODO(JE) Debugging only
|
||||
#include <profile.h>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#define EESCHEMA_FILE_STAMP "EESchema"
|
||||
|
||||
/* Default zoom values. Limited to these values to keep a decent size
|
||||
|
@ -198,6 +204,9 @@ void SCH_SCREEN::DeleteItem( SCH_ITEM* aItem )
|
|||
}
|
||||
else
|
||||
{
|
||||
if( GetCurItem() == aItem )
|
||||
SetCurItem( nullptr );
|
||||
|
||||
m_drawList.Remove( aItem );
|
||||
delete aItem;
|
||||
}
|
||||
|
@ -411,6 +420,7 @@ bool SCH_SCREEN::IsTerminalPoint( const wxPoint& aPosition, int aLayer )
|
|||
|
||||
SCH_SHEET_PIN* label;
|
||||
SCH_TEXT* text;
|
||||
SCH_CONNECTION conn;
|
||||
|
||||
switch( aLayer )
|
||||
{
|
||||
|
@ -421,12 +431,12 @@ bool SCH_SCREEN::IsTerminalPoint( const wxPoint& aPosition, int aLayer )
|
|||
|
||||
label = GetSheetLabel( aPosition );
|
||||
|
||||
if( label && IsBusLabel( label->GetText() ) && label->IsConnected( aPosition ) )
|
||||
if( label && conn.IsBusLabel( label->GetText() ) && label->IsConnected( aPosition ) )
|
||||
return true;
|
||||
|
||||
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) )
|
||||
return true;
|
||||
|
||||
|
@ -457,12 +467,12 @@ bool SCH_SCREEN::IsTerminalPoint( const wxPoint& aPosition, int aLayer )
|
|||
|
||||
text = GetLabel( aPosition );
|
||||
|
||||
if( text && text->IsConnected( aPosition ) && !IsBusLabel( text->GetText() ) )
|
||||
if( text && text->IsConnected( aPosition ) && !conn.IsBusLabel( text->GetText() ) )
|
||||
return true;
|
||||
|
||||
label = GetSheetLabel( aPosition );
|
||||
|
||||
if( label && label->IsConnected( aPosition ) && !IsBusLabel( label->GetText() ) )
|
||||
if( label && label->IsConnected( aPosition ) && !conn.IsBusLabel( label->GetText() ) )
|
||||
return true;
|
||||
|
||||
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()
|
||||
// if( panel->GetClipBox().Intersects( item->GetBoundingBox() ) )
|
||||
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 )
|
||||
|
@ -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)
|
||||
void SCH_SCREEN::Show( int nestLevel, std::ostream& os ) const
|
||||
{
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
#ifndef SCREEN_H
|
||||
#define SCREEN_H
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
#include <macros.h>
|
||||
#include <dlist.h>
|
||||
#include <sch_item_struct.h>
|
||||
|
@ -39,12 +41,14 @@
|
|||
#include <page_info.h>
|
||||
#include <kiway_player.h>
|
||||
#include <sch_marker.h>
|
||||
#include <bus_alias.h>
|
||||
|
||||
#include <../eeschema/general.h>
|
||||
|
||||
|
||||
class LIB_PIN;
|
||||
class SCH_COMPONENT;
|
||||
class SCH_SHEET_LIST;
|
||||
class SCH_SHEET_PATH;
|
||||
class SCH_SHEET_PIN;
|
||||
class SCH_LINE;
|
||||
|
@ -95,6 +99,9 @@ private:
|
|||
int m_modification_sync; ///< inequality with PART_LIBS::GetModificationHash()
|
||||
///< 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.
|
||||
* <p>
|
||||
|
@ -509,6 +516,38 @@ public:
|
|||
*/
|
||||
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)
|
||||
void Show( int nestLevel, std::ostream& os ) const override;
|
||||
#endif
|
||||
|
|
|
@ -926,7 +926,8 @@ void SCH_SHEET::GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
|
|||
item->m_Start = item->m_End = m_pins[i].GetPosition();
|
||||
aNetListItems.push_back( item );
|
||||
|
||||
if( IsBusLabel( m_pins[i].GetText() ) )
|
||||
SCH_CONNECTION conn;
|
||||
if( conn.IsBusLabel( m_pins[i].GetText() ) )
|
||||
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
|
||||
|
|
|
@ -38,13 +38,29 @@
|
|||
#include <class_library.h>
|
||||
#include <sch_sheet_path.h>
|
||||
#include <sch_component.h>
|
||||
#include <sch_sheet.h>
|
||||
#include <template_fieldnames.h>
|
||||
|
||||
#include <dialogs/dialog_schematic_find.h>
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
#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()
|
||||
{
|
||||
m_pageNumber = 0;
|
||||
|
|
|
@ -78,9 +78,9 @@
|
|||
* (usable in flat and simple hierarchies).
|
||||
*/
|
||||
|
||||
#include "sch_sheet.h" // SCH_SHEETS
|
||||
|
||||
class wxFindReplaceData;
|
||||
class SCH_SHEET;
|
||||
class SCH_SCREEN;
|
||||
class SCH_MARKER;
|
||||
class SCH_ITEM;
|
||||
|
@ -89,6 +89,8 @@ class SCH_REFERENCE_LIST;
|
|||
|
||||
#define SHEET_NOT_FOUND -1
|
||||
|
||||
typedef std::vector< SCH_SHEET* > SCH_SHEETS; // no ownership over contained SCH_SHEETs
|
||||
|
||||
|
||||
/**
|
||||
* 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 SCH_SHEET_PATHS::iterator SCH_SHEET_PATHS_ITER;
|
||||
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;
|
||||
SetTextPos( pos );
|
||||
m_isDangling = false;
|
||||
m_connectionType = CONNECTION_NONE;
|
||||
m_spin_style = 0;
|
||||
|
||||
SetMultilineAllowed( true );
|
||||
|
@ -361,6 +362,7 @@ bool SCH_TEXT::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList )
|
|||
|
||||
bool previousState = m_isDangling;
|
||||
m_isDangling = true;
|
||||
m_connectionType = CONNECTION_NONE;
|
||||
|
||||
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 NO_CONNECT_END:
|
||||
if( GetTextPos() == item.GetPosition() )
|
||||
{
|
||||
m_isDangling = false;
|
||||
|
||||
if( item.GetType() != PIN_END )
|
||||
m_connected_items.insert( static_cast< SCH_ITEM* >( item.GetItem() ) );
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case WIRE_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
|
||||
// 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];
|
||||
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;
|
||||
|
||||
|
@ -403,6 +426,9 @@ bool SCH_TEXT::UpdateDanglingState( std::vector<DANGLING_END_ITEM>& aItemList )
|
|||
break;
|
||||
}
|
||||
|
||||
if( m_isDangling )
|
||||
m_connectionType = CONNECTION_NONE;
|
||||
|
||||
return previousState != m_isDangling;
|
||||
}
|
||||
|
||||
|
@ -492,9 +518,11 @@ void SCH_TEXT::GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
|
|||
aNetListItems.push_back( item );
|
||||
|
||||
// If a bus connects to label
|
||||
if( IsBusLabel( m_Text ) )
|
||||
if( Connection( *aSheetPath )->IsBusLabel( m_Text ) )
|
||||
{
|
||||
item->ConvertBusToNetListItems( aNetListItems );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool SCH_TEXT::HitTest( const wxPoint& aPosition, int aAccuracy ) const
|
||||
|
@ -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)
|
||||
msg = MessageTextFromValue( aUnits, GetTextWidth(), true );
|
||||
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)
|
||||
|
@ -1066,10 +1106,14 @@ void SCH_HIERLABEL::Draw( EDA_DRAW_PANEL* panel,
|
|||
|
||||
linewidth = Clamp_Text_PenSize( linewidth, GetTextSize(), IsBold() );
|
||||
|
||||
auto conn = Connection( *g_CurrentSheet );
|
||||
|
||||
if( Color != COLOR4D::UNSPECIFIED )
|
||||
color = Color;
|
||||
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 );
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#include <macros.h>
|
||||
#include <eda_text.h>
|
||||
#include <sch_item_struct.h>
|
||||
#include <sch_connection.h> // for CONNECTION_TYPE
|
||||
|
||||
|
||||
class LINE_READER;
|
||||
|
@ -64,6 +65,8 @@ protected:
|
|||
/// supports connections.
|
||||
bool m_isDangling;
|
||||
|
||||
CONNECTION_TYPE m_connectionType;
|
||||
|
||||
/**
|
||||
* The orientation of text and any associated drawing elements of derived objects.
|
||||
* 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) )
|
||||
{
|
||||
m_CurrentSheet->push_back( (SCH_SHEET*) item );
|
||||
g_CurrentSheet->push_back( (SCH_SHEET*) item );
|
||||
DisplayCurrentSheet();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -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 )
|
||||
{
|
||||
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
|
||||
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
|
||||
{ // we must clear "new" components annotation
|
||||
SCH_SCREENS screensList( g_RootSheet );
|
||||
// We clear annotation of new sheet paths here:
|
||||
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
|
||||
// their annotation cleared, becuase they are new:
|
||||
((SCH_SHEET*) item)->GetScreen()->ClearAnnotation( m_CurrentSheet );
|
||||
((SCH_SHEET*) item)->GetScreen()->ClearAnnotation( g_CurrentSheet );
|
||||
}
|
||||
|
||||
if( doRefresh )
|
||||
|
@ -1331,3 +1406,77 @@ void SCH_EDIT_FRAME::OnOrient( wxCommandEvent& aEvent )
|
|||
if( item->GetFlags() == 0 )
|
||||
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_SHEET_PIN_T,
|
||||
SCH_SHEET_T,
|
||||
SCH_PIN_CONNECTION_T,
|
||||
|
||||
// Be prudent with these 3 types:
|
||||
// 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) 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
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -32,6 +33,7 @@
|
|||
|
||||
#include <wx/valtext.h>
|
||||
#include <wx/grid.h>
|
||||
#include <wx/regex.h>
|
||||
|
||||
/**
|
||||
* Class GRID_CELL_TEXT_EDITOR
|
||||
|
@ -112,6 +114,66 @@ public:
|
|||
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
|
||||
{
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue