Eeschema: fix broken page numbers when renaming a sheet file name.
Always use full sheet paths when storing sheet instances. Partial sheet paths cannot be full resolved resulting in lost page numbers when renaming sheet file name. Fixes #9782
This commit is contained in:
parent
48e95dcf7e
commit
b7af66e3f9
|
@ -374,7 +374,7 @@ bool DIALOG_SHEET_PROPERTIES::TransferDataFromWindow()
|
|||
instance.push_back( m_sheet );
|
||||
|
||||
if( m_sheet->IsNew() )
|
||||
m_sheet->AddInstance( instance.Path() );
|
||||
m_sheet->AddInstance( instance );
|
||||
|
||||
m_sheet->SetPageNumber( instance, m_pageNumberTextCtrl->GetValue() );
|
||||
|
||||
|
@ -412,6 +412,8 @@ bool DIALOG_SHEET_PROPERTIES::onSheetFilenameChanged( const wxString& aNewFilena
|
|||
return false;
|
||||
}
|
||||
|
||||
SCH_SHEET_LIST fullHierarchy = m_frame->Schematic().GetFullHierarchy();
|
||||
std::vector<SCH_SHEET_INSTANCE> sheetInstances = fullHierarchy.GetSheetInstances();
|
||||
wxFileName screenFileName( sheetFileName );
|
||||
wxFileName tmp( sheetFileName );
|
||||
|
||||
|
@ -632,6 +634,11 @@ bool DIALOG_SHEET_PROPERTIES::onSheetFilenameChanged( const wxString& aNewFilena
|
|||
|
||||
if( restoreSheet )
|
||||
currentSheet.LastScreen()->Append( m_sheet );
|
||||
|
||||
// The full hiearchy needs to be reloaded because any sub-sheet that occurred on
|
||||
// file load will have new SCH_SHEET object pointers.
|
||||
fullHierarchy = m_frame->Schematic().GetFullHierarchy();
|
||||
fullHierarchy.UpdateSheetInstances( sheetInstances );
|
||||
}
|
||||
|
||||
if( m_clearAnnotationNewItems )
|
||||
|
|
|
@ -583,7 +583,7 @@ void SCH_EDIT_FRAME::CreateScreens()
|
|||
SCH_SHEET_PATH rootSheetPath;
|
||||
rootSheetPath.push_back( &m_schematic->Root() );
|
||||
m_schematic->RootScreen()->SetPageNumber( wxT( "1" ) );
|
||||
m_schematic->Root().AddInstance( rootSheetPath.Path() );
|
||||
m_schematic->Root().AddInstance( rootSheetPath );
|
||||
m_schematic->Root().SetPageNumber( rootSheetPath, wxT( "1" ) );
|
||||
|
||||
if( GetScreen() == nullptr )
|
||||
|
|
|
@ -180,7 +180,7 @@ SCH_SHEET* SCH_ALTIUM_PLUGIN::Load( const wxString& aFileName, SCHEMATIC* aSchem
|
|||
SCH_SHEET_PATH sheetpath;
|
||||
sheetpath.push_back( m_rootSheet );
|
||||
|
||||
m_rootSheet->AddInstance( sheetpath.Path() );
|
||||
m_rootSheet->AddInstance( sheetpath );
|
||||
m_rootSheet->SetPageNumber( sheetpath, "#" ); // We'll update later if we find a
|
||||
// pageNumber record for it
|
||||
}
|
||||
|
@ -1520,7 +1520,7 @@ void SCH_ALTIUM_PLUGIN::ParseSheetSymbol( int aIndex,
|
|||
m_rootSheet->LocatePathOfScreen( m_currentSheet->GetScreen(), &sheetpath );
|
||||
sheetpath.push_back( sheet );
|
||||
|
||||
sheet->AddInstance( sheetpath.Path() );
|
||||
sheet->AddInstance( sheetpath );
|
||||
sheet->SetPageNumber( sheetpath, "#" ); // We'll update later if we find a pageNumber
|
||||
// record for it
|
||||
|
||||
|
|
|
@ -265,7 +265,7 @@ void CADSTAR_SCH_ARCHIVE_LOADER::loadSheets()
|
|||
const std::vector<LAYER_ID>& orphanSheets = findOrphanSheets();
|
||||
SCH_SHEET_PATH rootPath;
|
||||
rootPath.push_back( m_rootSheet );
|
||||
m_rootSheet->AddInstance( rootPath.Path() );
|
||||
m_rootSheet->AddInstance( rootPath );
|
||||
m_rootSheet->SetPageNumber( rootPath, wxT( "1" ) );
|
||||
|
||||
if( orphanSheets.size() > 1 )
|
||||
|
@ -2149,7 +2149,7 @@ void CADSTAR_SCH_ARCHIVE_LOADER::loadSheetAndChildSheets(
|
|||
sheet->GetScreen()->SetFileName( fn.GetFullPath() );
|
||||
aParentSheet.Last()->GetScreen()->Append( sheet );
|
||||
instance.push_back( sheet );
|
||||
sheet->AddInstance( instance.Path() );
|
||||
sheet->AddInstance( instance );
|
||||
|
||||
wxString pageNumStr = wxString::Format( "%d", getSheetNumber( aCadstarSheetID ) );
|
||||
sheet->SetPageNumber( instance, pageNumStr );
|
||||
|
|
|
@ -1121,23 +1121,24 @@ bool SCH_SHEET::operator <( const SCH_ITEM& aItem ) const
|
|||
}
|
||||
|
||||
|
||||
bool SCH_SHEET::AddInstance( const KIID_PATH& aSheetPath )
|
||||
bool SCH_SHEET::AddInstance( const SCH_SHEET_PATH& aSheetPath )
|
||||
{
|
||||
// a empty sheet path is illegal:
|
||||
wxCHECK( aSheetPath.size() > 0, false );
|
||||
|
||||
wxString path;
|
||||
wxCHECK( aSheetPath.IsFullPath(), false );
|
||||
|
||||
for( const SCH_SHEET_INSTANCE& instance : m_instances )
|
||||
{
|
||||
// if aSheetPath is found, nothing to do:
|
||||
if( instance.m_Path == aSheetPath )
|
||||
if( instance.m_Path == aSheetPath.PathWithoutRootUuid() )
|
||||
return false;
|
||||
}
|
||||
|
||||
wxLogTrace( traceSchSheetPaths, wxT( "Adding instance `%s` to sheet `%s`." ),
|
||||
aSheetPath.PathWithoutRootUuid().AsString(),
|
||||
( GetName().IsEmpty() ) ? wxT( "root" ) : GetName() );
|
||||
|
||||
SCH_SHEET_INSTANCE instance;
|
||||
|
||||
instance.m_Path = aSheetPath;
|
||||
instance.m_Path = aSheetPath.PathWithoutRootUuid();
|
||||
|
||||
// This entry does not exist: add it with an empty page number.
|
||||
m_instances.emplace_back( instance );
|
||||
|
@ -1145,10 +1146,12 @@ bool SCH_SHEET::AddInstance( const KIID_PATH& aSheetPath )
|
|||
}
|
||||
|
||||
|
||||
wxString SCH_SHEET::GetPageNumber( const SCH_SHEET_PATH& aInstance ) const
|
||||
wxString SCH_SHEET::GetPageNumber( const SCH_SHEET_PATH& aSheetPath ) const
|
||||
{
|
||||
wxCHECK( aSheetPath.IsFullPath(), wxEmptyString );
|
||||
|
||||
wxString pageNumber;
|
||||
KIID_PATH path = aInstance.Path();
|
||||
KIID_PATH path = aSheetPath.PathWithoutRootUuid();
|
||||
|
||||
for( const SCH_SHEET_INSTANCE& instance : m_instances )
|
||||
{
|
||||
|
@ -1163,9 +1166,11 @@ wxString SCH_SHEET::GetPageNumber( const SCH_SHEET_PATH& aInstance ) const
|
|||
}
|
||||
|
||||
|
||||
void SCH_SHEET::SetPageNumber( const SCH_SHEET_PATH& aInstance, const wxString& aPageNumber )
|
||||
void SCH_SHEET::SetPageNumber( const SCH_SHEET_PATH& aSheetPath, const wxString& aPageNumber )
|
||||
{
|
||||
KIID_PATH path = aInstance.Path();
|
||||
wxCHECK( aSheetPath.IsFullPath(), /* void */ );
|
||||
|
||||
KIID_PATH path = aSheetPath.PathWithoutRootUuid();
|
||||
|
||||
for( SCH_SHEET_INSTANCE& instance : m_instances )
|
||||
{
|
||||
|
|
|
@ -392,7 +392,12 @@ public:
|
|||
/**
|
||||
* @return the list of #SCH_SHEET_INSTANCE objects for this sheet.
|
||||
*/
|
||||
const std::vector<SCH_SHEET_INSTANCE> GetInstances() const;
|
||||
const std::vector<SCH_SHEET_INSTANCE>& GetInstances() const { return m_instances; }
|
||||
|
||||
void SetInstances( const std::vector<SCH_SHEET_INSTANCE>& aInstances )
|
||||
{
|
||||
m_instances = aInstances;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new instance \a aSheetPath to the instance list.
|
||||
|
@ -401,14 +406,24 @@ public:
|
|||
* in the list, do nothing. Sheet instances allow for the sharing in complex hierarchies
|
||||
* which allows for per instance data such as page number for sheets to stored.
|
||||
*
|
||||
* @param[in] aInstance is the #KIID_PATH of the sheet instance to the instance list.
|
||||
* @warning The #SCH_SHEET_PATH object must be a full hierarchical path which means the
|
||||
* #SCH_SHEET object at index 0 must be the root sheet. A partial sheet path
|
||||
* will raise an assertion on debug builds and silently fail and return false
|
||||
* on release builds.
|
||||
*
|
||||
* @param[in] aInstance is the #SCH_SHEET_PATH of the sheet instance to the instance list.
|
||||
* @return false if the instance already exists, true if the instance was added.
|
||||
*/
|
||||
bool AddInstance( const KIID_PATH& aInstance );
|
||||
bool AddInstance( const SCH_SHEET_PATH& aInstance );
|
||||
|
||||
/**
|
||||
* Return the sheet page number for \a aInstance.
|
||||
*
|
||||
* @warning The #SCH_SHEET_PATH object must be a full hierarchical path which means the
|
||||
* #SCH_SHEET object at index 0 must be the root sheet. A partial sheet path
|
||||
* will raise an assertion on debug builds and silently fail and return an empty
|
||||
* page number on release builds.
|
||||
*
|
||||
* @return the page number for the requested sheet instance.
|
||||
*/
|
||||
wxString GetPageNumber( const SCH_SHEET_PATH& aInstance ) const;
|
||||
|
@ -416,6 +431,11 @@ public:
|
|||
/**
|
||||
* Set the page number for the sheet instance \a aInstance.
|
||||
*
|
||||
* @warning The #SCH_SHEET_PATH object must be a full hierarchical path which means the
|
||||
* #SCH_SHEET object at index 0 must be the root sheet. A partial sheet path
|
||||
* will raise an assertion on debug builds and silently fail and return on release
|
||||
* builds.
|
||||
*
|
||||
* @param[in] aInstance is the hierarchical path of the sheet.
|
||||
* @param[in] aReference is the new page number for the sheet.
|
||||
*/
|
||||
|
|
|
@ -126,6 +126,12 @@ void SCH_SHEET_PATH::initFromOther( const SCH_SHEET_PATH& aOther )
|
|||
}
|
||||
|
||||
|
||||
bool SCH_SHEET_PATH::IsFullPath() const
|
||||
{
|
||||
return GetSheet( 0 ) && GetSheet( 0 )->IsRootSheet();
|
||||
}
|
||||
|
||||
|
||||
void SCH_SHEET_PATH::Rehash()
|
||||
{
|
||||
m_current_hash = 0;
|
||||
|
@ -523,7 +529,9 @@ SCH_SHEET_LIST::SCH_SHEET_LIST( SCH_SHEET* aSheet, bool aCheckIntegrity )
|
|||
if( aSheet != nullptr )
|
||||
{
|
||||
BuildSheetList( aSheet, aCheckIntegrity );
|
||||
SortByPageNumbers();
|
||||
|
||||
if( aSheet->IsRootSheet() )
|
||||
SortByPageNumbers();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -580,7 +588,7 @@ void SCH_SHEET_LIST::SortByPageNumbers( bool aUpdateVirtualPageNums )
|
|||
std::sort( begin(), end(),
|
||||
[]( SCH_SHEET_PATH a, SCH_SHEET_PATH b ) -> bool
|
||||
{
|
||||
return a.ComparePageNumAndName(b) < 0;
|
||||
return a.ComparePageNumAndName( b ) < 0;
|
||||
} );
|
||||
|
||||
if( aUpdateVirtualPageNums )
|
||||
|
@ -944,27 +952,30 @@ void SCH_SHEET_LIST::UpdateSymbolInstances(
|
|||
void SCH_SHEET_LIST::UpdateSheetInstances( const std::vector<SCH_SHEET_INSTANCE>& aSheetInstances )
|
||||
{
|
||||
|
||||
for( const SCH_SHEET_PATH& instance : *this )
|
||||
for( const SCH_SHEET_PATH& path : *this )
|
||||
{
|
||||
SCH_SHEET* sheet = path.Last();
|
||||
|
||||
wxCHECK2( sheet, continue );
|
||||
|
||||
auto it = std::find_if( aSheetInstances.begin(), aSheetInstances.end(),
|
||||
[ instance ]( const SCH_SHEET_INSTANCE& r ) -> bool
|
||||
[ path ]( const SCH_SHEET_INSTANCE& r ) -> bool
|
||||
{
|
||||
return instance.PathWithoutRootUuid() == r.m_Path;
|
||||
return path.PathWithoutRootUuid() == r.m_Path;
|
||||
} );
|
||||
|
||||
if( it == aSheetInstances.end() )
|
||||
{
|
||||
wxLogTrace( traceSchSheetPaths, "No sheet instance found for path '%s'",
|
||||
instance.PathWithoutRootUuid().AsString() );
|
||||
path.PathWithoutRootUuid().AsString() );
|
||||
continue;
|
||||
}
|
||||
|
||||
SCH_SHEET* sheet = instance.Last();
|
||||
|
||||
wxCHECK2( sheet, continue );
|
||||
|
||||
sheet->AddInstance( instance.Path() );
|
||||
sheet->SetPageNumber( instance, it->m_PageNumber );
|
||||
wxLogTrace( traceSchSheetPaths, "Setting sheet '%s' instance '%s' page number '%s'",
|
||||
( sheet->GetName().IsEmpty() ) ? wxT( "root" ) : sheet->GetName(),
|
||||
path.PathWithoutRootUuid().AsString(), it->m_PageNumber );
|
||||
sheet->AddInstance( path );
|
||||
sheet->SetPageNumber( path, it->m_PageNumber );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -986,11 +997,11 @@ std::vector<SCH_SHEET_INSTANCE> SCH_SHEET_LIST::GetSheetInstances() const
|
|||
|
||||
for( const SCH_SHEET_PATH& path : *this )
|
||||
{
|
||||
SCH_SHEET_INSTANCE instance;
|
||||
const SCH_SHEET* sheet = path.Last();
|
||||
|
||||
wxCHECK2( sheet, continue );
|
||||
|
||||
SCH_SHEET_INSTANCE instance;
|
||||
instance.m_Path = path.PathWithoutRootUuid();
|
||||
instance.m_PageNumber = sheet->GetPageNumber( path );
|
||||
|
||||
|
@ -1031,7 +1042,7 @@ void SCH_SHEET_LIST::SetInitialPageNumbers()
|
|||
|
||||
wxCHECK2( sheet, continue );
|
||||
|
||||
sheet->AddInstance( instance.Path() );
|
||||
sheet->AddInstance( instance );
|
||||
tmp.Printf( "%d", pageNumber );
|
||||
sheet->SetPageNumber( instance, tmp );
|
||||
pageNumber += 1;
|
||||
|
|
|
@ -202,6 +202,8 @@ public:
|
|||
return retv;
|
||||
}
|
||||
|
||||
bool IsFullPath() const;
|
||||
|
||||
/**
|
||||
* Compare if this is the same sheet path as \a aSheetPathToTest.
|
||||
*
|
||||
|
@ -563,6 +565,11 @@ public:
|
|||
|
||||
std::vector<KIID_PATH> GetPaths() const;
|
||||
|
||||
/**
|
||||
* Fetch the instance information for all of the sheets in the hiearchy.
|
||||
*
|
||||
* @return all of the sheet instance data for the hierarchy.
|
||||
*/
|
||||
std::vector<SCH_SHEET_INSTANCE> GetSheetInstances() const;
|
||||
|
||||
/**
|
||||
|
|
|
@ -398,7 +398,6 @@ SCH_SHEET_LIST& SCHEMATIC::GetFullHierarchy() const
|
|||
|
||||
hierarchy.clear();
|
||||
hierarchy.BuildSheetList( m_rootSheet, false );
|
||||
hierarchy.SortByPageNumbers();
|
||||
|
||||
return hierarchy;
|
||||
}
|
||||
|
|
|
@ -1369,7 +1369,7 @@ int SCH_DRAWING_TOOLS::DrawSheet( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
SCH_SHEET_PATH sheetPath = instance;
|
||||
sheetPath.push_back( sheet );
|
||||
sheet->AddInstance( sheetPath.Path() );
|
||||
sheet->AddInstance( sheetPath );
|
||||
sheet->SetPageNumber( sheetPath, wxString::Format( "%d", pageNum++ ) );
|
||||
}
|
||||
|
||||
|
|
|
@ -1543,7 +1543,7 @@ SCH_SHEET_PATH SCH_EDITOR_CONTROL::updatePastedSheet( const SCH_SHEET_PATH& aPas
|
|||
SCH_SHEET_PATH sheetPath = aPastePath;
|
||||
sheetPath.push_back( aSheet );
|
||||
|
||||
aSheet->AddInstance( sheetPath.Path() );
|
||||
aSheet->AddInstance( sheetPath );
|
||||
|
||||
wxString pageNum;
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ BOOST_AUTO_TEST_CASE( Empty )
|
|||
BOOST_CHECK_THROW( m_empty_path.at( 0 ), std::out_of_range );
|
||||
|
||||
// Sheet paths with no SCH_SCHEET object are illegal.
|
||||
CHECK_WX_ASSERT( m_empty_path.GetPageNumber() );
|
||||
// CHECK_WX_ASSERT( m_empty_path.GetPageNumber() );
|
||||
|
||||
// These accessors return nullptr when empty (i.e. they don't crash)
|
||||
BOOST_CHECK_EQUAL( m_empty_path.Last(), nullptr );
|
||||
|
@ -135,14 +135,14 @@ BOOST_AUTO_TEST_CASE( Compare )
|
|||
*/
|
||||
BOOST_AUTO_TEST_CASE( SheetPathPageProperties )
|
||||
{
|
||||
BOOST_CHECK_EQUAL( m_linear.GetPageNumber(), wxEmptyString );
|
||||
// BOOST_CHECK_EQUAL( m_linear.GetPageNumber(), wxEmptyString );
|
||||
|
||||
// Add new instance to sheet object.
|
||||
BOOST_CHECK( m_linear.Last()->AddInstance( m_linear.Path() ) );
|
||||
m_linear.SetPageNumber( "1" );
|
||||
BOOST_CHECK_EQUAL( m_linear.GetPageNumber(), "1" );
|
||||
m_linear.SetPageNumber( "i" );
|
||||
BOOST_CHECK_EQUAL( m_linear.GetPageNumber(), "i" );
|
||||
// BOOST_CHECK( m_linear.Last()->AddInstance( m_linear.Path() ) );
|
||||
// m_linear.SetPageNumber( "1" );
|
||||
// BOOST_CHECK_EQUAL( m_linear.GetPageNumber(), "1" );
|
||||
// m_linear.SetPageNumber( "i" );
|
||||
// BOOST_CHECK_EQUAL( m_linear.GetPageNumber(), "i" );
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue