In complex hierarchies, multiples parts per packages now should work, without restrictions

This commit is contained in:
charras 2008-04-16 08:40:31 +00:00
parent c77c3906bc
commit 2b0a25b4da
12 changed files with 1236 additions and 1114 deletions

View File

@ -5,7 +5,14 @@ Started 2007-June-11
Please add newer entries at the top, list the date and your name with Please add newer entries at the top, list the date and your name with
email address. email address.
2008-Apr-14 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr> 2008-Apr-16 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
+eeschema
In complex hierarchies, multiples parts per packages now should work,
without restrictions
2008-Apr-15 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================ ================================================================================
+eeschema +eeschema
More code cleaning and Files cleaning and reorganization. More code cleaning and Files cleaning and reorganization.

View File

@ -265,7 +265,7 @@ void AnnotateComponents( WinEDA_SchematicFrame* parent,
BaseListeCmp = AllocateCmpListStrct( NbOfCmp ); BaseListeCmp = AllocateCmpListStrct( NbOfCmp );
/* Second pass : Int data tables */ /* Second pass : Init data tables */
if( annotateSchematic ) if( annotateSchematic )
{ {
ii = 0; ii = 0;
@ -334,7 +334,7 @@ int ListeComposants( CmpListStruct* BaseListeCmp, DrawSheetPath* sheet )
BaseListeCmp[NbrCmp].m_Cmp = DrawLibItem; BaseListeCmp[NbrCmp].m_Cmp = DrawLibItem;
BaseListeCmp[NbrCmp].m_NbParts = Entry->m_UnitCount; BaseListeCmp[NbrCmp].m_NbParts = Entry->m_UnitCount;
BaseListeCmp[NbrCmp].m_Unit = DrawLibItem->m_Multi; BaseListeCmp[NbrCmp].m_Unit = DrawLibItem->GetUnitSelection( sheet );// DrawLibItem->m_Multi;
BaseListeCmp[NbrCmp].m_PartsLocked = Entry->m_UnitSelectionLocked; BaseListeCmp[NbrCmp].m_PartsLocked = Entry->m_UnitSelectionLocked;
BaseListeCmp[NbrCmp].m_SheetList = *sheet; BaseListeCmp[NbrCmp].m_SheetList = *sheet;
BaseListeCmp[NbrCmp].m_IsNew = FALSE; BaseListeCmp[NbrCmp].m_IsNew = FALSE;
@ -386,6 +386,7 @@ static void ReAnnotateComponents( CmpListStruct* BaseListeCmp, int NbOfCmp )
DrawLibItem->SetRef( &(BaseListeCmp[ii].m_SheetList), DrawLibItem->SetRef( &(BaseListeCmp[ii].m_SheetList),
CONV_FROM_UTF8( Text ) ); CONV_FROM_UTF8( Text ) );
DrawLibItem->m_Multi = BaseListeCmp[ii].m_Unit; DrawLibItem->m_Multi = BaseListeCmp[ii].m_Unit;
DrawLibItem->SetUnitSelection( &(BaseListeCmp[ii].m_SheetList), DrawLibItem->m_Multi );
} }
} }
@ -587,12 +588,14 @@ int GetLastReferenceNumber( CmpListStruct* Objet,
/***************************************************************************** /*****************************************************************************
* TODO: Translate this to english/ * Search in the sorted list of components, for a given componen,t an other component
* Recherche dans la liste triee des composants, pour les composants * with the same reference and a given part unit.
* multiples s'il existe pour le composant de reference Objet, * Mainly used to manage multiple parts per package components
* une unite de numero Unit * @param Objet = the given CmpListStruct* item to test
* Retourne index dans BaseListeCmp si oui * @param Unit = the given unit number to search
* retourne -1 si non * @param BaseListeCmp = list of items to examine
* @param NbOfCmp = size of list
* @return index in BaseListeCmp if found or -1 if not found
*****************************************************************************/ *****************************************************************************/
static int ExistUnit( CmpListStruct* Objet, int Unit, static int ExistUnit( CmpListStruct* Objet, int Unit,
CmpListStruct* BaseListeCmp, int NbOfCmp ) CmpListStruct* BaseListeCmp, int NbOfCmp )
@ -609,16 +612,15 @@ static int ExistUnit( CmpListStruct* Objet, int Unit,
ItemToTest < EndList; ItemToTest < EndList;
ItemToTest++, ii++ ) ItemToTest++, ii++ )
{ {
if( Objet == ItemToTest ) if( Objet == ItemToTest ) // Do not compare with itself !
continue; continue;
if( ItemToTest->m_IsNew ) if( ItemToTest->m_IsNew ) // Not already with an updated reference
continue; /* non affecte */
if( ItemToTest->m_NumRef != NumRef )
continue; continue;
/* Nouveau Identificateur */ if( ItemToTest->m_NumRef != NumRef ) // Not the same reference number (like 35 in R35)
if( strnicmp( RefText, ItemToTest->m_TextRef, 32 ) != 0 )
continue; continue;
if( ItemToTest->m_Unit == Unit ) if( strnicmp( RefText, ItemToTest->m_TextRef, 32 ) != 0 ) // Not the same reference prefix
continue;
if( ItemToTest->m_Unit == Unit ) // A part with the same reference and the given unit is found
{ {
return ii; return ii;
} }

View File

@ -772,7 +772,15 @@ wxString DrawSheetPath::PathHumanReadable()
} }
/***********************************************/
void DrawSheetPath::UpdateAllScreenReferences() void DrawSheetPath::UpdateAllScreenReferences()
/***********************************************/
/** Function UpdateAllScreenReferences
* Update the reference and the m_Multi parameter (part selection) for all components on a screen
* depending on the actual sheet path.
* Mandatory in complex hierarchies sheets use the same screen (basic schematic)
* but with different references and part selection according to the displayed sheet
*/
{ {
EDA_BaseStruct* t = LastDrawList(); EDA_BaseStruct* t = LastDrawList();
@ -780,13 +788,12 @@ void DrawSheetPath::UpdateAllScreenReferences()
{ {
if( t->Type() == TYPE_SCH_COMPONENT ) if( t->Type() == TYPE_SCH_COMPONENT )
{ {
SCH_COMPONENT* d = (SCH_COMPONENT*) t; SCH_COMPONENT* component = (SCH_COMPONENT*) t;
d->m_Field[REFERENCE].m_Text = d->GetRef( this ); component->m_Field[REFERENCE].m_Text = component->GetRef( this );
component->m_Multi = component->GetUnitSelection( this );
} }
t = t->Pnext; t = t->Pnext;
} }
printf( "on sheet: %s \n", CONV_TO_UTF8( PathHumanReadable() ) );
} }

