Commit daeeee56 authored by jean-pierre charras's avatar jean-pierre charras

Eeschema: Rework on netlist generator: code clenenig and enhancement.

Fix an annoying issue about not named nets:
now, these nets are named from the component references and pin names which are connected.
therefore, unless the net or the footprint references are modified, the net name is not modified between 2 netlist calculations.
parent 4afae651
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......@@ -32,8 +32,8 @@
#include <macros.h>
#include <wxEeschemaStruct.h>
#include <general.h>
#include <sch_component.h>
#include <class_netlist_object.h>
#include <wx/regex.h>
......@@ -175,7 +175,7 @@ NETLIST_OBJECT::NETLIST_OBJECT()
m_Flag = 0; /* flag used in calculations */
m_ElectricalType = 0; /* Has meaning only for Pins and hierarchical pins: electrical
* type */
m_NetCode = 0; /* net code for all items except BUS labels because a BUS
m_netCode = 0; /* net code for all items except BUS labels because a BUS
* label has as many net codes as bus members
*/
m_BusNetCode = 0; /* Used for BUS connections */
......@@ -184,7 +184,7 @@ NETLIST_OBJECT::NETLIST_OBJECT()
*/
m_FlagOfConnection = UNCONNECTED;
m_PinNum = 0; /* pin number ( 1 long = 4 bytes -> 4 ascii codes) */
m_NetNameCandidate = NULL; /* a pointer to a NETLIST_OBJECT type label connected to this
m_netNameCandidate = NULL; /* a pointer to a NETLIST_OBJECT type label connected to this
* object used to give a name to the net
*/
}
......@@ -201,6 +201,15 @@ NETLIST_OBJECT::~NETLIST_OBJECT()
{
}
// return true if the object is a label of any type
bool NETLIST_OBJECT::IsLabelType() const
{
return m_Type == NET_LABEL
|| m_Type == NET_GLOBLABEL || m_Type == NET_HIERLABEL
|| m_Type == NET_BUSLABELMEMBER || m_Type == NET_GLOBBUSLABELMEMBER
|| m_Type == NET_HIERBUSLABELMEMBER
|| m_Type == NET_PINLABEL;
}
bool NETLIST_OBJECT::IsLabelConnected( NETLIST_OBJECT* aNetItem )
{
......@@ -299,3 +308,80 @@ void NETLIST_OBJECT::ConvertBusToNetListItems( NETLIST_OBJECT_LIST& aNetListItem
aNetListItems.push_back( item );
}
}
/*
* return the net name of the item
*/
wxString NETLIST_OBJECT::GetNetName() const
{
if( m_netNameCandidate == NULL )
return wxEmptyString;
wxString netName;
if( m_netNameCandidate->m_Type == NET_PIN )
return GetShortNetName();
if( !m_netNameCandidate->IsLabelGlobal() )
{
// usual net name, prefix it by the sheet path
netName = m_netNameCandidate->m_SheetList.PathHumanReadable();
}
netName += m_netNameCandidate->m_Label;
return netName;
}
/**
* return the short net name of the item i.e. the net name
* from the "best" label without any prefix.
* 2 different nets can have the same short name
*/
wxString NETLIST_OBJECT::GetShortNetName() const
{
if( m_netNameCandidate == NULL )
return wxEmptyString;
wxString netName;
if( m_netNameCandidate->m_Type == NET_PIN )
{
if( m_Link )
{
netName = wxT("Net-<");
netName << ( (SCH_COMPONENT*) m_Link )->GetRef( &m_SheetList );
netName << wxT("-Pad") << LIB_PIN::ReturnPinStringNum( m_PinNum );
netName << wxT(">");
}
}
else
netName = m_netNameCandidate->m_Label;
return netName;
}
/**
* Set m_netNameCandidate to a connected item which will
* be used to calcule the net name of the item
* Obviously the candidate can be only a label
* when there is no label on the net a pad which will
* used to build a net name (something like Cmp<REF>_Pad<PAD_NAME>
* @param aCandidate = the connected item candidate
*/
void NETLIST_OBJECT::SetNetNameCandidate( NETLIST_OBJECT* aCandidate )
{
switch( aCandidate->m_Type )
{
case NET_HIERLABEL:
case NET_LABEL:
case NET_PINLABEL:
case NET_GLOBLABEL:
case NET_PIN:
m_netNameCandidate = aCandidate;
break;
default:
break;
}
}
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......@@ -33,15 +33,9 @@
#include <sch_sheet_path.h>
#include <lib_pin.h> // LIB_PIN::ReturnPinStringNum( m_PinNum )
class NETLIST_OBJECT;
// Buffer to build the list of items used in netlist and erc calculations
typedef std::vector <NETLIST_OBJECT*> NETLIST_OBJECT_LIST;
class NETLIST_OBJECT_LIST;
/* Type of Net objects (wires, labels, pins...) */
......@@ -89,53 +83,46 @@ enum NET_CONNECTION_T {
};
/**
* Function IsBusLabel
* 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.
*/
extern bool IsBusLabel( const wxString& aLabel );
class NETLIST_OBJECT
{
public:
NETLIST_ITEM_T m_Type; /* Type of item (see NETLIST_ITEM_T enum) */
EDA_ITEM* m_Comp; /* Pointer on the library item that
EDA_ITEM* m_Comp; /* Pointer to the library item that
* created this net object (the parent)
*/
SCH_ITEM* m_Link; /* For SCH_SHEET_PIN:
* Pointer to the hierarchy sheet that
* contains this SCH_SHEET_PIN
* For Pins: pointer to the component
* that contains this pin
* Pointer to the hierarchy sheet that
* contains this SCH_SHEET_PIN
* For Pins: pointer to the schematic component
* that contains this pin
*/
int m_Flag; /* flag used in calculations */
SCH_SHEET_PATH m_SheetList;
int m_ElectricalType; /* Has meaning only for Pins and
* hierarchical pins: electrical type */
private:
int m_NetCode; /* net code for all items except BUS
* labels because a BUS label has
* as many net codes as bus members
*/
public:
int m_BusNetCode; /* Used for BUS connections */
int m_Member; /* for labels type NET_BUSLABELMEMBER ( bus member
* created from the BUS label ) member number.
*/
NET_CONNECTION_T m_FlagOfConnection;
SCH_SHEET_PATH m_SheetListInclude; /* sheet that the hierarchical label connects to.*/
long m_PinNum; /* pin number ( 1 long = 4 bytes -> 4 ascii codes) */
wxString m_Label; /* Label text. */
SCH_SHEET_PATH m_SheetListInclude; // sheet path which contains the hierarchical label
long m_PinNum; // pin number ( 1 long = 4 bytes -> 4 ascii codes)
wxString m_Label; // Label text (for labels) or Pin name (for pins)
wxPoint m_Start; // Position of object or for segments: starting point
wxPoint m_End; // For segments (wire and buses): ending point
NETLIST_OBJECT* m_NetNameCandidate; /* a pointer to a label connected to the net,
private:
int m_netCode; /* net code for all items except BUS
* labels because a BUS label has
* as many net codes as bus members
*/
NETLIST_OBJECT* m_netNameCandidate; /* a pointer to a label connected to the net,
* that can be used to give a name to the net
* NULL if no usable label
* or a pin if there is no label in net
* When no label, the pin is used to build
* default net name.
*/
public:
#if defined(DEBUG)
void Show( std::ostream& out, int ndx ) const; // override
......@@ -146,8 +133,19 @@ public:
~NETLIST_OBJECT();
void SetNet( int aNetCode ) { m_NetCode = aNetCode; }
int GetNet() const { return m_NetCode; }
// Accessors:
void SetNet( int aNetCode ) { m_netCode = aNetCode; }
int GetNet() const { return m_netCode; }
/**
* Set m_netNameCandidate to a connected item which will
* be used to calcule the net name of the item
* Obviously the candidate can be only a label
* when there is no label on the net a pad which will
* used to build a net name (something like Cmp<REF>_Pad<PAD_NAME>
* @param aCandidate = the connected item candidate
*/
void SetNetNameCandidate( NETLIST_OBJECT* aCandidate );
/**
* Function GetPinNum
......@@ -171,6 +169,38 @@ public:
*/
bool IsLabelConnected( NETLIST_OBJECT* aNetItem );
/**
* Function IsLabelGlobal
* @return true if the object is a global label
* (i.e. an real global label or a pin label coming
* from a power pin invisible
*/
bool IsLabelGlobal() const
{
return ( m_Type == NET_PINLABEL ) || ( m_Type == NET_GLOBLABEL );
}
/**
* Function IsLabelType
* @return true if the object is a label of any type
*/
bool IsLabelType() const;
/**
* Function GetNetName
* @return the full net name of the item, i.e. the net name
* from the "best" label, prefixed by the sheet path
*/
wxString GetNetName() const;
/**
* Function GetShortNetName
* @return the short net name of the item i.e. the net name
* from the "best" label without any prefix.
* 2 different nets can have the same short name
*/
wxString GetShortNetName() const;
/**
* Function ConvertBusToNetListItems
* breaks the text of a bus label type net list object into as many members as
......@@ -184,4 +214,156 @@ public:
};
/**
* NETLIST_OBJECT_LIST is a class to handle the list of connected items
* in a full shematic hierarchy for netlist and erc calculations
*/
class NETLIST_OBJECT_LIST: public std::vector <NETLIST_OBJECT*>
{
bool m_isOwner; // = true if the objects in list are owned my me, and therefore
// the memory should be freed by the destructor and the list cleared
public:
/**
* Constructor.
* NETLIST_OBJECT_LIST handle a list of connected items.
* the instance can be owner of items or not.
* If it is the owner, the items are freeed by the destructor
* @param aIsOwner true if the instance is the owner of item list
* (default = false)
*/
NETLIST_OBJECT_LIST( bool aIsOwner = false ) { m_isOwner = aIsOwner; }
~NETLIST_OBJECT_LIST();
void SetOwner( bool aIsOwner ) { m_isOwner = aIsOwner; }
/**
* Function BuildNetListInfo
* the master function of tgis class.
* Build the list of connected objects (pins, labels ...) and
* all info to generate netlists or run ERC diags
* @param aSheets = the flattened sheet list
* @return true if OK, false is not item found
*/
bool BuildNetListInfo( SCH_SHEET_LIST& aSheets );
/*
* Acces to an item in list
*/
NETLIST_OBJECT* GetItem( unsigned aIdx )
{
return *( this->begin() + aIdx );
}
/*
* Delete all objects in list and clear list
* (free memory used to store info about NETLIST_OBJECT items)
*/
void ClearList();
/*
* Sorts the list of connected items by net code
*/
void SortListbyNetcode();
/*
* Sorts the list of connected items by sheet.
* This sorting is used when searching "physical" connection between items
* because obviously only items inside the same sheet can be connected
*/
void SortListbySheet();
/*
* Propagate net codes from a parent sheet to an include sheet,
* from a pin sheet connection
*/
void SheetLabelConnect( NETLIST_OBJECT* aSheetLabel );
void PointToPointConnect( NETLIST_OBJECT* aRef, bool aIsBus, int start );
/*
* Search connections betweena junction and segments
* Propagate the junction net code to objects connected by this junction.
* The junction must have a valid net code
* The list of objects is expected sorted by sheets.
* Search is done from index aIdxStart to the last element of list
*/
void SegmentToPointConnect( NETLIST_OBJECT* aJonction, bool aIsBus, int aIdxStart );
void ConnectBusLabels();
/*
* Set the m_FlagOfConnection member of items in list
* depending on the connection type:
* UNCONNECTED, PAD_CONNECT or NOCONNECT_SYMBOL_PRESENT
* The list is expected sorted by order of net code,
* i.e. items having the same net code are grouped
*/
void SetUnconnectedFlag();
/**
* Function FindBestNetNameForEachNet
* fill the .m_NetNameCandidate member of each item of aNetItemBuffer
* with a reference to the "best" NETLIST_OBJECT usable to give a name to the net
* If no suitable object found, .m_NetNameCandidate is filled with 0.
* The "best" NETLIST_OBJECT is a NETLIST_OBJECT that have the type label
* and by priority order:
* the label is global or local
* the label is in the first sheet in a hierarchy (the root sheet has the most priority)
* alphabetic order.
*/
void FindBestNetNameForEachNet();
#if defined(DEBUG)
void DumpNetTable()
{
for( unsigned idx = 0; idx < size(); ++idx )
{
GetItem( idx )->Show( std::cout, idx );
}
}
#endif
private:
/*
* Propagate aNewNetCode to items having an internal netcode aOldNetCode
* used to interconnect group of items already physically connected,
* when a new connection is found between aOldNetCode and aNewNetCode
*/
void propageNetCode( int aOldNetCode, int aNewNetCode, bool aIsBus );
/*
* This function merges the net codes of groups of objects already connected
* to labels (wires, bus, pins ... ) when 2 labels are equivalents
* (i.e. group objects connected by labels)
*/
void labelConnect( NETLIST_OBJECT* aLabelRef );
/* Comparison function to sort by increasing Netcode the list of connected items
*/
static bool sortItemsbyNetcode( const NETLIST_OBJECT* Objet1, const NETLIST_OBJECT* Objet2 )
{
return Objet1->GetNet() < Objet2->GetNet();
}
/* Comparison routine to sort items by Sheet Number
*/
static bool sortItemsBySheet( const NETLIST_OBJECT* Objet1, const NETLIST_OBJECT* Objet2 )
{
return Objet1->m_SheetList.Cmp( Objet2->m_SheetList ) < 0;
}
};
extern NETLIST_OBJECT_LIST g_NetObjectslist;
/**
* Function IsBusLabel
* 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.
*/
extern bool IsBusLabel( const wxString& aLabel );
#endif // _CLASS_NETLIST_OBJECT_H_
......@@ -37,8 +37,8 @@
#include <wxEeschemaStruct.h>
#include <invoke_sch_dialog.h>
#include <general.h>
#include <netlist.h>
#include <class_netlist_object.h>
#include <sch_marker.h>
#include <sch_sheet.h>
#include <lib_pin.h>
......
......@@ -33,8 +33,8 @@
#include <kicad_string.h>
#include <wxEeschemaStruct.h>
#include <general.h>
#include <netlist.h>
#include <class_netlist_object.h>
#include <lib_pin.h>
#include <protos.h>
#include <erc.h>
......
......@@ -35,12 +35,11 @@
#include <wxEeschemaStruct.h>
#include <appl_wxstruct.h>
#include <general.h>
#include <protos.h>
#include <eeschema_id.h>
#include <class_library.h>
#include <libeditframe.h>
#include <sch_sheet.h>
#include <sch_sheet_path.h>
#include <sch_component.h>
#include <wildcards_and_files_ext.h>
......
......@@ -5,26 +5,20 @@
#ifndef _GENERAL_H_
#define _GENERAL_H_
#include <wx/string.h>
#include <wx/gdicmn.h>
#include <colors.h> // for EDA_COLOR_T
#include <block_commande.h>
#include <class_netlist_object.h>
class SCH_SHEET;
class TRANSFORM;
class SCH_SHEET;
#define EESCHEMA_VERSION 2
#define SCHEMATIC_HEAD_STRING "Schematic File Version"
#define TXTMARGE 10 // Offset in mils for placement of labels and pin numbers
#define DEFAULT_TEXT_SIZE 50 // Default size for field texts
#define DANGLING_SYMBOL_SIZE 12
#define GR_DEFAULT_DRAWMODE GR_COPY
#define DANGLING_SYMBOL_SIZE 12
// this enum is for color management
typedef enum {
LAYER_WIRE,
......@@ -75,8 +69,6 @@ extern int g_RepeatDeltaLabel;
/* First and main (root) screen */
extern SCH_SHEET* g_RootSheet;
extern NETLIST_OBJECT_LIST g_NetObjectslist;
/**
* Default line thickness used to draw/plot items having a
* default thickness line value (i.e. = 0 ).
......
......@@ -32,6 +32,7 @@
#include <base_struct.h>
#include <transform.h>
#include <gr_basic.h>
#include <boost/ptr_container/ptr_vector.hpp>
......
......@@ -43,6 +43,7 @@
#include <libeditframe.h>
#include <class_library.h>
#include <lib_polyline.h>
#include <lib_pin.h>
#include <kicad_device_context.h>
#include <hotkeys.h>
......
......@@ -35,8 +35,8 @@
#include <appl_wxstruct.h>
#include <wxEeschemaStruct.h>
#include <general.h>
#include <netlist.h>
#include <class_netlist_object.h>
#include <class_library.h>
#include <lib_pin.h>
#include <sch_component.h>
......@@ -121,7 +121,8 @@ class NETLIST_EXPORT_TOOL
* <li> "/path/netname" for the usual nets
* </ul>
*/
static void sprintPinNetName( wxString* aResult, const wxString& aNetNameFormat, NETLIST_OBJECT* aPin );
static void sprintPinNetName( wxString& aResult, const wxString& aNetNameFormat,
NETLIST_OBJECT* aPin );
/**
* Function findNextComponentAndCreatePinList
......@@ -462,7 +463,7 @@ static bool sortPinsByNumber( LIB_PIN* aPin1, LIB_PIN* aPin2 )
}
void NETLIST_EXPORT_TOOL::sprintPinNetName( wxString* aResult,
void NETLIST_EXPORT_TOOL::sprintPinNetName( wxString& aResult,
const wxString& aNetNameFormat, NETLIST_OBJECT* aPin )
{
int netcode = aPin->GetNet();
......@@ -470,34 +471,14 @@ void NETLIST_EXPORT_TOOL::sprintPinNetName( wxString* aResult,
// Not wxString::Clear(), which would free memory. We want the worst
// case wxString memory to grow to avoid reallocation from within the
// caller's loop.
aResult->Empty();
aResult.Empty();
if( netcode != 0 && aPin->m_FlagOfConnection == PAD_CONNECT )
{
NETLIST_OBJECT* netref = aPin->m_NetNameCandidate;
if( netref )
*aResult = netref->m_Label;
aResult = aPin->GetNetName();
if( !aResult->IsEmpty() )
{
// prefix non global label names with the sheet path, to avoid name collisions
if( netref->m_Type != NET_PINLABEL && netref->m_Type != NET_GLOBLABEL )
{
wxString lnet = *aResult;
*aResult = netref->m_SheetList.PathHumanReadable();
// If sheet path is too long, use the time stamp name instead
if( aResult->Length() > 32 )
*aResult = netref->m_SheetList.Path();
*aResult += lnet;
}
}
else
{
aResult->Printf( aNetNameFormat.GetData(), netcode );
}
if( aResult.IsEmpty() ) // No net name: give a name from net code
aResult.Printf( aNetNameFormat.GetData(), netcode );
}
}
......@@ -880,22 +861,7 @@ XNODE* NETLIST_EXPORT_TOOL::makeGenericListOfNets()
if( ( netCode = nitem->GetNet() ) != lastNetCode )
{
sameNetcodeCount = 0; // item count for this net
netName.Empty();
// Find a label for this net, if it exists.
NETLIST_OBJECT* netref = nitem->m_NetNameCandidate;
if( netref )
{
if( netref->m_Type != NET_PINLABEL && netref->m_Type != NET_GLOBLABEL )
{
// usual net name, prefix it by the sheet path
netName = netref->m_SheetList.PathHumanReadable();
}
netName += netref->m_Label;
}
netName = nitem->GetNetName();
lastNetCode = netCode;
}
......@@ -1316,7 +1282,7 @@ bool NETLIST_EXPORT_TOOL::WriteNetListPspice( FILE* f, bool aUsePrefix )
if( !pin )
continue;
sprintPinNetName( &netName , wxT( "N-%.6d" ), pin );
sprintPinNetName( netName , wxT( "N-%.6d" ), pin );
if( netName.IsEmpty() )
netName = wxT( "?" );
......@@ -1470,7 +1436,7 @@ bool NETLIST_EXPORT_TOOL::WriteNetListPCBNEW( FILE* f, bool with_pcbnew )
if( !pin )
continue;
sprintPinNetName( &netName, wxT( "N-%.6d" ), pin );
sprintPinNetName( netName, wxT( "N-%.6d" ), pin );
if( netName.IsEmpty() )
netName = wxT( "?" );
......@@ -1682,49 +1648,33 @@ bool NETLIST_EXPORT_TOOL::writeGENERICListOfNets( FILE* f, NETLIST_OBJECT_LIST&
for( unsigned ii = 0; ii < aObjectsList.size(); ii++ )
{
SCH_COMPONENT* comp;
NETLIST_OBJECT* nitem = aObjectsList[ii];
// New net found, write net id;
if( ( netCode = aObjectsList[ii]->GetNet() ) != lastNetCode )
if( ( netCode = nitem->GetNet() ) != lastNetCode )
{
sameNetcodeCount = 0; // Items count for this net
netName.Empty();
// Find a label (if exists) for this net.
NETLIST_OBJECT* netref;
netref = aObjectsList[ii]->m_NetNameCandidate;
if( netref )
netName = netref->m_Label;
netName = nitem->GetNetName();
netcodeName.Printf( wxT( "Net %d " ), netCode );
netcodeName += wxT( "\"" );
if( !netName.IsEmpty() )
{
if( ( netref->m_Type != NET_PINLABEL )
&& ( netref->m_Type != NET_GLOBLABEL ) )
{
// usual net name, prefix it by the sheet path
netcodeName += netref->m_SheetList.PathHumanReadable();
}
netcodeName += netName;
}
netcodeName += wxT( "\"" );
netcodeName << wxT( "\"" ) << netName << wxT( "\"" );
// Add the netname without prefix, in cases we need only the
// "short" netname
netcodeName += wxT( " \"" ) + netName + wxT( "\"" );
netcodeName += wxT( " \"" ) + nitem->GetShortNetName() + wxT( "\"" );
lastNetCode = netCode;
}
if( aObjectsList[ii]->m_Type != NET_PIN )
if( nitem->m_Type != NET_PIN )
continue;
if( aObjectsList[ii]->m_Flag != 0 ) // Redundant pin, skip it
if( nitem->m_Flag != 0 ) // Redundant pin, skip it
continue;
comp = (SCH_COMPONENT*) aObjectsList[ii]->m_Link;
comp = (SCH_COMPONENT*) nitem->m_Link;
// Get the reference for the net name and the main parent component
ref = comp->GetRef( &aObjectsList[ii]->m_SheetList );
ref = comp->GetRef( &nitem->m_SheetList );
if( ref[0] == wxChar( '#' ) )
continue; // Pseudo component (Like Power symbol)
......@@ -1750,7 +1700,7 @@ bool NETLIST_EXPORT_TOOL::writeGENERICListOfNets( FILE* f, NETLIST_OBJECT_LIST&
if( sameNetcodeCount >= 2 )
ret |= fprintf( f, " %s %.4s\n", TO_UTF8( ref ),
(const char*) &aObjectsList[ii]->m_PinNum );
(const char*) &nitem->m_PinNum );
}
return ret >= 0;
......@@ -1841,48 +1791,37 @@ bool NETLIST_EXPORT_TOOL::writeListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST&
int print_ter = 0;
int NetCode, lastNetCode = -1;
SCH_COMPONENT* Cmp;
wxString NetName;
wxString netName;
for( ii = 0; ii < g_NetObjectslist.size(); ii++ )
{
NETLIST_OBJECT* nitem = aObjectsList[ii];
// Get the NetName of the current net :
if( ( NetCode = aObjectsList[ii]->GetNet() ) != lastNetCode )
if( ( NetCode = nitem->GetNet() ) != lastNetCode )
{
NetName.Empty();
NETLIST_OBJECT* netref;
netref = aObjectsList[ii]->m_NetNameCandidate;
if( netref )
NetName = netref->m_Label;
netName = nitem->GetNetName();
netcodeName = wxT( "\"" );
if( !NetName.IsEmpty() )
{
if( ( netref->m_Type != NET_PINLABEL )
&& ( netref->m_Type != NET_GLOBLABEL ) )
{
// usual net name, prefix it by the sheet path
netcodeName +=
netref->m_SheetList.PathHumanReadable();
}
netcodeName += NetName;
}
if( !netName.IsEmpty() )
netcodeName << netName;
else // this net has no name: create a default name $<net number>
netcodeName << wxT( "$" ) << NetCode;
netcodeName += wxT( "\"" );
lastNetCode = NetCode;
print_ter = 0;
}
if( aObjectsList[ii]->m_Type != NET_PIN )
if( nitem->m_Type != NET_PIN )
continue;
if( aObjectsList[ii]->m_Flag != 0 )
if( nitem->m_Flag != 0 )
continue;
Cmp = (SCH_COMPONENT*) aObjectsList[ii]->m_Link;
wxString refstr = Cmp->GetRef( &(aObjectsList[ii]->m_SheetList) );
Cmp = (SCH_COMPONENT*) nitem->m_Link;
wxString refstr = Cmp->GetRef( &nitem->m_SheetList );
if( refstr[0] == '#' )
continue; // Power supply symbols.
......@@ -1892,7 +1831,7 @@ bool NETLIST_EXPORT_TOOL::writeListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST&
{
char buf[5];
wxString str_pinnum;
strncpy( buf, (char*) &aObjectsList[ii]->m_PinNum, 4 );
strncpy( buf, (char*) &nitem->m_PinNum, 4 );
buf[4] = 0;
str_pinnum = FROM_UTF8( buf );
InitNetDescLine.Printf( wxT( "\n%s %s %.4s %s" ),
......@@ -1909,18 +1848,18 @@ bool NETLIST_EXPORT_TOOL::writeListOfNetsCADSTAR( FILE* f, NETLIST_OBJECT_LIST&
ret |= fprintf( f, "%s %s %.4s\n",
TO_UTF8( StartNetDesc ),
TO_UTF8( refstr ),
(char*) &aObjectsList[ii]->m_PinNum );
(char*) &nitem->m_PinNum );
print_ter++;
break;
default:
ret |= fprintf( f, " %s %.4s\n",
TO_UTF8( refstr ),
(char*) &aObjectsList[ii]->m_PinNum );
(char*) &nitem->m_PinNum );
break;
}
aObjectsList[ii]->m_Flag = 1;
nitem->m_Flag = 1;
}
return ret >= 0;
......
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2009 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 1992-2011 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 2013 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2013 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 1992-2013 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
......@@ -30,8 +30,8 @@
#include <fctsys.h>
#include <wxEeschemaStruct.h>
#include <general.h>
#include <netlist.h>
#include <class_netlist_object.h>
#include <protos.h>
#include <class_library.h>
#include <lib_pin.h>
......@@ -45,126 +45,113 @@
#include <boost/foreach.hpp>
const SCH_SHEET_PATH BOM_LABEL::emptySheetPath;
enum BUS_OR_WIRE
{
IS_WIRE = 0,
IS_BUS = 1
};
#define IS_WIRE false
#define IS_BUS true
// Buffer to build the list of items used in netlist and erc calculations
NETLIST_OBJECT_LIST g_NetObjectslist;
NETLIST_OBJECT_LIST g_NetObjectslist( true );
//#define NETLIST_DEBUG
static void PropageNetCode( int OldNetCode, int NewNetCode, BUS_OR_WIRE IsBus );
static void SheetLabelConnect( NETLIST_OBJECT* SheetLabel );
static void PointToPointConnect( NETLIST_OBJECT* Ref, BUS_OR_WIRE IsBus, int start );
static void SegmentToPointConnect( NETLIST_OBJECT* Jonction, BUS_OR_WIRE IsBus, int start );
static void LabelConnect( NETLIST_OBJECT* Label );
static void ConnectBusLabels( NETLIST_OBJECT_LIST& aNetItemBuffer );
static void SetUnconnectedFlag( NETLIST_OBJECT_LIST& aNetItemBuffer );
static void FindBestNetNameForEachNet( NETLIST_OBJECT_LIST& aNetItemBuffer );
static NETLIST_OBJECT* FindBestNetName( NETLIST_OBJECT_LIST& aLabelItemBuffer );
// Sort functions used here:
static bool SortItemsbyNetcode( const NETLIST_OBJECT* Objet1, const NETLIST_OBJECT* Objet2 );
static bool SortItemsBySheet( const NETLIST_OBJECT* Objet1, const NETLIST_OBJECT* Objet2 );
// Local variables
static int LastNetCode, LastBusNetCode;
NETLIST_OBJECT_LIST::~NETLIST_OBJECT_LIST()
{
if( m_isOwner )
ClearList();
}
#if defined(DEBUG)
void dumpNetTable()
/*
* Delete all objects in list and clear list
* (free memory used to store info about NETLIST_OBJECT items)
*/
void NETLIST_OBJECT_LIST::ClearList()
{
for( unsigned idx = 0; idx < g_NetObjectslist.size(); ++idx )
std::vector<NETLIST_OBJECT*>::iterator iter;
for( iter = begin(); iter != end(); iter++ )
{
g_NetObjectslist[idx]->Show( std::cout, idx );
NETLIST_OBJECT* item = *iter;
delete item;
}
}
#endif
clear();
}
wxString BOM_LABEL::GetText() const
void NETLIST_OBJECT_LIST::SortListbyNetcode()
{
const SCH_TEXT* tmp = (SCH_TEXT*) m_label;
return tmp->GetText();
sort( this->begin(), this->end(), NETLIST_OBJECT_LIST::sortItemsbyNetcode );
}
/*
* Routine to free memory used to calculate the netlist TabNetItems = pointer
* to the main table (list items)
*/
static void FreeNetObjectsList( NETLIST_OBJECT_LIST& aNetObjectsBuffer )
void NETLIST_OBJECT_LIST::SortListbySheet()
{
for( unsigned i = 0; i < aNetObjectsBuffer.size(); i++ )
delete aNetObjectsBuffer[i];
aNetObjectsBuffer.clear();
sort( this->begin(), this->end(), NETLIST_OBJECT_LIST::sortItemsBySheet );
}
/*
* Build net list connection table.
*
* Updates:
* g_NetObjectslist
* Updates g_NetObjectslist
*/
void SCH_EDIT_FRAME::BuildNetListBase()
{
int NetCode;
SCH_SHEET_PATH* sheet;
wxString msg, activity;
wxBusyCursor Busy;
activity = _( "Building net list:" );
SetStatusText( activity );
FreeNetObjectsList( g_NetObjectslist );
// Creates the flattened sheet list:
SCH_SHEET_LIST aSheets;
/* Build the sheet (not screen) list (flattened)*/
SCH_SHEET_LIST sheets;
// Build netlist info
bool success = g_NetObjectslist.BuildNetListInfo( aSheets );
/* Fill g_NetObjectslist with items used in connectivity calculation */
for( sheet = sheets.GetFirst(); sheet != NULL; sheet = sheets.GetNext() )
if( !success )
{
for( SCH_ITEM* item = sheet->LastScreen()->GetDrawItems(); item; item = item->Next() )
{
item->GetNetListItem( g_NetObjectslist, sheet );
}
SetStatusText( _("No Objects" ) );
return;
}
if( g_NetObjectslist.size() == 0 )
return; // no objects
/* The new %zu specification is needed to properly format a size_t
* value (returned by size(), here) */
activity += wxString::Format( _( " net count = %zu" ),
g_NetObjectslist.size() );
SetStatusText( activity );
wxString msg;
/* Sort objects by Sheet */
msg.Printf( _( "Net count = %zu" ), g_NetObjectslist.size() );
SetStatusText( msg );
}
sort( g_NetObjectslist.begin(), g_NetObjectslist.end(), SortItemsBySheet );
/* the master function of NETLIST_OBJECT_LIST class.
* Build the list of connected objects (pins, labels ...) and
* all info needed to generate netlists or run ERC diags
*/
bool NETLIST_OBJECT_LIST::BuildNetListInfo( SCH_SHEET_LIST& aSheets )
{
g_NetObjectslist.SetOwner( true );
g_NetObjectslist.ClearList();
activity += _( ", connections... " );
SetStatusText( activity );
SCH_SHEET_PATH* sheet;
// Fill list with connected items from the flattened sheet list
for( sheet = aSheets.GetFirst(); sheet != NULL;
sheet = aSheets.GetNext() )
{
for( SCH_ITEM* item = sheet->LastScreen()->GetDrawItems(); item; item = item->Next() )
{
item->GetNetListItem( *this, sheet );
}
}
if( size() == 0 )
return false;
sheet = &(g_NetObjectslist[0]->m_SheetList);
// Sort objects by Sheet
SortListbySheet();
sheet = &(GetItem( 0 )->m_SheetList);
LastNetCode = LastBusNetCode = 1;
for( unsigned ii = 0, istart = 0; ii < g_NetObjectslist.size(); ii++ )
for( unsigned ii = 0, istart = 0; ii < size(); ii++ )
{
NETLIST_OBJECT* net_item = g_NetObjectslist[ii];
NETLIST_OBJECT* net_item = GetItem( ii );
if( net_item->m_SheetList != *sheet ) // Sheet change
{
......@@ -186,7 +173,7 @@ void SCH_EDIT_FRAME::BuildNetListBase()
break;
case NET_SEGMENT:
/* Control connections point to point type without bus. */
// Test connections point to point type without bus.
if( net_item->GetNet() == 0 )
{
net_item->SetNet( LastNetCode );
......@@ -197,7 +184,7 @@ void SCH_EDIT_FRAME::BuildNetListBase()
break;
case NET_JUNCTION:
/* Control of the junction outside BUS. */
// Control of the junction outside BUS.
if( net_item->GetNet() == 0 )
{
net_item->SetNet( LastNetCode );
......@@ -219,7 +206,7 @@ void SCH_EDIT_FRAME::BuildNetListBase()
case NET_LABEL:
case NET_HIERLABEL:
case NET_GLOBLABEL:
/* Control connections type junction without bus. */
// Test connections type junction without bus.
if( net_item->GetNet() == 0 )
{
net_item->SetNet( LastNetCode );
......@@ -261,22 +248,16 @@ void SCH_EDIT_FRAME::BuildNetListBase()
#if defined(NETLIST_DEBUG) && defined(DEBUG)
std::cout << "\n\nafter sheet local\n\n";
dumpNetTable();
DumpNetTable();
#endif
activity += _( "done" );
SetStatusText( activity );
/* Updating the Bus Labels Netcode connected by Bus */
ConnectBusLabels( g_NetObjectslist );
activity += _( ", bus labels..." );
SetStatusText( activity );
ConnectBusLabels();
/* Group objects by label. */
for( unsigned ii = 0; ii < g_NetObjectslist.size(); ii++ )
for( unsigned ii = 0; ii < size(); ii++ )
{
switch( g_NetObjectslist[ii]->m_Type )
switch( GetItem( ii )->m_Type )
{
case NET_PIN:
case NET_SHEETLABEL:
......@@ -291,7 +272,7 @@ void SCH_EDIT_FRAME::BuildNetListBase()
case NET_PINLABEL:
case NET_BUSLABELMEMBER:
case NET_GLOBBUSLABELMEMBER:
LabelConnect( g_NetObjectslist[ii] );
labelConnect( GetItem( ii ) );
break;
case NET_SHEETBUSLABELMEMBER:
......@@ -306,53 +287,106 @@ void SCH_EDIT_FRAME::BuildNetListBase()
#if defined(NETLIST_DEBUG) && defined(DEBUG)
std::cout << "\n\nafter sheet global\n\n";
dumpNetTable();
DumpNetTable();
#endif
activity += _( "done" );
SetStatusText( activity );
/* Connection hierarchy. */
activity += _( ", hierarchy..." );
SetStatusText( activity );
// Connection between hierarchy sheets
for( unsigned ii = 0; ii < g_NetObjectslist.size(); ii++ )
{
if( g_NetObjectslist[ii]->m_Type == NET_SHEETLABEL
|| g_NetObjectslist[ii]->m_Type == NET_SHEETBUSLABELMEMBER )
SheetLabelConnect( g_NetObjectslist[ii] );
if( GetItem( ii )->m_Type == NET_SHEETLABEL
|| GetItem( ii )->m_Type == NET_SHEETBUSLABELMEMBER )
SheetLabelConnect( GetItem( ii ) );
}
/* Sort objects by NetCode */
sort( g_NetObjectslist.begin(), g_NetObjectslist.end(), SortItemsbyNetcode );
// Sort objects by NetCode
SortListbyNetcode();
#if defined(NETLIST_DEBUG) && defined(DEBUG)
std::cout << "\n\nafter qsort()\n";
dumpNetTable();
DumpNetTable();
#endif
activity += _( "done" );
SetStatusText( activity );
/* Compress numbers of Netcode having consecutive values. */
LastNetCode = NetCode = 0;
int NetCode = 0;
LastNetCode = 0;
for( unsigned ii = 0; ii < g_NetObjectslist.size(); ii++ )
for( unsigned ii = 0; ii < size(); ii++ )
{
if( g_NetObjectslist[ii]->GetNet() != LastNetCode )
if( GetItem( ii )->GetNet() != LastNetCode )
{
NetCode++;
LastNetCode = g_NetObjectslist[ii]->GetNet();
LastNetCode = GetItem( ii )->GetNet();
}
g_NetObjectslist[ii]->SetNet( NetCode );
GetItem( ii )->SetNet( NetCode );
}
/* Assignment of m_FlagOfConnection based connection or not. */
SetUnconnectedFlag( g_NetObjectslist );
// Set the minimal connection info:
SetUnconnectedFlag();
/* find the best label object to give the best net name to each net */
FindBestNetNameForEachNet( g_NetObjectslist );
// find the best label object to give the best net name to each net
FindBestNetNameForEachNet();
return true;
}
// Helper function to give a priority to sort labels:
// NET_PINLABEL and NET_GLOBLABEL are global labels
// and the priority is hight
static int getPriority( const NETLIST_OBJECT* Objet )
{
switch( Objet->m_Type )
{
case NET_PIN: return 1;
case NET_LABEL: return 2;
case NET_HIERLABEL: return 3;
case NET_PINLABEL: return 4;
case NET_GLOBLABEL: return 5;
default: break;
}
return 0;
}
/* function evalLabelsPriority used by FindBestNetNameForEachNet()
* evalLabelsPriority calculates the priority of alabel1 and aLabel2
* return true if alabel1 has a smaller priority than aLabel2
*/
static bool evalLabelsPriority( const NETLIST_OBJECT* aLabel1,
const NETLIST_OBJECT* aLabel2 )
{
int priority1 = getPriority( aLabel1 );
int priority2 = getPriority( aLabel2 );
if( priority1 != priority2 )
return priority1 < priority2;
// Objects have here the same priority, therefore they have the same type.
// for global labels, we select the best candidate by alphabetic order
// because they have no sheetpath as prefix name
// for other labels, we select them before by sheet deep order
// because the actual name is /sheetpath/label
// and for a given path length, by alphabetic order
if( aLabel1->m_Type == NET_PINLABEL || aLabel1->m_Type == NET_GLOBLABEL )
return aLabel1->m_Label.Cmp( aLabel2->m_Label );
// not global: names are prefixed by their sheetpath
// use name defined in higher hierarchical sheet
// (i.e. shorter path because paths are /<timestamp1>/<timestamp2>/...
// and timestamp = 8 letters.
if( aLabel1->m_SheetList.Path().Length() != aLabel2->m_SheetList.Path().Length() )
return aLabel1->m_SheetList.Path().Length() < aLabel2->m_SheetList.Path().Length();
// Sheet paths have the same length: use alphabetic label name order
// For labels on sheets having an equivalent deep in hierarchy, use
// alphabetic label name order:
if( aLabel1->m_Label.Cmp( aLabel2->m_Label ) != 0 )
return aLabel1->m_Label.Cmp( aLabel2->m_Label ) ;
return aLabel1->m_SheetList.PathHumanReadable().Cmp(
aLabel2->m_SheetList.PathHumanReadable() );
}
......@@ -367,39 +401,37 @@ void SCH_EDIT_FRAME::BuildNetListBase()
* the label is in the first sheet in a hierarchy (the root sheet has the most priority)
* alphabetic order.
*/
void FindBestNetNameForEachNet( NETLIST_OBJECT_LIST& aNetItemBuffer )
void NETLIST_OBJECT_LIST::FindBestNetNameForEachNet()
{
if( aNetItemBuffer.size() == 0 )
return; // Should not occur: if this function is called, obviously some items exist in list
NETLIST_OBJECT_LIST candidates;
int netcode = 0; // current netcode for tested items
unsigned idxstart = 0; // index of the first item of this net
for( unsigned ii = 0; ii <= aNetItemBuffer.size(); ii++ )
unsigned idxstart = 0; // index of the first item of this net
NETLIST_OBJECT* item;
NETLIST_OBJECT* candidate;
// Pass 1: find the best name for labelled nets:
item = NULL;
candidate = NULL;
for( unsigned ii = 0; ii <= size(); ii++ )
{
NETLIST_OBJECT* item;
if( ii == aNetItemBuffer.size() ) // last item already found
if( ii == size() ) // last item already found
netcode = -2;
else
item = aNetItemBuffer[ii];
item = GetItem( ii );
if( netcode != item->GetNet() ) // End of net found
if( netcode != item->GetNet() ) // End of net found
{
if( candidates.size() ) // One or more labels exists, find the best
if( candidate ) // One or more labels exists, find the best
{
NETLIST_OBJECT* bestlabel = FindBestNetName( candidates );
for (unsigned jj = idxstart; jj < ii; jj++ )
aNetItemBuffer[jj]->m_NetNameCandidate = bestlabel;
GetItem( jj )->SetNetNameCandidate( candidate );
}
if( netcode == -2 )
break;
netcode = item->GetNet();
candidates.clear();
candidate = NULL;
idxstart = ii;
}
......@@ -409,138 +441,85 @@ void FindBestNetNameForEachNet( NETLIST_OBJECT_LIST& aNetItemBuffer )
case NET_LABEL:
case NET_PINLABEL:
case NET_GLOBLABEL:
candidates.push_back( item );
// A candidate is found: select the better between the previous
// and this one
if( candidate == NULL )
candidate = item;
else
{
if( evalLabelsPriority( item, candidate ) )
candidate = item;
}
break;
default:
break;
}
}
}
/**
* Function FindBestNetName
* @return a reference to the "best" label that can be used to give a name
* to a net.
* @param aLabelItemBuffer = list of NETLIST_OBJECT type labels candidates.
* labels are local labels, hierarchical labels or pin labels
* labels in included sheets have a lower priority than labels in the current sheet.
* so labels inside the root sheet have the higher priority.
* pin labels are global labels and have the higher priority
* local labels have the lower priority
* labels having the same priority are sorted by alphabetic order.
*
*/
static NETLIST_OBJECT* FindBestNetName( NETLIST_OBJECT_LIST& aLabelItemBuffer )
{
if( aLabelItemBuffer.size() == 0 )
return NULL;
// Define a priority (from low to high) to sort labels:
// NET_PINLABEL and NET_GLOBLABEL are global labels
// and priority >= NET_PRIO_MAX-1 is for global connections
// ( i.e. for labels that are not prefixed by a sheetpath)
#define NET_PRIO_MAX 4
static int priority_order[NET_PRIO_MAX+1] = {
NET_ITEM_UNSPECIFIED,
NET_LABEL,
NET_HIERLABEL,
NET_PINLABEL,
NET_GLOBLABEL };
NETLIST_OBJECT*item = aLabelItemBuffer[0];
// Calculate item priority (initial priority)
int item_priority = 0;
for( unsigned ii = 0; ii <= NET_PRIO_MAX; ii++ )
// Pass 2: find the best name for not labelled nets:
// The "default" net name is Net-<<Ref cmp>_Pad<num pad>>
// (see NETLIST_OBJECT::GetShortNetName())
// therefore the "best" is the short net name alphabetically classed first
// (to avoid net names changes when the net is not modified,
// even if components are moved or deleted and undelete or replaced, as long
// the reference is kept)
netcode = 0;
idxstart = 0;
candidate = NULL;
item = NULL;
for( unsigned ii = 0; ii <= size(); ii++ )
{
if ( item->m_Type == priority_order[ii] )
{
item_priority = ii;
break;
}
}
for( unsigned ii = 1; ii < aLabelItemBuffer.size(); ii++ )
{
NETLIST_OBJECT* candidate = aLabelItemBuffer[ii];
// Calculate candidate priority
int candidate_priority = 0;
if( ii == size() ) // last item already found
netcode = -2;
else
item = GetItem( ii );
for( unsigned prio = 0; prio <= NET_PRIO_MAX; prio++ )
if( netcode != item->GetNet() ) // End of net found
{
if ( candidate->m_Type == priority_order[prio] )
if( candidate )
{
candidate_priority = prio;
break;
for (unsigned jj = idxstart; jj < ii; jj++ )
GetItem( jj )->SetNetNameCandidate( candidate );
}
if( netcode == -2 )
break;
netcode = item->GetNet();
candidate = NULL;
idxstart = ii;
}
if( candidate_priority > item_priority )
{
item = candidate;
item_priority = candidate_priority;
}
else if( candidate_priority == item_priority )
if( item->m_Type == NET_PIN && item->GetShortNetName().IsEmpty() )
{
// for global labels, we select the best candidate by alphabetic order
// because they have no sheetpath as prefix name
// for other labels, we select them before by sheet deep order
// because the actual name is /sheetpath/label
// and for a given path length, by alphabetic order
if( item_priority >= NET_PRIO_MAX-1 ) // global label or pin label
{ // selection by alphabetic order:
if( candidate->m_Label.Cmp( item->m_Label ) < 0 )
item = candidate;
}
else // not global: names are prefixed by their sheetpath
// A candidate is found: select the better between the previous
// and this one
item->SetNetNameCandidate( item ); // Needed to calculate GetShortNetName
if( candidate == NULL )
candidate = item;
else
{
// use name defined in higher hierarchical sheet
// (i.e. shorter path because paths are /<timestamp1>/<timestamp2>/...
// and timestamp = 8 letters.
if( candidate->m_SheetList.Path().Length() < item->m_SheetList.Path().Length() )
{
item = candidate;
}
else if( candidate->m_SheetList.Path().Length() == item->m_SheetList.Path().Length() )
{
// For labels on sheets having an equivalent deep in hierarchy, use
// alphabetic label name order:
if( candidate->m_Label.Cmp( item->m_Label ) < 0 )
item = candidate;
else if( candidate->m_Label.Cmp( item->m_Label ) == 0 )
{
if( candidate->m_SheetList.PathHumanReadable().Cmp( item->m_SheetList.PathHumanReadable() ) < 0 )
item = candidate;
}
}
if( item->GetShortNetName().Cmp( candidate->GetShortNetName() ) < 0 )
candidate = item;
}
}
}
return item;
}
/*
* Connect sheets by sheetLabels
* Propagate net codes from a parent sheet to an include sheet,
* from a pin sheet connection
*/
static void SheetLabelConnect( NETLIST_OBJECT* SheetLabel )
void NETLIST_OBJECT_LIST::SheetLabelConnect( NETLIST_OBJECT* SheetLabel )
{
if( SheetLabel->GetNet() == 0 )
return;
/* Calculate the number of nodes in the corresponding sheetlabel */
/* Comparison with SheetLabel GLABELS sub sheet to group Netcode */
for( unsigned ii = 0; ii < g_NetObjectslist.size(); ii++ )
for( unsigned ii = 0; ii < size(); ii++ )
{
NETLIST_OBJECT* ObjetNet = g_NetObjectslist[ii];
NETLIST_OBJECT* ObjetNet = GetItem( ii );
if( ObjetNet->m_SheetList != SheetLabel->m_SheetListInclude )
continue; //use SheetInclude, not the sheet!!
......@@ -554,9 +533,9 @@ static void SheetLabelConnect( NETLIST_OBJECT* SheetLabel )
if( ObjetNet->m_Label.CmpNoCase( SheetLabel->m_Label ) != 0 )
continue; //different names.
/* Propagate Netcode having all the objects of the same Netcode. */
// Propagate Netcode having all the objects of the same Netcode.
if( ObjetNet->GetNet() )
PropageNetCode( ObjetNet->GetNet(), SheetLabel->GetNet(), IS_WIRE );
propageNetCode( ObjetNet->GetNet(), SheetLabel->GetNet(), IS_WIRE );
else
ObjetNet->SetNet( SheetLabel->GetNet() );
}
......@@ -564,17 +543,17 @@ static void SheetLabelConnect( NETLIST_OBJECT* SheetLabel )
/*
* Routine that analyzes the type labels xxBUSLABELMEMBER
* Propagate Netcode between the corresponding labels (ie when
* Their member number is the same) when they are connected
* Generally by their BusNetCode
* Analyzes the labels type bus member (<BUS_NAME><member_number>
* Propagate net codes between the corresponding labels (ie when
* the <member_number> is the same) when they are connected
* uqsually by their BusNetCode
* Uses and updates the variable LastNetCode
*/
static void ConnectBusLabels( NETLIST_OBJECT_LIST& aNetItemBuffer )
void NETLIST_OBJECT_LIST::ConnectBusLabels()
{
for( unsigned ii = 0; ii < aNetItemBuffer.size(); ii++ )
for( unsigned ii = 0; ii < size(); ii++ )
{
NETLIST_OBJECT* Label = aNetItemBuffer[ii];
NETLIST_OBJECT* Label = GetItem( ii );
if( (Label->m_Type == NET_SHEETBUSLABELMEMBER)
|| (Label->m_Type == NET_BUSLABELMEMBER)
......@@ -586,9 +565,9 @@ static void ConnectBusLabels( NETLIST_OBJECT_LIST& aNetItemBuffer )
LastNetCode++;
}
for( unsigned jj = ii + 1; jj < aNetItemBuffer.size(); jj++ )
for( unsigned jj = ii + 1; jj < size(); jj++ )
{
NETLIST_OBJECT* LabelInTst = aNetItemBuffer[jj];
NETLIST_OBJECT* LabelInTst = GetItem( jj );
if( (LabelInTst->m_Type == NET_SHEETBUSLABELMEMBER)
|| (LabelInTst->m_Type == NET_BUSLABELMEMBER)
|| (LabelInTst->m_Type == NET_HIERBUSLABELMEMBER) )
......@@ -602,7 +581,7 @@ static void ConnectBusLabels( NETLIST_OBJECT_LIST& aNetItemBuffer )
if( LabelInTst->GetNet() == 0 )
LabelInTst->SetNet( Label->GetNet() );
else
PropageNetCode( LabelInTst->GetNet(), Label->GetNet(), IS_WIRE );
propageNetCode( LabelInTst->GetNet(), Label->GetNet(), IS_WIRE );
}
}
}
......@@ -611,38 +590,34 @@ static void ConnectBusLabels( NETLIST_OBJECT_LIST& aNetItemBuffer )
/*
* PropageNetCode propagates Netcode NewNetCode on all elements
* belonging to the former Netcode OldNetCode
* If IsBus == 0; Netcode is the member who is spreading
* If IsBus != 0; is the member who is spreading BusNetCode
* propageNetCode propagates the net code NewNetCode to all elements
* having previously the net code OldNetCode
* If IsBus == false, m_Netcode is used to propagate the new net code
* If IsBus == true, m_BusNetCode is used to propagate the new net code
*/
static void PropageNetCode( int OldNetCode, int NewNetCode, BUS_OR_WIRE IsBus )
void NETLIST_OBJECT_LIST::propageNetCode( int aOldNetCode, int aNewNetCode, bool aIsBus )
{
if( OldNetCode == NewNetCode )
if( aOldNetCode == aNewNetCode )
return;
if( IsBus == IS_WIRE ) // Propagate NetCode
if( aIsBus == false ) // Propagate NetCode
{
for( unsigned jj = 0; jj < g_NetObjectslist.size(); jj++ )
for( unsigned jj = 0; jj < size(); jj++ )
{
NETLIST_OBJECT* Objet = g_NetObjectslist[jj];
NETLIST_OBJECT* objet = GetItem( jj );
if( Objet->GetNet() == OldNetCode )
{
Objet->SetNet( NewNetCode );
}
if( objet->GetNet() == aOldNetCode )
objet->SetNet( aNewNetCode );
}
}
else /* Propagate BusNetCode */
else // Propagate BusNetCode
{
for( unsigned jj = 0; jj < g_NetObjectslist.size(); jj++ )
for( unsigned jj = 0; jj < size(); jj++ )
{
NETLIST_OBJECT* Objet = g_NetObjectslist[jj];
NETLIST_OBJECT* objet = GetItem( jj );
if( Objet->m_BusNetCode == OldNetCode )
{
Objet->m_BusNetCode = NewNetCode;
}
if( objet->m_BusNetCode == aOldNetCode )
objet->m_BusNetCode = aNewNetCode;
}
}
}
......@@ -667,19 +642,20 @@ static void PropageNetCode( int OldNetCode, int NewNetCode, BUS_OR_WIRE IsBus )
* Leaf schema
* (There can be no physical connection between elements of different sheets)
*/
static void PointToPointConnect( NETLIST_OBJECT* Ref, BUS_OR_WIRE IsBus, int start )
void NETLIST_OBJECT_LIST::PointToPointConnect( NETLIST_OBJECT* aRef, bool aIsBus,
int start )
{
int netCode;
if( IsBus == IS_WIRE ) // Objects other than BUS and BUSLABELS
if( aIsBus == false ) // Objects other than BUS and BUSLABELS
{
netCode = Ref->GetNet();
netCode = aRef->GetNet();
for( unsigned i = start; i < g_NetObjectslist.size(); i++ )
for( unsigned i = start; i < size(); i++ )
{
NETLIST_OBJECT* item = g_NetObjectslist[i];
NETLIST_OBJECT* item = GetItem( i );
if( item->m_SheetList != Ref->m_SheetList ) //used to be > (why?)
if( item->m_SheetList != aRef->m_SheetList ) //used to be > (why?)
continue;
switch( item->m_Type )
......@@ -693,15 +669,15 @@ static void PointToPointConnect( NETLIST_OBJECT* Ref, BUS_OR_WIRE IsBus, int sta
case NET_PINLABEL:
case NET_JUNCTION:
case NET_NOCONNECT:
if( Ref->m_Start == item->m_Start
|| Ref->m_Start == item->m_End
|| Ref->m_End == item->m_Start
|| Ref->m_End == item->m_End )
if( aRef->m_Start == item->m_Start
|| aRef->m_Start == item->m_End
|| aRef->m_End == item->m_Start
|| aRef->m_End == item->m_End )
{
if( item->GetNet() == 0 )
item->SetNet( netCode );
else
PropageNetCode( item->GetNet(), netCode, IS_WIRE );
propageNetCode( item->GetNet(), netCode, IS_WIRE );
}
break;
......@@ -717,13 +693,13 @@ static void PointToPointConnect( NETLIST_OBJECT* Ref, BUS_OR_WIRE IsBus, int sta
}
else /* Object type BUS, BUSLABELS, and junctions. */
{
netCode = Ref->m_BusNetCode;
netCode = aRef->m_BusNetCode;
for( unsigned i = start; i<g_NetObjectslist.size(); i++ )
for( unsigned i = start; i < size(); i++ )
{
NETLIST_OBJECT* item = g_NetObjectslist[i];
NETLIST_OBJECT* item = GetItem( i );
if( item->m_SheetList != Ref->m_SheetList )
if( item->m_SheetList != aRef->m_SheetList )
continue;
switch( item->m_Type )
......@@ -745,15 +721,15 @@ static void PointToPointConnect( NETLIST_OBJECT* Ref, BUS_OR_WIRE IsBus, int sta
case NET_HIERBUSLABELMEMBER:
case NET_GLOBBUSLABELMEMBER:
case NET_JUNCTION:
if( Ref->m_Start == item->m_Start
|| Ref->m_Start == item->m_End
|| Ref->m_End == item->m_Start
|| Ref->m_End == item->m_End )
if( aRef->m_Start == item->m_Start
|| aRef->m_Start == item->m_End
|| aRef->m_End == item->m_Start
|| aRef->m_End == item->m_End )
{
if( item->m_BusNetCode == 0 )
item->m_BusNetCode = netCode;
else
PropageNetCode( item->m_BusNetCode, netCode, IS_BUS );
propageNetCode( item->m_BusNetCode, netCode, IS_BUS );
}
break;
}
......@@ -763,131 +739,111 @@ static void PointToPointConnect( NETLIST_OBJECT* Ref, BUS_OR_WIRE IsBus, int sta
/*
* Search if a junction is connected to segments and propagate the junction Netcode
* to objects connected by the junction.
* The junction must have a valid Netcode
* Search connections betweena junction and segments
* Propagate the junction net code to objects connected by this junction.
* The junction must have a valid net code
* The list of objects is expected sorted by sheets.
* Search is done from index aIdxStart to the last element of g_NetObjectslist
* Search is done from index aIdxStart to the last element of list
*/
static void SegmentToPointConnect( NETLIST_OBJECT* aJonction, BUS_OR_WIRE aIsBus, int aIdxStart )
void NETLIST_OBJECT_LIST::SegmentToPointConnect( NETLIST_OBJECT* aJonction,
bool aIsBus, int aIdxStart )
{
for( unsigned i = aIdxStart; i < g_NetObjectslist.size(); i++ )
for( unsigned i = aIdxStart; i < size(); i++ )
{
NETLIST_OBJECT* Segment = g_NetObjectslist[i];
NETLIST_OBJECT* segment = GetItem( i );
// if different sheets, no physical connection between elements is possible.
if( Segment->m_SheetList != aJonction->m_SheetList )
// if different sheets, obviously no physical connection between elements.
if( segment->m_SheetList != aJonction->m_SheetList )
continue;
if( aIsBus == IS_WIRE )
{
if( Segment->m_Type != NET_SEGMENT )
if( segment->m_Type != NET_SEGMENT )
continue;
}
else
{
if( Segment->m_Type != NET_BUS )
if( segment->m_Type != NET_BUS )
continue;
}
if( SegmentIntersect( Segment->m_Start, Segment->m_End, aJonction->m_Start ) )
if( SegmentIntersect( segment->m_Start, segment->m_End, aJonction->m_Start ) )
{
/* Propagation Netcode has all the objects of the same Netcode. */
// Propagation Netcode has all the objects of the same Netcode.
if( aIsBus == IS_WIRE )
{
if( Segment->GetNet() )
PropageNetCode( Segment->GetNet(), aJonction->GetNet(), aIsBus );
if( segment->GetNet() )
propageNetCode( segment->GetNet(), aJonction->GetNet(), aIsBus );
else
Segment->SetNet( aJonction->GetNet() );
segment->SetNet( aJonction->GetNet() );
}
else
{
if( Segment->m_BusNetCode )
PropageNetCode( Segment->m_BusNetCode, aJonction->m_BusNetCode, aIsBus );
if( segment->m_BusNetCode )
propageNetCode( segment->m_BusNetCode, aJonction->m_BusNetCode, aIsBus );
else
Segment->m_BusNetCode = aJonction->m_BusNetCode;
segment->m_BusNetCode = aJonction->m_BusNetCode;
}
}
}
}
/*****************************************************************
* Function which connects the groups of object which have the same label
*******************************************************************/
void LabelConnect( NETLIST_OBJECT* LabelRef )
/*
* This function merges the net codes of groups of objects already connected
* to labels (wires, bus, pins ... ) when 2 labels are equivalents
* (i.e. group objects connected by labels)
*/
void NETLIST_OBJECT_LIST::labelConnect( NETLIST_OBJECT* aLabelRef )
{
if( LabelRef->GetNet() == 0 )
if( aLabelRef->GetNet() == 0 )
return;
for( unsigned i = 0; i < g_NetObjectslist.size(); i++ )
for( unsigned i = 0; i < size(); i++ )
{
if( g_NetObjectslist[i]->GetNet() == LabelRef->GetNet() )
NETLIST_OBJECT* item = GetItem( i );
if( item->GetNet() == aLabelRef->GetNet() )
continue;
if( g_NetObjectslist[i]->m_SheetList != LabelRef->m_SheetList )
if( item->m_SheetList != aLabelRef->m_SheetList )
{
if( (g_NetObjectslist[i]->m_Type != NET_PINLABEL
&& g_NetObjectslist[i]->m_Type != NET_GLOBLABEL
&& g_NetObjectslist[i]->m_Type != NET_GLOBBUSLABELMEMBER) )
if( item->m_Type != NET_PINLABEL && item->m_Type != NET_GLOBLABEL
&& item->m_Type != NET_GLOBBUSLABELMEMBER )
continue;
if( (g_NetObjectslist[i]->m_Type == NET_GLOBLABEL
|| g_NetObjectslist[i]->m_Type == NET_GLOBBUSLABELMEMBER)
&& g_NetObjectslist[i]->m_Type != LabelRef->m_Type )
if( (item->m_Type == NET_GLOBLABEL
|| item->m_Type == NET_GLOBBUSLABELMEMBER)
&& item->m_Type != aLabelRef->m_Type )
//global labels only connect other global labels.
continue;
}
// regular labels are sheet-local;
// NET_HIERLABEL are used to connect sheets.
// NET_LABEL is sheet-local (***)
// NET_GLOBLABEL is global.
// NET_LABEL are local to a sheet
// NET_GLOBLABEL are global.
// NET_PINLABEL is a kind of global label (generated by a power pin invisible)
NETLIST_ITEM_T ntype = g_NetObjectslist[i]->m_Type;
if( ntype == NET_LABEL
|| ntype == NET_GLOBLABEL
|| ntype == NET_HIERLABEL
|| ntype == NET_BUSLABELMEMBER
|| ntype == NET_GLOBBUSLABELMEMBER
|| ntype == NET_HIERBUSLABELMEMBER
|| ntype == NET_PINLABEL )
if( item->IsLabelType() )
{
if( g_NetObjectslist[i]->m_Label.CmpNoCase( LabelRef->m_Label ) != 0 )
if( item->m_Label.CmpNoCase( aLabelRef->m_Label ) != 0 )
continue;
if( g_NetObjectslist[i]->GetNet() )
PropageNetCode( g_NetObjectslist[i]->GetNet(), LabelRef->GetNet(), IS_WIRE );
if( item->GetNet() )
propageNetCode( item->GetNet(), aLabelRef->GetNet(), IS_WIRE );
else
g_NetObjectslist[i]->SetNet( LabelRef->GetNet() );
item->SetNet( aLabelRef->GetNet() );
}
}
}
/* Comparison routine for sorting by increasing Netcode
* table of elements connected (TabPinSort) by qsort ()
/* Set the m_FlagOfConnection member of items in list
* depending on the connection type:
* UNCONNECTED, PAD_CONNECT or NOCONNECT_SYMBOL_PRESENT
* The list is expected sorted by order of net code,
* i.e. items having the same net code are grouped
*/
bool SortItemsbyNetcode( const NETLIST_OBJECT* Objet1, const NETLIST_OBJECT* Objet2 )
{
return Objet1->GetNet() < Objet2->GetNet();
}
/* Comparison routine for sorting items by Sheet Number ( used by qsort )
*/
bool SortItemsBySheet( const NETLIST_OBJECT* Objet1, const NETLIST_OBJECT* Objet2 )
{
return Objet1->m_SheetList.Cmp( Objet2->m_SheetList ) < 0;
}
/* Routine positioning member. FlagNoConnect ELEMENTS
* List of objects NetList, sorted by order of Netcode
*/
static void SetUnconnectedFlag( NETLIST_OBJECT_LIST& aNetItemBuffer )
void NETLIST_OBJECT_LIST::SetUnconnectedFlag()
{
NETLIST_OBJECT* NetItemRef;
unsigned NetStart, NetEnd;
......@@ -895,17 +851,17 @@ static void SetUnconnectedFlag( NETLIST_OBJECT_LIST& aNetItemBuffer )
NetStart = NetEnd = 0;
StateFlag = UNCONNECTED;
for( unsigned ii = 0; ii < aNetItemBuffer.size(); ii++ )
for( unsigned ii = 0; ii < size(); ii++ )
{
NetItemRef = aNetItemBuffer[ii];
NetItemRef = GetItem( ii );
if( NetItemRef->m_Type == NET_NOCONNECT && StateFlag != PAD_CONNECT )
StateFlag = NOCONNECT_SYMBOL_PRESENT;
/* Analysis of current net. */
unsigned idxtoTest = ii + 1;
if( ( idxtoTest >= aNetItemBuffer.size() )
|| ( NetItemRef->GetNet() != aNetItemBuffer[idxtoTest]->GetNet() ) )
if( ( idxtoTest >= size() )
|| ( NetItemRef->GetNet() != GetItem( idxtoTest )->GetNet() ) )
{
/* Net analysis to update m_FlagOfConnection */
NetEnd = idxtoTest;
......@@ -913,9 +869,9 @@ static void SetUnconnectedFlag( NETLIST_OBJECT_LIST& aNetItemBuffer )
/* set m_FlagOfConnection member to StateFlag for all items of
* this net: */
for( unsigned kk = NetStart; kk < NetEnd; kk++ )
aNetItemBuffer[kk]->m_FlagOfConnection = StateFlag;
GetItem( kk )->m_FlagOfConnection = StateFlag;
if( idxtoTest >= aNetItemBuffer.size() )
if( idxtoTest >= size() )
return;
/* Start Analysis next Net */
......@@ -934,11 +890,11 @@ static void SetUnconnectedFlag( NETLIST_OBJECT_LIST& aNetItemBuffer )
*/
for( ; ; idxtoTest++ )
{
if( ( idxtoTest >= aNetItemBuffer.size() )
|| ( NetItemRef->GetNet() != aNetItemBuffer[idxtoTest]->GetNet() ) )
if( ( idxtoTest >= size() )
|| ( NetItemRef->GetNet() != GetItem( idxtoTest )->GetNet() ) )
break;
switch( aNetItemBuffer[idxtoTest]->m_Type )
switch( GetItem( idxtoTest )->m_Type )
{
case NET_ITEM_UNSPECIFIED:
wxMessageBox( wxT( "BuildNetListBase() error" ) );
......@@ -973,3 +929,4 @@ static void SetUnconnectedFlag( NETLIST_OBJECT_LIST& aNetItemBuffer )
}
}
}
......@@ -37,6 +37,7 @@
#include <class_libentry.h>
#include <sch_sheet_path.h>
#include <sch_component.h>
#include <sch_text.h>
/// netlist types
......@@ -483,7 +484,7 @@ private:
/**
* Class BOM_LABEL
* is used to build a BOM by handling the list of labels in schematic because in a
* is used to build a List of Labels by handling the list of labels in schematic because in a
* complex hierarchy, a label is used more than once and has more than one sheet path
* so we must create a flat list of labels.
*/
......@@ -512,7 +513,11 @@ public:
const SCH_SHEET_PATH& GetSheetPath() const { return m_sheetPath; }
wxString GetText() const;
wxString GetText() const
{
const SCH_TEXT* tmp = (SCH_TEXT*) m_label;
return tmp->GetText();
}
};
......
......@@ -34,7 +34,6 @@
#include <wxEeschemaStruct.h>
#include <menus_helpers.h>
#include <general.h>
#include <sch_bus_entry.h>
#include <sch_text.h>
#include <sch_marker.h>
......@@ -43,6 +42,7 @@
#include <sch_no_connect.h>
#include <sch_component.h>
#include <sch_sheet.h>
#include <sch_sheet_path.h>
#include <sch_bitmap.h>
......
......@@ -28,7 +28,7 @@
#include <macros.h>
#include <general.h>
#include <sch_sheet_path.h>
#include <transform.h>
#include <sch_collectors.h>
#include <sch_component.h>
......
......@@ -1720,8 +1720,8 @@ SEARCH_RESULT SCH_COMPONENT::Visit( INSPECTOR* aInspector, const void* aTestData
}
void SCH_COMPONENT::GetNetListItem( vector<NETLIST_OBJECT*>& aNetListItems,
SCH_SHEET_PATH* aSheetPath )
void SCH_COMPONENT::GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
SCH_SHEET_PATH* aSheetPath )
{
LIB_COMPONENT* component = CMP_LIBRARY::FindLibraryComponent( GetLibName() );
......
......@@ -40,7 +40,7 @@ class SCH_SHEET_PATH;
class LIB_ITEM;
class LIB_PIN;
class LIB_COMPONENT;
class NETLIST_OBJECT_LIST;
/// A container for several SCH_FIELD items
typedef std::vector<SCH_FIELD> SCH_FIELDS;
......@@ -384,8 +384,8 @@ public:
BITMAP_DEF GetMenuImage() const { return add_component_xpm; }
void GetNetListItem( vector<NETLIST_OBJECT*>& aNetListItems,
SCH_SHEET_PATH* aSheetPath );
void GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
SCH_SHEET_PATH* aSheetPath );
bool operator <( const SCH_ITEM& aItem ) const;
......
......@@ -36,6 +36,7 @@
#include <plot_common.h>
#include <sch_junction.h>
#include <class_netlist_object.h>
int SCH_JUNCTION::m_symbolSize = 40; // Default diameter of the junction symbol
......@@ -173,7 +174,7 @@ void SCH_JUNCTION::GetConnectionPoints( vector< wxPoint >& aPoints ) const
}
void SCH_JUNCTION::GetNetListItem( vector<NETLIST_OBJECT*>& aNetListItems,
void SCH_JUNCTION::GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
SCH_SHEET_PATH* aSheetPath )
{
NETLIST_OBJECT* item = new NETLIST_OBJECT();
......
......@@ -31,6 +31,7 @@
#include <sch_item_struct.h>
class NETLIST_OBJECT_LIST;
class SCH_JUNCTION : public SCH_ITEM
{
......@@ -86,7 +87,7 @@ public:
BITMAP_DEF GetMenuImage() const { return add_junction_xpm; }
void GetNetListItem( vector<NETLIST_OBJECT*>& aNetListItems, SCH_SHEET_PATH* aSheetPath );
void GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems, SCH_SHEET_PATH* aSheetPath );
wxPoint GetPosition() const { return m_pos; }
......
......@@ -516,8 +516,8 @@ BITMAP_DEF SCH_LINE::GetMenuImage() const
}
void SCH_LINE::GetNetListItem( vector<NETLIST_OBJECT*>& aNetListItems,
SCH_SHEET_PATH* aSheetPath )
void SCH_LINE::GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
SCH_SHEET_PATH* aSheetPath )
{
// Net list item not required for graphic lines.
if( (GetLayer() != LAYER_BUS) && (GetLayer() != LAYER_WIRE) )
......
......@@ -32,6 +32,7 @@
#include <sch_item_struct.h>
class NETLIST_OBJECT_LIST;
/**
* Class SCH_LINE
......@@ -128,7 +129,7 @@ public:
BITMAP_DEF GetMenuImage() const;
void GetNetListItem( vector<NETLIST_OBJECT*>& aNetListItems, SCH_SHEET_PATH* aSheetPath );
void GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems, SCH_SHEET_PATH* aSheetPath );
bool operator <( const SCH_ITEM& aItem ) const;
......
......@@ -188,8 +188,8 @@ void SCH_NO_CONNECT::GetConnectionPoints( vector< wxPoint >& aPoints ) const
}
void SCH_NO_CONNECT::GetNetListItem( vector<NETLIST_OBJECT*>& aNetListItems,
SCH_SHEET_PATH* aSheetPath )
void SCH_NO_CONNECT::GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
SCH_SHEET_PATH* aSheetPath )
{
NETLIST_OBJECT* item = new NETLIST_OBJECT();
......
......@@ -32,6 +32,7 @@
#include <sch_item_struct.h>
class NETLIST_OBJECT_LIST;
class SCH_NO_CONNECT : public SCH_ITEM
{
......@@ -86,7 +87,7 @@ public:
BITMAP_DEF GetMenuImage() const { return noconn_xpm; }
void GetNetListItem( vector<NETLIST_OBJECT*>& aNetListItems, SCH_SHEET_PATH* aSheetPath );
void GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems, SCH_SHEET_PATH* aSheetPath );
wxPoint GetPosition() const { return m_pos; }
......
......@@ -40,9 +40,8 @@
#include <wxEeschemaStruct.h>
#include <plot_common.h>
#include <general.h>
#include <protos.h>
#include <netlist.h>
#include <class_netlist_object.h>
#include <class_library.h>
#include <sch_junction.h>
#include <sch_bus_entry.h>
......@@ -52,6 +51,7 @@
#include <sch_sheet.h>
#include <sch_component.h>
#include <sch_text.h>
#include <lib_pin.h>
#include <boost/foreach.hpp>
......
......@@ -37,7 +37,6 @@
#include <kicad_string.h>
#include <msgpanel.h>
#include <general.h>
#include <sch_sheet.h>
#include <sch_sheet_path.h>
#include <sch_component.h>
......@@ -1073,8 +1072,8 @@ wxPoint SCH_SHEET::GetResizePosition() const
}
void SCH_SHEET::GetNetListItem( vector<NETLIST_OBJECT*>& aNetListItems,
SCH_SHEET_PATH* aSheetPath )
void SCH_SHEET::GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
SCH_SHEET_PATH* aSheetPath )
{
SCH_SHEET_PATH sheetPath = *aSheetPath;
sheetPath.Push( this );
......
......@@ -42,6 +42,7 @@ class SCH_SHEET_PIN;
class SCH_SHEET_PATH;
class DANGLING_END_ITEM;
class SCH_EDIT_FRAME;
class NETLIST_OBJECT_LIST;
#define MIN_SHEET_WIDTH 500
......@@ -541,8 +542,8 @@ public:
BITMAP_DEF GetMenuImage() const { return add_hierarchical_subsheet_xpm; }
void GetNetListItem( vector<NETLIST_OBJECT*>& aNetListItems,
SCH_SHEET_PATH* aSheetPath );
void GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
SCH_SHEET_PATH* aSheetPath );
SCH_ITEM& operator=( const SCH_ITEM& aSheet );
......
......@@ -613,8 +613,8 @@ wxString SCH_TEXT::GetSelectMenuText() const
}
void SCH_TEXT::GetNetListItem( vector<NETLIST_OBJECT*>& aNetListItems,
SCH_SHEET_PATH* aSheetPath )
void SCH_TEXT::GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
SCH_SHEET_PATH* aSheetPath )
{
if( GetLayer() == LAYER_NOTES || GetLayer() == LAYER_SHEETLABEL )
return;
......
......@@ -37,6 +37,7 @@
class LINE_READER;
class NETLIST_OBJECT_LIST;
/* Type of SCH_HIERLABEL and SCH_GLOBALLABEL
......@@ -196,8 +197,8 @@ public:
virtual BITMAP_DEF GetMenuImage() const { return add_text_xpm; }
virtual void GetNetListItem( vector<NETLIST_OBJECT*>& aNetListItems,
SCH_SHEET_PATH* aSheetPath );
virtual void GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
SCH_SHEET_PATH* aSheetPath );
virtual wxPoint GetPosition() const { return m_Pos; }
......
......@@ -47,6 +47,7 @@
#include <sch_junction.h>
#include <sch_line.h>
#include <sch_sheet.h>
#include <sch_sheet_path.h>
void SCH_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
......
......@@ -44,6 +44,7 @@ class SCH_EDIT_FRAME;
class wxFindReplaceData;
class PLOTTER;
class NETLIST_OBJECT;
class NETLIST_OBJECT_LIST;
typedef boost::ptr_vector< SCH_ITEM > SCH_ITEMS;
......@@ -342,8 +343,8 @@ public:
* net list objects associated with them.
* </p>
*/
virtual void GetNetListItem( vector<NETLIST_OBJECT*>& aNetListItems,
SCH_SHEET_PATH* aSheetPath ) { }
virtual void GetNetListItem( NETLIST_OBJECT_LIST& aNetListItems,
SCH_SHEET_PATH* aSheetPath ) { }
/**
* Function GetPosition
......
......@@ -643,9 +643,12 @@ public:
* @param aDefaultLayer = Preselection (NB_PCB_LAYERS for "(Deselect)" layer)
* @param aNotAllowedLayersMask = a layer mask for not allowed layers
* (= 0 to show all layers in use)
* @param aDlgPosition = position of dialog ( defualt = centered)
* @return the selected layer id
*/
LAYER_NUM SelectLayer( LAYER_NUM aDefaultLayer, LAYER_MSK aNotAllowedLayersMask = 0 );
LAYER_NUM SelectLayer( LAYER_NUM aDefaultLayer,
LAYER_MSK aNotAllowedLayersMask = 0,
wxPoint aDlgPosition = wxDefaultPosition );
/* Display a list of two copper layers to choose a pair of copper layers
* the layer pair is used to fast switch between copper layers when placing vias
......
......@@ -283,7 +283,7 @@ void DIALOG_COPPER_ZONE::initDialog()
ctrlWidth += 4; // add small margin between text and window borders
m_LayerSelectionCtrl->SetMinSize( wxSize(ctrlWidth, -1));
wxString netNameDoNotShowFilter = wxT( "N-*" );
wxString netNameDoNotShowFilter = wxT( "Net-*" );
if( m_Config )
{
int opt = m_Config->Read( ZONE_NET_SORT_OPTION_KEY, 1l );
......
......@@ -60,18 +60,12 @@
void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
{
int id = event.GetId();
wxPoint pos;
LAYER_NUM itmp;
INSTALL_UNBUFFERED_DC( dc, m_canvas );
MODULE* module;
m_canvas->CrossHairOff( &dc );
wxGetMousePosition( &pos.x, &pos.y );
pos.y += 20;
switch( id ) // Some (not all ) edit commands must be finished or aborted
{
case wxID_CUT:
......@@ -246,7 +240,7 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
break;
case ID_PCB_GLOBAL_DELETE:
InstallPcbGlobalDeleteFrame( pos );
InstallPcbGlobalDeleteFrame( wxDefaultPosition );
break;
case ID_POPUP_PLACE_BLOCK:
......@@ -409,7 +403,10 @@ void PCB_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
id == ID_POPUP_PCB_SELECT_CU_LAYER_AND_PLACE_BLIND_BURIED_VIA )
{
m_canvas->SetIgnoreMouseEvents( true );
LAYER_NUM layer = SelectLayer( getActiveLayer(), ALL_NO_CU_LAYERS );
wxPoint dlgPosition;
wxGetMousePosition( &dlgPosition.x, &dlgPosition.y );
LAYER_NUM layer = SelectLayer( getActiveLayer(), ALL_NO_CU_LAYERS,
dlgPosition );
m_canvas->SetIgnoreMouseEvents( false );
m_canvas->MoveCursorToCrossHair();
......
......@@ -87,16 +87,7 @@ class PCB_ONE_LAYER_SELECTOR : public PCB_LAYER_SELECTOR,
public:
PCB_ONE_LAYER_SELECTOR( wxWindow* aParent, BOARD * aBrd,
LAYER_NUM aDefaultLayer,
LAYER_MSK aNotAllowedLayersMask )
:PCB_LAYER_SELECTOR( aBrd ), DIALOG_LAYER_SELECTION_BASE( aParent )
{
m_layerSelected = (int) aDefaultLayer;
m_notAllowedLayersMask = aNotAllowedLayersMask;
BuildList();
Layout();
GetSizer()->SetSizeHints(this);
SetFocus();
}
LAYER_MSK aNotAllowedLayersMask );
LAYER_NUM GetLayerSelection() { return m_layerSelected; }
......@@ -108,6 +99,20 @@ private:
void BuildList();
};
PCB_ONE_LAYER_SELECTOR::PCB_ONE_LAYER_SELECTOR( wxWindow* aParent,
BOARD * aBrd,
LAYER_NUM aDefaultLayer,
LAYER_MSK aNotAllowedLayersMask )
: PCB_LAYER_SELECTOR( aBrd ), DIALOG_LAYER_SELECTION_BASE( aParent )
{
m_layerSelected = (int) aDefaultLayer;
m_notAllowedLayersMask = aNotAllowedLayersMask;
BuildList();
Layout();
GetSizer()->SetSizeHints(this);
SetFocus();
}
// Build the layers list
// Column position by function:
#define SELECT_COLNUM 0
......@@ -221,10 +226,18 @@ void PCB_ONE_LAYER_SELECTOR::OnRightGridCellClick( wxGridEvent& event )
* @return the selected layer id
*/
LAYER_NUM PCB_BASE_FRAME::SelectLayer( LAYER_NUM aDefaultLayer,
LAYER_MSK aNotAllowedLayersMask )
LAYER_MSK aNotAllowedLayersMask,
wxPoint aDlgPosition )
{
PCB_ONE_LAYER_SELECTOR dlg( this, GetBoard(),
aDefaultLayer, aNotAllowedLayersMask );
if( aDlgPosition != wxDefaultPosition )
{
wxSize dlgSize = dlg.GetSize();
aDlgPosition.x -= dlgSize.x/2;
aDlgPosition.y -= dlgSize.y/2;
dlg.SetPosition( aDlgPosition );
}
dlg.ShowModal();
LAYER_NUM layer = dlg.GetLayerSelection();
return layer;
......
......@@ -14,7 +14,6 @@
#include <class_drawsegment.h>
#include <pcbnew.h>
#include <protos.h>
#include <wx/statline.h>
......@@ -31,7 +30,7 @@ enum swap_layer_id {
};
class WinEDA_SwapLayerFrame : public DIALOG_SHIM
class SWAP_LAYERS_DIALOG : public DIALOG_SHIM
{
private:
PCB_BASE_FRAME* m_Parent;
......@@ -46,8 +45,8 @@ private:
public:
WinEDA_SwapLayerFrame( PCB_BASE_FRAME* parent );
~WinEDA_SwapLayerFrame() { };
SWAP_LAYERS_DIALOG( PCB_BASE_FRAME* parent );
~SWAP_LAYERS_DIALOG() { };
private:
void Sel_Layer( wxCommandEvent& event );
......@@ -58,16 +57,16 @@ private:
};
BEGIN_EVENT_TABLE( WinEDA_SwapLayerFrame, wxDialog )
BEGIN_EVENT_TABLE( SWAP_LAYERS_DIALOG, wxDialog )
EVT_COMMAND_RANGE( ID_BUTTON_0, ID_BUTTON_0 + NB_PCB_LAYERS - 1,
wxEVT_COMMAND_BUTTON_CLICKED,
WinEDA_SwapLayerFrame::Sel_Layer )
EVT_BUTTON( wxID_OK, WinEDA_SwapLayerFrame::OnOkClick )
EVT_BUTTON( wxID_CANCEL, WinEDA_SwapLayerFrame::OnCancelClick )
SWAP_LAYERS_DIALOG::Sel_Layer )
EVT_BUTTON( wxID_OK, SWAP_LAYERS_DIALOG::OnOkClick )
EVT_BUTTON( wxID_CANCEL, SWAP_LAYERS_DIALOG::OnCancelClick )
END_EVENT_TABLE()
WinEDA_SwapLayerFrame::WinEDA_SwapLayerFrame( PCB_BASE_FRAME* parent ) :
SWAP_LAYERS_DIALOG::SWAP_LAYERS_DIALOG( PCB_BASE_FRAME* parent ) :
DIALOG_SHIM( parent, -1, _( "Swap Layers:" ), wxPoint( -1, -1 ),
wxDefaultSize, wxDEFAULT_DIALOG_STYLE | MAYBE_RESIZE_BORDER )
{
......@@ -269,10 +268,12 @@ WinEDA_SwapLayerFrame::WinEDA_SwapLayerFrame( PCB_BASE_FRAME* parent ) :
{
GetSizer()->SetSizeHints( this );
}
Center();
}
void WinEDA_SwapLayerFrame::Sel_Layer( wxCommandEvent& event )
void SWAP_LAYERS_DIALOG::Sel_Layer( wxCommandEvent& event )
{
int ii;
......@@ -283,21 +284,24 @@ void WinEDA_SwapLayerFrame::Sel_Layer( wxCommandEvent& event )
ii = event.GetId() - ID_BUTTON_0;
LAYER_NUM jj = New_Layer[ii];
LAYER_NUM layer = New_Layer[ii];
if( (jj < 0) || (jj > NB_PCB_LAYERS) )
jj = LAYER_NO_CHANGE; // (Defaults to "No Change".)
if( (layer < 0) || (layer > NB_PCB_LAYERS) )
layer = LAYER_NO_CHANGE; // (Defaults to "No Change".)
jj = m_Parent->SelectLayer( jj );
LAYER_MSK notallowed_mask = ii < NB_COPPER_LAYERS ?
ALL_NO_CU_LAYERS : ALL_CU_LAYERS;
layer = m_Parent->SelectLayer( layer == LAYER_NO_CHANGE ? ii : layer,
notallowed_mask );
if( !IsValidLayer( jj ) )
if( !IsValidLayer( layer ) )
return;
if( jj != New_Layer[ii] )
if( layer != New_Layer[ii] )
{
New_Layer[ii] = jj;
New_Layer[ii] = layer;
if( jj >= LAYER_NO_CHANGE || jj == ii )
if( layer >= LAYER_NO_CHANGE || layer == ii )
{
layer_list[ii]->SetLabel( _( "No Change" ) );
......@@ -307,7 +311,7 @@ void WinEDA_SwapLayerFrame::Sel_Layer( wxCommandEvent& event )
}
else
{
layer_list[ii]->SetLabel( m_Parent->GetBoard()->GetLayerName( jj ) );
layer_list[ii]->SetLabel( m_Parent->GetBoard()->GetLayerName( layer ) );
// Change the text color to fuchsia (to highlight
// that this layer *is* being swapped)
......@@ -317,13 +321,13 @@ void WinEDA_SwapLayerFrame::Sel_Layer( wxCommandEvent& event )
}
void WinEDA_SwapLayerFrame::OnCancelClick( wxCommandEvent& event )
void SWAP_LAYERS_DIALOG::OnCancelClick( wxCommandEvent& event )
{
EndModal( -1 );
}
void WinEDA_SwapLayerFrame::OnOkClick( wxCommandEvent& event )
void SWAP_LAYERS_DIALOG::OnOkClick( wxCommandEvent& event )
{
EndModal( 1 );
}
......@@ -340,10 +344,9 @@ void PCB_EDIT_FRAME::Swap_Layers( wxCommandEvent& event )
for( ii = FIRST_LAYER; ii < NB_PCB_LAYERS; ii++ )
New_Layer[ii] = LAYER_NO_CHANGE;
WinEDA_SwapLayerFrame* frame = new WinEDA_SwapLayerFrame( this );
SWAP_LAYERS_DIALOG dlg( this );
ii = frame->ShowModal();
frame->Destroy();
ii = dlg.ShowModal();
if( ii != 1 )
return; // (Canceled dialog box returns -1 instead)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment