From 00749af91445e501f64dc33f79b13a9df0f97eeb Mon Sep 17 00:00:00 2001 From: Wayne Stambaugh Date: Mon, 5 Feb 2018 09:01:55 -0500 Subject: [PATCH] Eeschema: fix using subpaths in sheets. Fix double path name issue when using sheet file name paths that differ from the project path. This fix also allows for nesting schematics in subfolder in multiple root paths. Fixes lp:1745109 https://bugs.launchpad.net/bugs/1745109 Fixes lp:1735982 https://bugs.launchpad.net/bugs/1735982 --- eeschema/sch_legacy_plugin.cpp | 27 ++++++++++++++++++++++++++- eeschema/sheet.cpp | 27 ++++++++++++++++++++------- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/eeschema/sch_legacy_plugin.cpp b/eeschema/sch_legacy_plugin.cpp index 2bc406deec..69a3a55dea 100644 --- a/eeschema/sch_legacy_plugin.cpp +++ b/eeschema/sch_legacy_plugin.cpp @@ -598,7 +598,22 @@ SCH_SHEET* SCH_LEGACY_PLUGIN::Load( const wxString& aFileName, KIWAY* aKiway, // always be an absolute path so the project path can be used for load child sheet files. wxASSERT( fn.IsAbsolute() ); - m_path = fn.GetPath(); + if( aAppendToMe ) + { + wxLogDebug( "Append \"%s\" to sheet \"%s\".", aFileName, aAppendToMe->GetFileName() ); + + wxFileName normedFn = aAppendToMe->GetFileName(); + + if( !normedFn.IsAbsolute() ) + { + if( aFileName.Right( normedFn.GetFullPath().Length() ) == normedFn.GetFullPath() ) + m_path = aFileName.Left( aFileName.Length() - normedFn.GetFullPath().Length() ); + } + } + else + { + m_path = aKiway->Prj().GetProjectPath(); + } init( aKiway, aProperties ); @@ -641,6 +656,13 @@ void SCH_LEGACY_PLUGIN::loadHierarchy( SCH_SHEET* aSheet ) if( !fileName.IsAbsolute() ) fileName.MakeAbsolute( m_path ); + // Save the current path so that it gets restored when decending and ascending the + // sheet hierarchy which allows for sheet schematic files to be nested in folders + // relative to the last path a schematic was loaded from. + m_path = fileName.GetPath(); + + wxLogDebug( "Saving last path \"%s\"", m_path ); + m_rootSheet->SearchHierarchy( fileName.GetFullPath(), &screen ); if( screen ) @@ -693,6 +715,9 @@ void SCH_LEGACY_PLUGIN::loadHierarchy( SCH_SHEET* aSheet ) m_error += ioe.What(); } } + + wxLogDebug( "Restoring last path \"%s\"", fileName.GetPath() ); + m_path = fileName.GetPath(); } } diff --git a/eeschema/sheet.cpp b/eeschema/sheet.cpp index 99823ba123..c134daa60b 100644 --- a/eeschema/sheet.cpp +++ b/eeschema/sheet.cpp @@ -100,20 +100,32 @@ bool SCH_EDIT_FRAME::EditSheet( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy ) bool loadFromFile = false; SCH_SCREEN* useScreen = NULL; + // Relative file names are relative to the path of the current sheet. This allows for + // nesting of schematic files in subfolders. + if( !fileName.IsAbsolute() ) + { + const SCH_SCREEN* currentScreen = aHierarchy->LastScreen(); + + wxCHECK_MSG( currentScreen, false, "Invalid sheet path object." ); + + wxFileName currentSheetFileName = currentScreen->GetFileName(); + + wxCHECK_MSG( fileName.Normalize( wxPATH_NORM_ALL, currentSheetFileName.GetPath() ), false, + "Cannot normalize new sheet schematic file path." ); + } + wxString newFilename = fileName.GetFullPath(); // Search for a schematic file having the same filename // already in use in the hierarchy or on disk, in order to reuse it. - if( !g_RootSheet->SearchHierarchy( fileName.GetFullName(), &useScreen ) ) + if( !g_RootSheet->SearchHierarchy( newFilename, &useScreen ) ) { - // if user entered a relative path, allow that to stay, but do the - // file existence test with an absolute (full) path. This transformation - // is local to this scope, but is the same one used at load time later. - newFilename = Prj().AbsolutePath( newFilename ); - loadFromFile = wxFileExists( newFilename ); } + wxLogDebug( "Sheet requested file \"%s\", %s", newFilename, + (loadFromFile) ? "found" : "not found" ); + // Inside Eeschema, filenames are stored using unix notation newFilename.Replace( wxT( "\\" ), wxT( "/" ) ); @@ -236,7 +248,8 @@ bool SCH_EDIT_FRAME::EditSheet( SCH_SHEET* aSheet, SCH_SHEET_PATH* aHierarchy ) } } - aSheet->SetFileName( fileName.GetFullPath( wxPATH_UNIX ) ); + wxFileName userFileName = dlg.GetFileName(); + aSheet->SetFileName( userFileName.GetFullPath( wxPATH_UNIX ) ); if( useScreen ) {