Commit dc982a28 authored by Dick Hollenbeck's avatar Dick Hollenbeck

++PCBNew

  * added BOARD::GetPad(int), made BOARD::m_NetInfo private, and contained
    within the BOARD, not dynamically allocated and owned via pointer.
  * added BOARD::GetPadCount()
  * changed NETINFO_LIST::GetCount() to GetNetCount()
  * added BOARD::GetNetCount()
  * more kicad_plugin work.
parents 2600bb31 4c2a1dd5
...@@ -17,8 +17,8 @@ install_manifest.txt ...@@ -17,8 +17,8 @@ install_manifest.txt
Documentation/doxygen Documentation/doxygen
*.cmake *.cmake
*.bak *.bak
pcbnew/pcb_plot_params_keywords.cpp common/pcb_plot_params_keywords.cpp
pcbnew/pcb_plot_params_lexer.h common/pcb_plot_params_lexer.h
pcbnew/specctra_keywords.cpp pcbnew/specctra_keywords.cpp
pcbnew/specctra_lexer.h pcbnew/specctra_lexer.h
new/html new/html
......
...@@ -4,6 +4,17 @@ KiCad ChangeLog 2011 ...@@ -4,6 +4,17 @@ KiCad ChangeLog 2011
Please add newer entries at the top, list the date and your name with Please add newer entries at the top, list the date and your name with
email address. email address.
2011-Dec-9 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================
++PCBNew
* added BOARD::GetPad(int), made BOARD::m_NetInfo private, and contained
within the BOARD, not dynamically allocated and owned via pointer.
* added BOARD::GetPadCount()
* changed NETINFO_LIST::GetCount() to GetNetCount()
* added BOARD::GetNetCount()
* more kicad_plugin work.
2011-Dec-5 UPDATE Dick Hollenbeck <dick@softplc.com> 2011-Dec-5 UPDATE Dick Hollenbeck <dick@softplc.com>
================================================================================ ================================================================================
++PCBNew ++PCBNew
......
...@@ -276,9 +276,13 @@ add_subdirectory(template) ...@@ -276,9 +276,13 @@ add_subdirectory(template)
#================================================ #================================================
find_package(Doxygen) find_package(Doxygen)
if(DOXYGEN_FOUND) if(DOXYGEN_FOUND)
add_custom_target( doxygen-docs ${DOXYGEN_EXECUTABLE} add_custom_target( doxygen-docs
${CMAKE_COMMAND} -E remove_directory Documentation/doxygen
COMMAND ${DOXYGEN_EXECUTABLE}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS Doxyfile ) DEPENDS Doxyfile
COMMENT "building doxygen docs into directory Documentation/doxygen/html"
)
else(DOXYGEN_FOUND) else(DOXYGEN_FOUND)
message( STATUS "WARNING: Doxygen not found - doxygen-docs (Source Docs) target not created" ) message( STATUS "WARNING: Doxygen not found - doxygen-docs (Source Docs) target not created" )
endif() endif()
......
...@@ -113,7 +113,7 @@ public: ...@@ -113,7 +113,7 @@ public:
* Function GetCount * Function GetCount
* returns the number of elements in the list. * returns the number of elements in the list.
*/ */
unsigned GetCount() { return count; } unsigned GetCount() const { return count; }
#if defined(DEBUG) #if defined(DEBUG)
void VerifyListIntegrity(); void VerifyListIntegrity();
......
...@@ -203,9 +203,9 @@ void PlaceCells( BOARD* aPcb, int net_code, int flag ) ...@@ -203,9 +203,9 @@ void PlaceCells( BOARD* aPcb, int net_code, int flag )
via_marge = clearance + (viaSize / 2); via_marge = clearance + (viaSize / 2);
// Place PADS on matrix routing: // Place PADS on matrix routing:
for( unsigned i = 0; i < aPcb->GetPadsCount(); ++i ) for( unsigned i = 0; i < aPcb->GetPadCount(); ++i )
{ {
D_PAD* pad = aPcb->m_NetInfo->GetPad( i ); D_PAD* pad = aPcb->GetPad( i );
if( net_code != pad->GetNet() || (flag & FORCE_PADS) ) if( net_code != pad->GetNet() || (flag & FORCE_PADS) )
{ {
......
...@@ -30,6 +30,7 @@ wxPoint BOARD_ITEM::ZeroOffset( 0, 0 ); ...@@ -30,6 +30,7 @@ wxPoint BOARD_ITEM::ZeroOffset( 0, 0 );
BOARD::BOARD() : BOARD::BOARD() :
BOARD_ITEM( (BOARD_ITEM*) NULL, PCB_T ), BOARD_ITEM( (BOARD_ITEM*) NULL, PCB_T ),
m_NetInfo( this ),
m_NetClasses( this ) m_NetClasses( this )
{ {
// we have not loaded a board yet, assume latest until then. // we have not loaded a board yet, assume latest until then.
...@@ -42,8 +43,8 @@ BOARD::BOARD() : ...@@ -42,8 +43,8 @@ BOARD::BOARD() :
m_CurrentZoneContour = NULL; // This ZONE_CONTAINER handle the m_CurrentZoneContour = NULL; // This ZONE_CONTAINER handle the
// zone contour currently in progress // zone contour currently in progress
m_NetInfo = new NETINFO_LIST( this ); // handle nets info list (name, design constraints ..
m_NetInfo->BuildListOfNets(); // prepare pads and nets lists containers. BuildListOfNets(); // prepare pad and netlist containers.
for( int layer = 0; layer < NB_COPPER_LAYERS; ++layer ) for( int layer = 0; layer < NB_COPPER_LAYERS; ++layer )
{ {
...@@ -89,8 +90,6 @@ BOARD::~BOARD() ...@@ -89,8 +90,6 @@ BOARD::~BOARD()
delete m_CurrentZoneContour; delete m_CurrentZoneContour;
m_CurrentZoneContour = NULL; m_CurrentZoneContour = NULL;
delete m_NetInfo;
} }
...@@ -814,25 +813,25 @@ void BOARD::DeleteZONEOutlines() ...@@ -814,25 +813,25 @@ void BOARD::DeleteZONEOutlines()
} }
int BOARD::GetNumSegmTrack() int BOARD::GetNumSegmTrack() const
{ {
return m_Track.GetCount(); return m_Track.GetCount();
} }
int BOARD::GetNumSegmZone() int BOARD::GetNumSegmZone() const
{ {
return m_Zone.GetCount(); return m_Zone.GetCount();
} }
unsigned BOARD::GetNoconnectCount() unsigned BOARD::GetNoconnectCount() const
{ {
return m_NbNoconnect; return m_NbNoconnect;
} }
unsigned BOARD::GetNodesCount() unsigned BOARD::GetNodesCount() const
{ {
return m_NbNodes; return m_NbNodes;
} }
...@@ -844,7 +843,7 @@ EDA_RECT BOARD::ComputeBoundingBox( bool aBoardEdgesOnly ) ...@@ -844,7 +843,7 @@ EDA_RECT BOARD::ComputeBoundingBox( bool aBoardEdgesOnly )
EDA_RECT area; EDA_RECT area;
// Check segments, dimensions, texts, and fiducials // Check segments, dimensions, texts, and fiducials
for( BOARD_ITEM* item = m_Drawings; item != NULL; item = item->Next() ) for( BOARD_ITEM* item = m_Drawings; item; item = item->Next() )
{ {
if( aBoardEdgesOnly && (item->Type() != PCB_LINE_T || item->GetLayer() != EDGE_N ) ) if( aBoardEdgesOnly && (item->Type() != PCB_LINE_T || item->GetLayer() != EDGE_N ) )
continue; continue;
...@@ -931,7 +930,7 @@ void BOARD::DisplayInfo( EDA_DRAW_FRAME* frame ) ...@@ -931,7 +930,7 @@ void BOARD::DisplayInfo( EDA_DRAW_FRAME* frame )
trackSegmentsCount++; trackSegmentsCount++;
} }
txt.Printf( wxT( "%d" ), GetPadsCount() ); txt.Printf( wxT( "%d" ), GetPadCount() );
frame->AppendMsgPanel( _( "Pads" ), txt, DARKGREEN ); frame->AppendMsgPanel( _( "Pads" ), txt, DARKGREEN );
txt.Printf( wxT( "%d" ), viasCount ); txt.Printf( wxT( "%d" ), viasCount );
...@@ -943,7 +942,7 @@ void BOARD::DisplayInfo( EDA_DRAW_FRAME* frame ) ...@@ -943,7 +942,7 @@ void BOARD::DisplayInfo( EDA_DRAW_FRAME* frame )
txt.Printf( wxT( "%d" ), GetNodesCount() ); txt.Printf( wxT( "%d" ), GetNodesCount() );
frame->AppendMsgPanel( _( "Nodes" ), txt, DARKCYAN ); frame->AppendMsgPanel( _( "Nodes" ), txt, DARKCYAN );
txt.Printf( wxT( "%d" ), m_NetInfo->GetCount() ); txt.Printf( wxT( "%d" ), m_NetInfo.GetNetCount() );
frame->AppendMsgPanel( _( "Nets" ), txt, RED ); frame->AppendMsgPanel( _( "Nets" ), txt, RED );
/* These parameters are known only if the full ratsnest is available, /* These parameters are known only if the full ratsnest is available,
...@@ -1229,10 +1228,10 @@ SEARCH_RESULT BOARD::Visit( INSPECTOR* inspector, const void* testData, ...@@ -1229,10 +1228,10 @@ SEARCH_RESULT BOARD::Visit( INSPECTOR* inspector, const void* testData,
NETINFO_ITEM* BOARD::FindNet( int aNetcode ) const NETINFO_ITEM* BOARD::FindNet( int aNetcode ) const
{ {
// the first valid netcode is 1 and the last is m_NetInfo->GetCount()-1. // the first valid netcode is 1 and the last is m_NetInfo.GetCount()-1.
// zero is reserved for "no connection" and is not used. // zero is reserved for "no connection" and is not used.
// NULL is returned for non valid netcodes // NULL is returned for non valid netcodes
NETINFO_ITEM* net = m_NetInfo->GetNetItem( aNetcode ); NETINFO_ITEM* net = m_NetInfo.GetNetItem( aNetcode );
#if defined(DEBUG) #if defined(DEBUG)
if( net ) // item can be NULL if anetcode is not valid if( net ) // item can be NULL if anetcode is not valid
...@@ -1256,7 +1255,7 @@ NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname ) const ...@@ -1256,7 +1255,7 @@ NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname ) const
if( aNetname.IsEmpty() ) if( aNetname.IsEmpty() )
return NULL; return NULL;
int ncount = m_NetInfo->GetCount(); int ncount = m_NetInfo.GetNetCount();
// Search for a netname = aNetname // Search for a netname = aNetname
#if 0 #if 0
...@@ -1264,7 +1263,7 @@ NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname ) const ...@@ -1264,7 +1263,7 @@ NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname ) const
// Use a sequential search: easy to understand, but slow // Use a sequential search: easy to understand, but slow
for( int ii = 1; ii < ncount; ii++ ) for( int ii = 1; ii < ncount; ii++ )
{ {
NETINFO_ITEM* item = m_NetInfo->GetNetItem( ii ); NETINFO_ITEM* item = m_NetInfo.GetNetItem( ii );
if( item && item->GetNetname() == aNetname ) if( item && item->GetNetname() == aNetname )
{ {
...@@ -1289,7 +1288,7 @@ NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname ) const ...@@ -1289,7 +1288,7 @@ NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname ) const
if( (ii & 1) && ( ii > 1 ) ) if( (ii & 1) && ( ii > 1 ) )
ncount++; ncount++;
NETINFO_ITEM* item = m_NetInfo->GetNetItem( index ); NETINFO_ITEM* item = m_NetInfo.GetNetItem( index );
if( item == NULL ) if( item == NULL )
return NULL; return NULL;
...@@ -1370,18 +1369,18 @@ static bool s_SortByNodes( const NETINFO_ITEM* a, const NETINFO_ITEM* b ) ...@@ -1370,18 +1369,18 @@ static bool s_SortByNodes( const NETINFO_ITEM* a, const NETINFO_ITEM* b )
int BOARD::ReturnSortedNetnamesList( wxArrayString& aNames, bool aSortbyPadsCount ) int BOARD::ReturnSortedNetnamesList( wxArrayString& aNames, bool aSortbyPadsCount )
{ {
if( m_NetInfo->GetCount() == 0 ) if( m_NetInfo.GetNetCount() == 0 )
return 0; return 0;
// Build the list // Build the list
std::vector <NETINFO_ITEM*> netBuffer; std::vector <NETINFO_ITEM*> netBuffer;
netBuffer.reserve( m_NetInfo->GetCount() ); netBuffer.reserve( m_NetInfo.GetNetCount() );
for( unsigned ii = 1; ii < m_NetInfo->GetCount(); ii++ ) for( unsigned ii = 1; ii < m_NetInfo.GetNetCount(); ii++ )
{ {
if( m_NetInfo->GetNetItem( ii )->GetNet() > 0 ) if( m_NetInfo.GetNetItem( ii )->GetNet() > 0 )
netBuffer.push_back( m_NetInfo->GetNetItem( ii ) ); netBuffer.push_back( m_NetInfo.GetNetItem( ii ) );
} }
// sort the list // sort the list
...@@ -1561,9 +1560,9 @@ D_PAD* BOARD::GetPad( TRACK* aTrace, int aEndPoint ) ...@@ -1561,9 +1560,9 @@ D_PAD* BOARD::GetPad( TRACK* aTrace, int aEndPoint )
D_PAD* BOARD::GetPadFast( const wxPoint& aPosition, int aLayerMask ) D_PAD* BOARD::GetPadFast( const wxPoint& aPosition, int aLayerMask )
{ {
for( unsigned i=0; i<GetPadsCount(); ++i ) for( unsigned i=0; i<GetPadCount(); ++i )
{ {
D_PAD* pad = m_NetInfo->GetPad(i); D_PAD* pad = m_NetInfo.GetPad(i);
if( pad->m_Pos != aPosition ) if( pad->m_Pos != aPosition )
continue; continue;
...@@ -1675,8 +1674,8 @@ static bool sortPadsByXthenYCoord( D_PAD* const & ref, D_PAD* const & comp ) ...@@ -1675,8 +1674,8 @@ static bool sortPadsByXthenYCoord( D_PAD* const & ref, D_PAD* const & comp )
void BOARD::GetSortedPadListByXthenYCoord( std::vector<D_PAD*>& aVector ) void BOARD::GetSortedPadListByXthenYCoord( std::vector<D_PAD*>& aVector )
{ {
aVector.insert( aVector.end(), m_NetInfo->m_PadsFullList.begin(), aVector.insert( aVector.end(), m_NetInfo.m_PadsFullList.begin(),
m_NetInfo->m_PadsFullList.end() ); m_NetInfo.m_PadsFullList.end() );
sort( aVector.begin(), aVector.end(), sortPadsByXthenYCoord ); sort( aVector.begin(), aVector.end(), sortPadsByXthenYCoord );
} }
......
...@@ -38,7 +38,8 @@ typedef std::vector< TRACK* > TRACK_PTRS; ...@@ -38,7 +38,8 @@ typedef std::vector< TRACK* > TRACK_PTRS;
* Enum LAYER_T * Enum LAYER_T
* gives the allowed types of layers, same as Specctra DSN spec. * gives the allowed types of layers, same as Specctra DSN spec.
*/ */
enum LAYER_T { enum LAYER_T
{
LT_SIGNAL, LT_SIGNAL,
LT_POWER, LT_POWER,
LT_MIXED, LT_MIXED,
...@@ -169,6 +170,23 @@ private: ...@@ -169,6 +170,23 @@ private:
EDA_RECT m_BoundingBox; EDA_RECT m_BoundingBox;
NETINFO_LIST m_NetInfo; ///< net info list (name, design constraints ..
BOARD_DESIGN_SETTINGS m_designSettings;
COLORS_DESIGN_SETTINGS* m_colorsSettings; // Link to current colors settings
/**
* Function chainMarkedSegments
* is used by MarkTrace() to set the BUSY flag of connected segments of the trace
* segment located at \a aPosition on aLayerMask.
* Vias are put in list but their flags BUSY is not set
* @param aPosition A wxPoint object containing the position of the starting search.
* @param aLayerMask The allowed layers for segments to search.
* @param aList The track list to fill with points of flagged segments.
*/
void chainMarkedSegments( wxPoint aPosition, int aLayerMask, TRACK_PTRS* aList );
public: public:
/// Flags used in ratsnest calculation and update. /// Flags used in ratsnest calculation and update.
...@@ -185,9 +203,6 @@ public: ...@@ -185,9 +203,6 @@ public:
DLIST<TRACK> m_Track; // linked list of TRACKs and SEGVIAs DLIST<TRACK> m_Track; // linked list of TRACKs and SEGVIAs
DLIST<SEGZONE> m_Zone; // linked list of SEGZONEs DLIST<SEGZONE> m_Zone; // linked list of SEGZONEs
/// nets info list (name, design constraints ..
NETINFO_LIST* m_NetInfo;
/// Ratsnest list for the BOARD /// Ratsnest list for the BOARD
std::vector<RATSNEST_ITEM> m_FullRatsnest; std::vector<RATSNEST_ITEM> m_FullRatsnest;
...@@ -223,22 +238,7 @@ public: ...@@ -223,22 +238,7 @@ public:
// Index for m_TrackWidthList to select the value. // Index for m_TrackWidthList to select the value.
unsigned m_TrackWidthSelector; unsigned m_TrackWidthSelector;
private:
BOARD_DESIGN_SETTINGS m_designSettings;
COLORS_DESIGN_SETTINGS* m_colorsSettings; // Link to current colors settings
/**
* Function chainMarkedSegments
* is used by MarkTrace() to set the BUSY flag of connected segments of the trace
* segment located at \a aPosition on aLayerMask.
* Vias are put in list but their flags BUSY is not set
* @param aPosition A wxPoint object containing the position of the starting search.
* @param aLayerMask The allowed layers for segments to search.
* @param aList The track list to fill with points of flagged segments.
*/
void chainMarkedSegments( wxPoint aPosition, int aLayerMask, TRACK_PTRS* aList );
public:
BOARD(); BOARD();
~BOARD(); ~BOARD();
...@@ -310,7 +310,6 @@ public: ...@@ -310,7 +310,6 @@ public:
*/ */
void DeleteZONEOutlines(); void DeleteZONEOutlines();
/** /**
* Function GetMARKER * Function GetMARKER
* returns the MARKER at a given index. * returns the MARKER at a given index.
...@@ -325,7 +324,6 @@ public: ...@@ -325,7 +324,6 @@ public:
return NULL; return NULL;
} }
/** /**
* Function GetMARKERCount * Function GetMARKERCount
* @return int - The number of MARKER_PCBS. * @return int - The number of MARKER_PCBS.
...@@ -335,7 +333,6 @@ public: ...@@ -335,7 +333,6 @@ public:
return (int) m_markers.size(); return (int) m_markers.size();
} }
/** /**
* Function ResetHighLight * Function ResetHighLight
* Reset all high light data to the init state * Reset all high light data to the init state
...@@ -361,7 +358,6 @@ public: ...@@ -361,7 +358,6 @@ public:
m_hightLight.m_netCode = aNetCode; m_hightLight.m_netCode = aNetCode;
} }
/** /**
* Function IsHighLightNetON * Function IsHighLightNetON
* @return true if a net is currently highlighted * @return true if a net is currently highlighted
...@@ -610,19 +606,19 @@ public: ...@@ -610,19 +606,19 @@ public:
*/ */
int GetLayerColor( int aLayer ); int GetLayerColor( int aLayer );
/* Functions to get some items count */ /** Functions to get some items count */
int GetNumSegmTrack(); int GetNumSegmTrack() const;
/* Calculate the zone segment count */ /** Calculate the zone segment count */
int GetNumSegmZone(); int GetNumSegmZone() const;
unsigned GetNoconnectCount(); // Return the number of missing links. unsigned GetNoconnectCount() const; // Return the number of missing links.
/** /**
* Function GetNumRatsnests * Function GetNumRatsnests
* @return int - The number of rats * @return int - The number of rats
*/ */
unsigned GetRatsnestsCount() unsigned GetRatsnestsCount() const
{ {
return m_FullRatsnest.size(); return m_FullRatsnest.size();
} }
...@@ -632,15 +628,71 @@ public: ...@@ -632,15 +628,71 @@ public:
* Function GetNodesCount * Function GetNodesCount
* @return the number of pads members of nets (i.e. with netcode > 0) * @return the number of pads members of nets (i.e. with netcode > 0)
*/ */
unsigned GetNodesCount(); unsigned GetNodesCount() const;
/** /**
* Function GetPadsCount * Function GetPadCount
* @return the number of pads in board * @return the number of pads in board
*/ */
unsigned GetPadsCount() unsigned GetPadCount() const
{
return m_NetInfo.GetPadCount();
}
/**
* Function GetPad
* @return D_PAD* - at the \a aIndex from m_NetInfo
*/
D_PAD* GetPad( unsigned aIndex ) const
{
return m_NetInfo.GetPad( aIndex );
}
/**
* Function GetPads
* returns a list of all the pads by value. The returned list is not
* sorted and contains pointers to PADS, but those pointers do not convey
* ownership of the respective PADs.
* @return std::vector<D_PAD*> - a full list of pads
*/
std::vector<D_PAD*> GetPads()
{
return m_NetInfo.m_PadsFullList;
}
void BuildListOfNets()
{
m_NetInfo.buildListOfNets();
}
/**
* Function FindNet
* searches for a net with the given netcode.
* @param aNetcode A netcode to search for.
* @return NETINFO_ITEM_ITEM* - the net or NULL if not found.
*/
NETINFO_ITEM* FindNet( int aNetcode ) const;
/**
* Function FindNet overloaded
* searches for a net with the given name.
* @param aNetname A Netname to search for.
* @return NETINFO_ITEM* - the net or NULL if not found.
*/
NETINFO_ITEM* FindNet( const wxString& aNetname ) const;
void AppendNet( NETINFO_ITEM* aNewNet )
{
m_NetInfo.AppendNet( aNewNet );
}
/**
* Function GetNetCount
* @return the number of nets (NETINFO_ITEM)
*/
unsigned GetNetCount() const
{ {
return m_NetInfo->GetPadsCount(); return m_NetInfo.GetNetCount();
} }
/** /**
...@@ -709,23 +761,6 @@ public: ...@@ -709,23 +761,6 @@ public:
SEARCH_RESULT Visit( INSPECTOR* inspector, const void* testData, SEARCH_RESULT Visit( INSPECTOR* inspector, const void* testData,
const KICAD_T scanTypes[] ); const KICAD_T scanTypes[] );
/**
* Function FindNet
* searches for a net with the given netcode.
* @param aNetcode A netcode to search for.
* @return NETINFO_ITEM_ITEM* - the net or NULL if not found.
*/
NETINFO_ITEM* FindNet( int aNetcode ) const;
/**
* Function FindNet overloaded
* searches for a net with the given name.
* @param aNetname A Netname to search for.
* @return NETINFO_ITEM* - the net or NULL if not found.
*/
NETINFO_ITEM* FindNet( const wxString& aNetname ) const;
/** /**
* Function FindModuleByReference * Function FindModuleByReference
* searches for a MODULE within this board with the given * searches for a MODULE within this board with the given
...@@ -787,7 +822,6 @@ public: ...@@ -787,7 +822,6 @@ public:
return m_TrackWidthList[m_TrackWidthSelector]; return m_TrackWidthList[m_TrackWidthSelector];
} }
/** /**
* Function GetCurrentViaSize * Function GetCurrentViaSize
* @return the current via size, according to the selected options * @return the current via size, according to the selected options
...@@ -799,7 +833,6 @@ public: ...@@ -799,7 +833,6 @@ public:
return m_ViasDimensionsList[m_ViaSizeSelector].m_Diameter; return m_ViasDimensionsList[m_ViaSizeSelector].m_Diameter;
} }
/** /**
* Function GetCurrentViaDrill * Function GetCurrentViaDrill
* @return the current via size, according to the selected options * @return the current via size, according to the selected options
...@@ -837,7 +870,6 @@ public: ...@@ -837,7 +870,6 @@ public:
*/ */
bool Save( FILE* aFile ) const; bool Save( FILE* aFile ) const;
/** /**
* Function GetClass * Function GetClass
* returns the class name. * returns the class name.
...@@ -848,7 +880,6 @@ public: ...@@ -848,7 +880,6 @@ public:
return wxT( "BOARD" ); return wxT( "BOARD" );
} }
#if defined(DEBUG) #if defined(DEBUG)
/** /**
...@@ -922,7 +953,6 @@ public: ...@@ -922,7 +953,6 @@ public:
return NULL; return NULL;
} }
/** /**
* Function GetAreaIndex * Function GetAreaIndex
* returns the Area Index for the given Zone Container. * returns the Area Index for the given Zone Container.
...@@ -940,7 +970,6 @@ public: ...@@ -940,7 +970,6 @@ public:
return -1; return -1;
} }
/** /**
* Function GetAreaCount * Function GetAreaCount
* @return int - The number of Areas or ZONE_CONTAINER. * @return int - The number of Areas or ZONE_CONTAINER.
...@@ -950,7 +979,6 @@ public: ...@@ -950,7 +979,6 @@ public:
return (int) m_ZoneDescriptorList.size(); return (int) m_ZoneDescriptorList.size();
} }
/* Functions used in test, merge and cut outlines */ /* Functions used in test, merge and cut outlines */
/** /**
...@@ -1196,7 +1224,6 @@ public: ...@@ -1196,7 +1224,6 @@ public:
*/ */
void GetSortedPadListByXthenYCoord( std::vector<D_PAD*>& aVector ); void GetSortedPadListByXthenYCoord( std::vector<D_PAD*>& aVector );
/** /**
* Function GetTrace * Function GetTrace
* find the segment of \a aTrace at \a aPosition on \a aLayer if \a Layer is visible. * find the segment of \a aTrace at \a aPosition on \a aLayer if \a Layer is visible.
......
...@@ -195,7 +195,7 @@ void BOARD::SynchronizeNetsAndNetClasses() ...@@ -195,7 +195,7 @@ void BOARD::SynchronizeNetsAndNetClasses()
// set all NETs to the default NETCLASS, then later override some // set all NETs to the default NETCLASS, then later override some
// as we go through the NETCLASSes. // as we go through the NETCLASSes.
int count = m_NetInfo->GetCount(); int count = m_NetInfo.GetNetCount();
for( int i=0; i<count; ++i ) for( int i=0; i<count; ++i )
{ {
NETINFO_ITEM* net = FindNet( i ); NETINFO_ITEM* net = FindNet( i );
......
...@@ -26,7 +26,6 @@ class BOARD; ...@@ -26,7 +26,6 @@ class BOARD;
class BOARD_ITEM; class BOARD_ITEM;
/* Class RATSNEST_ITEM: describes a ratsnest line: a straight line connecting 2 pads */
/*****************************/ /*****************************/
/* flags for a RATSNEST_ITEM */ /* flags for a RATSNEST_ITEM */
...@@ -37,6 +36,11 @@ class BOARD_ITEM; ...@@ -37,6 +36,11 @@ class BOARD_ITEM;
#define CH_ACTIF 8 /* Not routed. */ #define CH_ACTIF 8 /* Not routed. */
#define LOCAL_RATSNEST_ITEM 0x8000 /* Line between two pads of a single module. */ #define LOCAL_RATSNEST_ITEM 0x8000 /* Line between two pads of a single module. */
/**
* Class RATSNEST_ITEM
* describes a ratsnest line: a straight line connecting 2 pads
*/
class RATSNEST_ITEM class RATSNEST_ITEM
{ {
private: private:
...@@ -59,7 +63,6 @@ public: ...@@ -59,7 +63,6 @@ public:
return m_NetCode; return m_NetCode;
} }
void SetNet( int aNetCode ) void SetNet( int aNetCode )
{ {
m_NetCode = aNetCode; m_NetCode = aNetCode;
...@@ -87,37 +90,38 @@ public: ...@@ -87,37 +90,38 @@ public:
}; };
/***************************************************************/
/******************* class NETINFO *****************************/
/***************************************************************/
/**
* Class NETINFO
* is a container class for NETINFO_ITEM elements, which are the nets. That makes
* this class a container for the nets.
*/
class NETINFO_LIST class NETINFO_LIST
{ {
private: friend class BOARD;
BOARD* m_Parent;
std::vector<NETINFO_ITEM*> m_NetBuffer; // nets buffer list (name, design constraints ..
public: public:
std::vector<D_PAD*> m_PadsFullList; // Entry for a sorted pad list (used in ratsnest NETINFO_LIST( BOARD* aParent );
// calculations)
public: NETINFO_LIST( BOARD* aParent );
~NETINFO_LIST(); ~NETINFO_LIST();
/** /**
* Function GetItem * Function GetItem
* @param aNetcode = netcode to identify a given NETINFO_ITEM * @param aNetcode = netcode to identify a given NETINFO_ITEM
* @return a NETINFO_ITEM pointer to the selected NETINFO_ITEM by its * @return NETINFO_ITEM* - by \a aNetcode, or NULL if not found
* netcode, or NULL if not found
*/ */
NETINFO_ITEM* GetNetItem( int aNetcode ); NETINFO_ITEM* GetNetItem( int aNetcode ) const
{
if( unsigned( aNetcode ) >= GetNetCount() ) // catches < 0 too
return NULL;
return m_NetBuffer[aNetcode];
}
/** /**
* Function GetCount * Function GetNetCount
* @return the number of nets ( always >= 1 ) * @return the number of nets ( always >= 1 )
* becuse the first net is the "not connected" net and always exists * because the first net is the "not connected" net and always exists
*/ */
unsigned GetCount() { return m_NetBuffer.size(); } unsigned GetNetCount() const { return m_NetBuffer.size(); }
/** /**
* Function Append * Function Append
...@@ -126,33 +130,28 @@ public: NETINFO_LIST( BOARD* aParent ); ...@@ -126,33 +130,28 @@ public: NETINFO_LIST( BOARD* aParent );
void AppendNet( NETINFO_ITEM* aNewElement ); void AppendNet( NETINFO_ITEM* aNewElement );
/** /**
* Function DeleteData * Function GetPadCount
* delete the list of nets (and free memory) * @return the number of pads in board
*/
void DeleteData();
/**
* Function BuildListOfNets
* Build or rebuild the list of NETINFO_ITEM m_NetBuffer
* The list is sorted by names.
*/ */
void BuildListOfNets(); unsigned GetPadCount() const { return m_PadsFullList.size(); }
/** /**
* Function GetPadsCount * Function GetPads
* @return the number of pads in board * returns a list of all the pads. The returned list is not
*/ * sorted and contains pointers to PADS, but those pointers do not convey
unsigned GetPadsCount() * ownership of the respective PADs.
* @return std::vector<D_PAD*>& - a full list of pads
std::vector<D_PAD*>& GetPads()
{ {
return m_PadsFullList.size(); return m_PadsFullList;
} }
*/
/** /**
* Function GetPad * Function GetPad
* @return the pad idx from m_PadsFullList * @return the pad idx from m_PadsFullList
*/ */
D_PAD* GetPad( unsigned aIdx ) D_PAD* GetPad( unsigned aIdx ) const
{ {
if( aIdx < m_PadsFullList.size() ) if( aIdx < m_PadsFullList.size() )
return m_PadsFullList[aIdx]; return m_PadsFullList[aIdx];
...@@ -160,19 +159,36 @@ public: NETINFO_LIST( BOARD* aParent ); ...@@ -160,19 +159,36 @@ public: NETINFO_LIST( BOARD* aParent );
return NULL; return NULL;
} }
private: private:
/** /**
* Function Build_Pads_Full_List * Function DeleteData
* Create the pad list * deletes the list of nets (and free memory)
* initialise: */
void clear();
/**
* Function BuildListOfNets
* builds or rebuilds the list of NETINFO_ITEMs
* The list is sorted by names.
*/
void buildListOfNets();
/**
* Function buildPadsFullList
* creates the pad list, and initializes:
* m_Pads (list of pads) * m_Pads (list of pads)
* set m_Status_Pcb = LISTE_PAD_OK; * set m_Status_Pcb = LISTE_PAD_OK;
* and clear for all pads in list the m_SubRatsnest member; * and clear for all pads in list the m_SubRatsnest member;
* clear m_Pcb->m_FullRatsnest * clear m_Pcb->m_FullRatsnest
*/ */
void Build_Pads_Full_List(); void buildPadsFullList();
BOARD* m_Parent;
std::vector<NETINFO_ITEM*> m_NetBuffer; ///< net list (name, design constraints ..)
std::vector<D_PAD*> m_PadsFullList; ///< contains all pads, sorted by pad's netname.
///< can be used in ratsnest calculations.
}; };
...@@ -183,11 +199,11 @@ private: ...@@ -183,11 +199,11 @@ private:
class NETINFO_ITEM class NETINFO_ITEM
{ {
private: private:
int m_NetCode; // this is a number equivalent to the net name int m_NetCode; ///< A number equivalent to the net name.
// Used for fast comparisons in ratsnest and DRC computations. ///< Used for fast comparisons in ratsnest and DRC computations.
wxString m_Netname; // Full net name like /mysheet/mysubsheet/vout wxString m_Netname; ///< Full net name like /mysheet/mysubsheet/vout
// used by Eeschema ///< used by Eeschema
wxString m_ShortNetname; // short net name, like vout from wxString m_ShortNetname; // short net name, like vout from
// /mysheet/mysubsheet/vout // /mysheet/mysubsheet/vout
...@@ -233,13 +249,11 @@ public: ...@@ -233,13 +249,11 @@ public:
m_NetClassName = NETCLASS::Default; m_NetClassName = NETCLASS::Default;
} }
NETCLASS* GetNetClass() NETCLASS* GetNetClass()
{ {
return m_NetClass; return m_NetClass;
} }
/** /**
* Function GetClassName * Function GetClassName
* returns the class name * returns the class name
...@@ -249,7 +263,6 @@ public: ...@@ -249,7 +263,6 @@ public:
return m_NetClassName; return m_NetClassName;
} }
#if 1 #if 1
/** /**
...@@ -272,7 +285,6 @@ public: ...@@ -272,7 +285,6 @@ public:
return m_NetClass->GetViaDiameter(); return m_NetClass->GetViaDiameter();
} }
/** /**
* Function GetMicroViaSize * Function GetMicroViaSize
* returns the size of vias used to route this net * returns the size of vias used to route this net
...@@ -283,7 +295,6 @@ public: ...@@ -283,7 +295,6 @@ public:
return m_NetClass->GetuViaDiameter(); return m_NetClass->GetuViaDiameter();
} }
/** /**
* Function GetViaDrillSize * Function GetViaDrillSize
* returns the size of via drills used to route this net * returns the size of via drills used to route this net
...@@ -294,7 +305,6 @@ public: ...@@ -294,7 +305,6 @@ public:
return m_NetClass->GetViaDrill(); return m_NetClass->GetViaDrill();
} }
/** /**
* Function GetViaDrillSize * Function GetViaDrillSize
* returns the size of via drills used to route this net * returns the size of via drills used to route this net
...@@ -318,7 +328,6 @@ public: ...@@ -318,7 +328,6 @@ public:
return m_NetClass->GetViaMinSize(); return m_NetClass->GetViaMinSize();
} }
#endif #endif
/** /**
...@@ -331,7 +340,6 @@ public: ...@@ -331,7 +340,6 @@ public:
return m_NetClass->GetClearance(); return m_NetClass->GetClearance();
} }
#endif #endif
/* Reading and writing data on files */ /* Reading and writing data on files */
...@@ -346,7 +354,6 @@ public: ...@@ -346,7 +354,6 @@ public:
*/ */
bool Save( FILE* aFile ) const; bool Save( FILE* aFile ) const;
/** /**
* Function Draw * Function Draw
* @todo we actually could show a NET, simply show all the tracks and * @todo we actually could show a NET, simply show all the tracks and
...@@ -354,7 +361,6 @@ public: ...@@ -354,7 +361,6 @@ public:
*/ */
void Draw( EDA_DRAW_PANEL* panel, wxDC* DC, int aDrawMode, const wxPoint& offset ); void Draw( EDA_DRAW_PANEL* panel, wxDC* DC, int aDrawMode, const wxPoint& offset );
/** /**
* Function GetNet * Function GetNet
* @return int - the netcode * @return int - the netcode
...@@ -383,14 +389,13 @@ public: ...@@ -383,14 +389,13 @@ public:
*/ */
void SetNetname( const wxString& aNetname ); void SetNetname( const wxString& aNetname );
/**
/** * Function DisplayInfo
* Function DisplayInfo * has knowledge about the frame and how and where to put status information
* has knowledge about the frame and how and where to put status information * about this object into the frame's message panel.
* about this object into the frame's message panel. * Is virtual from EDA_ITEM.
* Is virtual from EDA_ITEM. * @param frame A EDA_DRAW_FRAME in which to print status information.
* @param frame A EDA_DRAW_FRAME in which to print status information. */
*/
void DisplayInfo( EDA_DRAW_FRAME* frame ); void DisplayInfo( EDA_DRAW_FRAME* frame );
}; };
......
...@@ -140,7 +140,6 @@ void NETINFO_ITEM::DisplayInfo( EDA_DRAW_FRAME* frame ) ...@@ -140,7 +140,6 @@ void NETINFO_ITEM::DisplayInfo( EDA_DRAW_FRAME* frame )
// Displays the net lenght of internal ICs connections (wires inside ICs): // Displays the net lenght of internal ICs connections (wires inside ICs):
txt = frame->CoordinateToString( lengthdie ); txt = frame->CoordinateToString( lengthdie );
frame->AppendMsgPanel( _( "On Die" ), txt, RED ); frame->AppendMsgPanel( _( "On Die" ), txt, RED );
} }
...@@ -170,7 +169,9 @@ void RATSNEST_ITEM::Draw( EDA_DRAW_PANEL* panel, ...@@ -170,7 +169,9 @@ void RATSNEST_ITEM::Draw( EDA_DRAW_PANEL* panel,
const wxPoint& aOffset ) const wxPoint& aOffset )
{ {
GRSetDrawMode( DC, aDrawMode ); GRSetDrawMode( DC, aDrawMode );
int color = g_ColorsSettings.GetItemColor(RATSNEST_VISIBLE); int color = g_ColorsSettings.GetItemColor(RATSNEST_VISIBLE);
GRLine( &panel->m_ClipBox, DC, m_PadStart->m_Pos - aOffset, GRLine( &panel->m_ClipBox, DC, m_PadStart->m_Pos - aOffset,
m_PadEnd->m_Pos - aOffset, 0, color ); m_PadEnd->m_Pos - aOffset, 0, color );
} }
...@@ -23,31 +23,13 @@ NETINFO_LIST::NETINFO_LIST( BOARD* aParent ) ...@@ -23,31 +23,13 @@ NETINFO_LIST::NETINFO_LIST( BOARD* aParent )
NETINFO_LIST::~NETINFO_LIST() NETINFO_LIST::~NETINFO_LIST()
{ {
DeleteData(); clear();
} }
/** void NETINFO_LIST::clear()
* Function GetItem
* @param aNetcode = netcode to identify a given NETINFO_ITEM
* @return a NETINFO_ITEM pointer to the selected NETINFO_ITEM by its netcode, or NULL if not found
*/
NETINFO_ITEM* NETINFO_LIST::GetNetItem( int aNetcode )
{ {
if( aNetcode < 0 || ( aNetcode > (int) ( GetCount() - 1 ) ) ) for( unsigned ii = 0; ii < GetNetCount(); ii++ )
return NULL;
return m_NetBuffer[aNetcode];
}
/**
* Function DeleteData
* delete the list of nets (and free memory)
*/
void NETINFO_LIST::DeleteData()
{
for( unsigned ii = 0; ii < GetCount(); ii++ )
delete m_NetBuffer[ii]; delete m_NetBuffer[ii];
m_NetBuffer.clear(); m_NetBuffer.clear();
...@@ -72,7 +54,7 @@ void NETINFO_LIST::AppendNet( NETINFO_ITEM* aNewElement ) ...@@ -72,7 +54,7 @@ void NETINFO_LIST::AppendNet( NETINFO_ITEM* aNewElement )
* and expects to have a nets list sorted by an alphabetic case sensitive sort * and expects to have a nets list sorted by an alphabetic case sensitive sort
*/ */
static bool PadlistSortByNetnames( const D_PAD* a, const D_PAD* b ) static bool padlistSortByNetnames( const D_PAD* a, const D_PAD* b )
{ {
return ( a->GetNetname().Cmp( b->GetNetname() ) ) < 0; return ( a->GetNetname().Cmp( b->GetNetname() ) ) < 0;
} }
...@@ -90,23 +72,23 @@ static bool PadlistSortByNetnames( const D_PAD* a, const D_PAD* b ) ...@@ -90,23 +72,23 @@ static bool PadlistSortByNetnames( const D_PAD* a, const D_PAD* b )
* and expects to have a nets list sorted by an alphabetic case sensitive sort * and expects to have a nets list sorted by an alphabetic case sensitive sort
* So do not change Build_Pads_Full_List() taht build a sorted list of pads * So do not change Build_Pads_Full_List() taht build a sorted list of pads
*/ */
void NETINFO_LIST::BuildListOfNets() void NETINFO_LIST::buildListOfNets()
{ {
D_PAD* pad; D_PAD* pad;
int nodes_count = 0; int nodes_count = 0;
NETINFO_ITEM* net_item; NETINFO_ITEM* net_item;
DeleteData(); // Remove all nets info and free memory clear(); // Remove all nets info and free memory
// Create and add the "unconnected net", always existing, // Create and add the "unconnected net", always existing,
// used to handle pads and tracks that are not member of a "real" net // used to handle pads and tracks that are not member of a "real" net
net_item = new NETINFO_ITEM( (BOARD_ITEM*) m_Parent ); net_item = new NETINFO_ITEM( (BOARD_ITEM*) m_Parent );
AppendNet( net_item ); AppendNet( net_item );
/* Build the PAD list, sorted by net */ // Build the PAD list, sorted by net
Build_Pads_Full_List(); buildPadsFullList();
/* Build netnames list, and create a netcode for each netname */ // Build netnames list, and create a netcode for each netname
D_PAD* last_pad = NULL; D_PAD* last_pad = NULL;
int netcode = 0; int netcode = 0;
...@@ -158,21 +140,20 @@ void NETINFO_LIST::BuildListOfNets() ...@@ -158,21 +140,20 @@ void NETINFO_LIST::BuildListOfNets()
} }
/** void NETINFO_LIST::buildPadsFullList()
* Function Build_Pads_Full_List
* Create the pad list, sorted by net names (sorted by an alphabetic case sensitive sort)
* initialise:
* m_Pads (list of pads)
* set m_Status_Pcb = LISTE_PAD_OK;
* also clear m_Pcb->m_FullRatsnest that could have bad data
* (m_Pcb->m_FullRatsnest uses pointer to pads)
* Be aware NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname )
* when search a net by its net name does a binary search
* and expects to have a nets list sorted by an alphabetic case sensitive sort
* So do not change the sort function used here
*/
void NETINFO_LIST::Build_Pads_Full_List()
{ {
/*
* initialize:
* m_Pads (list of pads)
* set m_Status_Pcb = LISTE_PAD_OK;
* also clear m_Pcb->m_FullRatsnest that could have bad data
* (m_Pcb->m_FullRatsnest uses pointer to pads)
* Be aware NETINFO_ITEM* BOARD::FindNet( const wxString& aNetname )
* when search a net by its net name does a binary search
* and expects to have a nets list sorted by an alphabetic case sensitive sort
* So do not change the sort function used here
*/
if( m_Parent->m_Status_Pcb & LISTE_PAD_OK ) if( m_Parent->m_Status_Pcb & LISTE_PAD_OK )
return; return;
...@@ -180,7 +161,7 @@ void NETINFO_LIST::Build_Pads_Full_List() ...@@ -180,7 +161,7 @@ void NETINFO_LIST::Build_Pads_Full_List()
m_PadsFullList.clear(); m_PadsFullList.clear();
m_Parent->m_FullRatsnest.clear(); m_Parent->m_FullRatsnest.clear();
/* Clear variables used in rastnest computation */ // Clear variables used in ratsnest computation
for( MODULE* module = m_Parent->m_Modules; module; module = module->Next() ) for( MODULE* module = m_Parent->m_Modules; module; module = module->Next() )
{ {
for( D_PAD* pad = module->m_Pads; pad; pad = pad->Next() ) for( D_PAD* pad = module->m_Pads; pad; pad = pad->Next() )
...@@ -193,8 +174,7 @@ void NETINFO_LIST::Build_Pads_Full_List() ...@@ -193,8 +174,7 @@ void NETINFO_LIST::Build_Pads_Full_List()
} }
// Sort pad list per net // Sort pad list per net
// sort( m_PadsFullList.begin(), m_PadsFullList.end(), padlistSortByNetnames );
sort( m_PadsFullList.begin(), m_PadsFullList.end(), PadlistSortByNetnames );
m_Parent->m_Status_Pcb = LISTE_PAD_OK; m_Parent->m_Status_Pcb = LISTE_PAD_OK;
} }
...@@ -69,7 +69,7 @@ void CleanupTracks( PCB_EDIT_FRAME* aFrame, ...@@ -69,7 +69,7 @@ void CleanupTracks( PCB_EDIT_FRAME* aFrame,
/* Rebuild the pad infos (pad list and netcodes) to ensure an up to date info */ /* Rebuild the pad infos (pad list and netcodes) to ensure an up to date info */
aFrame->GetBoard()->m_Status_Pcb = 0; aFrame->GetBoard()->m_Status_Pcb = 0;
aFrame->GetBoard()->m_NetInfo->BuildListOfNets(); aFrame->GetBoard()->BuildListOfNets();
if( aCleanVias ) // delete redundant vias if( aCleanVias ) // delete redundant vias
{ {
......
...@@ -677,9 +677,9 @@ void CONNECTIONS::Propagate_SubNets() ...@@ -677,9 +677,9 @@ void CONNECTIONS::Propagate_SubNets()
void PCB_BASE_FRAME::TestConnections() void PCB_BASE_FRAME::TestConnections()
{ {
// Clear the cluster identifier for all pads // Clear the cluster identifier for all pads
for( unsigned i = 0; i< m_Pcb->GetPadsCount(); ++i ) for( unsigned i = 0; i< m_Pcb->GetPadCount(); ++i )
{ {
D_PAD* pad = m_Pcb->m_NetInfo->GetPad(i); D_PAD* pad = m_Pcb->GetPad(i);
pad->SetZoneSubNet( 0 ); pad->SetZoneSubNet( 0 );
pad->SetSubNet( 0 ); pad->SetSubNet( 0 );
...@@ -720,9 +720,9 @@ void PCB_BASE_FRAME::TestNetConnection( wxDC* aDC, int aNetCode ) ...@@ -720,9 +720,9 @@ void PCB_BASE_FRAME::TestNetConnection( wxDC* aDC, int aNetCode )
Compile_Ratsnest( aDC, true ); Compile_Ratsnest( aDC, true );
// Clear the cluster identifier (subnet) of pads for this net // Clear the cluster identifier (subnet) of pads for this net
for( unsigned i = 0; i < m_Pcb->GetPadsCount(); ++i ) for( unsigned i = 0; i < m_Pcb->GetPadCount(); ++i )
{ {
D_PAD* pad = m_Pcb->m_NetInfo->GetPad(i); D_PAD* pad = m_Pcb->GetPad(i);
int pad_net_code = pad->GetNet(); int pad_net_code = pad->GetNet();
if( pad_net_code < aNetCode ) if( pad_net_code < aNetCode )
...@@ -786,7 +786,8 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode() ...@@ -786,7 +786,8 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode()
TRACK* curr_track; TRACK* curr_track;
// Build the net info list // Build the net info list
GetBoard()->m_NetInfo->BuildListOfNets(); GetBoard()->BuildListOfNets();
// Reset variables and flags used in computation // Reset variables and flags used in computation
curr_track = m_Pcb->m_Track; curr_track = m_Pcb->m_Track;
for( ; curr_track != NULL; curr_track = curr_track->Next() ) for( ; curr_track != NULL; curr_track = curr_track->Next() )
...@@ -801,7 +802,7 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode() ...@@ -801,7 +802,7 @@ void PCB_BASE_FRAME::RecalculateAllTracksNetcode()
} }
// If no pad, reset pointers and netcode, and do nothing else // If no pad, reset pointers and netcode, and do nothing else
if( m_Pcb->GetPadsCount() == 0 ) if( m_Pcb->GetPadCount() == 0 )
return; return;
CONNECTIONS connections( m_Pcb ); CONNECTIONS connections( m_Pcb );
......
...@@ -276,9 +276,9 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) ...@@ -276,9 +276,9 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads )
// Compute the min distance to pads // Compute the min distance to pads
if( testPads ) if( testPads )
{ {
for( unsigned ii = 0; ii<m_pcb->GetPadsCount(); ++ii ) for( unsigned ii = 0; ii<m_pcb->GetPadCount(); ++ii )
{ {
D_PAD* pad = m_pcb->m_NetInfo->GetPad( ii ); D_PAD* pad = m_pcb->GetPad( ii );
/* No problem if pads are on an other layer, /* No problem if pads are on an other layer,
* But if a drill hole exists (a pad on a single layer can have a hole!) * But if a drill hole exists (a pad on a single layer can have a hole!)
......
...@@ -262,12 +262,10 @@ static void CreatePadsShapesSection( FILE* aFile, BOARD* aPcb ) ...@@ -262,12 +262,10 @@ static void CreatePadsShapesSection( FILE* aFile, BOARD* aPcb )
fputs( "$PADS\n", aFile ); fputs( "$PADS\n", aFile );
// Enumerate and sort the pads // Enumerate and sort the pads
if( aPcb->GetPadsCount() > 0 ) if( aPcb->GetPadCount() > 0 )
{ {
pads.insert( pads.end(), pads = aPcb->GetPads();
aPcb->m_NetInfo->m_PadsFullList.begin(), qsort( &pads[0], aPcb->GetPadCount(), sizeof( D_PAD* ),
aPcb->m_NetInfo->m_PadsFullList.end() );
qsort( &pads[0], aPcb->GetPadsCount(), sizeof( D_PAD* ),
PadListSortByShape ); PadListSortByShape );
} }
...@@ -643,9 +641,9 @@ static void CreateSignalsSection( FILE* aFile, BOARD* aPcb ) ...@@ -643,9 +641,9 @@ static void CreateSignalsSection( FILE* aFile, BOARD* aPcb )
fputs( "$SIGNALS\n", aFile ); fputs( "$SIGNALS\n", aFile );
for( unsigned ii = 0; ii < aPcb->m_NetInfo->GetCount(); ii++ ) for( unsigned ii = 0; ii < aPcb->GetNetCount(); ii++ )
{ {
net = aPcb->m_NetInfo->GetNetItem( ii ); net = aPcb->FindNet( ii );
if( net->GetNetname() == wxEmptyString ) // dummy netlist (no connection) if( net->GetNetname() == wxEmptyString ) // dummy netlist (no connection)
{ {
......
...@@ -63,9 +63,9 @@ void PCB_EDIT_FRAME::ListNetsAndSelect( wxCommandEvent& event ) ...@@ -63,9 +63,9 @@ void PCB_EDIT_FRAME::ListNetsAndSelect( wxCommandEvent& event )
return; return;
wxString Line; wxString Line;
for( unsigned ii = 0; ii < GetBoard()->m_NetInfo->GetCount(); ii++ ) for( unsigned ii = 0; ii < GetBoard()->GetNetCount(); ii++ )
{ {
net = GetBoard()->m_NetInfo->GetNetItem( ii ); net = GetBoard()->m_NetInfo.GetNetItem( ii );
if( !WildCompareString( netFilter, net->GetNetname(), false ) ) if( !WildCompareString( netFilter, net->GetNetname(), false ) )
continue; continue;
...@@ -84,9 +84,9 @@ void PCB_EDIT_FRAME::ListNetsAndSelect( wxCommandEvent& event ) ...@@ -84,9 +84,9 @@ void PCB_EDIT_FRAME::ListNetsAndSelect( wxCommandEvent& event )
unsigned netcode = (unsigned) choiceDlg.GetSelection(); unsigned netcode = (unsigned) choiceDlg.GetSelection();
// Search for the net selected. // Search for the net selected.
for( unsigned ii = 0; ii < GetBoard()->m_NetInfo->GetCount(); ii++ ) for( unsigned ii = 0; ii < GetBoard()->GetNetCount(); ii++ )
{ {
net = GetBoard()->m_NetInfo->GetNetItem( ii ); net = GetBoard()->FindNet( ii );
if( !WildCompareString( netFilter, net->GetNetname(), false ) ) if( !WildCompareString( netFilter, net->GetNetname(), false ) )
continue; continue;
......
...@@ -824,7 +824,7 @@ bool PCB_EDIT_FRAME::WriteGeneralDescrPcb( FILE* File ) ...@@ -824,7 +824,7 @@ bool PCB_EDIT_FRAME::WriteGeneralDescrPcb( FILE* File )
fprintf( File, "Nzone %d\n", GetBoard()->GetNumSegmZone() ); fprintf( File, "Nzone %d\n", GetBoard()->GetNumSegmZone() );
fprintf( File, "BoardThickness %d\n", GetBoard()->GetDesignSettings().m_BoardThickness ); fprintf( File, "BoardThickness %d\n", GetBoard()->GetDesignSettings().m_BoardThickness );
fprintf( File, "Nmodule %d\n", NbModules ); fprintf( File, "Nmodule %d\n", NbModules );
fprintf( File, "Nnets %d\n", GetBoard()->m_NetInfo->GetCount() ); fprintf( File, "Nnets %d\n", GetBoard()->GetNetCount() );
fprintf( File, "$EndGENERAL\n\n" ); fprintf( File, "$EndGENERAL\n\n" );
return true; return true;
} }
...@@ -1010,7 +1010,7 @@ int PCB_EDIT_FRAME::ReadPcbFile( LINE_READER* aReader, bool Append ) ...@@ -1010,7 +1010,7 @@ int PCB_EDIT_FRAME::ReadPcbFile( LINE_READER* aReader, bool Append )
if( TESTLINE( "EQUIPOT" ) ) if( TESTLINE( "EQUIPOT" ) )
{ {
NETINFO_ITEM* net = new NETINFO_ITEM( board ); NETINFO_ITEM* net = new NETINFO_ITEM( board );
board->m_NetInfo->AppendNet( net ); board->m_NetInfo.AppendNet( net );
net->ReadDescr( aReader ); net->ReadDescr( aReader );
continue; continue;
} }
...@@ -1130,10 +1130,10 @@ int PCB_EDIT_FRAME::ReadPcbFile( LINE_READER* aReader, bool Append ) ...@@ -1130,10 +1130,10 @@ int PCB_EDIT_FRAME::ReadPcbFile( LINE_READER* aReader, bool Append )
SetLocaleTo_Default(); // revert to the current locale SetLocaleTo_Default(); // revert to the current locale
GetBoard()->m_Status_Pcb = 0; board->m_Status_Pcb = 0;
// Build the net info list // Build the net info list
GetBoard()->m_NetInfo->BuildListOfNets(); board->BuildListOfNets();
board->SynchronizeNetsAndNetClasses(); board->SynchronizeNetsAndNetClasses();
......
...@@ -41,7 +41,6 @@ ...@@ -41,7 +41,6 @@
#include "pcbnew.h" #include "pcbnew.h"
#include "pcbnew_id.h" #include "pcbnew_id.h"
#include "autorout.h" #include "autorout.h"
#include "pcb_plot_params.h"
#include "3d_struct.h" #include "3d_struct.h"
#include "trigo.h" #include "trigo.h"
...@@ -60,8 +59,8 @@ bool BOARD::Save( FILE* aFile ) const ...@@ -60,8 +59,8 @@ bool BOARD::Save( FILE* aFile ) const
BOARD_ITEM* item; BOARD_ITEM* item;
// save the nets // save the nets
for( unsigned ii = 0; ii < m_NetInfo->GetCount(); ii++ ) for( unsigned ii = 0; ii < GetNetCount(); ii++ )
if( !m_NetInfo->GetNetItem( ii )->Save( aFile ) ) if( !FindNet( ii )->Save( aFile ) )
goto out; goto out;
// Saved nets do not include netclass names, so save netclasses after nets. // Saved nets do not include netclass names, so save netclasses after nets.
......
This diff is collapsed.
...@@ -40,6 +40,9 @@ class ZONE_CONTAINER; ...@@ -40,6 +40,9 @@ class ZONE_CONTAINER;
class DIMENSION; class DIMENSION;
class NETINFO_ITEM; class NETINFO_ITEM;
class TEXTE_MODULE; class TEXTE_MODULE;
class EDGE_MODULE;
class TRACK;
class SEGZONE;
/** /**
...@@ -73,6 +76,7 @@ protected: ...@@ -73,6 +76,7 @@ protected:
LINE_READER* m_reader; ///< no ownership here. LINE_READER* m_reader; ///< no ownership here.
FILE* m_fp; ///< no ownership here. FILE* m_fp; ///< no ownership here.
wxString m_filename; ///< for saves only, name is in m_reader for loads
wxString m_field; ///< reused to stuff MODULE fields. wxString m_field; ///< reused to stuff MODULE fields.
...@@ -88,9 +92,6 @@ protected: ...@@ -88,9 +92,6 @@ protected:
double biuToDisk; ///< convert from BIUs to disk engineering units with this scale factor double biuToDisk; ///< convert from BIUs to disk engineering units with this scale factor
double diskToBiu; ///< convert from disk engineering units to BIUs with this scale factor double diskToBiu; ///< convert from disk engineering units to BIUs with this scale factor
/// convert a BIU to engineering units by scaling and formatting to ASCII.
std::string biuFmt( BIU aValue );
/** /**
* Function biuParse * Function biuParse
* parses an ASCII decimal floating point value and scales it into a BIU * parses an ASCII decimal floating point value and scales it into a BIU
...@@ -133,12 +134,12 @@ protected: ...@@ -133,12 +134,12 @@ protected:
void loadMODULE(); void loadMODULE();
void load3D( MODULE* aModule ); void load3D( MODULE* aModule );
void loadPAD( MODULE* aModule ); void loadPAD( MODULE* aModule );
void loadTEXTE_MODULE( TEXTE_MODULE* aText ); void loadMODULE_TEXT( TEXTE_MODULE* aText );
void loadEDGE_MODULE( MODULE* aModule ); void loadEDGE_MODULE( MODULE* aModule );
void loadDRAWSEGMENT(); void loadDRAWSEGMENT();
void loadNETINFO_ITEM(); void loadNETINFO_ITEM();
void loadPCB_TEXTE(); void loadPCB_TEXT();
void loadNETCLASS(); void loadNETCLASS();
/** /**
...@@ -158,6 +159,50 @@ protected: ...@@ -158,6 +159,50 @@ protected:
void loadPCB_TARGET(); // "$PCB_TARGET" void loadPCB_TARGET(); // "$PCB_TARGET"
//-----</ load/parse functions>--------------------------------------------- //-----</ load/parse functions>---------------------------------------------
//-----<save functions>-----------------------------------------------------
/**
* Function checkWriteError
* checks to see if there is an error on the output FILE, and its ability to
* continue saving to disk.
*/
void checkWriteError( const char* aCaller ) const;
/// convert a BIU to engineering units by scaling and formatting to ASCII.
std::string biuFmt( BIU aValue );
void saveAllSections() const;
void saveGENERAL() const;
void saveSHEET() const;
void saveSETUP() const;
void saveBOARD() const;
void saveMODULE( const MODULE* aModule ) const;
void saveNETINFO_ITEM( const NETINFO_ITEM* aNet ) const;
void saveNETCLASSES() const;
void saveNETCLASS( const NETCLASS* aNetclass ) const;
void savePCB_TEXT( const TEXTE_PCB* aText ) const;
void saveEDGE_MODULE( const EDGE_MODULE* aEdge ) const;
void saveTARGET( const PCB_TARGET* aTarget ) const;
void saveDIMENTION( const DIMENSION* aDimension ) const;
void saveTRACK( const TRACK* aTrack ) const;
/**
* Function saveSEGZONE
* saves the oldschool zones, now outdated in favor of polygon zones.
*/
void saveSEGZONE( const SEGZONE* aZone ) const;
/**
* Function saveZONE_CONTAINER
* saves the new polygon zones.
*/
void saveZONE_CONTAINER( const ZONE_CONTAINER* aZone ) const;
//-----</save functions>----------------------------------------------------
}; };
#endif // KICAD_PLUGIN_H_ #endif // KICAD_PLUGIN_H_
...@@ -134,7 +134,7 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module() ...@@ -134,7 +134,7 @@ MODULE* FOOTPRINT_EDIT_FRAME::Import_Module()
module->DisplayInfo( this ); module->DisplayInfo( this );
PlaceModule( module, NULL ); PlaceModule( module, NULL );
GetBoard()->m_Status_Pcb = 0; GetBoard()->m_Status_Pcb = 0;
GetBoard()->m_NetInfo->BuildListOfNets(); GetBoard()->BuildListOfNets();
return module; return module;
} }
......
...@@ -86,7 +86,7 @@ bool FOOTPRINT_EDIT_FRAME::Load_Module_From_BOARD( MODULE* aModule ) ...@@ -86,7 +86,7 @@ bool FOOTPRINT_EDIT_FRAME::Load_Module_From_BOARD( MODULE* aModule )
aModule->m_Flags = 0; aModule->m_Flags = 0;
GetBoard()->m_NetInfo->BuildListOfNets(); GetBoard()->BuildListOfNets();
GetScreen()->SetCrossHairPosition( wxPoint( 0, 0 ) ); GetScreen()->SetCrossHairPosition( wxPoint( 0, 0 ) );
PlaceModule( aModule, NULL ); PlaceModule( aModule, NULL );
...@@ -196,7 +196,7 @@ MODULE* PCB_BASE_FRAME::Load_Module_From_Library( const wxString& library, wxDC* ...@@ -196,7 +196,7 @@ MODULE* PCB_BASE_FRAME::Load_Module_From_Library( const wxString& library, wxDC*
*/ */
// GetBoard()->m_Pcb->m_NetInfo->BuildListOfNets(); // GetBoard()->m_Pcb->m_NetInfo.BuildListOfNets();
RecalculateAllTracksNetcode(); RecalculateAllTracksNetcode();
if( DC ) if( DC )
......
...@@ -242,7 +242,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event ) ...@@ -242,7 +242,7 @@ void FOOTPRINT_EDIT_FRAME::Process_Special_Functions( wxCommandEvent& event )
// Initialize data relative to nets and netclasses (for a new // Initialize data relative to nets and netclasses (for a new
// module the defaults are used) // module the defaults are used)
// This is mandatory to handle and draw pads // This is mandatory to handle and draw pads
GetBoard()->m_NetInfo->BuildListOfNets(); GetBoard()->BuildListOfNets();
redraw = true; redraw = true;
module->SetPosition( wxPoint( 0, 0 ) ); module->SetPosition( wxPoint( 0, 0 ) );
......
...@@ -170,7 +170,7 @@ void Abort_MoveOrCopyModule( EDA_DRAW_PANEL* Panel, wxDC* DC ) ...@@ -170,7 +170,7 @@ void Abort_MoveOrCopyModule( EDA_DRAW_PANEL* Panel, wxDC* DC )
module->DeleteStructure(); module->DeleteStructure();
module = NULL; module = NULL;
pcbframe->GetBoard()->m_Status_Pcb = 0; pcbframe->GetBoard()->m_Status_Pcb = 0;
pcbframe->GetBoard()->m_NetInfo->BuildListOfNets(); pcbframe->GetBoard()->BuildListOfNets();
} }
} }
......
...@@ -135,7 +135,7 @@ void PCB_BASE_FRAME::Compile_Ratsnest( wxDC* aDC, bool aDisplayStatus ) ...@@ -135,7 +135,7 @@ void PCB_BASE_FRAME::Compile_Ratsnest( wxDC* aDC, bool aDisplayStatus )
{ {
wxString msg; wxString msg;
GetBoard()->m_Status_Pcb = 0; /* we want a full ratsnest computation, from the scratch */ GetBoard()->m_Status_Pcb = 0; // we want a full ratsnest computation, from the scratch
ClearMsgPanel(); ClearMsgPanel();
// Rebuild the full pads and net info list // Rebuild the full pads and net info list
...@@ -143,9 +143,9 @@ void PCB_BASE_FRAME::Compile_Ratsnest( wxDC* aDC, bool aDisplayStatus ) ...@@ -143,9 +143,9 @@ void PCB_BASE_FRAME::Compile_Ratsnest( wxDC* aDC, bool aDisplayStatus )
if( aDisplayStatus ) if( aDisplayStatus )
{ {
msg.Printf( wxT( " %d" ), m_Pcb->GetPadsCount() ); msg.Printf( wxT( " %d" ), m_Pcb->GetPadCount() );
AppendMsgPanel( wxT( "Pads" ), msg, RED ); AppendMsgPanel( wxT( "Pads" ), msg, RED );
msg.Printf( wxT( " %d" ), m_Pcb->m_NetInfo->GetCount() ); msg.Printf( wxT( " %d" ), m_Pcb->GetNetCount() );
AppendMsgPanel( wxT( "Nets" ), msg, CYAN ); AppendMsgPanel( wxT( "Nets" ), msg, CYAN );
} }
...@@ -158,7 +158,7 @@ void PCB_BASE_FRAME::Compile_Ratsnest( wxDC* aDC, bool aDisplayStatus ) ...@@ -158,7 +158,7 @@ void PCB_BASE_FRAME::Compile_Ratsnest( wxDC* aDC, bool aDisplayStatus )
*/ */
Build_Board_Ratsnest(); Build_Board_Ratsnest();
/* Compute the pad connections due to the existing tracks (physical connections) */ // Compute the pad connections due to the existing tracks (physical connections)
TestConnections(); TestConnections();
/* Compute the active ratsnest, i.e. the unconnected links /* Compute the active ratsnest, i.e. the unconnected links
...@@ -206,16 +206,16 @@ void PCB_BASE_FRAME::Build_Board_Ratsnest() ...@@ -206,16 +206,16 @@ void PCB_BASE_FRAME::Build_Board_Ratsnest()
m_Pcb->m_FullRatsnest.clear(); m_Pcb->m_FullRatsnest.clear();
if( m_Pcb->GetPadsCount() == 0 ) if( m_Pcb->GetPadCount() == 0 )
return; return;
/* Created pad list and the net_codes if needed */ /* Created pad list and the net_codes if needed */
if( (m_Pcb->m_Status_Pcb & NET_CODES_OK) == 0 ) if( (m_Pcb->m_Status_Pcb & NET_CODES_OK) == 0 )
m_Pcb->m_NetInfo->BuildListOfNets(); m_Pcb->BuildListOfNets();
for( unsigned ii = 0; ii<m_Pcb->GetPadsCount(); ++ii ) for( unsigned ii = 0; ii<m_Pcb->GetPadCount(); ++ii )
{ {
pad = m_Pcb->m_NetInfo->GetPad( ii ); pad = m_Pcb->GetPad( ii );
pad->SetSubRatsnest( 0 ); pad->SetSubRatsnest( 0 );
} }
...@@ -227,7 +227,7 @@ void PCB_BASE_FRAME::Build_Board_Ratsnest() ...@@ -227,7 +227,7 @@ void PCB_BASE_FRAME::Build_Board_Ratsnest()
// (net_code = 0 -> no connect) // (net_code = 0 -> no connect)
noconn = 0; noconn = 0;
MIN_SPAN_TREE_PADS min_spanning_tree; MIN_SPAN_TREE_PADS min_spanning_tree;
for( ; current_net_code < m_Pcb->m_NetInfo->GetCount(); current_net_code++ ) for( ; current_net_code < m_Pcb->GetNetCount(); current_net_code++ )
{ {
NETINFO_ITEM* net = m_Pcb->FindNet( current_net_code ); NETINFO_ITEM* net = m_Pcb->FindNet( current_net_code );
...@@ -439,13 +439,13 @@ void PCB_BASE_FRAME::TestForActiveLinksInRatsnest( int aNetCode ) ...@@ -439,13 +439,13 @@ void PCB_BASE_FRAME::TestForActiveLinksInRatsnest( int aNetCode )
D_PAD* pad; D_PAD* pad;
NETINFO_ITEM* net; NETINFO_ITEM* net;
if( m_Pcb->GetPadsCount() == 0 ) if( m_Pcb->GetPadCount() == 0 )
return; return;
if( (m_Pcb->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 ) if( (m_Pcb->m_Status_Pcb & LISTE_RATSNEST_ITEM_OK) == 0 )
Build_Board_Ratsnest(); Build_Board_Ratsnest();
for( int net_code = 1; net_code < (int) m_Pcb->m_NetInfo->GetCount(); net_code++ ) for( int net_code = 1; net_code < (int) m_Pcb->GetNetCount(); net_code++ )
{ {
net = m_Pcb->FindNet( net_code ); net = m_Pcb->FindNet( net_code );
...@@ -514,7 +514,7 @@ void PCB_BASE_FRAME::build_ratsnest_module( MODULE* aModule ) ...@@ -514,7 +514,7 @@ void PCB_BASE_FRAME::build_ratsnest_module( MODULE* aModule )
if( (GetBoard()->m_Status_Pcb & LISTE_PAD_OK) == 0 ) if( (GetBoard()->m_Status_Pcb & LISTE_PAD_OK) == 0 )
{ {
GetBoard()->m_Status_Pcb = 0; GetBoard()->m_Status_Pcb = 0;
GetBoard()->m_NetInfo->BuildListOfNets(); GetBoard()->BuildListOfNets();
} }
/* Compute the "local" ratsnest if needed (when this footprint starts move) /* Compute the "local" ratsnest if needed (when this footprint starts move)
......
...@@ -508,12 +508,11 @@ static int Autoroute_One_Track( PCB_EDIT_FRAME* pcbframe, ...@@ -508,12 +508,11 @@ static int Autoroute_One_Track( PCB_EDIT_FRAME* pcbframe,
/* Regenerates the remaining barriers (which may encroach on the placement bits precedent) /* Regenerates the remaining barriers (which may encroach on the placement bits precedent)
*/ */
i = pcbframe->GetBoard()->GetPadsCount(); i = pcbframe->GetBoard()->GetPadCount();
for( unsigned ii = 0; ii < pcbframe->GetBoard()->GetPadsCount(); ii++ ) for( unsigned ii = 0; ii < pcbframe->GetBoard()->GetPadCount(); ii++ )
{ {
D_PAD* ptr = pcbframe->GetBoard()->GetPad( ii );
D_PAD* ptr = pcbframe->GetBoard()->m_NetInfo->GetPad( ii );
if( ( pt_cur_ch->m_PadStart != ptr ) && ( pt_cur_ch->m_PadEnd != ptr ) ) if( ( pt_cur_ch->m_PadStart != ptr ) && ( pt_cur_ch->m_PadEnd != ptr ) )
{ {
......
...@@ -1172,7 +1172,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR ) ...@@ -1172,7 +1172,7 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR )
std::string componentId; std::string componentId;
// find the highest numbered netCode within the board. // find the highest numbered netCode within the board.
int highestNetCode = aBoard->m_NetInfo->GetCount() - 1; int highestNetCode = aBoard->GetNetCount() - 1;
deleteNETs(); deleteNETs();
// expand the net vector to highestNetCode+1, setting empty to NULL // expand the net vector to highestNetCode+1, setting empty to NULL
...@@ -1182,9 +1182,9 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR ) ...@@ -1182,9 +1182,9 @@ void SPECCTRA_DB::FromBOARD( BOARD* aBoard ) throw( IO_ERROR )
for( unsigned i=1; i<nets.size(); ++i ) for( unsigned i=1; i<nets.size(); ++i )
nets[i] = new NET( pcb->network ); nets[i] = new NET( pcb->network );
for( unsigned ii = 0; ii < aBoard->m_NetInfo->GetCount(); ii++ ) for( unsigned ii = 0; ii < aBoard->GetNetCount(); ii++ )
{ {
NETINFO_ITEM* net = aBoard->m_NetInfo->GetNetItem(ii); NETINFO_ITEM* net = aBoard->FindNet(ii);
int netcode = net->GetNet(); int netcode = net->GetNet();
if( netcode > 0 ) if( netcode > 0 )
nets[ netcode ]->net_id = TO_UTF8( net->GetNetname() ); nets[ netcode ]->net_id = TO_UTF8( net->GetNetname() );
......
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