Convert timestamps to UUIDs.

This commit is contained in:
Jeff Young 2020-02-20 12:11:04 +00:00
parent 4014afad54
commit 129042f8a6
88 changed files with 951 additions and 1150 deletions

View File

@ -86,7 +86,6 @@ void EDA_ITEM::initVars()
m_StructType = TYPE_NOT_INIT; m_StructType = TYPE_NOT_INIT;
m_Parent = NULL; // Linked list: Link (parent struct) m_Parent = NULL; // Linked list: Link (parent struct)
m_Flags = 0; // flags for editions and other m_Flags = 0; // flags for editions and other
SetTimeStamp( 0 ); // Time stamp used for logical links
m_Status = 0; m_Status = 0;
m_forceVisible = false; // true to override the visibility setting of the item. m_forceVisible = false; // true to override the visibility setting of the item.
} }
@ -222,9 +221,6 @@ EDA_ITEM& EDA_ITEM::operator=( const EDA_ITEM& aItem )
m_Parent = aItem.m_Parent; m_Parent = aItem.m_Parent;
m_forceVisible = aItem.m_forceVisible; m_forceVisible = aItem.m_forceVisible;
// A copy of an item cannot have the same time stamp as the original item.
SetTimeStamp( GetNewTimeStamp() );
return *this; return *this;
} }

View File

@ -23,16 +23,10 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
/**
* @file common.cpp
*/
#include <fctsys.h> #include <fctsys.h>
#include <eda_base_frame.h> #include <eda_base_frame.h>
#include <base_struct.h>
#include <common.h> #include <common.h>
#include <macros.h> #include <macros.h>
#include <base_units.h>
#include <reporter.h> #include <reporter.h>
#include <mutex> #include <mutex>
#include <settings/settings_manager.h> #include <settings/settings_manager.h>
@ -42,12 +36,137 @@
#include <wx/utils.h> #include <wx/utils.h>
#include <wx/stdpaths.h> #include <wx/stdpaths.h>
#include <wx/url.h> #include <wx/url.h>
#include <boost/uuid/uuid_generators.hpp>
#include <pgm_base.h> #include <boost/uuid/uuid_io.hpp>
#include <boost/functional/hash.hpp>
using KIGFX::COLOR4D; using KIGFX::COLOR4D;
// Create only once, as seeding is *very* expensive
static boost::uuids::random_generator randomGenerator;
// These don't have the same performance penalty, but might as well be consistent
static boost::uuids::string_generator stringGenerator;
static boost::uuids::nil_generator nilGenerator;
// Global nil reference
UUID niluuid( 0 );
UUID::UUID() :
m_uuid( randomGenerator() ),
m_cached_timestamp( 0 )
{
}
UUID::UUID( int null ) :
m_uuid( nilGenerator() ),
m_cached_timestamp( 0 )
{
wxASSERT( null == 0 );
}
UUID::UUID( const wxString& aString ) :
m_uuid(),
m_cached_timestamp( 0 )
{
if( aString.length() == 8 )
{
// A legacy-timestamp-based UUID has only the last 4 octets filled in.
// Convert them individually to avoid stepping in the little-endian/big-endian
// doo-doo.
for( int i = 0; i < 4; ++i )
{
wxString octet = aString.substr( i * 2, 2 );
m_uuid.data[ i + 12 ] = strtol( octet.data(), NULL, 16 );
}
m_cached_timestamp = strtol( aString.c_str(), NULL, 16 );
}
else
{
try
{
m_uuid = stringGenerator( aString.wc_str() );
if( IsLegacyTimestamp() )
m_cached_timestamp = strtol( aString.substr( 28 ).c_str(), NULL, 16 );
}
catch( ... )
{
// Failed to parse string representation; best we can do is assign a new
// random one.
m_uuid = randomGenerator();
}
}
}
UUID::UUID( timestamp_t aTimestamp )
{
m_cached_timestamp = aTimestamp;
// A legacy-timestamp-based UUID has only the last 4 octets filled in.
// Convert them individually to avoid stepping in the little-endian/big-endian
// doo-doo.
wxString str = AsLegacyTimestampString();
for( int i = 0; i < 4; ++i )
{
wxString octet = str.substr( i * 2, 2 );
m_uuid.data[ i + 12 ] = strtol( octet.data(), NULL, 16 );
}
}
bool UUID::IsLegacyTimestamp() const
{
return !m_uuid.data[8] && !m_uuid.data[9] && !m_uuid.data[10] && !m_uuid.data[11];
}
timestamp_t UUID::AsLegacyTimestamp() const
{
return m_cached_timestamp;
}
size_t UUID::Hash() const
{
size_t hash = 0;
// Note: this is NOT little-endian/big-endian safe, but as long as it's just used
// at runtime it won't matter.
for( int i = 0; i < 4; ++i )
boost::hash_combine( hash, reinterpret_cast<const uint32_t*>( m_uuid.data )[i] );
return hash;
}
void UUID::Clone( const UUID& aUUID )
{
m_uuid = aUUID.m_uuid;
m_cached_timestamp = aUUID.m_cached_timestamp;
}
wxString UUID::AsString() const
{
return boost::uuids::to_string( m_uuid );
}
wxString UUID::AsLegacyTimestampString() const
{
return wxString::Format( "%8.8lX", (unsigned long) AsLegacyTimestamp() );
}
/** /**
* Global variables definitions. * Global variables definitions.
* *

View File

@ -260,23 +260,6 @@ NODE_MAP MapChildren( wxXmlNode* aCurrentNode )
} }
timestamp_t EagleTimeStamp( wxXmlNode* aTree )
{
// in this case from a unique tree memory location
return (timestamp_t) reinterpret_cast<uintptr_t>( aTree );
}
timestamp_t EagleModuleTstamp( const wxString& aName, const wxString& aValue, int aUnit )
{
std::size_t h1 = std::hash<wxString>{}( aName );
std::size_t h2 = std::hash<wxString>{}( aValue );
std::size_t h3 = std::hash<int>{}( aUnit );
return (timestamp_t)( h1 ^ (h2 << 1) ^ (h3 << 2) );
}
wxPoint ConvertArcCenter( const wxPoint& aStart, const wxPoint& aEnd, double aAngle ) wxPoint ConvertArcCenter( const wxPoint& aStart, const wxPoint& aEnd, double aAngle )
{ {
// Eagle give us start and end. // Eagle give us start and end.

View File

@ -30,6 +30,7 @@
// 'FT232BL' 'QFP:LQFP-32_7x7mm_Pitch0.8mm' // 'FT232BL' 'QFP:LQFP-32_7x7mm_Pitch0.8mm'
// //
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" // For boost...
#include <boost/ptr_container/ptr_vector.hpp> #include <boost/ptr_container/ptr_vector.hpp>
class FOOTPRINT_EQUIVALENCE class FOOTPRINT_EQUIVALENCE

View File

@ -1,12 +1,7 @@
/**
* @file annotate.cpp
* @brief Component annotation.
*/
/* /*
* 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) 2004-2017 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2004-2020 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
@ -38,7 +33,7 @@
#include <class_library.h> #include <class_library.h>
void mapExistingAnnotation( std::map<timestamp_t, wxString>& aMap ) void mapExistingAnnotation( std::map<UUID, wxString>& aMap )
{ {
SCH_SHEET_LIST sheets( g_RootSheet ); SCH_SHEET_LIST sheets( g_RootSheet );
SCH_REFERENCE_LIST references; SCH_REFERENCE_LIST references;
@ -51,7 +46,7 @@ void mapExistingAnnotation( std::map<timestamp_t, wxString>& aMap )
wxString ref = comp->GetField( REFERENCE )->GetFullyQualifiedText(); wxString ref = comp->GetField( REFERENCE )->GetFullyQualifiedText();
if( !ref.Contains( wxT( "?" ) ) ) if( !ref.Contains( wxT( "?" ) ) )
aMap[ comp->GetTimeStamp() ] = ref; aMap[ comp->m_Uuid ] = ref;
} }
} }
@ -99,7 +94,7 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic,
SCH_MULTI_UNIT_REFERENCE_MAP lockedComponents; SCH_MULTI_UNIT_REFERENCE_MAP lockedComponents;
// Map of previous annotation for building info messages // Map of previous annotation for building info messages
std::map<timestamp_t, wxString> previousAnnotation; std::map<UUID, wxString> previousAnnotation;
// Test for and replace duplicate time stamps in components and sheets. Duplicate // Test for and replace duplicate time stamps in components and sheets. Duplicate
// time stamps can happen with old schematics, schematic conversions, or manual // time stamps can happen with old schematics, schematic conversions, or manual
@ -120,13 +115,9 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic,
if( aLockUnits ) if( aLockUnits )
{ {
if( aAnnotateSchematic ) if( aAnnotateSchematic )
{
sheets.GetMultiUnitComponents( lockedComponents ); sheets.GetMultiUnitComponents( lockedComponents );
}
else else
{
g_CurrentSheet->GetMultiUnitComponents( lockedComponents ); g_CurrentSheet->GetMultiUnitComponents( lockedComponents );
}
} }
// Store previous annotations for building info messages // Store previous annotations for building info messages
@ -141,13 +132,9 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic,
// Build component list // Build component list
if( aAnnotateSchematic ) if( aAnnotateSchematic )
{
sheets.GetComponents( references ); sheets.GetComponents( references );
}
else else
{
g_CurrentSheet->GetComponents( references ); g_CurrentSheet->GetComponents( references );
}
// Break full components reference in name (prefix) and number: // Break full components reference in name (prefix) and number:
// example: IC1 become IC, and 1 // example: IC1 become IC, and 1
@ -156,13 +143,8 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic,
switch( aSortOption ) switch( aSortOption )
{ {
default: default:
case SORT_BY_X_POSITION: case SORT_BY_X_POSITION: references.SortByXCoordinate(); break;
references.SortByXCoordinate(); case SORT_BY_Y_POSITION: references.SortByYCoordinate(); break;
break;
case SORT_BY_Y_POSITION:
references.SortByYCoordinate();
break;
} }
bool useSheetNum = false; bool useSheetNum = false;
@ -191,7 +173,7 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic,
for( size_t i = 0; i < references.GetCount(); i++ ) for( size_t i = 0; i < references.GetCount(); i++ )
{ {
SCH_COMPONENT* comp = references[ i ].GetComp(); SCH_COMPONENT* comp = references[ i ].GetComp();
wxString prevRef = previousAnnotation[ comp->GetTimeStamp() ]; wxString prevRef = previousAnnotation[ comp->m_Uuid ];
wxString newRef = comp->GetField( REFERENCE )->GetFullyQualifiedText(); wxString newRef = comp->GetField( REFERENCE )->GetFullyQualifiedText();
wxString msg; wxString msg;
@ -202,27 +184,27 @@ void SCH_EDIT_FRAME::AnnotateComponents( bool aAnnotateSchematic,
if( comp->GetUnitCount() > 1 ) if( comp->GetUnitCount() > 1 )
msg.Printf( _( "Updated %s (unit %s) from %s to %s" ), msg.Printf( _( "Updated %s (unit %s) from %s to %s" ),
GetChars( comp->GetField( VALUE )->GetShownText() ), comp->GetField( VALUE )->GetShownText(),
LIB_PART::SubReference( comp->GetUnit(), false ), LIB_PART::SubReference( comp->GetUnit(), false ),
GetChars( prevRef ), prevRef,
GetChars( newRef ) ); newRef );
else else
msg.Printf( _( "Updated %s from %s to %s" ), msg.Printf( _( "Updated %s from %s to %s" ),
GetChars( comp->GetField( VALUE )->GetShownText() ), comp->GetField( VALUE )->GetShownText(),
GetChars( prevRef ), prevRef,
GetChars( newRef ) ); newRef );
} }
else else
{ {
if( comp->GetUnitCount() > 1 ) if( comp->GetUnitCount() > 1 )
msg.Printf( _( "Annotated %s (unit %s) as %s" ), msg.Printf( _( "Annotated %s (unit %s) as %s" ),
GetChars( comp->GetField( VALUE )->GetShownText() ), comp->GetField( VALUE )->GetShownText(),
LIB_PART::SubReference( comp->GetUnit(), false ), LIB_PART::SubReference( comp->GetUnit(), false ),
GetChars( newRef ) ); newRef );
else else
msg.Printf( _( "Annotated %s as %s" ), msg.Printf( _( "Annotated %s as %s" ),
GetChars( comp->GetField( VALUE )->GetShownText() ), comp->GetField( VALUE )->GetShownText(),
GetChars( newRef ) ); newRef );
} }
aReporter.Report( msg, REPORTER::RPT_ACTION ); aReporter.Report( msg, REPORTER::RPT_ACTION );

View File

@ -31,7 +31,9 @@
#ifndef CLASS_LIBRARY_H #ifndef CLASS_LIBRARY_H
#define CLASS_LIBRARY_H #define CLASS_LIBRARY_H
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" // For boost...
#include <boost/ptr_container/ptr_vector.hpp> #include <boost/ptr_container/ptr_vector.hpp>
#include <wx/filename.h> #include <wx/filename.h>
#include <sch_io_mgr.h> #include <sch_io_mgr.h>

View File

@ -8,7 +8,7 @@
* *
* Copyright (C) 1992-2018 jean-pierre Charras <jp.charras at wanadoo.fr> * Copyright (C) 1992-2018 jean-pierre Charras <jp.charras at wanadoo.fr>
* Copyright (C) 1992-2011 Wayne Stambaugh <stambaughw@verizon.net> * Copyright (C) 1992-2011 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2020 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
@ -43,48 +43,50 @@
#include <sch_edit_frame.h> #include <sch_edit_frame.h>
//#define USE_OLD_ALGO
void SCH_REFERENCE_LIST::RemoveItem( unsigned int aIndex ) void SCH_REFERENCE_LIST::RemoveItem( unsigned int aIndex )
{ {
if( aIndex < componentFlatList.size() ) if( aIndex < flatList.size() )
componentFlatList.erase( componentFlatList.begin() + aIndex ); flatList.erase( flatList.begin() + aIndex );
} }
bool SCH_REFERENCE_LIST::sortByXPosition( const SCH_REFERENCE& item1, bool SCH_REFERENCE_LIST::sortByXPosition( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 )
const SCH_REFERENCE& item2 )
{ {
int ii = item1.CompareRef( item2 ); int ii = item1.CompareRef( item2 );
if( ii == 0 ) if( ii == 0 )
ii = item1.m_SheetNum - item2.m_SheetNum; ii = item1.m_SheetNum - item2.m_SheetNum;
if( ii == 0 ) if( ii == 0 )
ii = item1.m_CmpPos.x - item2.m_CmpPos.x; ii = item1.m_CmpPos.x - item2.m_CmpPos.x;
if( ii == 0 ) if( ii == 0 )
ii = item1.m_CmpPos.y - item2.m_CmpPos.y; ii = item1.m_CmpPos.y - item2.m_CmpPos.y;
if( ii == 0 )
ii = item1.m_TimeStamp - item2.m_TimeStamp;
return ii < 0; if( ii == 0 )
return item1.m_Uuid < item2.m_Uuid; // ensure a deterministic sort
else
return ii < 0;
} }
bool SCH_REFERENCE_LIST::sortByYPosition( const SCH_REFERENCE& item1,
const SCH_REFERENCE& item2 ) bool SCH_REFERENCE_LIST::sortByYPosition( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 )
{ {
int ii = item1.CompareRef( item2 ); int ii = item1.CompareRef( item2 );
if( ii == 0 ) if( ii == 0 )
ii = item1.m_SheetNum - item2.m_SheetNum; ii = item1.m_SheetNum - item2.m_SheetNum;
if( ii == 0 ) if( ii == 0 )
ii = item1.m_CmpPos.y - item2.m_CmpPos.y; ii = item1.m_CmpPos.y - item2.m_CmpPos.y;
if( ii == 0 ) if( ii == 0 )
ii = item1.m_CmpPos.x - item2.m_CmpPos.x; ii = item1.m_CmpPos.x - item2.m_CmpPos.x;
if( ii == 0 )
ii = item1.m_TimeStamp - item2.m_TimeStamp;
return ii < 0; if( ii == 0 )
return item1.m_Uuid < item2.m_Uuid; // ensure a deterministic sort
else
return ii < 0;
} }
@ -92,41 +94,41 @@ bool SCH_REFERENCE_LIST::sortByRefAndValue( const SCH_REFERENCE& item1,
const SCH_REFERENCE& item2 ) const SCH_REFERENCE& item2 )
{ {
int ii = item1.CompareRef( item2 ); int ii = item1.CompareRef( item2 );
if( ii == 0 ) if( ii == 0 )
ii = item1.CompareValue( item2 ); ii = item1.CompareValue( item2 );
if( ii == 0 ) if( ii == 0 )
ii = item1.m_Unit - item2.m_Unit; ii = item1.m_Unit - item2.m_Unit;
if( ii == 0 ) if( ii == 0 )
ii = item1.m_SheetNum - item2.m_SheetNum; ii = item1.m_SheetNum - item2.m_SheetNum;
if( ii == 0 ) if( ii == 0 )
ii = item1.m_CmpPos.x - item2.m_CmpPos.x; ii = item1.m_CmpPos.x - item2.m_CmpPos.x;
if( ii == 0 ) if( ii == 0 )
ii = item1.m_CmpPos.y - item2.m_CmpPos.y; ii = item1.m_CmpPos.y - item2.m_CmpPos.y;
if( ii == 0 )
ii = item1.m_TimeStamp - item2.m_TimeStamp;
return ii < 0; if( ii == 0 )
return item1.m_Uuid < item2.m_Uuid; // ensure a deterministic sort
else
return ii < 0;
} }
bool SCH_REFERENCE_LIST::sortByReferenceOnly( const SCH_REFERENCE& item1, bool SCH_REFERENCE_LIST::sortByReferenceOnly( const SCH_REFERENCE& item1,
const SCH_REFERENCE& item2 ) const SCH_REFERENCE& item2 )
{ {
int ii; int ii = UTIL::RefDesStringCompare( item1.GetRef(), item2.GetRef() );
ii = UTIL::RefDesStringCompare( item1.GetRef(), item2.GetRef() );
if( ii == 0 ) if( ii == 0 )
{
ii = item1.m_RootCmp->GetField( VALUE )->GetText().CmpNoCase( item2.m_RootCmp->GetField( VALUE )->GetText() );
}
if( ii == 0 )
{
ii = item1.m_Unit - item2.m_Unit; ii = item1.m_Unit - item2.m_Unit;
}
return ii < 0; if( ii == 0 )
return item1.m_Uuid < item2.m_Uuid; // ensure a deterministic sort
else
return ii < 0;
} }
@ -136,70 +138,43 @@ bool SCH_REFERENCE_LIST::sortByTimeStamp( const SCH_REFERENCE& item1,
int ii = item1.m_SheetPath.Cmp( item2.m_SheetPath ); int ii = item1.m_SheetPath.Cmp( item2.m_SheetPath );
if( ii == 0 ) if( ii == 0 )
ii = item1.m_TimeStamp - item2.m_TimeStamp; return item1.m_Uuid < item2.m_Uuid; // ensure a deterministic sort
else
return ii < 0; return ii < 0;
} }
int SCH_REFERENCE_LIST::FindUnit( size_t aIndex, int aUnit ) int SCH_REFERENCE_LIST::FindUnit( size_t aIndex, int aUnit )
{ {
int NumRef; int NumRef;
NumRef = componentFlatList[aIndex].m_NumRef; NumRef = flatList[aIndex].m_NumRef;
for( size_t ii = 0; ii < componentFlatList.size(); ii++ ) for( size_t ii = 0; ii < flatList.size(); ii++ )
{ {
if( ( aIndex == ii ) if( ( aIndex == ii )
|| ( componentFlatList[ii].m_IsNew ) || ( flatList[ii].m_IsNew )
|| ( componentFlatList[ii].m_NumRef != NumRef ) || ( flatList[ii].m_NumRef != NumRef )
|| ( componentFlatList[aIndex].CompareRef( componentFlatList[ii] ) != 0 ) ) || ( flatList[aIndex].CompareRef( flatList[ii] ) != 0 ) )
continue; continue;
if( componentFlatList[ii].m_Unit == aUnit ) if( flatList[ii].m_Unit == aUnit )
return (int) ii; return (int) ii;
} }
return -1; return -1;
} }
int SCH_REFERENCE_LIST::FindRefByPath( const wxString& aPath ) const int SCH_REFERENCE_LIST::FindRefByPath( const wxString& aPath ) const
{ {
for( size_t i = 0; i < componentFlatList.size(); ++i ) for( size_t i = 0; i < flatList.size(); ++i )
if( componentFlatList[i].GetPath() == aPath )
return i;
return -1;
}
void SCH_REFERENCE_LIST::RemoveSubComponentsFromList()
{
SCH_COMPONENT* libItem;
wxString oldName;
wxString currName;
// The component list **MUST** be sorted by reference and by unit number
// in order to find all parts of a component
SortByReferenceOnly();
for( unsigned ii = 0; ii < componentFlatList.size(); ii++ )
{ {
if( flatList[i].GetPath() == aPath )
libItem = componentFlatList[ii].m_RootCmp; return i;
if( libItem == NULL )
continue;
currName = componentFlatList[ii].GetRef();
if( !oldName.IsEmpty() )
{
if( oldName == currName ) // currName is a subpart of oldName: remove it
{
componentFlatList.erase( componentFlatList.begin() + ii );
ii--;
}
}
oldName = currName;
} }
return -1;
} }
@ -207,11 +182,10 @@ void SCH_REFERENCE_LIST::GetRefsInUse( int aIndex, std::vector< int >& aIdList,
{ {
aIdList.clear(); aIdList.clear();
for( unsigned ii = 0; ii < componentFlatList.size(); ii++ ) for( SCH_REFERENCE& ref : flatList )
{ {
if( ( componentFlatList[aIndex].CompareRef( componentFlatList[ii] ) == 0 ) if( flatList[aIndex].CompareRef( ref ) == 0 && ref.m_NumRef >= aMinRefId )
&& ( componentFlatList[ii].m_NumRef >= aMinRefId ) ) aIdList.push_back( ref.m_NumRef );
aIdList.push_back( componentFlatList[ii].m_NumRef );
} }
sort( aIdList.begin(), aIdList.end() ); sort( aIdList.begin(), aIdList.end() );
@ -230,15 +204,15 @@ int SCH_REFERENCE_LIST::GetLastReference( int aIndex, int aMinValue )
{ {
int lastNumber = aMinValue; int lastNumber = aMinValue;
for( unsigned ii = 0; ii < componentFlatList.size(); ii++ ) for( SCH_REFERENCE& ref : flatList )
{ {
// search only for the current reference prefix: // search only for the current reference prefix:
if( componentFlatList[aIndex].CompareRef( componentFlatList[ii] ) != 0 ) if( flatList[aIndex].CompareRef( ref ) != 0 )
continue; continue;
// update max value for the current reference prefix // update max value for the current reference prefix
if( lastNumber < componentFlatList[ii].m_NumRef ) if( lastNumber < ref.m_NumRef )
lastNumber = componentFlatList[ii].m_NumRef; lastNumber = ref.m_NumRef;
} }
return lastNumber; return lastNumber;
@ -296,9 +270,9 @@ wxString buildFullReference( const SCH_REFERENCE& aItem, int aUnitNumber = -1 )
void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId, int aStartNumber, void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId, int aStartNumber,
SCH_MULTI_UNIT_REFERENCE_MAP aLockedUnitMap ) SCH_MULTI_UNIT_REFERENCE_MAP aLockedUnitMap )
{ {
if ( componentFlatList.size() == 0 ) if ( flatList.size() == 0 )
return; return;
int LastReferenceNumber = 0; int LastReferenceNumber = 0;
@ -312,20 +286,11 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId, int
unsigned first = 0; unsigned first = 0;
// calculate the last used number for this reference prefix: // calculate the last used number for this reference prefix:
#ifdef USE_OLD_ALGO
int minRefId = 0;
// when using sheet number, ensure ref number >= sheet number* aSheetIntervalId
if( aUseSheetNum )
minRefId = componentFlatList[first].m_SheetNum * aSheetIntervalId;
LastReferenceNumber = GetLastReference( first, minRefId );
#else
int minRefId; int minRefId;
// when using sheet number, ensure ref number >= sheet number* aSheetIntervalId // when using sheet number, ensure ref number >= sheet number* aSheetIntervalId
if( aUseSheetNum ) if( aUseSheetNum )
minRefId = componentFlatList[first].m_SheetNum * aSheetIntervalId + 1; minRefId = flatList[first].m_SheetNum * aSheetIntervalId + 1;
else else
minRefId = aStartNumber + 1; minRefId = aStartNumber + 1;
@ -345,10 +310,10 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId, int
// Will be refilled for each new reference prefix. // Will be refilled for each new reference prefix.
std::vector<int>idList; std::vector<int>idList;
GetRefsInUse( first, idList, minRefId ); GetRefsInUse( first, idList, minRefId );
#endif
for( unsigned ii = 0; ii < componentFlatList.size(); ii++ ) for( unsigned ii = 0; ii < flatList.size(); ii++ )
{ {
auto& ref_unit = componentFlatList[ii]; auto& ref_unit = flatList[ii];
if( ref_unit.m_Flag ) if( ref_unit.m_Flag )
continue; continue;
@ -372,21 +337,12 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId, int
if( lockedList != NULL ) break; if( lockedList != NULL ) break;
} }
if( ( componentFlatList[first].CompareRef( ref_unit ) != 0 ) if( ( flatList[first].CompareRef( ref_unit ) != 0 )
|| ( aUseSheetNum && ( componentFlatList[first].m_SheetNum != ref_unit.m_SheetNum ) ) ) || ( aUseSheetNum && ( flatList[first].m_SheetNum != ref_unit.m_SheetNum ) ) )
{ {
// New reference found: we need a new ref number for this reference // New reference found: we need a new ref number for this reference
first = ii; first = ii;
#ifdef USE_OLD_ALGO
minRefId = 0;
// when using sheet number, ensure ref number >= sheet number* aSheetIntervalId
if( aUseSheetNum )
minRefId = ref_unit.m_SheetNum * aSheetIntervalId;
LastReferenceNumber = GetLastReference( ii, minRefId );
#else
// when using sheet number, ensure ref number >= sheet number* aSheetIntervalId // when using sheet number, ensure ref number >= sheet number* aSheetIntervalId
if( aUseSheetNum ) if( aUseSheetNum )
minRefId = ref_unit.m_SheetNum * aSheetIntervalId + 1; minRefId = ref_unit.m_SheetNum * aSheetIntervalId + 1;
@ -394,7 +350,6 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId, int
minRefId = aStartNumber + 1; minRefId = aStartNumber + 1;
GetRefsInUse( first, idList, minRefId ); GetRefsInUse( first, idList, minRefId );
#endif
} }
// Annotation of one part per package components (trivial case). // Annotation of one part per package components (trivial case).
@ -402,11 +357,7 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId, int
{ {
if( ref_unit.m_IsNew ) if( ref_unit.m_IsNew )
{ {
#ifdef USE_OLD_ALGO
LastReferenceNumber++;
#else
LastReferenceNumber = CreateFirstFreeRefId( idList, minRefId ); LastReferenceNumber = CreateFirstFreeRefId( idList, minRefId );
#endif
ref_unit.m_NumRef = LastReferenceNumber; ref_unit.m_NumRef = LastReferenceNumber;
} }
@ -421,11 +372,7 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId, int
if( ref_unit.m_IsNew ) if( ref_unit.m_IsNew )
{ {
#ifdef USE_OLD_ALGO
LastReferenceNumber++;
#else
LastReferenceNumber = CreateFirstFreeRefId( idList, minRefId ); LastReferenceNumber = CreateFirstFreeRefId( idList, minRefId );
#endif
ref_unit.m_NumRef = LastReferenceNumber; ref_unit.m_NumRef = LastReferenceNumber;
if( !ref_unit.IsUnitsLocked() ) if( !ref_unit.IsUnitsLocked() )
@ -459,9 +406,9 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId, int
continue; continue;
// Find the matching component // Find the matching component
for( unsigned jj = ii + 1; jj < componentFlatList.size(); jj++ ) for( unsigned jj = ii + 1; jj < flatList.size(); jj++ )
{ {
if( ! thisRef.IsSameInstance( componentFlatList[jj] ) ) if( ! thisRef.IsSameInstance( flatList[jj] ) )
continue; continue;
wxString ref_candidate = buildFullReference( ref_unit, thisRef.m_Unit ); wxString ref_candidate = buildFullReference( ref_unit, thisRef.m_Unit );
@ -471,10 +418,10 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId, int
// multiunits components have duplicate references) // multiunits components have duplicate references)
if( inUseRefs.find( ref_candidate ) == inUseRefs.end() ) if( inUseRefs.find( ref_candidate ) == inUseRefs.end() )
{ {
componentFlatList[jj].m_NumRef = ref_unit.m_NumRef; flatList[jj].m_NumRef = ref_unit.m_NumRef;
componentFlatList[jj].m_Unit = thisRef.m_Unit; flatList[jj].m_Unit = thisRef.m_Unit;
componentFlatList[jj].m_IsNew = false; flatList[jj].m_IsNew = false;
componentFlatList[jj].m_Flag = 1; flatList[jj].m_Flag = 1;
// lock this new full reference // lock this new full reference
inUseRefs.insert( ref_candidate ); inUseRefs.insert( ref_candidate );
break; break;
@ -499,9 +446,9 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId, int
continue; // this unit exists for this reference (unit already annotated) continue; // this unit exists for this reference (unit already annotated)
// Search a component to annotate ( same prefix, same value, not annotated) // Search a component to annotate ( same prefix, same value, not annotated)
for( unsigned jj = ii + 1; jj < componentFlatList.size(); jj++ ) for( unsigned jj = ii + 1; jj < flatList.size(); jj++ )
{ {
auto& cmp_unit = componentFlatList[jj]; auto& cmp_unit = flatList[jj];
if( cmp_unit.m_Flag ) // already tested if( cmp_unit.m_Flag ) // already tested
continue; continue;
@ -538,33 +485,6 @@ void SCH_REFERENCE_LIST::Annotate( bool aUseSheetNum, int aSheetIntervalId, int
} }
} }
int SCH_REFERENCE_LIST::checkForDuplicatedElements( REPORTER& aReporter )
{
int error = 0;
wxString msg;
for( size_t ii = 0; ii < componentFlatList.size() - 1; ii++ )
{
if( ( componentFlatList[ii].m_TimeStamp != componentFlatList[ii + 1].m_TimeStamp )
|| ( componentFlatList[ii].GetSheetPath()
!= componentFlatList[ii + 1].GetSheetPath() ) )
continue;
// Same time stamp found.
wxString full_path;
full_path.Printf( wxT( "%s%8.8X" ), GetChars( componentFlatList[ii].GetSheetPath().Path() ),
componentFlatList[ii].m_TimeStamp );
msg.Printf( _( "Duplicate time stamp (%s) for %s%d and %s%d" ), full_path,
componentFlatList[ii].GetRef(), componentFlatList[ii].m_NumRef,
componentFlatList[ii + 1].GetRef(), componentFlatList[ii + 1].m_NumRef );
aReporter.Report( msg, REPORTER::RPT_WARNING );
error++;
}
return error;
}
int SCH_REFERENCE_LIST::CheckAnnotation( REPORTER& aReporter ) int SCH_REFERENCE_LIST::CheckAnnotation( REPORTER& aReporter )
{ {
int error = 0; int error = 0;
@ -577,32 +497,32 @@ int SCH_REFERENCE_LIST::CheckAnnotation( REPORTER& aReporter )
SplitReferences(); SplitReferences();
// count not yet annotated items or annotation error. // count not yet annotated items or annotation error.
for( unsigned ii = 0; ii < componentFlatList.size(); ii++ ) for( unsigned ii = 0; ii < flatList.size(); ii++ )
{ {
msg.Empty(); msg.Empty();
tmp.Empty(); tmp.Empty();
if( componentFlatList[ii].m_IsNew ) // Not yet annotated if( flatList[ii].m_IsNew ) // Not yet annotated
{ {
if( componentFlatList[ii].m_NumRef >= 0 ) if( flatList[ii].m_NumRef >= 0 )
tmp << componentFlatList[ii].m_NumRef; tmp << flatList[ii].m_NumRef;
else else
tmp = wxT( "?" ); tmp = wxT( "?" );
if( ( componentFlatList[ii].m_Unit > 0 ) if( ( flatList[ii].m_Unit > 0 )
&& ( componentFlatList[ii].m_Unit < 0x7FFFFFFF ) ) && ( flatList[ii].m_Unit < 0x7FFFFFFF ) )
{ {
msg.Printf( _( "Item not annotated: %s%s (unit %d)\n" ), msg.Printf( _( "Item not annotated: %s%s (unit %d)\n" ),
componentFlatList[ii].GetRef(), flatList[ii].GetRef(),
tmp, tmp,
componentFlatList[ii].m_Unit ); flatList[ii].m_Unit );
} }
else else
{ {
msg.Printf( _( "Item not annotated: %s%s\n" ), msg.Printf( _( "Item not annotated: %s%s\n" ),
GetChars( componentFlatList[ii].GetRef() ), flatList[ii].GetRef(),
GetChars( tmp ) ); tmp );
} }
aReporter.Report( msg, REPORTER::RPT_WARNING ); aReporter.Report( msg, REPORTER::RPT_WARNING );
@ -613,19 +533,19 @@ int SCH_REFERENCE_LIST::CheckAnnotation( REPORTER& aReporter )
// Error if unit number selected does not exist ( greater than the number of // Error if unit number selected does not exist ( greater than the number of
// parts in the component ). This can happen if a component has changed in a // parts in the component ). This can happen if a component has changed in a
// library after a previous annotation. // library after a previous annotation.
if( std::max( componentFlatList[ii].GetLibPart()->GetUnitCount(), 1 ) if( std::max( flatList[ii].GetLibPart()->GetUnitCount(), 1 )
< componentFlatList[ii].m_Unit ) < flatList[ii].m_Unit )
{ {
if( componentFlatList[ii].m_NumRef >= 0 ) if( flatList[ii].m_NumRef >= 0 )
tmp << componentFlatList[ii].m_NumRef; tmp << flatList[ii].m_NumRef;
else else
tmp = wxT( "?" ); tmp = wxT( "?" );
msg.Printf( _( "Error: symbol %s%s unit %d and symbol has only %d units defined\n" ), msg.Printf( _( "Error: symbol %s%s unit %d and symbol has only %d units defined\n" ),
componentFlatList[ii].GetRef(), flatList[ii].GetRef(),
tmp, tmp,
componentFlatList[ii].m_Unit, flatList[ii].m_Unit,
componentFlatList[ii].GetLibPart()->GetUnitCount() ); flatList[ii].GetLibPart()->GetUnitCount() );
aReporter.Report( msg, REPORTER::RPT_ERROR ); aReporter.Report( msg, REPORTER::RPT_ERROR );
error++; error++;
@ -637,37 +557,37 @@ int SCH_REFERENCE_LIST::CheckAnnotation( REPORTER& aReporter )
return error; return error;
// count the duplicated elements (if all are annotated) // count the duplicated elements (if all are annotated)
int imax = componentFlatList.size() - 1; int imax = flatList.size() - 1;
for( int ii = 0; ii < imax; ii++ ) for( int ii = 0; ii < imax; ii++ )
{ {
msg.Empty(); msg.Empty();
tmp.Empty(); tmp.Empty();
if( ( componentFlatList[ii].CompareRef( componentFlatList[ii + 1] ) != 0 ) if( ( flatList[ii].CompareRef( flatList[ii + 1] ) != 0 )
|| ( componentFlatList[ii].m_NumRef != componentFlatList[ii + 1].m_NumRef ) ) || ( flatList[ii].m_NumRef != flatList[ii + 1].m_NumRef ) )
continue; continue;
// Same reference found. If same unit, error! // Same reference found. If same unit, error!
if( componentFlatList[ii].m_Unit == componentFlatList[ii + 1].m_Unit ) if( flatList[ii].m_Unit == flatList[ii + 1].m_Unit )
{ {
if( componentFlatList[ii].m_NumRef >= 0 ) if( flatList[ii].m_NumRef >= 0 )
tmp << componentFlatList[ii].m_NumRef; tmp << flatList[ii].m_NumRef;
else else
tmp = wxT( "?" ); tmp = wxT( "?" );
if( ( componentFlatList[ii].m_Unit > 0 ) if( ( flatList[ii].m_Unit > 0 )
&& ( componentFlatList[ii].m_Unit < 0x7FFFFFFF ) ) && ( flatList[ii].m_Unit < 0x7FFFFFFF ) )
{ {
msg.Printf( _( "Multiple item %s%s (unit %d)\n" ), msg.Printf( _( "Multiple item %s%s (unit %d)\n" ),
componentFlatList[ii].GetRef(), flatList[ii].GetRef(),
tmp, tmp,
componentFlatList[ii].m_Unit ); flatList[ii].m_Unit );
} }
else else
{ {
msg.Printf( _( "Multiple item %s%s\n" ), msg.Printf( _( "Multiple item %s%s\n" ),
componentFlatList[ii].GetRef(), flatList[ii].GetRef(),
tmp ); tmp );
} }
@ -678,27 +598,27 @@ int SCH_REFERENCE_LIST::CheckAnnotation( REPORTER& aReporter )
/* Test error if units are different but number of parts per package /* Test error if units are different but number of parts per package
* too high (ex U3 ( 1 part) and we find U3B this is an error) */ * too high (ex U3 ( 1 part) and we find U3B this is an error) */
if( componentFlatList[ii].GetLibPart()->GetUnitCount() if( flatList[ii].GetLibPart()->GetUnitCount()
!= componentFlatList[ii + 1].GetLibPart()->GetUnitCount() ) != flatList[ ii + 1].GetLibPart()->GetUnitCount() )
{ {
if( componentFlatList[ii].m_NumRef >= 0 ) if( flatList[ii].m_NumRef >= 0 )
tmp << componentFlatList[ii].m_NumRef; tmp << flatList[ii].m_NumRef;
else else
tmp = wxT( "?" ); tmp = wxT( "?" );
if( ( componentFlatList[ii].m_Unit > 0 ) if( ( flatList[ii].m_Unit > 0 )
&& ( componentFlatList[ii].m_Unit < 0x7FFFFFFF ) ) && ( flatList[ii].m_Unit < 0x7FFFFFFF ) )
{ {
msg.Printf( _( "Multiple item %s%s (unit %d)\n" ), msg.Printf( _( "Multiple item %s%s (unit %d)\n" ),
GetChars( componentFlatList[ii].GetRef() ), flatList[ii].GetRef(),
GetChars( tmp ), tmp,
componentFlatList[ii].m_Unit ); flatList[ii].m_Unit );
} }
else else
{ {
msg.Printf( _( "Multiple item %s%s\n" ), msg.Printf( _( "Multiple item %s%s\n" ),
GetChars( componentFlatList[ii].GetRef() ), flatList[ii].GetRef(),
GetChars( tmp ) ); tmp );
} }
aReporter.Report( msg, REPORTER::RPT_ERROR ); aReporter.Report( msg, REPORTER::RPT_ERROR );
@ -708,27 +628,23 @@ int SCH_REFERENCE_LIST::CheckAnnotation( REPORTER& aReporter )
// Error if values are different between units, for the same reference // Error if values are different between units, for the same reference
int next = ii + 1; int next = ii + 1;
if( componentFlatList[ii].CompareValue( componentFlatList[next] ) != 0 ) if( flatList[ii].CompareValue( flatList[next] ) != 0 )
{ {
msg.Printf( _( "Different values for %s%d%s (%s) and %s%d%s (%s)" ), msg.Printf( _( "Different values for %s%d%s (%s) and %s%d%s (%s)" ),
componentFlatList[ii].GetRef(), flatList[ii].GetRef(),
componentFlatList[ii].m_NumRef, flatList[ii].m_NumRef,
LIB_PART::SubReference( componentFlatList[ii].m_Unit ), LIB_PART::SubReference( flatList[ii].m_Unit ),
componentFlatList[ii].m_Value->GetText(), flatList[ii].m_Value->GetText(),
componentFlatList[next].GetRef(), flatList[next].GetRef(),
componentFlatList[next].m_NumRef, flatList[next].m_NumRef,
LIB_PART::SubReference( componentFlatList[next].m_Unit ), LIB_PART::SubReference( flatList[next].m_Unit ),
componentFlatList[next].m_Value->GetText() ); flatList[next].m_Value->GetText() );
aReporter.Report( msg, REPORTER::RPT_ERROR ); aReporter.Report( msg, REPORTER::RPT_ERROR );
error++; error++;
} }
} }
// count the duplicated time stamps
SortByTimeStamp();
error += checkForDuplicatedElements( aReporter );
return error; return error;
} }
@ -745,7 +661,7 @@ SCH_REFERENCE::SCH_REFERENCE( SCH_COMPONENT* aComponent, LIB_PART* aLibPart,
m_SheetPath = aSheetPath; m_SheetPath = aSheetPath;
m_IsNew = false; m_IsNew = false;
m_Flag = 0; m_Flag = 0;
m_TimeStamp = aComponent->GetTimeStamp(); m_Uuid = aComponent->m_Uuid;
m_CmpPos = aComponent->GetPosition(); m_CmpPos = aComponent->GetPosition();
m_SheetNum = 0; m_SheetNum = 0;
@ -769,9 +685,7 @@ void SCH_REFERENCE::Annotate()
if( m_NumRef < 0 ) if( m_NumRef < 0 )
m_Ref += '?'; m_Ref += '?';
else else
{
m_Ref = TO_UTF8( GetRef() << GetRefNumber() ); m_Ref = TO_UTF8( GetRef() << GetRefNumber() );
}
m_RootCmp->SetRef( &m_SheetPath, FROM_UTF8( m_Ref.c_str() ) ); m_RootCmp->SetRef( &m_SheetPath, FROM_UTF8( m_Ref.c_str() ) );
m_RootCmp->SetUnit( m_Unit ); m_RootCmp->SetUnit( m_Unit );

View File

@ -171,7 +171,6 @@ bool CONNECTION_SUBGRAPH::ResolveDrivers( bool aCreateMarkers )
second_item->GetPosition(); second_item->GetPosition();
auto marker = new SCH_MARKER(); auto marker = new SCH_MARKER();
marker->SetTimeStamp( GetNewTimeStamp() );
marker->SetMarkerType( MARKER_BASE::MARKER_ERC ); marker->SetMarkerType( MARKER_BASE::MARKER_ERC );
marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_WARNING ); marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_WARNING );
marker->SetData( ERCE_DRIVER_CONFLICT, p0, msg, p1 ); marker->SetData( ERCE_DRIVER_CONFLICT, p0, msg, p1 );
@ -1987,7 +1986,6 @@ bool CONNECTION_GRAPH::ercCheckBusToNetConflicts( const CONNECTION_SUBGRAPH* aSu
net_item->GetSelectMenuText( m_frame->GetUserUnits() ) ); net_item->GetSelectMenuText( m_frame->GetUserUnits() ) );
auto marker = new SCH_MARKER(); auto marker = new SCH_MARKER();
marker->SetTimeStamp( GetNewTimeStamp() );
marker->SetMarkerType( MARKER_BASE::MARKER_ERC ); marker->SetMarkerType( MARKER_BASE::MARKER_ERC );
marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_ERROR ); marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_ERROR );
marker->SetData( ERCE_BUS_TO_NET_CONFLICT, marker->SetData( ERCE_BUS_TO_NET_CONFLICT,
@ -2068,7 +2066,6 @@ bool CONNECTION_GRAPH::ercCheckBusToBusConflicts( const CONNECTION_SUBGRAPH* aSu
port->GetSelectMenuText( m_frame->GetUserUnits() ) ); port->GetSelectMenuText( m_frame->GetUserUnits() ) );
auto marker = new SCH_MARKER(); auto marker = new SCH_MARKER();
marker->SetTimeStamp( GetNewTimeStamp() );
marker->SetMarkerType( MARKER_BASE::MARKER_ERC ); marker->SetMarkerType( MARKER_BASE::MARKER_ERC );
marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_ERROR ); marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_ERROR );
marker->SetData( ERCE_BUS_TO_BUS_CONFLICT, marker->SetData( ERCE_BUS_TO_BUS_CONFLICT,
@ -2162,7 +2159,6 @@ bool CONNECTION_GRAPH::ercCheckBusToBusEntryConflicts( const CONNECTION_SUBGRAPH
bus_wire->Connection( sheet )->Name( true ) ); bus_wire->Connection( sheet )->Name( true ) );
auto marker = new SCH_MARKER(); auto marker = new SCH_MARKER();
marker->SetTimeStamp( GetNewTimeStamp() );
marker->SetMarkerType( MARKER_BASE::MARKER_ERC ); marker->SetMarkerType( MARKER_BASE::MARKER_ERC );
marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_WARNING ); marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_WARNING );
marker->SetData( ERCE_BUS_ENTRY_CONFLICT, marker->SetData( ERCE_BUS_ENTRY_CONFLICT,
@ -2229,7 +2225,6 @@ bool CONNECTION_GRAPH::ercCheckNoConnects( const CONNECTION_SUBGRAPH* aSubgraph,
pin->GetParentComponent()->GetRef( &aSubgraph->m_sheet ) ); pin->GetParentComponent()->GetRef( &aSubgraph->m_sheet ) );
auto marker = new SCH_MARKER(); auto marker = new SCH_MARKER();
marker->SetTimeStamp( GetNewTimeStamp() );
marker->SetMarkerType( MARKER_BASE::MARKER_ERC ); marker->SetMarkerType( MARKER_BASE::MARKER_ERC );
marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_WARNING ); marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_WARNING );
marker->SetData( ERCE_NOCONNECT_CONNECTED, pos, msg, pos ); marker->SetData( ERCE_NOCONNECT_CONNECTED, pos, msg, pos );
@ -2249,7 +2244,6 @@ bool CONNECTION_GRAPH::ercCheckNoConnects( const CONNECTION_SUBGRAPH* aSubgraph,
msg.Printf( _( "No-connect marker is not connected to anything" ) ); msg.Printf( _( "No-connect marker is not connected to anything" ) );
auto marker = new SCH_MARKER(); auto marker = new SCH_MARKER();
marker->SetTimeStamp( GetNewTimeStamp() );
marker->SetMarkerType( MARKER_BASE::MARKER_ERC ); marker->SetMarkerType( MARKER_BASE::MARKER_ERC );
marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_WARNING ); marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_WARNING );
marker->SetData( ERCE_NOCONNECT_NOT_CONNECTED, pos, msg, pos ); marker->SetData( ERCE_NOCONNECT_NOT_CONNECTED, pos, msg, pos );
@ -2315,7 +2309,6 @@ bool CONNECTION_GRAPH::ercCheckNoConnects( const CONNECTION_SUBGRAPH* aSubgraph,
pin->GetParentComponent()->GetRef( &aSubgraph->m_sheet ) ); pin->GetParentComponent()->GetRef( &aSubgraph->m_sheet ) );
auto marker = new SCH_MARKER(); auto marker = new SCH_MARKER();
marker->SetTimeStamp( GetNewTimeStamp() );
marker->SetMarkerType( MARKER_BASE::MARKER_ERC ); marker->SetMarkerType( MARKER_BASE::MARKER_ERC );
marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_WARNING ); marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_WARNING );
marker->SetData( ERCE_PIN_NOT_CONNECTED, pos, msg, pos ); marker->SetData( ERCE_PIN_NOT_CONNECTED, pos, msg, pos );
@ -2423,7 +2416,6 @@ bool CONNECTION_GRAPH::ercCheckLabels( const CONNECTION_SUBGRAPH* aSubgraph,
msg.Printf( _( "%s %s is not connected anywhere else in the schematic." ), msg.Printf( _( "%s %s is not connected anywhere else in the schematic." ),
prefix, GetChars( text->ShortenedShownText() ) ); prefix, GetChars( text->ShortenedShownText() ) );
marker->SetTimeStamp( GetNewTimeStamp() );
marker->SetMarkerType( MARKER_BASE::MARKER_ERC ); marker->SetMarkerType( MARKER_BASE::MARKER_ERC );
marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_WARNING ); marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_WARNING );
marker->SetData( type, pos, msg, pos ); marker->SetData( type, pos, msg, pos );

