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