Fix renaming sheet check

If we are renaming a sheet that exists only once in the schematic, then
we don't need to warn about case sensitivity.  If the sheet exists
multiple times, we do.  We can't check this using SCREENS because the
screens don't maintain full state information about where they are used.

Fixes https://gitlab.com/kicad/code/kicad/-/issues/17901
This commit is contained in:
Seth Hillbrand 2024-05-03 13:21:25 -07:00
parent 44717f927c
commit ba4974749c
5 changed files with 41 additions and 48 deletions

View File

@ -502,7 +502,7 @@ bool DIALOG_SHEET_PROPERTIES::onSheetFilenameChanged( const wxString& aNewFilena
if( m_sheet->GetScreen() == nullptr ) // New just created sheet. if( m_sheet->GetScreen() == nullptr ) // New just created sheet.
{ {
if( !m_frame->AllowCaseSensitiveFileNameClashes( newAbsoluteFilename ) ) if( !m_frame->AllowCaseSensitiveFileNameClashes( m_sheet->GetFileName(), newAbsoluteFilename ) )
return false; return false;
if( useScreen || loadFromFile ) // Load from existing file. if( useScreen || loadFromFile ) // Load from existing file.
@ -527,7 +527,7 @@ bool DIALOG_SHEET_PROPERTIES::onSheetFilenameChanged( const wxString& aNewFilena
{ {
isExistingSheet = true; isExistingSheet = true;
if( !m_frame->AllowCaseSensitiveFileNameClashes( newAbsoluteFilename ) ) if( !m_frame->AllowCaseSensitiveFileNameClashes( m_sheet->GetFileName(), newAbsoluteFilename ) )
return false; return false;
// We are always using here a case insensitive comparison to avoid issues // We are always using here a case insensitive comparison to avoid issues

View File

@ -546,7 +546,7 @@ public:
* @param aSchematicFileName is the absolute path and file name of the file to test. * @param aSchematicFileName is the absolute path and file name of the file to test.
* @return true if the user accepts the potential file name clash risk. * @return true if the user accepts the potential file name clash risk.
*/ */
bool AllowCaseSensitiveFileNameClashes( const wxString& aSchematicFileName ); bool AllowCaseSensitiveFileNameClashes( const wxString& aOldName, const wxString& aSchematicFileName );
/** /**
* Edit an existing sheet or add a new sheet to the schematic. * Edit an existing sheet or add a new sheet to the schematic.

View File

@ -2084,33 +2084,6 @@ bool SCH_SCREENS::HasSchematic( const wxString& aSchematicFileName )
} }
bool SCH_SCREENS::CanCauseCaseSensitivityIssue( const wxString& aSchematicFileName ) const
{
wxString lhsLower;
wxString rhsLower;
wxFileName lhs;
wxFileName rhs = aSchematicFileName;
wxCHECK( rhs.IsAbsolute(), false );
for( const SCH_SCREEN* screen : m_screens )
{
lhs = screen->GetFileName();
if( lhs.GetPath() != rhs.GetPath() )
continue;
lhsLower = lhs.GetFullName().Lower();
rhsLower = rhs.GetFullName().Lower();
if( lhsLower == rhsLower && lhs.GetFullName() != rhs.GetFullName() )
return true;
}
return false;
}
void SCH_SCREENS::BuildClientSheetPathList() void SCH_SCREENS::BuildClientSheetPathList()
{ {
SCH_SCREEN* first = GetFirst(); SCH_SCREEN* first = GetFirst();

View File

@ -812,19 +812,6 @@ public:
*/ */
void BuildClientSheetPathList(); void BuildClientSheetPathList();
/**
* Check \a aSchematicFileName for a potential file name case sensitivity issue.
*
* On platforms where file names are case sensitive, it is possible to schematic sheet
* file names that would cause issues on platforms where file name are case insensitive.
* File names foo.sch and Foo.sch are unique files on Linux and MacOS but on Windows
* this would result in a broken schematic.
*
* @param[in] aSchematicFileName is the absolute path and file name of the file to test.
* @return true if \a aSchematicFileName would cause an issue.
*/
bool CanCauseCaseSensitivityIssue( const wxString& aSchematicFileName ) const;
/** /**
* Update the symbol value and footprint instance data for legacy designs. * Update the symbol value and footprint instance data for legacy designs.
*/ */

View File

@ -690,16 +690,49 @@ void SCH_EDIT_FRAME::DrawCurrentSheetToClipboard()
} }
bool SCH_EDIT_FRAME::AllowCaseSensitiveFileNameClashes( const wxString& aSchematicFileName ) bool SCH_EDIT_FRAME::AllowCaseSensitiveFileNameClashes( const wxString& aOldName, const wxString& aSchematicFileName )
{ {
wxString msg; wxString msg;
SCH_SCREENS screens( Schematic().Root() ); SCH_SHEET_LIST sheets( &Schematic().Root() );
wxFileName fn = aSchematicFileName; wxFileName fn = aSchematicFileName;
wxCHECK( fn.IsAbsolute(), false ); wxCHECK( fn.IsAbsolute(), false );
if( eeconfig()->m_Appearance.show_sheet_filename_case_sensitivity_dialog auto can_cause_issues = [&]() -> bool
&& screens.CanCauseCaseSensitivityIssue( aSchematicFileName ) ) {
wxFileName lhs;
wxFileName rhs = aSchematicFileName;
wxFileName old = aOldName;
wxString oldLower = old.GetFullName().Lower();
wxString rhsLower = rhs.GetFullName().Lower();
wxString lhsLower;
size_t count = 0;
wxCHECK( rhs.IsAbsolute(), false );
for( SCH_SHEET_PATH& sheet : sheets )
{
lhs = sheet.LastScreen()->GetFileName();
if( lhs.GetPath() != rhs.GetPath() )
continue;
lhsLower = lhs.GetFullName().Lower();
if( lhsLower == rhsLower && lhs.GetFullName() != rhs.GetFullName() )
count++;
}
// If we are renaming a sheet that is only used once, then we are not going to cause
// a case sensitivity issue.
if( oldLower == rhsLower )
return count > 1;
return count > 0;
};
if( eeconfig()->m_Appearance.show_sheet_filename_case_sensitivity_dialog && can_cause_issues() )
{ {
msg.Printf( _( "The file name '%s' can cause issues with an existing file name\n" msg.Printf( _( "The file name '%s' can cause issues with an existing file name\n"
"already defined in the schematic on systems that support case\n" "already defined in the schematic on systems that support case\n"
@ -712,7 +745,7 @@ bool SCH_EDIT_FRAME::AllowCaseSensitiveFileNameClashes( const wxString& aSchemat
wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION ); wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION );
dlg.ShowCheckBox( _( "Do not show this message again." ) ); dlg.ShowCheckBox( _( "Do not show this message again." ) );
dlg.SetYesNoLabels( wxMessageDialog::ButtonLabel( _( "Create New Sheet" ) ), dlg.SetYesNoLabels( wxMessageDialog::ButtonLabel( _( "Create New Sheet" ) ),
wxMessageDialog::ButtonLabel( _( "Discard New Sheet" ) ) ); wxMessageDialog::ButtonLabel( _( "Cancel" ) ) );
if( dlg.ShowModal() == wxID_NO ) if( dlg.ShowModal() == wxID_NO )
return false; return false;