2009-01-04 18:52:57 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
2009-11-03 13:26:31 +00:00
|
|
|
|
2009-01-04 18:52:57 +00:00
|
|
|
// Name: class_drawsheet.cpp
|
2009-11-04 20:46:53 +00:00
|
|
|
// Purpose: member functions for SCH_SHEET
|
2009-11-03 13:26:31 +00:00
|
|
|
// header = class_drawsheet.h
|
2009-01-04 18:52:57 +00:00
|
|
|
// Author: jean-pierre Charras
|
|
|
|
// Modified by:
|
2009-11-03 13:26:31 +00:00
|
|
|
// License: License GNU
|
2009-01-04 18:52:57 +00:00
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#include "fctsys.h"
|
|
|
|
|
|
|
|
#include "common.h"
|
|
|
|
#include "program.h"
|
|
|
|
#include "general.h"
|
|
|
|
|
|
|
|
|
|
|
|
/**********************************************/
|
2009-11-03 13:26:31 +00:00
|
|
|
/* class to handle a series of sheets *********/
|
2009-01-04 18:52:57 +00:00
|
|
|
/* a 'path' so to speak.. *********************/
|
|
|
|
/**********************************************/
|
2009-12-02 21:44:03 +00:00
|
|
|
SCH_SHEET_PATH::SCH_SHEET_PATH()
|
2009-01-04 18:52:57 +00:00
|
|
|
{
|
|
|
|
for( int i = 0; i<DSLSZ; i++ )
|
|
|
|
m_sheets[i] = NULL;
|
|
|
|
|
|
|
|
m_numSheets = 0;
|
|
|
|
}
|
|
|
|
|
2009-11-03 13:26:31 +00:00
|
|
|
|
2009-01-07 20:09:03 +00:00
|
|
|
/** Function BuildSheetPathInfoFromSheetPathValue
|
2009-11-03 13:26:31 +00:00
|
|
|
* Fill this with data to access to the hierarchical sheet known by its path
|
|
|
|
* aPath
|
2009-01-07 20:09:03 +00:00
|
|
|
* @param aPath = path of the sheet to reach (in non human readable format)
|
|
|
|
* @return true if success else false
|
|
|
|
*/
|
2009-12-02 21:44:03 +00:00
|
|
|
bool SCH_SHEET_PATH::BuildSheetPathInfoFromSheetPathValue(
|
|
|
|
const wxString& aPath,
|
|
|
|
bool aFound )
|
|
|
|
{
|
2009-11-03 13:26:31 +00:00
|
|
|
if( aFound )
|
2009-01-07 20:09:03 +00:00
|
|
|
return true;
|
|
|
|
|
2009-11-03 13:26:31 +00:00
|
|
|
if( GetSheetsCount() == 0 )
|
2009-01-07 20:09:03 +00:00
|
|
|
Push( g_RootSheet );
|
|
|
|
|
2009-11-03 13:26:31 +00:00
|
|
|
if( aPath == Path() )
|
2009-01-07 20:09:03 +00:00
|
|
|
return true;
|
|
|
|
|
|
|
|
SCH_ITEM* schitem = LastDrawList();
|
|
|
|
while( schitem && GetSheetsCount() < NB_MAX_SHEET )
|
|
|
|
{
|
|
|
|
if( schitem->Type() == DRAW_SHEET_STRUCT_TYPE )
|
|
|
|
{
|
2009-11-04 20:46:53 +00:00
|
|
|
SCH_SHEET* sheet = (SCH_SHEET*) schitem;
|
2009-01-07 20:09:03 +00:00
|
|
|
Push( sheet );
|
2009-11-03 13:26:31 +00:00
|
|
|
if( aPath == Path() )
|
2009-01-07 20:09:03 +00:00
|
|
|
return true;
|
2009-11-03 13:26:31 +00:00
|
|
|
if( BuildSheetPathInfoFromSheetPathValue( aPath ) )
|
2009-01-07 20:09:03 +00:00
|
|
|
return true;
|
|
|
|
Pop();
|
|
|
|
}
|
|
|
|
schitem = schitem->Next();
|
|
|
|
}
|
2009-11-03 13:26:31 +00:00
|
|
|
|
2009-01-07 20:09:03 +00:00
|
|
|
return false;
|
|
|
|
}
|
2009-01-04 18:52:57 +00:00
|
|
|
|
2009-11-03 13:26:31 +00:00
|
|
|
|
2009-01-06 20:09:32 +00:00
|
|
|
/** Function Cmp
|
|
|
|
* Compare if this is the same sheet path as aSheetPathToTest
|
|
|
|
* @param aSheetPathToTest = sheet path to compare
|
2009-11-03 13:26:31 +00:00
|
|
|
* @return -1 if different, 0 if same
|
2009-01-06 20:09:32 +00:00
|
|
|
*/
|
2009-12-02 21:44:03 +00:00
|
|
|
int SCH_SHEET_PATH::Cmp( const SCH_SHEET_PATH& aSheetPathToTest ) const
|
2009-01-04 18:52:57 +00:00
|
|
|
{
|
2009-01-06 20:09:32 +00:00
|
|
|
if( m_numSheets > aSheetPathToTest.m_numSheets )
|
2009-01-04 18:52:57 +00:00
|
|
|
return 1;
|
2009-01-06 20:09:32 +00:00
|
|
|
if( m_numSheets < aSheetPathToTest.m_numSheets )
|
2009-01-04 18:52:57 +00:00
|
|
|
return -1;
|
|
|
|
|
|
|
|
//otherwise, same number of sheets.
|
2009-01-07 20:09:03 +00:00
|
|
|
for( unsigned i = 0; i<m_numSheets; i++ )
|
2009-01-04 18:52:57 +00:00
|
|
|
{
|
2009-11-03 13:26:31 +00:00
|
|
|
if( m_sheets[i]->m_TimeStamp >
|
|
|
|
aSheetPathToTest.m_sheets[i]->m_TimeStamp )
|
2009-01-04 18:52:57 +00:00
|
|
|
return 1;
|
2009-11-03 13:26:31 +00:00
|
|
|
if( m_sheets[i]->m_TimeStamp <
|
|
|
|
aSheetPathToTest.m_sheets[i]->m_TimeStamp )
|
2009-01-04 18:52:57 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-01-07 17:33:18 +00:00
|
|
|
/** Function Last
|
2009-11-03 13:26:31 +00:00
|
|
|
* returns a pointer to the last sheet of the list
|
|
|
|
* One can see the others sheet as the "path" to reach this last sheet
|
2009-01-07 17:33:18 +00:00
|
|
|
*/
|
2009-12-02 21:44:03 +00:00
|
|
|
SCH_SHEET* SCH_SHEET_PATH::Last()
|
2009-01-04 18:52:57 +00:00
|
|
|
{
|
|
|
|
if( m_numSheets )
|
|
|
|
return m_sheets[m_numSheets - 1];
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-01-07 17:33:18 +00:00
|
|
|
/** Function LastScreen
|
|
|
|
* @return the SCH_SCREEN relative to the last sheet in list
|
|
|
|
*/
|
2009-12-02 21:44:03 +00:00
|
|
|
SCH_SCREEN* SCH_SHEET_PATH::LastScreen()
|
2009-01-04 18:52:57 +00:00
|
|
|
{
|
|
|
|
if( m_numSheets )
|
|
|
|
return m_sheets[m_numSheets - 1]->m_AssociatedScreen;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-01-07 17:33:18 +00:00
|
|
|
/** Function LastScreen
|
|
|
|
* @return a pointer to the first schematic item handled by the
|
|
|
|
* SCH_SCREEN relative to the last sheet in list
|
|
|
|
*/
|
2009-12-02 21:44:03 +00:00
|
|
|
SCH_ITEM* SCH_SHEET_PATH::LastDrawList()
|
2009-01-04 18:52:57 +00:00
|
|
|
{
|
|
|
|
if( m_numSheets && m_sheets[m_numSheets - 1]->m_AssociatedScreen )
|
|
|
|
return m_sheets[m_numSheets - 1]->m_AssociatedScreen->EEDrawList;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-01-06 20:09:32 +00:00
|
|
|
/** Function Push
|
|
|
|
* store (push) aSheet in list
|
2009-11-04 20:46:53 +00:00
|
|
|
* @param aSheet = pointer to the SCH_SHEET to store in list
|
2009-01-06 20:09:32 +00:00
|
|
|
*/
|
2009-12-02 21:44:03 +00:00
|
|
|
void SCH_SHEET_PATH::Push( SCH_SHEET* aSheet )
|
|
|
|
{
|
2009-01-06 20:09:32 +00:00
|
|
|
if( m_numSheets > DSLSZ )
|
2009-12-02 21:44:03 +00:00
|
|
|
wxMessageBox( wxT( "SCH_SHEET_PATH::Push() error: no room in buffer \
|
2009-11-03 13:26:31 +00:00
|
|
|
to store sheet" ) );
|
|
|
|
|
2009-01-04 18:52:57 +00:00
|
|
|
if( m_numSheets < DSLSZ )
|
|
|
|
{
|
2009-01-06 20:09:32 +00:00
|
|
|
m_sheets[m_numSheets] = aSheet;
|
2009-01-04 18:52:57 +00:00
|
|
|
m_numSheets++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-01-06 20:09:32 +00:00
|
|
|
/** Function Pop
|
|
|
|
* retrieves (pop) the last entered sheet and remove it from list
|
2009-11-04 20:46:53 +00:00
|
|
|
* @return a SCH_SHEET* pointer to the removed sheet in list
|
2009-01-06 20:09:32 +00:00
|
|
|
*/
|
2009-12-02 21:44:03 +00:00
|
|
|
SCH_SHEET* SCH_SHEET_PATH::Pop()
|
|
|
|
{
|
2009-01-04 18:52:57 +00:00
|
|
|
if( m_numSheets > 0 )
|
|
|
|
{
|
|
|
|
m_numSheets--;
|
|
|
|
return m_sheets[m_numSheets];
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-01-06 20:09:32 +00:00
|
|
|
/** Function Path
|
2009-11-03 13:26:31 +00:00
|
|
|
* the path uses the time stamps which do not changes even when editing sheet
|
|
|
|
* parameters
|
2009-01-06 20:09:32 +00:00
|
|
|
* a path is something like / (root) or /34005677 or /34005677/00AE4523
|
|
|
|
*/
|
2009-12-02 21:44:03 +00:00
|
|
|
wxString SCH_SHEET_PATH::Path()
|
|
|
|
{
|
2009-01-04 18:52:57 +00:00
|
|
|
wxString s, t;
|
|
|
|
|
2009-01-06 20:09:32 +00:00
|
|
|
s = wxT( "/" ); // This is the root path
|
2009-01-04 18:52:57 +00:00
|
|
|
|
2009-11-03 13:26:31 +00:00
|
|
|
// start at 1 to avoid the root sheet,
|
|
|
|
// which does not need to be added to the path
|
|
|
|
// it's timestamp changes anyway.
|
|
|
|
for( unsigned i = 1; i < m_numSheets; i++ )
|
2009-01-04 18:52:57 +00:00
|
|
|
{
|
|
|
|
t.Printf( _( "%8.8lX/" ), m_sheets[i]->m_TimeStamp );
|
|
|
|
s = s + t;
|
|
|
|
}
|
|
|
|
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-01-06 20:09:32 +00:00
|
|
|
/** Function PathHumanReadable
|
|
|
|
* Return the sheet path in a readable form, i.e.
|
|
|
|
* as a path made from sheet names.
|
2009-11-03 13:26:31 +00:00
|
|
|
* (the "normal" path uses the time stamps which do not changes even when
|
|
|
|
* editing sheet parameters)
|
2009-01-06 20:09:32 +00:00
|
|
|
*/
|
2009-12-02 21:44:03 +00:00
|
|
|
wxString SCH_SHEET_PATH::PathHumanReadable()
|
|
|
|
{
|
2009-01-04 18:52:57 +00:00
|
|
|
wxString s, t;
|
|
|
|
|
|
|
|
s = wxT( "/" );
|
|
|
|
|
2009-11-03 13:26:31 +00:00
|
|
|
// start at 1 to avoid the root sheet, as above.
|
2009-01-07 20:09:03 +00:00
|
|
|
for( unsigned i = 1; i< m_numSheets; i++ )
|
2009-01-04 18:52:57 +00:00
|
|
|
{
|
|
|
|
s = s + m_sheets[i]->m_SheetName + wxT( "/" );
|
|
|
|
}
|
|
|
|
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-12-02 21:44:03 +00:00
|
|
|
void SCH_SHEET_PATH::UpdateAllScreenReferences()
|
2009-01-04 18:52:57 +00:00
|
|
|
{
|
|
|
|
EDA_BaseStruct* t = LastDrawList();
|
|
|
|
|
|
|
|
while( t )
|
|
|
|
{
|
|
|
|
if( t->Type() == TYPE_SCH_COMPONENT )
|
|
|
|
{
|
|
|
|
SCH_COMPONENT* component = (SCH_COMPONENT*) t;
|
2009-01-06 20:09:32 +00:00
|
|
|
component->GetField( REFERENCE )->m_Text = component->GetRef( this );
|
2009-01-04 18:52:57 +00:00
|
|
|
component->m_Multi = component->GetUnitSelection( this );
|
|
|
|
}
|
|
|
|
t = t->Next();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-12-02 21:44:03 +00:00
|
|
|
bool SCH_SHEET_PATH::operator=( const SCH_SHEET_PATH& d1 )
|
2009-01-04 18:52:57 +00:00
|
|
|
{
|
|
|
|
m_numSheets = d1.m_numSheets;
|
2009-01-07 20:09:03 +00:00
|
|
|
unsigned i;
|
2009-11-03 13:26:31 +00:00
|
|
|
for( i = 0; i < m_numSheets; i++ )
|
2009-01-04 18:52:57 +00:00
|
|
|
{
|
|
|
|
m_sheets[i] = d1.m_sheets[i];
|
|
|
|
}
|
|
|
|
|
2009-11-03 13:26:31 +00:00
|
|
|
for( ; i < DSLSZ; i++ )
|
2009-01-04 18:52:57 +00:00
|
|
|
{
|
|
|
|
m_sheets[i] = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-12-02 21:44:03 +00:00
|
|
|
bool SCH_SHEET_PATH::operator==( const SCH_SHEET_PATH& d1 )
|
2009-01-04 18:52:57 +00:00
|
|
|
{
|
|
|
|
if( m_numSheets != d1.m_numSheets )
|
|
|
|
return false;
|
2009-11-03 13:26:31 +00:00
|
|
|
for( unsigned i = 0; i < m_numSheets; i++ )
|
2009-01-04 18:52:57 +00:00
|
|
|
{
|
|
|
|
if( m_sheets[i] != d1.m_sheets[i] )
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-12-02 21:44:03 +00:00
|
|
|
bool SCH_SHEET_PATH::operator!=( const SCH_SHEET_PATH& d1 )
|
2009-01-04 18:52:57 +00:00
|
|
|
{
|
|
|
|
if( m_numSheets != d1.m_numSheets )
|
|
|
|
return true;
|
2009-11-03 13:26:31 +00:00
|
|
|
for( unsigned i = 0; i < m_numSheets; i++ )
|
2009-01-04 18:52:57 +00:00
|
|
|
{
|
|
|
|
if( m_sheets[i] != d1.m_sheets[i] )
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*********************************************************************/
|
2009-12-02 21:44:03 +00:00
|
|
|
/* Class SCH_SHEET_LIST to handle the list of Sheets in a hierarchy */
|
2009-01-04 18:52:57 +00:00
|
|
|
/*********************************************************************/
|
|
|
|
|
2009-01-06 20:09:32 +00:00
|
|
|
|
|
|
|
/* The constructor: build the list of sheets from aSheet.
|
|
|
|
* If aSheet == NULL (default) build the whole list of sheets in hierarchy
|
|
|
|
* So usually call it with no param.
|
|
|
|
*/
|
2009-12-02 21:44:03 +00:00
|
|
|
SCH_SHEET_LIST::SCH_SHEET_LIST( SCH_SHEET* aSheet )
|
|
|
|
{
|
2009-01-06 20:09:32 +00:00
|
|
|
m_index = 0;
|
|
|
|
m_count = 0;
|
|
|
|
m_List = NULL;
|
|
|
|
if( aSheet == NULL )
|
|
|
|
aSheet = g_RootSheet;
|
|
|
|
BuildSheetList( aSheet );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/** Function GetFirst
|
|
|
|
* @return the first item (sheet) in m_List and prepare calls to GetNext()
|
|
|
|
*/
|
2009-12-02 21:44:03 +00:00
|
|
|
SCH_SHEET_PATH* SCH_SHEET_LIST::GetFirst()
|
|
|
|
{
|
2009-01-04 18:52:57 +00:00
|
|
|
m_index = 0;
|
2009-01-06 20:09:32 +00:00
|
|
|
if( GetCount() > 0 )
|
2009-01-04 18:52:57 +00:00
|
|
|
return &( m_List[0] );
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-01-06 20:09:32 +00:00
|
|
|
/** Function GetNext
|
2009-11-03 13:26:31 +00:00
|
|
|
* @return the next item (sheet) in m_List or NULL if no more item in sheet
|
|
|
|
* list
|
2009-01-06 20:09:32 +00:00
|
|
|
*/
|
2009-12-02 21:44:03 +00:00
|
|
|
SCH_SHEET_PATH* SCH_SHEET_LIST::GetNext()
|
|
|
|
{
|
2009-01-06 20:09:32 +00:00
|
|
|
if( m_index < GetCount() )
|
2009-01-04 18:52:57 +00:00
|
|
|
m_index++;
|
|
|
|
return GetSheet( m_index );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-01-06 20:09:32 +00:00
|
|
|
/** Function GetSheet
|
2009-11-03 13:26:31 +00:00
|
|
|
* @return the item (sheet) in aIndex position in m_List or NULL if less than
|
|
|
|
* index items
|
2009-01-06 20:09:32 +00:00
|
|
|
* @param aIndex = index in sheet list to get the sheet
|
2009-01-04 18:52:57 +00:00
|
|
|
*/
|
2009-12-02 21:44:03 +00:00
|
|
|
SCH_SHEET_PATH* SCH_SHEET_LIST::GetSheet( int aIndex )
|
|
|
|
{
|
2009-01-06 20:09:32 +00:00
|
|
|
if( aIndex < GetCount() )
|
2009-11-03 13:26:31 +00:00
|
|
|
return &( m_List[aIndex] );
|
2009-01-04 18:52:57 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-01-06 20:09:32 +00:00
|
|
|
/** Function BuildSheetList
|
|
|
|
* Build the list of sheets and their sheet path from the aSheet sheet
|
2009-11-03 13:26:31 +00:00
|
|
|
* if aSheet = g_RootSheet, the full sheet path list (and full sheet list) is
|
|
|
|
* built
|
2009-01-06 20:09:32 +00:00
|
|
|
* @param aSheet = the starting sheet to build list
|
|
|
|
*/
|
2009-12-02 21:44:03 +00:00
|
|
|
void SCH_SHEET_LIST::BuildSheetList( SCH_SHEET* aSheet )
|
|
|
|
{
|
2009-01-04 18:52:57 +00:00
|
|
|
if( m_List == NULL )
|
|
|
|
{
|
2009-01-06 20:09:32 +00:00
|
|
|
int count = aSheet->CountSheets();
|
2009-01-04 18:52:57 +00:00
|
|
|
m_count = count;
|
|
|
|
m_index = 0;
|
2009-12-02 21:44:03 +00:00
|
|
|
count *= sizeof(SCH_SHEET_PATH);
|
|
|
|
|
|
|
|
/* @bug - MyZMalloc() can return a NULL pointer if there is not enough
|
|
|
|
* memory. This code continues on it's merry way with out
|
|
|
|
* checking to see if the memory was actually allocated.
|
|
|
|
*/
|
|
|
|
m_List = (SCH_SHEET_PATH*) MyZMalloc( count );
|
2009-01-04 18:52:57 +00:00
|
|
|
m_currList.Clear();
|
|
|
|
}
|
2009-12-02 21:44:03 +00:00
|
|
|
|
2009-01-06 20:09:32 +00:00
|
|
|
m_currList.Push( aSheet );
|
2009-01-04 18:52:57 +00:00
|
|
|
m_List[m_index] = m_currList;
|
|
|
|
m_index++;
|
2009-12-02 21:44:03 +00:00
|
|
|
|
2009-01-06 20:09:32 +00:00
|
|
|
if( aSheet->m_AssociatedScreen != NULL )
|
2009-01-04 18:52:57 +00:00
|
|
|
{
|
|
|
|
EDA_BaseStruct* strct = m_currList.LastDrawList();
|
|
|
|
while( strct )
|
|
|
|
{
|
|
|
|
if( strct->Type() == DRAW_SHEET_STRUCT_TYPE )
|
|
|
|
{
|
2009-11-04 20:46:53 +00:00
|
|
|
SCH_SHEET* sheet = (SCH_SHEET*) strct;
|
2009-01-06 20:09:32 +00:00
|
|
|
BuildSheetList( sheet );
|
2009-01-04 18:52:57 +00:00
|
|
|
}
|
2009-12-02 21:44:03 +00:00
|
|
|
|
2009-01-04 18:52:57 +00:00
|
|
|
strct = strct->Next();
|
|
|
|
}
|
|
|
|
}
|
2009-12-02 21:44:03 +00:00
|
|
|
|
2009-01-04 18:52:57 +00:00
|
|
|
m_currList.Pop();
|
|
|
|
}
|