Commit da9f4b8a authored by Wayne Stambaugh's avatar Wayne Stambaugh

Undo schematic hierarchy path container changes.

* Boost container release method clobbering sheet pointers causing
  seg faults.
parent 3c49fb1e
...@@ -216,8 +216,6 @@ SCH_ITEM* SCH_SCREEN::ExtractWires( bool CreateCopy ) ...@@ -216,8 +216,6 @@ SCH_ITEM* SCH_SCREEN::ExtractWires( bool CreateCopy )
*/ */
bool SCH_SCREEN::SchematicCleanUp( EDA_DRAW_PANEL* aCanvas, wxDC* aDC ) bool SCH_SCREEN::SchematicCleanUp( EDA_DRAW_PANEL* aCanvas, wxDC* aDC )
{ {
wxASSERT( aCanvas != NULL );
SCH_ITEM* DrawList, * TstDrawList; SCH_ITEM* DrawList, * TstDrawList;
bool Modify = FALSE; bool Modify = FALSE;
...@@ -674,11 +672,11 @@ bool SCH_SCREEN::TestDanglingEnds( EDA_DRAW_PANEL* aCanvas, wxDC* aDC ) ...@@ -674,11 +672,11 @@ bool SCH_SCREEN::TestDanglingEnds( EDA_DRAW_PANEL* aCanvas, wxDC* aDC )
{ {
item->Draw( aCanvas, aDC, wxPoint( 0, 0 ), g_XorMode ); item->Draw( aCanvas, aDC, wxPoint( 0, 0 ), g_XorMode );
item->Draw( aCanvas, aDC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE ); item->Draw( aCanvas, aDC, wxPoint( 0, 0 ), GR_DEFAULT_DRAWMODE );
}
if( item->IsDangling() ) if( item->IsDangling() )
hasDanglingEnds = true; hasDanglingEnds = true;
} }
}
return hasDanglingEnds; return hasDanglingEnds;
} }
......
...@@ -65,6 +65,8 @@ SCH_SHEET::SCH_SHEET( const SCH_SHEET& aSheet ) : ...@@ -65,6 +65,8 @@ SCH_SHEET::SCH_SHEET( const SCH_SHEET& aSheet ) :
SCH_SHEET::~SCH_SHEET() SCH_SHEET::~SCH_SHEET()
{ {
wxLogDebug( wxT( "Destroying sheet " ) + m_SheetName );
// also, look at the associated sheet & its reference count // also, look at the associated sheet & its reference count
// perhaps it should be deleted also. // perhaps it should be deleted also.
if( m_AssociatedScreen ) if( m_AssociatedScreen )
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
// Purpose: member functions for SCH_SHEET_PATH // Purpose: member functions for SCH_SHEET_PATH
// header = sch_sheet_path.h // header = sch_sheet_path.h
// Author: jean-pierre Charras // Author: jean-pierre Charras
// Modified by: Wayne Stambaugh // Modified by:
// License: License GNU // License: License GNU
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
...@@ -25,43 +25,44 @@ ...@@ -25,43 +25,44 @@
#include "dialogs/dialog_schematic_find.h" #include "dialogs/dialog_schematic_find.h"
/**********************************************/
/* class to handle a series of sheets *********/
/* a 'path' so to speak.. *********************/
/**********************************************/
SCH_SHEET_PATH::SCH_SHEET_PATH() SCH_SHEET_PATH::SCH_SHEET_PATH()
{ {
} for( int i = 0; i<DSLSZ; i++ )
m_sheets[i] = NULL;
SCH_SHEET_PATH::~SCH_SHEET_PATH()
{
// The sheets are not owned by the sheet path object so don't allow them to be destroyed.
Clear();
}
m_numSheets = 0;
void SCH_SHEET_PATH::Clear()
{
while( !m_sheets.empty() )
m_sheets.pop_back().release();
} }
/**
* Function BuildSheetPathInfoFromSheetPathValue
* Fill this with data to access to the hierarchical sheet known by its path
* aPath
* @param aPath = path of the sheet to reach (in non human readable format)
* @return true if success else false
*/
bool SCH_SHEET_PATH::BuildSheetPathInfoFromSheetPathValue( const wxString& aPath, bool aFound ) bool SCH_SHEET_PATH::BuildSheetPathInfoFromSheetPathValue( const wxString& aPath, bool aFound )
{ {
if( aFound ) if( aFound )
return true; return true;
if( GetSheetCount() == 0 ) if( GetSheetsCount() == 0 )
Push( g_RootSheet ); Push( g_RootSheet );
if( aPath == Path() ) if( aPath == Path() )
return true; return true;
SCH_ITEM* item = LastDrawList(); SCH_ITEM* schitem = LastDrawList();
while( item && GetSheetCount() < NB_MAX_SHEET ) while( schitem && GetSheetsCount() < NB_MAX_SHEET )
{ {
if( item->Type() == SCH_SHEET_T ) if( schitem->Type() == SCH_SHEET_T )
{ {
SCH_SHEET* sheet = (SCH_SHEET*) item; SCH_SHEET* sheet = (SCH_SHEET*) schitem;
Push( sheet ); Push( sheet );
if( aPath == Path() ) if( aPath == Path() )
...@@ -72,29 +73,34 @@ bool SCH_SHEET_PATH::BuildSheetPathInfoFromSheetPathValue( const wxString& aPath ...@@ -72,29 +73,34 @@ bool SCH_SHEET_PATH::BuildSheetPathInfoFromSheetPathValue( const wxString& aPath
Pop(); Pop();
} }
schitem = schitem->Next();
item = item->Next();
} }
return false; return false;
} }
/**
* Function Cmp
* Compare if this is the same sheet path as aSheetPathToTest
* @param aSheetPathToTest = sheet path to compare
* @return -1 if different, 0 if same
*/
int SCH_SHEET_PATH::Cmp( const SCH_SHEET_PATH& aSheetPathToTest ) const int SCH_SHEET_PATH::Cmp( const SCH_SHEET_PATH& aSheetPathToTest ) const
{ {
if( m_sheets.size() > aSheetPathToTest.GetSheetCount() ) if( m_numSheets > aSheetPathToTest.m_numSheets )
return 1; return 1;
if( m_sheets.size() < aSheetPathToTest.GetSheetCount() ) if( m_numSheets < aSheetPathToTest.m_numSheets )
return -1; return -1;
// Same number of sheets, use time stamps. //otherwise, same number of sheets.
for( unsigned i = 0; i < GetSheetCount(); i++ ) for( unsigned i = 0; i<m_numSheets; i++ )
{ {
if( m_sheets[i].m_TimeStamp > aSheetPathToTest.m_sheets[i].m_TimeStamp ) if( m_sheets[i]->m_TimeStamp > aSheetPathToTest.m_sheets[i]->m_TimeStamp )
return 1; return 1;
if( m_sheets[i].m_TimeStamp < aSheetPathToTest.m_sheets[i].m_TimeStamp ) if( m_sheets[i]->m_TimeStamp < aSheetPathToTest.m_sheets[i]->m_TimeStamp )
return -1; return -1;
} }
...@@ -102,15 +108,24 @@ int SCH_SHEET_PATH::Cmp( const SCH_SHEET_PATH& aSheetPathToTest ) const ...@@ -102,15 +108,24 @@ int SCH_SHEET_PATH::Cmp( const SCH_SHEET_PATH& aSheetPathToTest ) const
} }
/**
* Function Last
* returns a pointer to the last sheet of the list
* One can see the others sheet as the "path" to reach this last sheet
*/
SCH_SHEET* SCH_SHEET_PATH::Last() SCH_SHEET* SCH_SHEET_PATH::Last()
{ {
if( !m_sheets.empty() ) if( m_numSheets )
return &m_sheets[ m_sheets.size() - 1 ]; return m_sheets[m_numSheets - 1];
return NULL; return NULL;
} }
/**
* Function LastScreen
* @return the SCH_SCREEN relative to the last sheet in list
*/
SCH_SCREEN* SCH_SHEET_PATH::LastScreen() SCH_SCREEN* SCH_SHEET_PATH::LastScreen()
{ {
SCH_SHEET* lastSheet = Last(); SCH_SHEET* lastSheet = Last();
...@@ -122,12 +137,17 @@ SCH_SCREEN* SCH_SHEET_PATH::LastScreen() ...@@ -122,12 +137,17 @@ SCH_SCREEN* SCH_SHEET_PATH::LastScreen()
} }
/**
* Function LastScreen
* @return a pointer to the first schematic item handled by the
* SCH_SCREEN relative to the last sheet in list
*/
SCH_ITEM* SCH_SHEET_PATH::LastDrawList() SCH_ITEM* SCH_SHEET_PATH::LastDrawList()
{ {
SCH_SCREEN* screen = LastScreen(); SCH_SHEET* lastSheet = Last();
if( screen ) if( lastSheet && lastSheet->GetScreen() )
return screen->GetDrawItems(); return lastSheet->GetScreen()->GetDrawItems();
return NULL; return NULL;
} }
...@@ -137,37 +157,66 @@ SCH_ITEM* SCH_SHEET_PATH::FirstDrawList() ...@@ -137,37 +157,66 @@ SCH_ITEM* SCH_SHEET_PATH::FirstDrawList()
{ {
SCH_ITEM* item = NULL; SCH_ITEM* item = NULL;
if( !m_sheets.empty() && m_sheets[0].GetScreen() ) if( m_numSheets && m_sheets[0]->GetScreen() )
item = m_sheets[0].GetScreen()->GetDrawItems(); item = m_sheets[0]->GetScreen()->GetDrawItems();
/* @fixme - These lists really should be one of the boost pointer containers. This
* is a brain dead hack to allow reverse iteration of EDA_ITEM linked
* list.
*/
SCH_ITEM* lastItem = NULL;
while( item != NULL )
{
lastItem = item;
item = item->Next();
}
return item; return lastItem;
} }
void SCH_SHEET_PATH::Push( SCH_SHEET* aSheet ) void SCH_SHEET_PATH::Push( SCH_SHEET* aSheet )
{ {
if( m_sheets.size() >= MAX_SHEET_PATH_DEPTH ) if( m_numSheets > DSLSZ )
{ {
wxLogWarning( _( "Schematic sheets can only be nested %d levels deep. Not adding sheet %s" ), wxString msg;
MAX_SHEET_PATH_DEPTH, GetChars( aSheet->m_SheetName ) ); msg.Printf( _( "Schematic sheets can only be nested %d levels deep." ), DSLSZ );
return; wxMessageBox( msg );
} }
m_sheets.push_back( aSheet ); if( m_numSheets < DSLSZ )
{
m_sheets[m_numSheets] = aSheet;
m_numSheets++;
}
} }
/**
* Function Pop
* retrieves (pop) the last entered sheet and remove it from list
* @return a SCH_SHEET* pointer to the removed sheet in list
*/
SCH_SHEET* SCH_SHEET_PATH::Pop() SCH_SHEET* SCH_SHEET_PATH::Pop()
{ {
if( m_sheets.empty() ) if( m_numSheets > 0 )
return NULL; {
m_numSheets--;
return m_sheets[m_numSheets];
}
// The sheet must be released from the end of the container otherwise it will be destroyed. return NULL;
return m_sheets.pop_back().release();
} }
wxString SCH_SHEET_PATH::Path() const /**
* 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 SCH_SHEET_PATH::Path()
{ {
wxString s, t; wxString s, t;
...@@ -176,9 +225,9 @@ wxString SCH_SHEET_PATH::Path() const ...@@ -176,9 +225,9 @@ wxString SCH_SHEET_PATH::Path() const
// start at 1 to avoid the root sheet, // start at 1 to avoid the root sheet,
// which does not need to be added to the path // 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 < m_sheets.size(); i++ ) for( unsigned i = 1; i < m_numSheets; i++ )
{ {
t.Printf( _( "%8.8lX/" ), m_sheets[i].m_TimeStamp ); t.Printf( _( "%8.8lX/" ), m_sheets[i]->m_TimeStamp );
s = s + t; s = s + t;
} }
...@@ -186,6 +235,13 @@ wxString SCH_SHEET_PATH::Path() const ...@@ -186,6 +235,13 @@ wxString SCH_SHEET_PATH::Path() const
} }
/**
* 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 SCH_SHEET_PATH::PathHumanReadable() const wxString SCH_SHEET_PATH::PathHumanReadable() const
{ {
wxString s, t; wxString s, t;
...@@ -193,9 +249,9 @@ wxString SCH_SHEET_PATH::PathHumanReadable() const ...@@ -193,9 +249,9 @@ wxString SCH_SHEET_PATH::PathHumanReadable() const
s = wxT( "/" ); s = wxT( "/" );
// start at 1 to avoid the root sheet, as above. // start at 1 to avoid the root sheet, as above.
for( unsigned i = 1; i< m_sheets.size(); i++ ) for( unsigned i = 1; i< m_numSheets; i++ )
{ {
s = s + m_sheets[i].m_SheetName + wxT( "/" ); s = s + m_sheets[i]->m_SheetName + wxT( "/" );
} }
return s; return s;
...@@ -257,12 +313,12 @@ void SCH_SHEET_PATH::AnnotatePowerSymbols( int* aReference ) ...@@ -257,12 +313,12 @@ void SCH_SHEET_PATH::AnnotatePowerSymbols( int* aReference )
} }
void SCH_SHEET_PATH::GetComponents( SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols ) void SCH_SHEET_PATH::GetComponents( SCH_REFERENCE_LIST& aReferences,
bool aIncludePowerSymbols )
{ {
// Search to sheet path number: // Search to sheet path number:
int sheetnumber = 1; // 1 = root int sheetnumber = 1; // 1 = root
SCH_SHEET_LIST sheetList; SCH_SHEET_LIST sheetList;
for( SCH_SHEET_PATH* path = sheetList.GetFirst(); path != NULL; for( SCH_SHEET_PATH* path = sheetList.GetFirst(); path != NULL;
path = sheetList.GetNext(), sheetnumber++ ) path = sheetList.GetNext(), sheetnumber++ )
if( Cmp(*path) == 0 ) if( Cmp(*path) == 0 )
...@@ -360,7 +416,7 @@ SCH_ITEM* SCH_SHEET_PATH::FindPreviousItem( KICAD_T aType, SCH_ITEM* aLastItem, ...@@ -360,7 +416,7 @@ SCH_ITEM* SCH_SHEET_PATH::FindPreviousItem( KICAD_T aType, SCH_ITEM* aLastItem,
SCH_ITEM* SCH_SHEET_PATH::MatchNextItem( wxFindReplaceData& aSearchData, SCH_ITEM* SCH_SHEET_PATH::MatchNextItem( wxFindReplaceData& aSearchData,
SCH_ITEM* aLastItem, SCH_ITEM* aLastItem,
wxPoint* aFindLocation ) wxPoint * aFindLocation )
{ {
bool hasWrapped = false; bool hasWrapped = false;
bool firstItemFound = false; bool firstItemFound = false;
...@@ -392,14 +448,34 @@ SCH_ITEM* SCH_SHEET_PATH::MatchNextItem( wxFindReplaceData& aSearchData, ...@@ -392,14 +448,34 @@ SCH_ITEM* SCH_SHEET_PATH::MatchNextItem( wxFindReplaceData& aSearchData,
} }
bool SCH_SHEET_PATH::operator=( const SCH_SHEET_PATH& d1 )
{
m_numSheets = d1.m_numSheets;
unsigned i;
for( i = 0; i < m_numSheets; i++ )
{
m_sheets[i] = d1.m_sheets[i];
}
for( ; i < DSLSZ; i++ )
{
m_sheets[i] = 0;
}
return true;
}
bool SCH_SHEET_PATH::operator==( const SCH_SHEET_PATH& d1 ) const bool SCH_SHEET_PATH::operator==( const SCH_SHEET_PATH& d1 ) const
{ {
if( m_sheets.size() != d1.m_sheets.size() ) if( m_numSheets != d1.m_numSheets )
return false; return false;
for( unsigned i = 0; i < m_sheets.size(); i++ ) for( unsigned i = 0; i < m_numSheets; i++ )
{ {
if( &m_sheets[i] != &d1.m_sheets[i] ) if( m_sheets[i] != d1.m_sheets[i] )
return false; return false;
} }
...@@ -407,11 +483,38 @@ bool SCH_SHEET_PATH::operator==( const SCH_SHEET_PATH& d1 ) const ...@@ -407,11 +483,38 @@ bool SCH_SHEET_PATH::operator==( const SCH_SHEET_PATH& d1 ) const
} }
bool SCH_SHEET_PATH::operator!=( const SCH_SHEET_PATH& d1 ) const
{
if( m_numSheets != d1.m_numSheets )
return true;
for( unsigned i = 0; i < m_numSheets; i++ )
{
if( m_sheets[i] != d1.m_sheets[i] )
{
/*
printf( "micompare this:'%s' d1:'%s'\n",
CONV_TO_UTF8( PathHumanReadable() ),
CONV_TO_UTF8( d1.PathHumanReadable() ) );
*/
return true;
}
}
return false;
}
/*********************************************************************/ /*********************************************************************/
/* Class SCH_SHEET_LIST to handle the list of Sheets in a hierarchy */ /* Class SCH_SHEET_LIST to handle the list of Sheets in a hierarchy */
/*********************************************************************/ /*********************************************************************/
/* 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.
*/
SCH_SHEET_LIST::SCH_SHEET_LIST( SCH_SHEET* aSheet ) SCH_SHEET_LIST::SCH_SHEET_LIST( SCH_SHEET* aSheet )
{ {
m_index = 0; m_index = 0;
...@@ -425,6 +528,10 @@ SCH_SHEET_LIST::SCH_SHEET_LIST( SCH_SHEET* aSheet ) ...@@ -425,6 +528,10 @@ SCH_SHEET_LIST::SCH_SHEET_LIST( SCH_SHEET* aSheet )
} }
/**
* Function GetFirst
* @return the first item (sheet) in m_List and prepare calls to GetNext()
*/
SCH_SHEET_PATH* SCH_SHEET_LIST::GetFirst() SCH_SHEET_PATH* SCH_SHEET_LIST::GetFirst()
{ {
m_index = 0; m_index = 0;
...@@ -436,6 +543,11 @@ SCH_SHEET_PATH* SCH_SHEET_LIST::GetFirst() ...@@ -436,6 +543,11 @@ SCH_SHEET_PATH* SCH_SHEET_LIST::GetFirst()
} }
/**
* Function GetNext
* @return the next item (sheet) in m_List or NULL if no more item in sheet
* list
*/
SCH_SHEET_PATH* SCH_SHEET_LIST::GetNext() SCH_SHEET_PATH* SCH_SHEET_LIST::GetNext()
{ {
if( m_index < GetCount() ) if( m_index < GetCount() )
...@@ -467,6 +579,12 @@ SCH_SHEET_PATH* SCH_SHEET_LIST::GetPrevious() ...@@ -467,6 +579,12 @@ SCH_SHEET_PATH* SCH_SHEET_LIST::GetPrevious()
} }
/**
* Function GetSheet
* @return the item (sheet) in aIndex position in m_List or NULL if less than
* index items
* @param aIndex = index in sheet list to get the sheet
*/
SCH_SHEET_PATH* SCH_SHEET_LIST::GetSheet( int aIndex ) SCH_SHEET_PATH* SCH_SHEET_LIST::GetSheet( int aIndex )
{ {
if( aIndex < GetCount() ) if( aIndex < GetCount() )
...@@ -476,28 +594,6 @@ SCH_SHEET_PATH* SCH_SHEET_LIST::GetSheet( int aIndex ) ...@@ -476,28 +594,6 @@ SCH_SHEET_PATH* SCH_SHEET_LIST::GetSheet( int aIndex )
} }
bool SCH_SHEET_LIST::IsModified()
{
for( SCH_SHEET_PATH* sheet = GetFirst(); sheet != NULL; sheet = GetNext() )
{
if( sheet->LastScreen() && sheet->LastScreen()->IsModify() )
return true;
}
return false;
}
void SCH_SHEET_LIST::ClearModifyStatus()
{
for( SCH_SHEET_PATH* sheet = GetFirst(); sheet != NULL; sheet = GetNext() )
{
if( sheet->LastScreen() )
sheet->LastScreen()->ClrModify();
}
}
void SCH_SHEET_LIST::BuildSheetList( SCH_SHEET* aSheet ) void SCH_SHEET_LIST::BuildSheetList( SCH_SHEET* aSheet )
{ {
if( m_List == NULL ) if( m_List == NULL )
...@@ -649,7 +745,7 @@ SCH_ITEM* SCH_SHEET_LIST::FindPreviousItem( KICAD_T aType, SCH_SHEET_PATH** aShe ...@@ -649,7 +745,7 @@ SCH_ITEM* SCH_SHEET_LIST::FindPreviousItem( KICAD_T aType, SCH_SHEET_PATH** aShe
SCH_ITEM* SCH_SHEET_LIST::MatchNextItem( wxFindReplaceData& aSearchData, SCH_ITEM* SCH_SHEET_LIST::MatchNextItem( wxFindReplaceData& aSearchData,
SCH_SHEET_PATH** aSheetFoundIn, SCH_SHEET_PATH** aSheetFoundIn,
SCH_ITEM* aLastItem, SCH_ITEM* aLastItem,
wxPoint* aFindLocation ) wxPoint * aFindLocation )
{ {
bool hasWrapped = false; bool hasWrapped = false;
bool firstItemFound = false; bool firstItemFound = false;
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#ifndef CLASS_DRAWSHEET_PATH_H #ifndef CLASS_DRAWSHEET_PATH_H
#define CLASS_DRAWSHEET_PATH_H #define CLASS_DRAWSHEET_PATH_H
#include "sch_sheet.h" #include "base_struct.h"
/** Info about complex hierarchies handling: /** Info about complex hierarchies handling:
* A hierarchical schematic uses sheets (hierarchical sheets) included in a * A hierarchical schematic uses sheets (hierarchical sheets) included in a
...@@ -53,59 +53,72 @@ ...@@ -53,59 +53,72 @@
class wxFindReplaceData; class wxFindReplaceData;
class SCH_SCREEN; class SCH_SCREEN;
class SCH_MARKER; class SCH_MARKER;
class SCH_SHEET;
class SCH_ITEM; class SCH_ITEM;
class SCH_REFERENCE_LIST; class SCH_REFERENCE_LIST;
/** /**
* Class SCH_SHEET_PATH * Class SCH_SHEET_PATH
* handles access to a hierarchical sheet by way of a path. * handles access to a sheet by way of a path.
* <p> * <p>
* The sheets are stored from the first (usually the root sheet) to the last sheet in * The member m_sheets stores the list of sheets from the first (usually
* the hierarchy. The _last_ sheet is usually the sheet used to select or reach the * g_RootSheet) to a given sheet in last position.
* data for the sheet (which is what the function Last() returns). The other sheets * The _last_ sheet is usually the sheet we want to select or reach (which is
* constitute the "path" to the last sheet. * what the function Last() returns).
* Others sheets constitute the "path" from the first to the last sheet.
*/ */
class SCH_SHEET_PATH class SCH_SHEET_PATH
{ {
SCH_SHEETS m_sheets; ///< The list of sheets used to create this sheet path. private:
unsigned m_numSheets;
public: public:
#define MAX_SHEET_PATH_DEPTH 32 // Max number of levels for a sheet path #define DSLSZ 32 // Max number of levels for a sheet path
SCH_SHEET* m_sheets[DSLSZ];
public:
SCH_SHEET_PATH(); SCH_SHEET_PATH();
// ~SCH_SHEET_PATH() { };
~SCH_SHEET_PATH(); void Clear()
{
m_numSheets = 0;
}
void Clear();
unsigned GetSheetCount() const { return m_sheets.size(); } unsigned GetSheetsCount()
{
return m_numSheets;
}
/** /**
* Function Cmp * Function Cmp
* compares if the sheet path is the same as the sheet path of \a aSheetPathToTest * Compare if this is the same sheet path as aSheetPathToTest
* @param aSheetPathToTest Sheet path to compare. * @param aSheetPathToTest = sheet path to compare
* @return -1 is less than, 0 if same as, or 1 if greater than. * @return -1 if different, 0 if same
*/ */
int Cmp( const SCH_SHEET_PATH& aSheetPathToTest ) const; int Cmp( const SCH_SHEET_PATH& aSheetPathToTest ) const;
/** /**
* Function Last * Function Last
* returns a pointer to the last sheet of the list. * returns a pointer to the last sheet of the list
* One can see the others sheet as the "path" to reach this last sheet. * One can see the others sheet as the "path" to reach this last sheet
*/ */
SCH_SHEET* Last(); SCH_SHEET* Last();
/** /**
* Function LastScreen * Function LastScreen
* @return The SCH_SCREEN relative to the last sheet in the hierarchy. * @return the SCH_SCREEN relative to the last sheet in list
*/ */
SCH_SCREEN* LastScreen(); SCH_SCREEN* LastScreen();
/** /**
* Function LastDrawItem * Function LastScreen
* @return The first item in the draw list of the screen associated with the last * @return a pointer to the first schematic item handled by the
* sheet in the hierarchy. * SCH_SCREEN relative to the last sheet in list
*/ */
SCH_ITEM* LastDrawList(); SCH_ITEM* LastDrawList();
...@@ -119,54 +132,57 @@ public: ...@@ -119,54 +132,57 @@ public:
/** /**
* Function Push * Function Push
* adds \a aSheet to the end of the hierarchy. * store (push) aSheet in list
* @param aSheet The SCH_SHEET to store in the hierarchy. * @param aSheet = pointer to the SCH_SHEET to store in list
* Push is used to enter a sheet to select or analyze it. This is like using * Push is used when entered a sheet to select or analyze it
* cd &ltdirectory&gt to navigate a directory. * This is like cd &ltdirectory&gt in directories navigation
*/ */
void Push( SCH_SHEET* aSheet ); void Push( SCH_SHEET* aSheet );
/** /**
* Function Pop * Function Pop
* removes and returns the last sheet in the hierarchy. * retrieves (pop) the last entered sheet and remove it from list
* @return The last in the hierarchy or NULL if there are no sheets in the hierarchy. * @return a SCH_SHEET* pointer to the removed sheet in list
* <p> * Pop is used when leaving a sheet after a selection or analyze
* Pop is used when leaving a sheet after a has been selected or analyzed. This is * This is like cd .. in directories navigation
* like using cd .. to navigate a directory.
*/ */
SCH_SHEET* Pop(); SCH_SHEET* Pop();
/** /**
* Function Path * Function Path
* returns the path using the time stamps which do not changes even when editing * the path uses the time stamps which do not changes even when editing
* sheet parameters. * sheet parameters
* Sample paths include / (root) or /34005677 or /34005677/00AE4523 * a path is something like / (root) or /34005677 or /34005677/00AE4523
*/ */
wxString Path() const; wxString Path();
/** /**
* Function PathHumanReadable * Function PathHumanReadable
* returns the sheet path in a human readable form, i.e. as a path made from sheet * returns the sheet path in a human readable form, i.e. as a path made
* names. This is the "normal" path instead of the path that uses the time stamps * from sheet names. The the "normal" path instead uses the time
* in the path. Time stamps do not change even when the sheet name is changed. * stamps in the path. (Time stamps do not change even when editing
* sheet parameters).
*/ */
wxString PathHumanReadable() const; wxString PathHumanReadable() const;
/** /**
* Function BuildSheetPathInfoFromSheetPathValue * Function BuildSheetPathInfoFromSheetPathValue
* creates the hierarchy to access the sheet known by \a aPath. * Fill this with data to access to the hierarchical sheet known by its path \a aPath
* @param aPath = path of the sheet to reach (in non human readable format) * @param aPath = path of the sheet to reach (in non human readable format)
* @param aFound - Please document me. * @param aFound - Please document me.
* @return true if success else false * @return true if success else false
*/ */
bool BuildSheetPathInfoFromSheetPathValue( const wxString& aPath, bool aFound = false ); bool BuildSheetPathInfoFromSheetPathValue( const wxString& aPath,
bool aFound = false );
/** /**
* Function UpdateAllScreenReferences * Function UpdateAllScreenReferences
* updates the reference and the part selection parameter for all components with * updates the reference and the m_Multi parameter (part selection) for all
* multiple parts on a screen depending on the actual sheet path. This is required * components on a screen depending on the actual sheet path.
* in complex hierarchies because sheets use the same screen with different references * Mandatory in complex hierarchies because sheets use the same screen
* and part selections according to the displayed sheet. * (basic schematic)
* but with different references and part selections according to the
* displayed sheet
*/ */
void UpdateAllScreenReferences(); void UpdateAllScreenReferences();
...@@ -190,61 +206,56 @@ public: ...@@ -190,61 +206,56 @@ public:
bool aIncludePowerSymbols = true ); bool aIncludePowerSymbols = true );
/** /**
* Function FindNextItem * Find the next schematic item in this sheet ojbect.
* searches for the next schematic item of \a aType in the hierarchy.
* *
* @param aType The type of schematic item object to search for. * @param aType - The type of schematic item object to search for.
* @param aLastItem Start search from aLastItem. If no aLastItem, search from * @param aLastItem - Start search from aLastItem. If no aLastItem, search from
* the beginning of the list. * the beginning of the list.
* @param aWrap Wrap around the end of the list to find the next item if aLastItem * @param aWrap - Wrap around the end of the list to find the next item if aLastItem
* is defined. * is defined.
* @return The next schematic item if found. Otherwise, NULL is returned. * @return - The next schematic item if found. Otherwise, NULL is returned.
*/ */
SCH_ITEM* FindNextItem( KICAD_T aType, SCH_ITEM* aLastItem = NULL, bool aWrap = false ); SCH_ITEM* FindNextItem( KICAD_T aType, SCH_ITEM* aLastItem = NULL, bool aWrap = false );
/** /**
* Fucntion FindPreviousItem * Find the previous schematic item in this sheet path object.
* searched for the previous schematic item of \a aType in the hierarchy.
* *
* @param aType The type of schematic item object to search for. * @param aType - The type of schematic item object to search for.
* @param aLastItem Start search from aLastItem. If no aLastItem, search from * @param aLastItem - Start search from aLastItem. If no aLastItem, search from
* the end of the list. * the end of the list.
* @param aWrap Wrap around the beginning of the list to find the next item if aLastItem * @param aWrap - Wrap around the beginning of the list to find the next item if aLastItem
* is defined. * is defined.
* @return The previous schematic item if found. Otherwise, NULL is returned. * @return - The previous schematic item if found. Otherwise, NULL is returned.
*/ */
SCH_ITEM* FindPreviousItem( KICAD_T aType, SCH_ITEM* aLastItem = NULL, bool aWrap = false ); SCH_ITEM* FindPreviousItem( KICAD_T aType, SCH_ITEM* aLastItem = NULL, bool aWrap = false );
/** /**
* Funnction MatchNextItem * Search this sheet path for the next item that matches the search criteria.
* searches the hierarchy for the next item that matches the search criteria
* \a aSeaechDate.
* *
* @param aSearchData Criteria to search item against. * @param aSearchData - Criteria to search item against.
* @param aLastItem Find next item after aLastItem if not NULL. * @param aLastItem - Find next item after aLastItem if not NULL.
* @param aFindLocation The location where to put the location of matched item. Can be NULL. * @param aFindLocation - a wxPoint where to put the location of matched item. can be NULL.
* @return The next schematic item if found. Otherwise, returns NULL. * @return If found, Returns the next schematic item. Otherwise, returns NULL.
*/ */
SCH_ITEM* MatchNextItem( wxFindReplaceData& aSearchData, SCH_ITEM* aLastItem, SCH_ITEM* MatchNextItem( wxFindReplaceData& aSearchData, SCH_ITEM* aLastItem,
wxPoint* aFindLocation ); wxPoint * aFindLocation );
bool operator=( const SCH_SHEET_PATH& d1 );
bool operator==( const SCH_SHEET_PATH& d1 ) const; bool operator==( const SCH_SHEET_PATH& d1 ) const;
bool operator!=( const SCH_SHEET_PATH& d1 ) const { return !( *this == d1 ); } bool operator!=( const SCH_SHEET_PATH& d1 ) const;
}; };
/** /**
* Class SCH_SHEET_LIST * Class SCH_SHEET_LIST
* handles a list of hierarchies. * handles the list of Sheets in a hierarchy.
* <p> * Sheets are not unique, there can be many sheets with the same
* Sheets may not be unique. There can be many sheets that share the same file name and * filename and the same SCH_SCREEN reference.
* SCH_SCREEN reference. When a file is shared between sheets the component references * The schematic (SCH_SCREEN) is shared between these sheets,
* are specific to where the sheet is in the hierarchy. When a sheet is entered, the * and component references are specific to a sheet path.
* component references and sheet number in the screen are updated to reflect the sheet * When a sheet is entered, component references and sheet number are updated.
* path. If the hierarchy is created with the root sheet, the hierarchy represents the
* entire schematic.
* </p>
*/ */
class SCH_SHEET_LIST class SCH_SHEET_LIST
{ {
...@@ -282,34 +293,35 @@ public: ...@@ -282,34 +293,35 @@ public:
/** /**
* Function GetCount * Function GetCount
* @return The number of sheets in the hierarchy. * @return the number of sheets in list:
* usually the number of sheets found in the whole hierarchy * usually the number of sheets found in the whole hierarchy
*/ */
int GetCount() { return m_count; } int GetCount() { return m_count; }
/** /**
* Function GetFirst * Function GetFirst
* @return The first hierarchical path and prepare for calls to GetNext(). * @return the first item (sheet) in m_List and prepare calls to GetNext()
*/ */
SCH_SHEET_PATH* GetFirst(); SCH_SHEET_PATH* GetFirst();
/** /**
* Function GetNext * Function GetNext
* @return The next hierarchical path or NULL if the end of the list. * @return the next item (sheet) in m_List or NULL if no more item in
* sheet list
*/ */
SCH_SHEET_PATH* GetNext(); SCH_SHEET_PATH* GetNext();
/** /**
* Function GetLast * Function GetLast
* returns the last sheet in the hierarchy. * returns the last sheet in the sheet list.
* *
* @return Last sheet in the hierarchy or NULL if the hierarchy is empty. * @return Last sheet in the list or NULL if sheet list is empty.
*/ */
SCH_SHEET_PATH* GetLast(); SCH_SHEET_PATH* GetLast();
/** /**
* Function GetPrevious * Function GetPrevious
* returns the previous sheet in the hierarchy. * returns the previous sheet in the sheet list.
* *
* @return The previous sheet in the sheet list or NULL if already at the * @return The previous sheet in the sheet list or NULL if already at the
* beginning of the list. * beginning of the list.
...@@ -318,23 +330,15 @@ public: ...@@ -318,23 +330,15 @@ public:
/** /**
* Function GetSheet * Function GetSheet
* @return The hierarchy at \a aIndex position or NULL if \a aIndex is out of range. * @return the item (sheet) in aIndex position in m_List or NULL if less
* @param aIndex Index in the list of hierarchies. * than index items
* @param aIndex = index in sheet list to get the sheet
*/ */
SCH_SHEET_PATH* GetSheet( int aIndex ); SCH_SHEET_PATH* GetSheet( int aIndex );
/**
* Function IsModified
* checks the entire hierachy for any modifications.
* @returns True if the hierarchy is modified otherwise false.
*/
bool IsModified();
void ClearModifyStatus();
/** /**
* Function AnnotatePowerSymbols * Function AnnotatePowerSymbols
* clear and annotate the entire hierarchy of the sheet path list. * clear and annotates the entire hierarchy of the sheet path list.
*/ */
void AnnotatePowerSymbols(); void AnnotatePowerSymbols();
...@@ -352,11 +356,11 @@ public: ...@@ -352,11 +356,11 @@ public:
* Function FindNextItem * Function FindNextItem
* searches the entire schematic for the next schematic object. * searches the entire schematic for the next schematic object.
* *
* @param aType The type of schematic item to find. * @param aType - The type of schematic item to find.
* @param aSheetFound The sheet the item was found in. NULL if the next item * @param aSheetFound - The sheet the item was found in. NULL if the next item
* is not found. * is not found.
* @param aLastItem Find next item after aLastItem if not NULL. * @param aLastItem - Find next item after aLastItem if not NULL.
* @param aWrap Wrap past around the end of the list of sheets. * @param aWrap - Wrap past around the end of the list of sheets.
* @return If found, Returns the next schematic item. Otherwise, returns NULL. * @return If found, Returns the next schematic item. Otherwise, returns NULL.
*/ */
SCH_ITEM* FindNextItem( KICAD_T aType, SCH_SHEET_PATH** aSheetFound = NULL, SCH_ITEM* FindNextItem( KICAD_T aType, SCH_SHEET_PATH** aSheetFound = NULL,
...@@ -366,11 +370,11 @@ public: ...@@ -366,11 +370,11 @@ public:
* Function FindPreviousItem * Function FindPreviousItem
* searches the entire schematic for the previous schematic item. * searches the entire schematic for the previous schematic item.
* *
* @param aType The type of schematic item to find. * @param aType - The type of schematic item to find.
* @param aSheetFound The sheet the item was found in. NULL if the previous item * @param aSheetFound - The sheet the item was found in. NULL if the previous item
* is not found. * is not found.
* @param aLastItem Find the previous item before aLastItem if not NULL. * @param aLastItem - Find the previous item before aLastItem if not NULL.
* @param aWrap Wrap past around the beginning of the list of sheets. * @param aWrap - Wrap past around the beginning of the list of sheets.
* @return If found, the previous schematic item. Otherwise, NULL. * @return If found, the previous schematic item. Otherwise, NULL.
*/ */
SCH_ITEM* FindPreviousItem( KICAD_T aType, SCH_SHEET_PATH** aSheetFound = NULL, SCH_ITEM* FindPreviousItem( KICAD_T aType, SCH_SHEET_PATH** aSheetFound = NULL,
...@@ -380,27 +384,27 @@ public: ...@@ -380,27 +384,27 @@ public:
* Function MatchNextItem * Function MatchNextItem
* searches the entire schematic for the next item that matches the search criteria. * searches the entire schematic for the next item that matches the search criteria.
* *
* @param aSearchData Criteria to search item against. * @param aSearchData - Criteria to search item against.
* @param aSheetFound The sheet the item was found in. NULL if the next item * @param aSheetFound - The sheet the item was found in. NULL if the next item
* is not found. * is not found.
* @param aLastItem Find next item after aLastItem if not NULL. * @param aLastItem - Find next item after aLastItem if not NULL.
* @param aFindLocation a wxPoint where to put the location of matched item. can be NULL. * @param aFindLocation - a wxPoint where to put the location of matched item. can be NULL.
* @return If found, Returns the next schematic item. Otherwise, returns NULL. * @return If found, Returns the next schematic item. Otherwise, returns NULL.
*/ */
SCH_ITEM* MatchNextItem( wxFindReplaceData& aSearchData, SCH_ITEM* MatchNextItem( wxFindReplaceData& aSearchData,
SCH_SHEET_PATH** aSheetFound, SCH_SHEET_PATH** aSheetFound,
SCH_ITEM* aLastItem, SCH_ITEM* aLastItem,
wxPoint* aFindLocation ); wxPoint * aFindLocation );
private: private:
/** /**
* Function BuildSheetList * Function BuildSheetList
* builds the list of sheets and their sheet path from \a aSheet. If \a aSheet is * builds the list of sheets and their sheet path from \a aSheet.
* the root sheet, the full sheet path and sheet list is built. * If aSheet = g_RootSheet, the full sheet path and sheet list is built
* *
* @param aSheet The starting sheet from which the list is built, or NULL indicating * @param aSheet is the starting sheet from which the list is built,
* that the root sheet should be used. * or NULL indicating that g_RootSheet should be used.
*/ */
void BuildSheetList( SCH_SHEET* aSheet ); void BuildSheetList( SCH_SHEET* aSheet );
}; };
......
...@@ -346,12 +346,23 @@ void SCH_EDIT_FRAME::CreateScreens() ...@@ -346,12 +346,23 @@ void SCH_EDIT_FRAME::CreateScreens()
void SCH_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event ) void SCH_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
{ {
if( m_LibeditFrame && !m_LibeditFrame->Close() ) // Can close component editor? SCH_SHEET_PATH* sheet;
if( m_LibeditFrame ) // Can close component editor ?
{
if( !m_LibeditFrame->Close() )
return; return;
}
SCH_SHEET_LIST SheetList; SCH_SHEET_LIST SheetList;
if( SheetList.IsModified() ) for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() )
{
if( sheet->LastScreen() && sheet->LastScreen()->IsModify() )
break;
}
if( sheet )
{ {
wxMessageDialog dialog( this, wxMessageDialog dialog( this,
_( "Schematic modified, Save before exit ?" ), _( "Schematic modified, Save before exit ?" ),
...@@ -374,7 +385,15 @@ void SCH_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event ) ...@@ -374,7 +385,15 @@ void SCH_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
} }
} }
SheetList.ClearModifyStatus(); for( sheet = SheetList.GetFirst();
sheet != NULL;
sheet = SheetList.GetNext() )
{
if( sheet->LastScreen() )
{
sheet->LastScreen()->ClrModify();
}
}
if( !g_RootSheet->GetScreen()->GetFileName().IsEmpty() if( !g_RootSheet->GetScreen()->GetFileName().IsEmpty()
&& (g_RootSheet->GetScreen()->GetDrawItems() != NULL) ) && (g_RootSheet->GetScreen()->GetDrawItems() != NULL) )
......
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