View File

@ -127,7 +127,7 @@ public:
/* class to handle a series of sheets *********/ /* class to handle a series of sheets *********/
/* a 'path' so to speak.. *********************/ /* a 'path' so to speak.. *********************/
/**********************************************/ /**********************************************/
#define DSLSZ 32 #define DSLSZ 32 // Max number of levels for a sheet path
class DrawSheetPath class DrawSheetPath
{ {
public: public:
@ -143,8 +143,23 @@ public:
EDA_BaseStruct* LastDrawList(); EDA_BaseStruct* LastDrawList();
void Push( DrawSheetStruct* sheet ); void Push( DrawSheetStruct* sheet );
DrawSheetStruct* Pop(); DrawSheetStruct* Pop();
/** Function Path
* the path uses the time stamps which do not changes even when editing sheet parameters
* a path is something like / (root) or /34005677 or /34005677/00AE4523
*/
wxString Path(); wxString Path();
/** Function PathHumanReadable
* Return the sheet path in a readable form, i.e.
* as a path made from sheet names.
* (the "normal" path uses the time stamps which do not changes even when editing sheet parameters)
*/
wxString PathHumanReadable(); wxString PathHumanReadable();
/** Function UpdateAllScreenReferences
* Update the reference and the m_Multi parameter (part selection) for all components on a screen
* depending on the actual sheet path.
* Mandatory in complex hierarchies because sheets use the same screen (basic schematic)
* but with different references and part selection according to the displayed sheet
*/
void UpdateAllScreenReferences(); void UpdateAllScreenReferences();
bool operator =( const DrawSheetPath& d1 ); bool operator =( const DrawSheetPath& d1 );

View File

@ -27,12 +27,14 @@ WX_DEFINE_OBJARRAY( ArrayOfSheetLists );
/** Function AddHierarchicalReference /** Function AddHierarchicalReference
* Add a full hierachical reference (path + local reference) * Add a full hierachical reference (path + local reference)
* @param path = hierarchical path (/<sheet timestamp>/component timestamp> like /05678E50/A23EF560) * @param aPath = hierarchical path (/<sheet timestamp>/component timestamp> like /05678E50/A23EF560)
* @param ref = local reference like C45, R56 * @param aRef = local reference like C45, R56
* @param aMulti = part selection, used in multi part per package (0 or 1 for non multi)
*/ */
void SCH_COMPONENT::AddHierarchicalReference( const wxString& path, const wxString& ref ) void SCH_COMPONENT::AddHierarchicalReference( const wxString& aPath,
const wxString& aRef,
int aMulti )
{ {
wxString h_path, h_ref; wxString h_path, h_ref;
wxStringTokenizer tokenizer; wxStringTokenizer tokenizer;
wxString separators( wxT( " " ) ); wxString separators( wxT( " " ) );
@ -42,16 +44,16 @@ void SCH_COMPONENT::AddHierarchicalReference( const wxString& path, const wxStri
{ {
tokenizer.SetString( m_PathsAndReferences[ii], separators ); tokenizer.SetString( m_PathsAndReferences[ii], separators );
h_path = tokenizer.GetNextToken(); h_path = tokenizer.GetNextToken();
if( h_path.Cmp( path ) == 0 ) if( h_path.Cmp( aPath ) == 0 )
{ {
m_PathsAndReferences.RemoveAt(ii); m_PathsAndReferences.RemoveAt( ii );
ii --; ii--;
} }
} }
h_ref = path + wxT( " " ) + ref; h_ref = aPath + wxT( " " ) + aRef;
h_ref << wxT( " " ) << m_Multi; h_ref << wxT( " " ) << aMulti;
m_PathsAndReferences.Add( h_ref ); m_PathsAndReferences.Add( h_ref );
} }
@ -156,16 +158,15 @@ const wxString SCH_COMPONENT::GetRef( DrawSheetPath* sheet )
void SCH_COMPONENT::SetRef( DrawSheetPath* sheet, const wxString& ref ) void SCH_COMPONENT::SetRef( DrawSheetPath* sheet, const wxString& ref )
/***********************************************************************/ /***********************************************************************/
{ {
//check to see if it is already there before inserting it
wxString path = GetPath( sheet ); wxString path = GetPath( sheet );
// printf( "SetRef path: %s ref: %s\n", CONV_TO_UTF8( path ), CONV_TO_UTF8( ref ) ); // Debug
bool notInArray = true; bool notInArray = true;
wxString h_path, h_ref; wxString h_path, h_ref;
wxStringTokenizer tokenizer; wxStringTokenizer tokenizer;
wxString separators( wxT( " " ) ); wxString separators( wxT( " " ) );
//check to see if it is already there before inserting it
for( unsigned ii = 0; ii<m_PathsAndReferences.GetCount(); ii++ ) for( unsigned ii = 0; ii<m_PathsAndReferences.GetCount(); ii++ )
{ {
tokenizer.SetString( m_PathsAndReferences[ii], separators ); tokenizer.SetString( m_PathsAndReferences[ii], separators );
@ -184,7 +185,7 @@ void SCH_COMPONENT::SetRef( DrawSheetPath* sheet, const wxString& ref )
} }
if( notInArray ) if( notInArray )
AddHierarchicalReference( path, ref ); AddHierarchicalReference( path, ref, m_Multi );
if( m_Field[REFERENCE].m_Text.IsEmpty() if( m_Field[REFERENCE].m_Text.IsEmpty()
|| ( abs( m_Field[REFERENCE].m_Pos.x - m_Pos.x ) + || ( abs( m_Field[REFERENCE].m_Pos.x - m_Pos.x ) +
@ -199,6 +200,74 @@ void SCH_COMPONENT::SetRef( DrawSheetPath* sheet, const wxString& ref )
} }
/***********************************************************/
int SCH_COMPONENT::GetUnitSelection( DrawSheetPath* aSheet )
/***********************************************************/
//returns the unit selection, for the given sheet path.
{
wxString path = GetPath( aSheet );
wxString h_path, h_multi;
wxStringTokenizer tokenizer;
wxString separators( wxT( " " ) );
for( unsigned ii = 0; ii<m_PathsAndReferences.GetCount(); ii++ )
{
tokenizer.SetString( m_PathsAndReferences[ii], separators );
h_path = tokenizer.GetNextToken();
if( h_path.Cmp( path ) == 0 )
{
tokenizer.GetNextToken(); // Skip reference
h_multi = tokenizer.GetNextToken();
long imulti = 1;
h_multi.ToLong( &imulti );
return imulti;
}
}
//if it was not found in m_Paths array, then use m_Multi.
// this will happen if we load a version 1 schematic file.
return m_Multi;
}
/********************************************************************************/
void SCH_COMPONENT::SetUnitSelection( DrawSheetPath* aSheet, int aUnitSelection )
/********************************************************************************/
//Set the unit selection, for the given sheet path.
{
wxString path = GetPath( aSheet );
bool notInArray = true;
wxString h_path, h_ref;
wxStringTokenizer tokenizer;
wxString separators( wxT( " " ) );
//check to see if it is already there before inserting it
for( unsigned ii = 0; ii<m_PathsAndReferences.GetCount(); ii++ )
{
tokenizer.SetString( m_PathsAndReferences[ii], separators );
h_path = tokenizer.GetNextToken();
if( h_path.Cmp( path ) == 0 )
{
//just update the unit selection.
h_ref = h_path + wxT( " " );
h_ref += tokenizer.GetNextToken(); // Add reference
h_ref += wxT( " " );
h_ref << aUnitSelection; // Add part selection
// Ann the part selection
m_PathsAndReferences[ii] = h_ref;
notInArray = false;
}
}
if( notInArray )
AddHierarchicalReference( path, m_PrefixString, aUnitSelection );
}
/******************************************************************/ /******************************************************************/
const wxString& SCH_COMPONENT::GetFieldValue( int aFieldNdx ) const const wxString& SCH_COMPONENT::GetFieldValue( int aFieldNdx ) const
/******************************************************************/ /******************************************************************/
@ -992,9 +1061,9 @@ bool SCH_COMPONENT::Save( FILE* f ) const
} }
/* If this is a complex hierarchy; save hierarchical references. /* If this is a complex hierarchy; save hierarchical references.
* but for simple hierarchies it is not necessary. * but for simple hierarchies it is not necessary.
* the reference inf is already saved * the reference inf is already saved
* this is usefull for old eeschema version compatibility * this is usefull for old eeschema version compatibility
*/ */
if( m_PathsAndReferences.GetCount() > 1 ) if( m_PathsAndReferences.GetCount() > 1 )
{ {

View File

@ -164,15 +164,25 @@ public:
void SwapData( SCH_COMPONENT* copyitem ); void SwapData( SCH_COMPONENT* copyitem );
virtual void Place( WinEDA_DrawFrame* frame, wxDC* DC ); void Place( WinEDA_DrawFrame* frame, wxDC* DC );
//returns a unique ID, in the form of a path. //returns a unique ID, in the form of a path.
wxString GetPath( DrawSheetPath* sheet ); wxString GetPath( DrawSheetPath* sheet );
//returns the reference, for the given sheet path.
const wxString GetRef( DrawSheetPath* sheet ); const wxString GetRef( DrawSheetPath* sheet );
//Set the reference, for the given sheet path.
void SetRef( DrawSheetPath* sheet, const wxString& ref ); void SetRef( DrawSheetPath* sheet, const wxString& ref );
void AddHierarchicalReference( const wxString& path, const wxString& ref ); /** Function AddHierarchicalReference
* Add a full hierachical reference (path + local reference)
* @param aPath = hierarchical path (/<sheet timestamp>/component timestamp> like /05678E50/A23EF560)
* @param aRef = local reference like C45, R56
* @param aMulti = part selection, used in multi part per package (0 or 1 for non multi)
*/
void AddHierarchicalReference( const wxString& aPath, const wxString& aRef, int aMulti );
//returns the unit selection, for the given sheet path.
int GetUnitSelection( DrawSheetPath* aSheet ); int GetUnitSelection( DrawSheetPath* aSheet );
//Set the unit selection, for the given sheet path.
void SetUnitSelection( DrawSheetPath* aSheet, int aUnitSelection ); void SetUnitSelection( DrawSheetPath* aSheet, int aUnitSelection );
#if defined (DEBUG) #if defined (DEBUG)

View File

@ -87,7 +87,7 @@ void WinEDA_SchematicFrame::RedrawActiveWindow( wxDC* DC, bool EraseBg )
ActiveScreen = GetScreen(); ActiveScreen = GetScreen();
/* Forcage de la reinit de la brosse et plume courante */ /* Reinit draw and pen parameters */
GRResetPenAndBrush( DC ); GRResetPenAndBrush( DC );
DC->SetBackground( *wxBLACK_BRUSH ); DC->SetBackground( *wxBLACK_BRUSH );
DC->SetBackgroundMode( wxTRANSPARENT ); DC->SetBackgroundMode( wxTRANSPARENT );
@ -116,7 +116,9 @@ void WinEDA_SchematicFrame::RedrawActiveWindow( wxDC* DC, bool EraseBg )
Affiche_Status_Box(); Affiche_Status_Box();
GetScreen()->ClrRefreshReq(); GetScreen()->ClrRefreshReq();
if( GetScreen()->m_FileName == g_DefaultSchematicFileName )
// Display the sheet filename, and the sheet path, for non root sheets
if( GetScreen()->m_FileName == g_DefaultSchematicFileName ) // This is the root sheet
{ {
wxString msg = g_Main_Title + wxT( " " ) + GetBuildVersion(); wxString msg = g_Main_Title + wxT( " " ) + GetBuildVersion();
title.Printf( wxT( "%s [%s]" ), msg.GetData(), GetScreen()->m_FileName.GetData() ); title.Printf( wxT( "%s [%s]" ), msg.GetData(), GetScreen()->m_FileName.GetData() );
@ -124,7 +126,9 @@ void WinEDA_SchematicFrame::RedrawActiveWindow( wxDC* DC, bool EraseBg )
} }
else else
{ {
title.Printf( wxT( "[%s]" ), GetScreen()->m_FileName.GetData() ); title = wxT( "[" );
title << GetScreen()->m_FileName << wxT( "] " ) << _("Sheet") ;
title << wxT( " " ) << m_CurrentSheet->PathHumanReadable();
SetTitle( title ); SetTitle( title );
} }
} }

View File

@ -241,8 +241,6 @@ void WinEDA_HierFrame::OnSelect(wxTreeEvent& event)
*(m_Parent->m_CurrentSheet) = *(m_Parent->m_CurrentSheet) =
((TreeItemData*)(m_Tree->GetItemData(ItemSel)))->m_SheetList; ((TreeItemData*)(m_Tree->GetItemData(ItemSel)))->m_SheetList;
wxString path = m_Parent->m_CurrentSheet->PathHumanReadable();
printf("changing to sheet %s\n", CONV_TO_UTF8(path));
UpdateScreenFromSheet(m_Parent); UpdateScreenFromSheet(m_Parent);
Close(TRUE); Close(TRUE);
} }
@ -319,14 +317,14 @@ static bool UpdateScreenFromSheet(WinEDA_SchematicFrame * frame)
//update the References //update the References
frame->m_CurrentSheet->UpdateAllScreenReferences(); frame->m_CurrentSheet->UpdateAllScreenReferences();
frame->DrawPanel->m_CanStartBlock = -1; frame->DrawPanel->m_CanStartBlock = -1;
ActiveScreen = frame->m_CurrentSheet->LastScreen();
if ( NewScreen->m_FirstRedraw ){ if ( NewScreen->m_FirstRedraw ){
NewScreen->m_FirstRedraw = FALSE; NewScreen->m_FirstRedraw = FALSE;
frame->Zoom_Automatique(TRUE); frame->Zoom_Automatique(TRUE);
}else{ }else{
frame->ReDrawPanel(); frame->DrawPanel->Refresh();
frame->DrawPanel->MouseToCursorSchema(); frame->DrawPanel->MouseToCursorSchema();
} }
ActiveScreen = frame->m_CurrentSheet->LastScreen();
return true; return true;
} }

View File

@ -613,26 +613,29 @@ static int ReadPartDescr( wxWindow* frame, char* Line, FILE* f,
if( Line[0] == 'A' && Line[1] == 'R' ) if( Line[0] == 'A' && Line[1] == 'R' )
{ {
/*format: /*format:
AR Path="/9086AF6E/67452AA0" Ref="C99" AR Path="/9086AF6E/67452AA0" Ref="C99" Part="1"
where 9086AF6E is the unique timestamp of the containing sheet where 9086AF6E is the unique timestamp of the containing sheet
and 67452AA0 is the timestamp of this component. and 67452AA0 is the timestamp of this component.
C99 is the reference given this path. C99 is the reference given this path.
*/ */
int i=2; int ii;
while(i<256 && Line[i] != '"'){ i++; } i++; ptcar = Line + 2;
//copy the path. //copy the path.
int j = 0; ii = ReadDelimitedText(Name1, ptcar, 255 );
while(i<256 && Line[i] != '"'){Name1[j] = Line[i]; i++; j++;} i++; ptcar += ii+1;
Name1[j] = 0;
wxString path = CONV_FROM_UTF8(Name1); wxString path = CONV_FROM_UTF8(Name1);
//i should be one after the closing quote, match the next opening quote // copy the reference
while(i<256 && Line[i] != '"'){ i++; } i++; ii = ReadDelimitedText(Name1, ptcar, 255 );
j = 0; ptcar += ii+1;
while(i<256 && Line[i] != '"'){Name1[j] = Line[i]; i++; j++;} i++;
Name1[j] = 0;
wxString ref = CONV_FROM_UTF8(Name1); wxString ref = CONV_FROM_UTF8(Name1);
LibItemStruct->AddHierarchicalReference(path, ref); // copy the multi, if exists
ii = ReadDelimitedText(Name1, ptcar, 255 );
if ( Name1[0] == 0 ) // Nothing read, put a default value
sprintf( Name1, "%d", LibItemStruct->m_Multi );
int multi = atoi(Name1);
if ( multi < 0 || multi > 25 ) multi = 1;
LibItemStruct->AddHierarchicalReference(path, ref, multi);
LibItemStruct->m_Field[REFERENCE].m_Text = ref; LibItemStruct->m_Field[REFERENCE].m_Text = ref;
} }
if( Line[0] == 'F' ) if( Line[0] == 'F' )
@ -724,7 +727,6 @@ static int ReadPartDescr( wxWindow* frame, char* Line, FILE* f,
LibItemStruct->m_Field[fieldref].m_Name = CONV_FROM_UTF8( FieldUserName ); LibItemStruct->m_Field[fieldref].m_Name = CONV_FROM_UTF8( FieldUserName );
} }
// 27 juin 2001: A Supprimer lorsque tous les schemas auront ete traites :
if( fieldref == REFERENCE ) if( fieldref == REFERENCE )
if( LibItemStruct->m_Field[fieldref].m_Text[0] == '#' ) if( LibItemStruct->m_Field[fieldref].m_Text[0] == '#' )
LibItemStruct->m_Field[fieldref].m_Attributs |= TEXT_NO_VISIBLE; LibItemStruct->m_Field[fieldref].m_Attributs |= TEXT_NO_VISIBLE;

View File

@ -5,7 +5,7 @@
COMMON_GLOBL wxString g_BuildVersion COMMON_GLOBL wxString g_BuildVersion
#ifdef EDA_BASE #ifdef EDA_BASE
(wxT("(20080313-r890)")) (wxT("(20080416-r981)"))
#endif #endif
; ;

Binary file not shown.

File diff suppressed because it is too large Load Diff