Eeschema: fix incorrect references clearing for shared sheet paths.
Previously, when creating a new instance of a sheet, the full set of references was cleared. Moreover, if this sheet has sub-sheets, the annotation was incorrectly handled Now only (and all) new sheet path(s) created have a reference cleared, as expected. (new sheet paths can be more than one, if the new instance of the sheet has sub-sheets) Fixes: lp:1789048 https://bugs.launchpad.net/kicad/+bug/1789048
This commit is contained in:
parent
e29e7ff95d
commit
500abd0ac4
|
@ -1111,6 +1111,32 @@ void SCH_COMPONENT::ClearAnnotation( SCH_SHEET_PATH* aSheetPath )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_COMPONENT::AddSheetPathReferenceEntry( const wxString& aSheetPathName )
|
||||||
|
{
|
||||||
|
if( aSheetPathName.IsEmpty() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
wxString reference_path;
|
||||||
|
|
||||||
|
// The full component reference path is aSheetPathName + the component time stamp itself
|
||||||
|
// full_AR_path is the alternate reference path to search
|
||||||
|
wxString full_AR_path = aSheetPathName + wxString::Format( "%8.8X", GetTimeStamp() );
|
||||||
|
|
||||||
|
for( unsigned int ii = 0; ii < m_PathsAndReferences.GetCount(); ii++ )
|
||||||
|
{
|
||||||
|
// Break hierarchical reference in path, ref and multi selection:
|
||||||
|
reference_path = m_PathsAndReferences[ii].BeforeFirst( ' ' );
|
||||||
|
|
||||||
|
// if aSheetPath is found, nothing to do:
|
||||||
|
if( reference_path.Cmp( full_AR_path ) == 0 )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This entry does not exist: add it, with a (temporary?) reference (last ref used for display)
|
||||||
|
AddHierarchicalReference( full_AR_path, m_Fields[REFERENCE].GetText(), m_unit );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_COMPONENT::SetOrientation( int aOrientation )
|
void SCH_COMPONENT::SetOrientation( int aOrientation )
|
||||||
{
|
{
|
||||||
TRANSFORM temp = TRANSFORM();
|
TRANSFORM temp = TRANSFORM();
|
||||||
|
|
|
@ -299,6 +299,16 @@ public:
|
||||||
*/
|
*/
|
||||||
void ClearAnnotation( SCH_SHEET_PATH* aSheetPath );
|
void ClearAnnotation( SCH_SHEET_PATH* aSheetPath );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add aSheetPath in m_PathsAndReferences alternate references list,
|
||||||
|
* if this entry does not exist
|
||||||
|
* Do nothing if already exists.
|
||||||
|
* In component lists shared by more than one sheet path, an entry for each
|
||||||
|
* sheet path must exist to manage references
|
||||||
|
* @param aSheetPathName is the candidate sheet path name
|
||||||
|
*/
|
||||||
|
void AddSheetPathReferenceEntry( const wxString& aSheetPathName );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Change the time stamp to \a aNewTimeStamp and updates the reference path.
|
* Change the time stamp to \a aNewTimeStamp and updates the reference path.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1402,13 +1402,19 @@ void SCH_EDIT_FRAME::addCurrentItemToList( bool aRedraw )
|
||||||
|
|
||||||
if( item->IsNew() )
|
if( item->IsNew() )
|
||||||
{
|
{
|
||||||
|
// When a new sheet is added to the hierarchy, a clear annotation can be needed
|
||||||
|
// for all new sheet paths added by the new sheet (if this sheet is loaded from
|
||||||
|
// and existing sheet or a existing file, it can also contain subsheets)
|
||||||
|
bool doClearAnnotation = false;
|
||||||
|
SCH_SHEET_LIST initial_sheetpathList( g_RootSheet );
|
||||||
|
|
||||||
if( item->Type() == SCH_SHEET_T )
|
if( item->Type() == SCH_SHEET_T )
|
||||||
{
|
{
|
||||||
// Fix the size and position of the new sheet using the last values set by
|
// Fix the size and position of the new sheet using the last values set by
|
||||||
// the m_mouseCaptureCallback function.
|
// the m_mouseCaptureCallback function.
|
||||||
m_canvas->SetMouseCapture( NULL, NULL );
|
m_canvas->SetMouseCapture( NULL, NULL );
|
||||||
|
|
||||||
if( !EditSheet( (SCH_SHEET*)item, m_CurrentSheet ) )
|
if( !EditSheet( (SCH_SHEET*)item, m_CurrentSheet, &doClearAnnotation ) )
|
||||||
{
|
{
|
||||||
screen->SetCurItem( NULL );
|
screen->SetCurItem( NULL );
|
||||||
delete item;
|
delete item;
|
||||||
|
@ -1446,6 +1452,14 @@ void SCH_EDIT_FRAME::addCurrentItemToList( bool aRedraw )
|
||||||
wxLogMessage( wxT( "addCurrentItemToList: expected type = SCH_SHEET_PIN_T, actual type = %d" ),
|
wxLogMessage( wxT( "addCurrentItemToList: expected type = SCH_SHEET_PIN_T, actual type = %d" ),
|
||||||
item->Type() );
|
item->Type() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( doClearAnnotation )
|
||||||
|
{
|
||||||
|
// Clear annotation of new sheet paths: the new sheet and its sub-sheets
|
||||||
|
// If needed the missing alternate references of components will be created
|
||||||
|
SCH_SCREENS screensList( g_RootSheet );
|
||||||
|
screensList.ClearAnnotationOfNewSheetPaths( initial_sheetpathList );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -1111,8 +1111,15 @@ public:
|
||||||
* the current associated screen file name is changed and saved to disk.
|
* the current associated screen file name is changed and saved to disk.
|
||||||
*
|
*
|
||||||
* Note: the screen is not refresh. The caller is responsible to do that
|
* Note: the screen is not refresh. The caller is responsible to do that
|
||||||
|
*
|
||||||
|
* @param aSheet is the sheet to edit
|
||||||
|
* @param aHierarchy is the current hierarchy containing aSheet
|
||||||
|
* @param aClearAnnotationNewItems is a reference to a bool to know if the items managed by
|
||||||
|
* this sheet need to have their annotation cleared i.e. when an existing item list is used.
|
||||||
|
* it can happens when the edited sheet used an existying file, or becomes a new instance
|
||||||
|
* of a already existing sheet.
|
||||||
*/
|
*/
|
||||||
bool EditSheet( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy );
|
bool EditSheet( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy, bool* aClearAnnotationNewItems );
|
||||||
|
|
||||||
wxPoint GetLastSheetPinPosition() const { return m_lastSheetPinPosition; }
|
wxPoint GetLastSheetPinPosition() const { return m_lastSheetPinPosition; }
|
||||||
|
|
||||||
|
|
|
@ -734,6 +734,24 @@ void SCH_SCREEN::ClearAnnotation( SCH_SHEET_PATH* aSheetPath )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_SCREEN::EnsureAlternateReferencesExist()
|
||||||
|
{
|
||||||
|
if( GetClientSheetPathsCount() <= 1 ) // No need for alternate reference
|
||||||
|
return;
|
||||||
|
|
||||||
|
for( SCH_ITEM* item = m_drawList.begin(); item; item = item->Next() )
|
||||||
|
{
|
||||||
|
if( item->Type() != SCH_COMPONENT_T )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Add (when not existing) all sheet path entries
|
||||||
|
for( unsigned int ii = 0; ii < m_clientSheetPathList.GetCount(); ii++ )
|
||||||
|
((SCH_COMPONENT*)item)->AddSheetPathReferenceEntry( m_clientSheetPathList[ii] );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void SCH_SCREEN::GetHierarchicalItems( EDA_ITEMS& aItems )
|
void SCH_SCREEN::GetHierarchicalItems( EDA_ITEMS& aItems )
|
||||||
{
|
{
|
||||||
SCH_ITEM* item = m_drawList.begin();
|
SCH_ITEM* item = m_drawList.begin();
|
||||||
|
@ -1348,6 +1366,51 @@ void SCH_SCREENS::ClearAnnotation()
|
||||||
m_screens[i]->ClearAnnotation( NULL );
|
m_screens[i]->ClearAnnotation( NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_SCREENS::ClearAnnotationOfNewSheetPaths( SCH_SHEET_LIST& aInitialSheetPathList )
|
||||||
|
{
|
||||||
|
// Clear the annotation for the components inside new sheetpaths
|
||||||
|
// not already in aInitialSheetList
|
||||||
|
SCH_SCREENS screensList( g_RootSheet ); // The list of screens, shared by sheet paths
|
||||||
|
screensList.BuildClientSheetPathList(); // build the shared by sheet paths, by screen
|
||||||
|
|
||||||
|
// Search for new sheet paths, not existing in aInitialSheetPathList
|
||||||
|
// and existing in sheetpathList
|
||||||
|
SCH_SHEET_LIST sheetpathList( g_RootSheet );
|
||||||
|
|
||||||
|
for( SCH_SHEET_PATH& sheetpath: sheetpathList )
|
||||||
|
{
|
||||||
|
bool path_exists = false;
|
||||||
|
|
||||||
|
for( const SCH_SHEET_PATH& existing_sheetpath: aInitialSheetPathList )
|
||||||
|
{
|
||||||
|
if( existing_sheetpath.Path() == sheetpath.Path() )
|
||||||
|
{
|
||||||
|
path_exists = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !path_exists )
|
||||||
|
{
|
||||||
|
// A new sheet path is found: clear the annotation corresponding to this new path:
|
||||||
|
SCH_SCREEN* curr_screen = sheetpath.LastScreen();
|
||||||
|
#if 0 // For test and debug only
|
||||||
|
wxLogMessage(">>>new path %s <%s> screen %p usage %d",
|
||||||
|
sheetpath.Path(), sheetpath.PathHumanReadable(),
|
||||||
|
curr_screen, curr_screen->GetClientSheetPathsCount() );
|
||||||
|
#endif
|
||||||
|
// Clear annotation and create the AR for this path, if not exists,
|
||||||
|
// when the screen is shared by sheet paths.
|
||||||
|
// Otherwise ClearAnnotation do nothing, because the F1 field is used as
|
||||||
|
// reference default value and takes the latest displayed value
|
||||||
|
curr_screen->EnsureAlternateReferencesExist();
|
||||||
|
curr_screen->ClearAnnotation( &sheetpath );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int SCH_SCREENS::ReplaceDuplicateTimeStamps()
|
int SCH_SCREENS::ReplaceDuplicateTimeStamps()
|
||||||
{
|
{
|
||||||
EDA_ITEMS items;
|
EDA_ITEMS items;
|
||||||
|
@ -1556,3 +1619,28 @@ int SCH_SCREENS::ChangeSymbolLibNickname( const wxString& aFrom, const wxString&
|
||||||
|
|
||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void SCH_SCREENS::BuildClientSheetPathList()
|
||||||
|
{
|
||||||
|
SCH_SHEET_LIST sheetList( g_RootSheet );
|
||||||
|
|
||||||
|
for( SCH_SCREEN* curr_screen = GetFirst(); curr_screen; curr_screen = GetNext() )
|
||||||
|
curr_screen->GetClientSheetPaths().Clear();
|
||||||
|
|
||||||
|
for( SCH_SHEET_PATH& sheetpath: sheetList )
|
||||||
|
{
|
||||||
|
SCH_SCREEN* used_screen = sheetpath.LastScreen();
|
||||||
|
|
||||||
|
// SEarch for the used_screen in list and add this unique sheet path:
|
||||||
|
for( SCH_SCREEN* curr_screen = GetFirst(); curr_screen; curr_screen = GetNext() )
|
||||||
|
{
|
||||||
|
if( used_screen == curr_screen )
|
||||||
|
{
|
||||||
|
curr_screen->GetClientSheetPaths().Add( sheetpath.Path() );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@ class SCH_SHEET_PIN;
|
||||||
class SCH_LINE;
|
class SCH_LINE;
|
||||||
class SCH_TEXT;
|
class SCH_TEXT;
|
||||||
class PLOTTER;
|
class PLOTTER;
|
||||||
|
class SCH_SHEET_LIST;
|
||||||
|
|
||||||
|
|
||||||
enum SCH_LINE_TEST_T
|
enum SCH_LINE_TEST_T
|
||||||
|
@ -73,6 +74,14 @@ private:
|
||||||
int m_refCount; ///< Number of sheets referencing this screen.
|
int m_refCount; ///< Number of sheets referencing this screen.
|
||||||
///< Delete when it goes to zero.
|
///< Delete when it goes to zero.
|
||||||
|
|
||||||
|
/** the list of scheet paths sharing this screen
|
||||||
|
* used in some annotation calculations to update alternate references
|
||||||
|
* Note: a screen having a m_refCount = 1 (only one sheet path using it)
|
||||||
|
* can have many scheet paths sharing this screen, if this sheet is inside
|
||||||
|
* an other sheet having many instances (one sheet path by parent sheet instance).
|
||||||
|
*/
|
||||||
|
wxArrayString m_clientSheetPathList;
|
||||||
|
|
||||||
/// The size of the paper to print or plot on
|
/// The size of the paper to print or plot on
|
||||||
PAGE_INFO m_paper; // keep with the MVC 'model' if this class gets split
|
PAGE_INFO m_paper; // keep with the MVC 'model' if this class gets split
|
||||||
|
|
||||||
|
@ -132,6 +141,17 @@ public:
|
||||||
|
|
||||||
int GetRefCount() const { return m_refCount; }
|
int GetRefCount() const { return m_refCount; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the sheet paths count sharing this screen
|
||||||
|
* if 1 this screen is not in a complex hierarchy: the reference field can be
|
||||||
|
* used to store the component reference
|
||||||
|
* if > 1 this screen is in a complex hierarchy, and components must have
|
||||||
|
* a full alternate reference management
|
||||||
|
*/
|
||||||
|
int GetClientSheetPathsCount() { return (int) m_clientSheetPathList.GetCount(); }
|
||||||
|
|
||||||
|
wxArrayString& GetClientSheetPaths() { return m_clientSheetPathList; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return A pointer to the first item in the linked list of draw items.
|
* @return A pointer to the first item in the linked list of draw items.
|
||||||
*/
|
*/
|
||||||
|
@ -401,6 +421,17 @@ public:
|
||||||
*/
|
*/
|
||||||
void ClearAnnotation( SCH_SHEET_PATH* aSheetPath );
|
void ClearAnnotation( SCH_SHEET_PATH* aSheetPath );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For screens shared by many sheetpaths (complex hierarchies):
|
||||||
|
* to be able to clear or modify any reference related sharing this screen
|
||||||
|
* (i.e. thie list of components), an entry for each screen path must exist.
|
||||||
|
* This function creates missing entries, using as default reference the current
|
||||||
|
* reference field and unit number
|
||||||
|
* Note: m_clientSheetPathList must be up to date
|
||||||
|
* ( built by SCH_SCREENS::BuildClientSheetPathList() )
|
||||||
|
*/
|
||||||
|
void EnsureAlternateReferencesExist();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add all schematic sheet and component objects in the screen to \a aItems.
|
* Add all schematic sheet and component objects in the screen to \a aItems.
|
||||||
*
|
*
|
||||||
|
@ -519,6 +550,16 @@ public:
|
||||||
*/
|
*/
|
||||||
void ClearAnnotation();
|
void ClearAnnotation();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the annotation for the components inside new sheetpaths
|
||||||
|
* when a complex hierarchy is modified and new sheetpaths added
|
||||||
|
* when a screen shares more than one sheet path, missing alternate references are added
|
||||||
|
* and alternate references of new sheet paths are cleared
|
||||||
|
*
|
||||||
|
* @param aInitialSheetPathList is the initial sheet paths list of hierarchy before changes.
|
||||||
|
*/
|
||||||
|
void ClearAnnotationOfNewSheetPaths( SCH_SHEET_LIST& aInitialSheetPathList );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test all sheet and component objects in the schematic for duplicate time stamps
|
* Test all sheet and component objects in the schematic for duplicate time stamps
|
||||||
* and replaces them as necessary.
|
* and replaces them as necessary.
|
||||||
|
@ -590,6 +631,12 @@ public:
|
||||||
*/
|
*/
|
||||||
int ChangeSymbolLibNickname( const wxString& aFrom, const wxString& aTo );
|
int ChangeSymbolLibNickname( const wxString& aFrom, const wxString& aTo );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* built the list of sheet paths sharing a screen for each screen in use
|
||||||
|
*/
|
||||||
|
void BuildClientSheetPathList();
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void addScreenToList( SCH_SCREEN* aScreen );
|
void addScreenToList( SCH_SCREEN* aScreen );
|
||||||
void buildScreenList( SCH_SHEET* aSheet);
|
void buildScreenList( SCH_SHEET* aSheet);
|
||||||
|
|
|
@ -1046,8 +1046,28 @@ void SCH_EDIT_FRAME::OnEditItem( wxCommandEvent& aEvent )
|
||||||
}
|
}
|
||||||
|
|
||||||
case SCH_SHEET_T:
|
case SCH_SHEET_T:
|
||||||
if( EditSheet( (SCH_SHEET*) item, m_CurrentSheet ) )
|
{
|
||||||
|
bool doClearAnnotation;
|
||||||
|
bool doRefresh = false;
|
||||||
|
// Keep trace of existing sheet paths. EditSheet() can modify this list
|
||||||
|
SCH_SHEET_LIST initial_sheetpathList( g_RootSheet );
|
||||||
|
|
||||||
|
doRefresh = EditSheet( (SCH_SHEET*) item, m_CurrentSheet, &doClearAnnotation );
|
||||||
|
|
||||||
|
if( doClearAnnotation ) // happens when the current sheet load a existing file
|
||||||
|
{ // we must clear "new" components annotation
|
||||||
|
SCH_SCREENS screensList( g_RootSheet );
|
||||||
|
// We clear annotation of new sheet paths here:
|
||||||
|
screensList.ClearAnnotationOfNewSheetPaths( initial_sheetpathList );
|
||||||
|
// Clear annotation of m_CurrentSheet itself, because its sheetpath
|
||||||
|
// is not a new path, but components managed by its sheet path must have
|
||||||
|
// their annotation cleared, becuase they are new:
|
||||||
|
((SCH_SHEET*) item)->GetScreen()->ClearAnnotation( m_CurrentSheet );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( doRefresh )
|
||||||
m_canvas->Refresh();
|
m_canvas->Refresh();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SCH_SHEET_PIN_T:
|
case SCH_SHEET_PIN_T:
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
#include <dialogs/dialog_sch_sheet_props.h>
|
#include <dialogs/dialog_sch_sheet_props.h>
|
||||||
|
|
||||||
|
|
||||||
bool SCH_EDIT_FRAME::EditSheet( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy )
|
bool SCH_EDIT_FRAME::EditSheet( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy, bool* aClearAnnotationNewItems )
|
||||||
{
|
{
|
||||||
if( aSheet == NULL || aHierarchy == NULL )
|
if( aSheet == NULL || aHierarchy == NULL )
|
||||||
return false;
|
return false;
|
||||||
|
@ -331,10 +331,8 @@ bool SCH_EDIT_FRAME::EditSheet( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( clearAnnotation )
|
if( aClearAnnotationNewItems )
|
||||||
{
|
*aClearAnnotationNewItems = clearAnnotation;
|
||||||
newScreens.ClearAnnotation();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_canvas->MoveCursorToCrossHair();
|
m_canvas->MoveCursorToCrossHair();
|
||||||
m_canvas->SetIgnoreMouseEvents( false );
|
m_canvas->SetIgnoreMouseEvents( false );
|
||||||
|
|
Loading…
Reference in New Issue