View File

@ -3,7 +3,7 @@
* *
* Copyright (C) 2019 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2019 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net> * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 2004-2019 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2004-2020 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
@ -271,8 +271,8 @@ std::string FormatProbeItem( EDA_ITEM* aItem, SCH_COMPONENT* aComp )
case SCH_SHEET_T: case SCH_SHEET_T:
{ {
SCH_SHEET* sheet = (SCH_SHEET*)aItem; SCH_SHEET* sheet = (SCH_SHEET*)aItem;
return StrPrintf( "$SHEET: \"%8.8lX\"", (unsigned long) sheet->GetTimeStamp() ); return StrPrintf( "$SHEET: \"%s\"", TO_UTF8( sheet->m_Uuid.AsString() ) );
} }
case SCH_PIN_T: case SCH_PIN_T:

View File

@ -206,8 +206,7 @@ bool DIALOG_EDIT_COMPONENT_IN_SCHEMATIC::TransferDataToWindow()
m_rbMirror->SetSelection( 0 ); m_rbMirror->SetSelection( 0 );
// Set the component's unique ID time stamp. // Set the component's unique ID time stamp.
m_textCtrlTimeStamp->SetValue( wxString::Format( wxT( "%8.8lX" ), m_textCtrlTimeStamp->SetValue( m_cmp->m_Uuid.AsString() );
(unsigned long) m_cmp->GetTimeStamp() ) );
// Set the component's library name. // Set the component's library name.
m_libraryNameTextCtrl->SetValue( m_cmp->GetLibId().Format() ); m_libraryNameTextCtrl->SetValue( m_cmp->GetLibId().Format() );

View File

@ -577,11 +577,13 @@ void DIALOG_ERC::TestErc( REPORTER& aReporter )
{ {
SCH_MARKER* marker = new SCH_MARKER(); SCH_MARKER* marker = new SCH_MARKER();
marker->SetTimeStamp( GetNewTimeStamp() );
marker->SetData( ERCE_DIFFERENT_UNIT_NET, item->m_Start, marker->SetData( ERCE_DIFFERENT_UNIT_NET, item->m_Start,
wxString::Format( _( "Pin %s on %s is connected to both %s and %s" ), wxString::Format( _( "Pin %s on %s is connected to both %s and %s" ),
item->m_PinNum, ref, pin_to_net_map[pin_name], item->GetNetName() ), item->m_PinNum,
item->m_Start ); ref,
pin_to_net_map[pin_name],
item->GetNetName() ),
item->m_Start );
marker->SetMarkerType( MARKER_BASE::MARKER_ERC ); marker->SetMarkerType( MARKER_BASE::MARKER_ERC );
marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_ERROR ); marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_ERROR );

View File

@ -2,7 +2,7 @@
* 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) 2017 Oliver Walters * Copyright (C) 2017 Oliver Walters
* Copyright (C) 2017-2019 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2017-2020 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
@ -184,7 +184,7 @@ protected:
// Data store // Data store
// A map of compID : fieldSet, where fieldSet is a map of fieldName : fieldValue // A map of compID : fieldSet, where fieldSet is a map of fieldName : fieldValue
std::map< timestamp_t, std::map<wxString, wxString> > m_dataStore; std::map< UUID, std::map<wxString, wxString> > m_dataStore;
public: public:
@ -206,8 +206,7 @@ public:
for( unsigned i = 0; i < m_componentRefs.GetCount(); ++i ) for( unsigned i = 0; i < m_componentRefs.GetCount(); ++i )
{ {
SCH_COMPONENT* comp = m_componentRefs[ i ].GetComp(); SCH_COMPONENT* comp = m_componentRefs[ i ].GetComp();
timestamp_t compID = comp->GetTimeStamp(); m_dataStore[ comp->m_Uuid ][ aFieldName ] = comp->GetFieldText( aFieldName, m_frame );
m_dataStore[ compID ][ aFieldName ] = comp->GetFieldText( aFieldName, m_frame );
} }
} }
@ -270,7 +269,7 @@ public:
} }
else // Other columns are either a single value or ROW_MULTI_ITEMS else // Other columns are either a single value or ROW_MULTI_ITEMS
{ {
timestamp_t compID = ref.GetComp()->GetTimeStamp(); const UUID& compID = ref.GetComp()->m_Uuid;
if( !m_dataStore.count( compID ) || if( !m_dataStore.count( compID ) ||
!m_dataStore[ compID ].count( m_fieldNames[ aCol ] ) ) !m_dataStore[ compID ].count( m_fieldNames[ aCol ] ) )
@ -331,7 +330,7 @@ public:
wxString fieldName = m_fieldNames[ aCol ]; wxString fieldName = m_fieldNames[ aCol ];
for( const auto& ref : rowGroup.m_Refs ) for( const auto& ref : rowGroup.m_Refs )
m_dataStore[ ref.GetComp()->GetTimeStamp() ][ fieldName ] = aValue; m_dataStore[ ref.GetComp()->m_Uuid ][ fieldName ] = aValue;
m_edited = true; m_edited = true;
} }
@ -419,8 +418,8 @@ public:
matchFound = true; matchFound = true;
} }
timestamp_t lhRefID = lhRef.GetComp()->GetTimeStamp(); const UUID& lhRefID = lhRef.GetComp()->m_Uuid;
timestamp_t rhRefID = rhRef.GetComp()->GetTimeStamp(); const UUID& rhRefID = rhRef.GetComp()->m_Uuid;
// Now check all the other columns. This must be done out of the dataStore // Now check all the other columns. This must be done out of the dataStore
// for the refresh button to work after editing. // for the refresh button to work after editing.
@ -598,7 +597,7 @@ public:
m_frame->SetCurrentSheet( m_componentRefs[i].GetSheetPath() ); m_frame->SetCurrentSheet( m_componentRefs[i].GetSheetPath() );
m_frame->SaveCopyInUndoList( &comp, UR_CHANGED, true ); m_frame->SaveCopyInUndoList( &comp, UR_CHANGED, true );
const std::map<wxString, wxString>& fieldStore = m_dataStore[comp.GetTimeStamp()]; const std::map<wxString, wxString>& fieldStore = m_dataStore[comp.m_Uuid];
for( const std::pair<wxString, wxString> srcData : fieldStore ) for( const std::pair<wxString, wxString> srcData : fieldStore )
{ {
@ -648,7 +647,7 @@ public:
for( unsigned compRef = 0; compRef < m_componentRefs.GetCount(); ++ compRef ) for( unsigned compRef = 0; compRef < m_componentRefs.GetCount(); ++ compRef )
{ {
timestamp_t compId = m_componentRefs[ compRef ].GetComp()->GetTimeStamp(); const UUID& compId = m_componentRefs[ compRef ].GetComp()->m_Uuid;
wxString text = m_dataStore[ compId ][ column_label ]; wxString text = m_dataStore[ compId ][ column_label ];
width = std::max( width, GetTextSize( text, GetView() ).x ); width = std::max( width, GetTextSize( text, GetView() ).x );
} }

View File

@ -90,8 +90,7 @@ bool DIALOG_SCH_SHEET_PROPS::TransferDataToWindow()
m_filenameTextSize.SetValue( m_sheet->GetFileNameSize() ); m_filenameTextSize.SetValue( m_sheet->GetFileNameSize() );
m_sheetnameTextSize.SetValue( m_sheet->GetSheetNameSize() ); m_sheetnameTextSize.SetValue( m_sheet->GetSheetNameSize() );
auto tstamp = wxString::Format( wxT( "%8.8lX" ), (unsigned long) m_sheet->GetTimeStamp() ); m_textCtrlTimeStamp->SetValue( m_sheet->m_Uuid.AsString() );
m_textCtrlTimeStamp->SetValue( tstamp );
return true; return true;
} }

View File

@ -185,7 +185,6 @@ int TestDuplicateSheetNames( bool aCreateMarker )
{ {
/* Create a new marker type ERC error*/ /* Create a new marker type ERC error*/
SCH_MARKER* marker = new SCH_MARKER(); SCH_MARKER* marker = new SCH_MARKER();
marker->SetTimeStamp( GetNewTimeStamp() );
marker->SetData( ERCE_DUPLICATE_SHEET_NAME, marker->SetData( ERCE_DUPLICATE_SHEET_NAME,
( (SCH_SHEET*) test_item )->GetPosition(), ( (SCH_SHEET*) test_item )->GetPosition(),
_( "Duplicate sheet name" ), _( "Duplicate sheet name" ),
@ -306,7 +305,6 @@ int TestMultiunitFootprints( SCH_SHEET_LIST& aSheetList )
wxPoint pos = unit->GetPosition(); wxPoint pos = unit->GetPosition();
SCH_MARKER* marker = new SCH_MARKER(); SCH_MARKER* marker = new SCH_MARKER();
marker->SetTimeStamp( GetNewTimeStamp() );
marker->SetData( ERCE_DIFFERENT_UNIT_FP, pos, msg, pos ); marker->SetData( ERCE_DIFFERENT_UNIT_FP, pos, msg, pos );
marker->SetMarkerType( MARKER_BASE::MARKER_ERC ); marker->SetMarkerType( MARKER_BASE::MARKER_ERC );
marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_WARNING ); marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_WARNING );
@ -332,8 +330,6 @@ void Diagnose( NETLIST_OBJECT* aNetItemRef, NETLIST_OBJECT* aNetItemTst, int aMi
/* Create new marker for ERC error. */ /* Create new marker for ERC error. */
marker = new SCH_MARKER(); marker = new SCH_MARKER();
marker->SetTimeStamp( GetNewTimeStamp() );
marker->SetMarkerType( MARKER_BASE::MARKER_ERC ); marker->SetMarkerType( MARKER_BASE::MARKER_ERC );
marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_WARNING ); marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_WARNING );
screen = aNetItemRef->m_SheetPath.LastScreen(); screen = aNetItemRef->m_SheetPath.LastScreen();
@ -827,8 +823,6 @@ static void SimilarLabelsDiagnose( NETLIST_OBJECT* aItemA, NETLIST_OBJECT* aItem
{ {
// Create new marker for ERC. // Create new marker for ERC.
SCH_MARKER* marker = new SCH_MARKER(); SCH_MARKER* marker = new SCH_MARKER();
marker->SetTimeStamp( GetNewTimeStamp() );
marker->SetMarkerType( MARKER_BASE::MARKER_ERC ); marker->SetMarkerType( MARKER_BASE::MARKER_ERC );
marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_WARNING ); marker->SetErrorLevel( MARKER_BASE::MARKER_SEVERITY_WARNING );
SCH_SCREEN* screen = aItemA->m_SheetPath.LastScreen(); SCH_SCREEN* screen = aItemA->m_SheetPath.LastScreen();

View File

@ -201,8 +201,6 @@ XNODE* NETLIST_EXPORTER_GENERIC::makeComponents()
{ {
XNODE* xcomps = node( "components" ); XNODE* xcomps = node( "components" );
wxString timeStamp;
m_ReferencesAlreadyFound.Clear(); m_ReferencesAlreadyFound.Clear();
SCH_SHEET_LIST sheetList( g_RootSheet ); SCH_SHEET_LIST sheetList( g_RootSheet );
@ -273,9 +271,7 @@ XNODE* NETLIST_EXPORTER_GENERIC::makeComponents()
xcomp->AddChild( xsheetpath = node( "sheetpath" ) ); xcomp->AddChild( xsheetpath = node( "sheetpath" ) );
xsheetpath->AddAttribute( "names", sheetList[i].PathHumanReadable() ); xsheetpath->AddAttribute( "names", sheetList[i].PathHumanReadable() );
xsheetpath->AddAttribute( "tstamps", sheetList[i].Path() ); xsheetpath->AddAttribute( "tstamps", sheetList[i].Path() );
xcomp->AddChild( node( "tstamp", comp->m_Uuid.AsString() ) );
timeStamp.Printf( "%8.8lX", (unsigned long)comp->GetTimeStamp() );
xcomp->AddChild( node( "tstamp", timeStamp ) );
} }
} }

View File

@ -138,8 +138,6 @@ SCH_COMPONENT::SCH_COMPONENT( LIB_PART& aPart, LIB_ID aLibId, SCH_SHEET_PATH* sh
m_part.reset( part.release() ); m_part.reset( part.release() );
m_fieldsAutoplaced = AUTOPLACED_NO; m_fieldsAutoplaced = AUTOPLACED_NO;
SetTimeStamp( GetNewTimeStamp() );
// Copy fields from the library component // Copy fields from the library component
UpdateFields( true, true ); UpdateFields( true, true );
@ -181,7 +179,7 @@ SCH_COMPONENT::SCH_COMPONENT( const SCH_COMPONENT& aComponent ) :
if( aComponent.m_part ) if( aComponent.m_part )
m_part.reset( new LIB_PART( *aComponent.m_part.get() ) ); m_part.reset( new LIB_PART( *aComponent.m_part.get() ) );
SetTimeStamp( aComponent.m_TimeStamp ); const_cast<UUID&>( m_Uuid ) = aComponent.m_Uuid;
m_transform = aComponent.m_transform; m_transform = aComponent.m_transform;
m_prefix = aComponent.m_prefix; m_prefix = aComponent.m_prefix;
@ -596,10 +594,7 @@ wxString SCH_COMPONENT::GetPath( const SCH_SHEET_PATH* sheet ) const
wxCHECK_MSG( sheet != NULL, wxEmptyString, wxCHECK_MSG( sheet != NULL, wxEmptyString,
wxT( "Cannot get component path with invalid sheet object." ) ); wxT( "Cannot get component path with invalid sheet object." ) );
wxString str; return sheet->Path() + m_Uuid.AsString();
str.Printf( wxT( "%8.8lX" ), (long unsigned) m_TimeStamp );
return sheet->Path() + str;
} }
@ -739,19 +734,6 @@ bool SCH_COMPONENT::IsAnnotated( const SCH_SHEET_PATH* aSheet )
} }
void SCH_COMPONENT::SetTimeStamp( timestamp_t aNewTimeStamp )
{
wxString string_timestamp, string_oldtimestamp;
string_timestamp.Printf( wxT( "%08lX" ), (long unsigned) aNewTimeStamp );
string_oldtimestamp.Printf( wxT( "%08lX" ), (long unsigned) m_TimeStamp );
EDA_ITEM::SetTimeStamp( aNewTimeStamp );
for( wxString& entry : m_PathsAndReferences )
entry.Replace( string_oldtimestamp.GetData(), string_timestamp.GetData() );
}
int SCH_COMPONENT::GetUnitSelection( const SCH_SHEET_PATH* aSheet ) const int SCH_COMPONENT::GetUnitSelection( const SCH_SHEET_PATH* aSheet ) const
{ {
wxString path = GetPath( aSheet ); wxString path = GetPath( aSheet );
@ -1101,8 +1083,7 @@ bool SCH_COMPONENT::AddSheetPathReferenceEntryIfMissing( const wxString& aSheetP
// The full component reference path is aSheetPathName + the component time stamp itself // The full component reference path is aSheetPathName + the component time stamp itself
// full_AR_path is the alternate reference path to search // full_AR_path is the alternate reference path to search
wxString full_AR_path = aSheetPathName wxString full_AR_path = aSheetPathName + m_Uuid.AsString();
+ wxString::Format( "%8.8lX", (unsigned long) GetTimeStamp() );
for( unsigned int ii = 0; ii < m_PathsAndReferences.GetCount(); ii++ ) for( unsigned int ii = 0; ii < m_PathsAndReferences.GetCount(); ii++ )
{ {
@ -1757,7 +1738,7 @@ bool SCH_COMPONENT::operator <( const SCH_ITEM& aItem ) const
if( m_Pos.y != component->m_Pos.y ) if( m_Pos.y != component->m_Pos.y )
return m_Pos.y < component->m_Pos.y; return m_Pos.y < component->m_Pos.y;
return GetTimeStamp() < aItem.GetTimeStamp(); return m_Uuid < aItem.m_Uuid; // Ensure deterministic sort
} }

View File

@ -326,15 +326,6 @@ public:
*/ */
bool AddSheetPathReferenceEntryIfMissing( const wxString& aSheetPathName ); bool AddSheetPathReferenceEntryIfMissing( const wxString& aSheetPathName );
/**
* Change the time stamp to \a aNewTimeStamp and updates the reference path.
*
* @see m_PathsAndReferences
*
* @param aNewTimeStamp = new time stamp
*/
void SetTimeStamp( timestamp_t aNewTimeStamp );
/** /**
* Clear the HIGHLIGHTED flag of all items of the component (fields, pins ...) * Clear the HIGHLIGHTED flag of all items of the component (fields, pins ...)
*/ */

View File

@ -588,8 +588,6 @@ void SCH_EAGLE_PLUGIN::loadSchematic( wxXmlNode* aSchematicNode )
std::unique_ptr<SCH_SHEET> sheet( new SCH_SHEET( pos ) ); std::unique_ptr<SCH_SHEET> sheet( new SCH_SHEET( pos ) );
SCH_SCREEN* screen = new SCH_SCREEN( m_kiway ); SCH_SCREEN* screen = new SCH_SCREEN( m_kiway );
sheet->SetTimeStamp(
GetNewTimeStamp() - i ); // minus the sheet index to make it unique.
sheet->SetParent( m_rootSheet->GetScreen() ); sheet->SetParent( m_rootSheet->GetScreen() );
sheet->SetScreen( screen ); sheet->SetScreen( screen );
sheet->GetScreen()->SetFileName( sheet->GetFileName() ); sheet->GetScreen()->SetFileName( sheet->GetFileName() );
@ -646,11 +644,9 @@ void SCH_EAGLE_PLUGIN::loadSchematic( wxXmlNode* aSchematicNode )
// Instantiate the missing component unit // Instantiate the missing component unit
int unit = unitEntry.first; int unit = unitEntry.first;
const wxString reference = origCmp->GetField( REFERENCE )->GetText(); const wxString reference = origCmp->GetField( REFERENCE )->GetText();
std::unique_ptr<SCH_COMPONENT> component( new SCH_COMPONENT( *origCmp ) ); std::unique_ptr<SCH_COMPONENT> component( (SCH_COMPONENT*) origCmp->Duplicate() );
component->SetUnitSelection( &sheetpath, unit ); component->SetUnitSelection( &sheetpath, unit );
component->SetUnit( unit ); component->SetUnit( unit );
component->SetTimeStamp(
EagleModuleTstamp( reference, origCmp->GetField( VALUE )->GetText(), unit ) );
component->SetOrientation( 0 ); component->SetOrientation( 0 );
component->AddHierarchicalReference( sheetpath.Path(), reference, unit ); component->AddHierarchicalReference( sheetpath.Path(), reference, unit );
@ -1102,17 +1098,15 @@ void SCH_EAGLE_PLUGIN::loadInstance( wxXmlNode* aInstanceNode )
auto p = elib->package.find( kisymbolname ); auto p = elib->package.find( kisymbolname );
if( p != elib->package.end() ) if( p != elib->package.end() )
{
package = p->second; package = p->second;
}
LIB_PART* part = LIB_PART* part =
m_pi->LoadSymbol( getLibFileName().GetFullPath(), kisymbolname, m_properties.get() ); m_pi->LoadSymbol( getLibFileName().GetFullPath(), kisymbolname, m_properties.get() );
if( !part ) if( !part )
{ {
wxLogMessage( wxString::Format( wxLogMessage( wxString::Format( _( "Could not find %s in the imported library" ),
_( "Could not find %s in the imported library" ), kisymbolname ) ); kisymbolname ) );
return; return;
} }
@ -1122,17 +1116,13 @@ void SCH_EAGLE_PLUGIN::loadInstance( wxXmlNode* aInstanceNode )
component->SetUnit( unit ); component->SetUnit( unit );
component->SetPosition( wxPoint( einstance.x.ToSchUnits(), -einstance.y.ToSchUnits() ) ); component->SetPosition( wxPoint( einstance.x.ToSchUnits(), -einstance.y.ToSchUnits() ) );
component->GetField( FOOTPRINT )->SetText( package ); component->GetField( FOOTPRINT )->SetText( package );
component->SetTimeStamp(
EagleModuleTstamp( einstance.part, epart->value ? *epart->value : "", unit ) );
if( einstance.rot ) if( einstance.rot )
{ {
component->SetOrientation( kiCadComponentRotation( einstance.rot->degrees ) ); component->SetOrientation( kiCadComponentRotation( einstance.rot->degrees ) );
if( einstance.rot->mirror ) if( einstance.rot->mirror )
{
component->MirrorY( einstance.x.ToSchUnits() ); component->MirrorY( einstance.x.ToSchUnits() );
}
} }
LIB_FIELDS partFields; LIB_FIELDS partFields;
@ -1158,10 +1148,7 @@ void SCH_EAGLE_PLUGIN::loadInstance( wxXmlNode* aInstanceNode )
SCH_SHEET_PATH sheetpath; SCH_SHEET_PATH sheetpath;
m_rootSheet->LocatePathOfScreen( screen, &sheetpath ); m_rootSheet->LocatePathOfScreen( screen, &sheetpath );
wxString current_sheetpath = sheetpath.Path(); wxString current_sheetpath = sheetpath.Path();
current_sheetpath += component->m_Uuid.AsString();
wxString tstamp;
tstamp.Printf( "%8.8lX", (unsigned long) component->GetTimeStamp() );
current_sheetpath += tstamp;
component->GetField( REFERENCE )->SetText( reference ); component->GetField( REFERENCE )->SetText( reference );
component->AddHierarchicalReference( current_sheetpath, reference, unit ); component->AddHierarchicalReference( current_sheetpath, reference, unit );

View File

@ -72,12 +72,12 @@ SCH_ITEM::~SCH_ITEM()
} }
SCH_ITEM* SCH_ITEM::Duplicate( bool doClone ) SCH_ITEM* SCH_ITEM::Duplicate( bool doClone ) const
{ {
SCH_ITEM* newItem = (SCH_ITEM*) Clone(); SCH_ITEM* newItem = (SCH_ITEM*) Clone();
if( doClone ) if( !doClone )
newItem->SetTimeStamp( GetTimeStamp() ); const_cast<UUID&>( newItem->m_Uuid ) = UUID();
newItem->ClearFlags( SELECTED | HIGHLIGHTED | BRIGHTENED ); newItem->ClearFlags( SELECTED | HIGHLIGHTED | BRIGHTENED );
@ -174,8 +174,8 @@ bool SCH_ITEM::operator < ( const SCH_ITEM& aItem ) const
if( Type() != aItem.Type() ) if( Type() != aItem.Type() )
return Type() < aItem.Type(); return Type() < aItem.Type();
if( GetTimeStamp() != aItem.GetTimeStamp() ) if( m_Uuid != aItem.m_Uuid )
return GetTimeStamp() < aItem.GetTimeStamp(); return m_Uuid < aItem.m_Uuid;
if( GetPosition().x != aItem.GetPosition().x ) if( GetPosition().x != aItem.GetPosition().x )
return GetPosition().x < aItem.GetPosition().x; return GetPosition().x < aItem.GetPosition().x;

View File

@ -181,7 +181,7 @@ public:
* @param doClone (default = false) indicates unique values (such as timestamp and * @param doClone (default = false) indicates unique values (such as timestamp and
* sheet name) should be duplicated. Use only for undo/redo operations. * sheet name) should be duplicated. Use only for undo/redo operations.
*/ */
SCH_ITEM* Duplicate( bool doClone = false ); SCH_ITEM* Duplicate( bool doClone = false ) const;
/** /**
* Virtual function IsMovableFromAnchorPoint * Virtual function IsMovableFromAnchorPoint

View File

@ -2,7 +2,7 @@
* 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) 2016 CERN * Copyright (C) 2016 CERN
* Copyright (C) 2016-2019 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2016-2020 KiCad Developers, see AUTHORS.txt for contributors.
* *
* @author Wayne Stambaugh <stambaughw@gmail.com> * @author Wayne Stambaugh <stambaughw@gmail.com>
* *
@ -193,8 +193,7 @@ static int parseInt( LINE_READER& aReader, const char* aLine, const char** aOutp
* @throw IO_ERROR on an unexpected end of line. * @throw IO_ERROR on an unexpected end of line.
* @throw PARSE_ERROR if the parsed token is not a valid integer. * @throw PARSE_ERROR if the parsed token is not a valid integer.
*/ */
static uint32_t parseHex( LINE_READER& aReader, const char* aLine, static uint32_t parseHex( LINE_READER& aReader, const char* aLine, const char** aOutput = NULL )
const char** aOutput = NULL )
{ {
if( !*aLine ) if( !*aLine )
SCH_PARSE_ERROR( _( "unexpected end of line" ), aReader, aLine ); SCH_PARSE_ERROR( _( "unexpected end of line" ), aReader, aLine );
@ -458,7 +457,7 @@ static void parseQuotedString( wxString& aString, LINE_READER& aReader,
{ {
const char* next = tmp; const char* next = tmp;
while( *next && *next == ' ' ) while( *next == ' ' )
next++; next++;
*aNextToken = next; *aNextToken = next;
@ -963,8 +962,6 @@ SCH_SHEET* SCH_LEGACY_PLUGIN::loadSheet( LINE_READER& aReader )
{ {
std::unique_ptr< SCH_SHEET > sheet( new SCH_SHEET() ); std::unique_ptr< SCH_SHEET > sheet( new SCH_SHEET() );
sheet->SetTimeStamp( GetNewTimeStamp() );
const char* line = aReader.ReadLine(); const char* line = aReader.ReadLine();
while( line != NULL ) while( line != NULL )
@ -983,9 +980,11 @@ SCH_SHEET* SCH_LEGACY_PLUGIN::loadSheet( LINE_READER& aReader )
size.SetHeight( Mils2Iu( parseInt( aReader, line, &line ) ) ); size.SetHeight( Mils2Iu( parseInt( aReader, line, &line ) ) );
sheet->SetSize( size ); sheet->SetSize( size );
} }
else if( strCompare( "U", line, &line ) ) // Sheet time stamp. else if( strCompare( "U", line, &line ) ) // Sheet UUID.
{ {
sheet->SetTimeStamp( parseHex( aReader, line ) ); wxString text;
parseUnquotedString( text, aReader, line );
const_cast<UUID&>( sheet->m_Uuid ) = UUID( text );
} }
else if( *line == 'F' ) // Sheet field. else if( *line == 'F' ) // Sheet field.
{ {
@ -1578,7 +1577,9 @@ SCH_COMPONENT* SCH_LEGACY_PLUGIN::loadComponent( LINE_READER& aReader )
component->SetConvert( convert ); component->SetConvert( convert );
component->SetTimeStamp( parseHex( aReader, line, &line ) ); wxString text;
parseUnquotedString( text, aReader, line, &line );
const_cast<UUID&>( component->m_Uuid ) = UUID( text );
} }
else if( strCompare( "P", line, &line ) ) else if( strCompare( "P", line, &line ) )
{ {
@ -2009,9 +2010,11 @@ void SCH_LEGACY_PLUGIN::saveComponent( SCH_COMPONENT* aComponent )
m_out->Print( 0, "$Comp\n" ); m_out->Print( 0, "$Comp\n" );
m_out->Print( 0, "L %s %s\n", name2.c_str(), name1.c_str() ); m_out->Print( 0, "L %s %s\n", name2.c_str(), name1.c_str() );
// Generate unit number, convert and time stamp // Generate unit number, conversion and UUID (including legacy timestamp if present)
m_out->Print( 0, "U %d %d %8.8X\n", aComponent->GetUnit(), aComponent->GetConvert(), m_out->Print( 0, "U %d %d %s\n",
aComponent->GetTimeStamp() ); aComponent->GetUnit(),
aComponent->GetConvert(),
TO_UTF8( aComponent->m_Uuid.AsString() ) );
// Save the position // Save the position
m_out->Print( 0, "P %d %d\n", m_out->Print( 0, "P %d %d\n",
@ -2160,17 +2163,21 @@ void SCH_LEGACY_PLUGIN::saveSheet( SCH_SHEET* aSheet )
m_out->Print( 0, "$Sheet\n" ); m_out->Print( 0, "$Sheet\n" );
m_out->Print( 0, "S %-4d %-4d %-4d %-4d\n", m_out->Print( 0, "S %-4d %-4d %-4d %-4d\n",
Iu2Mils( aSheet->GetPosition().x ), Iu2Mils( aSheet->GetPosition().y ), Iu2Mils( aSheet->GetPosition().x ),
Iu2Mils( aSheet->GetSize().x ), Iu2Mils( aSheet->GetSize().y ) ); Iu2Mils( aSheet->GetPosition().y ),
Iu2Mils( aSheet->GetSize().x ),
Iu2Mils( aSheet->GetSize().y ) );
m_out->Print( 0, "U %8.8X\n", aSheet->GetTimeStamp() ); m_out->Print( 0, "U %s\n", TO_UTF8( aSheet->m_Uuid.AsString() ) );
if( !aSheet->GetName().IsEmpty() ) if( !aSheet->GetName().IsEmpty() )
m_out->Print( 0, "F0 %s %d\n", EscapedUTF8( aSheet->GetName() ).c_str(), m_out->Print( 0, "F0 %s %d\n",
EscapedUTF8( aSheet->GetName() ).c_str(),
Iu2Mils( aSheet->GetSheetNameSize() ) ); Iu2Mils( aSheet->GetSheetNameSize() ) );
if( !aSheet->GetFileName().IsEmpty() ) if( !aSheet->GetFileName().IsEmpty() )
m_out->Print( 0, "F1 %s %d\n", EscapedUTF8( aSheet->GetFileName() ).c_str(), m_out->Print( 0, "F1 %s %d\n",
EscapedUTF8( aSheet->GetFileName() ).c_str(),
Iu2Mils( aSheet->GetFileNameSize() ) ); Iu2Mils( aSheet->GetFileNameSize() ) );
for( const SCH_SHEET_PIN* pin : aSheet->GetPins() ) for( const SCH_SHEET_PIN* pin : aSheet->GetPins() )
@ -2191,25 +2198,16 @@ void SCH_LEGACY_PLUGIN::saveSheet( SCH_SHEET* aSheet )
switch( pin->GetShape() ) switch( pin->GetShape() )
{ {
case PINSHEETLABEL_SHAPE::PS_INPUT:
type = 'I';
break;
case PINSHEETLABEL_SHAPE::PS_OUTPUT:
type = 'O';
break;
case PINSHEETLABEL_SHAPE::PS_BIDI:
type = 'B';
break;
case PINSHEETLABEL_SHAPE::PS_TRISTATE:
type = 'T';
break;
default: default:
case PINSHEETLABEL_SHAPE::PS_UNSPECIFIED: case PINSHEETLABEL_SHAPE::PS_UNSPECIFIED: type = 'U'; break;
type = 'U'; case PINSHEETLABEL_SHAPE::PS_INPUT: type = 'I'; break;
break; case PINSHEETLABEL_SHAPE::PS_OUTPUT: type = 'O'; break;
case PINSHEETLABEL_SHAPE::PS_BIDI: type = 'B'; break;
case PINSHEETLABEL_SHAPE::PS_TRISTATE: type = 'T'; break;
} }
m_out->Print( 0, "F%d %s %c %c %-3d %-3d %-3d\n", pin->GetNumber(), m_out->Print( 0, "F%d %s %c %c %-3d %-3d %-3d\n",
pin->GetNumber(),
EscapedUTF8( pin->GetText() ).c_str(), // supplies wrapping quotes EscapedUTF8( pin->GetText() ).c_str(), // supplies wrapping quotes
type, side, Iu2Mils( pin->GetPosition().x ), type, side, Iu2Mils( pin->GetPosition().x ),
Iu2Mils( pin->GetPosition().y ), Iu2Mils( pin->GetPosition().y ),
@ -2225,7 +2223,8 @@ void SCH_LEGACY_PLUGIN::saveJunction( SCH_JUNCTION* aJunction )
wxCHECK_RET( aJunction != NULL, "SCH_JUNCTION* is NULL" ); wxCHECK_RET( aJunction != NULL, "SCH_JUNCTION* is NULL" );
m_out->Print( 0, "Connection ~ %-4d %-4d\n", m_out->Print( 0, "Connection ~ %-4d %-4d\n",
Iu2Mils( aJunction->GetPosition().x ), Iu2Mils( aJunction->GetPosition().y ) ); Iu2Mils( aJunction->GetPosition().x ),
Iu2Mils( aJunction->GetPosition().y ) );
} }
@ -2233,7 +2232,8 @@ void SCH_LEGACY_PLUGIN::saveNoConnect( SCH_NO_CONNECT* aNoConnect )
{ {
wxCHECK_RET( aNoConnect != NULL, "SCH_NOCONNECT* is NULL" ); wxCHECK_RET( aNoConnect != NULL, "SCH_NOCONNECT* is NULL" );
m_out->Print( 0, "NoConn ~ %-4d %-4d\n", Iu2Mils( aNoConnect->GetPosition().x ), m_out->Print( 0, "NoConn ~ %-4d %-4d\n",
Iu2Mils( aNoConnect->GetPosition().x ),
Iu2Mils( aNoConnect->GetPosition().y ) ); Iu2Mils( aNoConnect->GetPosition().y ) );
} }

View File

@ -100,7 +100,7 @@ wxString SCH_PIN::GetDefaultNetName( const SCH_SHEET_PATH aPath )
// Add timestamp for uninitialized components // Add timestamp for uninitialized components
if( name.Last() == '?' ) if( name.Last() == '?' )
{ {
name << GetParentComponent()->GetTimeStamp(); name << GetParentComponent()->m_Uuid.AsString();
annotated = false; annotated = false;
} }

View File

@ -3,7 +3,7 @@
* *
* Copyright (C) 1992-2011 jean-pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr> * Copyright (C) 1992-2011 jean-pierre Charras <jean-pierre.charras@gipsa-lab.inpg.fr>
* Copyright (C) 1992-2011 Wayne Stambaugh <stambaughw@verizon.net> * Copyright (C) 1992-2011 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 1992-2018 KiCad Developers, see authors.txt for contributors. * Copyright (C) 1992-2020 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
@ -23,11 +23,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
/**
* @file eeschema/sch_reference_list.h
*/
#ifndef _SCH_REFERENCE_LIST_H_ #ifndef _SCH_REFERENCE_LIST_H_
#define _SCH_REFERENCE_LIST_H_ #define _SCH_REFERENCE_LIST_H_
@ -65,7 +60,7 @@ class SCH_REFERENCE
SCH_SHEET_PATH m_SheetPath; ///< The sheet path for this reference. SCH_SHEET_PATH m_SheetPath; ///< The sheet path for this reference.
bool m_IsNew; ///< True if not yet annotated. bool m_IsNew; ///< True if not yet annotated.
int m_SheetNum; ///< The sheet number for the reference. int m_SheetNum; ///< The sheet number for the reference.
timestamp_t m_TimeStamp; ///< The time stamp for the reference. UUID m_Uuid; ///< UUID of the component.
EDA_TEXT* m_Value; ///< The component value of the reference. It is the EDA_TEXT* m_Value; ///< The component value of the reference. It is the
///< same for all instances. ///< same for all instances.
int m_NumRef; ///< The numeric part of the reference designator. int m_NumRef; ///< The numeric part of the reference designator.
@ -79,15 +74,14 @@ public:
SCH_REFERENCE() : SCH_REFERENCE() :
m_SheetPath() m_SheetPath()
{ {
m_RootCmp = NULL; m_RootCmp = NULL;
m_Entry = NULL; m_Entry = NULL;
m_Unit = 0; m_Unit = 0;
m_TimeStamp = 0; m_IsNew = false;
m_IsNew = false; m_Value = NULL;
m_Value = NULL; m_NumRef = 0;
m_NumRef = 0; m_Flag = 0;
m_Flag = 0; m_SheetNum = 0;
m_SheetNum = 0;
} }
SCH_REFERENCE( SCH_COMPONENT* aComponent, LIB_PART* aLibComponent, SCH_REFERENCE( SCH_COMPONENT* aComponent, LIB_PART* aLibComponent,
@ -215,7 +209,7 @@ public:
class SCH_REFERENCE_LIST class SCH_REFERENCE_LIST
{ {
private: private:
std::vector <SCH_REFERENCE> componentFlatList; std::vector <SCH_REFERENCE> flatList;
public: public:
/** Constructor /** Constructor
@ -226,7 +220,7 @@ public:
SCH_REFERENCE& operator[]( int aIndex ) SCH_REFERENCE& operator[]( int aIndex )
{ {
return componentFlatList[ aIndex ]; return flatList[ aIndex ];
} }
/** /**
@ -235,7 +229,7 @@ public:
*/ */
unsigned GetCount() unsigned GetCount()
{ {
return componentFlatList.size(); return flatList.size();
} }
/** /**
@ -244,7 +238,7 @@ public:
*/ */
SCH_REFERENCE& GetItem( int aIdx ) SCH_REFERENCE& GetItem( int aIdx )
{ {
return componentFlatList[aIdx]; return flatList[aIdx];
} }
/** /**
@ -254,7 +248,7 @@ public:
*/ */
void AddItem( SCH_REFERENCE& aItem ) void AddItem( SCH_REFERENCE& aItem )
{ {
componentFlatList.push_back( aItem ); flatList.push_back( aItem );
} }
/** /**
@ -265,14 +259,6 @@ public:
*/ */
void RemoveItem( unsigned int aIndex ); void RemoveItem( unsigned int aIndex );
/**
* Function RemoveSubComponentsFromList
* Remove sub components from the list, when multiples parts per package are
* found in this list.
* Useful to create BOM, when a component must appear only once
*/
void RemoveSubComponentsFromList();
/* Sort functions: /* Sort functions:
* Sort functions are used to sort components for annotation or BOM generation. * Sort functions are used to sort components for annotation or BOM generation.
* Because sorting depends on what we want to do, there are many sort functions. * Because sorting depends on what we want to do, there are many sort functions.
@ -294,7 +280,7 @@ public:
void SplitReferences() void SplitReferences()
{ {
for( unsigned ii = 0; ii < GetCount(); ii++ ) for( unsigned ii = 0; ii < GetCount(); ii++ )
componentFlatList[ii].Split(); flatList[ii].Split();
} }
/** /**
@ -309,7 +295,7 @@ public:
/* update the reference numbers */ /* update the reference numbers */
for( unsigned ii = 0; ii < GetCount(); ii++ ) for( unsigned ii = 0; ii < GetCount(); ii++ )
{ {
componentFlatList[ii].Annotate(); flatList[ii].Annotate();
} }
} }
@ -350,14 +336,6 @@ public:
*/ */
int CheckAnnotation( REPORTER& aReporter ); int CheckAnnotation( REPORTER& aReporter );
/**
* @brief Check components having same references designator. Must be called with references
* sorted by timestamp \ref SortByTimeStamp()
* @param aReporter A sink for error messages. Use NULL_REPORTER if you don't need errors.
* @return The number of errors found.
*/
int checkForDuplicatedElements( REPORTER& aReporter );
/** /**
* Function sortByXCoordinate * Function sortByXCoordinate
* sorts the list of references by X position. * sorts the list of references by X position.
@ -374,7 +352,7 @@ public:
*/ */
void SortByXCoordinate() void SortByXCoordinate()
{ {
sort( componentFlatList.begin(), componentFlatList.end(), sortByXPosition ); sort( flatList.begin(), flatList.end(), sortByXPosition );
} }
/** /**
@ -393,7 +371,7 @@ public:
*/ */
void SortByYCoordinate() void SortByYCoordinate()
{ {
sort( componentFlatList.begin(), componentFlatList.end(), sortByYPosition ); sort( flatList.begin(), flatList.end(), sortByYPosition );
} }
/** /**
@ -403,7 +381,7 @@ public:
*/ */
void SortByTimeStamp() void SortByTimeStamp()
{ {
sort( componentFlatList.begin(), componentFlatList.end(), sortByTimeStamp ); sort( flatList.begin(), flatList.end(), sortByTimeStamp );
} }
/** /**
@ -423,7 +401,7 @@ public:
*/ */
void SortByRefAndValue() void SortByRefAndValue()
{ {
sort( componentFlatList.begin(), componentFlatList.end(), sortByRefAndValue ); sort( flatList.begin(), flatList.end(), sortByRefAndValue );
} }
/** /**
@ -439,7 +417,7 @@ public:
*/ */
void SortByReferenceOnly() void SortByReferenceOnly()
{ {
sort( componentFlatList.begin(), componentFlatList.end(), sortByReferenceOnly ); sort( flatList.begin(), flatList.end(), sortByReferenceOnly );
} }
/** /**
@ -485,9 +463,9 @@ public:
{ {
printf( "%s\n", aPrefix ); printf( "%s\n", aPrefix );
for( unsigned i=0; i<componentFlatList.size(); ++i ) for( unsigned i=0; i < flatList.size(); ++i )
{ {
SCH_REFERENCE& schref = componentFlatList[i]; SCH_REFERENCE& schref = flatList[i];
printf( " [%-2d] ref:%-8s num:%-3d lib_part:%s\n", printf( " [%-2d] ref:%-8s num:%-3d lib_part:%s\n",
i, i,
@ -510,7 +488,7 @@ public:
friend class BACK_ANNOTATION; friend class BACK_ANNOTATION;
private: private:
/* sort functions used to sort componentFlatList /* sort functions used to sort flatList
*/ */
static bool sortByRefAndValue( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 ); static bool sortByRefAndValue( const SCH_REFERENCE& item1, const SCH_REFERENCE& item2 );

View File

@ -1081,40 +1081,28 @@ int SCH_SCREENS::ReplaceDuplicateTimeStamps()
int count = 0; int count = 0;
auto timestamp_cmp = []( const EDA_ITEM* a, const EDA_ITEM* b ) -> bool auto timestamp_cmp = []( const EDA_ITEM* a, const EDA_ITEM* b ) -> bool
{ {
return a->GetTimeStamp() < b->GetTimeStamp(); return a->m_Uuid < b->m_Uuid;
}; };
std::set<EDA_ITEM*, decltype( timestamp_cmp )> unique_stamps( timestamp_cmp ); std::set<EDA_ITEM*, decltype( timestamp_cmp )> unique_stamps( timestamp_cmp );
for( size_t i = 0; i < m_screens.size(); i++ ) for( SCH_SCREEN* screen : m_screens )
m_screens[i]->GetHierarchicalItems( items ); screen->GetHierarchicalItems( items );
if( items.size() < 2 ) if( items.size() < 2 )
return 0; return 0;
for( auto item : items ) for( EDA_ITEM* item : items )
{ {
int failed = 0; if( !unique_stamps.insert( item ).second )
while( !unique_stamps.insert( item ).second )
{ {
failed = 1; // Reset to fully random UUID. This may lose reference, but better to be
// deterministic about it rather than to have duplicate UUIDs with random
// for a component, update its Time stamp and its paths // side-effects.
// (m_PathsAndReferences field) const_cast<UUID&>( item->m_Uuid ) = UUID();
if( item->Type() == SCH_COMPONENT_T ) count++;
static_cast<SCH_COMPONENT*>( item )->SetTimeStamp( GetNewTimeStamp() );
// for a sheet, update only its time stamp (annotation of its
// components will be lost)
// @todo: see how to change sheet paths for its cmp list (can
// be possible in most cases)
else
item->SetTimeStamp( GetNewTimeStamp() );
} }
count += failed;
} }
return count; return count;

View File

@ -51,12 +51,11 @@ SCH_SHEET::SCH_SHEET( const wxPoint& pos ) :
m_Layer = LAYER_SHEET; m_Layer = LAYER_SHEET;
m_pos = pos; m_pos = pos;
m_size = wxSize( Mils2iu( MIN_SHEET_WIDTH ), Mils2iu( MIN_SHEET_HEIGHT ) ); m_size = wxSize( Mils2iu( MIN_SHEET_WIDTH ), Mils2iu( MIN_SHEET_HEIGHT ) );
SetTimeStamp( GetNewTimeStamp() );
m_sheetNameSize = GetDefaultTextSize(); m_sheetNameSize = GetDefaultTextSize();
m_fileNameSize = GetDefaultTextSize(); m_fileNameSize = GetDefaultTextSize();
m_screen = NULL; m_screen = NULL;
m_name.Printf( wxT( "Sheet%8.8lX" ), (long) m_TimeStamp ); m_name.Printf( wxT( "Sheet%s" ), m_Uuid.AsString() );
m_fileName.Printf( wxT( "file%8.8lX.sch" ), (long) m_TimeStamp ); m_fileName.Printf( wxT( "file%s.sch" ), m_Uuid.AsString() );
} }
@ -66,7 +65,7 @@ SCH_SHEET::SCH_SHEET( const SCH_SHEET& aSheet ) :
m_pos = aSheet.m_pos; m_pos = aSheet.m_pos;
m_size = aSheet.m_size; m_size = aSheet.m_size;
m_Layer = aSheet.m_Layer; m_Layer = aSheet.m_Layer;
SetTimeStamp( aSheet.m_TimeStamp ); const_cast<UUID&>( m_Uuid ) = aSheet.m_Uuid;
m_sheetNameSize = aSheet.m_sheetNameSize; m_sheetNameSize = aSheet.m_sheetNameSize;
m_fileNameSize = aSheet.m_fileNameSize; m_fileNameSize = aSheet.m_fileNameSize;
m_screen = aSheet.m_screen; m_screen = aSheet.m_screen;

View File

@ -25,7 +25,9 @@
#ifndef SCH_SHEEET_H #ifndef SCH_SHEEET_H
#define SCH_SHEEET_H #define SCH_SHEEET_H
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" // For boost...
#include <boost/ptr_container/ptr_vector.hpp> #include <boost/ptr_container/ptr_vector.hpp>
#include <sch_text.h> #include <sch_text.h>

View File

@ -23,11 +23,6 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
/**
* @file sch_sheet_path.cpp
* @brief SCH_SHEET_PATH class implementation.
*/
#include <fctsys.h> #include <fctsys.h>
#include <sch_screen.h> #include <sch_screen.h>
@ -39,9 +34,6 @@
#include <sch_component.h> #include <sch_component.h>
#include <sch_sheet.h> #include <sch_sheet.h>
#include <template_fieldnames.h> #include <template_fieldnames.h>
#include <dialogs/dialog_schematic_find.h>
#include <boost/functional/hash.hpp> #include <boost/functional/hash.hpp>
#include <wx/filename.h> #include <wx/filename.h>
@ -67,7 +59,7 @@ void SCH_SHEET_PATH::Rehash()
m_current_hash = 0; m_current_hash = 0;
for( auto sheet : m_sheets ) for( auto sheet : m_sheets )
boost::hash_combine( m_current_hash, sheet->GetTimeStamp() ); boost::hash_combine( m_current_hash, sheet->m_Uuid.Hash() );
} }
@ -82,11 +74,11 @@ int SCH_SHEET_PATH::Cmp( const SCH_SHEET_PATH& aSheetPathToTest ) const
//otherwise, same number of sheets. //otherwise, same number of sheets.
for( unsigned i = 0; i < size(); i++ ) for( unsigned i = 0; i < size(); i++ )
{ {
if( at( i )->GetTimeStamp() > aSheetPathToTest.at( i )->GetTimeStamp() ) if( at( i )->m_Uuid < aSheetPathToTest.at( i )->m_Uuid )
return 1;
if( at( i )->GetTimeStamp() < aSheetPathToTest.at( i )->GetTimeStamp() )
return -1; return -1;
if( at( i )->m_Uuid != aSheetPathToTest.at( i )->m_Uuid )
return 1;
} }
return 0; return 0;
@ -126,17 +118,14 @@ SCH_SCREEN* SCH_SHEET_PATH::LastScreen() const
wxString SCH_SHEET_PATH::Path() const wxString SCH_SHEET_PATH::Path() const
{ {
wxString s, t; wxString s;
s = wxT( "/" ); // This is the root path s = wxT( "/" ); // This is the root path
// Start at 1 to avoid the root sheet, which does not need to be added to the path. // Start at 1 to avoid the root sheet, which does not need to be added to the path.
// It's timestamp changes anyway. // It's timestamp changes anyway.
for( unsigned i = 1; i < size(); i++ ) for( unsigned i = 1; i < size(); i++ )
{ s += at( i )->m_Uuid.AsString();
t.Printf( _( "%8.8lX/" ), (long unsigned) at( i )->GetTimeStamp() );
s = s + t;
}
return s; return s;
} }

View File

@ -476,9 +476,8 @@ bool SCH_EDIT_FRAME::LoadSheetFromFile( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHier
wxCHECK2_MSG( renamedSheet, continue, wxCHECK2_MSG( renamedSheet, continue,
"Sheet " + duplicateName + " not found in imported schematic." ); "Sheet " + duplicateName + " not found in imported schematic." );
timestamp_t newtimestamp = GetNewTimeStamp(); const_cast<UUID&>( renamedSheet->m_Uuid ) = UUID();
renamedSheet->SetTimeStamp( newtimestamp ); renamedSheet->SetName( wxString::Format( "Sheet%s", renamedSheet->m_Uuid.AsString() ) );
renamedSheet->SetName( wxString::Format( "Sheet%8.8lX", (unsigned long) newtimestamp ) );
} }
// Set all sheets loaded into the correct sheet file paths. // Set all sheets loaded into the correct sheet file paths.
@ -747,8 +746,7 @@ bool SCH_EDIT_FRAME::EditSheet( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy,
aSheet->SetSheetNameSize( dlg.GetSheetNameTextSize() ); aSheet->SetSheetNameSize( dlg.GetSheetNameTextSize() );
if( aSheet->GetName().IsEmpty() ) if( aSheet->GetName().IsEmpty() )
aSheet->SetName( wxString::Format( wxT( "Sheet%8.8lX" ), aSheet->SetName( wxString::Format( wxT( "Sheet%s" ), aSheet->m_Uuid.AsString() ) );
(long unsigned) aSheet->GetTimeStamp() ) );
if( aClearAnnotationNewItems ) if( aClearAnnotationNewItems )
*aClearAnnotationNewItems = clearAnnotation; *aClearAnnotationNewItems = clearAnnotation;

View File

@ -71,8 +71,6 @@ bool BACK_ANNOTATE::BackAnnotateSymbols( const std::string& aNetlist )
sheets.GetComponents( m_refs, false ); sheets.GetComponents( m_refs, false );
sheets.GetMultiUnitComponents( m_multiUnitsRefs ); sheets.GetMultiUnitComponents( m_multiUnitsRefs );
m_refs.SortByTimeStamp();
errors += m_refs.checkForDuplicatedElements( m_settings.reporter );
errors += getChangeList(); errors += getChangeList();
errors += checkForUnusedSymbols(); errors += checkForUnusedSymbols();
errors += checkSharedSchematicErrors(); errors += checkSharedSchematicErrors();
@ -91,7 +89,7 @@ bool BACK_ANNOTATE::BackAnnotateSymbols( const std::string& aNetlist )
} }
else else
m_settings.reporter.ReportTail( m_settings.reporter.ReportTail(
_( "No errors during dry run. Ready to go." ), REPORTER::RPT_ACTION ); _( "No errors during dry run. Ready to go." ), REPORTER::RPT_ACTION );
} }
else else
{ {

View File

@ -214,7 +214,6 @@ int SCH_DRAWING_TOOLS::PlaceComponent( const TOOL_EVENT& aEvent )
next_comp->SetFlags( IS_NEW | IS_MOVED ); next_comp->SetFlags( IS_NEW | IS_MOVED );
next_comp->SetUnit( new_unit ); next_comp->SetUnit( new_unit );
next_comp->SetUnitSelection( g_CurrentSheet, new_unit ); next_comp->SetUnitSelection( g_CurrentSheet, new_unit );
next_comp->SetTimeStamp( GetNewTimeStamp() );
if( m_frame->GetAutoplaceFields() ) if( m_frame->GetAutoplaceFields() )
component->AutoplaceFields( /* aScreen */ NULL, /* aManual */ false ); component->AutoplaceFields( /* aScreen */ NULL, /* aManual */ false );
@ -834,7 +833,6 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
sheet = new SCH_SHEET( (wxPoint) cursorPos ); sheet = new SCH_SHEET( (wxPoint) cursorPos );
sheet->SetFlags( IS_NEW | IS_RESIZED ); sheet->SetFlags( IS_NEW | IS_RESIZED );
sheet->SetTimeStamp( GetNewTimeStamp() );
sheet->SetParent( m_frame->GetScreen() ); sheet->SetParent( m_frame->GetScreen() );
sheet->SetScreen( NULL ); sheet->SetScreen( NULL );
sizeSheet( sheet, cursorPos ); sizeSheet( sheet, cursorPos );

View File

@ -796,13 +796,8 @@ int SCH_EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
case SCH_SHEET_T: case SCH_SHEET_T:
{ {
SCH_SHEET* sheet = (SCH_SHEET*) newItem; SCH_SHEET* sheet = (SCH_SHEET*) newItem;
// Duplicate sheet names and sheet time stamps are not valid. Use a time stamp // Duplicate sheet names are not valid. Generate a UUID-based sheet name.
// based sheet name and update the time stamp for each sheet in the block. sheet->SetName( wxString::Format( wxT( "Sheet%s" ), sheet->m_Uuid.AsString() ) );
timestamp_t timeStamp = GetNewTimeStamp();
sheet->SetName( wxString::Format( wxT( "sheet%8.8lX" ), (unsigned long)timeStamp ) );
sheet->SetTimeStamp( timeStamp );
sheet->SetParent( m_frame->GetScreen() ); sheet->SetParent( m_frame->GetScreen() );
m_frame->AddToScreen( sheet ); m_frame->AddToScreen( sheet );
@ -813,10 +808,7 @@ int SCH_EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
case SCH_COMPONENT_T: case SCH_COMPONENT_T:
{ {
SCH_COMPONENT* component = (SCH_COMPONENT*) newItem; SCH_COMPONENT* component = (SCH_COMPONENT*) newItem;
component->SetTimeStamp( GetNewTimeStamp() );
component->ClearAnnotation( NULL ); component->ClearAnnotation( NULL );
component->SetParent( m_frame->GetScreen() ); component->SetParent( m_frame->GetScreen() );
m_frame->AddToScreen( component ); m_frame->AddToScreen( component );
break; break;
@ -853,14 +845,12 @@ int SCH_EDIT_TOOL::RepeatDrawItem( const TOOL_EVENT& aEvent )
m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true ); m_toolMgr->RunAction( EE_ACTIONS::clearSelection, true );
SCH_ITEM* newItem = (SCH_ITEM*) sourceItem->Clone(); SCH_ITEM* newItem = sourceItem->Duplicate();
bool performDrag = false; bool performDrag = false;
// If cloning a component then put into 'move' mode. // If cloning a component then put into 'move' mode.
if( newItem->Type() == SCH_COMPONENT_T ) if( newItem->Type() == SCH_COMPONENT_T )
{ {
( (SCH_COMPONENT*) newItem )->SetTimeStamp( GetNewTimeStamp() );
wxPoint cursorPos = (wxPoint) getViewControls()->GetCursorPosition( true ); wxPoint cursorPos = (wxPoint) getViewControls()->GetCursorPosition( true );
newItem->Move( cursorPos - newItem->GetPosition() ); newItem->Move( cursorPos - newItem->GetPosition() );
performDrag = true; performDrag = true;

View File

@ -1007,7 +1007,7 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
{ {
for( auto existingItem : m_frame->GetScreen()->Items() ) for( auto existingItem : m_frame->GetScreen()->Items() )
{ {
if( item->GetTimeStamp() == existingItem->GetTimeStamp() ) if( item->m_Uuid == existingItem->m_Uuid )
{ {
dropAnnotations = true; dropAnnotations = true;
break; break;
@ -1055,7 +1055,7 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
if( dropAnnotations ) if( dropAnnotations )
{ {
component->SetTimeStamp( GetNewTimeStamp() ); const_cast<UUID&>( component->m_Uuid ) = UUID();
// clear the annotation, but preserve the selected unit // clear the annotation, but preserve the selected unit
int unit = component->GetUnit(); int unit = component->GetUnit();
@ -1066,19 +1066,22 @@ int SCH_EDITOR_CONTROL::Paste( const TOOL_EVENT& aEvent )
component->Resolve( *symLibTable, partLib ); component->Resolve( *symLibTable, partLib );
component->UpdatePins(); component->UpdatePins();
} }
else if( item->Type() == SCH_SHEET_T ) else
{
// Everything else gets a new UUID
const_cast<UUID&>( item->m_Uuid ) = UUID();
}
if( item->Type() == SCH_SHEET_T )
{ {
SCH_SHEET* sheet = (SCH_SHEET*) item; SCH_SHEET* sheet = (SCH_SHEET*) item;
wxFileName fn = sheet->GetFileName(); wxFileName fn = sheet->GetFileName();
SCH_SCREEN* existingScreen = nullptr; SCH_SCREEN* existingScreen = nullptr;
bool dropSheetAnnotations = false; bool dropSheetAnnotations = false;
// Duplicate sheet names and timestamps are not valid. Generate new timestamps // Duplicate sheet names are not valid. Generate new UUID-based sheet names.
// and timestamp-based sheet names. sheet->SetName( wxString::Format( wxT( "Sheet%s" ), sheet->m_Uuid.AsString() ) );
timestamp_t uid = GetNewTimeStamp();
sheet->SetName( wxString::Format( wxT( "sheet%8.8lX" ), (unsigned long)uid ) );
sheet->SetTimeStamp( uid );
sheet->SetParent( g_CurrentSheet->Last() ); sheet->SetParent( g_CurrentSheet->Last() );
sheet->SetScreen( nullptr ); sheet->SetScreen( nullptr );
sheetsPasted = true; sheetsPasted = true;

View File

@ -162,6 +162,9 @@ typedef unsigned STATUS_FLAGS;
*/ */
class EDA_ITEM : public KIGFX::VIEW_ITEM class EDA_ITEM : public KIGFX::VIEW_ITEM
{ {
public:
const UUID m_Uuid;
private: private:
/** /**
@ -175,7 +178,6 @@ private:
protected: protected:
EDA_ITEM* m_Parent; ///< Linked list: Link (parent struct) EDA_ITEM* m_Parent; ///< Linked list: Link (parent struct)
timestamp_t m_TimeStamp; ///< Time stamp used for logical links
/// Set to true to override the visibility setting of the item. /// Set to true to override the visibility setting of the item.
bool m_forceVisible; bool m_forceVisible;
@ -209,9 +211,6 @@ public:
return m_StructType; return m_StructType;
} }
void SetTimeStamp( timestamp_t aNewTimeStamp ) { m_TimeStamp = aNewTimeStamp; }
timestamp_t GetTimeStamp() const { return m_TimeStamp; }
EDA_ITEM* GetParent() const { return m_Parent; } EDA_ITEM* GetParent() const { return m_Parent; }
void SetParent( EDA_ITEM* aParent ) { m_Parent = aParent; } void SetParent( EDA_ITEM* aParent ) { m_Parent = aParent; }

View File

@ -158,6 +158,18 @@ public:
*/ */
virtual void Print( PCB_BASE_FRAME* aFrame, wxDC* DC, const wxPoint& offset = ZeroOffset ) = 0; virtual void Print( PCB_BASE_FRAME* aFrame, wxDC* DC, const wxPoint& offset = ZeroOffset ) = 0;
/**
* Function Duplicate
* creates a copy of a BOARD_ITEM.
*/
BOARD_ITEM* Duplicate() const
{
EDA_ITEM* dupe = Clone();
const_cast<UUID&>( dupe->m_Uuid ) = UUID();
return static_cast<BOARD_ITEM*>( dupe );
}
/** /**
* Swap data between aItem and aImage. * Swap data between aItem and aImage.
* aItem and aImage should have the same type * aItem and aImage should have the same type

View File

@ -47,6 +47,7 @@
#include <memory> #include <memory>
#include <type_traits> #include <type_traits>
#include <typeinfo> #include <typeinfo>
#include <boost/uuid/uuid.hpp>
class SEARCH_STACK; class SEARCH_STACK;
class REPORTER; class REPORTER;
@ -61,6 +62,107 @@ class REPORTER;
*/ */
typedef uint32_t timestamp_t; typedef uint32_t timestamp_t;
class UUID
{
public:
UUID();
UUID( int null );
UUID( const wxString& aString );
UUID( timestamp_t aTimestamp );
void Clone( const UUID& aUUID );
size_t Hash() const;
bool IsLegacyTimestamp() const;
timestamp_t AsLegacyTimestamp() const;
wxString AsString() const;
wxString AsLegacyTimestampString() const;
bool operator==( UUID const& rhs) const
{
return m_uuid == rhs.m_uuid;
}
bool operator!=( UUID const& rhs) const
{
return m_uuid != rhs.m_uuid;
}
bool operator<( UUID const& rhs) const
{
return m_uuid < rhs.m_uuid;
}
private:
boost::uuids::uuid m_uuid;
timestamp_t m_cached_timestamp;
};
extern UUID niluuid;
class UUID_PATH : public std::vector<UUID>
{
public:
UUID_PATH()
{}
UUID_PATH( const wxString& aString )
{
for( const wxString& pathStep : wxSplit( aString, '/' ) )
{
if( !pathStep.empty() )
emplace_back( UUID( pathStep ) );
}
}
wxString AsString() const
{
wxString path;
for( const UUID& pathStep : *this )
path += '/' + pathStep.AsString();
return path;
}
bool operator==( UUID_PATH const& rhs) const
{
if( size() != rhs.size() )
return false;
for( int i = 0; i < size(); ++i )
{
if( at( i ) != rhs.at( i ) )
return false;
}
return true;
}
bool operator<( UUID_PATH const& rhs) const
{
if( size() != rhs.size() )
return size() < rhs.size();
for( int i = 0; i < size(); ++i )
{
if( at( i ) < rhs.at( i ) )
return true;
if( at( i ) != rhs.at( i ) )
return false;
}
return false;
}
};
/// default name for nameless projects /// default name for nameless projects
#define NAMELESS_PROJECT wxT( "noname" ) #define NAMELESS_PROJECT wxT( "noname" )
@ -154,15 +256,6 @@ void SelectReferenceNumber( wxTextEntry* aTextEntry );
int ProcessExecute( const wxString& aCommandLine, int aFlags = wxEXEC_ASYNC, int ProcessExecute( const wxString& aCommandLine, int aFlags = wxEXEC_ASYNC,
wxProcess *callback = NULL ); wxProcess *callback = NULL );
/**
* @return an unique time stamp that changes after each call
*/
timestamp_t GetNewTimeStamp();
int GetCommandOptions( const int argc, const char** argv,
const char* stringtst, const char** optarg,
int* optind );
/** /**
* Split \a aString to a string list separated at \a aSplitter. * Split \a aString to a string list separated at \a aSplitter.
* *

View File

@ -33,7 +33,10 @@
#include <wx/confbase.h> #include <wx/confbase.h>
#include <wx/fileconf.h> #include <wx/fileconf.h>
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" // For boost...
#include <boost/ptr_container/ptr_vector.hpp> #include <boost/ptr_container/ptr_vector.hpp>
#include <gal/color4d.h> #include <gal/color4d.h>
#include <limits> #include <limits>

View File

@ -365,12 +365,6 @@ public:
*/ */
NODE_MAP MapChildren( wxXmlNode* aCurrentNode ); NODE_MAP MapChildren( wxXmlNode* aCurrentNode );
///> Make a unique time stamp
timestamp_t EagleTimeStamp( wxXmlNode* aTree );
///> Computes module timestamp basing on its name, value and unit
timestamp_t EagleModuleTstamp( const wxString& aName, const wxString& aValue, int aUnit );
///> Convert an Eagle curve end to a KiCad center for S_ARC ///> Convert an Eagle curve end to a KiCad center for S_ARC
wxPoint ConvertArcCenter( const wxPoint& aStart, const wxPoint& aEnd, double aAngle ); wxPoint ConvertArcCenter( const wxPoint& aStart, const wxPoint& aEnd, double aAngle );

View File

@ -30,6 +30,7 @@
#define FOOTPRINT_INFO_H_ #define FOOTPRINT_INFO_H_
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#include <boost/ptr_container/ptr_vector.hpp> #include <boost/ptr_container/ptr_vector.hpp>
#include <import_export.h> #include <import_export.h>

View File

@ -28,8 +28,10 @@
#include <map> #include <map>
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" // For boost...
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
#include <boost/ptr_container/ptr_vector.hpp> #include <boost/ptr_container/ptr_vector.hpp>
#include <memory> #include <memory>
#include <project.h> #include <project.h>

View File

@ -26,7 +26,9 @@
#ifndef MULTIVECTOR_H #ifndef MULTIVECTOR_H
#define MULTIVECTOR_H #define MULTIVECTOR_H
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" // For boost...
#include <boost/ptr_container/ptr_vector.hpp> #include <boost/ptr_container/ptr_vector.hpp>
#include <stdexcept> #include <stdexcept>
/** /**

View File

@ -2,7 +2,7 @@
* 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.
* *
* Created on: 11 Mar 2016, author John Beard * Created on: 11 Mar 2016, author John Beard
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2020 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
@ -94,17 +94,33 @@ void ARRAY_CREATOR::Invoke()
else else
{ {
// Need to create a new item // Need to create a new item
BOARD_ITEM* new_item; BOARD_ITEM* new_item = nullptr;
if( m_editModules ) if( m_editModules )
{ {
// Don't bother incrementing pads: the module won't update // Don't bother incrementing pads: the module won't update
// until commit, so we can only do this once // until commit, so we can only do this once
new_item = module->Duplicate( item, false ); new_item = module->DuplicateItem( item, false );
} }
else else
{ {
new_item = m_parent.GetBoard()->Duplicate( item ); switch( item->Type() )
{
case PCB_MODULE_T:
case PCB_TEXT_T:
case PCB_LINE_T:
case PCB_TRACE_T:
case PCB_VIA_T:
case PCB_ZONE_AREA_T:
case PCB_TARGET_T:
case PCB_DIMENSION_T:
new_item = item->Duplicate();
break;
default:
// Silently drop other items (such as footprint texts) from duplication
break;
}
// PCB items keep the same numbering // PCB items keep the same numbering

View File

@ -38,7 +38,6 @@
#include <fctsys.h> #include <fctsys.h>
#include <convert_to_biu.h> #include <convert_to_biu.h>
#include <confirm.h> #include <confirm.h>
#include <pcbnew.h>
#include <pcb_edit_frame.h> #include <pcb_edit_frame.h>
#include <class_board.h> #include <class_board.h>
#include <class_module.h> #include <class_module.h>
@ -219,8 +218,8 @@ void SpreadFootprints( std::vector<MODULE*>* aFootprints,
bool islastItem = false; bool islastItem = false;
if( ii == footprintList.size() - 1 || if( ii == footprintList.size() - 1 ||
( footprintList[ii]->GetPath().BeforeLast( '/' ) != ( footprintList[ii]->GetPath().AsString().BeforeLast( '/' ) !=
footprintList[ii+1]->GetPath().BeforeLast( '/' ) ) ) footprintList[ii+1]->GetPath().AsString().BeforeLast( '/' ) ) )
islastItem = true; islastItem = true;
footprintListBySheet.push_back( footprint ); footprintListBySheet.push_back( footprint );
@ -303,8 +302,5 @@ void SpreadFootprints( std::vector<MODULE*>* aFootprints,
// without the time stamp of the footprint ). // without the time stamp of the footprint ).
static bool sortFootprintsbySheetPath( MODULE* ref, MODULE* compare ) static bool sortFootprintsbySheetPath( MODULE* ref, MODULE* compare )
{ {
if( ref->GetPath().Length() == compare->GetPath().Length() ) return ref->GetPath() < compare->GetPath();
return ref->GetPath().BeforeLast( '/' ).Cmp( compare->GetPath().BeforeLast( '/' ) ) < 0;
return ref->GetPath().Length() < compare->GetPath().Length();
} }

View File

@ -10,7 +10,7 @@
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net> * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
* *
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2020 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
@ -1076,26 +1076,18 @@ MODULE* BOARD::FindModuleByReference( const wxString& aReference ) const
} }
MODULE* BOARD::FindModule( const wxString& aRefOrTimeStamp, bool aSearchByTimeStamp ) const MODULE* BOARD::FindModuleByPath( const UUID_PATH& aPath ) const
{ {
if( aSearchByTimeStamp ) for( MODULE* module : m_modules )
{ {
for( auto module : m_modules ) if( module->GetPath() == aPath )
{ return module;
if( aRefOrTimeStamp.CmpNoCase( module->GetPath() ) == 0 )
return module;
}
}
else
{
return FindModuleByReference( aRefOrTimeStamp );
} }
return NULL; return nullptr;
} }
// The pad count for each netcode, stored in a buffer for a fast access. // The pad count for each netcode, stored in a buffer for a fast access.
// This is needed by the sort function sortNetsByNodes() // This is needed by the sort function sortNetsByNodes()
static std::vector<int> padCountListByNet; static std::vector<int> padCountListByNet;
@ -1589,10 +1581,11 @@ ZONE_CONTAINER* BOARD::InsertArea( int aNetcode, int aAreaIdx, PCB_LAYER_ID aLay
int aCornerY, ZONE_HATCH_STYLE aHatch ) int aCornerY, ZONE_HATCH_STYLE aHatch )
{ {
ZONE_CONTAINER* new_area = new ZONE_CONTAINER( this ); ZONE_CONTAINER* new_area = new ZONE_CONTAINER( this );
// JEY TODO: this should be a duplicate so we don't have to handle the UUID here....
const_cast<UUID&>( new_area->m_Uuid ) = UUID();
new_area->SetNetCode( aNetcode ); new_area->SetNetCode( aNetcode );
new_area->SetLayer( aLayer ); new_area->SetLayer( aLayer );
new_area->SetTimeStamp( GetNewTimeStamp() );
if( aAreaIdx < (int) ( m_ZoneDescriptorList.size() - 1 ) ) if( aAreaIdx < (int) ( m_ZoneDescriptorList.size() - 1 ) )
m_ZoneDescriptorList.insert( m_ZoneDescriptorList.begin() + aAreaIdx + 1, new_area ); m_ZoneDescriptorList.insert( m_ZoneDescriptorList.begin() + aAreaIdx + 1, new_area );
@ -1656,36 +1649,6 @@ bool BOARD::NormalizeAreaPolygon( PICKED_ITEMS_LIST * aNewZonesList, ZONE_CONTAI
} }
BOARD_ITEM* BOARD::Duplicate( const BOARD_ITEM* aItem, bool aAddToBoard )
{
BOARD_ITEM* new_item = NULL;
switch( aItem->Type() )
{
case PCB_MODULE_T:
case PCB_TEXT_T:
case PCB_LINE_T:
case PCB_TRACE_T:
case PCB_VIA_T:
case PCB_ZONE_AREA_T:
case PCB_TARGET_T:
case PCB_DIMENSION_T:
new_item = static_cast<BOARD_ITEM*>( aItem->Clone() );
break;
default:
// Un-handled item for duplication
new_item = NULL;
break;
}
if( new_item && aAddToBoard )
Add( new_item );
return new_item;
}
/* Extracts the board outlines and build a closed polygon /* Extracts the board outlines and build a closed polygon
* from lines, arcs and circle items on edge cut layer * from lines, arcs and circle items on edge cut layer
* Any closed outline inside the main outline is a hole * Any closed outline inside the main outline is a hole
@ -1707,7 +1670,6 @@ bool BOARD::GetBoardPolygonOutlines( SHAPE_POLY_SET& aOutlines, wxString* aError
aOutlines.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); aOutlines.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
return success; return success;
} }

View File

@ -2,7 +2,7 @@
* 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) 2007 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com * Copyright (C) 2007 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
* Copyright (C) 1992-2017 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2020 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
@ -290,8 +290,6 @@ public:
BOARD_ITEM* GetItem( void* aWeakReference ); BOARD_ITEM* GetItem( void* aWeakReference );
BOARD_ITEM* Duplicate( const BOARD_ITEM* aItem, bool aAddToBoard = false );
/** /**
* Function GetConnectivity() * Function GetConnectivity()
* returns list of missing connections between components/tracks. * returns list of missing connections between components/tracks.
@ -816,25 +814,20 @@ public:
/** /**
* Function FindModuleByReference * Function FindModuleByReference
* searches for a MODULE within this board with the given * searches for a MODULE within this board with the given reference designator.
* reference designator. Finds only the first one, if there * Finds only the first one, if there is more than one such MODULE.
* is more than one such MODULE.
* @param aReference The reference designator of the MODULE to find. * @param aReference The reference designator of the MODULE to find.
* @return MODULE* - If found, the MODULE having the given reference * @return MODULE* - If found, the MODULE having the given reference designator, else NULL.
* designator, else NULL.
*/ */
MODULE* FindModuleByReference( const wxString& aReference ) const; MODULE* FindModuleByReference( const wxString& aReference ) const;
/** /**
* Function FindModule * Function FindModuleByPath
* searches for a module matching \a aRefOrTimeStamp depending on the state of * searches for a MODULE within this board with the given path.
* \a aSearchByTimeStamp. * @param aPath The path ([sheetUUID, .., symbolUUID]) to search for.
* @param aRefOrTimeStamp is the search string. * @return MODULE* - If found, the MODULE having the given uuid, else NULL.
* @param aSearchByTimeStamp searches by the module time stamp value if true. Otherwise
* search by reference designator.
* @return MODULE* - If found, the module meeting the search criteria, else NULL.
*/ */
MODULE* FindModule( const wxString& aRefOrTimeStamp, bool aSearchByTimeStamp = false ) const; MODULE* FindModuleByPath( const UUID_PATH& aPath ) const;
/** /**
* Function SortedNetnamesList * Function SortedNetnamesList

View File

@ -4,7 +4,7 @@
* Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2015 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> * Copyright (C) 2015 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2015 Wayne Stambaugh <stambaughw@gmail.com> * Copyright (C) 2015 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2020 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
@ -87,7 +87,7 @@ MODULE::MODULE( const MODULE& aModule ) :
m_CntRot180 = aModule.m_CntRot180; m_CntRot180 = aModule.m_CntRot180;
m_LastEditTime = aModule.m_LastEditTime; m_LastEditTime = aModule.m_LastEditTime;
m_Link = aModule.m_Link; m_Link = aModule.m_Link;
m_Path = aModule.m_Path; // is this correct behavior? m_Path = aModule.m_Path;
m_LocalClearance = aModule.m_LocalClearance; m_LocalClearance = aModule.m_LocalClearance;
m_LocalSolderMaskMargin = aModule.m_LocalSolderMaskMargin; m_LocalSolderMaskMargin = aModule.m_LocalSolderMaskMargin;
@ -149,7 +149,7 @@ MODULE::MODULE( const MODULE& aModule ) :
CalculateBoundingBox(); CalculateBoundingBox();
m_initial_comments = aModule.m_initial_comments ? m_initial_comments = aModule.m_initial_comments ?
new wxArrayString( *aModule.m_initial_comments ) : 0; new wxArrayString( *aModule.m_initial_comments ) : nullptr;
} }
@ -191,7 +191,7 @@ MODULE& MODULE::operator=( const MODULE& aOther )
m_CntRot180 = aOther.m_CntRot180; m_CntRot180 = aOther.m_CntRot180;
m_LastEditTime = aOther.m_LastEditTime; m_LastEditTime = aOther.m_LastEditTime;
m_Link = aOther.m_Link; m_Link = aOther.m_Link;
m_Path = aOther.m_Path; //is this correct behavior? m_Path = aOther.m_Path;
m_LocalClearance = aOther.m_LocalClearance; m_LocalClearance = aOther.m_LocalClearance;
m_LocalSolderMaskMargin = aOther.m_LocalSolderMaskMargin; m_LocalSolderMaskMargin = aOther.m_LocalSolderMaskMargin;
@ -573,14 +573,10 @@ void MODULE::GetMsgPanelInfo( EDA_UNITS aUnits, std::vector<MSG_PANEL_ITEM>& aLi
aList.emplace_back( MSG_PANEL_ITEM( _( "Last Change" ), msg, BROWN ) ); aList.emplace_back( MSG_PANEL_ITEM( _( "Last Change" ), msg, BROWN ) );
// display schematic path
aList.emplace_back( MSG_PANEL_ITEM( _( "Netlist Path" ), m_Path, BROWN ) );
// display the board side placement // display the board side placement
aList.emplace_back( MSG_PANEL_ITEM( _( "Board Side" ), aList.emplace_back( MSG_PANEL_ITEM( _( "Board Side" ),
IsFlipped()? _( "Back (Flipped)" ) : _( "Front" ), RED ) ); IsFlipped()? _( "Back (Flipped)" ) : _( "Front" ), RED ) );
msg.Printf( wxT( "%zu" ), m_pads.size() ); msg.Printf( wxT( "%zu" ), m_pads.size() );
aList.emplace_back( MSG_PANEL_ITEM( _( "Pads" ), msg, BLUE ) ); aList.emplace_back( MSG_PANEL_ITEM( _( "Pads" ), msg, BLUE ) );
@ -1295,8 +1291,8 @@ void MODULE::SetOrientation( double newangle )
CalculateBoundingBox(); CalculateBoundingBox();
} }
BOARD_ITEM* MODULE::Duplicate( const BOARD_ITEM* aItem, bool aIncrementPadNumbers, BOARD_ITEM* MODULE::DuplicateItem( const BOARD_ITEM* aItem, bool aIncrementPadNumbers,
bool aAddToModule ) bool aAddToModule )
{ {
BOARD_ITEM* new_item = NULL; BOARD_ITEM* new_item = NULL;
MODULE_ZONE_CONTAINER* new_zone = NULL; MODULE_ZONE_CONTAINER* new_zone = NULL;

View File

@ -2,7 +2,7 @@
* 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) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2020 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
@ -225,8 +225,8 @@ public:
const wxString& GetKeywords() const { return m_KeyWord; } const wxString& GetKeywords() const { return m_KeyWord; }
void SetKeywords( const wxString& aKeywords ) { m_KeyWord = aKeywords; } void SetKeywords( const wxString& aKeywords ) { m_KeyWord = aKeywords; }
const wxString& GetPath() const { return m_Path; } const UUID_PATH& GetPath() const { return m_Path; }
void SetPath( const wxString& aPath ) { m_Path = aPath; } void SetPath( const UUID_PATH& aPath ) { m_Path = aPath; }
int GetLocalSolderMaskMargin() const { return m_LocalSolderMaskMargin; } int GetLocalSolderMaskMargin() const { return m_LocalSolderMaskMargin; }
void SetLocalSolderMaskMargin( int aMargin ) { m_LocalSolderMaskMargin = aMargin; } void SetLocalSolderMaskMargin( int aMargin ) { m_LocalSolderMaskMargin = aMargin; }
@ -546,8 +546,8 @@ public:
double GetArea( int aPadding = 0 ) const; double GetArea( int aPadding = 0 ) const;
timestamp_t GetLink() const { return m_Link; } UUID GetLink() const { return m_Link; }
void SetLink( timestamp_t aLink ) { m_Link = aLink; } void SetLink( const UUID& aLink ) { m_Link = aLink; }
int GetPlacementCost180() const { return m_CntRot180; } int GetPlacementCost180() const { return m_CntRot180; }
void SetPlacementCost180( int aCost ) { m_CntRot180 = aCost; } void SetPlacementCost180( int aCost ) { m_CntRot180 = aCost; }
@ -556,13 +556,12 @@ public:
void SetPlacementCost90( int aCost ) { m_CntRot90 = aCost; } void SetPlacementCost90( int aCost ) { m_CntRot90 = aCost; }
/** /**
* Function Duplicate * Function DuplicateItem
* Duplicate a given item within the module, without adding to the board * Duplicate a given item within the module, without adding to the board
* @return the new item, or NULL if the item could not be duplicated * @return the new item, or NULL if the item could not be duplicated
*/ */
BOARD_ITEM* Duplicate( const BOARD_ITEM* aItem, BOARD_ITEM* DuplicateItem( const BOARD_ITEM* aItem, bool aIncrementPadNumbers,
bool aIncrementPadNumbers, bool aAddToModule = false );
bool aAddToModule = false );
/** /**
* Function Add3DModel * Function Add3DModel
@ -706,10 +705,10 @@ private:
wxString m_Doc; // File name and path for documentation file. wxString m_Doc; // File name and path for documentation file.
wxString m_KeyWord; // Search keywords to find module in library. wxString m_KeyWord; // Search keywords to find module in library.
wxString m_Path; UUID_PATH m_Path; // Path to associated symbol ([sheetUUID, .., symbolUUID]).
timestamp_t m_LastEditTime; timestamp_t m_LastEditTime;
int m_arflag; // Use to trace ratsnest and auto routing. int m_arflag; // Use to trace ratsnest and auto routing.
timestamp_t m_Link; // Temporary logical link used during editing UUID m_Link; // Temporary logical link used during editing
int m_CntRot90; // Horizontal automatic placement cost ( 0..10 ). int m_CntRot90; // Horizontal automatic placement cost ( 0..10 ).
int m_CntRot180; // Vertical automatic placement cost ( 0..10 ). int m_CntRot180; // Vertical automatic placement cost ( 0..10 ).

View File

@ -2,7 +2,7 @@
* 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) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2018 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2020 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
@ -805,10 +805,9 @@ public:
/** /**
* same as Clone, but returns a D_PAD item. * same as Clone, but returns a D_PAD item.
* Useful mainly for pythons scripts, because Clone (virtual function) * Useful mainly for python scripts, because Clone returns an EDA_ITEM.
* returns an EDA_ITEM.
*/ */
D_PAD* Duplicate() const D_PAD* ClonePad() const
{ {
return (D_PAD*) Clone(); return (D_PAD*) Clone();
} }

View File

@ -1,7 +1,7 @@
/* /*
* 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) 2019 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2019-2020 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
@ -145,10 +145,10 @@ void PCB_EDIT_FRAME::ExecuteRemoteCommand( const char* cmdline )
else if( strcmp( idcmd, "$SHEET:" ) == 0 ) else if( strcmp( idcmd, "$SHEET:" ) == 0 )
{ {
msg.Printf( _( "Selecting all from sheet \"%s\"" ), FROM_UTF8( text ) ); msg.Printf( _( "Selecting all from sheet \"%s\"" ), FROM_UTF8( text ) );
wxString sheetStamp( FROM_UTF8( text ) ); wxString sheetUIID( FROM_UTF8( text ) );
SetStatusText( msg ); SetStatusText( msg );
GetToolManager()->RunAction( PCB_ACTIONS::selectOnSheetFromEeschema, true, GetToolManager()->RunAction( PCB_ACTIONS::selectOnSheetFromEeschema, true,
static_cast<void*>( &sheetStamp ) ); static_cast<void*>( &sheetUIID ) );
return; return;
} }
else if( strcmp( idcmd, "$CLEAR" ) == 0 ) else if( strcmp( idcmd, "$CLEAR" ) == 0 )
@ -341,7 +341,7 @@ void PCB_EDIT_FRAME::KiwayMailIn( KIWAY_EXPRESS& mail )
for( auto& module : this->GetBoard()->Modules() ) for( auto& module : this->GetBoard()->Modules() )
{ {
netlist.AddComponent( new COMPONENT( module->GetFPID(), module->GetReference(), netlist.AddComponent( new COMPONENT( module->GetFPID(), module->GetReference(),
module->GetValue(), module->GetPath() ) ); module->GetValue(), module->GetPath() ) );
} }
netlist.Format( netlist.Format(
"pcb_netlist", &sf, 0, CTL_OMIT_FILTERS | CTL_OMIT_NETS | CTL_OMIT_FILTERS ); "pcb_netlist", &sf, 0, CTL_OMIT_FILTERS | CTL_OMIT_NETS | CTL_OMIT_FILTERS );

View File

@ -180,12 +180,6 @@ DIALOG_FOOTPRINT_BOARD_EDITOR::~DIALOG_FOOTPRINT_BOARD_EDITOR()
void DIALOG_FOOTPRINT_BOARD_EDITOR::EditFootprint( wxCommandEvent& ) void DIALOG_FOOTPRINT_BOARD_EDITOR::EditFootprint( wxCommandEvent& )
{ {
if( m_footprint->GetTimeStamp() == 0 ) // Module Editor needs a non null timestamp
{
m_footprint->SetTimeStamp( GetNewTimeStamp() );
m_frame->OnModify();
}
EndModal( PRM_EDITOR_EDIT_BOARD_FOOTPRINT ); EndModal( PRM_EDITOR_EDIT_BOARD_FOOTPRINT );
} }
@ -281,7 +275,12 @@ bool DIALOG_FOOTPRINT_BOARD_EDITOR::TransferDataToWindow()
m_BoardSideCtrl->SetSelection( (m_footprint->GetLayer() == B_Cu) ? 1 : 0 ); m_BoardSideCtrl->SetSelection( (m_footprint->GetLayer() == B_Cu) ? 1 : 0 );
m_tcUniqueID->SetValue( m_footprint->GetPath() ); wxString path;
for( const UUID& pathStep : m_footprint->GetPath() )
path += '/' + pathStep.AsString();
m_tcUniqueID->SetValue( path );
if( m_footprint->IsLocked() ) if( m_footprint->IsLocked() )
m_AutoPlaceCtrl->SetSelection( 2 ); m_AutoPlaceCtrl->SetSelection( 2 );

View File

@ -686,7 +686,7 @@ bool DIALOG_FOOTPRINT_FP_EDITOR::TransferDataFromWindow()
static bool footprintIsFromBoard( MODULE* aFootprint ) static bool footprintIsFromBoard( MODULE* aFootprint )
{ {
return aFootprint->GetLink() != 0; return aFootprint->GetLink() != niluuid;
} }

View File

@ -488,7 +488,7 @@ void PCB_EDIT_FRAME::Exchange_Module( MODULE* aSrc, MODULE* aDest, BOARD_COMMIT&
aDest->Models() = aSrc->Models(); // Linked list of 3D models. aDest->Models() = aSrc->Models(); // Linked list of 3D models.
// Updating other parameters // Updating other parameters
aDest->SetTimeStamp( aSrc->GetTimeStamp() ); const_cast<UUID&>( aDest->m_Uuid ) = aSrc->m_Uuid;
aDest->SetPath( aSrc->GetPath() ); aDest->SetPath( aSrc->GetPath() );
aDest->CalculateBoundingBox(); aDest->CalculateBoundingBox();

View File

@ -2,7 +2,7 @@
* 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) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2012-2019 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2012-2020 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
@ -521,7 +521,6 @@ void EAGLE_PLUGIN::loadPlain( wxXmlNode* aGraphics )
dseg->SetAngle( *w.curve * -10.0 ); // KiCad rotates the other way dseg->SetAngle( *w.curve * -10.0 ); // KiCad rotates the other way
} }
dseg->SetTimeStamp( EagleTimeStamp( gr ) );
dseg->SetLayer( layer ); dseg->SetLayer( layer );
dseg->SetWidth( width ); dseg->SetWidth( width );
} }
@ -541,7 +540,6 @@ void EAGLE_PLUGIN::loadPlain( wxXmlNode* aGraphics )
m_board->Add( pcbtxt, ADD_MODE::APPEND ); m_board->Add( pcbtxt, ADD_MODE::APPEND );
pcbtxt->SetLayer( layer ); pcbtxt->SetLayer( layer );
pcbtxt->SetTimeStamp( EagleTimeStamp( gr ) );
pcbtxt->SetText( FROM_UTF8( t.text.c_str() ) ); pcbtxt->SetText( FROM_UTF8( t.text.c_str() ) );
pcbtxt->SetTextPos( wxPoint( kicad_x( t.x ), kicad_y( t.y ) ) ); pcbtxt->SetTextPos( wxPoint( kicad_x( t.x ), kicad_y( t.y ) ) );
@ -549,7 +547,7 @@ void EAGLE_PLUGIN::loadPlain( wxXmlNode* aGraphics )
double ratio = t.ratio ? *t.ratio : 8; // DTD says 8 is default double ratio = t.ratio ? *t.ratio : 8; // DTD says 8 is default
pcbtxt->SetThickness( t.size.ToPcbUnits() * ratio / 100 ); pcbtxt->SetThickness( KiROUND( t.size.ToPcbUnits() * ratio / 100 ) );
int align = t.align ? *t.align : ETEXT::BOTTOM_LEFT; int align = t.align ? *t.align : ETEXT::BOTTOM_LEFT;
@ -659,7 +657,6 @@ void EAGLE_PLUGIN::loadPlain( wxXmlNode* aGraphics )
} }
dseg->SetShape( S_CIRCLE ); dseg->SetShape( S_CIRCLE );
dseg->SetTimeStamp( EagleTimeStamp( gr ) );
dseg->SetLayer( layer ); dseg->SetLayer( layer );
dseg->SetStart( wxPoint( kicad_x( c.x ), kicad_y( c.y ) ) ); dseg->SetStart( wxPoint( kicad_x( c.x ), kicad_y( c.y ) ) );
dseg->SetEnd( wxPoint( kicad_x( c.x ) + radius, kicad_y( c.y ) ) ); dseg->SetEnd( wxPoint( kicad_x( c.x ) + radius, kicad_y( c.y ) ) );
@ -682,7 +679,6 @@ void EAGLE_PLUGIN::loadPlain( wxXmlNode* aGraphics )
ZONE_CONTAINER* zone = new ZONE_CONTAINER( m_board ); ZONE_CONTAINER* zone = new ZONE_CONTAINER( m_board );
m_board->Add( zone, ADD_MODE::APPEND ); m_board->Add( zone, ADD_MODE::APPEND );
zone->SetTimeStamp( EagleTimeStamp( gr ) );
zone->SetLayer( layer ); zone->SetLayer( layer );
zone->SetNetCode( NETINFO_LIST::UNCONNECTED ); zone->SetNetCode( NETINFO_LIST::UNCONNECTED );
@ -699,7 +695,7 @@ void EAGLE_PLUGIN::loadPlain( wxXmlNode* aGraphics )
zone->Rotate( zone->GetPosition(), r.rot->degrees * 10 ); zone->Rotate( zone->GetPosition(), r.rot->degrees * 10 );
} }
// this is not my fault: // this is not my fault:
zone->SetHatch( outline_hatch, zone->GetDefaultHatchPitch(), true ); zone->SetHatch( outline_hatch, ZONE_CONTAINER::GetDefaultHatchPitch(), true );
} }
m_xpath->pop(); m_xpath->pop();
@ -901,8 +897,8 @@ void EAGLE_PLUGIN::loadElements( wxXmlNode* aElements )
EELEMENT e( element ); EELEMENT e( element );
// use "NULL-ness" as an indication of presence of the attribute: // use "NULL-ness" as an indication of presence of the attribute:
EATTR* nameAttr = 0; EATTR* nameAttr = nullptr;
EATTR* valueAttr = 0; EATTR* valueAttr = nullptr;
m_xpath->Value( e.name.c_str() ); m_xpath->Value( e.name.c_str() );
@ -1127,7 +1123,6 @@ ZONE_CONTAINER* EAGLE_PLUGIN::loadPolygon( wxXmlNode* aPolyNode )
// use a "netcode = 0" type ZONE: // use a "netcode = 0" type ZONE:
zone = new ZONE_CONTAINER( m_board ); zone = new ZONE_CONTAINER( m_board );
zone->SetTimeStamp( EagleTimeStamp( aPolyNode ) );
m_board->Add( zone, ADD_MODE::APPEND ); m_board->Add( zone, ADD_MODE::APPEND );
if( p.layer == EAGLE_LAYER::TRESTRICT ) // front layer keepout if( p.layer == EAGLE_LAYER::TRESTRICT ) // front layer keepout
@ -1634,9 +1629,7 @@ void EAGLE_PLUGIN::packageText( MODULE* aModule, wxXmlNode* aTree ) const
PCB_LAYER_ID layer = kicad_layer( t.layer ); PCB_LAYER_ID layer = kicad_layer( t.layer );
if( layer == UNDEFINED_LAYER ) if( layer == UNDEFINED_LAYER )
{
layer = Cmts_User; layer = Cmts_User;
}
TEXTE_MODULE* txt; TEXTE_MODULE* txt;
@ -1651,7 +1644,6 @@ void EAGLE_PLUGIN::packageText( MODULE* aModule, wxXmlNode* aTree ) const
aModule->Add( txt ); aModule->Add( txt );
} }
txt->SetTimeStamp( EagleTimeStamp( aTree ) );
txt->SetText( FROM_UTF8( t.text.c_str() ) ); txt->SetText( FROM_UTF8( t.text.c_str() ) );
wxPoint pos( kicad_x( t.x ), kicad_y( t.y ) ); wxPoint pos( kicad_x( t.x ), kicad_y( t.y ) );
@ -1664,7 +1656,7 @@ void EAGLE_PLUGIN::packageText( MODULE* aModule, wxXmlNode* aTree ) const
double ratio = t.ratio ? *t.ratio : 8; // DTD says 8 is default double ratio = t.ratio ? *t.ratio : 8; // DTD says 8 is default
txt->SetThickness( t.size.ToPcbUnits() * ratio / 100 ); txt->SetThickness( KiROUND( t.size.ToPcbUnits() * ratio / 100 ) );
int align = t.align ? *t.align : ETEXT::BOTTOM_LEFT; // bottom-left is eagle default int align = t.align ? *t.align : ETEXT::BOTTOM_LEFT; // bottom-left is eagle default
@ -1745,8 +1737,6 @@ void EAGLE_PLUGIN::packageRectangle( MODULE* aModule, wxXmlNode* aTree ) const
dwg->SetLayer( layer ); dwg->SetLayer( layer );
dwg->SetWidth( 0 ); dwg->SetWidth( 0 );
dwg->SetTimeStamp( EagleTimeStamp( aTree ) );
std::vector<wxPoint> pts; std::vector<wxPoint> pts;
wxPoint start( wxPoint( kicad_x( r.x1 ), kicad_y( r.y1 ) ) ); wxPoint start( wxPoint( kicad_x( r.x1 ), kicad_y( r.y1 ) ) );
@ -1763,9 +1753,7 @@ void EAGLE_PLUGIN::packageRectangle( MODULE* aModule, wxXmlNode* aTree ) const
dwg->SetEnd0( end ); dwg->SetEnd0( end );
if( r.rot ) if( r.rot )
{
dwg->Rotate( dwg->GetCenter(), r.rot->degrees * 10 ); dwg->Rotate( dwg->GetCenter(), r.rot->degrees * 10 );
}
} }
@ -1779,7 +1767,6 @@ void EAGLE_PLUGIN::packagePolygon( MODULE* aModule, wxXmlNode* aTree ) const
dwg->SetWidth( 0 ); // it's filled, no need for boundary width dwg->SetWidth( 0 ); // it's filled, no need for boundary width
dwg->SetLayer( layer ); dwg->SetLayer( layer );
dwg->SetTimeStamp( EagleTimeStamp( aTree ) );
std::vector<wxPoint> pts; std::vector<wxPoint> pts;
@ -1877,7 +1864,6 @@ void EAGLE_PLUGIN::packageCircle( MODULE* aModule, wxXmlNode* aTree ) const
} }
gr->SetLayer( layer ); gr->SetLayer( layer );
gr->SetTimeStamp( EagleTimeStamp( aTree ) );
gr->SetStart0( wxPoint( kicad_x( e.x ), kicad_y( e.y ) ) ); gr->SetStart0( wxPoint( kicad_x( e.x ), kicad_y( e.y ) ) );
gr->SetEnd0( wxPoint( kicad_x( e.x ) + radius, kicad_y( e.y ) ) ); gr->SetEnd0( wxPoint( kicad_x( e.x ) + radius, kicad_y( e.y ) ) );
gr->SetDrawCoord(); gr->SetDrawCoord();
@ -1994,9 +1980,7 @@ void EAGLE_PLUGIN::packageSMD( MODULE* aModule, wxXmlNode* aTree ) const
} }
if( e.rot ) if( e.rot )
{
pad->SetOrientation( e.rot->degrees * 10 ); pad->SetOrientation( e.rot->degrees * 10 );
}
pad->SetLocalSolderPasteMargin( -eagleClamp( m_rules->mlMinCreamFrame, pad->SetLocalSolderPasteMargin( -eagleClamp( m_rules->mlMinCreamFrame,
(int) ( m_rules->mvCreamFrame * minPadSize ), (int) ( m_rules->mvCreamFrame * minPadSize ),
@ -2138,7 +2122,6 @@ void EAGLE_PLUGIN::loadSignals( wxXmlNode* aSignals )
TRACK* t = new TRACK( m_board ); TRACK* t = new TRACK( m_board );
t->SetTimeStamp( EagleTimeStamp( netItem ) + int( RAD2DEG( angle ) ) );
t->SetPosition( start ); t->SetPosition( start );
t->SetEnd( end ); t->SetEnd( end );
t->SetWidth( width ); t->SetWidth( width );
@ -2153,7 +2136,6 @@ void EAGLE_PLUGIN::loadSignals( wxXmlNode* aSignals )
TRACK* t = new TRACK( m_board ); TRACK* t = new TRACK( m_board );
t->SetTimeStamp( EagleTimeStamp( netItem ) );
t->SetPosition( start ); t->SetPosition( start );
t->SetEnd( wxPoint( kicad_x( w.x2 ), kicad_y( w.y2 ) ) ); t->SetEnd( wxPoint( kicad_x( w.x2 ), kicad_y( w.y2 ) ) );
t->SetWidth( width ); t->SetWidth( width );
@ -2227,8 +2209,6 @@ void EAGLE_PLUGIN::loadSignals( wxXmlNode* aSignals )
else else
via->SetViaType( VIATYPE::BLIND_BURIED ); via->SetViaType( VIATYPE::BLIND_BURIED );
via->SetTimeStamp( EagleTimeStamp( netItem ) );
wxPoint pos( kicad_x( v.x ), kicad_y( v.y ) ); wxPoint pos( kicad_x( v.x ), kicad_y( v.y ) );
via->SetPosition( pos ); via->SetPosition( pos );
@ -2281,8 +2261,8 @@ void EAGLE_PLUGIN::loadSignals( wxXmlNode* aSignals )
{ {
// KiCad does not support an unconnected zone with its own non-zero netcode, // KiCad does not support an unconnected zone with its own non-zero netcode,
// but only when assigned netcode = 0 w/o a name... // but only when assigned netcode = 0 w/o a name...
for( ZONES::iterator it = zones.begin(); it != zones.end(); ++it ) for( ZONE_CONTAINER* zone : zones )
(*it)->SetNetCode( NETINFO_LIST::UNCONNECTED ); zone->SetNetCode( NETINFO_LIST::UNCONNECTED );
// therefore omit this signal/net. // therefore omit this signal/net.
} }
@ -2526,7 +2506,7 @@ void EAGLE_PLUGIN::FootprintEnumerate( wxArrayString& aFootprintNames, const wxS
MODULE* EAGLE_PLUGIN::FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName, MODULE* EAGLE_PLUGIN::FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName,
const PROPERTIES* aProperties ) const PROPERTIES* aProperties )
{ {
init( aProperties ); init( aProperties );
cacheLib( aLibraryPath ); cacheLib( aLibraryPath );
@ -2535,10 +2515,8 @@ MODULE* EAGLE_PLUGIN::FootprintLoad( const wxString& aLibraryPath, const wxStrin
if( mi == m_templates.end() ) if( mi == m_templates.end() )
return NULL; return NULL;
// copy constructor to clone the template // Return a copy of the template
MODULE* ret = new MODULE( *mi->second ); return (MODULE*) mi->second->Duplicate();
return ret;
} }

View File

@ -5,7 +5,7 @@
* 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) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2012-2017 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2012-2020 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
@ -130,7 +130,7 @@ public:
bool aBestEfforts, const PROPERTIES* aProperties = NULL) override; bool aBestEfforts, const PROPERTIES* aProperties = NULL) override;
MODULE* FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName, MODULE* FootprintLoad( const wxString& aLibraryPath, const wxString& aFootprintName,
const PROPERTIES* aProperties = NULL ) override; const PROPERTIES* aProperties = NULL ) override;
long long GetLibraryTimestamp( const wxString& aLibraryPath ) const override long long GetLibraryTimestamp( const wxString& aLibraryPath ) const override
{ {

View File

@ -43,8 +43,8 @@ bool RecreateCmpFile( BOARD * aBrd, const wxString& aFullCmpFileName )
for( auto module : aBrd->Modules() ) for( auto module : aBrd->Modules() )
{ {
fprintf( cmpFile, "\nBeginCmp\n" ); fprintf( cmpFile, "\nBeginCmp\n" );
fprintf( cmpFile, "TimeStamp = %8.8lX\n", (unsigned long)module->GetTimeStamp() ); fprintf( cmpFile, "TimeStamp = %s\n", TO_UTF8( module->m_Uuid.AsString() ) );
fprintf( cmpFile, "Path = %s\n", TO_UTF8( module->GetPath() ) ); fprintf( cmpFile, "Path = %s\n", TO_UTF8( module->GetPath().AsString() ) );
fprintf( cmpFile, "Reference = %s;\n", fprintf( cmpFile, "Reference = %s;\n",
!module->GetReference().IsEmpty() ? TO_UTF8( module->GetReference() ) : "[NoRef]" ); !module->GetReference().IsEmpty() ? TO_UTF8( module->GetReference() ) : "[NoRef]" );
fprintf( cmpFile, "ValeurCmp = %s;\n", fprintf( cmpFile, "ValeurCmp = %s;\n",

View File

@ -334,7 +334,7 @@ bool FOOTPRINT_EDIT_FRAME::IsCurrentFPFromBoard() const
{ {
MODULE* module = GetBoard()->GetFirstModule(); MODULE* module = GetBoard()->GetFirstModule();
return ( module && module->GetLink() > 0 ); return ( module && module->GetLink() != niluuid );
} }
@ -559,10 +559,10 @@ void FOOTPRINT_EDIT_FRAME::OnUpdateInsertModuleInBoard( wxUpdateUIEvent& aEvent
PCB_EDIT_FRAME* frame = (PCB_EDIT_FRAME*) Kiway().Player( FRAME_PCB_EDITOR, false ); PCB_EDIT_FRAME* frame = (PCB_EDIT_FRAME*) Kiway().Player( FRAME_PCB_EDITOR, false );
MODULE* module_in_edit = GetBoard()->GetFirstModule(); MODULE* module_in_edit = GetBoard()->GetFirstModule();
bool canInsert = frame && module_in_edit && !module_in_edit->GetLink(); bool canInsert = frame && module_in_edit && module_in_edit->GetLink() == niluuid;
// If the source was deleted, the module can inserted but not updated in the board. // If the source was deleted, the module can inserted but not updated in the board.
if( frame && module_in_edit && module_in_edit->GetLink() ) // this is not a new module if( frame && module_in_edit && module_in_edit->GetLink() != niluuid ) // this is not a new module
{ {
BOARD* mainpcb = frame->GetBoard(); BOARD* mainpcb = frame->GetBoard();
canInsert = true; canInsert = true;
@ -570,7 +570,7 @@ void FOOTPRINT_EDIT_FRAME::OnUpdateInsertModuleInBoard( wxUpdateUIEvent& aEvent
// search if the source module was not deleted: // search if the source module was not deleted:
for( auto source_module : mainpcb->Modules() ) for( auto source_module : mainpcb->Modules() )
{ {
if( module_in_edit->GetLink() == source_module->GetTimeStamp() ) if( module_in_edit->GetLink() == source_module->m_Uuid )
{ {
canInsert = false; canInsert = false;
break; break;

View File

@ -361,7 +361,6 @@ void FOOTPRINT_EDIT_FRAME::Export_Module( MODULE* aModule )
/* This module should *already* be "normalized" in a way such that /* This module should *already* be "normalized" in a way such that
orientation is zero, etc., since it came from module editor. orientation is zero, etc., since it came from module editor.
module->SetTimeStamp( 0 );
module->SetParent( 0 ); module->SetParent( 0 );
module->SetOrientation( 0 ); module->SetOrientation( 0 );
*/ */
@ -372,9 +371,8 @@ void FOOTPRINT_EDIT_FRAME::Export_Module( MODULE* aModule )
if( fp == NULL ) if( fp == NULL )
{ {
wxMessageBox( wxString::Format( wxMessageBox( wxString::Format( _( "Unable to create or write file \"%s\"" ),
_( "Unable to create or write file \"%s\"" ), dlg.GetPath() ) );
GetChars( dlg.GetPath() ) ) );
return; return;
} }
@ -694,7 +692,7 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprint( MODULE* aModule )
wxString footprintName = aModule->GetFPID().GetLibItemName(); wxString footprintName = aModule->GetFPID().GetLibItemName();
bool nameChanged = m_footprintNameWhenLoaded != footprintName; bool nameChanged = m_footprintNameWhenLoaded != footprintName;
if( aModule->GetLink() ) if( aModule->GetLink() != niluuid )
{ {
if( SaveFootprintToBoard( false ) ) if( SaveFootprintToBoard( false ) )
{ {
@ -786,13 +784,13 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprintToBoard( bool aAddNew )
// Search the old module (source) if exists // Search the old module (source) if exists
// Because this source could be deleted when editing the main board... // Because this source could be deleted when editing the main board...
if( module_in_edit->GetLink() ) // this is not a new module ... if( module_in_edit->GetLink() != niluuid ) // this is not a new module ...
{ {
source_module = nullptr; source_module = nullptr;
for( auto mod : mainpcb->Modules() ) for( auto mod : mainpcb->Modules() )
{ {
if( module_in_edit->GetLink() == mod->GetTimeStamp() ) if( module_in_edit->GetLink() == mod->m_Uuid )
{ {
source_module = mod; source_module = mod;
break; break;
@ -819,7 +817,7 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprintToBoard( bool aAddNew )
// Create the "new" module // Create the "new" module
MODULE* newmodule = new MODULE( *module_in_edit ); MODULE* newmodule = new MODULE( *module_in_edit );
newmodule->SetParent( mainpcb ); newmodule->SetParent( mainpcb );
newmodule->SetLink( 0 ); newmodule->SetLink( niluuid );
if( source_module ) // this is an update command if( source_module ) // this is an update command
{ {
@ -828,7 +826,7 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprintToBoard( bool aAddNew )
// and connexions are kept) // and connexions are kept)
// and the source_module (old module) is deleted // and the source_module (old module) is deleted
pcbframe->Exchange_Module( source_module, newmodule, commit ); pcbframe->Exchange_Module( source_module, newmodule, commit );
newmodule->SetTimeStamp( module_in_edit->GetLink() ); const_cast<UUID&>( newmodule->m_Uuid ) = module_in_edit->GetLink();
commit.Push( wxT( "Update module" ) ); commit.Push( wxT( "Update module" ) );
} }
else // This is an insert command else // This is an insert command
@ -841,7 +839,7 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprintToBoard( bool aAddNew )
pcbframe->PlaceModule( newmodule ); pcbframe->PlaceModule( newmodule );
newmodule->SetPosition( wxPoint( 0, 0 ) ); newmodule->SetPosition( wxPoint( 0, 0 ) );
viewControls->SetCrossHairCursorPosition( cursorPos, false ); viewControls->SetCrossHairCursorPosition( cursorPos, false );
newmodule->SetTimeStamp( GetNewTimeStamp() ); const_cast<UUID&>( newmodule->m_Uuid ) = UUID();
commit.Push( wxT( "Insert module" ) ); commit.Push( wxT( "Insert module" ) );
pcbframe->Raise(); pcbframe->Raise();
@ -967,7 +965,7 @@ bool FOOTPRINT_EDIT_FRAME::SaveFootprintAs( MODULE* aModule )
return false; return false;
// Once saved-as a board footprint is no longer a board footprint // Once saved-as a board footprint is no longer a board footprint
aModule->SetLink( 0 ); aModule->SetLink( niluuid );
wxString fmt = module_exists ? _( "Component \"%s\" replaced in \"%s\"" ) : wxString fmt = module_exists ? _( "Component \"%s\" replaced in \"%s\"" ) :
_( "Component \"%s\" added in \"%s\"" ); _( "Component \"%s\" added in \"%s\"" );

View File

@ -670,7 +670,7 @@ void FOOTPRINT_VIEWER_FRAME::AddFootprintToPCB( wxCommandEvent& aEvent )
BOARD_COMMIT commit( pcbframe ); BOARD_COMMIT commit( pcbframe );
// Create the "new" module // Create the "new" module
MODULE* newmodule = new MODULE( *GetBoard()->GetFirstModule() ); MODULE* newmodule = (MODULE*) GetBoard()->GetFirstModule()->Duplicate();
newmodule->SetParent( pcbframe->GetBoard() ); newmodule->SetParent( pcbframe->GetBoard() );
newmodule->SetLink( 0 ); newmodule->SetLink( 0 );
@ -682,7 +682,6 @@ void FOOTPRINT_VIEWER_FRAME::AddFootprintToPCB( wxCommandEvent& aEvent )
pcbframe->PlaceModule( newmodule ); pcbframe->PlaceModule( newmodule );
newmodule->SetPosition( wxPoint( 0, 0 ) ); newmodule->SetPosition( wxPoint( 0, 0 ) );
viewControls->SetCrossHairCursorPosition( cursorPos, false ); viewControls->SetCrossHairCursorPosition( cursorPos, false );
newmodule->SetTimeStamp( GetNewTimeStamp() );
commit.Push( wxT( "Insert module" ) ); commit.Push( wxT( "Insert module" ) );
pcbframe->Raise(); pcbframe->Raise();

View File

@ -72,7 +72,10 @@ Vary: Accept-Encoding
#include <kicad_curl/kicad_curl_easy.h> // Include before any wx file #include <kicad_curl/kicad_curl_easy.h> // Include before any wx file
#include <sstream> #include <sstream>
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" // For boost...
#include <boost/ptr_container/ptr_map.hpp> #include <boost/ptr_container/ptr_map.hpp>
#include <set> #include <set>
#include <wx/zipstrm.h> #include <wx/zipstrm.h>

View File

@ -2,7 +2,7 @@
* 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) 2012 Wayne Stambaugh <stambaughw@gmail.com> * Copyright (C) 2012 Wayne Stambaugh <stambaughw@gmail.com>
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2020 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
@ -944,7 +944,7 @@ MODULE* GPCB_PLUGIN::FootprintLoad( const wxString& aLibraryPath, const wxString
const PROPERTIES* aProperties ) const PROPERTIES* aProperties )
{ {
const MODULE* footprint = getFootprint( aLibraryPath, aFootprintName, aProperties, true ); const MODULE* footprint = getFootprint( aLibraryPath, aFootprintName, aProperties, true );
return footprint ? new MODULE( *footprint ) : nullptr; return footprint ? (MODULE*) footprint->Duplicate() : nullptr;
} }

View File

@ -7,7 +7,7 @@
* *
* 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) 2017 KiCad Developers, see CHANGELOG.TXT for contributors. * Copyright (C) 2017-2020 KiCad Developers, see CHANGELOG.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
@ -44,11 +44,7 @@ public:
MODULE* parseMODULE( wxArrayString* aInitialComments ) MODULE* parseMODULE( wxArrayString* aInitialComments )
{ {
MODULE* mod = PCB_PARSER::parseMODULE( aInitialComments ); return PCB_PARSER::parseMODULE( aInitialComments );
//TODO: figure out better way of handling paths
mod->SetPath( wxT( "" ) );
return mod;
} }
}; };

View File

@ -2,7 +2,7 @@
* 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) 2012 CERN * Copyright (C) 2012 CERN
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2020 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
@ -806,8 +806,7 @@ void PCB_IO::format( DIMENSION* aDimension, int aNestLevel ) const
formatLayer( aDimension ); formatLayer( aDimension );
if( aDimension->GetTimeStamp() ) m_out->Print( 0, " (tstamp %s)", TO_UTF8( aDimension->m_Uuid.AsString() ) );
m_out->Print( 0, " (tstamp %lX)", (unsigned long)aDimension->GetTimeStamp() );
m_out->Print( 0, "\n" ); m_out->Print( 0, "\n" );
@ -927,8 +926,7 @@ void PCB_IO::format( DRAWSEGMENT* aSegment, int aNestLevel ) const
m_out->Print( 0, " (width %s)", FormatInternalUnits( aSegment->GetWidth() ).c_str() ); m_out->Print( 0, " (width %s)", FormatInternalUnits( aSegment->GetWidth() ).c_str() );
if( aSegment->GetTimeStamp() ) m_out->Print( 0, " (tstamp %s)", TO_UTF8( aSegment->m_Uuid.AsString() ) );
m_out->Print( 0, " (tstamp %lX)", (unsigned long)aSegment->GetTimeStamp() );
if( aSegment->GetStatus() ) if( aSegment->GetStatus() )
m_out->Print( 0, " (status %X)", aSegment->GetStatus() ); m_out->Print( 0, " (status %X)", aSegment->GetStatus() );
@ -1025,8 +1023,7 @@ void PCB_IO::format( PCB_TARGET* aTarget, int aNestLevel ) const
formatLayer( aTarget ); formatLayer( aTarget );
if( aTarget->GetTimeStamp() ) m_out->Print( 0, " (tstamp %s)", TO_UTF8( aTarget->m_Uuid.AsString() ) );
m_out->Print( 0, " (tstamp %lX)", (unsigned long)aTarget->GetTimeStamp() );
m_out->Print( 0, ")\n" ); m_out->Print( 0, ")\n" );
} }
@ -1061,11 +1058,9 @@ void PCB_IO::format( MODULE* aModule, int aNestLevel ) const
m_out->Print( 0, " (tedit %lX)", (unsigned long)aModule->GetLastEditTime() ); m_out->Print( 0, " (tedit %lX)", (unsigned long)aModule->GetLastEditTime() );
if( !( m_ctl & CTL_OMIT_TSTAMPS ) ) if( !( m_ctl & CTL_OMIT_TSTAMPS ) )
{ m_out->Print( 0, " (tstamp %s)", TO_UTF8( aModule->m_Uuid.AsString() ) );
m_out->Print( 0, " (tstamp %lX)\n", (unsigned long)aModule->GetTimeStamp() );
} m_out->Print( 0, "\n" );
else
m_out->Print( 0, "\n" );
if( !( m_ctl & CTL_OMIT_AT ) ) if( !( m_ctl & CTL_OMIT_AT ) )
{ {
@ -1085,9 +1080,9 @@ void PCB_IO::format( MODULE* aModule, int aNestLevel ) const
m_out->Print( aNestLevel+1, "(tags %s)\n", m_out->Print( aNestLevel+1, "(tags %s)\n",
m_out->Quotew( aModule->GetKeywords() ).c_str() ); m_out->Quotew( aModule->GetKeywords() ).c_str() );
if( !( m_ctl & CTL_OMIT_PATH ) && !!aModule->GetPath() ) if( !( m_ctl & CTL_OMIT_PATH ) && !aModule->GetPath().empty() )
m_out->Print( aNestLevel+1, "(path %s)\n", m_out->Print( aNestLevel+1, "(path %s)\n",
m_out->Quotew( aModule->GetPath() ).c_str() ); m_out->Quotew( aModule->GetPath().AsString() ).c_str() );
if( aModule->GetPlacementCost90() != 0 ) if( aModule->GetPlacementCost90() != 0 )
m_out->Print( aNestLevel+1, "(autoplace_cost90 %d)\n", aModule->GetPlacementCost90() ); m_out->Print( aNestLevel+1, "(autoplace_cost90 %d)\n", aModule->GetPlacementCost90() );
@ -1598,8 +1593,7 @@ void PCB_IO::format( TEXTE_PCB* aText, int aNestLevel ) const
formatLayer( aText ); formatLayer( aText );
if( aText->GetTimeStamp() ) m_out->Print( 0, " (tstamp %s)", TO_UTF8( aText->m_Uuid.AsString() ) );
m_out->Print( 0, " (tstamp %lX)", (unsigned long)aText->GetTimeStamp() );
m_out->Print( 0, "\n" ); m_out->Print( 0, "\n" );
@ -1723,8 +1717,7 @@ void PCB_IO::format( TRACK* aTrack, int aNestLevel ) const
m_out->Print( 0, " (net %d)", m_mapping->Translate( aTrack->GetNetCode() ) ); m_out->Print( 0, " (net %d)", m_mapping->Translate( aTrack->GetNetCode() ) );
if( aTrack->GetTimeStamp() != 0 ) m_out->Print( 0, " (tstamp %s)", TO_UTF8( aTrack->m_Uuid.AsString() ) );
m_out->Print( 0, " (tstamp %lX)", (unsigned long)aTrack->GetTimeStamp() );
if( aTrack->GetStatus() != 0 ) if( aTrack->GetStatus() != 0 )
m_out->Print( 0, " (status %X)", aTrack->GetStatus() ); m_out->Print( 0, " (status %X)", aTrack->GetStatus() );
@ -1752,7 +1745,7 @@ void PCB_IO::format( ZONE_CONTAINER* aZone, int aNestLevel ) const
formatLayer( aZone ); formatLayer( aZone );
} }
m_out->Print( 0, " (tstamp %lX)", (unsigned long) aZone->GetTimeStamp() ); m_out->Print( 0, " (tstamp %s)", TO_UTF8( aZone->m_Uuid.AsString() ) );
// Save the outline aux info // Save the outline aux info
std::string hatch; std::string hatch;
@ -2180,7 +2173,7 @@ MODULE* PCB_IO::FootprintLoad( const wxString& aLibraryPath, const wxString& aFo
const PROPERTIES* aProperties ) const PROPERTIES* aProperties )
{ {
const MODULE* footprint = getFootprint( aLibraryPath, aFootprintName, aProperties, true ); const MODULE* footprint = getFootprint( aLibraryPath, aFootprintName, aProperties, true );
return footprint ? new MODULE( *footprint ) : nullptr; return footprint ? (MODULE*) footprint->Duplicate() : nullptr;
} }
@ -2266,11 +2259,9 @@ void PCB_IO::FootprintSave( const wxString& aLibraryPath, const MODULE* aFootpri
} }
// I need my own copy for the cache // I need my own copy for the cache
MODULE* module = new MODULE( *aFootprint ); MODULE* module = static_cast<MODULE*>( aFootprint->Duplicate() );
// and it's time stamp must be 0, it should have no parent, orientation should // It should have no parent, orientation should be zero, and it should be on the front layer.
// be zero, and it should be on the front layer.
module->SetTimeStamp( 0 );
module->SetParent( nullptr ); module->SetParent( nullptr );
module->SetOrientation( 0 ); module->SetOrientation( 0 );
@ -2278,7 +2269,7 @@ void PCB_IO::FootprintSave( const wxString& aLibraryPath, const MODULE* aFootpri
{ {
auto cfg = dynamic_cast<PCBNEW_SETTINGS*>( Kiface().KifaceSettings() ); auto cfg = dynamic_cast<PCBNEW_SETTINGS*>( Kiface().KifaceSettings() );
if( cfg != nullptr ) if( cfg )
module->Flip( module->GetPosition(), cfg->m_FlipLeftRight ); module->Flip( module->GetPosition(), cfg->m_FlipLeftRight );
else else
module->Flip( module->GetPosition(), false ); module->Flip( module->GetPosition(), false );
@ -2301,7 +2292,7 @@ void PCB_IO::FootprintDelete( const wxString& aLibraryPath, const wxString& aFoo
if( !m_cache->IsWritable() ) if( !m_cache->IsWritable() )
{ {
THROW_IO_ERROR( wxString::Format( _( "Library \"%s\" is read only" ), THROW_IO_ERROR( wxString::Format( _( "Library \"%s\" is read only." ),
aLibraryPath.GetData() ) ); aLibraryPath.GetData() ) );
} }
@ -2320,7 +2311,7 @@ void PCB_IO::FootprintLibCreate( const wxString& aLibraryPath, const PROPERTIES*
{ {
if( wxDir::Exists( aLibraryPath ) ) if( wxDir::Exists( aLibraryPath ) )
{ {
THROW_IO_ERROR( wxString::Format( _( "cannot overwrite library path \"%s\"" ), THROW_IO_ERROR( wxString::Format( _( "Cannot overwrite library path \"%s\"." ),
aLibraryPath.GetData() ) ); aLibraryPath.GetData() ) );
} }
@ -2345,7 +2336,7 @@ bool PCB_IO::FootprintLibDelete( const wxString& aLibraryPath, const PROPERTIES*
if( !fn.IsDirWritable() ) if( !fn.IsDirWritable() )
{ {
THROW_IO_ERROR( wxString::Format( _( "user does not have permission to delete directory \"%s\"" ), THROW_IO_ERROR( wxString::Format( _( "User does not have permission to delete directory \"%s\"." ),
aLibraryPath.GetData() ) ); aLibraryPath.GetData() ) );
} }
@ -2353,7 +2344,7 @@ bool PCB_IO::FootprintLibDelete( const wxString& aLibraryPath, const PROPERTIES*
if( dir.HasSubDirs() ) if( dir.HasSubDirs() )
{ {
THROW_IO_ERROR( wxString::Format( _( "library directory \"%s\" has unexpected sub-directories" ), THROW_IO_ERROR( wxString::Format( _( "Library directory \"%s\" has unexpected sub-directories." ),
aLibraryPath.GetData() ) ); aLibraryPath.GetData() ) );
} }
@ -2372,25 +2363,23 @@ bool PCB_IO::FootprintLibDelete( const wxString& aLibraryPath, const PROPERTIES*
if( tmp.GetExt() != KiCadFootprintFileExtension ) if( tmp.GetExt() != KiCadFootprintFileExtension )
{ {
THROW_IO_ERROR( wxString::Format( _( "unexpected file \"%s\" was found in library path \"%s\"" ), THROW_IO_ERROR( wxString::Format( _( "Unexpected file \"%s\" was found in library path \"%s\"." ),
files[i].GetData(), aLibraryPath.GetData() ) ); files[i].GetData(), aLibraryPath.GetData() ) );
} }
} }
for( i = 0; i < files.GetCount(); i++ ) for( i = 0; i < files.GetCount(); i++ )
{
wxRemoveFile( files[i] ); wxRemoveFile( files[i] );
}
} }
wxLogTrace( traceKicadPcbPlugin, wxT( "Removing footprint library \"%s\"" ), wxLogTrace( traceKicadPcbPlugin, wxT( "Removing footprint library \"%s\"." ),
aLibraryPath.GetData() ); aLibraryPath.GetData() );
// Some of the more elaborate wxRemoveFile() crap puts up its own wxLog dialog // Some of the more elaborate wxRemoveFile() crap puts up its own wxLog dialog
// we don't want that. we want bare metal portability with no UI here. // we don't want that. we want bare metal portability with no UI here.
if( !wxRmdir( aLibraryPath ) ) if( !wxRmdir( aLibraryPath ) )
{ {
THROW_IO_ERROR( wxString::Format( _( "footprint library \"%s\" cannot be deleted" ), THROW_IO_ERROR( wxString::Format( _( "Footprint library \"%s\" cannot be deleted." ),
aLibraryPath.GetData() ) ); aLibraryPath.GetData() ) );
} }

View File

@ -4,7 +4,7 @@
* *
* Copyright (C) 2007-2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> * Copyright (C) 2007-2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2019 Jean-Pierre Charras, jp.charras@wanadoo.fr * Copyright (C) 2019 Jean-Pierre Charras, jp.charras@wanadoo.fr
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2020 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
@ -651,13 +651,6 @@ void LEGACY_PLUGIN::loadGENERAL()
m_board->GetDesignSettings().SetBoardThickness( thickn ); m_board->GetDesignSettings().SetBoardThickness( thickn );
} }
/*
else if( TESTLINE( "Links" ) )
{
// Info only, do nothing, but only for a short while.
}
*/
else if( TESTLINE( "NoConn" ) ) else if( TESTLINE( "NoConn" ) )
{ {
// ignore // ignore
@ -672,28 +665,6 @@ void LEGACY_PLUGIN::loadGENERAL()
biuParse( data ); biuParse( data );
} }
/* This is no more usefull, so this info is no more parsed
// Read the number of segments of type DRAW, TRACK, ZONE
else if( TESTLINE( "Ndraw" ) )
{
NbDraw = intParse( line + SZ( "Ndraw" ) );
}
else if( TESTLINE( "Ntrack" ) )
{
NbTrack = intParse( line + SZ( "Ntrack" ) );
}
else if( TESTLINE( "Nzone" ) )
{
NbZone = intParse( line + SZ( "Nzone" ) );
}
else if( TESTLINE( "Nmodule" ) )
{
NbMod = intParse( line + SZ( "Nmodule" ) );
}*/
else if( TESTLINE( "Nnets" ) ) else if( TESTLINE( "Nnets" ) )
{ {
m_netCodes.resize( intParse( line + SZ( "Nnets" ) ) ); m_netCodes.resize( intParse( line + SZ( "Nnets" ) ) );
@ -717,7 +688,7 @@ void LEGACY_PLUGIN::loadSHEET()
char buf[260]; char buf[260];
TITLE_BLOCK tb; TITLE_BLOCK tb;
char* line; char* line;
char* saveptr; char* data;
while( ( line = READLINE( m_reader ) ) != NULL ) while( ( line = READLINE( m_reader ) ) != NULL )
{ {
@ -725,23 +696,24 @@ void LEGACY_PLUGIN::loadSHEET()
{ {
// e.g. "Sheet A3 16535 11700" // e.g. "Sheet A3 16535 11700"
// width and height are in 1/1000th of an inch, always // width and height are in 1/1000th of an inch, always
PAGE_INFO page; PAGE_INFO page;
char* sname = strtok_r( line + SZ( "Sheet" ), delims, &saveptr ); char* sname = strtok_r( line + SZ( "Sheet" ), delims, &data );
if( sname ) if( sname )
{ {
wxString wname = FROM_UTF8( sname ); wxString wname = FROM_UTF8( sname );
if( !page.SetType( wname ) ) if( !page.SetType( wname ) )
{ {
m_error.Printf( _( "Unknown sheet type \"%s\" on line:%d" ), m_error.Printf( _( "Unknown sheet type \"%s\" on line:%d" ),
wname.GetData(), m_reader->LineNumber() ); wname.GetData(),
m_reader->LineNumber() );
THROW_IO_ERROR( m_error ); THROW_IO_ERROR( m_error );
} }
char* width = strtok_r( NULL, delims, &saveptr ); char* width = strtok_r( NULL, delims, &data );
char* height = strtok_r( NULL, delims, &saveptr ); char* height = strtok_r( NULL, delims, &data );
char* orient = strtok_r( NULL, delims, &saveptr ); char* orient = strtok_r( NULL, delims, &data );
// only parse the width and height if page size is custom ("User") // only parse the width and height if page size is custom ("User")
if( wname == PAGE_INFO::Custom ) if( wname == PAGE_INFO::Custom )
@ -924,12 +896,14 @@ void LEGACY_PLUGIN::loadSETUP()
*/ */
data = strtok_r( (char*) data+1, delims, &saveptr ); // +1 for ']' data = strtok_r( (char*) data+1, delims, &saveptr ); // +1 for ']'
if( data ) if( data )
{ {
wxString layerName = FROM_UTF8( data ); wxString layerName = FROM_UTF8( data );
m_board->SetLayerName( layer_id, layerName ); m_board->SetLayerName( layer_id, layerName );
data = strtok_r( NULL, delims, &saveptr ); data = strtok_r( NULL, delims, &saveptr );
if( data ) // optional in old board files if( data ) // optional in old board files
{ {
LAYER_T type = LAYER::ParseType( data ); LAYER_T type = LAYER::ParseType( data );
@ -1005,7 +979,7 @@ void LEGACY_PLUGIN::loadSETUP()
BIU drill = 0; BIU drill = 0;
BIU diameter = biuParse( line + SZ( "ViaSizeList" ), &data ); BIU diameter = biuParse( line + SZ( "ViaSizeList" ), &data );
data = strtok_r( (char*) data, delims, &saveptr ); data = strtok_r( (char*) data, delims, (char**) &data );
if( data ) // DRILL may not be present ? if( data ) // DRILL may not be present ?
drill = biuParse( data ); drill = biuParse( data );
@ -1194,7 +1168,6 @@ void LEGACY_PLUGIN::loadSETUP()
void LEGACY_PLUGIN::loadMODULE( MODULE* aModule ) void LEGACY_PLUGIN::loadMODULE( MODULE* aModule )
{ {
char* line; char* line;
char* saveptr;
while( ( line = READLINE( m_reader ) ) != NULL ) while( ( line = READLINE( m_reader ) ) != NULL )
{ {
@ -1216,10 +1189,9 @@ void LEGACY_PLUGIN::loadMODULE( MODULE* aModule )
else if( TESTSUBSTR( "T" ) ) else if( TESTSUBSTR( "T" ) )
{ {
// e.g. "T1 6940 -16220 350 300 900 60 M I 20 N "CFCARD"\r\n" // e.g. "T1 6940 -16220 350 300 900 60 M I 20 N "CFCARD"\r\n"
int tnum = intParse( line + SZ( "T" ) ); int tnum = intParse( line + SZ( "T" ) );
TEXTE_MODULE* textm = 0; TEXTE_MODULE* textm = nullptr;
switch( tnum ) switch( tnum )
{ {
@ -1242,21 +1214,16 @@ void LEGACY_PLUGIN::loadMODULE( MODULE* aModule )
else if( TESTLINE( "Po" ) ) else if( TESTLINE( "Po" ) )
{ {
// e.g. "Po 19120 39260 900 0 4E823D06 46EAAFA5 ~~\r\n" // e.g. "Po 19120 39260 900 0 4E823D06 68183921-93a5-49ac-91b0-49d05a0e1647 ~~\r\n"
BIU pos_x = biuParse( line + SZ( "Po" ), &data );
// sscanf( PtLine, "%d %d %d %d %lX %lX %s", &m_Pos.x, &m_Pos.y, &m_Orient, &m_Layer, &m_LastEdit_Time, &m_TimeStamp, BufCar1 ); BIU pos_y = biuParse( data, &data );
int orient = intParse( data, &data );
BIU pos_x = biuParse( line + SZ( "Po" ), &data );
BIU pos_y = biuParse( data, &data );
int orient = intParse( data, &data );
LAYER_NUM layer_num = layerParse( data, &data ); LAYER_NUM layer_num = layerParse( data, &data );
PCB_LAYER_ID layer_id = leg_layer2new( m_cu_count, layer_num ); PCB_LAYER_ID layer_id = leg_layer2new( m_cu_count, layer_num );
long edittime = hexParse( data, &data );
char* uuid = strtok_r( (char*) data, delims, (char**) &data );
long edittime = hexParse( data, &data ); data = strtok_r( (char*) data+1, delims, (char**) &data );
timestamp_t timestamp = hexParse( data, &data );
data = strtok_r( (char*) data+1, delims, &saveptr );
// data is now a two character long string // data is now a two character long string
// Note: some old files do not have this field // Note: some old files do not have this field
@ -1269,7 +1236,7 @@ void LEGACY_PLUGIN::loadMODULE( MODULE* aModule )
aModule->SetPosition( wxPoint( pos_x, pos_y ) ); aModule->SetPosition( wxPoint( pos_x, pos_y ) );
aModule->SetLayer( layer_id ); aModule->SetLayer( layer_id );
aModule->SetOrientation( orient ); aModule->SetOrientation( orient );
aModule->SetTimeStamp( timestamp ); const_cast<UUID&>( aModule->m_Uuid ) = UUID( uuid );
aModule->SetLastEditTime( edittime ); aModule->SetLastEditTime( edittime );
} }
@ -1284,8 +1251,8 @@ void LEGACY_PLUGIN::loadMODULE( MODULE* aModule )
else if( TESTLINE( "Sc" ) ) // timestamp else if( TESTLINE( "Sc" ) ) // timestamp
{ {
timestamp_t timestamp = hexParse( line + SZ( "Sc" ) ); char* uuid = strtok_r( (char*) line + SZ( "Sc" ), delims, (char**) &data );
aModule->SetTimeStamp( timestamp ); const_cast<UUID&>( aModule->m_Uuid ) = UUID( uuid );
} }
else if( TESTLINE( "Op" ) ) // (Op)tions for auto placement else if( TESTLINE( "Op" ) ) // (Op)tions for auto placement
@ -1327,10 +1294,11 @@ void LEGACY_PLUGIN::loadMODULE( MODULE* aModule )
else if( TESTLINE( "AR" ) ) // Alternate Reference else if( TESTLINE( "AR" ) ) // Alternate Reference
{ {
// e.g. "AR /47BA2624/45525076" // e.g. "AR /68183921-93a5-49ac-e164-49d05a0e1647/93a549d0-49d0-e164-91b0-49d05a0e1647"
data = strtok_r( line + SZ( "AR" ), delims, &saveptr ); data = strtok_r( line + SZ( "AR" ), delims, (char**) &data );
if( data ) if( data )
aModule->SetPath( FROM_UTF8( data ) ); aModule->SetPath( UUID_PATH( FROM_UTF8( data ) ) );
} }
else if( TESTLINE( "$SHAPE3D" ) ) else if( TESTLINE( "$SHAPE3D" ) )
@ -1440,7 +1408,6 @@ void LEGACY_PLUGIN::loadPAD( MODULE* aModule )
data = data + ReadDelimitedText( mypadname, data, sizeof(mypadname) ) + 1; // +1 trailing whitespace data = data + ReadDelimitedText( mypadname, data, sizeof(mypadname) ) + 1; // +1 trailing whitespace
// sscanf( PtLine, " %s %d %d %d %d %d", BufCar, &m_Size.x, &m_Size.y, &m_DeltaSize.x, &m_DeltaSize.y, &m_Orient );
while( isSpace( *data ) ) while( isSpace( *data ) )
++data; ++data;
@ -1499,8 +1466,6 @@ void LEGACY_PLUGIN::loadPAD( MODULE* aModule )
else if( TESTLINE( "Dr" ) ) // (Dr)ill else if( TESTLINE( "Dr" ) ) // (Dr)ill
{ {
// e.g. "Dr 350 0 0" or "Dr 0 0 0 O 0 0" // e.g. "Dr 350 0 0" or "Dr 0 0 0 O 0 0"
// sscanf( PtLine, "%d %d %d %s %d %d", &m_Drill.x, &m_Offset.x, &m_Offset.y, BufCar, &dx, &dy );
BIU drill_x = biuParse( line + SZ( "Dr" ), &data ); BIU drill_x = biuParse( line + SZ( "Dr" ), &data );
BIU drill_y = drill_x; BIU drill_y = drill_x;
BIU offs_x = biuParse( data, &data ); BIU offs_x = biuParse( data, &data );
@ -1535,7 +1500,7 @@ void LEGACY_PLUGIN::loadPAD( MODULE* aModule )
PAD_ATTR_T attribute; PAD_ATTR_T attribute;
data = strtok_r( line + SZ( "At" ), delims, &saveptr ); data = strtok_r( line + SZ( "At" ), delims, (char**) &data );
if( !strcmp( data, "SMD" ) ) if( !strcmp( data, "SMD" ) )
attribute = PAD_ATTRIB_SMD; attribute = PAD_ATTRIB_SMD;
@ -1546,8 +1511,8 @@ void LEGACY_PLUGIN::loadPAD( MODULE* aModule )
else else
attribute = PAD_ATTRIB_STANDARD; attribute = PAD_ATTRIB_STANDARD;
strtok_r( NULL, delims, &saveptr ); // skip BufCar strtok_r( NULL, delims, (char**) &data ); // skip BufCar
data = strtok_r( NULL, delims, &saveptr ); strtok_r( NULL, delims, (char**) &data );
LEG_MASK layer_mask = hexParse( data ); LEG_MASK layer_mask = hexParse( data );
@ -1567,11 +1532,9 @@ void LEGACY_PLUGIN::loadPAD( MODULE* aModule )
// read Netname // read Netname
ReadDelimitedText( buf, data, sizeof(buf) ); ReadDelimitedText( buf, data, sizeof(buf) );
#ifndef NDEBUG
if( m_board ) wxASSERT( m_board->FindNet( getNetCode( netcode ) )->GetNetname()
assert( m_board->FindNet( getNetCode( netcode ) )->GetNetname() == == FROM_UTF8( StrPurge( buf ) ) );
FROM_UTF8( StrPurge( buf ) ) );
#endif /* NDEBUG */
} }
else if( TESTLINE( "Po" ) ) // (Po)sition else if( TESTLINE( "Po" ) ) // (Po)sition
@ -1687,7 +1650,6 @@ void LEGACY_PLUGIN::loadMODULE_EDGE( MODULE* aModule )
{ {
case S_ARC: case S_ARC:
{ {
// sscanf( Line + 3, "%d %d %d %d %d %d %d", &m_Start0.x, &m_Start0.y, &m_End0.x, &m_End0.y, &m_Angle, &m_Width, &m_Layer );
BIU start0_x = biuParse( line + SZ( "DA" ), &data ); BIU start0_x = biuParse( line + SZ( "DA" ), &data );
BIU start0_y = biuParse( data, &data ); BIU start0_y = biuParse( data, &data );
BIU end0_x = biuParse( data, &data ); BIU end0_x = biuParse( data, &data );
@ -1707,8 +1669,6 @@ void LEGACY_PLUGIN::loadMODULE_EDGE( MODULE* aModule )
case S_CIRCLE: case S_CIRCLE:
{ {
// e.g. "DS -7874 -10630 7874 -10630 50 20\r\n" // e.g. "DS -7874 -10630 7874 -10630 50 20\r\n"
// sscanf( Line + 3, "%d %d %d %d %d %d", &m_Start0.x, &m_Start0.y, &m_End0.x, &m_End0.y, &m_Width, &m_Layer );
BIU start0_x = biuParse( line + SZ( "DS" ), &data ); BIU start0_x = biuParse( line + SZ( "DS" ), &data );
BIU start0_y = biuParse( data, &data ); BIU start0_y = biuParse( data, &data );
BIU end0_x = biuParse( data, &data ); BIU end0_x = biuParse( data, &data );
@ -1725,8 +1685,6 @@ void LEGACY_PLUGIN::loadMODULE_EDGE( MODULE* aModule )
case S_POLYGON: case S_POLYGON:
{ {
// e.g. "DP %d %d %d %d %d %d %d\n" // e.g. "DP %d %d %d %d %d %d %d\n"
// sscanf( Line + 3, "%d %d %d %d %d %d %d", &m_Start0.x, &m_Start0.y, &m_End0.x, &m_End0.y, &pointCount, &m_Width, &m_Layer );
BIU start0_x = biuParse( line + SZ( "DP" ), &data ); BIU start0_x = biuParse( line + SZ( "DP" ), &data );
BIU start0_y = biuParse( data, &data ); BIU start0_y = biuParse( data, &data );
BIU end0_x = biuParse( data, &data ); BIU end0_x = biuParse( data, &data );
@ -1797,7 +1755,6 @@ void LEGACY_PLUGIN::loadMODULE_TEXT( TEXTE_MODULE* aText )
const char* data; const char* data;
const char* txt_end; const char* txt_end;
const char* line = m_reader->Line(); // current (old) line const char* line = m_reader->Line(); // current (old) line
char* saveptr;
// sscanf( line + 1, "%d %d %d %d %d %d %d %s %s %d %s", // sscanf( line + 1, "%d %d %d %d %d %d %d %s %s %d %s",
// &type, &m_Pos0.x, &m_Pos0.y, &m_Size.y, &m_Size.x, // &type, &m_Pos0.x, &m_Pos0.y, &m_Size.y, &m_Size.x,
@ -1829,16 +1786,16 @@ void LEGACY_PLUGIN::loadMODULE_TEXT( TEXTE_MODULE* aText )
// after switching to strtok, there's no easy coming back because of the // after switching to strtok, there's no easy coming back because of the
// embedded nul(s?) placed to the right of the current field. // embedded nul(s?) placed to the right of the current field.
// (that's the reason why strtok was deprecated...) // (that's the reason why strtok was deprecated...)
char* mirror = strtok_r( (char*) data, delims, &saveptr ); char* mirror = strtok_r( (char*) data, delims, (char**) &data );
char* hide = strtok_r( NULL, delims, &saveptr ); char* hide = strtok_r( NULL, delims, (char**) &data );
char* tmp = strtok_r( NULL, delims, &saveptr ); char* tmp = strtok_r( NULL, delims, (char**) &data );
LAYER_NUM layer_num = tmp ? layerParse( tmp ) : SILKSCREEN_N_FRONT; LAYER_NUM layer_num = tmp ? layerParse( tmp ) : SILKSCREEN_N_FRONT;
char* italic = strtok_r( NULL, delims, &saveptr ); char* italic = strtok_r( NULL, delims, (char**) &data );
char* hjust = strtok_r( (char*) txt_end, delims, &saveptr ); char* hjust = strtok_r( (char*) txt_end, delims, (char**) &data );
char* vjust = strtok_r( NULL, delims, &saveptr ); char* vjust = strtok_r( NULL, delims, (char**) &data );
if( type != TEXTE_MODULE::TEXT_is_REFERENCE if( type != TEXTE_MODULE::TEXT_is_REFERENCE
&& type != TEXTE_MODULE::TEXT_is_VALUE ) && type != TEXTE_MODULE::TEXT_is_VALUE )
@ -1963,7 +1920,6 @@ void LEGACY_PLUGIN::loadPCB_LINE()
if( TESTLINE( "Po" ) ) if( TESTLINE( "Po" ) )
{ {
// sscanf( line + 2, " %d %d %d %d %d %d", &m_Shape, &m_Start.x, &m_Start.y, &m_End.x, &m_End.y, &m_Width );
int shape = intParse( line + SZ( "Po" ), &data ); int shape = intParse( line + SZ( "Po" ), &data );
BIU start_x = biuParse( data, &data ); BIU start_x = biuParse( data, &data );
BIU start_y = biuParse( data, &data ); BIU start_y = biuParse( data, &data );
@ -2013,9 +1969,7 @@ void LEGACY_PLUGIN::loadPCB_LINE()
dseg->SetAngle( angle ); // m_Angle dseg->SetAngle( angle ); // m_Angle
break; break;
case 3: case 3:
timestamp_t timestamp; const_cast<UUID&>( dseg->m_Uuid ) = UUID( data );
timestamp = hexParse( data );
dseg->SetTimeStamp( timestamp );
break; break;
case 4: case 4:
STATUS_FLAGS state; STATUS_FLAGS state;
@ -2151,7 +2105,6 @@ void LEGACY_PLUGIN::loadPCB_TEXT()
m_board->Add( pcbtxt, ADD_MODE::APPEND ); m_board->Add( pcbtxt, ADD_MODE::APPEND );
char* line; char* line;
char* saveptr;
while( ( line = READLINE( m_reader ) ) != NULL ) while( ( line = READLINE( m_reader ) ) != NULL )
{ {
@ -2171,7 +2124,6 @@ void LEGACY_PLUGIN::loadPCB_TEXT()
else if( TESTLINE( "Po" ) ) else if( TESTLINE( "Po" ) )
{ {
// sscanf( line + 2, " %d %d %d %d %d %d", &m_Pos.x, &m_Pos.y, &m_Size.x, &m_Size.y, &m_Thickness, &m_Orient );
wxSize size; wxSize size;
BIU pos_x = biuParse( line + SZ( "Po" ), &data ); BIU pos_x = biuParse( line + SZ( "Po" ), &data );
@ -2191,18 +2143,16 @@ void LEGACY_PLUGIN::loadPCB_TEXT()
else if( TESTLINE( "De" ) ) else if( TESTLINE( "De" ) )
{ {
// e.g. "De 21 1 0 Normal C\r\n" // e.g. "De 21 1 68183921-93a5-49ac-91b0-49d05a0e1647 Normal C\r\n"
// sscanf( line + 2, " %d %d %lX %s %c\n", &m_Layer, &normal_display, &m_TimeStamp, style, &hJustify );
LAYER_NUM layer_num = layerParse( line + SZ( "De" ), &data ); LAYER_NUM layer_num = layerParse( line + SZ( "De" ), &data );
int notMirrored = intParse( data, &data ); int notMirrored = intParse( data, &data );
timestamp_t timestamp = hexParse( data, &data ); char* uuid = strtok_r( (char*) data, delims, (char**) &data );
char* style = strtok_r( (char*) data, delims, &saveptr ); char* style = strtok_r( NULL, delims, (char**) &data );
char* hJustify = strtok_r( NULL, delims, &saveptr ); char* hJustify = strtok_r( NULL, delims, (char**) &data );
char* vJustify = strtok_r( NULL, delims, &saveptr ); char* vJustify = strtok_r( NULL, delims, (char**) &data );
pcbtxt->SetMirrored( !notMirrored ); pcbtxt->SetMirrored( !notMirrored );
pcbtxt->SetTimeStamp( timestamp ); const_cast<UUID&>( pcbtxt->m_Uuid ) = UUID( uuid );
pcbtxt->SetItalic( !strcmp( style, "Italic" ) ); pcbtxt->SetItalic( !strcmp( style, "Italic" ) );
if( hJustify ) if( hJustify )
@ -2241,7 +2191,6 @@ void LEGACY_PLUGIN::loadPCB_TEXT()
void LEGACY_PLUGIN::loadTrackList( int aStructType ) void LEGACY_PLUGIN::loadTrackList( int aStructType )
{ {
char* line; char* line;
char* saveptr;
while( ( line = READLINE( m_reader ) ) != NULL ) while( ( line = READLINE( m_reader ) ) != NULL )
{ {
@ -2249,14 +2198,11 @@ void LEGACY_PLUGIN::loadTrackList( int aStructType )
// example first line: // example first line:
// e.g. "Po 0 23994 28800 24400 28800 150 -1" for a track // e.g. "Po 0 23994 28800 24400 28800 150 -1" for a track
// e.g. "Po 3 21086 17586 21086 17586 180 -1" for a via (uses sames start and end) // e.g. "Po 3 21086 17586 21086 17586 180 -1" for a via (uses sames start and end)
const char* data; const char* data;
if( line[0] == '$' ) // $EndTRACK if( line[0] == '$' ) // $EndTRACK
return; // preferred exit return; // preferred exit
// int arg_count = sscanf( line + 2, " %d %d %d %d %d %d %d", &shape, &tempStartX, &tempStartY, &tempEndX, &tempEndY, &width, &drill );
assert( TESTLINE( "Po" ) ); assert( TESTLINE( "Po" ) );
VIATYPE viatype = static_cast<VIATYPE>( intParse( line + SZ( "Po" ), &data ) ); VIATYPE viatype = static_cast<VIATYPE>( intParse( line + SZ( "Po" ), &data ) );
@ -2267,7 +2213,7 @@ void LEGACY_PLUGIN::loadTrackList( int aStructType )
BIU width = biuParse( data, &data ); BIU width = biuParse( data, &data );
// optional 7th drill parameter (must be optional in an old format?) // optional 7th drill parameter (must be optional in an old format?)
data = strtok_r( (char*) data, delims, &saveptr ); data = strtok_r( (char*) data, delims, (char**) &data );
BIU drill = data ? biuParse( data ) : -1; // SetDefault() if < 0 BIU drill = data ? biuParse( data ) : -1; // SetDefault() if < 0
@ -2294,18 +2240,16 @@ void LEGACY_PLUGIN::loadTrackList( int aStructType )
#endif #endif
int makeType; int makeType;
unsigned long timeStamp;
LAYER_NUM layer_num;
int type, net_code, flags_int;
// parse the 2nd line to determine the type of object // parse the 2nd line to determine the type of object
// e.g. "De 15 1 7 0 0" for a via // e.g. "De 15 1 7 68183921-93a5-49ac-91b0-49d05a0e1647 0" for a via
sscanf( line + SZ( "De" ), " %d %d %d %lX %X", &layer_num, &type, &net_code, LAYER_NUM layer_num = layerParse( line + SZ( "De" ), &data );
&timeStamp, &flags_int ); int type = intParse( data, &data );
int net_code = intParse( data, &data );
char* uuid = strtok_r( (char*) data, delims, (char**) &data );
int flags_int = intParse( data, (const char**) &data );
STATUS_FLAGS flags; STATUS_FLAGS flags = static_cast<STATUS_FLAGS>( flags_int );
flags = static_cast<STATUS_FLAGS>( flags_int );
if( aStructType == PCB_TRACE_T ) if( aStructType == PCB_TRACE_T )
{ {
@ -2326,16 +2270,11 @@ void LEGACY_PLUGIN::loadTrackList( int aStructType )
switch( makeType ) switch( makeType )
{ {
default: default:
case PCB_TRACE_T: case PCB_TRACE_T: newTrack = new TRACK( m_board ); break;
newTrack = new TRACK( m_board ); case PCB_VIA_T: newTrack = new VIA( m_board ); break;
break;
case PCB_VIA_T:
newTrack = new VIA( m_board );
break;
} }
newTrack->SetTimeStamp( (timestamp_t)timeStamp ); const_cast<UUID&>( newTrack->m_Uuid ) = UUID( uuid );
newTrack->SetPosition( wxPoint( start_x, start_y ) ); newTrack->SetPosition( wxPoint( start_x, start_y ) );
newTrack->SetEnd( wxPoint( end_x, end_y ) ); newTrack->SetEnd( wxPoint( end_x, end_y ) );
@ -2495,7 +2434,6 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
int holeIndex = -1; // -1 is the main outline; holeIndex >= 0 = hole index int holeIndex = -1; // -1 is the main outline; holeIndex >= 0 = hole index
char buf[1024]; char buf[1024];
char* line; char* line;
char* saveptr;
while( ( line = READLINE( m_reader ) ) != NULL ) while( ( line = READLINE( m_reader ) ) != NULL )
{ {
@ -2526,16 +2464,14 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
else if( TESTLINE( "ZInfo" ) ) // general info found else if( TESTLINE( "ZInfo" ) ) // general info found
{ {
// e.g. 'ZInfo 479194B1 310 "COMMON"' // e.g. 'ZInfo 68183921-93a5-49ac-91b0-49d05a0e1647 310 "COMMON"'
timestamp_t timestamp = hexParse( line + SZ( "ZInfo" ), &data ); char* uuid = strtok_r( (char*) line + SZ( "ZInfo" ), delims, (char**) &data );
int netcode = intParse( data, &data ); int netcode = intParse( data, &data );
if( ReadDelimitedText( buf, data, sizeof(buf) ) > (int) sizeof(buf) ) if( ReadDelimitedText( buf, data, sizeof(buf) ) > (int) sizeof(buf) )
{
THROW_IO_ERROR( "ZInfo netname too long" ); THROW_IO_ERROR( "ZInfo netname too long" );
}
zc->SetTimeStamp( timestamp ); const_cast<UUID&>( zc->m_Uuid ) = UUID( uuid );
// Init the net code only, not the netname, to be sure // Init the net code only, not the netname, to be sure
// the zone net name is the name read in file. // the zone net name is the name read in file.
// (When mismatch, the user will be prompted in DRC, to fix the actual name) // (When mismatch, the user will be prompted in DRC, to fix the actual name)
@ -2552,29 +2488,23 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
{ {
// e.g. "ZAux 7 E" // e.g. "ZAux 7 E"
int ignore = intParse( line + SZ( "ZAux" ), &data ); int ignore = intParse( line + SZ( "ZAux" ), &data );
char* hopt = strtok_r( (char*) data, delims, &saveptr ); char* hopt = strtok_r( (char*) data, delims, (char**) &data );
if( !hopt ) if( !hopt )
{ {
m_error.Printf( _( "Bad ZAux for CZONE_CONTAINER \"%s\"" ), zc->GetNetname().GetData() ); m_error.Printf( _( "Bad ZAux for CZONE_CONTAINER \"%s\"" ),
zc->GetNetname().GetData() );
THROW_IO_ERROR( m_error ); THROW_IO_ERROR( m_error );
} }
switch( *hopt ) // upper case required switch( *hopt ) // upper case required
{ {
case 'N': case 'N': outline_hatch = ZONE_HATCH_STYLE::NO_HATCH; break;
outline_hatch = ZONE_HATCH_STYLE::NO_HATCH; case 'E': outline_hatch = ZONE_HATCH_STYLE::DIAGONAL_EDGE; break;
break; case 'F': outline_hatch = ZONE_HATCH_STYLE::DIAGONAL_FULL; break;
case 'E':
outline_hatch = ZONE_HATCH_STYLE::DIAGONAL_EDGE;
break;
case 'F':
outline_hatch = ZONE_HATCH_STYLE::DIAGONAL_FULL;
break;
default: default:
m_error.Printf( m_error.Printf( _( "Bad ZAux for CZONE_CONTAINER \"%s\"" ),
_( "Bad ZAux for CZONE_CONTAINER \"%s\"" ), zc->GetNetname().GetData() ); zc->GetNetname().GetData() );
THROW_IO_ERROR( m_error ); THROW_IO_ERROR( m_error );
} }
@ -2591,7 +2521,8 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
if( smoothing >= ZONE_SETTINGS::SMOOTHING_LAST || smoothing < 0 ) if( smoothing >= ZONE_SETTINGS::SMOOTHING_LAST || smoothing < 0 )
{ {
m_error.Printf( _( "Bad ZSmoothing for CZONE_CONTAINER \"%s\"" ), zc->GetNetname().GetData() ); m_error.Printf( _( "Bad ZSmoothing for CZONE_CONTAINER \"%s\"" ),
zc->GetNetname().GetData() );
THROW_IO_ERROR( m_error ); THROW_IO_ERROR( m_error );
} }
@ -2601,29 +2532,30 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
else if( TESTLINE( "ZKeepout" ) ) else if( TESTLINE( "ZKeepout" ) )
{ {
char* token;
zc->SetIsKeepout( true ); zc->SetIsKeepout( true );
// e.g. "ZKeepout tracks N vias N pads Y" // e.g. "ZKeepout tracks N vias N pads Y"
data = strtok_r( line + SZ( "ZKeepout" ), delims, &saveptr ); token = strtok_r( line + SZ( "ZKeepout" ), delims, (char**) &data );
while( data ) while( token )
{ {
if( !strcmp( data, "tracks" ) ) if( !strcmp( token, "tracks" ) )
{ {
data = strtok_r( NULL, delims, &saveptr ); token = strtok_r( NULL, delims, (char**) &data );
zc->SetDoNotAllowTracks( data && *data == 'N' ); zc->SetDoNotAllowTracks( token && *token == 'N' );
} }
else if( !strcmp( data, "vias" ) ) else if( !strcmp( token, "vias" ) )
{ {
data = strtok_r( NULL, delims, &saveptr ); token = strtok_r( NULL, delims, (char**) &data );
zc->SetDoNotAllowVias( data && *data == 'N' ); zc->SetDoNotAllowVias( token && *token == 'N' );
} }
else if( !strcmp( data, "copperpour" ) ) else if( !strcmp( token, "copperpour" ) )
{ {
data = strtok_r( NULL, delims, &saveptr ); token = strtok_r( NULL, delims, (char**) &data );
zc->SetDoNotAllowCopperPour( data && *data == 'N' ); zc->SetDoNotAllowCopperPour( token && *token == 'N' );
} }
data = strtok_r( NULL, delims, &saveptr ); token = strtok_r( NULL, delims, (char**) &data );
} }
} }
@ -2671,27 +2603,18 @@ void LEGACY_PLUGIN::loadZONE_CONTAINER()
{ {
// e.g. "ZClearance 40 I" // e.g. "ZClearance 40 I"
BIU clearance = biuParse( line + SZ( "ZClearance" ), &data ); BIU clearance = biuParse( line + SZ( "ZClearance" ), &data );
char* padoption = strtok_r( (char*) data, delims, &saveptr ); // data: " I" char* padoption = strtok_r( (char*) data, delims, (char**) &data ); // data: " I"
ZONE_CONNECTION popt; ZONE_CONNECTION popt;
switch( *padoption ) switch( *padoption )
{ {
case 'I': case 'I': popt = ZONE_CONNECTION::FULL; break;
popt = ZONE_CONNECTION::FULL; case 'T': popt = ZONE_CONNECTION::THERMAL; break;
break; case 'H': popt = ZONE_CONNECTION::THT_THERMAL; break;
case 'T': case 'X': popt = ZONE_CONNECTION::NONE; break;
popt = ZONE_CONNECTION::THERMAL;
break;
case 'H':
popt = ZONE_CONNECTION::THT_THERMAL;
break;
case 'X':
popt = ZONE_CONNECTION::NONE;
break;
default: default:
m_error.Printf( _( "Bad ZClearance padoption for CZONE_CONTAINER \"%s\"" ), m_error.Printf( _( "Bad ZClearance padoption for CZONE_CONTAINER \"%s\"" ),
zc->GetNetname().GetData() ); zc->GetNetname().GetData() );
THROW_IO_ERROR( m_error ); THROW_IO_ERROR( m_error );
} }
@ -2797,7 +2720,6 @@ void LEGACY_PLUGIN::loadDIMENSION()
unique_ptr<DIMENSION> dim( new DIMENSION( m_board ) ); unique_ptr<DIMENSION> dim( new DIMENSION( m_board ) );
char* line; char* line;
char* saveptr;
while( ( line = READLINE( m_reader ) ) != NULL ) while( ( line = READLINE( m_reader ) ) != NULL )
{ {
@ -2817,22 +2739,13 @@ void LEGACY_PLUGIN::loadDIMENSION()
else if( TESTLINE( "Ge" ) ) else if( TESTLINE( "Ge" ) )
{ {
LAYER_NUM layer_num; // e.g. "Ge 1 21 68183921-93a5-49ac-91b0-49d05a0e1647\r\n"
unsigned long timestamp; int shape = intParse( line + SZ( "De" ), (const char**) &data );
int shape; LAYER_NUM layer_num = layerParse( data, &data );
int ilayer; char* uuid = strtok_r( (char*) data, delims, (char**) &data );
sscanf( line + SZ( "Ge" ), " %d %d %lX", &shape, &ilayer, &timestamp );
if( ilayer < FIRST_NON_COPPER_LAYER )
layer_num = FIRST_NON_COPPER_LAYER;
else if( ilayer > LAST_NON_COPPER_LAYER )
layer_num = LAST_NON_COPPER_LAYER;
else
layer_num = ilayer;
dim->SetLayer( leg_layer2new( m_cu_count, layer_num ) ); dim->SetLayer( leg_layer2new( m_cu_count, layer_num ) );
dim->SetTimeStamp( (timestamp_t) timestamp ); const_cast<UUID&>( dim->m_Uuid ) = UUID( uuid );
dim->SetShape( shape ); dim->SetShape( shape );
} }
@ -2846,16 +2759,13 @@ void LEGACY_PLUGIN::loadDIMENSION()
else if( TESTLINE( "Po" ) ) else if( TESTLINE( "Po" ) )
{ {
// sscanf( Line + 2, " %d %d %d %d %d %d %d", &m_Text->m_Pos.x, &m_Text->m_Pos.y,
// &m_Text->m_Size.x, &m_Text->m_Size.y, &thickness, &orientation, &normal_display );
BIU pos_x = biuParse( line + SZ( "Po" ), &data ); BIU pos_x = biuParse( line + SZ( "Po" ), &data );
BIU pos_y = biuParse( data, &data ); BIU pos_y = biuParse( data, &data );
BIU width = biuParse( data, &data ); BIU width = biuParse( data, &data );
BIU height = biuParse( data, &data ); BIU height = biuParse( data, &data );
BIU thickn = biuParse( data, &data ); BIU thickn = biuParse( data, &data );
double orient = degParse( data, &data ); double orient = degParse( data, &data );
char* mirror = strtok_r( (char*) data, delims, &saveptr ); char* mirror = strtok_r( (char*) data, delims, (char**) &data );
// This sets both DIMENSION's position and internal m_Text's. // This sets both DIMENSION's position and internal m_Text's.
// @todo: But why do we even know about internal m_Text? // @todo: But why do we even know about internal m_Text?
@ -2869,8 +2779,6 @@ void LEGACY_PLUGIN::loadDIMENSION()
else if( TESTLINE( "Sb" ) ) else if( TESTLINE( "Sb" ) )
{ {
// sscanf( Line + 2, " %d %d %d %d %d %d", &Dummy, &m_crossBarOx, &m_crossBarOy, &m_crossBarFx, &m_crossBarFy, &m_Width );
int ignore = biuParse( line + SZ( "Sb" ), &data ); int ignore = biuParse( line + SZ( "Sb" ), &data );
BIU crossBarOx = biuParse( data, &data ); BIU crossBarOx = biuParse( data, &data );
BIU crossBarOy = biuParse( data, &data ); BIU crossBarOy = biuParse( data, &data );
@ -2888,8 +2796,6 @@ void LEGACY_PLUGIN::loadDIMENSION()
else if( TESTLINE( "Sd" ) ) else if( TESTLINE( "Sd" ) )
{ {
// sscanf( Line + 2, " %d %d %d %d %d %d", &Dummy, &m_featureLineDOx, &m_featureLineDOy, &m_featureLineDFx, &m_featureLineDFy, &Dummy );
int ignore = intParse( line + SZ( "Sd" ), &data ); int ignore = intParse( line + SZ( "Sd" ), &data );
BIU featureLineDOx = biuParse( data, &data ); BIU featureLineDOx = biuParse( data, &data );
BIU featureLineDOy = biuParse( data, &data ); BIU featureLineDOy = biuParse( data, &data );
@ -2905,8 +2811,6 @@ void LEGACY_PLUGIN::loadDIMENSION()
else if( TESTLINE( "Sg" ) ) else if( TESTLINE( "Sg" ) )
{ {
// sscanf( Line + 2, " %d %d %d %d %d %d", &Dummy, &m_featureLineGOx, &m_featureLineGOy, &m_featureLineGFx, &m_featureLineGFy, &Dummy );
int ignore = intParse( line + SZ( "Sg" ), &data ); int ignore = intParse( line + SZ( "Sg" ), &data );
BIU featureLineGOx = biuParse( data, &data ); BIU featureLineGOx = biuParse( data, &data );
BIU featureLineGOy = biuParse( data, &data ); BIU featureLineGOy = biuParse( data, &data );
@ -2922,8 +2826,6 @@ void LEGACY_PLUGIN::loadDIMENSION()
else if( TESTLINE( "S1" ) ) else if( TESTLINE( "S1" ) )
{ {
// sscanf( Line + 2, " %d %d %d %d %d %d", &Dummy, &m_arrowD1Ox, &m_arrowD1Oy, &m_arrowD1Fx, &m_arrowD1Fy, &Dummy );
int ignore = intParse( line + SZ( "S1" ), &data ); int ignore = intParse( line + SZ( "S1" ), &data );
biuParse( data, &data ); // skipping excessive data biuParse( data, &data ); // skipping excessive data
biuParse( data, &data ); // skipping excessive data biuParse( data, &data ); // skipping excessive data
@ -2937,8 +2839,6 @@ void LEGACY_PLUGIN::loadDIMENSION()
else if( TESTLINE( "S2" ) ) else if( TESTLINE( "S2" ) )
{ {
// sscanf( Line + 2, " %d %d %d %d %d %d", &Dummy, &m_arrowD2Ox, &m_arrowD2Oy, &m_arrowD2Fx, &m_arrowD2Fy, &Dummy );
int ignore = intParse( line + SZ( "S2" ), &data ); int ignore = intParse( line + SZ( "S2" ), &data );
biuParse( data, &data ); // skipping excessive data biuParse( data, &data ); // skipping excessive data
biuParse( data, &data ); // skipping excessive data biuParse( data, &data ); // skipping excessive data
@ -2952,7 +2852,6 @@ void LEGACY_PLUGIN::loadDIMENSION()
else if( TESTLINE( "S3" ) ) else if( TESTLINE( "S3" ) )
{ {
// sscanf( Line + 2, " %d %d %d %d %d %d\n", &Dummy, &m_arrowG1Ox, &m_arrowG1Oy, &m_arrowG1Fx, &m_arrowG1Fy, &Dummy );
int ignore = intParse( line + SZ( "S3" ), &data ); int ignore = intParse( line + SZ( "S3" ), &data );
biuParse( data, &data ); // skipping excessive data biuParse( data, &data ); // skipping excessive data
biuParse( data, &data ); // skipping excessive data biuParse( data, &data ); // skipping excessive data
@ -2966,7 +2865,6 @@ void LEGACY_PLUGIN::loadDIMENSION()
else if( TESTLINE( "S4" ) ) else if( TESTLINE( "S4" ) )
{ {
// sscanf( Line + 2, " %d %d %d %d %d %d", &Dummy, &m_arrowG2Ox, &m_arrowG2Oy, &m_arrowG2Fx, &m_arrowG2Fy, &Dummy );
int ignore = intParse( line + SZ( "S4" ), &data ); int ignore = intParse( line + SZ( "S4" ), &data );
biuParse( data, &data ); // skipping excessive data biuParse( data, &data ); // skipping excessive data
biuParse( data, &data ); // skipping excessive data biuParse( data, &data ); // skipping excessive data
@ -2998,17 +2896,13 @@ void LEGACY_PLUGIN::loadPCB_TARGET()
else if( TESTLINE( "Po" ) ) else if( TESTLINE( "Po" ) )
{ {
// sscanf( Line + 2, " %X %d %d %d %d %d %lX", &m_Shape, &m_Layer, &m_Pos.x, &m_Pos.y, &m_Size, &m_Width, &m_TimeStamp ); int shape = intParse( line + SZ( "Po" ), &data );
int shape = intParse( line + SZ( "Po" ), &data );
LAYER_NUM layer_num = layerParse( data, &data ); LAYER_NUM layer_num = layerParse( data, &data );
BIU pos_x = biuParse( data, &data );
BIU pos_x = biuParse( data, &data ); BIU pos_y = biuParse( data, &data );
BIU pos_y = biuParse( data, &data ); BIU size = biuParse( data, &data );
BIU size = biuParse( data, &data ); BIU width = biuParse( data, &data );
BIU width = biuParse( data, &data ); char* uuid = strtok_r( (char*) data, delims, (char**) &data );
timestamp_t timestamp = hexParse( data );
if( layer_num < FIRST_NON_COPPER_LAYER ) if( layer_num < FIRST_NON_COPPER_LAYER )
layer_num = FIRST_NON_COPPER_LAYER; layer_num = FIRST_NON_COPPER_LAYER;
@ -3017,10 +2911,10 @@ void LEGACY_PLUGIN::loadPCB_TARGET()
layer_num = LAST_NON_COPPER_LAYER; layer_num = LAST_NON_COPPER_LAYER;
PCB_TARGET* t = new PCB_TARGET( m_board, shape, leg_layer2new( m_cu_count, layer_num ), PCB_TARGET* t = new PCB_TARGET( m_board, shape, leg_layer2new( m_cu_count, layer_num ),
wxPoint( pos_x, pos_y ), size, width ); wxPoint( pos_x, pos_y ), size, width );
m_board->Add( t, ADD_MODE::APPEND ); m_board->Add( t, ADD_MODE::APPEND );
t->SetTimeStamp( timestamp ); const_cast<UUID&>( t->m_Uuid ) = UUID( uuid );
} }
} }
@ -3171,8 +3065,6 @@ void LEGACY_PLUGIN::SaveModule3D( const MODULE* me ) const
++sM; ++sM;
} }
return;
} }
@ -3282,7 +3174,7 @@ void LP_CACHE::Load()
void LP_CACHE::ReadAndVerifyHeader( LINE_READER* aReader ) void LP_CACHE::ReadAndVerifyHeader( LINE_READER* aReader )
{ {
char* line = aReader->ReadLine(); char* line = aReader->ReadLine();
char* saveptr; char* data;
if( !line ) if( !line )
THROW_IO_ERROR( wxString::Format( _( "File '%s' is empty." ), m_lib_path ) ); THROW_IO_ERROR( wxString::Format( _( "File '%s' is empty." ), m_lib_path ) );
@ -3294,7 +3186,7 @@ void LP_CACHE::ReadAndVerifyHeader( LINE_READER* aReader )
{ {
if( TESTLINE( "Units" ) ) if( TESTLINE( "Units" ) )
{ {
const char* units = strtok_r( line + SZ( "Units" ), delims, &saveptr ); const char* units = strtok_r( line + SZ( "Units" ), delims, &data );
if( !strcmp( units, "mm" ) ) if( !strcmp( units, "mm" ) )
m_owner->diskToBiu = IU_PER_MM; m_owner->diskToBiu = IU_PER_MM;
@ -3493,8 +3385,8 @@ MODULE* LEGACY_PLUGIN::FootprintLoad( const wxString& aLibraryPath,
return NULL; return NULL;
} }
// copy constructor to clone the already loaded MODULE // Return copy of already loaded MODULE
return new MODULE( *it->second ); return (MODULE*) it->second->Duplicate();
} }
@ -3542,11 +3434,11 @@ bool LEGACY_PLUGIN::IsFootprintLibWritable( const wxString& aLibraryPath )
LEGACY_PLUGIN::LEGACY_PLUGIN() : LEGACY_PLUGIN::LEGACY_PLUGIN() :
m_cu_count( 16 ), // for FootprintLoad() m_cu_count( 16 ), // for FootprintLoad()
m_board( 0 ), m_board( nullptr ),
m_props( 0 ), m_props( nullptr ),
m_reader( 0 ), m_reader( nullptr ),
m_fp( 0 ), m_fp( nullptr ),
m_cache( 0 ), m_cache( nullptr ),
m_mapping( new NETINFO_MAPPING() ) m_mapping( new NETINFO_MAPPING() )
{ {
init( NULL ); init( NULL );

View File

@ -106,9 +106,9 @@ bool FOOTPRINT_EDIT_FRAME::Load_Module_From_BOARD( MODULE* aModule )
if( !Clear_Pcb( true ) ) if( !Clear_Pcb( true ) )
return false; return false;
newModule = new MODULE( *aModule ); newModule = (MODULE*) aModule->Duplicate();
newModule->SetParent( GetBoard() ); newModule->SetParent( GetBoard() );
newModule->SetLink( aModule->GetTimeStamp() ); newModule->SetLink( aModule->m_Uuid );
newModule->ClearFlags(); newModule->ClearFlags();
newModule->RunOnChildren( std::bind( &clearModuleItemFlags, _1 ) ); newModule->RunOnChildren( std::bind( &clearModuleItemFlags, _1 ) );

View File

@ -178,7 +178,6 @@ MODULE* BOARD_NETLIST_UPDATER::addNewComponent( COMPONENT* aComponent )
{ {
footprint->SetParent( m_board ); footprint->SetParent( m_board );
footprint->SetPosition( estimateComponentInsertionPosition( ) ); footprint->SetPosition( estimateComponentInsertionPosition( ) );
footprint->SetTimeStamp( GetNewTimeStamp() );
m_addedComponents.push_back( footprint ); m_addedComponents.push_back( footprint );
m_commit.Add( footprint ); m_commit.Add( footprint );
@ -280,18 +279,18 @@ bool BOARD_NETLIST_UPDATER::updateComponentParameters( MODULE* aPcbComponent,
} }
// Test for time stamp change. // Test for time stamp change.
if( aPcbComponent->GetPath() != aNewComponent->GetTimeStamp() ) if( aPcbComponent->GetPath() != aNewComponent->GetPath() )
{ {
msg.Printf( _( "Change symbol path \"%s:%s\" to \"%s\"." ), msg.Printf( _( "Update %s symbol association from %s to %s." ),
aPcbComponent->GetReference(), aPcbComponent->GetReference(),
aPcbComponent->GetPath(), aPcbComponent->GetPath().AsString(),
aNewComponent->GetTimeStamp() ); aNewComponent->GetPath().AsString() );
m_reporter->Report( msg, REPORTER::RPT_INFO ); m_reporter->Report( msg, REPORTER::RPT_INFO );
if( !m_isDryRun ) if( !m_isDryRun )
{ {
changed = true; changed = true;
aPcbComponent->SetPath( aNewComponent->GetTimeStamp() ); aPcbComponent->SetPath( aNewComponent->GetPath() );
} }
} }
@ -590,7 +589,7 @@ bool BOARD_NETLIST_UPDATER::deleteUnusedComponents( NETLIST& aNetlist )
{ {
if( m_lookupByTimestamp ) if( m_lookupByTimestamp )
component = aNetlist.GetComponentByTimeStamp( module->GetPath() ); component = aNetlist.GetComponentByPath( module->GetPath() );
else else
component = aNetlist.GetComponentByReference( module->GetReference() ); component = aNetlist.GetComponentByReference( module->GetReference() );
@ -763,9 +762,8 @@ bool BOARD_NETLIST_UPDATER::UpdateNetlist( NETLIST& aNetlist )
int matchCount = 0; int matchCount = 0;
MODULE* tmp; MODULE* tmp;
msg.Printf( _( "Processing component \"%s:%s:%s\"." ), msg.Printf( _( "Processing component \"%s:%s\"." ),
component->GetReference(), component->GetReference(),
component->GetTimeStamp(),
component->GetFPID().Format().wx_str() ); component->GetFPID().Format().wx_str() );
m_reporter->Report( msg, REPORTER::RPT_INFO ); m_reporter->Report( msg, REPORTER::RPT_INFO );
@ -776,7 +774,7 @@ bool BOARD_NETLIST_UPDATER::UpdateNetlist( NETLIST& aNetlist )
if( footprint ) if( footprint )
{ {
if( m_lookupByTimestamp ) if( m_lookupByTimestamp )
match = footprint->GetPath() == component->GetTimeStamp(); match = footprint->GetPath() == component->GetPath();
else else
match = footprint->GetReference().CmpNoCase( component->GetReference() ) == 0; match = footprint->GetReference().CmpNoCase( component->GetReference() ) == 0;
} }

View File

@ -5,7 +5,7 @@
* 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) 1992-2011 Jean-Pierre Charras. * Copyright (C) 1992-2011 Jean-Pierre Charras.
* Copyright (C) 1992-2016 KiCad Developers, see change_log.txt for contributors. * Copyright (C) 1992-2020 KiCad Developers, see change_log.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
@ -282,23 +282,24 @@ void KICAD_NETLIST_PARSER::parseComponent()
{ {
/* Parses a section like /* Parses a section like
* (comp (ref P1) * (comp (ref P1)
* (value DB25FEMELLE) * (value DB25FEMALE)
* (footprint DB25FC) * (footprint DB25FC)
* (libsource (lib conn) (part DB25)) * (libsource (lib conn) (part DB25))
* (sheetpath (names /) (tstamps /)) * (sheetpath (names /) (tstamps /))
* (tstamp 3256759C)) * (tstamp 68183921-93a5-49ac-91b0-49d05a0e1647))
* *
* other fields (unused) are skipped * other fields (unused) are skipped
* A component need a reference, value, footprint name and a full time stamp * A component need a reference, value, footprint name and a full time stamp
* The full time stamp is the sheetpath time stamp + the component time stamp * The full time stamp is the sheetpath time stamp + the component time stamp
*/ */
LIB_ID fpid; LIB_ID fpid;
wxString footprint; wxString footprint;
wxString ref; wxString ref;
wxString value; wxString value;
wxString library; wxString library;
wxString name; wxString name;
wxString pathtimestamp, timestamp; UUID_PATH path;
UUID uuid;
// The token comp was read, so the next data is (ref P1) // The token comp was read, so the next data is (ref P1)
while( (token = NextTok()) != T_RIGHT ) while( (token = NextTok()) != T_RIGHT )
@ -365,14 +366,14 @@ void KICAD_NETLIST_PARSER::parseComponent()
} }
NeedSYMBOLorNUMBER(); NeedSYMBOLorNUMBER();
pathtimestamp = FROM_UTF8( CurText() ); path = UUID_PATH( FROM_UTF8( CurText() ) );
NeedRIGHT(); NeedRIGHT();
NeedRIGHT(); NeedRIGHT();
break; break;
case T_tstamp: case T_tstamp:
NeedSYMBOLorNUMBER(); NeedSYMBOLorNUMBER();
timestamp = FROM_UTF8( CurText() ); uuid = UUID( FROM_UTF8( CurText() ) );
NeedRIGHT(); NeedRIGHT();
break; break;
@ -392,8 +393,8 @@ void KICAD_NETLIST_PARSER::parseComponent()
THROW_IO_ERROR( error ); THROW_IO_ERROR( error );
} }
pathtimestamp += timestamp; path.push_back( uuid );
COMPONENT* component = new COMPONENT( fpid, ref, value, pathtimestamp ); COMPONENT* component = new COMPONENT( fpid, ref, value, path );
component->SetName( name ); component->SetName( name );
component->SetLibrary( library ); component->SetLibrary( library );
m_netlist->AddComponent( component ); m_netlist->AddComponent( component );

View File

@ -100,7 +100,6 @@ COMPONENT* LEGACY_NETLIST_READER::loadComponent( char* aText )
{ {
char* text; char* text;
wxString msg; wxString msg;
wxString timeStamp; // the full time stamp read from netlist
wxString footprintName; // the footprint name read from netlist wxString footprintName; // the footprint name read from netlist
wxString value; // the component value read from netlist wxString value; // the component value read from netlist
wxString reference; // the component schematic reference designator read from netlist wxString reference; // the component schematic reference designator read from netlist
@ -112,7 +111,7 @@ COMPONENT* LEGACY_NETLIST_READER::loadComponent( char* aText )
value = wxT( "~" ); value = wxT( "~" );
// Sample component line: /40C08647 $noname R20 4.7K {Lib=R} // Sample component line: /68183921-93a5-49ac-91b0-49d05a0e1647 $noname R20 4.7K {Lib=R}
// Read time stamp (first word) // Read time stamp (first word)
if( ( text = strtok( line, " ()\t\n" ) ) == NULL ) if( ( text = strtok( line, " ()\t\n" ) ) == NULL )
@ -122,7 +121,7 @@ COMPONENT* LEGACY_NETLIST_READER::loadComponent( char* aText )
m_lineReader->Length() ); m_lineReader->Length() );
} }
timeStamp = FROM_UTF8( text ); UUID_PATH path( FROM_UTF8( text ) );
// Read footprint name (second word) // Read footprint name (second word)
if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL ) if( ( text = strtok( NULL, " ()\t\n" ) ) == NULL )
@ -170,7 +169,7 @@ COMPONENT* LEGACY_NETLIST_READER::loadComponent( char* aText )
if( !footprintName.IsEmpty() ) if( !footprintName.IsEmpty() )
fpid.SetLibItemName( footprintName ); fpid.SetLibItemName( footprintName );
COMPONENT* component = new COMPONENT( fpid, reference, value, timeStamp ); COMPONENT* component = new COMPONENT( fpid, reference, value, path );
component->SetName( name ); component->SetName( name );
m_netlist->AddComponent( component ); m_netlist->AddComponent( component );
return component; return component;

View File

@ -140,7 +140,7 @@ void PCB_EDIT_FRAME::LoadFootprints( NETLIST& aNetlist, REPORTER& aReporter )
wxString msg; wxString msg;
LIB_ID lastFPID; LIB_ID lastFPID;
COMPONENT* component; COMPONENT* component;
MODULE* module = 0; MODULE* module = nullptr;
MODULE* fpOnBoard; MODULE* fpOnBoard;
if( aNetlist.IsEmpty() || Prj().PcbFootprintLibs()->IsEmpty() ) if( aNetlist.IsEmpty() || Prj().PcbFootprintLibs()->IsEmpty() )
@ -153,8 +153,7 @@ void PCB_EDIT_FRAME::LoadFootprints( NETLIST& aNetlist, REPORTER& aReporter )
component = aNetlist.GetComponent( ii ); component = aNetlist.GetComponent( ii );
#if ALLOW_PARTIAL_FPID #if ALLOW_PARTIAL_FPID
// The FPID is ok as long as there is a footprint portion coming // The FPID is ok as long as there is a footprint portion coming from eeschema.
// from eeschema.
if( !component->GetFPID().GetLibItemName().size() ) if( !component->GetFPID().GetLibItemName().size() )
#else #else
if( component->GetFPID().empty() ) if( component->GetFPID().empty() )
@ -170,9 +169,9 @@ void PCB_EDIT_FRAME::LoadFootprints( NETLIST& aNetlist, REPORTER& aReporter )
// Check if component footprint is already on BOARD and only load the footprint from // Check if component footprint is already on BOARD and only load the footprint from
// the library if it's needed. Nickname can be blank. // the library if it's needed. Nickname can be blank.
if( aNetlist.IsFindByTimeStamp() ) if( aNetlist.IsFindByTimeStamp() )
fpOnBoard = m_Pcb->FindModule( aNetlist.GetComponent( ii )->GetTimeStamp(), true ); fpOnBoard = m_Pcb->FindModuleByPath( aNetlist.GetComponent( ii )->GetPath() );
else else
fpOnBoard = m_Pcb->FindModule( aNetlist.GetComponent( ii )->GetReference() ); fpOnBoard = m_Pcb->FindModuleByReference( aNetlist.GetComponent( ii )->GetReference() );
bool footprintMisMatch = fpOnBoard && fpOnBoard->GetFPID() != component->GetFPID(); bool footprintMisMatch = fpOnBoard && fpOnBoard->GetFPID() != component->GetFPID();

View File

@ -54,7 +54,7 @@ void COMPONENT::SetModule( MODULE* aModule )
aModule->SetReference( m_reference ); aModule->SetReference( m_reference );
aModule->SetValue( m_value ); aModule->SetValue( m_value );
aModule->SetFPID( m_fpid ); aModule->SetFPID( m_fpid );
aModule->SetPath( m_timeStamp ); aModule->SetPath( m_path );
} }
@ -85,7 +85,13 @@ void COMPONENT::Format( OUTPUTFORMATTER* aOut, int aNestLevel, int aCtl )
aOut->Print( nl+1, "(value %s)\n", aOut->Quotew( m_value ).c_str() ); aOut->Print( nl+1, "(value %s)\n", aOut->Quotew( m_value ).c_str() );
aOut->Print( nl+1, "(name %s)\n", aOut->Quotew( m_name ).c_str() ); aOut->Print( nl+1, "(name %s)\n", aOut->Quotew( m_name ).c_str() );
aOut->Print( nl+1, "(library %s)\n", aOut->Quotew( m_library ).c_str() ); aOut->Print( nl+1, "(library %s)\n", aOut->Quotew( m_library ).c_str() );
aOut->Print( nl+1, "(timestamp %s)\n", aOut->Quotew( m_timeStamp ).c_str() );
wxString path;
for( const UUID& pathStep : m_path )
path += '/' + pathStep.AsString();
aOut->Print( nl+1, "(timestamp %s)\n", aOut->Quotew( path ).c_str() );
} }
if( !( aCtl & CTL_OMIT_FILTERS ) && m_footprintFilters.GetCount() ) if( !( aCtl & CTL_OMIT_FILTERS ) && m_footprintFilters.GetCount() )
@ -158,20 +164,15 @@ COMPONENT* NETLIST::GetComponentByReference( const wxString& aReference )
} }
COMPONENT* NETLIST::GetComponentByTimeStamp( const wxString& aTimeStamp ) COMPONENT* NETLIST::GetComponentByPath( const UUID_PATH& aUuidPath )
{ {
COMPONENT* component = NULL; for( COMPONENT& component : m_components )
for( unsigned i = 0; i < m_components.size(); i++ )
{ {
if( m_components[i].GetTimeStamp() == aTimeStamp ) if( component.GetPath() == aUuidPath )
{ return &component;
component = &m_components[i];
break;
}
} }
return component; return nullptr;
} }

View File

@ -3,7 +3,7 @@
* *
* Copyright (C) 2012 Jean-Pierre Charras. * Copyright (C) 2012 Jean-Pierre Charras.
* Copyright (C) 2013-2016 Wayne Stambaugh <stambaughw@verizon.net>. * Copyright (C) 2013-2016 Wayne Stambaugh <stambaughw@verizon.net>.
* Copyright (C) 2012-2017 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2012-2020 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
@ -26,12 +26,9 @@
#ifndef PCB_NETLIST_H #ifndef PCB_NETLIST_H
#define PCB_NETLIST_H #define PCB_NETLIST_H
/** #pragma GCC diagnostic ignored "-Wdeprecated-declarations" // For boost...
* @file pcb_netlist.h
*/
#include <boost/ptr_container/ptr_vector.hpp> #include <boost/ptr_container/ptr_vector.hpp>
#include <wx/arrstr.h> #include <wx/arrstr.h>
#include <lib_id.h> #include <lib_id.h>
@ -90,8 +87,8 @@ class COMPONENT
wxString m_reference; ///< The component reference designator found in netlist. wxString m_reference; ///< The component reference designator found in netlist.
wxString m_value; ///< The component value found in netlist. wxString m_value; ///< The component value found in netlist.
// ZZZ This timestamp is string, not time_t /// A fully specified path to the component: [ sheetUUID, sheetUUID, .., componentUUID ]
wxString m_timeStamp; ///< The component full time stamp found in netlist. UUID_PATH m_path;
/// The name of the component in #m_library used when it was placed on the schematic.. /// The name of the component in #m_library used when it was placed on the schematic..
wxString m_name; wxString m_name;
@ -117,16 +114,16 @@ class COMPONENT
static COMPONENT_NET m_emptyNet; static COMPONENT_NET m_emptyNet;
public: public:
COMPONENT( const LIB_ID& aFPID, COMPONENT( const LIB_ID& aFPID,
const wxString& aReference, const wxString& aReference,
const wxString& aValue, const wxString& aValue,
const wxString& aTimeStamp ) const UUID_PATH& aPath )
{ {
m_fpid = aFPID; m_fpid = aFPID;
m_reference = aReference; m_reference = aReference;
m_value = aValue; m_value = aValue;
m_pinCount = 0; m_pinCount = 0;
m_timeStamp = aTimeStamp; m_path = aPath;
m_footprintChanged = false; m_footprintChanged = false;
} }
@ -170,7 +167,7 @@ public:
const LIB_ID& GetAltFPID() const { return m_altFpid; } const LIB_ID& GetAltFPID() const { return m_altFpid; }
const wxString& GetTimeStamp() const { return m_timeStamp; } const UUID_PATH& GetPath() const { return m_path; }
void SetFootprintFilters( const wxArrayString& aFilterList ) void SetFootprintFilters( const wxArrayString& aFilterList )
{ {
@ -288,13 +285,13 @@ public:
COMPONENT* GetComponentByReference( const wxString& aReference ); COMPONENT* GetComponentByReference( const wxString& aReference );
/** /**
* Function GetComponentByTimeStamp * Function GetComponentByPath
* returns a #COMPONENT by \a aTimeStamp. * returns a #COMPONENT by \a aPath.
* *
* @param aTimeStamp is the time stamp the #COMPONENT. * @param aPath is the UUID_PATH [ sheetUUID, .., compUUID ] of the #COMPONENT.
* @return a pointer to the #COMPONENT that matches \a aTimeStamp if found. Otherwise NULL. * @return a pointer to the #COMPONENT that matches \a aPath if found. Otherwise NULL.
*/ */
COMPONENT* GetComponentByTimeStamp( const wxString& aTimeStamp ); COMPONENT* GetComponentByPath( const UUID_PATH& aPath );
void SortByFPID(); void SortByFPID();

View File

@ -90,7 +90,6 @@ PCB::PCB( BOARD* aBoard ) : PCB_MODULE( this, aBoard )
m_layersMap[3].KiCadLayer = Eco2_User; m_layersMap[3].KiCadLayer = Eco2_User;
m_layersMap[6].KiCadLayer = F_SilkS; m_layersMap[6].KiCadLayer = F_SilkS;
m_layersMap[7].KiCadLayer = B_SilkS; m_layersMap[7].KiCadLayer = B_SilkS;
m_timestamp_cnt = 0x10000000;
} }
@ -110,11 +109,6 @@ PCB::~PCB()
} }
int PCB::GetNewTimestamp()
{
return m_timestamp_cnt++;
}
int PCB::GetNetCode( wxString aNetName ) int PCB::GetNetCode( wxString aNetName )
{ {
PCB_NET* net; PCB_NET* net;

View File

@ -56,7 +56,6 @@ public:
PCB_LAYER_ID GetKiCadLayer( int aPCadLayer ) override; PCB_LAYER_ID GetKiCadLayer( int aPCadLayer ) override;
LAYER_TYPE_T GetLayerType( int aPCadLayer ) override; LAYER_TYPE_T GetLayerType( int aPCadLayer ) override;
wxString GetLayerNetNameRef( int aPCadLayer ) override; wxString GetLayerNetNameRef( int aPCadLayer ) override;
int GetNewTimestamp() override;
int GetNetCode( wxString aNetName ) override; int GetNetCode( wxString aNetName ) override;
void ParseBoard( wxStatusBar* aStatusBar, void ParseBoard( wxStatusBar* aStatusBar,
@ -66,7 +65,6 @@ public:
void AddToBoard() override; void AddToBoard() override;
private: private:
int m_timestamp_cnt;
wxArrayString m_layersStackup; wxArrayString m_layersStackup;
XNODE* FindCompDefName( XNODE* aNode, const wxString& aName ); XNODE* FindCompDefName( XNODE* aNode, const wxString& aName );

View File

@ -3,7 +3,7 @@
* *
* Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk> * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
* Copyright (C) 2007, 2008, 2012-2013 Alexander Lunev <al.lunev@yahoo.com> * Copyright (C) 2007, 2008, 2012-2013 Alexander Lunev <al.lunev@yahoo.com>
* Copyright (C) 2012 KiCad Developers, see CHANGELOG.TXT for contributors. * Copyright (C) 2012-2020 KiCad Developers, see CHANGELOG.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
@ -182,7 +182,6 @@ void PCB_ARC::AddToBoard()
m_board->Add( dseg, ADD_MODE::APPEND ); m_board->Add( dseg, ADD_MODE::APPEND );
dseg->SetShape( IsCircle() ? S_CIRCLE : S_ARC ); dseg->SetShape( IsCircle() ? S_CIRCLE : S_ARC );
dseg->SetTimeStamp( m_timestamp );
dseg->SetLayer( m_KiCadLayer ); dseg->SetLayer( m_KiCadLayer );
dseg->SetStart( wxPoint( m_positionX, m_positionY ) ); dseg->SetStart( wxPoint( m_positionX, m_positionY ) );
dseg->SetEnd( wxPoint( m_startX, m_startY ) ); dseg->SetEnd( wxPoint( m_startX, m_startY ) );

View File

@ -42,7 +42,7 @@ enum LAYER_TYPE_T
typedef struct _TLAYER typedef struct _TLAYER
{ {
PCB_LAYER_ID KiCadLayer; PCB_LAYER_ID KiCadLayer;
LAYER_TYPE_T layerType; LAYER_TYPE_T layerType;
wxString netNameRef; wxString netNameRef;
} TLAYER; } TLAYER;
@ -60,7 +60,6 @@ namespace PCAD2KICAD
virtual PCB_LAYER_ID GetKiCadLayer( int aPCadLayer ) = 0; virtual PCB_LAYER_ID GetKiCadLayer( int aPCadLayer ) = 0;
virtual LAYER_TYPE_T GetLayerType( int aPCadLayer ) = 0; virtual LAYER_TYPE_T GetLayerType( int aPCadLayer ) = 0;
virtual wxString GetLayerNetNameRef( int aPCadLayer ) = 0; virtual wxString GetLayerNetNameRef( int aPCadLayer ) = 0;
virtual int GetNewTimestamp() = 0;
virtual int GetNetCode( wxString netName ) = 0; virtual int GetNetCode( wxString netName ) = 0;
}; };
} }

View File

@ -36,21 +36,22 @@
namespace PCAD2KICAD { namespace PCAD2KICAD {
PCB_COMPONENT::PCB_COMPONENT( PCB_CALLBACKS* aCallbacks, PCB_COMPONENT::PCB_COMPONENT( PCB_CALLBACKS* aCallbacks,
BOARD* aBoard ) : m_callbacks( aCallbacks ), BOARD* aBoard ) :
m_board( aBoard ) m_uuid(),
m_callbacks( aCallbacks ),
m_board( aBoard )
{ {
m_tag = 0; m_tag = 0;
m_objType = wxT( '?' ); m_objType = wxT( '?' );
m_PCadLayer = 0; m_PCadLayer = 0;
m_KiCadLayer = F_Cu; // It *has* to be somewhere... m_KiCadLayer = F_Cu; // It *has* to be somewhere...
m_timestamp = 0; m_positionX = 0;
m_positionX = 0; m_positionY = 0;
m_positionY = 0; m_rotation = 0;
m_rotation = 0;
InitTTextValue( &m_name ); InitTTextValue( &m_name );
m_net = wxEmptyString; m_net = wxEmptyString;
m_netCode = 0; m_netCode = 0;
m_compRef = wxEmptyString; m_compRef = wxEmptyString;
m_patGraphRefName = wxEmptyString; m_patGraphRefName = wxEmptyString;
} }

View File

@ -48,19 +48,19 @@ namespace PCAD2KICAD {
class PCB_COMPONENT : public wxObject class PCB_COMPONENT : public wxObject
{ {
public: public:
int m_tag; int m_tag;
char m_objType; char m_objType;
int m_PCadLayer; int m_PCadLayer;
PCB_LAYER_ID m_KiCadLayer; PCB_LAYER_ID m_KiCadLayer;
int m_timestamp; UUID m_uuid;
int m_positionX; int m_positionX;
int m_positionY; int m_positionY;
int m_rotation; int m_rotation;
TTEXTVALUE m_name; // name has also private positions, rotations and so on.... TTEXTVALUE m_name; // name has also private positions, rotations and so on....
wxString m_net; wxString m_net;
int m_netCode; int m_netCode;
wxString m_compRef; // internal usage for XL parsing wxString m_compRef; // internal usage for XL parsing
wxString m_patGraphRefName; // internal usage for XL parsing wxString m_patGraphRefName; // internal usage for XL parsing
PCB_COMPONENT( PCB_CALLBACKS* aCallbacks, BOARD* aBoard ); PCB_COMPONENT( PCB_CALLBACKS* aCallbacks, BOARD* aBoard );
~PCB_COMPONENT(); ~PCB_COMPONENT();
@ -71,7 +71,6 @@ public:
virtual void AddToBoard() = 0; virtual void AddToBoard() = 0;
PCB_LAYER_ID GetKiCadLayer() { return m_callbacks->GetKiCadLayer( m_PCadLayer ); } PCB_LAYER_ID GetKiCadLayer() { return m_callbacks->GetKiCadLayer( m_PCadLayer ); }
int GetNewTimestamp() { return m_callbacks->GetNewTimestamp(); }
int GetNetCode( wxString aNetName ) { return m_callbacks->GetNetCode( aNetName ); } int GetNetCode( wxString aNetName ) { return m_callbacks->GetNetCode( aNetName ); }
protected: protected:

View File

@ -139,8 +139,6 @@ void PCB_LINE::AddToBoard()
TRACK* track = new TRACK( m_board ); TRACK* track = new TRACK( m_board );
m_board->Add( track ); m_board->Add( track );
track->SetTimeStamp( m_timestamp );
track->SetPosition( wxPoint( m_positionX, m_positionY ) ); track->SetPosition( wxPoint( m_positionX, m_positionY ) );
track->SetEnd( wxPoint( m_toX, m_toY ) ); track->SetEnd( wxPoint( m_toX, m_toY ) );
@ -154,7 +152,6 @@ void PCB_LINE::AddToBoard()
DRAWSEGMENT* dseg = new DRAWSEGMENT( m_board ); DRAWSEGMENT* dseg = new DRAWSEGMENT( m_board );
m_board->Add( dseg, ADD_MODE::APPEND ); m_board->Add( dseg, ADD_MODE::APPEND );
dseg->SetTimeStamp( m_timestamp );
dseg->SetLayer( m_KiCadLayer ); dseg->SetLayer( m_KiCadLayer );
dseg->SetStart( wxPoint( m_positionX, m_positionY ) ); dseg->SetStart( wxPoint( m_positionX, m_positionY ) );
dseg->SetEnd( wxPoint( m_toX, m_toY ) ); dseg->SetEnd( wxPoint( m_toX, m_toY ) );

View File

@ -3,7 +3,7 @@
* *
* Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk> * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
* Copyright (C) 2007, 2008, 2012-2013 Alexander Lunev <al.lunev@yahoo.com> * Copyright (C) 2007, 2008, 2012-2013 Alexander Lunev <al.lunev@yahoo.com>
* Copyright (C) 2012-2016 KiCad Developers, see CHANGELOG.TXT for contributors. * Copyright (C) 2012-2020 KiCad Developers, see CHANGELOG.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
@ -516,7 +516,6 @@ void PCB_MODULE::AddToBoard()
module->SetPosition( wxPoint( m_positionX, m_positionY ) ); module->SetPosition( wxPoint( m_positionX, m_positionY ) );
module->SetLayer( m_mirror ? B_Cu : F_Cu ); module->SetLayer( m_mirror ? B_Cu : F_Cu );
module->SetOrientation( m_rotation ); module->SetOrientation( m_rotation );
module->SetTimeStamp( 0 );
module->SetLastEditTime( 0 ); module->SetLastEditTime( 0 );
LIB_ID fpID; LIB_ID fpID;

View File

@ -342,8 +342,6 @@ void PCB_PAD::AddToBoard()
VIA* via = new VIA( m_board ); VIA* via = new VIA( m_board );
m_board->Add( via ); m_board->Add( via );
via->SetTimeStamp( 0 );
via->SetPosition( wxPoint( m_positionX, m_positionY ) ); via->SetPosition( wxPoint( m_positionX, m_positionY ) );
via->SetEnd( wxPoint( m_positionX, m_positionY ) ); via->SetEnd( wxPoint( m_positionX, m_positionY ) );

View File

@ -3,7 +3,7 @@
* *
* Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk> * Copyright (C) 2007, 2008 Lubo Racko <developer@lura.sk>
* Copyright (C) 2007, 2008, 2012-2013 Alexander Lunev <al.lunev@yahoo.com> * Copyright (C) 2007, 2008, 2012-2013 Alexander Lunev <al.lunev@yahoo.com>
* Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2017-2020 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
@ -44,7 +44,6 @@ PCB_POLYGON::PCB_POLYGON( PCB_CALLBACKS* aCallbacks, BOARD* aBoard, int aPCadLay
m_objType = wxT( 'Z' ); m_objType = wxT( 'Z' );
m_PCadLayer = aPCadLayer; m_PCadLayer = aPCadLayer;
m_KiCadLayer = GetKiCadLayer(); m_KiCadLayer = GetKiCadLayer();
m_timestamp = GetNewTimestamp();
m_filled = true; m_filled = true;
} }
@ -189,7 +188,6 @@ void PCB_POLYGON::AddToBoard()
ZONE_CONTAINER* zone = new ZONE_CONTAINER( m_board ); ZONE_CONTAINER* zone = new ZONE_CONTAINER( m_board );
m_board->Add( zone, ADD_MODE::APPEND ); m_board->Add( zone, ADD_MODE::APPEND );
zone->SetTimeStamp( m_timestamp );
zone->SetLayer( m_KiCadLayer ); zone->SetLayer( m_KiCadLayer );
zone->SetNetCode( m_netCode ); zone->SetNetCode( m_netCode );

View File

@ -123,7 +123,6 @@ void PCB_TEXT::AddToBoard()
m_name.textPositionY ) ); m_name.textPositionY ) );
pcbtxt->SetMirrored( m_name.mirror ); pcbtxt->SetMirrored( m_name.mirror );
pcbtxt->SetTimeStamp( 0 );
pcbtxt->SetLayer( m_KiCadLayer ); pcbtxt->SetLayer( m_KiCadLayer );
} }

View File

@ -4,7 +4,7 @@
* Copyright (C) 2018 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr * Copyright (C) 2018 Jean-Pierre Charras, jean-pierre.charras@ujf-grenoble.fr
* Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com> * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.com>
* Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net> * Copyright (C) 2011 Wayne Stambaugh <stambaughw@verizon.net>
* Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 1992-2020 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
@ -171,11 +171,8 @@ void PCB_BASE_FRAME::AddModuleToBoard( MODULE* module )
GetBoard()->Add( module, ADD_MODE::APPEND ); GetBoard()->Add( module, ADD_MODE::APPEND );
module->SetFlags( IS_NEW ); module->SetFlags( IS_NEW );
module->SetPosition( wxPoint( 0, 0 ) ); // cursor in GAL may not be initialized yet module->SetPosition( wxPoint( 0, 0 ) ); // cursor in GAL may not be initialized yet
module->SetTimeStamp( GetNewTimeStamp() );
// Put it on FRONT layer (note that it might be stored flipped if the lib is an archive // Put it on FRONT layer (note that it might be stored flipped if the lib is an archive
// built from a board) // built from a board)
if( module->IsFlipped() ) if( module->IsFlipped() )

View File

@ -2,7 +2,7 @@
* 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) 2012 CERN * Copyright (C) 2012 CERN
* Copyright (C) 2012-2019 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2012-2020 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
@ -2035,7 +2035,8 @@ DRAWSEGMENT* PCB_PARSER::parseDRAWSEGMENT( bool aAllowCirclesZeroWidth )
break; break;
case T_tstamp: case T_tstamp:
segment->SetTimeStamp( parseHex() ); NextTok();
const_cast<UUID&>( segment->m_Uuid ) = UUID( CurStr() );
break; break;
case T_status: case T_status:
@ -2112,7 +2113,8 @@ TEXTE_PCB* PCB_PARSER::parseTEXTE_PCB()
break; break;
case T_tstamp: case T_tstamp:
text->SetTimeStamp( parseHex() ); NextTok();
const_cast<UUID&>( text->m_Uuid ) = UUID( CurStr() );
NeedRIGHT(); NeedRIGHT();
break; break;
@ -2163,19 +2165,20 @@ DIMENSION* PCB_PARSER::parseDIMENSION()
break; break;
case T_tstamp: case T_tstamp:
dimension->SetTimeStamp( parseHex() ); NextTok();
const_cast<UUID&>( dimension->m_Uuid ) = UUID( CurStr() );
NeedRIGHT(); NeedRIGHT();
break; break;
case T_gr_text: case T_gr_text:
{ {
TEXTE_PCB* text = parseTEXTE_PCB(); TEXTE_PCB* text = parseTEXTE_PCB();
// This copy (using the copy constructor) rebuild the text timestamp,
// that is not what we want.
dimension->Text() = *text; dimension->Text() = *text;
// reinitialises the text time stamp to the right value (the dimension time stamp)
dimension->Text().SetTimeStamp( dimension->GetTimeStamp() ); // The text is part of the dimension and shares its uuid
const_cast<UUID&>( dimension->Text().m_Uuid ) = dimension->m_Uuid;
// Fetch other dimension properties out of the text item
dimension->SetPosition( text->GetTextPos() ); dimension->SetPosition( text->GetTextPos() );
EDA_UNITS units = EDA_UNITS::INCHES; EDA_UNITS units = EDA_UNITS::INCHES;
@ -2381,7 +2384,8 @@ MODULE* PCB_PARSER::parseMODULE_unchecked( wxArrayString* aInitialComments )
break; break;
case T_tstamp: case T_tstamp:
module->SetTimeStamp( parseHex() ); NextTok();
const_cast<UUID&>( module->m_Uuid ) = UUID( CurStr() );
NeedRIGHT(); NeedRIGHT();
break; break;
@ -2417,7 +2421,7 @@ MODULE* PCB_PARSER::parseMODULE_unchecked( wxArrayString* aInitialComments )
case T_path: case T_path:
NeedSYMBOLorNUMBER(); // Paths can be numerical so a number is also a symbol here NeedSYMBOLorNUMBER(); // Paths can be numerical so a number is also a symbol here
module->SetPath( FromUTF8() ); module->SetPath( UUID_PATH( FromUTF8() ) );
NeedRIGHT(); NeedRIGHT();
break; break;
@ -2810,7 +2814,8 @@ EDGE_MODULE* PCB_PARSER::parseEDGE_MODULE()
break; break;
case T_tstamp: case T_tstamp:
segment->SetTimeStamp( parseHex() ); NextTok();
const_cast<UUID&>( segment->m_Uuid ) = UUID( CurStr() );
break; break;
case T_status: case T_status:
@ -3392,7 +3397,8 @@ TRACK* PCB_PARSER::parseTRACK()
break; break;
case T_tstamp: case T_tstamp:
track->SetTimeStamp( parseHex() ); NextTok();
const_cast<UUID&>( track->m_Uuid ) = UUID( CurStr() );
break; break;
case T_status: case T_status:
@ -3475,7 +3481,8 @@ VIA* PCB_PARSER::parseVIA()
break; break;
case T_tstamp: case T_tstamp:
via->SetTimeStamp( parseHex() ); NextTok();
const_cast<UUID&>( via->m_Uuid ) = UUID( CurStr() );
NeedRIGHT(); NeedRIGHT();
break; break;
@ -3562,7 +3569,8 @@ ZONE_CONTAINER* PCB_PARSER::parseZONE_CONTAINER( BOARD_ITEM_CONTAINER* aParent )
break; break;
case T_tstamp: case T_tstamp:
zone->SetTimeStamp( parseHex() ); NextTok();
const_cast<UUID&>( zone->m_Uuid ) = UUID( CurStr() );
NeedRIGHT(); NeedRIGHT();
break; break;
@ -3990,7 +3998,8 @@ PCB_TARGET* PCB_PARSER::parsePCB_TARGET()
break; break;
case T_tstamp: case T_tstamp:
target->SetTimeStamp( parseHex() ); NextTok();
const_cast<UUID&>( target->m_Uuid ) = UUID( CurStr() );
NeedRIGHT(); NeedRIGHT();
break; break;

View File

@ -325,11 +325,6 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard )
if( !session ) if( !session )
THROW_IO_ERROR( _("Session file is missing the \"session\" section") ); THROW_IO_ERROR( _("Session file is missing the \"session\" section") );
/* Dick 16-Jan-2012: session need not have a placement section.
if( !session->placement )
THROW_IO_ERROR( _("Session file is missing the \"placement\" section") );
*/
if( !session->route ) if( !session->route )
THROW_IO_ERROR( _("Session file is missing the \"routes\" section") ); THROW_IO_ERROR( _("Session file is missing the \"routes\" section") );
@ -358,10 +353,11 @@ void SPECCTRA_DB::FromSESSION( BOARD* aBoard )
wxString reference = FROM_UTF8( place->component_id.c_str() ); wxString reference = FROM_UTF8( place->component_id.c_str() );
MODULE* module = aBoard->FindModuleByReference( reference ); MODULE* module = aBoard->FindModuleByReference( reference );
if( !module ) if( !module )
{ {
THROW_IO_ERROR( wxString::Format( _("Session file has 'reference' to non-existent symbol \"%s\""), THROW_IO_ERROR( wxString::Format( _( "Reference '%s' not found." ),
GetChars( reference ) ) ); reference ) );
} }
if( !place->hasVertex ) if( !place->hasVertex )

View File

@ -4,7 +4,7 @@
* Copyright (C) 2013-2017 CERN * Copyright (C) 2013-2017 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch> * @author Maciej Suminski <maciej.suminski@cern.ch>
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* Copyright (C) 2017-2019 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2017-2020 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
@ -1079,18 +1079,35 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent )
if( m_editModules ) if( m_editModules )
{ {
dupe_item = editFrame->GetBoard()->GetFirstModule()->Duplicate( orig_item, increment ); MODULE* editModule = editFrame->GetBoard()->GetFirstModule();
dupe_item = editModule->DuplicateItem( orig_item, increment );
} }
else if( orig_item->GetParent() && orig_item->GetParent()->Type() == PCB_MODULE_T ) else if( orig_item->GetParent() && orig_item->GetParent()->Type() == PCB_MODULE_T )
{ {
MODULE* parent = static_cast<MODULE*>( orig_item->GetParent() ); MODULE* parent = static_cast<MODULE*>( orig_item->GetParent() );
m_commit->Modify( parent ); m_commit->Modify( parent );
dupe_item = parent->Duplicate( orig_item, false, true /* add to parent */ ); dupe_item = parent->DuplicateItem( orig_item, false, true /* add to parent */ );
} }
else else
{ {
dupe_item = editFrame->GetBoard()->Duplicate( orig_item ); switch( orig_item->Type() )
{
case PCB_MODULE_T:
case PCB_TEXT_T:
case PCB_LINE_T:
case PCB_TRACE_T:
case PCB_VIA_T:
case PCB_ZONE_AREA_T:
case PCB_TARGET_T:
case PCB_DIMENSION_T:
dupe_item = orig_item->Duplicate();
break;
default:
// Silently drop other items (such as footprint texts) from duplication
break;
}
} }
if( dupe_item ) if( dupe_item )
@ -1341,12 +1358,6 @@ int EDIT_TOOL::EditFpInFpEditor( const TOOL_EVENT& aEvent )
PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>(); PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();
if( mod->GetTimeStamp() == 0 ) // Module Editor needs a non null timestamp
{
mod->SetTimeStamp( GetNewTimeStamp() );
editFrame->OnModify();
}
auto editor = (FOOTPRINT_EDIT_FRAME*) editFrame->Kiway().Player( FRAME_FOOTPRINT_EDITOR, true ); auto editor = (FOOTPRINT_EDIT_FRAME*) editFrame->Kiway().Player( FRAME_FOOTPRINT_EDITOR, true );
editor->Load_Module_From_BOARD( mod ); editor->Load_Module_From_BOARD( mod );
@ -1425,7 +1436,9 @@ int EDIT_TOOL::copyToClipboard( const TOOL_EVENT& aEvent )
PCBNEW_SELECTION& selection = m_selectionTool->RequestSelection( PCBNEW_SELECTION& selection = m_selectionTool->RequestSelection(
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector ) []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector )
{ EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED_PADS | EXCLUDE_TRANSIENTS ); } ); {
EditToolSelectionFilter( aCollector, EXCLUDE_LOCKED_PADS | EXCLUDE_TRANSIENTS );
} );
if( selection.Empty() ) if( selection.Empty() )
return 1; return 1;

View File

@ -2,7 +2,7 @@
* 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) 2014 CERN * Copyright (C) 2014 CERN
* Copyright (C) 2014-2019 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2014-2020 KiCad Developers, see AUTHORS.txt for contributors.
* @author Maciej Suminski <maciej.suminski@cern.ch> * @author Maciej Suminski <maciej.suminski@cern.ch>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
@ -732,10 +732,9 @@ int PCB_EDITOR_CONTROL::PlaceModule( const TOOL_EVENT& aEvent )
if( module == NULL ) if( module == NULL )
continue; continue;
module->SetLink( 0 ); module->SetLink( niluuid );
module->SetFlags( IS_NEW ); // whatever module->SetFlags( IS_NEW ); // whatever
module->SetTimeStamp( GetNewTimeStamp() );
// Set parent so that clearance can be loaded // Set parent so that clearance can be loaded
module->SetParent( board ); module->SetParent( board );

View File

@ -4,7 +4,7 @@
* Copyright (C) 2013-2017 CERN * Copyright (C) 2013-2017 CERN
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* @author Maciej Suminski <maciej.suminski@cern.ch> * @author Maciej Suminski <maciej.suminski@cern.ch>
* Copyright (C) 2018 KiCad Developers, see AUTHORS.txt for contributors. * Copyright (C) 2018-2020 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
@ -963,15 +963,25 @@ int SELECTION_TOOL::selectNet( const TOOL_EVENT& aEvent )
} }
void SELECTION_TOOL::selectAllItemsOnSheet( wxString& aSheetpath ) void SELECTION_TOOL::selectAllItemsOnSheet( wxString& aSheetID )
{ {
UUID uuid( aSheetID );
std::list<MODULE*> modList; std::list<MODULE*> modList;
// store all modules that are on that sheet // store all modules that are on that sheet
for( MODULE* module : board()->Modules() ) for( MODULE* module : board()->Modules() )
{ {
if( module != NULL && module->GetPath().Contains( aSheetpath ) ) if( module == nullptr )
modList.push_back( module ); continue;
for( const UUID& pathStep : module->GetPath() )
{
if( pathStep == uuid )
{
modList.push_back( module );
break;
}
}
} }
//Generate a list of all pads, and of all nets they belong to. //Generate a list of all pads, and of all nets they belong to.
@ -1081,9 +1091,9 @@ void SELECTION_TOOL::zoomFitSelection()
int SELECTION_TOOL::selectSheetContents( const TOOL_EVENT& aEvent ) int SELECTION_TOOL::selectSheetContents( const TOOL_EVENT& aEvent )
{ {
ClearSelection( true /*quiet mode*/ ); ClearSelection( true /*quiet mode*/ );
wxString* sheetpath = aEvent.Parameter<wxString*>(); wxString* sheetID = aEvent.Parameter<wxString*>();
selectAllItemsOnSheet( *sheetpath ); selectAllItemsOnSheet( *sheetID );
zoomFitSelection(); zoomFitSelection();
@ -1111,14 +1121,15 @@ int SELECTION_TOOL::selectSameSheet( const TOOL_EVENT& aEvent )
auto mod = dynamic_cast<MODULE*>( item ); auto mod = dynamic_cast<MODULE*>( item );
if( mod->GetPath().empty() )
return 0;
ClearSelection( true /*quiet mode*/ ); ClearSelection( true /*quiet mode*/ );
// get the lowest subsheet name for this. // get the lowest subsheet name for this.
wxString sheetPath = mod->GetPath(); wxString sheetID = mod->GetPath().back().AsString();
sheetPath = sheetPath.BeforeLast( '/' );
sheetPath = sheetPath.AfterLast( '/' );
selectAllItemsOnSheet( sheetPath ); selectAllItemsOnSheet( sheetID );
// Inform other potentially interested tools // Inform other potentially interested tools
if( m_selection.Size() > 0 ) if( m_selection.Size() > 0 )

View File

@ -4,7 +4,7 @@
* Copyright (C) 2013-2017 CERN * Copyright (C) 2013-2017 CERN
* @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch> * @author Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
* @author Maciej Suminski <maciej.suminski@cern.ch> * @author Maciej Suminski <maciej.suminski@cern.ch>
* Copyright (C) 2017-2019 KiCad Developers, see CHANGELOG.TXT for contributors. * Copyright (C) 2017-2020 KiCad Developers, see CHANGELOG.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
@ -235,7 +235,7 @@ private:
* Selects all items with the given sheet timestamp name * Selects all items with the given sheet timestamp name
* (the sheet path) * (the sheet path)
*/ */
void selectAllItemsOnSheet( wxString& aSheetpath ); void selectAllItemsOnSheet( wxString& aSheetID );
///> Selects all modules belonging to same sheet, from Eeschema, ///> Selects all modules belonging to same sheet, from Eeschema,
///> using crossprobing ///> using crossprobing

View File

@ -166,17 +166,16 @@ static void SwapItemData( BOARD_ITEM* aItem, BOARD_ITEM* aImage )
wxASSERT( aItem->Type() == aImage->Type() ); wxASSERT( aItem->Type() == aImage->Type() );
// Remark: to create images of edited items to undo, we are using Clone method // Remark: to create images of edited items to undo, we are using Clone method
// which can duplication of items foe copy, but does not clone all members // which does not do a deep copy.
// mainly pointers in chain and time stamp, which is set to new, unique value.
// So we have to use the current values of these parameters. // So we have to use the current values of these parameters.
timestamp_t timestamp = aItem->GetTimeStamp(); wxASSERT( aItem->m_Uuid == aItem->m_Uuid );
EDA_ITEM* parent = aItem->GetParent(); EDA_ITEM* parent = aItem->GetParent();
aItem->SwapData( aImage ); aItem->SwapData( aImage );
// Restore pointers and time stamp, to be sure they are not broken // Restore pointers to be sure they are not broken
aItem->SetTimeStamp( timestamp );
aItem->SetParent( parent ); aItem->SetParent( parent );
} }