Commit df344195 authored by Wayne Stambaugh's avatar Wayne Stambaugh
Browse files

Schematic hierarchy path object improvements.

* Use Boost pointer container for sheet hierarchy object.
* Add test for modification in sheet hierarchy list object.
* Add method to clear modification flag in sheet hierarchy list object.
* Improve Doxygen comments for sheet hierarchy list object.
* Remove redundant definitions in prototypes header file.
parent 495f2a04
Loading
Loading
Loading
Loading
+17 −28
Original line number Original line Diff line number Diff line
@@ -2,29 +2,19 @@
#ifndef __PROTOS_H__
#ifndef __PROTOS_H__
#define __PROTOS_H__
#define __PROTOS_H__


#include "block_commande.h"
#include "colors.h"
#include "colors.h"
#include "sch_sheet_path.h"


#include <wx/wx.h>



class EDA_ITEM;
class EDA_DRAW_PANEL;
class EDA_DRAW_PANEL;
class EDA_DRAW_FRAME;
class EDA_DRAW_FRAME;
class SCH_EDIT_FRAME;
class SCH_EDIT_FRAME;
class LIB_EDIT_FRAME;
class LIB_EDIT_FRAME;
class CMP_LIBRARY;
class CMP_LIBRARY;
class LIB_COMPONENT;
class LIB_DRAW_ITEM;
class SCH_COMPONENT;
class SCH_COMPONENT;
class SCH_SCREEN;
class SCH_SCREEN;
class SCH_ITEM;
class SCH_ITEM;
class SCH_SHEET_PIN;
class PLOTTER;
class PLOTTER;
class SCH_SHEET;
class SCH_SHEET;
class LIB_PIN;
class LABEL_OBJECT;
class NETLIST_OBJECT;
class NETLIST_OBJECT;




@@ -57,6 +47,7 @@ void SnapLibItemPoint( int OrigX,
                       int*           ClosestX,
                       int*           ClosestX,
                       int*           ClosestY,
                       int*           ClosestY,
                       SCH_COMPONENT* DrawLibItem );
                       SCH_COMPONENT* DrawLibItem );

bool LibItemInBox( int x1, int y1, int x2, int y2, SCH_COMPONENT* DrawLibItem );
bool LibItemInBox( int x1, int y1, int x2, int y2, SCH_COMPONENT* DrawLibItem );


/************/
/************/
@@ -203,9 +194,7 @@ CMP_LIBRARY* SelectLibraryFromList( EDA_DRAW_FRAME* frame );
 *   0 if canceled order
 *   0 if canceled order
 * Place the name of the selected component list in BufName
 * Place the name of the selected component list in BufName
 */
 */
int            GetNameOfPartToLoad( EDA_DRAW_FRAME* frame,
int GetNameOfPartToLoad( EDA_DRAW_FRAME* frame, CMP_LIBRARY* Lib, wxString& BufName );
                                    CMP_LIBRARY*    Lib,
                                    wxString&       BufName );


/**************/
/**************/
/* LIBARCH.CPP */
/* LIBARCH.CPP */
+3 −0
Original line number Original line Diff line number Diff line
@@ -530,4 +530,7 @@ private:
    virtual EDA_ITEM* doClone() const;
    virtual EDA_ITEM* doClone() const;
};
};



typedef boost::ptr_vector< SCH_SHEET > SCH_SHEETS;

#endif /* CLASS_DRAWSHEET_H */
#endif /* CLASS_DRAWSHEET_H */
+78 −174
Original line number Original line Diff line number Diff line
@@ -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:
// Modified by: Wayne Stambaugh
// License:     License GNU
// License:     License GNU
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////


@@ -25,44 +25,43 @@
#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;



    m_numSheets = 0;
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();
}


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(  GetSheetsCount() == 0 )
    if( GetSheetCount() == 0 )
        Push( g_RootSheet );
        Push( g_RootSheet );


    if( aPath == Path() )
    if( aPath == Path() )
        return true;
        return true;


    SCH_ITEM* schitem = LastDrawList();
    SCH_ITEM* item = LastDrawList();


    while( schitem && GetSheetsCount() < NB_MAX_SHEET )
    while( item && GetSheetCount() < NB_MAX_SHEET )
    {
    {
        if( schitem->Type() == SCH_SHEET_T )
        if( item->Type() == SCH_SHEET_T )
        {
        {
            SCH_SHEET* sheet = (SCH_SHEET*) schitem;
            SCH_SHEET* sheet = (SCH_SHEET*) item;
            Push( sheet );
            Push( sheet );


            if( aPath == Path() )
            if( aPath == Path() )
@@ -73,34 +72,29 @@ 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_numSheets > aSheetPathToTest.m_numSheets )
    if( m_sheets.size() > aSheetPathToTest.GetSheetCount() )
        return 1;
        return 1;


    if( m_numSheets < aSheetPathToTest.m_numSheets )
    if( m_sheets.size() < aSheetPathToTest.GetSheetCount() )
        return -1;
        return -1;


    //otherwise, same number of sheets.
    // Same number of sheets, use time stamps.
    for( unsigned i = 0; i<m_numSheets; i++ )
    for( unsigned i = 0; i < GetSheetCount(); 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;
    }
    }


@@ -108,24 +102,15 @@ 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_numSheets )
    if( !m_sheets.empty() )
        return m_sheets[m_numSheets - 1];
        return &m_sheets[ m_sheets.size() - 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();
@@ -137,17 +122,12 @@ 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_SHEET* lastSheet = Last();
    SCH_SCREEN* screen = LastScreen();


    if( lastSheet && lastSheet->GetScreen() )
    if( screen )
        return lastSheet->GetScreen()->GetDrawItems();
        return screen->GetDrawItems();


    return NULL;
    return NULL;
}
}
@@ -157,66 +137,37 @@ SCH_ITEM* SCH_SHEET_PATH::FirstDrawList()
{
{
    SCH_ITEM* item = NULL;
    SCH_ITEM* item = NULL;


    if( m_numSheets && m_sheets[0]->GetScreen() )
    if( !m_sheets.empty() && 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 lastItem;
    return item;
}
}




void SCH_SHEET_PATH::Push( SCH_SHEET* aSheet )
void SCH_SHEET_PATH::Push( SCH_SHEET* aSheet )
{
{
    if( m_numSheets > DSLSZ )
    if( m_sheets.size() >= MAX_SHEET_PATH_DEPTH )
    {
    {
        wxString msg;
        wxLogWarning( _( "Schematic sheets can only be nested %d levels deep.  Not adding sheet %s" ),
        msg.Printf( _( "Schematic sheets can only be nested %d levels deep." ), DSLSZ );
                      MAX_SHEET_PATH_DEPTH, GetChars( aSheet->m_SheetName ) );
        wxMessageBox( msg );
        return;
    }
    }


    if( m_numSheets < DSLSZ )
    m_sheets.push_back( aSheet );
    {
        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_numSheets > 0 )
    if( m_sheets.empty() )
    {
        m_numSheets--;
        return m_sheets[m_numSheets];
    }

        return NULL;
        return NULL;

    // The sheet must be released from the end of the container otherwise it will be destroyed.
    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;


@@ -225,9 +176,9 @@ wxString SCH_SHEET_PATH::Path()
    // 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_numSheets; i++ )
    for( unsigned i = 1; i < m_sheets.size(); 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;
    }
    }


@@ -235,13 +186,6 @@ wxString SCH_SHEET_PATH::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 SCH_SHEET_PATH::PathHumanReadable() const
wxString SCH_SHEET_PATH::PathHumanReadable() const
{
{
    wxString s, t;
    wxString s, t;
@@ -249,9 +193,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_numSheets; i++ )
    for( unsigned i = 1; i< m_sheets.size(); i++ )
    {
    {
        s = s + m_sheets[i]->m_SheetName + wxT( "/" );
        s = s + m_sheets[i].m_SheetName + wxT( "/" );
    }
    }


    return s;
    return s;
@@ -313,12 +257,12 @@ void SCH_SHEET_PATH::AnnotatePowerSymbols( int* aReference )
}
}




void SCH_SHEET_PATH::GetComponents( SCH_REFERENCE_LIST& aReferences,
void SCH_SHEET_PATH::GetComponents( SCH_REFERENCE_LIST& aReferences, bool aIncludePowerSymbols )
                                    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 )
@@ -448,34 +392,14 @@ 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_numSheets != d1.m_numSheets )
    if( m_sheets.size() != d1.m_sheets.size() )
        return false;
        return false;


    for( unsigned i = 0; i < m_numSheets; i++ )
    for( unsigned i = 0; i < m_sheets.size(); i++ )
    {
    {
        if( m_sheets[i] != d1.m_sheets[i] )
        if( &m_sheets[i] != &d1.m_sheets[i] )
            return false;
            return false;
    }
    }


@@ -483,38 +407,11 @@ 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;
@@ -528,10 +425,6 @@ 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;
@@ -543,11 +436,6 @@ 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() )
@@ -579,12 +467,6 @@ 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() )
@@ -594,6 +476,28 @@ 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 )
+122 −126

File changed.

Preview size limit exceeded, changes collapsed.

+4 −23
Original line number Original line Diff line number Diff line
@@ -346,23 +346,12 @@ void SCH_EDIT_FRAME::CreateScreens()


void SCH_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
void SCH_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
{
{
    SCH_SHEET_PATH* sheet;
    if( m_LibeditFrame && !m_LibeditFrame->Close() )   // Can close component editor?

    if( m_LibeditFrame ) // Can close component editor ?
    {
        if( !m_LibeditFrame->Close() )
        return;
        return;
    }


    SCH_SHEET_LIST SheetList;
    SCH_SHEET_LIST SheetList;


    for( sheet = SheetList.GetFirst(); sheet != NULL; sheet = SheetList.GetNext() )
    if( SheetList.IsModified() )
    {
        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 ?" ),
@@ -385,15 +374,7 @@ void SCH_EDIT_FRAME::OnCloseWindow( wxCloseEvent& Event )
        }
        }
    }
    }


    for( sheet = SheetList.GetFirst();
    SheetList.ClearModifyStatus();
        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) )