Commit 26be6d01 authored by Dick Hollenbeck's avatar Dick Hollenbeck

committed

parents 41637b36 b942ebdc
...@@ -680,7 +680,11 @@ bool WinEDA_App::SetLanguage( bool first_time ) ...@@ -680,7 +680,11 @@ bool WinEDA_App::SetLanguage( bool first_time )
delete m_Locale; delete m_Locale;
m_Locale = new wxLocale; m_Locale = new wxLocale;
#if wxCHECK_VERSION( 2, 9, 0 )
if( !m_Locale->Init( m_LanguageId ) )
#else
if( !m_Locale->Init( m_LanguageId, wxLOCALE_CONV_ENCODING ) ) if( !m_Locale->Init( m_LanguageId, wxLOCALE_CONV_ENCODING ) )
#endif
{ {
wxLogDebug( wxT("This language is not supported by the system.") ); wxLogDebug( wxT("This language is not supported by the system.") );
......
This diff is collapsed.
...@@ -226,6 +226,39 @@ public: ...@@ -226,6 +226,39 @@ public:
* When annotating, some or all components are not annotated, * When annotating, some or all components are not annotated,
* i.e. ref is only U or R, with no number. * i.e. ref is only U or R, with no number.
*/ */
/**
* Function SplitReferences
* attempts to split all reference designators into a name (U) and number (1). If the
* last character is '?' or not a digit, the reference is tagged as not annotated.
* For components with multiple parts per package that are not already annotated, set
* m_Unit to a max value (0x7FFFFFFF).
* @see SCH_REFERENCE::Split()
*/
void SplitReferences()
{
for( unsigned ii = 0; ii < GetCount(); ii++ )
componentFlatList[ii].Split();
}
/**
* function UpdateAnnotation
* Update the reference components for the schematic project (or the current sheet)
* Note: this function does not calculate the reference numbers
* stored in m_NumRef
* So, it must be called after calcultaion of new reference numbers
* @see SCH_REFERENCE::Annotate()
*/
void UpdateAnnotation()
{
/* update the reference numbers */
for( unsigned ii = 0; ii < GetCount(); ii++ )
{
componentFlatList[ii].Annotate();
}
}
/** /**
* Function SortCmpByXCoordinate * Function SortCmpByXCoordinate
* sort the flat list by X coordinates. * sort the flat list by X coordinates.
......
...@@ -459,8 +459,12 @@ void DIR_LIB_SOURCE::GetRevisions( STRINGS* aResults, const STRING& aPartName ) ...@@ -459,8 +459,12 @@ void DIR_LIB_SOURCE::GetRevisions( STRINGS* aResults, const STRING& aPartName )
PN_ITER it = partnames.upper_bound( partName +'/' ); PN_ITER it = partnames.upper_bound( partName +'/' );
PN_ITER end = partnames.lower_bound( partName + char( '/' +1 ) ); PN_ITER end = partnames.lower_bound( partName + char( '/' +1 ) );
while( it != end ) for( ; it != end; ++it )
aResults->push_back( *it++ ); {
const char* rev = endsWithRev( *it );
assert( rev );
aResults->push_back( it->substr( rev - it->c_str() ) );
}
} }
} }
......
...@@ -39,13 +39,12 @@ ...@@ -39,13 +39,12 @@
/* /*
The LIB part cache consist of a std::map of partnames without revisions at the top level. The LIB part cache consists of a std::map of partnames without revisions at the
Each top level map entry can point to another std::map which it owns and holds all the revisions top level. Each top level map entry can point to another std::map which it owns
for that part name. At any point in the tree, there can be NULL pointers which and which holds all the revisions for that part name. At any point in the tree,
allow for lazy loading, including the very top most root pointer itself, which there can be NULL pointers which allow for lazy loading, including the very top
is PARTS* parts. We use the key to hold the partName at one level, and revision most root pointer itself, which is PARTS* parts. We use the key to hold the
at the deeper nested level, and that key information may not be present within partName at one level, and revision at the deeper nested level.
right hand side of the map tuple.
1) Only things which are asked for are done. 1) Only things which are asked for are done.
2) Anything we learn we remember. 2) Anything we learn we remember.
...@@ -54,10 +53,31 @@ right hand side of the map tuple. ...@@ -54,10 +53,31 @@ right hand side of the map tuple.
namespace SCH { namespace SCH {
class PART_REVS : public std::map< STRING, PART* >
/**
* Struct LTREV
* is for PART_REVS, and provides a custom way to compare rev STRINGs.
* Namely, the revN[N..] string if present, is collated according to a
* 'higher revision first'.
*/
struct LTREV
{ {
// @todo provide an integer sort on revN.. strings here. bool operator() ( const STRING& s1, const STRING& s2 ) const
{
return RevCmp( s1.c_str(), s2.c_str() ) < 0;
}
};
/**
* Class PART_REVS
* contains the collection of revisions for a particular part name, in the
* form of cached PARTs. The tuple consists of a rev string and a PART pointer.
* The rev string is like "rev1", the PART pointer will be NULL until the PART
* gets loaded, lazily.
*/
class PART_REVS : public std::map< STRING, PART*, LTREV >
{
public: public:
~PART_REVS() ~PART_REVS()
{ {
...@@ -68,6 +88,15 @@ public: ...@@ -68,6 +88,15 @@ public:
} }
}; };
/**
* Class PARTS
* contains the collection of PART_REVS for all PARTs in the lib.
* The tuple consists of a part name and a PART_REVS pointer.
* The part name does not have the revision attached (of course this is understood
* by definition of "part name"). The PART_REVS pointer will be NULL until a client
* askes about the revisions for a part name, so the loading is done lazily.
*/
class PARTS : public std::map< STRING, PART_REVS* > class PARTS : public std::map< STRING, PART_REVS* >
{ {
public: public:
...@@ -126,7 +155,7 @@ LIB::~LIB() ...@@ -126,7 +155,7 @@ LIB::~LIB()
} }
const PART* LIB::findPart( const LPID& aLPID ) throw( IO_ERROR ) const PART* LIB::lookupPart( const LPID& aLPID ) throw( IO_ERROR )
{ {
if( !parts ) if( !parts )
{ {
...@@ -137,7 +166,7 @@ const PART* LIB::findPart( const LPID& aLPID ) throw( IO_ERROR ) ...@@ -137,7 +166,7 @@ const PART* LIB::findPart( const LPID& aLPID ) throw( IO_ERROR )
// insert a PART_REVS for each part name // insert a PART_REVS for each part name
for( STRINGS::const_iterator it = vfetch.begin(); it!=vfetch.end(); ++it ) for( STRINGS::const_iterator it = vfetch.begin(); it!=vfetch.end(); ++it )
{ {
// D(printf("findPart:%s\n", it->c_str() );) D(printf("lookupPart:%s\n", it->c_str() );)
(*parts)[*it] = new PART_REVS; (*parts)[*it] = new PART_REVS;
} }
} }
...@@ -152,44 +181,46 @@ const PART* LIB::findPart( const LPID& aLPID ) throw( IO_ERROR ) ...@@ -152,44 +181,46 @@ const PART* LIB::findPart( const LPID& aLPID ) throw( IO_ERROR )
// if the key for parts has no aLPID.GetPartName() the part is not in this lib // if the key for parts has no aLPID.GetPartName() the part is not in this lib
if( revs ) if( revs )
{ {
if( revs->size() == 0 ) if( revs->size() == 0 ) // assume rev list has not been loaded yet
{ {
// load all the revisions for this part. // load all the revisions for this part.
source->GetRevisions( &vfetch, aLPID.GetPartName() ); source->GetRevisions( &vfetch, aLPID.GetPartName() );
// creat a PART_REV entry for revision, but leave the PART* NULL // create a PART_REV entry for each revision, but leave the PART* NULL
for( STRINGS::const_iterator it = vfetch.begin(); it!=vfetch.end(); ++it ) for( STRINGS::const_iterator it = vfetch.begin(); it!=vfetch.end(); ++it )
{ {
// D(printf("findPartRev:%s\n", it->c_str() );) D(printf("lookupPartRev:%s\n", it->c_str() );)
(*revs)[*it] = 0; (*revs)[*it] = 0;
} }
} }
PART_REVS::iterator result = revs->find( aLPID.GetPartNameAndRev() ); PART_REVS::iterator rev;
if( result != revs->end() ) // If caller did not say what revision, find the highest numbered one and return that.
if( !aLPID.GetRevision().size() && revs->size() )
{ {
if( !result->second ) // the PART has never been loaded before rev = revs->begin(); // sort order has highest rev first
if( !rev->second ) // the PART has never been instantiated before
{ {
result->second = new PART( this, aLPID.GetPartNameAndRev() ); rev->second = new PART( this, LPID::Format( "", aLPID.GetPartName(), rev->first ) );
} }
return result->second; D(printf("lookupPartLatestRev:%s\n", rev->second->partNameAndRev.c_str() );)
return rev->second;
} }
else
// If caller did not say what revision, find the highest numbered one and return that.
// Otherwise he knew what he wanted specifically, and we do not have it.
if( !aLPID.GetRevision().size() && revs->size() )
{ {
result = revs->begin(); // sort order has highest rev first rev = revs->find( aLPID.GetRevision() );
if( !result->second ) // the PART has never been loaded before if( rev != revs->end() )
{ {
result->second = new PART( this, LPID::Format( "", aLPID.GetPartName(), result->first ) ); if( !rev->second ) // the PART has never been instantiated before
{
rev->second = new PART( this, aLPID.GetPartNameAndRev() );
}
return rev->second;
} }
return result->second;
} }
} }
...@@ -199,7 +230,7 @@ const PART* LIB::findPart( const LPID& aLPID ) throw( IO_ERROR ) ...@@ -199,7 +230,7 @@ const PART* LIB::findPart( const LPID& aLPID ) throw( IO_ERROR )
PART* LIB::LookupPart( const LPID& aLPID, LIB_TABLE* aLibTable ) throw( IO_ERROR ) PART* LIB::LookupPart( const LPID& aLPID, LIB_TABLE* aLibTable ) throw( IO_ERROR )
{ {
PART* part = (PART*) findPart( aLPID ); PART* part = (PART*) lookupPart( aLPID );
if( !part ) // part does not exist in this lib if( !part ) // part does not exist in this lib
{ {
...@@ -221,7 +252,8 @@ PART* LIB::LookupPart( const LPID& aLPID, LIB_TABLE* aLibTable ) throw( IO_ERROR ...@@ -221,7 +252,8 @@ PART* LIB::LookupPart( const LPID& aLPID, LIB_TABLE* aLibTable ) throw( IO_ERROR
printf( "\n" ); printf( "\n" );
#endif #endif
SWEET_LEXER sw( part->body, wxString::FromUTF8("body") /* @todo have ReadPart give better source */ ); // @todo consider changing ReadPart to return a "source"
SWEET_LEXER sw( part->body, wxString::FromUTF8( aLPID.Format().c_str() ) );
part->Parse( &sw, aLibTable ); part->Parse( &sw, aLibTable );
} }
......
...@@ -343,14 +343,17 @@ protected: ...@@ -343,14 +343,17 @@ protected:
PARTS* parts; PARTS* parts;
/** /**
* Function findPart * Function lookupPart
* finds a PART, returns NULL if cannot find. * looks up a PART, returns NULL if cannot find in source. Does not parse
* the part. Does not even load the part's Sweet string. No ownership
* is given to the PART, it stays in the cache that is this LIB.
*
* @throw IO_ERROR if there is some kind of communications error reading * @throw IO_ERROR if there is some kind of communications error reading
* the original list of parts. * the original list of parts.
*
* @return PART* - the cached PART, or NULL if not found. No ownership transferred.
*/ */
const PART* findPart( const LPID& aLPID ) throw( IO_ERROR ); const PART* lookupPart( const LPID& aLPID ) throw( IO_ERROR );
}; };
......
...@@ -58,6 +58,20 @@ const char* EndsWithRev( const char* start, const char* tail, char separator ) ...@@ -58,6 +58,20 @@ const char* EndsWithRev( const char* start, const char* tail, char separator )
return 0; return 0;
} }
int RevCmp( const char* s1, const char* s2 )
{
int r = strncmp( s1, s2, 3 );
if( r || strlen(s1)<4 || strlen(s2)<4 )
{
return r;
}
int rnum1 = atoi( s1+3 );
int rnum2 = atoi( s2+3 );
return -(rnum1 - rnum2); // swap the sign, higher revs first
}
//----<Policy and field test functions>------------------------------------- //----<Policy and field test functions>-------------------------------------
...@@ -94,7 +108,7 @@ static int okRevision( const STRING& aField ) ...@@ -94,7 +108,7 @@ static int okRevision( const STRING& aField )
{ {
char rev[32]; // C string for speed char rev[32]; // C string for speed
if( aField.size() >= 4 && aField.size() <= sizeof(rev)-3 ) if( aField.size() >= 4 )
{ {
strcpy( rev, "x/" ); strcpy( rev, "x/" );
strcat( rev, aField.c_str() ); strcat( rev, aField.c_str() );
......
...@@ -228,4 +228,16 @@ static inline const char* EndsWithRev( const STRING& aPartName, char separator = ...@@ -228,4 +228,16 @@ static inline const char* EndsWithRev( const STRING& aPartName, char separator =
} }
/**
* Function RevCmp
* compares two rev strings in a way like strcmp() except that the highest numbered
* revision is considered first in the sort order. The function probably won't work
* unless you give it two rev strings.
* @param s1 is a rev string like "rev10"
* @param s2 is a rev string like "rev1".
* @return int - either negative, zero, or positive depending on whether the revision
* is greater, equal, or less on the left hand side.
*/
int RevCmp( const char* s1, const char* s2 );
#endif // SCH_LPID_H_ #endif // SCH_LPID_H_
...@@ -38,6 +38,11 @@ using namespace SCH; ...@@ -38,6 +38,11 @@ using namespace SCH;
struct XY {}; struct XY {};
struct AT {}; struct AT {};
class POLY_LINE
{
};
//-----</temporary home for PART sub objects, move after stable>----------------- //-----</temporary home for PART sub objects, move after stable>-----------------
...@@ -135,19 +140,28 @@ public: ...@@ -135,19 +140,28 @@ public:
/// @param me = ja mir, the object getting stuffed, from its perspective /// @param me = ja mir, the object getting stuffed, from its perspective
void parsePart( PART* me ) void parsePart( PART* me )
{ {
PART_T tok = in->NextTok(); PART_T tok;
#if 0
// Be flexible regarding the starting point of the stream. // Be flexible regarding the starting point of the stream.
// Caller may not have read the first two tokens out of the // Caller may not have read the first two tokens out of the
// stream: T_LEFT and T_part, so ignore them if seen here. // stream: T_LEFT and T_part, so ignore them if seen here.
// The 1st two tokens T_LEFT and T_part are then optional in the grammar. // The 1st two tokens T_LEFT and T_part are then optional in the grammar.
if( tok == T_LEFT ) if( (tok = in->NextTok() ) == T_LEFT )
{ {
if( ( tok = in->NextTok() ) != T_part ) if( ( tok = in->NextTok() ) != T_part )
in->Expecting( T_part ); in->Expecting( T_part );
} }
#else
// "( part" are not optional
in->NeedLEFT();
if( ( tok = in->NextTok() ) != T_part )
in->Expecting( T_part );
#endif
in->NeedSYMBOLorNUMBER(); // read in part NAME_HINT, and toss in->NeedSYMBOLorNUMBER(); // read in part NAME_HINT, and toss
tok = in->NextTok(); tok = in->NextTok();
...@@ -187,6 +201,11 @@ public: ...@@ -187,6 +201,11 @@ public:
contains |= PB(ANCHOR); contains |= PB(ANCHOR);
break; break;
case T_line:
break;
/* /*
case T_value: case T_value:
if( contains & PB(VALUE) ) if( contains & PB(VALUE) )
...@@ -236,9 +255,6 @@ public: ...@@ -236,9 +255,6 @@ public:
case T_polyline: case T_polyline:
break; break;
case T_line:
break;
case T_rectangle: case T_rectangle:
break; break;
...@@ -267,7 +283,7 @@ public: ...@@ -267,7 +283,7 @@ public:
contains |= PB(PARSED); contains |= PB(PARSED);
this->contains |= contains; me->contains |= contains;
} }
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment